Skip to content

Commit

Permalink
Merge tag 'wireless-drivers-next-for-davem-2018-02-08' of git://git.k…
Browse files Browse the repository at this point in the history
…ernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next

Kalle Valo says:

====================
wireless-drivers-next patches for 4.16

The most important here is the ssb fix, it has been reported by the
users frequently and the fix just missed the final v4.15. Also
numerous other fixes, mt76 had multiple problems with aggregation and
a long standing unaligned access bug in rtlwifi is finally fixed.

Major changes:

ath10k

* correct firmware RAM dump length for QCA6174/QCA9377

* add new QCA988X device id

* fix a kernel panic during pci probe

* revert a recent commit which broke ath10k firmware metadata parsing

ath9k

* fix a noise floor regression introduced during the merge window

* add new device id

rtlwifi

* fix unaligned access seen on ARM architecture

mt76

* various aggregation fixes which fix connection stalls

ssb

* fix b43 and b44 on non-MIPS which broke in v4.15-rc9
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Feb 8, 2018
2 parents 55b3280 + 99ffd19 commit e0c42c8
Show file tree
Hide file tree
Showing 18 changed files with 181 additions and 32 deletions.
43 changes: 36 additions & 7 deletions drivers/net/wireless/ath/ath10k/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,35 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA988X_HW_2_0_VERSION,
.dev_id = QCA988X_2_0_DEVICE_ID_UBNT,
.name = "qca988x hw2.0 ubiquiti",
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
.otp_exe_param = 0,
.channel_counters_freq_hz = 88000,
.max_probe_resp_desc_thres = 0,
.cal_data_len = 2116,
.fw = {
.dir = QCA988X_HW_2_0_FW_DIR,
.board = QCA988X_HW_2_0_BOARD_DATA_FILE,
.board_size = QCA988X_BOARD_DATA_SZ,
.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
},
.hw_ops = &qca988x_ops,
.decap_align_bytes = 4,
.spectral_bin_discard = 0,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
.n_cipher_suites = 8,
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA9887_HW_1_0_VERSION,
.dev_id = QCA9887_1_0_DEVICE_ID,
Expand Down Expand Up @@ -1276,10 +1305,7 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
len -= sizeof(*hdr);
data = hdr->data;

/* jump over the padding */
ie_len = ALIGN(ie_len, 4);

if (len < ie_len) {
if (len < ALIGN(ie_len, 4)) {
ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
ie_id, ie_len, len);
ret = -EINVAL;
Expand Down Expand Up @@ -1318,6 +1344,9 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
goto out;
}

/* jump over the padding */
ie_len = ALIGN(ie_len, 4);

len -= ie_len;
data += ie_len;
}
Expand Down Expand Up @@ -1448,9 +1477,6 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
len -= sizeof(*hdr);
data += sizeof(*hdr);

/* jump over the padding */
ie_len = ALIGN(ie_len, 4);

if (len < ie_len) {
ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
ie_id, len, ie_len);
Expand Down Expand Up @@ -1556,6 +1582,9 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
break;
}

/* jump over the padding */
ie_len = ALIGN(ie_len, 4);

