Commit e0c42c8e authored by David S. Miller's avatar David S. Miller

Merge tag 'wireless-drivers-next-for-davem-2018-02-08' of...

Merge tag 'wireless-drivers-next-for-davem-2018-02-08' of git://git.kernel.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: default avatarDavid S. Miller <davem@davemloft.net>
parents 55b3280d 99ffd198
...@@ -90,6 +90,35 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { ...@@ -90,6 +90,35 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.target_64bit = false, .target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, .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, .id = QCA9887_HW_1_0_VERSION,
.dev_id = QCA9887_1_0_DEVICE_ID, .dev_id = QCA9887_1_0_DEVICE_ID,
...@@ -1276,10 +1305,7 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar, ...@@ -1276,10 +1305,7 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
len -= sizeof(*hdr); len -= sizeof(*hdr);
data = hdr->data; data = hdr->data;
/* jump over the padding */ if (len < ALIGN(ie_len, 4)) {
ie_len = ALIGN(ie_len, 4);
if (len < ie_len) {
ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n", ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
ie_id, ie_len, len); ie_id, ie_len, len);
ret = -EINVAL; ret = -EINVAL;
...@@ -1318,6 +1344,9 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar, ...@@ -1318,6 +1344,9 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
goto out; goto out;
} }
/* jump over the padding */
ie_len = ALIGN(ie_len, 4);
len -= ie_len; len -= ie_len;
data += ie_len; data += ie_len;
} }
...@@ -1448,9 +1477,6 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name, ...@@ -1448,9 +1477,6 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
len -= sizeof(*hdr); len -= sizeof(*hdr);
data += sizeof(*hdr); data += sizeof(*hdr);
/* jump over the padding */
ie_len = ALIGN(ie_len, 4);
if (len < ie_len) { if (len < ie_len) {
ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n", ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
ie_id, len, ie_len); ie_id, len, ie_len);
...@@ -1556,6 +1582,9 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name, ...@@ -1556,6 +1582,9 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
break; break;
} }
/* jump over the padding */
ie_len = ALIGN(ie_len, 4);
len -= ie_len; len -= ie_len;
data += ie_len; data += ie_len;
} }
......
/* /*
* Copyright (c) 2011-2017 Qualcomm Atheros, 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 * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
...@@ -616,7 +617,7 @@ static const struct ath10k_mem_region qca6174_hw30_mem_regions[] = { ...@@ -616,7 +617,7 @@ static const struct ath10k_mem_region qca6174_hw30_mem_regions[] = {
{ {
.type = ATH10K_MEM_REGION_TYPE_DRAM, .type = ATH10K_MEM_REGION_TYPE_DRAM,
.start = 0x400000, .start = 0x400000,
.len = 0x90000, .len = 0xa8000,
.name = "DRAM", .name = "DRAM",
.section_table = { .section_table = {
.sections = NULL, .sections = NULL,
......
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, 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 * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
...@@ -81,6 +82,8 @@ void ath10k_debug_print_hwfw_info(struct ath10k *ar) ...@@ -81,6 +82,8 @@ void ath10k_debug_print_hwfw_info(struct ath10k *ar)
void ath10k_debug_print_board_info(struct ath10k *ar) void ath10k_debug_print_board_info(struct ath10k *ar)
{ {
char boardinfo[100]; char boardinfo[100];
const struct firmware *board;
u32 crc;
if (ar->id.bmi_ids_valid) if (ar->id.bmi_ids_valid)
scnprintf(boardinfo, sizeof(boardinfo), "%d:%d", scnprintf(boardinfo, sizeof(boardinfo), "%d:%d",
...@@ -88,11 +91,16 @@ void ath10k_debug_print_board_info(struct ath10k *ar) ...@@ -88,11 +91,16 @@ void ath10k_debug_print_board_info(struct ath10k *ar)
else else
scnprintf(boardinfo, sizeof(boardinfo), "N/A"); 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", ath10k_info(ar, "board_file api %d bmi_id %s crc32 %08x",
ar->bd_api, ar->bd_api,
boardinfo, boardinfo,
crc32_le(0, ar->normal_mode_fw.board->data, crc);
ar->normal_mode_fw.board->size));
} }
void ath10k_debug_print_boot_info(struct ath10k *ar) void ath10k_debug_print_boot_info(struct ath10k *ar)
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define ATH10K_FW_DIR "ath10k" #define ATH10K_FW_DIR "ath10k"
#define QCA988X_2_0_DEVICE_ID_UBNT (0x11ac)
#define QCA988X_2_0_DEVICE_ID (0x003c) #define QCA988X_2_0_DEVICE_ID (0x003c)
#define QCA6164_2_1_DEVICE_ID (0x0041) #define QCA6164_2_1_DEVICE_ID (0x0041)
#define QCA6174_2_1_DEVICE_ID (0x003e) #define QCA6174_2_1_DEVICE_ID (0x003e)
......
...@@ -58,6 +58,9 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)"); ...@@ -58,6 +58,9 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)");
#define ATH10K_DIAG_TRANSFER_LIMIT 0x5000 #define ATH10K_DIAG_TRANSFER_LIMIT 0x5000
static const struct pci_device_id ath10k_pci_id_table[] = { 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, 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, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */
{ PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */ { PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */
...@@ -74,6 +77,7 @@ static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = { ...@@ -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 * hacks. ath10k doesn't have them and these devices crash horribly
* because of that. * 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 }, { QCA988X_2_0_DEVICE_ID, QCA988X_HW_2_0_CHIP_ID_REV },
{ QCA6164_2_1_DEVICE_ID, QCA6174_HW_2_1_CHIP_ID_REV }, { QCA6164_2_1_DEVICE_ID, QCA6174_HW_2_1_CHIP_ID_REV },
...@@ -2193,6 +2197,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar) ...@@ -2193,6 +2197,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
switch (ar_pci->pdev->device) { switch (ar_pci->pdev->device) {
case QCA988X_2_0_DEVICE_ID_UBNT:
case QCA988X_2_0_DEVICE_ID: case QCA988X_2_0_DEVICE_ID:
case QCA99X0_2_0_DEVICE_ID: case QCA99X0_2_0_DEVICE_ID:
case QCA9888_2_0_DEVICE_ID: case QCA9888_2_0_DEVICE_ID:
...@@ -3424,6 +3429,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, ...@@ -3424,6 +3429,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr); u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr);
switch (pci_dev->device) { switch (pci_dev->device) {
case QCA988X_2_0_DEVICE_ID_UBNT:
case QCA988X_2_0_DEVICE_ID: case QCA988X_2_0_DEVICE_ID:
hw_rev = ATH10K_HW_QCA988X; hw_rev = ATH10K_HW_QCA988X;
pci_ps = false; pci_ps = false;
......
...@@ -72,7 +72,7 @@ static s16 ath9k_hw_get_default_nf(struct ath_hw *ah, ...@@ -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 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan,
s16 nf) s16 nf)
{ {
s8 noise = ath9k_hw_get_default_nf(ah, chan, 0); s8 noise = ATH_DEFAULT_NOISE_FLOOR;
if (nf) { if (nf) {
s8 delta = nf - ATH9K_NF_CAL_NOISE_THRESH - s8 delta = nf - ATH9K_NF_CAL_NOISE_THRESH -
......
...@@ -24,6 +24,7 @@ static const struct usb_device_id ath9k_hif_usb_ids[] = { ...@@ -24,6 +24,7 @@ static const struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */ { USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */
{ USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */ { USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */
{ USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */ { USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */
{ USB_DEVICE(0x07b8, 0x9271) }, /* Altai WA1011N-GU */
{ USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */ { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */
{ USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */ { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
{ USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */ { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
......
...@@ -98,6 +98,7 @@ mt76_rx_aggr_reorder_work(struct work_struct *work) ...@@ -98,6 +98,7 @@ mt76_rx_aggr_reorder_work(struct work_struct *work)
reorder_work.work); reorder_work.work);
struct mt76_dev *dev = tid->dev; struct mt76_dev *dev = tid->dev;
struct sk_buff_head frames; struct sk_buff_head frames;
int nframes;
__skb_queue_head_init(&frames); __skb_queue_head_init(&frames);
...@@ -105,14 +106,44 @@ mt76_rx_aggr_reorder_work(struct work_struct *work) ...@@ -105,14 +106,44 @@ mt76_rx_aggr_reorder_work(struct work_struct *work)
spin_lock(&tid->lock); spin_lock(&tid->lock);
mt76_rx_aggr_check_release(tid, &frames); mt76_rx_aggr_check_release(tid, &frames);
nframes = tid->nframes;
spin_unlock(&tid->lock); 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); mt76_rx_complete(dev, &frames, -1);
local_bh_enable(); 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) 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; struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
...@@ -126,9 +157,14 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames) ...@@ -126,9 +157,14 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
__skb_queue_tail(frames, skb); __skb_queue_tail(frames, skb);
sta = wcid_to_sta(wcid); sta = wcid_to_sta(wcid);
if (!sta || !status->aggr) if (!sta)
return; return;
if (!status->aggr) {
mt76_rx_aggr_check_ctl(skb, frames);
return;
}
tid = rcu_dereference(wcid->aggr[status->tid]); tid = rcu_dereference(wcid->aggr[status->tid]);
if (!tid) if (!tid)
return; return;
......
...@@ -276,6 +276,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht, ...@@ -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_AMSDU);
ieee80211_hw_set(hw, TX_FRAG_LIST); ieee80211_hw_set(hw, TX_FRAG_LIST);
ieee80211_hw_set(hw, MFP_CAPABLE); ieee80211_hw_set(hw, MFP_CAPABLE);
ieee80211_hw_set(hw, AP_LINK_PS);
wiphy->flags |= WIPHY_FLAG_IBSS_RSN; wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
...@@ -470,6 +471,53 @@ mt76_check_ccmp_pn(struct sk_buff *skb) ...@@ -470,6 +471,53 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
return 0; 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, void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
int queue) int queue)
{ {
...@@ -498,8 +546,10 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q) ...@@ -498,8 +546,10 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q)
__skb_queue_head_init(&frames); __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_aggr_reorder(skb, &frames);
}
mt76_rx_complete(dev, &frames, q); mt76_rx_complete(dev, &frames, q);
} }
...@@ -121,11 +121,18 @@ struct mt76_queue_ops { ...@@ -121,11 +121,18 @@ struct mt76_queue_ops {
void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); 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_wcid {
struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS]; struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS];
struct work_struct aggr_work; struct work_struct aggr_work;
unsigned long flags;
u8 idx; u8 idx;
u8 hw_key_idx; u8 hw_key_idx;
...@@ -206,6 +213,9 @@ struct mt76_driver_ops { ...@@ -206,6 +213,9 @@ struct mt76_driver_ops {
struct sk_buff *skb); struct sk_buff *skb);
void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); 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 { struct mt76_channel_state {
......
...@@ -218,6 +218,8 @@ void mt76x2_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q); ...@@ -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, void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb); 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); void mt76x2_update_channel(struct mt76_dev *mdev);
s8 mt76x2_tx_get_max_txpwr_adj(struct mt76x2_dev *dev, s8 mt76x2_tx_get_max_txpwr_adj(struct mt76x2_dev *dev,
......
...@@ -630,6 +630,7 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev) ...@@ -630,6 +630,7 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
.tx_complete_skb = mt76x2_tx_complete_skb, .tx_complete_skb = mt76x2_tx_complete_skb,
.rx_skb = mt76x2_queue_rx_skb, .rx_skb = mt76x2_queue_rx_skb,
.rx_poll_complete = mt76x2_rx_poll_complete, .rx_poll_complete = mt76x2_rx_poll_complete,
.sta_ps = mt76x2_sta_ps,
}; };
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct mt76x2_dev *dev; struct mt76x2_dev *dev;
......
...@@ -341,7 +341,7 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, ...@@ -341,7 +341,7 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
mt76x2_remove_hdr_pad(skb, pad_len); mt76x2_remove_hdr_pad(skb, pad_len);
if (rxinfo & MT_RXINFO_BA) if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL))
status->aggr = true; status->aggr = true;
if (WARN_ON_ONCE(len > skb->len)) if (WARN_ON_ONCE(len > skb->len))
......
...@@ -282,6 +282,9 @@ mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -282,6 +282,9 @@ mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
for (i = 0; i < ARRAY_SIZE(sta->txq); i++) for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
mt76x2_txq_init(dev, sta->txq[i]); mt76x2_txq_init(dev, sta->txq[i]);
if (vif->type == NL80211_IFTYPE_AP)
set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
rcu_assign_pointer(dev->wcid[idx], &msta->wcid); rcu_assign_pointer(dev->wcid[idx], &msta->wcid);
out: out:
...@@ -311,23 +314,14 @@ mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -311,23 +314,14 @@ mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
return 0; return 0;
} }
static void void
mt76x2_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
{ {
struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
struct mt76x2_dev *dev = hw->priv; struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
int idx = msta->wcid.idx; int idx = msta->wcid.idx;
switch (cmd) { mt76x2_mac_wcid_set_drop(dev, idx, ps);
case STA_NOTIFY_SLEEP:
mt76x2_mac_wcid_set_drop(dev, idx, true);
mt76_stop_tx_queues(&dev->mt76, sta, true);
break;
case STA_NOTIFY_AWAKE:
mt76x2_mac_wcid_set_drop(dev, idx, false);
break;
}
} }
static int static int
...@@ -549,6 +543,12 @@ static void mt76x2_set_coverage_class(struct ieee80211_hw *hw, ...@@ -549,6 +543,12 @@ static void mt76x2_set_coverage_class(struct ieee80211_hw *hw,
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
} }
static int
mt76x2_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
{
return 0;
}
const struct ieee80211_ops mt76x2_ops = { const struct ieee80211_ops mt76x2_ops = {
.tx = mt76x2_tx, .tx = mt76x2_tx,
.start = mt76x2_start, .start = mt76x2_start,
...@@ -560,7 +560,6 @@ const struct ieee80211_ops mt76x2_ops = { ...@@ -560,7 +560,6 @@ const struct ieee80211_ops mt76x2_ops = {
.bss_info_changed = mt76x2_bss_info_changed, .bss_info_changed = mt76x2_bss_info_changed,
.sta_add = mt76x2_sta_add, .sta_add = mt76x2_sta_add,
.sta_remove = mt76x2_sta_remove, .sta_remove = mt76x2_sta_remove,
.sta_notify = mt76x2_sta_notify,
.set_key = mt76x2_set_key, .set_key = mt76x2_set_key,
.conf_tx = mt76x2_conf_tx, .conf_tx = mt76x2_conf_tx,
.sw_scan_start = mt76x2_sw_scan, .sw_scan_start = mt76x2_sw_scan,
...@@ -573,5 +572,6 @@ const struct ieee80211_ops mt76x2_ops = { ...@@ -573,5 +572,6 @@ const struct ieee80211_ops mt76x2_ops = {
.release_buffered_frames = mt76_release_buffered_frames, .release_buffered_frames = mt76_release_buffered_frames,
.set_coverage_class = mt76x2_set_coverage_class, .set_coverage_class = mt76x2_set_coverage_class,
.get_survey = mt76_get_survey, .get_survey = mt76_get_survey,
.set_tim = mt76x2_set_tim,
}; };
...@@ -1123,7 +1123,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr) ...@@ -1123,7 +1123,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
} }
if (0 == tmp) { if (0 == tmp) {
read_addr = REG_DBI_RDATA + addr % 4; read_addr = REG_DBI_RDATA + addr % 4;
ret = rtl_read_word(rtlpriv, read_addr); ret = rtl_read_byte(rtlpriv, read_addr);
} }
return ret; return ret;
} }
...@@ -1165,7 +1165,8 @@ static void _rtl8821ae_enable_aspm_back_door(struct ieee80211_hw *hw) ...@@ -1165,7 +1165,8 @@ static void _rtl8821ae_enable_aspm_back_door(struct ieee80211_hw *hw)
} }
tmp = _rtl8821ae_dbi_read(rtlpriv, 0x70f); tmp = _rtl8821ae_dbi_read(rtlpriv, 0x70f);
_rtl8821ae_dbi_write(rtlpriv, 0x70f, tmp | BIT(7)); _rtl8821ae_dbi_write(rtlpriv, 0x70f, tmp | BIT(7) |
ASPM_L1_LATENCY << 3);
tmp = _rtl8821ae_dbi_read(rtlpriv, 0x719); tmp = _rtl8821ae_dbi_read(rtlpriv, 0x719);
_rtl8821ae_dbi_write(rtlpriv, 0x719, tmp | BIT(3) | BIT(4)); _rtl8821ae_dbi_write(rtlpriv, 0x719, tmp | BIT(3) | BIT(4));
......
...@@ -99,6 +99,7 @@ ...@@ -99,6 +99,7 @@
#define RTL_USB_MAX_RX_COUNT 100 #define RTL_USB_MAX_RX_COUNT 100
#define QBSS_LOAD_SIZE 5 #define QBSS_LOAD_SIZE 5
#define MAX_WMMELE_LENGTH 64 #define MAX_WMMELE_LENGTH 64
#define ASPM_L1_LATENCY 7
#define TOTAL_CAM_ENTRY 32 #define TOTAL_CAM_ENTRY 32
......
...@@ -31,7 +31,7 @@ config SSB_BLOCKIO ...@@ -31,7 +31,7 @@ config SSB_BLOCKIO
config SSB_PCIHOST_POSSIBLE config SSB_PCIHOST_POSSIBLE
bool bool
depends on SSB && (PCI = y || PCI = SSB) && PCI_DRIVERS_LEGACY depends on SSB && (PCI = y || PCI = SSB) && (PCI_DRIVERS_LEGACY || !MIPS)
default y default y
config SSB_PCIHOST config SSB_PCIHOST
......
...@@ -149,6 +149,8 @@ ...@@ -149,6 +149,8 @@
#define PCI_VENDOR_ID_DYNALINK 0x0675 #define PCI_VENDOR_ID_DYNALINK 0x0675
#define PCI_DEVICE_ID_DYNALINK_IS64PH 0x1702 #define PCI_DEVICE_ID_DYNALINK_IS64PH 0x1702
#define PCI_VENDOR_ID_UBIQUITI 0x0777
#define PCI_VENDOR_ID_BERKOM 0x0871 #define PCI_VENDOR_ID_BERKOM 0x0871
#define PCI_DEVICE_ID_BERKOM_A1T 0xffa1 #define PCI_DEVICE_ID_BERKOM_A1T 0xffa1
#define PCI_DEVICE_ID_BERKOM_T_CONCEPT 0xffa2 #define PCI_DEVICE_ID_BERKOM_T_CONCEPT 0xffa2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment