aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-09-26 23:21:46 -0400
committerDavid S. Miller <davem@davemloft.net>2017-09-26 23:21:46 -0400
commit20c62c797e85b589152970089eaf22a7d88d989a (patch)
treecf9ac0ca1db8b3d00939f26bbda0494e22e579ab
parent2760f5a34421bba937dafa29a9decdbad11d2718 (diff)
parent3e747fa18202896b5be66b88478352d5880fb8eb (diff)
Merge tag 'wireless-drivers-for-davem-2017-09-25' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers
Kalle Valo says: ==================== wireless-drivers fixes for 4.14 Quite a lot of fixes this time. Most notable is the brcmfmac fix for a CVE issue. iwlwifi * a couple of bugzilla bugs related to multicast handling * two fixes for WoWLAN bugs that were causing queue hangs and re-initialization problems * two fixes for potential uninitialized variable use reported by Dan Carpenter in relation to a recently introduced patch * a fix for buffer reordering in the newly supported 9000 device family * fix a race when starting aggregation * small fix for a recent patch to wake mac80211 queues * send non-bufferable management frames in the generic queue so they are not sent on queues that are under power-save ath10k * fix a PCI PM related gcc warning brcmfmac * CVE-2017-0786: add length check scan results from firmware * respect passive scan requests from user space qtnfmac * fix race in tx path when using multiple interfaces * cancel ongoing scan when removing the wireless interface ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c7
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c37
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/d3.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c62
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c8
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tt.c1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tx.c10
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/cfg80211.c9
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/cfg80211.h3
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/event.c2
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c9
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h2
17 files changed, 125 insertions, 46 deletions
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index bc1633945a56..195dafb98131 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -3396,9 +3396,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
3396 3396
3397MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table); 3397MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table);
3398 3398
3399#ifdef CONFIG_PM 3399static __maybe_unused int ath10k_pci_pm_suspend(struct device *dev)
3400
3401static int ath10k_pci_pm_suspend(struct device *dev)
3402{ 3400{
3403 struct ath10k *ar = dev_get_drvdata(dev); 3401 struct ath10k *ar = dev_get_drvdata(dev);
3404 int ret; 3402 int ret;
@@ -3414,7 +3412,7 @@ static int ath10k_pci_pm_suspend(struct device *dev)
3414 return ret; 3412 return ret;
3415} 3413}
3416 3414
3417static int ath10k_pci_pm_resume(struct device *dev) 3415static __maybe_unused int ath10k_pci_pm_resume(struct device *dev)
3418{ 3416{
3419 struct ath10k *ar = dev_get_drvdata(dev); 3417 struct ath10k *ar = dev_get_drvdata(dev);
3420 int ret; 3418 int ret;
@@ -3433,7 +3431,6 @@ static int ath10k_pci_pm_resume(struct device *dev)
3433static SIMPLE_DEV_PM_OPS(ath10k_pci_pm_ops, 3431static SIMPLE_DEV_PM_OPS(ath10k_pci_pm_ops,
3434 ath10k_pci_pm_suspend, 3432 ath10k_pci_pm_suspend,
3435 ath10k_pci_pm_resume); 3433 ath10k_pci_pm_resume);
3436#endif
3437 3434
3438static struct pci_driver ath10k_pci_driver = { 3435static struct pci_driver ath10k_pci_driver = {
3439 .name = "ath10k_pci", 3436 .name = "ath10k_pci",
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index aaed4ab503ad..4157c90ad973 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -980,7 +980,7 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
980 980
981 eth_broadcast_addr(params_le->bssid); 981 eth_broadcast_addr(params_le->bssid);
982 params_le->bss_type = DOT11_BSSTYPE_ANY; 982 params_le->bss_type = DOT11_BSSTYPE_ANY;
983 params_le->scan_type = 0; 983 params_le->scan_type = BRCMF_SCANTYPE_ACTIVE;
984 params_le->channel_num = 0; 984 params_le->channel_num = 0;
985 params_le->nprobes = cpu_to_le32(-1); 985 params_le->nprobes = cpu_to_le32(-1);
986 params_le->active_time = cpu_to_le32(-1); 986 params_le->active_time = cpu_to_le32(-1);
@@ -988,12 +988,9 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
988 params_le->home_time = cpu_to_le32(-1); 988 params_le->home_time = cpu_to_le32(-1);
989 memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le)); 989 memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
990 990
991 /* if request is null exit so it will be all channel broadcast scan */
992 if (!request)
993 return;
994
995 n_ssids = request->n_ssids; 991 n_ssids = request->n_ssids;
996 n_channels = request->n_channels; 992 n_channels = request->n_channels;
993
997 /* Copy channel array if applicable */ 994 /* Copy channel array if applicable */
998 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n", 995 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
999 n_channels); 996 n_channels);
@@ -1030,16 +1027,8 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
1030 ptr += sizeof(ssid_le); 1027 ptr += sizeof(ssid_le);
1031 } 1028 }
1032 } else { 1029 } else {
1033 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids); 1030 brcmf_dbg(SCAN, "Performing passive scan\n");
1034 if ((request->ssids) && request->ssids->ssid_len) { 1031 params_le->scan_type = BRCMF_SCANTYPE_PASSIVE;
1035 brcmf_dbg(SCAN, "SSID %s len=%d\n",
1036 params_le->ssid_le.SSID,
1037 request->ssids->ssid_len);
1038 params_le->ssid_le.SSID_len =
1039 cpu_to_le32(request->ssids->ssid_len);
1040 memcpy(&params_le->ssid_le.SSID, request->ssids->ssid,
1041 request->ssids->ssid_len);
1042 }
1043 } 1032 }
1044 /* Adding mask to channel numbers */ 1033 /* Adding mask to channel numbers */
1045 params_le->channel_num = 1034 params_le->channel_num =
@@ -3162,6 +3151,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3162 struct brcmf_cfg80211_info *cfg = ifp->drvr->config; 3151 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3163 s32 status; 3152 s32 status;
3164 struct brcmf_escan_result_le *escan_result_le; 3153 struct brcmf_escan_result_le *escan_result_le;
3154 u32 escan_buflen;
3165 struct brcmf_bss_info_le *bss_info_le; 3155 struct brcmf_bss_info_le *bss_info_le;
3166 struct brcmf_bss_info_le *bss = NULL; 3156 struct brcmf_bss_info_le *bss = NULL;
3167 u32 bi_length; 3157 u32 bi_length;
@@ -3181,11 +3171,23 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3181 3171
3182 if (status == BRCMF_E_STATUS_PARTIAL) { 3172 if (status == BRCMF_E_STATUS_PARTIAL) {
3183 brcmf_dbg(SCAN, "ESCAN Partial result\n"); 3173 brcmf_dbg(SCAN, "ESCAN Partial result\n");
3174 if (e->datalen < sizeof(*escan_result_le)) {
3175 brcmf_err("invalid event data length\n");
3176 goto exit;
3177 }
3184 escan_result_le = (struct brcmf_escan_result_le *) data; 3178 escan_result_le = (struct brcmf_escan_result_le *) data;
3185 if (!escan_result_le) { 3179 if (!escan_result_le) {
3186 brcmf_err("Invalid escan result (NULL pointer)\n"); 3180 brcmf_err("Invalid escan result (NULL pointer)\n");
3187 goto exit; 3181 goto exit;
3188 } 3182 }
3183 escan_buflen = le32_to_cpu(escan_result_le->buflen);
3184 if (escan_buflen > BRCMF_ESCAN_BUF_SIZE ||
3185 escan_buflen > e->datalen ||
3186 escan_buflen < sizeof(*escan_result_le)) {
3187 brcmf_err("Invalid escan buffer length: %d\n",
3188 escan_buflen);
3189 goto exit;
3190 }
3189 if (le16_to_cpu(escan_result_le->bss_count) != 1) { 3191 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3190 brcmf_err("Invalid bss_count %d: ignoring\n", 3192 brcmf_err("Invalid bss_count %d: ignoring\n",
3191 escan_result_le->bss_count); 3193 escan_result_le->bss_count);
@@ -3202,9 +3204,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3202 } 3204 }
3203 3205
3204 bi_length = le32_to_cpu(bss_info_le->length); 3206 bi_length = le32_to_cpu(bss_info_le->length);
3205 if (bi_length != (le32_to_cpu(escan_result_le->buflen) - 3207 if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
3206 WL_ESCAN_RESULTS_FIXED_SIZE)) { 3208 brcmf_err("Ignoring invalid bss_info length: %d\n",
3207 brcmf_err("Invalid bss_info length %d: ignoring\n",
3208 bi_length); 3209 bi_length);
3209 goto exit; 3210 goto exit;
3210 } 3211 }
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index 8391989b1882..e0d22fedb2b4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -45,6 +45,11 @@
45#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff 45#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
46#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 46#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
47 47
48/* scan type definitions */
49#define BRCMF_SCANTYPE_DEFAULT 0xFF
50#define BRCMF_SCANTYPE_ACTIVE 0
51#define BRCMF_SCANTYPE_PASSIVE 1
52
48#define BRCMF_WSEC_MAX_PSK_LEN 32 53#define BRCMF_WSEC_MAX_PSK_LEN 32
49#define BRCMF_WSEC_PASSPHRASE BIT(0) 54#define BRCMF_WSEC_PASSPHRASE BIT(0)
50 55
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 5de19ea10575..b205a7bfb828 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -2167,7 +2167,7 @@ out:
2167 * 1. We are not using a unified image 2167 * 1. We are not using a unified image
2168 * 2. We are using a unified image but had an error while exiting D3 2168 * 2. We are using a unified image but had an error while exiting D3
2169 */ 2169 */
2170 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); 2170 set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
2171 set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status); 2171 set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status);
2172 /* 2172 /*
2173 * When switching images we return 1, which causes mac80211 2173 * When switching images we return 1, which causes mac80211
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 15f2d826bb4b..3bcaa82f59b2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1546,6 +1546,11 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
1546 struct iwl_mvm_mc_iter_data *data = _data; 1546 struct iwl_mvm_mc_iter_data *data = _data;
1547 struct iwl_mvm *mvm = data->mvm; 1547 struct iwl_mvm *mvm = data->mvm;
1548 struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd; 1548 struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd;
1549 struct iwl_host_cmd hcmd = {
1550 .id = MCAST_FILTER_CMD,
1551 .flags = CMD_ASYNC,
1552 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
1553 };
1549 int ret, len; 1554 int ret, len;
1550 1555
1551 /* if we don't have free ports, mcast frames will be dropped */ 1556 /* if we don't have free ports, mcast frames will be dropped */
@@ -1560,7 +1565,10 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
1560 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); 1565 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
1561 len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4); 1566 len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
1562 1567
1563 ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd); 1568 hcmd.len[0] = len;
1569 hcmd.data[0] = cmd;
1570
1571 ret = iwl_mvm_send_cmd(mvm, &hcmd);
1564 if (ret) 1572 if (ret)
1565 IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret); 1573 IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
1566} 1574}
@@ -1635,6 +1643,12 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
1635 if (!cmd) 1643 if (!cmd)
1636 goto out; 1644 goto out;
1637 1645
1646 if (changed_flags & FIF_ALLMULTI)
1647 cmd->pass_all = !!(*total_flags & FIF_ALLMULTI);
1648
1649 if (cmd->pass_all)
1650 cmd->count = 0;
1651
1638 iwl_mvm_recalc_multicast(mvm); 1652 iwl_mvm_recalc_multicast(mvm);
1639out: 1653out:
1640 mutex_unlock(&mvm->mutex); 1654 mutex_unlock(&mvm->mutex);
@@ -2563,7 +2577,7 @@ static void iwl_mvm_purge_deferred_tx_frames(struct iwl_mvm *mvm,
2563 * queues, so we should never get a second deferred 2577 * queues, so we should never get a second deferred
2564 * frame for the RA/TID. 2578 * frame for the RA/TID.
2565 */ 2579 */
2566 iwl_mvm_start_mac_queues(mvm, info->hw_queue); 2580 iwl_mvm_start_mac_queues(mvm, BIT(info->hw_queue));
2567 ieee80211_free_txskb(mvm->hw, skb); 2581 ieee80211_free_txskb(mvm->hw, skb);
2568 } 2582 }
2569 } 2583 }
@@ -3975,6 +3989,43 @@ out_unlock:
3975 return ret; 3989 return ret;
3976} 3990}
3977 3991
3992static void iwl_mvm_flush_no_vif(struct iwl_mvm *mvm, u32 queues, bool drop)
3993{
3994 if (drop) {
3995 if (iwl_mvm_has_new_tx_api(mvm))
3996 /* TODO new tx api */
3997 WARN_ONCE(1,
3998 "Need to implement flush TX queue\n");
3999 else
4000 iwl_mvm_flush_tx_path(mvm,
4001 iwl_mvm_flushable_queues(mvm) & queues,
4002 0);
4003 } else {
4004 if (iwl_mvm_has_new_tx_api(mvm)) {
4005 struct ieee80211_sta *sta;
4006 int i;
4007
4008 mutex_lock(&mvm->mutex);
4009
4010 for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
4011 sta = rcu_dereference_protected(
4012 mvm->fw_id_to_mac_id[i],
4013 lockdep_is_held(&mvm->mutex));
4014 if (IS_ERR_OR_NULL(sta))
4015 continue;
4016
4017 iwl_mvm_wait_sta_queues_empty(mvm,
4018 iwl_mvm_sta_from_mac80211(sta));
4019 }
4020
4021 mutex_unlock(&mvm->mutex);
4022 } else {
4023 iwl_trans_wait_tx_queues_empty(mvm->trans,
4024 queues);
4025 }
4026 }
4027}
4028
3978static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, 4029static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
3979 struct ieee80211_vif *vif, u32 queues, bool drop) 4030 struct ieee80211_vif *vif, u32 queues, bool drop)
3980{ 4031{
@@ -3985,7 +4036,12 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
3985 int i; 4036 int i;
3986 u32 msk = 0; 4037 u32 msk = 0;
3987 4038
3988 if (!vif || vif->type != NL80211_IFTYPE_STATION) 4039 if (!vif) {
4040 iwl_mvm_flush_no_vif(mvm, queues, drop);
4041 return;
4042 }
4043
4044 if (vif->type != NL80211_IFTYPE_STATION)
3989 return; 4045 return;
3990 4046
3991 /* Make sure we're done with the deferred traffic before flushing */ 4047 /* Make sure we're done with the deferred traffic before flushing */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index ba7bd049d3d4..0fe723ca844e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -661,7 +661,8 @@ static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
661 (lq_sta->tx_agg_tid_en & BIT(tid)) && 661 (lq_sta->tx_agg_tid_en & BIT(tid)) &&
662 (tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) { 662 (tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) {
663 IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid); 663 IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid);
664 rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta); 664 if (rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta) == 0)
665 tid_data->state = IWL_AGG_QUEUED;
665 } 666 }
666} 667}
667 668
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 67ffd9774712..77f77bc5d083 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -672,11 +672,12 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
672 * If there was a significant jump in the nssn - adjust. 672 * If there was a significant jump in the nssn - adjust.
673 * If the SN is smaller than the NSSN it might need to first go into 673 * If the SN is smaller than the NSSN it might need to first go into
674 * the reorder buffer, in which case we just release up to it and the 674 * the reorder buffer, in which case we just release up to it and the
675 * rest of the function will take of storing it and releasing up to the 675 * rest of the function will take care of storing it and releasing up to
676 * nssn 676 * the nssn
677 */ 677 */
678 if (!iwl_mvm_is_sn_less(nssn, buffer->head_sn + buffer->buf_size, 678 if (!iwl_mvm_is_sn_less(nssn, buffer->head_sn + buffer->buf_size,
679 buffer->buf_size)) { 679 buffer->buf_size) ||
680 !ieee80211_sn_less(sn, buffer->head_sn + buffer->buf_size)) {
680 u16 min_sn = ieee80211_sn_less(sn, nssn) ? sn : nssn; 681 u16 min_sn = ieee80211_sn_less(sn, nssn) ? sn : nssn;
681 682
682 iwl_mvm_release_frames(mvm, sta, napi, buffer, min_sn); 683 iwl_mvm_release_frames(mvm, sta, napi, buffer, min_sn);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 50983615dce6..774122fed454 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -555,7 +555,7 @@ static int iwl_mvm_lmac_scan_abort(struct iwl_mvm *mvm)
555 struct iwl_host_cmd cmd = { 555 struct iwl_host_cmd cmd = {
556 .id = SCAN_OFFLOAD_ABORT_CMD, 556 .id = SCAN_OFFLOAD_ABORT_CMD,
557 }; 557 };
558 u32 status; 558 u32 status = CAN_ABORT_STATUS;
559 559
560 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status); 560 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
561 if (ret) 561 if (ret)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 411a2055dc45..c4a343534c5e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1285,7 +1285,7 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
1285{ 1285{
1286 struct iwl_mvm_add_sta_cmd cmd; 1286 struct iwl_mvm_add_sta_cmd cmd;
1287 int ret; 1287 int ret;
1288 u32 status; 1288 u32 status = ADD_STA_SUCCESS;
1289 1289
1290 lockdep_assert_held(&mvm->mutex); 1290 lockdep_assert_held(&mvm->mutex);
1291 1291
@@ -2385,8 +2385,10 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2385 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) 2385 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
2386 return -EINVAL; 2386 return -EINVAL;
2387 2387
2388 if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) { 2388 if (mvmsta->tid_data[tid].state != IWL_AGG_QUEUED &&
2389 IWL_ERR(mvm, "Start AGG when state is not IWL_AGG_OFF %d!\n", 2389 mvmsta->tid_data[tid].state != IWL_AGG_OFF) {
2390 IWL_ERR(mvm,
2391 "Start AGG when state is not IWL_AGG_QUEUED or IWL_AGG_OFF %d!\n",
2390 mvmsta->tid_data[tid].state); 2392 mvmsta->tid_data[tid].state);
2391 return -ENXIO; 2393 return -ENXIO;
2392 } 2394 }
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
index d13893806513..aedabe101cf0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
@@ -281,6 +281,7 @@ struct iwl_mvm_vif;
281 * These states relate to a specific RA / TID. 281 * These states relate to a specific RA / TID.
282 * 282 *
283 * @IWL_AGG_OFF: aggregation is not used 283 * @IWL_AGG_OFF: aggregation is not used
284 * @IWL_AGG_QUEUED: aggregation start work has been queued
284 * @IWL_AGG_STARTING: aggregation are starting (between start and oper) 285 * @IWL_AGG_STARTING: aggregation are starting (between start and oper)
285 * @IWL_AGG_ON: aggregation session is up 286 * @IWL_AGG_ON: aggregation session is up
286 * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the 287 * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the
@@ -290,6 +291,7 @@ struct iwl_mvm_vif;
290 */ 291 */
291enum iwl_mvm_agg_state { 292enum iwl_mvm_agg_state {
292 IWL_AGG_OFF = 0, 293 IWL_AGG_OFF = 0,
294 IWL_AGG_QUEUED,
293 IWL_AGG_STARTING, 295 IWL_AGG_STARTING,
294 IWL_AGG_ON, 296 IWL_AGG_ON,
295 IWL_EMPTYING_HW_QUEUE_ADDBA, 297 IWL_EMPTYING_HW_QUEUE_ADDBA,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index 8876c2abc440..4d907f60bce9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -529,6 +529,7 @@ int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 state)
529 529
530 lockdep_assert_held(&mvm->mutex); 530 lockdep_assert_held(&mvm->mutex);
531 531
532 status = 0;
532 ret = iwl_mvm_send_cmd_pdu_status(mvm, WIDE_ID(PHY_OPS_GROUP, 533 ret = iwl_mvm_send_cmd_pdu_status(mvm, WIDE_ID(PHY_OPS_GROUP,
533 CTDP_CONFIG_CMD), 534 CTDP_CONFIG_CMD),
534 sizeof(cmd), &cmd, &status); 535 sizeof(cmd), &cmd, &status);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 172b5e63d3fb..6f2e2af23219 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -564,8 +564,8 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm,
564 case NL80211_IFTYPE_AP: 564 case NL80211_IFTYPE_AP:
565 case NL80211_IFTYPE_ADHOC: 565 case NL80211_IFTYPE_ADHOC:
566 /* 566 /*
567 * Handle legacy hostapd as well, where station will be added 567 * Non-bufferable frames use the broadcast station, thus they
568 * only just before sending the association response. 568 * use the probe queue.
569 * Also take care of the case where we send a deauth to a 569 * Also take care of the case where we send a deauth to a
570 * station that we don't have, or similarly an association 570 * station that we don't have, or similarly an association
571 * response (with non-success status) for a station we can't 571 * response (with non-success status) for a station we can't
@@ -573,9 +573,9 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm,
573 * Also, disassociate frames might happen, particular with 573 * Also, disassociate frames might happen, particular with
574 * reason 7 ("Class 3 frame received from nonassociated STA"). 574 * reason 7 ("Class 3 frame received from nonassociated STA").
575 */ 575 */
576 if (ieee80211_is_probe_resp(fc) || ieee80211_is_auth(fc) || 576 if (ieee80211_is_mgmt(fc) &&
577 ieee80211_is_deauth(fc) || ieee80211_is_assoc_resp(fc) || 577 (!ieee80211_is_bufferable_mmpdu(fc) ||
578 ieee80211_is_disassoc(fc)) 578 ieee80211_is_deauth(fc) || ieee80211_is_disassoc(fc)))
579 return mvm->probe_queue; 579 return mvm->probe_queue;
580 if (info->hw_queue == info->control.vif->cab_queue) 580 if (info->hw_queue == info->control.vif->cab_queue)
581 return mvmvif->cab_queue; 581 return mvmvif->cab_queue;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 856fa6e8327e..a450bc6bc774 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -115,6 +115,8 @@ int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
115 115
116 vif = qtnf_netdev_get_priv(wdev->netdev); 116 vif = qtnf_netdev_get_priv(wdev->netdev);
117 117
118 qtnf_scan_done(vif->mac, true);
119
118 if (qtnf_cmd_send_del_intf(vif)) 120 if (qtnf_cmd_send_del_intf(vif))
119 pr_err("VIF%u.%u: failed to delete VIF\n", vif->mac->macid, 121 pr_err("VIF%u.%u: failed to delete VIF\n", vif->mac->macid,
120 vif->vifid); 122 vif->vifid);
@@ -335,6 +337,8 @@ static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev)
335 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); 337 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
336 int ret; 338 int ret;
337 339
340 qtnf_scan_done(vif->mac, true);
341
338 ret = qtnf_cmd_send_stop_ap(vif); 342 ret = qtnf_cmd_send_stop_ap(vif);
339 if (ret) { 343 if (ret) {
340 pr_err("VIF%u.%u: failed to stop AP operation in FW\n", 344 pr_err("VIF%u.%u: failed to stop AP operation in FW\n",
@@ -570,8 +574,6 @@ qtnf_del_station(struct wiphy *wiphy, struct net_device *dev,
570 !qtnf_sta_list_lookup(&vif->sta_list, params->mac)) 574 !qtnf_sta_list_lookup(&vif->sta_list, params->mac))
571 return 0; 575 return 0;
572 576
573 qtnf_scan_done(vif->mac, true);
574
575 ret = qtnf_cmd_send_del_sta(vif, params); 577 ret = qtnf_cmd_send_del_sta(vif, params);
576 if (ret) 578 if (ret)
577 pr_err("VIF%u.%u: failed to delete STA %pM\n", 579 pr_err("VIF%u.%u: failed to delete STA %pM\n",
@@ -1134,8 +1136,9 @@ void qtnf_virtual_intf_cleanup(struct net_device *ndev)
1134 } 1136 }
1135 1137
1136 vif->sta_state = QTNF_STA_DISCONNECTED; 1138 vif->sta_state = QTNF_STA_DISCONNECTED;
1137 qtnf_scan_done(mac, true);
1138 } 1139 }
1140
1141 qtnf_scan_done(mac, true);
1139} 1142}
1140 1143
1141void qtnf_cfg80211_vif_reset(struct qtnf_vif *vif) 1144void qtnf_cfg80211_vif_reset(struct qtnf_vif *vif)
diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.h b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.h
index 6a4af52522b8..66db26613b1f 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.h
@@ -34,6 +34,9 @@ static inline void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted)
34 .aborted = aborted, 34 .aborted = aborted,
35 }; 35 };
36 36
37 if (timer_pending(&mac->scan_timeout))
38 del_timer_sync(&mac->scan_timeout);
39
37 mutex_lock(&mac->mac_lock); 40 mutex_lock(&mac->mac_lock);
38 41
39 if (mac->scan_req) { 42 if (mac->scan_req) {
diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c
index 0fc2814eafad..43d2e7fd6e02 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
@@ -345,8 +345,6 @@ qtnf_event_handle_scan_complete(struct qtnf_wmac *mac,
345 return -EINVAL; 345 return -EINVAL;
346 } 346 }
347 347
348 if (timer_pending(&mac->scan_timeout))
349 del_timer_sync(&mac->scan_timeout);
350 qtnf_scan_done(mac, le32_to_cpu(status->flags) & QLINK_SCAN_ABORTED); 348 qtnf_scan_done(mac, le32_to_cpu(status->flags) & QLINK_SCAN_ABORTED);
351 349
352 return 0; 350 return 0;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c
index 502e72b7cdcc..69131965a298 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c
@@ -661,14 +661,18 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb)
661 struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); 661 struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus);
662 dma_addr_t txbd_paddr, skb_paddr; 662 dma_addr_t txbd_paddr, skb_paddr;
663 struct qtnf_tx_bd *txbd; 663 struct qtnf_tx_bd *txbd;
664 unsigned long flags;
664 int len, i; 665 int len, i;
665 u32 info; 666 u32 info;
666 int ret = 0; 667 int ret = 0;
667 668
669 spin_lock_irqsave(&priv->tx0_lock, flags);
670
668 if (!qtnf_tx_queue_ready(priv)) { 671 if (!qtnf_tx_queue_ready(priv)) {
669 if (skb->dev) 672 if (skb->dev)
670 netif_stop_queue(skb->dev); 673 netif_stop_queue(skb->dev);
671 674
675 spin_unlock_irqrestore(&priv->tx0_lock, flags);
672 return NETDEV_TX_BUSY; 676 return NETDEV_TX_BUSY;
673 } 677 }
674 678
@@ -717,8 +721,10 @@ tx_done:
717 dev_kfree_skb_any(skb); 721 dev_kfree_skb_any(skb);
718 } 722 }
719 723
720 qtnf_pcie_data_tx_reclaim(priv);
721 priv->tx_done_count++; 724 priv->tx_done_count++;
725 spin_unlock_irqrestore(&priv->tx0_lock, flags);
726
727 qtnf_pcie_data_tx_reclaim(priv);
722 728
723 return NETDEV_TX_OK; 729 return NETDEV_TX_OK;
724} 730}
@@ -1247,6 +1253,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1247 strcpy(bus->fwname, QTN_PCI_PEARL_FW_NAME); 1253 strcpy(bus->fwname, QTN_PCI_PEARL_FW_NAME);
1248 init_completion(&bus->request_firmware_complete); 1254 init_completion(&bus->request_firmware_complete);
1249 mutex_init(&bus->bus_lock); 1255 mutex_init(&bus->bus_lock);
1256 spin_lock_init(&pcie_priv->tx0_lock);
1250 spin_lock_init(&pcie_priv->irq_lock); 1257 spin_lock_init(&pcie_priv->irq_lock);
1251 spin_lock_init(&pcie_priv->tx_reclaim_lock); 1258 spin_lock_init(&pcie_priv->tx_reclaim_lock);
1252 1259
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h
index e76a23716ee0..86ac1ccedb52 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h
@@ -34,6 +34,8 @@ struct qtnf_pcie_bus_priv {
34 34
35 /* lock for tx reclaim operations */ 35 /* lock for tx reclaim operations */
36 spinlock_t tx_reclaim_lock; 36 spinlock_t tx_reclaim_lock;
37 /* lock for tx0 operations */
38 spinlock_t tx0_lock;
37 u8 msi_enabled; 39 u8 msi_enabled;
38 int mps; 40 int mps;
39 41