len -= ie_len;
data += ie_len;
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/wireless/ath/ath10k/coredump.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -616,7 +617,7 @@ static const struct ath10k_mem_region qca6174_hw30_mem_regions[] = {
{
.type = ATH10K_MEM_REGION_TYPE_DRAM,
.start = 0x400000,
.len = 0x90000,
.len = 0xa8000,
.name = "DRAM",
.section_table = {
.sections = NULL,
Expand Down
12 changes: 10 additions & 2 deletions drivers/net/wireless/ath/ath10k/debug.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -81,18 +82,25 @@ void ath10k_debug_print_hwfw_info(struct ath10k *ar)
void ath10k_debug_print_board_info(struct ath10k *ar)
{
char boardinfo[100];
const struct firmware *board;
u32 crc;

if (ar->id.bmi_ids_valid)
scnprintf(boardinfo, sizeof(boardinfo), "%d:%d",
ar->id.bmi_chip_id, ar->id.bmi_board_id);
else
scnprintf(boardinfo, sizeof(boardinfo), "N/A");

board = ar->normal_mode_fw.board;
if (!IS_ERR_OR_NULL(board))
crc = crc32_le(0, board->data, board->size);
else
crc = 0;

ath10k_info(ar, "board_file api %d bmi_id %s crc32 %08x",
ar->bd_api,
boardinfo,
crc32_le(0, ar->normal_mode_fw.board->data,
ar->normal_mode_fw.board->size));
crc);
}

void ath10k_debug_print_boot_info(struct ath10k *ar)
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath10k/hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#define ATH10K_FW_DIR "ath10k"

#define QCA988X_2_0_DEVICE_ID_UBNT (0x11ac)
#define QCA988X_2_0_DEVICE_ID (0x003c)
#define QCA6164_2_1_DEVICE_ID (0x0041)
#define QCA6174_2_1_DEVICE_ID (0x003e)
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/wireless/ath/ath10k/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)");
#define ATH10K_DIAG_TRANSFER_LIMIT 0x5000

static const struct pci_device_id ath10k_pci_id_table[] = {
/* PCI-E QCA988X V2 (Ubiquiti branded) */
{ PCI_VDEVICE(UBIQUITI, QCA988X_2_0_DEVICE_ID_UBNT) },

{ PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */
{ PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */
{ PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */
Expand All @@ -74,6 +77,7 @@ static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = {
* hacks. ath10k doesn't have them and these devices crash horribly
* because of that.
*/
{ QCA988X_2_0_DEVICE_ID_UBNT, QCA988X_HW_2_0_CHIP_ID_REV },
{ QCA988X_2_0_DEVICE_ID, QCA988X_HW_2_0_CHIP_ID_REV },

{ QCA6164_2_1_DEVICE_ID, QCA6174_HW_2_1_CHIP_ID_REV },
Expand Down Expand Up @@ -2193,6 +2197,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);

switch (ar_pci->pdev->device) {
case QCA988X_2_0_DEVICE_ID_UBNT:
case QCA988X_2_0_DEVICE_ID:
case QCA99X0_2_0_DEVICE_ID:
case QCA9888_2_0_DEVICE_ID:
Expand Down Expand Up @@ -3424,6 +3429,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr);

switch (pci_dev->device) {
case QCA988X_2_0_DEVICE_ID_UBNT:
case QCA988X_2_0_DEVICE_ID:
hw_rev = ATH10K_HW_QCA988X;
pci_ps = false;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath9k/calib.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan,
s16 nf)
{
s8 noise = ath9k_hw_get_default_nf(ah, chan, 0);
s8 noise = ATH_DEFAULT_NOISE_FLOOR;

if (nf) {
s8 delta = nf - ATH9K_NF_CAL_NOISE_THRESH -
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath9k/hif_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ static const struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */
{ USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */
{ USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */
{ USB_DEVICE(0x07b8, 0x9271) }, /* Altai WA1011N-GU */
{ USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */
{ USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
{ USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
Expand Down
40 changes: 38 additions & 2 deletions drivers/net/wireless/mediatek/mt76/agg-rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,52 @@ mt76_rx_aggr_reorder_work(struct work_struct *work)
reorder_work.work);
struct mt76_dev *dev = tid->dev;
struct sk_buff_head frames;
int nframes;

__skb_queue_head_init(&frames);

local_bh_disable();

spin_lock(&tid->lock);
mt76_rx_aggr_check_release(tid, &frames);
nframes = tid->nframes;
spin_unlock(&tid->lock);

ieee80211_queue_delayed_work(tid->dev->hw, &tid->reorder_work, REORDER_TIMEOUT);
if (nframes)
ieee80211_queue_delayed_work(tid->dev->hw, &tid->reorder_work,
REORDER_TIMEOUT);
mt76_rx_complete(dev, &frames, -1);

local_bh_enable();
}

static void
mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
{
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
struct ieee80211_bar *bar = (struct ieee80211_bar *) skb->data;
struct mt76_wcid *wcid = status->wcid;
struct mt76_rx_tid *tid;
u16 seqno;

if (!ieee80211_is_ctl(bar->frame_control))
return;

if (!ieee80211_is_back_req(bar->frame_control))
return;

status->tid = le16_to_cpu(bar->control) >> 12;
seqno = le16_to_cpu(bar->start_seq_num) >> 4;
tid = rcu_dereference(wcid->aggr[status->tid]);
if (!tid)
return;

spin_lock_bh(&tid->lock);
mt76_rx_aggr_release_frames(tid, frames, seqno);
mt76_rx_aggr_release_head(tid, frames);
spin_unlock_bh(&tid->lock);
}

void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
{
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
Expand All @@ -126,9 +157,14 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
__skb_queue_tail(frames, skb);

sta = wcid_to_sta(wcid);
if (!sta || !status->aggr)
if (!sta)
return;

if (!status->aggr) {
mt76_rx_aggr_check_ctl(skb, frames);
return;
}

tid = rcu_dereference(wcid->aggr[status->tid]);
if (!tid)
return;
Expand Down
52 changes: 51 additions & 1 deletion drivers/net/wireless/mediatek/mt76/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
ieee80211_hw_set(hw, TX_AMSDU);
ieee80211_hw_set(hw, TX_FRAG_LIST);
ieee80211_hw_set(hw, MFP_CAPABLE);
ieee80211_hw_set(hw, AP_LINK_PS);

wiphy->flags |= WIPHY_FLAG_IBSS_RSN;

Expand Down Expand Up @@ -470,6 +471,53 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
return 0;
}

static void
mt76_check_ps(struct mt76_dev *dev, struct sk_buff *skb)
{
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_sta *sta;
struct mt76_wcid *wcid = status->wcid;
bool ps;

if (!wcid || !wcid->sta)
return;

sta = container_of((void *) wcid, struct ieee80211_sta, drv_priv);

if (!test_bit(MT_WCID_FLAG_CHECK_PS, &wcid->flags))
return;

if (ieee80211_is_pspoll(hdr->frame_control)) {
ieee80211_sta_pspoll(sta);
return;
}

if (ieee80211_has_morefrags(hdr->frame_control) ||
!(ieee80211_is_mgmt(hdr->frame_control) ||
ieee80211_is_data(hdr->frame_control)))
return;

ps = ieee80211_has_pm(hdr->frame_control);

if (ps && (ieee80211_is_data_qos(hdr->frame_control) ||
ieee80211_is_qos_nullfunc(hdr->frame_control)))
ieee80211_sta_uapsd_trigger(sta, status->tid);

if (!!test_bit(MT_WCID_FLAG_PS, &wcid->flags) == ps)
return;

if (ps) {
set_bit(MT_WCID_FLAG_PS, &wcid->flags);
mt76_stop_tx_queues(dev, sta, true);
} else {
clear_bit(MT_WCID_FLAG_PS, &wcid->flags);
}

ieee80211_sta_ps_transition(sta, ps);
dev->drv->sta_ps(dev, sta, ps);
}

void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
int queue)
{
Expand Down Expand Up @@ -498,8 +546,10 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q)

__skb_queue_head_init(&frames);

while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL)
while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) {
mt76_check_ps(dev, skb);
mt76_rx_aggr_reorder(skb, &frames);
}

mt76_rx_complete(dev, &frames, q);
}
10 changes: 10 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt76.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,18 @@ struct mt76_queue_ops {
void (*kick)(struct mt76_dev *dev, struct mt76_queue *q);
};

enum mt76_wcid_flags {
MT_WCID_FLAG_CHECK_PS,
MT_WCID_FLAG_PS,
};

struct mt76_wcid {
struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS];

struct work_struct aggr_work;

unsigned long flags;

u8 idx;
u8 hw_key_idx;

Expand Down Expand Up @@ -206,6 +213,9 @@ struct mt76_driver_ops {
struct sk_buff *skb);

void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q);

void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta,
bool ps);
};

struct mt76_channel_state {
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt76x2.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ void mt76x2_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q);
void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb);

void mt76x2_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps);

void mt76x2_update_channel(struct mt76_dev *mdev);

s8 mt76x2_tx_get_max_txpwr_adj(struct mt76x2_dev *dev,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/mediatek/mt76/mt76x2_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,7 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
.tx_complete_skb = mt76x2_tx_complete_skb,
.rx_skb = mt76x2_queue_rx_skb,
.rx_poll_complete = mt76x2_rx_poll_complete,
.sta_ps = mt76x2_sta_ps,
};
struct ieee80211_hw *hw;
struct mt76x2_dev *dev;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,

mt76x2_remove_hdr_pad(skb, pad_len);

if (rxinfo & MT_RXINFO_BA)
if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL))
status->aggr = true;

if (WARN_ON_ONCE(len > skb->len))
Expand Down
Loading

0 comments on commit e0c42c8

Please sign in to comment.