aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c17
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h27
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.c21
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h6
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c211
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c6
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c3
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c40
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c12
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c46
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c8
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c3
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c99
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h9
-rw-r--r--drivers/net/wireless/ath/wil6210/wil_platform.c14
-rw-r--r--drivers/net/wireless/ath/wil6210/wil_platform.h3
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c5
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h10
-rw-r--r--drivers/net/wireless/b43/main.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c315
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/commonring.c19
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/commonring.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/debug.c50
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/feature.c1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/feature.h4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/firmware.c50
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h79
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c12
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c203
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/pcie.c16
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c6
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/dma.c74
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/eeprom.c4
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/init.c3
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/mac.c8
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/main.c1
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/usb.c9
-rw-r--r--drivers/net/wireless/mwifiex/11h.c32
-rw-r--r--drivers/net/wireless/mwifiex/11n.c104
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c85
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c130
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c5
-rw-r--r--drivers/net/wireless/mwifiex/decl.h7
-rw-r--r--drivers/net/wireless/mwifiex/fw.h62
-rw-r--r--drivers/net/wireless/mwifiex/ie.c102
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h1
-rw-r--r--drivers/net/wireless/mwifiex/join.c30
-rw-r--r--drivers/net/wireless/mwifiex/main.h37
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c26
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c62
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c21
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c57
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c68
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c18
-rw-r--r--drivers/net/wireless/mwifiex/util.c56
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c57
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c16
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/dm.c7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c51
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/mac.c15
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/mac.h3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/phy.c28
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/rf.c22
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/dm.c7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.c7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/dm.c7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/dm.c14
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h1
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.c3
83 files changed, 1723 insertions, 894 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index bcccae19325d..59496a90ad5e 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -48,6 +48,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
48 .name = "qca988x hw2.0", 48 .name = "qca988x hw2.0",
49 .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, 49 .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
50 .uart_pin = 7, 50 .uart_pin = 7,
51 .has_shifted_cc_wraparound = true,
51 .fw = { 52 .fw = {
52 .dir = QCA988X_HW_2_0_FW_DIR, 53 .dir = QCA988X_HW_2_0_FW_DIR,
53 .fw = QCA988X_HW_2_0_FW_FILE, 54 .fw = QCA988X_HW_2_0_FW_FILE,
@@ -1084,6 +1085,22 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
1084 if (status) 1085 if (status)
1085 goto err; 1086 goto err;
1086 1087
1088 /* Some of of qca988x solutions are having global reset issue
1089 * during target initialization. Bypassing PLL setting before
1090 * downloading firmware and letting the SoC run on REF_CLK is
1091 * fixing the problem. Corresponding firmware change is also needed
1092 * to set the clock source once the target is initialized.
1093 */
1094 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,
1095 ar->fw_features)) {
1096 status = ath10k_bmi_write32(ar, hi_skip_clock_init, 1);
1097 if (status) {
1098 ath10k_err(ar, "could not write to skip_clock_init: %d\n",
1099 status);
1100 goto err;
1101 }
1102 }
1103
1087 status = ath10k_download_fw(ar, mode); 1104 status = ath10k_download_fw(ar, mode);
1088 if (status) 1105 if (status)
1089 goto err; 1106 goto err;
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 70fcdc9c2758..78094f23c9dd 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -284,15 +284,6 @@ struct ath10k_sta {
284#endif 284#endif
285}; 285};
286 286
287struct ath10k_chanctx {
288 /* Used to story copy of chanctx_conf to avoid inconsistencies. Ideally
289 * mac80211 should allow some sort of explicit locking to guarantee
290 * that the publicly available chanctx_conf can be accessed safely at
291 * all times.
292 */
293 struct ieee80211_chanctx_conf conf;
294};
295
296#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ) 287#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ)
297 288
298enum ath10k_beacon_state { 289enum ath10k_beacon_state {
@@ -468,6 +459,9 @@ enum ath10k_fw_features {
468 */ 459 */
469 ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING, 460 ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING,
470 461
462 /* Firmware supports bypassing PLL setting on init. */
463 ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT = 9,
464
471 /* keep last */ 465 /* keep last */
472 ATH10K_FW_FEATURE_COUNT, 466 ATH10K_FW_FEATURE_COUNT,
473}; 467};
@@ -577,6 +571,13 @@ struct ath10k {
577 u32 patch_load_addr; 571 u32 patch_load_addr;
578 int uart_pin; 572 int uart_pin;
579 573
574 /* This is true if given HW chip has a quirky Cycle Counter
575 * wraparound which resets to 0x7fffffff instead of 0. All
576 * other CC related counters (e.g. Rx Clear Count) are divided
577 * by 2 so they never wraparound themselves.
578 */
579 bool has_shifted_cc_wraparound;
580
580 struct ath10k_hw_params_fw { 581 struct ath10k_hw_params_fw {
581 const char *dir; 582 const char *dir;
582 const char *fw; 583 const char *fw;
@@ -694,6 +695,14 @@ struct ath10k {
694 u32 survey_last_cycle_count; 695 u32 survey_last_cycle_count;
695 struct survey_info survey[ATH10K_NUM_CHANS]; 696 struct survey_info survey[ATH10K_NUM_CHANS];
696 697
698 /* Channel info events are expected to come in pairs without and with
699 * COMPLETE flag set respectively for each channel visit during scan.
700 *
701 * However there are deviations from this rule. This flag is used to
702 * avoid reporting garbage data.
703 */
704 bool ch_info_can_report_survey;
705
697 struct dfs_pattern_detector *dfs_detector; 706 struct dfs_pattern_detector *dfs_detector;
698 707
699 unsigned long tx_paused; /* see ATH10K_TX_PAUSE_ */ 708 unsigned long tx_paused; /* see ATH10K_TX_PAUSE_ */
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
index 839a8791fb9e..5997f00afe3b 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include <linux/types.h> 17#include <linux/types.h>
18#include "core.h"
18#include "hw.h" 19#include "hw.h"
19 20
20const struct ath10k_hw_regs qca988x_regs = { 21const struct ath10k_hw_regs qca988x_regs = {
@@ -56,3 +57,23 @@ const struct ath10k_hw_regs qca6174_regs = {
56 .soc_chip_id_address = 0x000f0, 57 .soc_chip_id_address = 0x000f0,
57 .scratch_3_address = 0x0028, 58 .scratch_3_address = 0x0028,
58}; 59};
60
61void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
62 u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
63{
64 u32 cc_fix = 0;
65
66 survey->filled |= SURVEY_INFO_TIME |
67 SURVEY_INFO_TIME_BUSY;
68
69 if (ar->hw_params.has_shifted_cc_wraparound && cc < cc_prev) {
70 cc_fix = 0x7fffffff;
71 survey->filled &= ~SURVEY_INFO_TIME_BUSY;
72 }
73
74 cc -= cc_prev - cc_fix;
75 rcc -= rcc_prev;
76
77 survey->time = CCNT_TO_MSEC(cc);
78 survey->time_busy = CCNT_TO_MSEC(rcc);
79}
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 89e09cbeac19..85cca29375fe 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -169,6 +169,9 @@ struct ath10k_hw_regs {
169extern const struct ath10k_hw_regs qca988x_regs; 169extern const struct ath10k_hw_regs qca988x_regs;
170extern const struct ath10k_hw_regs qca6174_regs; 170extern const struct ath10k_hw_regs qca6174_regs;
171 171
172void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
173 u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev);
174
172#define QCA_REV_988X(ar) ((ar)->hw_rev == ATH10K_HW_QCA988X) 175#define QCA_REV_988X(ar) ((ar)->hw_rev == ATH10K_HW_QCA988X)
173#define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174) 176#define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174)
174 177
@@ -449,6 +452,9 @@ enum ath10k_hw_rate_cck {
449#define SCRATCH_3_ADDRESS ar->regs->scratch_3_address 452#define SCRATCH_3_ADDRESS ar->regs->scratch_3_address
450#define CPU_INTR_ADDRESS 0x0010 453#define CPU_INTR_ADDRESS 0x0010
451 454
455/* Cycle counters are running at 88MHz */
456#define CCNT_TO_MSEC(x) ((x) / 88000)
457
452/* Firmware indications to the Host via SCRATCH_3 register. */ 458/* Firmware indications to the Host via SCRATCH_3 register. */
453#define FW_INDICATOR_ADDRESS (SOC_CORE_BASE_ADDRESS + SCRATCH_3_ADDRESS) 459#define FW_INDICATOR_ADDRESS (SOC_CORE_BASE_ADDRESS + SCRATCH_3_ADDRESS)
454#define FW_IND_EVENT_PENDING 1 460#define FW_IND_EVENT_PENDING 1
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 609ca8619ebd..218b6af63447 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3949,83 +3949,6 @@ static int ath10k_config_ps(struct ath10k *ar)
3949 return ret; 3949 return ret;
3950} 3950}
3951 3951
3952static void ath10k_mac_chan_reconfigure(struct ath10k *ar)
3953{
3954 struct ath10k_vif *arvif;
3955 struct cfg80211_chan_def def;
3956 int ret;
3957
3958 lockdep_assert_held(&ar->conf_mutex);
3959
3960 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac chan reconfigure\n");
3961
3962 /* First stop monitor interface. Some FW versions crash if there's a
3963 * lone monitor interface. */
3964 if (ar->monitor_started)
3965 ath10k_monitor_stop(ar);
3966
3967 list_for_each_entry(arvif, &ar->arvifs, list) {
3968 if (!arvif->is_started)
3969 continue;
3970
3971 if (!arvif->is_up)
3972 continue;
3973
3974 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
3975 continue;
3976
3977 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
3978 if (ret) {
3979 ath10k_warn(ar, "failed to down vdev %d: %d\n",
3980 arvif->vdev_id, ret);
3981 continue;
3982 }
3983 }
3984
3985 /* all vdevs are downed now - attempt to restart and re-up them */
3986
3987 list_for_each_entry(arvif, &ar->arvifs, list) {
3988 if (!arvif->is_started)
3989 continue;
3990
3991 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
3992 continue;
3993
3994 ret = ath10k_mac_setup_bcn_tmpl(arvif);
3995 if (ret)
3996 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
3997 ret);
3998
3999 ret = ath10k_mac_setup_prb_tmpl(arvif);
4000 if (ret)
4001 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
4002 ret);
4003
4004 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
4005 continue;
4006
4007 ret = ath10k_vdev_restart(arvif, &def);
4008 if (ret) {
4009 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
4010 arvif->vdev_id, ret);
4011 continue;
4012 }
4013
4014 if (!arvif->is_up)
4015 continue;
4016
4017 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
4018 arvif->bssid);
4019 if (ret) {
4020 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
4021 arvif->vdev_id, ret);
4022 continue;
4023 }
4024 }
4025
4026 ath10k_monitor_recalc(ar);
4027}
4028
4029static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower) 3952static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4030{ 3953{
4031 int ret; 3954 int ret;
@@ -6144,7 +6067,10 @@ static int ath10k_ampdu_action(struct ieee80211_hw *hw,
6144} 6067}
6145 6068
6146static void 6069static void
6147ath10k_mac_update_rx_channel(struct ath10k *ar) 6070ath10k_mac_update_rx_channel(struct ath10k *ar,
6071 struct ieee80211_chanctx_conf *ctx,
6072 struct ieee80211_vif_chanctx_switch *vifs,
6073 int n_vifs)
6148{ 6074{
6149 struct cfg80211_chan_def *def = NULL; 6075 struct cfg80211_chan_def *def = NULL;
6150 6076
@@ -6154,6 +6080,9 @@ ath10k_mac_update_rx_channel(struct ath10k *ar)
6154 lockdep_assert_held(&ar->conf_mutex); 6080 lockdep_assert_held(&ar->conf_mutex);
6155 lockdep_assert_held(&ar->data_lock); 6081 lockdep_assert_held(&ar->data_lock);
6156 6082
6083 WARN_ON(ctx && vifs);
6084 WARN_ON(vifs && n_vifs != 1);
6085
6157 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are 6086 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
6158 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each 6087 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
6159 * ppdu on Rx may reduce performance on low-end systems. It should be 6088 * ppdu on Rx may reduce performance on low-end systems. It should be
@@ -6165,36 +6094,28 @@ ath10k_mac_update_rx_channel(struct ath10k *ar)
6165 * affected much. 6094 * affected much.
6166 */ 6095 */
6167 rcu_read_lock(); 6096 rcu_read_lock();
6168 if (ath10k_mac_num_chanctxs(ar) == 1) { 6097 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
6169 ieee80211_iter_chan_contexts_atomic(ar->hw, 6098 ieee80211_iter_chan_contexts_atomic(ar->hw,
6170 ath10k_mac_get_any_chandef_iter, 6099 ath10k_mac_get_any_chandef_iter,
6171 &def); 6100 &def);
6101
6102 if (vifs)
6103 def = &vifs[0].new_ctx->def;
6104
6172 ar->rx_channel = def->chan; 6105 ar->rx_channel = def->chan;
6106 } else if (ctx && ath10k_mac_num_chanctxs(ar) == 0) {
6107 ar->rx_channel = ctx->def.chan;
6173 } else { 6108 } else {
6174 ar->rx_channel = NULL; 6109 ar->rx_channel = NULL;
6175 } 6110 }
6176 rcu_read_unlock(); 6111 rcu_read_unlock();
6177} 6112}
6178 6113
6179static void
6180ath10k_mac_chan_ctx_init(struct ath10k *ar,
6181 struct ath10k_chanctx *arctx,
6182 struct ieee80211_chanctx_conf *conf)
6183{
6184 lockdep_assert_held(&ar->conf_mutex);
6185 lockdep_assert_held(&ar->data_lock);
6186
6187 memset(arctx, 0, sizeof(*arctx));
6188
6189 arctx->conf = *conf;
6190}
6191
6192static int 6114static int
6193ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw, 6115ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
6194 struct ieee80211_chanctx_conf *ctx) 6116 struct ieee80211_chanctx_conf *ctx)
6195{ 6117{
6196 struct ath10k *ar = hw->priv; 6118 struct ath10k *ar = hw->priv;
6197 struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
6198 6119
6199 ath10k_dbg(ar, ATH10K_DBG_MAC, 6120 ath10k_dbg(ar, ATH10K_DBG_MAC,
6200 "mac chanctx add freq %hu width %d ptr %p\n", 6121 "mac chanctx add freq %hu width %d ptr %p\n",
@@ -6203,8 +6124,7 @@ ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
6203 mutex_lock(&ar->conf_mutex); 6124 mutex_lock(&ar->conf_mutex);
6204 6125
6205 spin_lock_bh(&ar->data_lock); 6126 spin_lock_bh(&ar->data_lock);
6206 ath10k_mac_chan_ctx_init(ar, arctx, ctx); 6127 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
6207 ath10k_mac_update_rx_channel(ar);
6208 spin_unlock_bh(&ar->data_lock); 6128 spin_unlock_bh(&ar->data_lock);
6209 6129
6210 ath10k_recalc_radar_detection(ar); 6130 ath10k_recalc_radar_detection(ar);
@@ -6228,7 +6148,7 @@ ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
6228 mutex_lock(&ar->conf_mutex); 6148 mutex_lock(&ar->conf_mutex);
6229 6149
6230 spin_lock_bh(&ar->data_lock); 6150 spin_lock_bh(&ar->data_lock);
6231 ath10k_mac_update_rx_channel(ar); 6151 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
6232 spin_unlock_bh(&ar->data_lock); 6152 spin_unlock_bh(&ar->data_lock);
6233 6153
6234 ath10k_recalc_radar_detection(ar); 6154 ath10k_recalc_radar_detection(ar);
@@ -6243,16 +6163,12 @@ ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
6243 u32 changed) 6163 u32 changed)
6244{ 6164{
6245 struct ath10k *ar = hw->priv; 6165 struct ath10k *ar = hw->priv;
6246 struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
6247 6166
6248 mutex_lock(&ar->conf_mutex); 6167 mutex_lock(&ar->conf_mutex);
6249 6168
6250 ath10k_dbg(ar, ATH10K_DBG_MAC, 6169 ath10k_dbg(ar, ATH10K_DBG_MAC,
6251 "mac chanctx change freq %hu->%hu width %d->%d ptr %p changed %x\n", 6170 "mac chanctx change freq %hu width %d ptr %p changed %x\n",
6252 arctx->conf.def.chan->center_freq, 6171 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
6253 ctx->def.chan->center_freq,
6254 arctx->conf.def.width, ctx->def.width,
6255 ctx, changed);
6256 6172
6257 /* This shouldn't really happen because channel switching should use 6173 /* This shouldn't really happen because channel switching should use
6258 * switch_vif_chanctx(). 6174 * switch_vif_chanctx().
@@ -6260,10 +6176,6 @@ ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
6260 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL)) 6176 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
6261 goto unlock; 6177 goto unlock;
6262 6178
6263 spin_lock_bh(&ar->data_lock);
6264 arctx->conf = *ctx;
6265 spin_unlock_bh(&ar->data_lock);
6266
6267 ath10k_recalc_radar_detection(ar); 6179 ath10k_recalc_radar_detection(ar);
6268 6180
6269 /* FIXME: How to configure Rx chains properly? */ 6181 /* FIXME: How to configure Rx chains properly? */
@@ -6283,7 +6195,6 @@ ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
6283 struct ieee80211_chanctx_conf *ctx) 6195 struct ieee80211_chanctx_conf *ctx)
6284{ 6196{
6285 struct ath10k *ar = hw->priv; 6197 struct ath10k *ar = hw->priv;
6286 struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
6287 struct ath10k_vif *arvif = (void *)vif->drv_priv; 6198 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6288 int ret; 6199 int ret;
6289 6200
@@ -6298,11 +6209,11 @@ ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
6298 return -EBUSY; 6209 return -EBUSY;
6299 } 6210 }
6300 6211
6301 ret = ath10k_vdev_start(arvif, &arctx->conf.def); 6212 ret = ath10k_vdev_start(arvif, &ctx->def);
6302 if (ret) { 6213 if (ret) {
6303 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n", 6214 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
6304 arvif->vdev_id, vif->addr, 6215 arvif->vdev_id, vif->addr,
6305 arctx->conf.def.chan->center_freq, ret); 6216 ctx->def.chan->center_freq, ret);
6306 goto err; 6217 goto err;
6307 } 6218 }
6308 6219
@@ -6377,7 +6288,7 @@ ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
6377{ 6288{
6378 struct ath10k *ar = hw->priv; 6289 struct ath10k *ar = hw->priv;
6379 struct ath10k_vif *arvif; 6290 struct ath10k_vif *arvif;
6380 struct ath10k_chanctx *arctx_new, *arctx_old; 6291 int ret;
6381 int i; 6292 int i;
6382 6293
6383 mutex_lock(&ar->conf_mutex); 6294 mutex_lock(&ar->conf_mutex);
@@ -6386,38 +6297,81 @@ ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
6386 "mac chanctx switch n_vifs %d mode %d\n", 6297 "mac chanctx switch n_vifs %d mode %d\n",
6387 n_vifs, mode); 6298 n_vifs, mode);
6388 6299
6389 spin_lock_bh(&ar->data_lock); 6300 /* First stop monitor interface. Some FW versions crash if there's a
6301 * lone monitor interface.
6302 */
6303 if (ar->monitor_started)
6304 ath10k_monitor_stop(ar);
6305
6390 for (i = 0; i < n_vifs; i++) { 6306 for (i = 0; i < n_vifs; i++) {
6391 arvif = ath10k_vif_to_arvif(vifs[i].vif); 6307 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6392 arctx_new = (void *)vifs[i].new_ctx->drv_priv;
6393 arctx_old = (void *)vifs[i].old_ctx->drv_priv;
6394 6308
6395 ath10k_dbg(ar, ATH10K_DBG_MAC, 6309 ath10k_dbg(ar, ATH10K_DBG_MAC,
6396 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d ptr %p->%p\n", 6310 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
6397 arvif->vdev_id, 6311 arvif->vdev_id,
6398 vifs[i].old_ctx->def.chan->center_freq, 6312 vifs[i].old_ctx->def.chan->center_freq,
6399 vifs[i].new_ctx->def.chan->center_freq, 6313 vifs[i].new_ctx->def.chan->center_freq,
6400 vifs[i].old_ctx->def.width, 6314 vifs[i].old_ctx->def.width,
6401 vifs[i].new_ctx->def.width, 6315 vifs[i].new_ctx->def.width);
6402 arctx_old, arctx_new);
6403 6316
6404 if (mode == CHANCTX_SWMODE_SWAP_CONTEXTS) { 6317 if (WARN_ON(!arvif->is_started))
6405 ath10k_mac_chan_ctx_init(ar, arctx_new, 6318 continue;
6406 vifs[i].new_ctx);
6407 }
6408 6319
6409 arctx_new->conf = *vifs[i].new_ctx; 6320 if (WARN_ON(!arvif->is_up))
6321 continue;
6410 6322
6411 /* FIXME: ath10k_mac_chan_reconfigure() uses current, i.e. not 6323 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
6412 * yet updated chanctx_conf pointer. 6324 if (ret) {
6413 */ 6325 ath10k_warn(ar, "failed to down vdev %d: %d\n",
6414 arctx_old->conf = *vifs[i].new_ctx; 6326 arvif->vdev_id, ret);
6327 continue;
6328 }
6415 } 6329 }
6416 ath10k_mac_update_rx_channel(ar); 6330
6331 /* All relevant vdevs are downed and associated channel resources
6332 * should be available for the channel switch now.
6333 */
6334
6335 spin_lock_bh(&ar->data_lock);
6336 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
6417 spin_unlock_bh(&ar->data_lock); 6337 spin_unlock_bh(&ar->data_lock);
6418 6338
6419 /* FIXME: Reconfigure only affected vifs */ 6339 for (i = 0; i < n_vifs; i++) {
6420 ath10k_mac_chan_reconfigure(ar); 6340 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6341
6342 if (WARN_ON(!arvif->is_started))
6343 continue;
6344
6345 if (WARN_ON(!arvif->is_up))
6346 continue;
6347
6348 ret = ath10k_mac_setup_bcn_tmpl(arvif);
6349 if (ret)
6350 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
6351 ret);
6352
6353 ret = ath10k_mac_setup_prb_tmpl(arvif);
6354 if (ret)
6355 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
6356 ret);
6357
6358 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
6359 if (ret) {
6360 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
6361 arvif->vdev_id, ret);
6362 continue;
6363 }
6364
6365 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
6366 arvif->bssid);
6367 if (ret) {
6368 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
6369 arvif->vdev_id, ret);
6370 continue;
6371 }
6372 }
6373
6374 ath10k_monitor_recalc(ar);
6421 6375
6422 mutex_unlock(&ar->conf_mutex); 6376 mutex_unlock(&ar->conf_mutex);
6423 return 0; 6377 return 0;
@@ -6914,7 +6868,6 @@ int ath10k_mac_register(struct ath10k *ar)
6914 6868
6915 ar->hw->vif_data_size = sizeof(struct ath10k_vif); 6869 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
6916 ar->hw->sta_data_size = sizeof(struct ath10k_sta); 6870 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
6917 ar->hw->chanctx_data_size = sizeof(struct ath10k_chanctx);
6918 6871
6919 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL; 6872 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
6920 6873
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 17a060e8efa2..ea656e011a96 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1424,7 +1424,6 @@ static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe)
1424 struct ath10k_ce_ring *ce_ring; 1424 struct ath10k_ce_ring *ce_ring;
1425 struct ce_desc *ce_desc; 1425 struct ce_desc *ce_desc;
1426 struct sk_buff *skb; 1426 struct sk_buff *skb;
1427 unsigned int id;
1428 int i; 1427 int i;
1429 1428
1430 ar = pci_pipe->hif_ce_state; 1429 ar = pci_pipe->hif_ce_state;
@@ -1448,8 +1447,6 @@ static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe)
1448 continue; 1447 continue;
1449 1448
1450 ce_ring->per_transfer_context[i] = NULL; 1449 ce_ring->per_transfer_context[i] = NULL;
1451 id = MS(__le16_to_cpu(ce_desc[i].flags),
1452 CE_DESC_FLAGS_META_DATA);
1453 1450
1454 ar_pci->msg_callbacks_current.tx_completion(ar, skb); 1451 ar_pci->msg_callbacks_current.tx_completion(ar, skb);
1455 } 1452 }
@@ -2850,6 +2847,7 @@ err_free_pipes:
2850 ath10k_pci_free_pipes(ar); 2847 ath10k_pci_free_pipes(ar);
2851 2848
2852err_sleep: 2849err_sleep:
2850 ath10k_pci_sleep_sync(ar);
2853 ath10k_pci_release(ar); 2851 ath10k_pci_release(ar);
2854 2852
2855err_core_destroy: 2853err_core_destroy:
@@ -2927,8 +2925,10 @@ MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE);
2927 2925
2928/* QCA6174 2.1 firmware files */ 2926/* QCA6174 2.1 firmware files */
2929MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" ATH10K_FW_API4_FILE); 2927MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" ATH10K_FW_API4_FILE);
2928MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" ATH10K_FW_API5_FILE);
2930MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" QCA6174_HW_2_1_BOARD_DATA_FILE); 2929MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" QCA6174_HW_2_1_BOARD_DATA_FILE);
2931 2930
2932/* QCA6174 3.1 firmware files */ 2931/* QCA6174 3.1 firmware files */
2933MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_FW_API4_FILE); 2932MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_FW_API4_FILE);
2933MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_FW_API5_FILE);
2934MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" QCA6174_HW_3_0_BOARD_DATA_FILE); 2934MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" QCA6174_HW_3_0_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 563fde73623c..8fdba3865c96 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -402,7 +402,7 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
402 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 402 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
403 403
404 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 404 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
405 return; 405 goto out;
406 406
407 trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 407 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
408 408
@@ -521,6 +521,7 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
521 break; 521 break;
522 } 522 }
523 523
524out:
524 dev_kfree_skb(skb); 525 dev_kfree_skb(skb);
525} 526}
526 527
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 0fabe689179c..6c046c244705 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -27,6 +27,7 @@
27#include "testmode.h" 27#include "testmode.h"
28#include "wmi-ops.h" 28#include "wmi-ops.h"
29#include "p2p.h" 29#include "p2p.h"
30#include "hw.h"
30 31
31/* MAIN WMI cmd track */ 32/* MAIN WMI cmd track */
32static struct wmi_cmd_map wmi_cmd_map = { 33static struct wmi_cmd_map wmi_cmd_map = {
@@ -1450,6 +1451,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1450 ret = ath10k_wmi_pull_mgmt_rx(ar, skb, &arg); 1451 ret = ath10k_wmi_pull_mgmt_rx(ar, skb, &arg);
1451 if (ret) { 1452 if (ret) {
1452 ath10k_warn(ar, "failed to parse mgmt rx event: %d\n", ret); 1453 ath10k_warn(ar, "failed to parse mgmt rx event: %d\n", ret);
1454 dev_kfree_skb(skb);
1453 return ret; 1455 return ret;
1454 } 1456 }
1455 1457
@@ -1636,20 +1638,22 @@ void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb)
1636 } 1638 }
1637 1639
1638 if (cmd_flags & WMI_CHAN_INFO_FLAG_COMPLETE) { 1640 if (cmd_flags & WMI_CHAN_INFO_FLAG_COMPLETE) {
1639 /* During scanning chan info is reported twice for each 1641 if (ar->ch_info_can_report_survey) {
1640 * visited channel. The reported cycle count is global 1642 survey = &ar->survey[idx];
1641 * and per-channel cycle count must be calculated */ 1643 survey->noise = noise_floor;
1642 1644 survey->filled = SURVEY_INFO_NOISE_DBM;
1643 cycle_count -= ar->survey_last_cycle_count; 1645
1644 rx_clear_count -= ar->survey_last_rx_clear_count; 1646 ath10k_hw_fill_survey_time(ar,
1645 1647 survey,
1646 survey = &ar->survey[idx]; 1648 cycle_count,
1647 survey->time = WMI_CHAN_INFO_MSEC(cycle_count); 1649 rx_clear_count,
1648 survey->time_busy = WMI_CHAN_INFO_MSEC(rx_clear_count); 1650 ar->survey_last_cycle_count,
1649 survey->noise = noise_floor; 1651 ar->survey_last_rx_clear_count);
1650 survey->filled = SURVEY_INFO_TIME | 1652 }
1651 SURVEY_INFO_TIME_BUSY | 1653
1652 SURVEY_INFO_NOISE_DBM; 1654 ar->ch_info_can_report_survey = false;
1655 } else {
1656 ar->ch_info_can_report_survey = true;
1653 } 1657 }
1654 1658
1655 ar->survey_last_rx_clear_count = rx_clear_count; 1659 ar->survey_last_rx_clear_count = rx_clear_count;
@@ -3219,7 +3223,7 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
3219 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 3223 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
3220 3224
3221 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 3225 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
3222 return; 3226 goto out;
3223 3227
3224 trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 3228 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
3225 3229
@@ -3323,6 +3327,7 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
3323 break; 3327 break;
3324 } 3328 }
3325 3329
3330out:
3326 dev_kfree_skb(skb); 3331 dev_kfree_skb(skb);
3327} 3332}
3328 3333
@@ -3336,7 +3341,7 @@ static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb)
3336 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 3341 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
3337 3342
3338 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 3343 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
3339 return; 3344 goto out;
3340 3345
3341 trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 3346 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
3342 3347
@@ -3459,7 +3464,7 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
3459 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 3464 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
3460 3465
3461 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 3466 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
3462 return; 3467 goto out;
3463 3468
3464 trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 3469 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
3465 3470
@@ -3567,6 +3572,7 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
3567 break; 3572 break;
3568 } 3573 }
3569 3574
3575out:
3570 dev_kfree_skb(skb); 3576 dev_kfree_skb(skb);
3571} 3577}
3572 3578
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index cad72ae76253..cf44a3d080a3 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4665,7 +4665,6 @@ struct wmi_peer_sta_kickout_event {
4665} __packed; 4665} __packed;
4666 4666
4667#define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0) 4667#define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0)
4668#define WMI_CHAN_INFO_MSEC(x) ((x) / 88000)
4669 4668
4670/* Beacon filter wmi command info */ 4669/* Beacon filter wmi command info */
4671#define BCN_FLT_MAX_SUPPORTED_IES 256 4670#define BCN_FLT_MAX_SUPPORTED_IES 256
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 19f88b4a24fb..05d25a94c781 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -1527,8 +1527,8 @@ struct wmi_connect_event {
1527 __le32 nw_type; 1527 __le32 nw_type;
1528 } sta; 1528 } sta;
1529 struct { 1529 struct {
1530 u8 phymode;
1531 u8 aid; 1530 u8 aid;
1531 u8 phymode;
1532 u8 mac_addr[ETH_ALEN]; 1532 u8 mac_addr[ETH_ALEN];
1533 u8 auth; 1533 u8 auth;
1534 u8 keymgmt; 1534 u8 keymgmt;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 5dbc617ecf8a..16dff4b89a86 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -531,6 +531,7 @@ struct ath9k_htc_priv {
531 struct ath9k_debug debug; 531 struct ath9k_debug debug;
532#endif 532#endif
533 struct mutex mutex; 533 struct mutex mutex;
534 struct ieee80211_vif *csa_vif;
534}; 535};
535 536
536static inline void ath_read_cachesize(struct ath_common *common, int *csz) 537static inline void ath_read_cachesize(struct ath_common *common, int *csz)
@@ -584,6 +585,7 @@ void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv);
584void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event); 585void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event);
585void ath9k_tx_failed_tasklet(unsigned long data); 586void ath9k_tx_failed_tasklet(unsigned long data);
586void ath9k_htc_tx_cleanup_timer(unsigned long data); 587void ath9k_htc_tx_cleanup_timer(unsigned long data);
588bool ath9k_htc_csa_is_finished(struct ath9k_htc_priv *priv);
587 589
588int ath9k_rx_init(struct ath9k_htc_priv *priv); 590int ath9k_rx_init(struct ath9k_htc_priv *priv);
589void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); 591void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index e8b6ec3c1dbb..e6bcb4c90fa0 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -257,6 +257,8 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,
257 } 257 }
258 258
259 spin_unlock_bh(&priv->beacon_lock); 259 spin_unlock_bh(&priv->beacon_lock);
260
261 ath9k_htc_csa_is_finished(priv);
260} 262}
261 263
262static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv, 264static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv,
@@ -503,3 +505,20 @@ void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv)
503 return; 505 return;
504 } 506 }
505} 507}
508
509bool ath9k_htc_csa_is_finished(struct ath9k_htc_priv *priv)
510{
511 struct ieee80211_vif *vif;
512
513 vif = priv->csa_vif;
514 if (!vif || !vif->csa_active)
515 return false;
516
517 if (!ieee80211_csa_is_complete(vif))
518 return false;
519
520 ieee80211_csa_finish(vif);
521
522 priv->csa_vif = NULL;
523 return true;
524}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 36218ee2bdbe..39eaf9b6e9b4 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -744,7 +744,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
744 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 744 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
745 745
746 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN | 746 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN |
747 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 747 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
748 WIPHY_FLAG_HAS_CHANNEL_SWITCH;
748 749
749 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; 750 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
750 751
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index b71f3072fd9a..dab1323dfec7 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1134,6 +1134,9 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1134 priv->nvifs--; 1134 priv->nvifs--;
1135 priv->vif_slot &= ~(1 << avp->index); 1135 priv->vif_slot &= ~(1 << avp->index);
1136 1136
1137 if (priv->csa_vif == vif)
1138 priv->csa_vif = NULL;
1139
1137 ath9k_htc_remove_station(priv, vif, NULL); 1140 ath9k_htc_remove_station(priv, vif, NULL);
1138 1141
1139 DEC_VIF(priv, vif->type); 1142 DEC_VIF(priv, vif->type);
@@ -1841,6 +1844,19 @@ static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
1841 return 0; 1844 return 0;
1842} 1845}
1843 1846
1847static void ath9k_htc_channel_switch_beacon(struct ieee80211_hw *hw,
1848 struct ieee80211_vif *vif,
1849 struct cfg80211_chan_def *chandef)
1850{
1851 struct ath9k_htc_priv *priv = hw->priv;
1852
1853 /* mac80211 does not support CSA in multi-if cases (yet) */
1854 if (WARN_ON(priv->csa_vif))
1855 return;
1856
1857 priv->csa_vif = vif;
1858}
1859
1844struct ieee80211_ops ath9k_htc_ops = { 1860struct ieee80211_ops ath9k_htc_ops = {
1845 .tx = ath9k_htc_tx, 1861 .tx = ath9k_htc_tx,
1846 .start = ath9k_htc_start, 1862 .start = ath9k_htc_start,
@@ -1867,6 +1883,7 @@ struct ieee80211_ops ath9k_htc_ops = {
1867 .set_bitrate_mask = ath9k_htc_set_bitrate_mask, 1883 .set_bitrate_mask = ath9k_htc_set_bitrate_mask,
1868 .get_stats = ath9k_htc_get_stats, 1884 .get_stats = ath9k_htc_get_stats,
1869 .get_antenna = ath9k_htc_get_antenna, 1885 .get_antenna = ath9k_htc_get_antenna,
1886 .channel_switch_beacon = ath9k_htc_channel_switch_beacon,
1870 1887
1871#ifdef CONFIG_ATH9K_HTC_DEBUGFS 1888#ifdef CONFIG_ATH9K_HTC_DEBUGFS
1872 .get_et_sset_count = ath9k_htc_get_et_sset_count, 1889 .get_et_sset_count = ath9k_htc_get_et_sset_count,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index d285e3a89853..cfd45cb8ccfc 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -216,11 +216,13 @@ static bool ath_prepare_reset(struct ath_softc *sc)
216 ath_stop_ani(sc); 216 ath_stop_ani(sc);
217 ath9k_hw_disable_interrupts(ah); 217 ath9k_hw_disable_interrupts(ah);
218 218
219 if (!ath_drain_all_txq(sc)) 219 if (AR_SREV_9300_20_OR_LATER(ah)) {
220 ret = false; 220 ret &= ath_stoprecv(sc);
221 221 ret &= ath_drain_all_txq(sc);
222 if (!ath_stoprecv(sc)) 222 } else {
223 ret = false; 223 ret &= ath_drain_all_txq(sc);
224 ret &= ath_stoprecv(sc);
225 }
224 226
225 return ret; 227 return ret;
226} 228}
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index dbfcdd16628a..c79cfe02ec80 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -289,6 +289,26 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
289 } 289 }
290 290
291 wil_dbg_misc(wil, "Start scan_request 0x%p\n", request); 291 wil_dbg_misc(wil, "Start scan_request 0x%p\n", request);
292 wil_dbg_misc(wil, "SSID count: %d", request->n_ssids);
293
294 for (i = 0; i < request->n_ssids; i++) {
295 wil_dbg_misc(wil, "SSID[%d]", i);
296 print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
297 request->ssids[i].ssid,
298 request->ssids[i].ssid_len);
299 }
300
301 if (request->n_ssids)
302 rc = wmi_set_ssid(wil, request->ssids[0].ssid_len,
303 request->ssids[0].ssid);
304 else
305 rc = wmi_set_ssid(wil, 0, NULL);
306
307 if (rc) {
308 wil_err(wil, "set SSID for scan request failed: %d\n", rc);
309 return rc;
310 }
311
292 wil->scan_request = request; 312 wil->scan_request = request;
293 mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO); 313 mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO);
294 314
@@ -778,6 +798,7 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
778 size_t hlen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); 798 size_t hlen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
779 const u8 *pr_ies = NULL; 799 const u8 *pr_ies = NULL;
780 size_t pr_ies_len = 0; 800 size_t pr_ies_len = 0;
801 u8 hidden_ssid;
781 802
782 wil_dbg_misc(wil, "%s()\n", __func__); 803 wil_dbg_misc(wil, "%s()\n", __func__);
783 804
@@ -790,6 +811,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
790 channel->center_freq, info->privacy ? "secure" : "open"); 811 channel->center_freq, info->privacy ? "secure" : "open");
791 wil_dbg_misc(wil, "Privacy: %d auth_type %d\n", 812 wil_dbg_misc(wil, "Privacy: %d auth_type %d\n",
792 info->privacy, info->auth_type); 813 info->privacy, info->auth_type);
814 wil_dbg_misc(wil, "Hidden SSID mode: %d\n",
815 info->hidden_ssid);
793 wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval, 816 wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
794 info->dtim_period); 817 info->dtim_period);
795 print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET, 818 print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
@@ -835,10 +858,28 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
835 858
836 wil->privacy = info->privacy; 859 wil->privacy = info->privacy;
837 860
861 switch (info->hidden_ssid) {
862 case NL80211_HIDDEN_SSID_NOT_IN_USE:
863 hidden_ssid = WMI_HIDDEN_SSID_DISABLED;
864 break;
865
866 case NL80211_HIDDEN_SSID_ZERO_LEN:
867 hidden_ssid = WMI_HIDDEN_SSID_SEND_EMPTY;
868 break;
869
870 case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
871 hidden_ssid = WMI_HIDDEN_SSID_CLEAR;
872 break;
873
874 default:
875 rc = -EOPNOTSUPP;
876 goto out;
877 }
878
838 netif_carrier_on(ndev); 879 netif_carrier_on(ndev);
839 880
840 rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype, 881 rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype,
841 channel->hw_value); 882 channel->hw_value, hidden_ssid);
842 if (rc) 883 if (rc)
843 goto err_pcp_start; 884 goto err_pcp_start;
844 885
@@ -1023,8 +1064,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
1023 1064
1024static void wil_wiphy_init(struct wiphy *wiphy) 1065static void wil_wiphy_init(struct wiphy *wiphy)
1025{ 1066{
1026 /* TODO: set real value */ 1067 wiphy->max_scan_ssids = 1;
1027 wiphy->max_scan_ssids = 10;
1028 wiphy->max_scan_ie_len = WMI_MAX_IE_LEN; 1068 wiphy->max_scan_ie_len = WMI_MAX_IE_LEN;
1029 wiphy->max_num_pmkids = 0 /* TODO: */; 1069 wiphy->max_num_pmkids = 0 /* TODO: */;
1030 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1070 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 8f9c0722a801..75219a1b8805 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1360,7 +1360,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data)
1360__acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock) 1360__acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
1361{ 1361{
1362 struct wil6210_priv *wil = s->private; 1362 struct wil6210_priv *wil = s->private;
1363 int i, tid; 1363 int i, tid, mcs;
1364 1364
1365 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { 1365 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1366 struct wil_sta_info *p = &wil->sta[i]; 1366 struct wil_sta_info *p = &wil->sta[i];
@@ -1390,6 +1390,12 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
1390 } 1390 }
1391 } 1391 }
1392 spin_unlock_bh(&p->tid_rx_lock); 1392 spin_unlock_bh(&p->tid_rx_lock);
1393 seq_puts(s, "Rx/MCS:");
1394 for (mcs = 0; mcs < ARRAY_SIZE(p->stats.rx_per_mcs);
1395 mcs++)
1396 seq_printf(s, " %lld",
1397 p->stats.rx_per_mcs[mcs]);
1398 seq_puts(s, "\n");
1393 } 1399 }
1394 } 1400 }
1395 1401
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 6d704aee3afd..b9febab89167 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -100,6 +100,8 @@ module_param_cb(rx_ring_order, &ring_order_ops, &rx_ring_order, S_IRUGO);
100MODULE_PARM_DESC(rx_ring_order, " Rx ring order; size = 1 << order"); 100MODULE_PARM_DESC(rx_ring_order, " Rx ring order; size = 1 << order");
101module_param_cb(tx_ring_order, &ring_order_ops, &tx_ring_order, S_IRUGO); 101module_param_cb(tx_ring_order, &ring_order_ops, &tx_ring_order, S_IRUGO);
102MODULE_PARM_DESC(tx_ring_order, " Tx ring order; size = 1 << order"); 102MODULE_PARM_DESC(tx_ring_order, " Tx ring order; size = 1 << order");
103module_param_cb(bcast_ring_order, &ring_order_ops, &bcast_ring_order, S_IRUGO);
104MODULE_PARM_DESC(bcast_ring_order, " Bcast ring order; size = 1 << order");
103 105
104#define RST_DELAY (20) /* msec, for loop in @wil_target_reset */ 106#define RST_DELAY (20) /* msec, for loop in @wil_target_reset */
105#define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */ 107#define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 6042f61b016c..8ef18ace110f 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -132,7 +132,7 @@ static void wil_dev_setup(struct net_device *dev)
132 dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT; 132 dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT;
133} 133}
134 134
135void *wil_if_alloc(struct device *dev, void __iomem *csr) 135void *wil_if_alloc(struct device *dev)
136{ 136{
137 struct net_device *ndev; 137 struct net_device *ndev;
138 struct wireless_dev *wdev; 138 struct wireless_dev *wdev;
@@ -147,7 +147,6 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
147 } 147 }
148 148
149 wil = wdev_to_wil(wdev); 149 wil = wdev_to_wil(wdev);
150 wil->csr = csr;
151 wil->wdev = wdev; 150 wil->wdev = wdev;
152 151
153 wil_dbg_misc(wil, "%s()\n", __func__); 152 wil_dbg_misc(wil, "%s()\n", __func__);
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 58c79166a6d1..aa3ecc607ca3 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -163,7 +163,6 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
163{ 163{
164 struct wil6210_priv *wil; 164 struct wil6210_priv *wil;
165 struct device *dev = &pdev->dev; 165 struct device *dev = &pdev->dev;
166 void __iomem *csr;
167 int rc; 166 int rc;
168 167
169 /* check HW */ 168 /* check HW */
@@ -178,9 +177,28 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
178 return -ENODEV; 177 return -ENODEV;
179 } 178 }
180 179
180 wil = wil_if_alloc(dev);
181 if (IS_ERR(wil)) {
182 rc = (int)PTR_ERR(wil);
183 dev_err(dev, "wil_if_alloc failed: %d\n", rc);
184 return rc;
185 }
186 wil->pdev = pdev;
187 pci_set_drvdata(pdev, wil);
188 /* rollback to if_free */
189
190 wil->platform_handle =
191 wil_platform_init(&pdev->dev, &wil->platform_ops);
192 if (!wil->platform_handle) {
193 rc = -ENODEV;
194 wil_err(wil, "wil_platform_init failed\n");
195 goto if_free;
196 }
197 /* rollback to err_plat */
198
181 rc = pci_enable_device(pdev); 199 rc = pci_enable_device(pdev);
182 if (rc) { 200 if (rc) {
183 dev_err(&pdev->dev, 201 wil_err(wil,
184 "pci_enable_device failed, retry with MSI only\n"); 202 "pci_enable_device failed, retry with MSI only\n");
185 /* Work around for platforms that can't allocate IRQ: 203 /* Work around for platforms that can't allocate IRQ:
186 * retry with MSI only 204 * retry with MSI only
@@ -188,47 +206,37 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
188 pdev->msi_enabled = 1; 206 pdev->msi_enabled = 1;
189 rc = pci_enable_device(pdev); 207 rc = pci_enable_device(pdev);
190 } 208 }
191 if (rc) 209 if (rc) {
192 return -ENODEV; 210 wil_err(wil,
211 "pci_enable_device failed, even with MSI only\n");
212 goto err_plat;
213 }
193 /* rollback to err_disable_pdev */ 214 /* rollback to err_disable_pdev */
194 215
195 rc = pci_request_region(pdev, 0, WIL_NAME); 216 rc = pci_request_region(pdev, 0, WIL_NAME);
196 if (rc) { 217 if (rc) {
197 dev_err(&pdev->dev, "pci_request_region failed\n"); 218 wil_err(wil, "pci_request_region failed\n");
198 goto err_disable_pdev; 219 goto err_disable_pdev;
199 } 220 }
200 /* rollback to err_release_reg */ 221 /* rollback to err_release_reg */
201 222
202 csr = pci_ioremap_bar(pdev, 0); 223 wil->csr = pci_ioremap_bar(pdev, 0);
203 if (!csr) { 224 if (!wil->csr) {
204 dev_err(&pdev->dev, "pci_ioremap_bar failed\n"); 225 wil_err(wil, "pci_ioremap_bar failed\n");
205 rc = -ENODEV; 226 rc = -ENODEV;
206 goto err_release_reg; 227 goto err_release_reg;
207 } 228 }
208 /* rollback to err_iounmap */ 229 /* rollback to err_iounmap */
209 dev_info(&pdev->dev, "CSR at %pR -> 0x%p\n", &pdev->resource[0], csr); 230 wil_info(wil, "CSR at %pR -> 0x%p\n", &pdev->resource[0], wil->csr);
210 231
211 wil = wil_if_alloc(dev, csr);
212 if (IS_ERR(wil)) {
213 rc = (int)PTR_ERR(wil);
214 dev_err(dev, "wil_if_alloc failed: %d\n", rc);
215 goto err_iounmap;
216 }
217 /* rollback to if_free */
218
219 pci_set_drvdata(pdev, wil);
220 wil->pdev = pdev;
221 wil_set_capabilities(wil); 232 wil_set_capabilities(wil);
222 wil6210_clear_irq(wil); 233 wil6210_clear_irq(wil);
223 234
224 wil->platform_handle =
225 wil_platform_init(&pdev->dev, &wil->platform_ops);
226
227 /* FW should raise IRQ when ready */ 235 /* FW should raise IRQ when ready */
228 rc = wil_if_pcie_enable(wil); 236 rc = wil_if_pcie_enable(wil);
229 if (rc) { 237 if (rc) {
230 wil_err(wil, "Enable device failed\n"); 238 wil_err(wil, "Enable device failed\n");
231 goto if_free; 239 goto err_iounmap;
232 } 240 }
233 /* rollback to bus_disable */ 241 /* rollback to bus_disable */
234 242
@@ -243,18 +251,19 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
243 251
244 return 0; 252 return 0;
245 253
246 bus_disable: 254bus_disable:
247 wil_if_pcie_disable(wil); 255 wil_if_pcie_disable(wil);
248 if_free: 256err_iounmap:
257 pci_iounmap(pdev, wil->csr);
258err_release_reg:
259 pci_release_region(pdev, 0);
260err_disable_pdev:
261 pci_disable_device(pdev);
262err_plat:
249 if (wil->platform_ops.uninit) 263 if (wil->platform_ops.uninit)
250 wil->platform_ops.uninit(wil->platform_handle); 264 wil->platform_ops.uninit(wil->platform_handle);
265if_free:
251 wil_if_free(wil); 266 wil_if_free(wil);
252 err_iounmap:
253 pci_iounmap(pdev, csr);
254 err_release_reg:
255 pci_release_region(pdev, 0);
256 err_disable_pdev:
257 pci_disable_device(pdev);
258 267
259 return rc; 268 return rc;
260} 269}
@@ -269,12 +278,12 @@ static void wil_pcie_remove(struct pci_dev *pdev)
269 wil6210_debugfs_remove(wil); 278 wil6210_debugfs_remove(wil);
270 wil_if_remove(wil); 279 wil_if_remove(wil);
271 wil_if_pcie_disable(wil); 280 wil_if_pcie_disable(wil);
272 if (wil->platform_ops.uninit)
273 wil->platform_ops.uninit(wil->platform_handle);
274 wil_if_free(wil);
275 pci_iounmap(pdev, csr); 281 pci_iounmap(pdev, csr);
276 pci_release_region(pdev, 0); 282 pci_release_region(pdev, 0);
277 pci_disable_device(pdev); 283 pci_disable_device(pdev);
284 if (wil->platform_ops.uninit)
285 wil->platform_ops.uninit(wil->platform_handle);
286 wil_if_free(wil);
278} 287}
279 288
280static const struct pci_device_id wil6210_pcie_ids[] = { 289static const struct pci_device_id wil6210_pcie_ids[] = {
@@ -291,7 +300,27 @@ static struct pci_driver wil6210_driver = {
291 .name = WIL_NAME, 300 .name = WIL_NAME,
292}; 301};
293 302
294module_pci_driver(wil6210_driver); 303static int __init wil6210_driver_init(void)
304{
305 int rc;
306
307 rc = wil_platform_modinit();
308 if (rc)
309 return rc;
310
311 rc = pci_register_driver(&wil6210_driver);
312 if (rc)
313 wil_platform_modexit();
314 return rc;
315}
316module_init(wil6210_driver_init);
317
318static void __exit wil6210_driver_exit(void)
319{
320 pci_unregister_driver(&wil6210_driver);
321 wil_platform_modexit();
322}
323module_exit(wil6210_driver_exit);
295 324
296MODULE_LICENSE("Dual BSD/GPL"); 325MODULE_LICENSE("Dual BSD/GPL");
297MODULE_AUTHOR("Qualcomm Atheros <wil6210@qca.qualcomm.com>"); 326MODULE_AUTHOR("Qualcomm Atheros <wil6210@qca.qualcomm.com>");
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 0113dac3a9a9..aa20af86e1d6 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -427,6 +427,8 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
427 cid = wil_rxdesc_cid(d); 427 cid = wil_rxdesc_cid(d);
428 stats = &wil->sta[cid].stats; 428 stats = &wil->sta[cid].stats;
429 stats->last_mcs_rx = wil_rxdesc_mcs(d); 429 stats->last_mcs_rx = wil_rxdesc_mcs(d);
430 if (stats->last_mcs_rx < ARRAY_SIZE(stats->rx_per_mcs))
431 stats->rx_per_mcs[stats->last_mcs_rx]++;
430 432
431 /* use radiotap header only if required */ 433 /* use radiotap header only if required */
432 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) 434 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index f3513a1fa424..275355d46a36 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -281,7 +281,7 @@ struct fw_map {
281}; 281};
282 282
283/* array size should be in sync with actual definition in the wmi.c */ 283/* array size should be in sync with actual definition in the wmi.c */
284extern const struct fw_map fw_mapping[7]; 284extern const struct fw_map fw_mapping[8];
285 285
286/** 286/**
287 * mk_cidxtid - construct @cidxtid field 287 * mk_cidxtid - construct @cidxtid field
@@ -464,6 +464,7 @@ enum wil_sta_status {
464}; 464};
465 465
466#define WIL_STA_TID_NUM (16) 466#define WIL_STA_TID_NUM (16)
467#define WIL_MCS_MAX (12) /* Maximum MCS supported */
467 468
468struct wil_net_stats { 469struct wil_net_stats {
469 unsigned long rx_packets; 470 unsigned long rx_packets;
@@ -473,6 +474,7 @@ struct wil_net_stats {
473 unsigned long tx_errors; 474 unsigned long tx_errors;
474 unsigned long rx_dropped; 475 unsigned long rx_dropped;
475 u16 last_mcs_rx; 476 u16 last_mcs_rx;
477 u64 rx_per_mcs[WIL_MCS_MAX + 1];
476}; 478};
477 479
478/** 480/**
@@ -684,7 +686,7 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
684void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, 686void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
685 size_t count); 687 size_t count);
686 688
687void *wil_if_alloc(struct device *dev, void __iomem *csr); 689void *wil_if_alloc(struct device *dev);
688void wil_if_free(struct wil6210_priv *wil); 690void wil_if_free(struct wil6210_priv *wil);
689int wil_if_add(struct wil6210_priv *wil); 691int wil_if_add(struct wil6210_priv *wil);
690void wil_if_remove(struct wil6210_priv *wil); 692void wil_if_remove(struct wil6210_priv *wil);
@@ -762,7 +764,8 @@ struct wireless_dev *wil_cfg80211_init(struct device *dev);
762void wil_wdev_free(struct wil6210_priv *wil); 764void wil_wdev_free(struct wil6210_priv *wil);
763 765
764int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); 766int wmi_set_mac_address(struct wil6210_priv *wil, void *addr);
765int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan); 767int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
768 u8 chan, u8 hidden_ssid);
766int wmi_pcp_stop(struct wil6210_priv *wil); 769int wmi_pcp_stop(struct wil6210_priv *wil);
767void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, 770void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
768 u16 reason_code, bool from_event); 771 u16 reason_code, bool from_event);
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.c b/drivers/net/wireless/ath/wil6210/wil_platform.c
index 976a071ba74e..de15f1422fe9 100644
--- a/drivers/net/wireless/ath/wil6210/wil_platform.c
+++ b/drivers/net/wireless/ath/wil6210/wil_platform.c
@@ -17,6 +17,15 @@
17#include "linux/device.h" 17#include "linux/device.h"
18#include "wil_platform.h" 18#include "wil_platform.h"
19 19
20int __init wil_platform_modinit(void)
21{
22 return 0;
23}
24
25void wil_platform_modexit(void)
26{
27}
28
20/** 29/**
21 * wil_platform_init() - wil6210 platform module init 30 * wil_platform_init() - wil6210 platform module init
22 * 31 *
@@ -26,10 +35,11 @@
26 */ 35 */
27void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops) 36void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops)
28{ 37{
29 void *handle = NULL; 38 void *handle = ops; /* to return some non-NULL for 'void' impl. */
30 39
31 if (!ops) { 40 if (!ops) {
32 dev_err(dev, "Invalid parameter. Cannot init platform module\n"); 41 dev_err(dev,
42 "Invalid parameter. Cannot init platform module\n");
33 return NULL; 43 return NULL;
34 } 44 }
35 45
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.h b/drivers/net/wireless/ath/wil6210/wil_platform.h
index 158c73b049a9..d7fa19b7886d 100644
--- a/drivers/net/wireless/ath/wil6210/wil_platform.h
+++ b/drivers/net/wireless/ath/wil6210/wil_platform.h
@@ -31,4 +31,7 @@ struct wil_platform_ops {
31 31
32void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops); 32void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops);
33 33
34int __init wil_platform_modinit(void);
35void wil_platform_modexit(void);
36
34#endif /* __WIL_PLATFORM_H__ */ 37#endif /* __WIL_PLATFORM_H__ */
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 3dc8daf69bd2..c759759afbb2 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -85,6 +85,7 @@ const struct fw_map fw_mapping[] = {
85 {0x880000, 0x88a000, 0x880000, "rgf"}, /* various RGF 40k */ 85 {0x880000, 0x88a000, 0x880000, "rgf"}, /* various RGF 40k */
86 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl"}, /* AGC table 4k */ 86 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl"}, /* AGC table 4k */
87 {0x88b000, 0x88c000, 0x88b000, "rgf_ext"}, /* Pcie_ext_rgf 4k */ 87 {0x88b000, 0x88c000, 0x88b000, "rgf_ext"}, /* Pcie_ext_rgf 4k */
88 {0x88c000, 0x88c200, 0x88c000, "mac_rgf_ext"}, /* mac_ext_rgf 512b */
88 {0x8c0000, 0x949000, 0x8c0000, "upper"}, /* upper area 548k */ 89 {0x8c0000, 0x949000, 0x8c0000, "upper"}, /* upper area 548k */
89 /* 90 /*
90 * 920000..930000 ucode code RAM 91 * 920000..930000 ucode code RAM
@@ -824,7 +825,8 @@ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr)
824 return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd)); 825 return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd));
825} 826}
826 827
827int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan) 828int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
829 u8 chan, u8 hidden_ssid)
828{ 830{
829 int rc; 831 int rc;
830 832
@@ -834,6 +836,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
834 .disable_sec_offload = 1, 836 .disable_sec_offload = 1,
835 .channel = chan - 1, 837 .channel = chan - 1,
836 .pcp_max_assoc_sta = max_assoc_sta, 838 .pcp_max_assoc_sta = max_assoc_sta,
839 .hidden_ssid = hidden_ssid,
837 }; 840 };
838 struct { 841 struct {
839 struct wil6210_mbox_hdr_wmi wmi; 842 struct wil6210_mbox_hdr_wmi wmi;
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index cc04ab73b398..6e90e78f1554 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -495,10 +495,18 @@ struct wmi_power_mgmt_cfg_cmd {
495/* 495/*
496 * WMI_PCP_START_CMDID 496 * WMI_PCP_START_CMDID
497 */ 497 */
498
499enum wmi_hidden_ssid {
500 WMI_HIDDEN_SSID_DISABLED = 0,
501 WMI_HIDDEN_SSID_SEND_EMPTY = 1,
502 WMI_HIDDEN_SSID_CLEAR = 2,
503};
504
498struct wmi_pcp_start_cmd { 505struct wmi_pcp_start_cmd {
499 __le16 bcon_interval; 506 __le16 bcon_interval;
500 u8 pcp_max_assoc_sta; 507 u8 pcp_max_assoc_sta;
501 u8 reserved0[9]; 508 u8 hidden_ssid;
509 u8 reserved0[8];
502 u8 network_type; 510 u8 network_type;
503 u8 channel; 511 u8 channel;
504 u8 disable_sec_offload; 512 u8 disable_sec_offload;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 575b9f4b5589..28490702124a 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -5361,6 +5361,10 @@ static void b43_supported_bands(struct b43_wldev *dev, bool *have_2ghz_phy,
5361 *have_5ghz_phy = true; 5361 *have_5ghz_phy = true;
5362 return; 5362 return;
5363 case 0x4321: /* BCM4306 */ 5363 case 0x4321: /* BCM4306 */
5364 /* There are 14e4:4321 PCI devs with 2.4 GHz BCM4321 (N-PHY) */
5365 if (dev->phy.type != B43_PHYTYPE_G)
5366 break;
5367 /* fall through */
5364 case 0x4313: /* BCM4311 */ 5368 case 0x4313: /* BCM4311 */
5365 case 0x431a: /* BCM4318 */ 5369 case 0x431a: /* BCM4318 */
5366 case 0x432a: /* BCM4321 */ 5370 case 0x432a: /* BCM4321 */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 71779b9e4bbe..410a6645d316 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -988,6 +988,7 @@ static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
988 988
989static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) 989static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
990{ 990{
991 sdiodev->state = BRCMF_SDIOD_DOWN;
991 if (sdiodev->bus) { 992 if (sdiodev->bus) {
992 brcmf_sdio_remove(sdiodev->bus); 993 brcmf_sdio_remove(sdiodev->bus);
993 sdiodev->bus = NULL; 994 sdiodev->bus = NULL;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
index e10fa67010c0..d86d1f1f1c91 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -52,8 +52,6 @@
52#define BRCMF_PNO_SCAN_COMPLETE 1 52#define BRCMF_PNO_SCAN_COMPLETE 1
53#define BRCMF_PNO_SCAN_INCOMPLETE 0 53#define BRCMF_PNO_SCAN_INCOMPLETE 0
54 54
55#define BRCMF_IFACE_MAX_CNT 3
56
57#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ 55#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
58#define WPA_OUI_TYPE 1 56#define WPA_OUI_TYPE 1
59#define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */ 57#define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
@@ -2398,27 +2396,80 @@ brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2398 brcmf_err("set wsec error (%d)\n", err); 2396 brcmf_err("set wsec error (%d)\n", err);
2399} 2397}
2400 2398
2399static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2400{
2401 struct nl80211_sta_flag_update *sfu;
2402
2403 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2404 si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
2405 sfu = &si->sta_flags;
2406 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2407 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2408 BIT(NL80211_STA_FLAG_ASSOCIATED) |
2409 BIT(NL80211_STA_FLAG_AUTHORIZED);
2410 if (fw_sta_flags & BRCMF_STA_WME)
2411 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2412 if (fw_sta_flags & BRCMF_STA_AUTHE)
2413 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2414 if (fw_sta_flags & BRCMF_STA_ASSOC)
2415 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2416 if (fw_sta_flags & BRCMF_STA_AUTHO)
2417 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2418}
2419
2420static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2421{
2422 struct {
2423 __le32 len;
2424 struct brcmf_bss_info_le bss_le;
2425 } *buf;
2426 u16 capability;
2427 int err;
2428
2429 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2430 if (!buf)
2431 return;
2432
2433 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2434 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2435 WL_BSS_INFO_MAX);
2436 if (err) {
2437 brcmf_err("Failed to get bss info (%d)\n", err);
2438 return;
2439 }
2440 si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2441 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2442 si->bss_param.dtim_period = buf->bss_le.dtim_period;
2443 capability = le16_to_cpu(buf->bss_le.capability);
2444 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2445 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2446 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2447 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2448 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2449 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2450}
2451
2401static s32 2452static s32
2402brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, 2453brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2403 const u8 *mac, struct station_info *sinfo) 2454 const u8 *mac, struct station_info *sinfo)
2404{ 2455{
2405 struct brcmf_if *ifp = netdev_priv(ndev); 2456 struct brcmf_if *ifp = netdev_priv(ndev);
2406 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2407 struct brcmf_scb_val_le scb_val;
2408 int rssi;
2409 s32 rate;
2410 s32 err = 0; 2457 s32 err = 0;
2411 u8 *bssid = profile->bssid;
2412 struct brcmf_sta_info_le sta_info_le; 2458 struct brcmf_sta_info_le sta_info_le;
2413 u32 beacon_period; 2459 u32 sta_flags;
2414 u32 dtim_period; 2460 u32 is_tdls_peer;
2415 2461
2416 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac); 2462 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2417 if (!check_vif_up(ifp->vif)) 2463 if (!check_vif_up(ifp->vif))
2418 return -EIO; 2464 return -EIO;
2419 2465
2420 if (brcmf_is_apmode(ifp->vif)) { 2466 memset(&sta_info_le, 0, sizeof(sta_info_le));
2421 memcpy(&sta_info_le, mac, ETH_ALEN); 2467 memcpy(&sta_info_le, mac, ETH_ALEN);
2468 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2469 &sta_info_le,
2470 sizeof(sta_info_le));
2471 is_tdls_peer = !err;
2472 if (err) {
2422 err = brcmf_fil_iovar_data_get(ifp, "sta_info", 2473 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2423 &sta_info_le, 2474 &sta_info_le,
2424 sizeof(sta_info_le)); 2475 sizeof(sta_info_le));
@@ -2426,73 +2477,48 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2426 brcmf_err("GET STA INFO failed, %d\n", err); 2477 brcmf_err("GET STA INFO failed, %d\n", err);
2427 goto done; 2478 goto done;
2428 } 2479 }
2429 sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); 2480 }
2430 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; 2481 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2431 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) { 2482 sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2432 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME); 2483 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2433 sinfo->connected_time = le32_to_cpu(sta_info_le.in); 2484 sta_flags = le32_to_cpu(sta_info_le.flags);
2434 } 2485 brcmf_convert_sta_flags(sta_flags, sinfo);
2435 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n", 2486 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2436 sinfo->inactive_time, sinfo->connected_time); 2487 if (is_tdls_peer)
2437 } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) { 2488 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2438 if (memcmp(mac, bssid, ETH_ALEN)) { 2489 else
2439 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n", 2490 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2440 mac, bssid); 2491 if (sta_flags & BRCMF_STA_ASSOC) {
2441 err = -ENOENT; 2492 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2442 goto done; 2493 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2443 } 2494 brcmf_fill_bss_param(ifp, sinfo);
2444 /* Report the current tx rate */ 2495 }
2445 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); 2496 if (sta_flags & BRCMF_STA_SCBSTATS) {
2446 if (err) { 2497 sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
2447 brcmf_err("Could not get rate (%d)\n", err); 2498 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2448 goto done; 2499 sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
2449 } else { 2500 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2501 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2502 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
2503 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2504 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2505 if (sinfo->tx_packets) {
2450 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); 2506 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2451 sinfo->txrate.legacy = rate * 5; 2507 sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate);
2452 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2); 2508 sinfo->txrate.legacy /= 100;
2453 } 2509 }
2454 2510 if (sinfo->rx_packets) {
2455 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, 2511 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
2456 &ifp->vif->sme_state)) { 2512 sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate);
2457 memset(&scb_val, 0, sizeof(scb_val)); 2513 sinfo->rxrate.legacy /= 100;
2458 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2459 &scb_val, sizeof(scb_val));
2460 if (err) {
2461 brcmf_err("Could not get rssi (%d)\n", err);
2462 goto done;
2463 } else {
2464 rssi = le32_to_cpu(scb_val.val);
2465 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2466 sinfo->signal = rssi;
2467 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2468 }
2469 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD,
2470 &beacon_period);
2471 if (err) {
2472 brcmf_err("Could not get beacon period (%d)\n",
2473 err);
2474 goto done;
2475 } else {
2476 sinfo->bss_param.beacon_interval =
2477 beacon_period;
2478 brcmf_dbg(CONN, "Beacon peroid %d\n",
2479 beacon_period);
2480 }
2481 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD,
2482 &dtim_period);
2483 if (err) {
2484 brcmf_err("Could not get DTIM period (%d)\n",
2485 err);
2486 goto done;
2487 } else {
2488 sinfo->bss_param.dtim_period = dtim_period;
2489 brcmf_dbg(CONN, "DTIM peroid %d\n",
2490 dtim_period);
2491 }
2492 sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2493 } 2514 }
2494 } else 2515 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2495 err = -EPERM; 2516 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
2517 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2518 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
2519 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2520 }
2521 }
2496done: 2522done:
2497 brcmf_dbg(TRACE, "Exit\n"); 2523 brcmf_dbg(TRACE, "Exit\n");
2498 return err; 2524 return err;
@@ -5640,53 +5666,6 @@ static int brcmf_setup_wiphybands(struct wiphy *wiphy)
5640 return 0; 5666 return 0;
5641} 5667}
5642 5668
5643static const struct ieee80211_iface_limit brcmf_iface_limits_mbss[] = {
5644 {
5645 .max = 1,
5646 .types = BIT(NL80211_IFTYPE_STATION) |
5647 BIT(NL80211_IFTYPE_ADHOC)
5648 },
5649 {
5650 .max = 4,
5651 .types = BIT(NL80211_IFTYPE_AP)
5652 },
5653 {
5654 .max = 1,
5655 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
5656 BIT(NL80211_IFTYPE_P2P_GO)
5657 },
5658 {
5659 .max = 1,
5660 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
5661 }
5662};
5663
5664static const struct ieee80211_iface_limit brcmf_iface_limits_sbss[] = {
5665 {
5666 .max = 2,
5667 .types = BIT(NL80211_IFTYPE_STATION) |
5668 BIT(NL80211_IFTYPE_ADHOC) |
5669 BIT(NL80211_IFTYPE_AP)
5670 },
5671 {
5672 .max = 1,
5673 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
5674 BIT(NL80211_IFTYPE_P2P_GO)
5675 },
5676 {
5677 .max = 1,
5678 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
5679 }
5680};
5681static struct ieee80211_iface_combination brcmf_iface_combos[] = {
5682 {
5683 .max_interfaces = BRCMF_IFACE_MAX_CNT,
5684 .num_different_channels = 1,
5685 .n_limits = ARRAY_SIZE(brcmf_iface_limits_sbss),
5686 .limits = brcmf_iface_limits_sbss,
5687 }
5688};
5689
5690static const struct ieee80211_txrx_stypes 5669static const struct ieee80211_txrx_stypes
5691brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { 5670brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5692 [NL80211_IFTYPE_STATION] = { 5671 [NL80211_IFTYPE_STATION] = {
@@ -5716,6 +5695,67 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5716 } 5695 }
5717}; 5696};
5718 5697
5698static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
5699{
5700 struct ieee80211_iface_combination *combo = NULL;
5701 struct ieee80211_iface_limit *limits = NULL;
5702 int i = 0, max_iface_cnt;
5703
5704 combo = kzalloc(sizeof(*combo), GFP_KERNEL);
5705 if (!combo)
5706 goto err;
5707
5708 limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL);
5709 if (!limits)
5710 goto err;
5711
5712 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
5713 BIT(NL80211_IFTYPE_ADHOC) |
5714 BIT(NL80211_IFTYPE_AP);
5715
5716 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
5717 combo->num_different_channels = 2;
5718 else
5719 combo->num_different_channels = 1;
5720
5721 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
5722 limits[i].max = 1;
5723 limits[i++].types = BIT(NL80211_IFTYPE_STATION);
5724 limits[i].max = 4;
5725 limits[i++].types = BIT(NL80211_IFTYPE_AP);
5726 max_iface_cnt = 5;
5727 } else {
5728 limits[i].max = 2;
5729 limits[i++].types = BIT(NL80211_IFTYPE_STATION) |
5730 BIT(NL80211_IFTYPE_AP);
5731 max_iface_cnt = 2;
5732 }
5733
5734 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) {
5735 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
5736 BIT(NL80211_IFTYPE_P2P_GO) |
5737 BIT(NL80211_IFTYPE_P2P_DEVICE);
5738 limits[i].max = 1;
5739 limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
5740 BIT(NL80211_IFTYPE_P2P_GO);
5741 limits[i].max = 1;
5742 limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
5743 max_iface_cnt += 2;
5744 }
5745 combo->max_interfaces = max_iface_cnt;
5746 combo->limits = limits;
5747 combo->n_limits = i;
5748
5749 wiphy->iface_combinations = combo;
5750 wiphy->n_iface_combinations = 1;
5751 return 0;
5752
5753err:
5754 kfree(limits);
5755 kfree(combo);
5756 return -ENOMEM;
5757}
5758
5719static void brcmf_wiphy_pno_params(struct wiphy *wiphy) 5759static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
5720{ 5760{
5721 /* scheduled scan settings */ 5761 /* scheduled scan settings */
@@ -5746,7 +5786,6 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy)
5746static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) 5786static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
5747{ 5787{
5748 struct ieee80211_supported_band *band; 5788 struct ieee80211_supported_band *band;
5749 struct ieee80211_iface_combination ifc_combo;
5750 __le32 bandlist[3]; 5789 __le32 bandlist[3];
5751 u32 n_bands; 5790 u32 n_bands;
5752 int err, i; 5791 int err, i;
@@ -5754,24 +5793,11 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
5754 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; 5793 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
5755 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; 5794 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5756 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; 5795 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
5757 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 5796
5758 BIT(NL80211_IFTYPE_ADHOC) | 5797 err = brcmf_setup_ifmodes(wiphy, ifp);
5759 BIT(NL80211_IFTYPE_AP) | 5798 if (err)
5760 BIT(NL80211_IFTYPE_P2P_CLIENT) | 5799 return err;
5761 BIT(NL80211_IFTYPE_P2P_GO) | 5800
5762 BIT(NL80211_IFTYPE_P2P_DEVICE);
5763 /* need VSDB firmware feature for concurrent channels */
5764 ifc_combo = brcmf_iface_combos[0];
5765 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
5766 ifc_combo.num_different_channels = 2;
5767 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
5768 ifc_combo.n_limits = ARRAY_SIZE(brcmf_iface_limits_mbss),
5769 ifc_combo.limits = brcmf_iface_limits_mbss;
5770 }
5771 wiphy->iface_combinations = kmemdup(&ifc_combo,
5772 sizeof(ifc_combo),
5773 GFP_KERNEL);
5774 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
5775 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 5801 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5776 wiphy->cipher_suites = __wl_cipher_suites; 5802 wiphy->cipher_suites = __wl_cipher_suites;
5777 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); 5803 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
@@ -6036,6 +6062,8 @@ static void brcmf_free_wiphy(struct wiphy *wiphy)
6036 if (!wiphy) 6062 if (!wiphy)
6037 return; 6063 return;
6038 6064
6065 if (wiphy->iface_combinations)
6066 kfree(wiphy->iface_combinations->limits);
6039 kfree(wiphy->iface_combinations); 6067 kfree(wiphy->iface_combinations);
6040 if (wiphy->bands[IEEE80211_BAND_2GHZ]) { 6068 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6041 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); 6069 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
@@ -6071,6 +6099,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6071 brcmf_err("Could not allocate wiphy device\n"); 6099 brcmf_err("Could not allocate wiphy device\n");
6072 return NULL; 6100 return NULL;
6073 } 6101 }
6102 memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
6074 set_wiphy_dev(wiphy, busdev); 6103 set_wiphy_dev(wiphy, busdev);
6075 6104
6076 cfg = wiphy_priv(wiphy); 6105 cfg = wiphy_priv(wiphy);
@@ -6178,10 +6207,8 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
6178 if (!cfg) 6207 if (!cfg)
6179 return; 6208 return;
6180 6209
6181 WARN_ON(!list_empty(&cfg->vif_list));
6182 wiphy_unregister(cfg->wiphy);
6183 brcmf_btcoex_detach(cfg); 6210 brcmf_btcoex_detach(cfg);
6184 brcmf_p2p_detach(&cfg->p2p); 6211 wiphy_unregister(cfg->wiphy);
6185 wl_deinit_priv(cfg); 6212 wl_deinit_priv(cfg);
6186 brcmf_free_wiphy(cfg->wiphy); 6213 brcmf_free_wiphy(cfg->wiphy);
6187} 6214}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
index 26c65872dae3..7b0e52195a85 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
@@ -223,8 +223,6 @@ void brcmf_commonring_write_cancel(struct brcmf_commonring *commonring,
223void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring, 223void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
224 u16 *n_items) 224 u16 *n_items)
225{ 225{
226 void *ret_addr;
227
228 if (commonring->cr_update_wptr) 226 if (commonring->cr_update_wptr)
229 commonring->cr_update_wptr(commonring->cr_ctx); 227 commonring->cr_update_wptr(commonring->cr_ctx);
230 228
@@ -235,19 +233,18 @@ void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
235 if (*n_items == 0) 233 if (*n_items == 0)
236 return NULL; 234 return NULL;
237 235
238 ret_addr = commonring->buf_addr + 236 return commonring->buf_addr +
239 (commonring->r_ptr * commonring->item_len); 237 (commonring->r_ptr * commonring->item_len);
240
241 commonring->r_ptr += *n_items;
242 if (commonring->r_ptr == commonring->depth)
243 commonring->r_ptr = 0;
244
245 return ret_addr;
246} 238}
247 239
248 240
249int brcmf_commonring_read_complete(struct brcmf_commonring *commonring) 241int brcmf_commonring_read_complete(struct brcmf_commonring *commonring,
242 u16 n_items)
250{ 243{
244 commonring->r_ptr += n_items;
245 if (commonring->r_ptr == commonring->depth)
246 commonring->r_ptr = 0;
247
251 if (commonring->cr_write_rptr) 248 if (commonring->cr_write_rptr)
252 return commonring->cr_write_rptr(commonring->cr_ctx); 249 return commonring->cr_write_rptr(commonring->cr_ctx);
253 250
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/commonring.h b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h
index 3d404016a92e..b85033611c8d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h
@@ -62,7 +62,8 @@ void brcmf_commonring_write_cancel(struct brcmf_commonring *commonring,
62 u16 n_items); 62 u16 n_items);
63void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring, 63void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
64 u16 *n_items); 64 u16 *n_items);
65int brcmf_commonring_read_complete(struct brcmf_commonring *commonring); 65int brcmf_commonring_read_complete(struct brcmf_commonring *commonring,
66 u16 n_items);
66 67
67#define brcmf_commonring_n_items(commonring) (commonring->depth) 68#define brcmf_commonring_n_items(commonring) (commonring->depth)
68#define brcmf_commonring_len_item(commonring) (commonring->item_len) 69#define brcmf_commonring_len_item(commonring) (commonring->item_len)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c
index f8f47dcfa886..fe9d3fbf5fe2 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -867,8 +867,6 @@ static void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
867 } 867 }
868 /* unregister will take care of freeing it */ 868 /* unregister will take care of freeing it */
869 unregister_netdev(ifp->ndev); 869 unregister_netdev(ifp->ndev);
870 } else {
871 kfree(ifp);
872 } 870 }
873} 871}
874 872
@@ -1100,6 +1098,8 @@ void brcmf_detach(struct device *dev)
1100 1098
1101 /* stop firmware event handling */ 1099 /* stop firmware event handling */
1102 brcmf_fweh_detach(drvr); 1100 brcmf_fweh_detach(drvr);
1101 if (drvr->config)
1102 brcmf_p2p_detach(&drvr->config->p2p);
1103 1103
1104 brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); 1104 brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
1105 1105
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/debug.c b/drivers/net/wireless/brcm80211/brcmfmac/debug.c
index 9b473d50b005..2d6d00553858 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c
@@ -41,15 +41,6 @@ void brcmf_debugfs_exit(void)
41 root_folder = NULL; 41 root_folder = NULL;
42} 42}
43 43
44static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data)
45{
46 struct brcmf_bus *bus = dev_get_drvdata(seq->private);
47
48 seq_printf(seq, "chip: %x(%u) rev %u\n",
49 bus->chip, bus->chip, bus->chiprev);
50 return 0;
51}
52
53int brcmf_debugfs_attach(struct brcmf_pub *drvr) 44int brcmf_debugfs_attach(struct brcmf_pub *drvr)
54{ 45{
55 struct device *dev = drvr->bus_if->dev; 46 struct device *dev = drvr->bus_if->dev;
@@ -58,7 +49,6 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
58 return -ENODEV; 49 return -ENODEV;
59 50
60 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); 51 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
61 brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read);
62 52
63 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); 53 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
64} 54}
@@ -74,44 +64,12 @@ struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
74 return drvr->dbgfs_dir; 64 return drvr->dbgfs_dir;
75} 65}
76 66
77struct brcmf_debugfs_entry {
78 int (*read)(struct seq_file *seq, void *data);
79 struct brcmf_pub *drvr;
80};
81
82static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f)
83{
84 struct brcmf_debugfs_entry *entry = inode->i_private;
85
86 return single_open(f, entry->read, entry->drvr->bus_if->dev);
87}
88
89static const struct file_operations brcmf_debugfs_def_ops = {
90 .owner = THIS_MODULE,
91 .open = brcmf_debugfs_entry_open,
92 .release = single_release,
93 .read = seq_read,
94 .llseek = seq_lseek
95};
96
97int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, 67int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
98 int (*read_fn)(struct seq_file *seq, void *data)) 68 int (*read_fn)(struct seq_file *seq, void *data))
99{ 69{
100 struct dentry *dentry = drvr->dbgfs_dir; 70 struct dentry *e;
101 struct brcmf_debugfs_entry *entry;
102
103 if (IS_ERR_OR_NULL(dentry))
104 return -ENOENT;
105
106 entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL);
107 if (!entry)
108 return -ENOMEM;
109
110 entry->read = read_fn;
111 entry->drvr = drvr;
112
113 dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry,
114 &brcmf_debugfs_def_ops);
115 71
116 return PTR_ERR_OR_ZERO(dentry); 72 e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn,
73 drvr->dbgfs_dir, read_fn);
74 return PTR_ERR_OR_ZERO(e);
117} 75}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
index 2c5fad3a3aa2..1e94e94e01dc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
@@ -129,6 +129,7 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
129 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); 129 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
130 if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID) 130 if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
131 brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0); 131 brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
132 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
132 133
133 /* set chip related quirks */ 134 /* set chip related quirks */
134 switch (drvr->bus_if->chip) { 135 switch (drvr->bus_if->chip) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/brcm80211/brcmfmac/feature.h
index 546962525cd2..6b381f799f22 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h
@@ -23,12 +23,14 @@
23 * MCHAN: multi-channel for concurrent P2P. 23 * MCHAN: multi-channel for concurrent P2P.
24 * PNO: preferred network offload. 24 * PNO: preferred network offload.
25 * WOWL: Wake-On-WLAN. 25 * WOWL: Wake-On-WLAN.
26 * P2P: peer-to-peer
26 */ 27 */
27#define BRCMF_FEAT_LIST \ 28#define BRCMF_FEAT_LIST \
28 BRCMF_FEAT_DEF(MBSS) \ 29 BRCMF_FEAT_DEF(MBSS) \
29 BRCMF_FEAT_DEF(MCHAN) \ 30 BRCMF_FEAT_DEF(MCHAN) \
30 BRCMF_FEAT_DEF(PNO) \ 31 BRCMF_FEAT_DEF(PNO) \
31 BRCMF_FEAT_DEF(WOWL) 32 BRCMF_FEAT_DEF(WOWL) \
33 BRCMF_FEAT_DEF(P2P)
32/* 34/*
33 * Quirks: 35 * Quirks:
34 * 36 *
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
index 7ae6461df932..743f16b6a072 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -43,7 +43,7 @@ enum nvram_parser_state {
43 * struct nvram_parser - internal info for parser. 43 * struct nvram_parser - internal info for parser.
44 * 44 *
45 * @state: current parser state. 45 * @state: current parser state.
46 * @fwnv: input buffer being parsed. 46 * @data: input buffer being parsed.
47 * @nvram: output buffer with parse result. 47 * @nvram: output buffer with parse result.
48 * @nvram_len: lenght of parse result. 48 * @nvram_len: lenght of parse result.
49 * @line: current line. 49 * @line: current line.
@@ -55,7 +55,7 @@ enum nvram_parser_state {
55 */ 55 */
56struct nvram_parser { 56struct nvram_parser {
57 enum nvram_parser_state state; 57 enum nvram_parser_state state;
58 const struct firmware *fwnv; 58 const u8 *data;
59 u8 *nvram; 59 u8 *nvram;
60 u32 nvram_len; 60 u32 nvram_len;
61 u32 line; 61 u32 line;
@@ -91,7 +91,7 @@ static enum nvram_parser_state brcmf_nvram_handle_idle(struct nvram_parser *nvp)
91{ 91{
92 char c; 92 char c;
93 93
94 c = nvp->fwnv->data[nvp->pos]; 94 c = nvp->data[nvp->pos];
95 if (c == '\n') 95 if (c == '\n')
96 return COMMENT; 96 return COMMENT;
97 if (is_whitespace(c)) 97 if (is_whitespace(c))
@@ -115,16 +115,16 @@ static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp)
115 enum nvram_parser_state st = nvp->state; 115 enum nvram_parser_state st = nvp->state;
116 char c; 116 char c;
117 117
118 c = nvp->fwnv->data[nvp->pos]; 118 c = nvp->data[nvp->pos];
119 if (c == '=') { 119 if (c == '=') {
120 /* ignore RAW1 by treating as comment */ 120 /* ignore RAW1 by treating as comment */
121 if (strncmp(&nvp->fwnv->data[nvp->entry], "RAW1", 4) == 0) 121 if (strncmp(&nvp->data[nvp->entry], "RAW1", 4) == 0)
122 st = COMMENT; 122 st = COMMENT;
123 else 123 else
124 st = VALUE; 124 st = VALUE;
125 if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0) 125 if (strncmp(&nvp->data[nvp->entry], "devpath", 7) == 0)
126 nvp->multi_dev_v1 = true; 126 nvp->multi_dev_v1 = true;
127 if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0) 127 if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0)
128 nvp->multi_dev_v2 = true; 128 nvp->multi_dev_v2 = true;
129 } else if (!is_nvram_char(c) || c == ' ') { 129 } else if (!is_nvram_char(c) || c == ' ') {
130 brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", 130 brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
@@ -145,11 +145,11 @@ brcmf_nvram_handle_value(struct nvram_parser *nvp)
145 char *ekv; 145 char *ekv;
146 u32 cplen; 146 u32 cplen;
147 147
148 c = nvp->fwnv->data[nvp->pos]; 148 c = nvp->data[nvp->pos];
149 if (!is_nvram_char(c)) { 149 if (!is_nvram_char(c)) {
150 /* key,value pair complete */ 150 /* key,value pair complete */
151 ekv = (u8 *)&nvp->fwnv->data[nvp->pos]; 151 ekv = (u8 *)&nvp->data[nvp->pos];
152 skv = (u8 *)&nvp->fwnv->data[nvp->entry]; 152 skv = (u8 *)&nvp->data[nvp->entry];
153 cplen = ekv - skv; 153 cplen = ekv - skv;
154 if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE) 154 if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE)
155 return END; 155 return END;
@@ -170,7 +170,7 @@ brcmf_nvram_handle_comment(struct nvram_parser *nvp)
170{ 170{
171 char *eoc, *sol; 171 char *eoc, *sol;
172 172
173 sol = (char *)&nvp->fwnv->data[nvp->pos]; 173 sol = (char *)&nvp->data[nvp->pos];
174 eoc = strchr(sol, '\n'); 174 eoc = strchr(sol, '\n');
175 if (!eoc) { 175 if (!eoc) {
176 eoc = strchr(sol, '\0'); 176 eoc = strchr(sol, '\0');
@@ -201,17 +201,17 @@ static enum nvram_parser_state
201}; 201};
202 202
203static int brcmf_init_nvram_parser(struct nvram_parser *nvp, 203static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
204 const struct firmware *nv) 204 const u8 *data, size_t data_len)
205{ 205{
206 size_t size; 206 size_t size;
207 207
208 memset(nvp, 0, sizeof(*nvp)); 208 memset(nvp, 0, sizeof(*nvp));
209 nvp->fwnv = nv; 209 nvp->data = data;
210 /* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */ 210 /* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */
211 if (nv->size > BRCMF_FW_MAX_NVRAM_SIZE) 211 if (data_len > BRCMF_FW_MAX_NVRAM_SIZE)
212 size = BRCMF_FW_MAX_NVRAM_SIZE; 212 size = BRCMF_FW_MAX_NVRAM_SIZE;
213 else 213 else
214 size = nv->size; 214 size = data_len;
215 /* Alloc for extra 0 byte + roundup by 4 + length field */ 215 /* Alloc for extra 0 byte + roundup by 4 + length field */
216 size += 1 + 3 + sizeof(u32); 216 size += 1 + 3 + sizeof(u32);
217 nvp->nvram = kzalloc(size, GFP_KERNEL); 217 nvp->nvram = kzalloc(size, GFP_KERNEL);
@@ -232,6 +232,8 @@ static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr,
232 u16 bus_nr) 232 u16 bus_nr)
233{ 233{
234 /* Device path with a leading '=' key-value separator */ 234 /* Device path with a leading '=' key-value separator */
235 char pci_path[] = "=pci/?/?";
236 size_t pci_len;
235 char pcie_path[] = "=pcie/?/?"; 237 char pcie_path[] = "=pcie/?/?";
236 size_t pcie_len; 238 size_t pcie_len;
237 239
@@ -251,6 +253,9 @@ static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr,
251 /* First search for the devpathX and see if it is the configuration 253 /* First search for the devpathX and see if it is the configuration
252 * for domain_nr/bus_nr. Search complete nvp 254 * for domain_nr/bus_nr. Search complete nvp
253 */ 255 */
256 snprintf(pci_path, sizeof(pci_path), "=pci/%d/%d", domain_nr,
257 bus_nr);
258 pci_len = strlen(pci_path);
254 snprintf(pcie_path, sizeof(pcie_path), "=pcie/%d/%d", domain_nr, 259 snprintf(pcie_path, sizeof(pcie_path), "=pcie/%d/%d", domain_nr,
255 bus_nr); 260 bus_nr);
256 pcie_len = strlen(pcie_path); 261 pcie_len = strlen(pcie_path);
@@ -260,8 +265,9 @@ static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr,
260 /* Format: devpathX=pcie/Y/Z/ 265 /* Format: devpathX=pcie/Y/Z/
261 * Y = domain_nr, Z = bus_nr, X = virtual ID 266 * Y = domain_nr, Z = bus_nr, X = virtual ID
262 */ 267 */
263 if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) && 268 if (strncmp(&nvp->nvram[i], "devpath", 7) == 0 &&
264 (strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len) == 0)) { 269 (!strncmp(&nvp->nvram[i + 8], pci_path, pci_len) ||
270 !strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len))) {
265 id = nvp->nvram[i + 7] - '0'; 271 id = nvp->nvram[i + 7] - '0';
266 found = true; 272 found = true;
267 break; 273 break;
@@ -356,18 +362,18 @@ fail:
356 * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. 362 * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
357 * End of buffer is completed with token identifying length of buffer. 363 * End of buffer is completed with token identifying length of buffer.
358 */ 364 */
359static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length, 365static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len,
360 u16 domain_nr, u16 bus_nr) 366 u32 *new_length, u16 domain_nr, u16 bus_nr)
361{ 367{
362 struct nvram_parser nvp; 368 struct nvram_parser nvp;
363 u32 pad; 369 u32 pad;
364 u32 token; 370 u32 token;
365 __le32 token_le; 371 __le32 token_le;
366 372
367 if (brcmf_init_nvram_parser(&nvp, nv) < 0) 373 if (brcmf_init_nvram_parser(&nvp, data, data_len) < 0)
368 return NULL; 374 return NULL;
369 375
370 while (nvp.pos < nv->size) { 376 while (nvp.pos < data_len) {
371 nvp.state = nv_parser_states[nvp.state](&nvp); 377 nvp.state = nv_parser_states[nvp.state](&nvp);
372 if (nvp.state == END) 378 if (nvp.state == END)
373 break; 379 break;
@@ -426,7 +432,7 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
426 goto fail; 432 goto fail;
427 433
428 if (fw) { 434 if (fw) {
429 nvram = brcmf_fw_nvram_strip(fw, &nvram_length, 435 nvram = brcmf_fw_nvram_strip(fw->data, fw->size, &nvram_length,
430 fwctx->domain_nr, fwctx->bus_nr); 436 fwctx->domain_nr, fwctx->bus_nr);
431 release_firmware(fw); 437 release_firmware(fw);
432 if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) 438 if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
index 374920965108..297911f38fa0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -32,7 +32,11 @@
32#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ 32#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */
33#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002 33#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002
34 34
35#define BRCMF_STA_ASSOC 0x10 /* Associated */ 35#define BRCMF_STA_WME 0x00000002 /* WMM association */
36#define BRCMF_STA_AUTHE 0x00000008 /* Authenticated */
37#define BRCMF_STA_ASSOC 0x00000010 /* Associated */
38#define BRCMF_STA_AUTHO 0x00000020 /* Authorized */
39#define BRCMF_STA_SCBSTATS 0x00004000 /* Per STA debug stats */
36 40
37/* size of brcmf_scan_params not including variable length array */ 41/* size of brcmf_scan_params not including variable length array */
38#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 42#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
@@ -113,6 +117,7 @@
113#define BRCMF_WOWL_MAXPATTERNSIZE 128 117#define BRCMF_WOWL_MAXPATTERNSIZE 128
114 118
115#define BRCMF_COUNTRY_BUF_SZ 4 119#define BRCMF_COUNTRY_BUF_SZ 4
120#define BRCMF_ANT_MAX 4
116 121
117/* join preference types for join_pref iovar */ 122/* join preference types for join_pref iovar */
118enum brcmf_join_pref_types { 123enum brcmf_join_pref_types {
@@ -456,25 +461,61 @@ struct brcmf_channel_info_le {
456}; 461};
457 462
458struct brcmf_sta_info_le { 463struct brcmf_sta_info_le {
459 __le16 ver; /* version of this struct */ 464 __le16 ver; /* version of this struct */
460 __le16 len; /* length in bytes of this structure */ 465 __le16 len; /* length in bytes of this structure */
461 __le16 cap; /* sta's advertised capabilities */ 466 __le16 cap; /* sta's advertised capabilities */
462 __le32 flags; /* flags defined below */ 467 __le32 flags; /* flags defined below */
463 __le32 idle; /* time since data pkt rx'd from sta */ 468 __le32 idle; /* time since data pkt rx'd from sta */
464 u8 ea[ETH_ALEN]; /* Station address */ 469 u8 ea[ETH_ALEN]; /* Station address */
465 __le32 count; /* # rates in this set */ 470 __le32 count; /* # rates in this set */
466 u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ 471 u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */
467 /* w/hi bit set if basic */ 472 /* w/hi bit set if basic */
468 __le32 in; /* seconds elapsed since associated */ 473 __le32 in; /* seconds elapsed since associated */
469 __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ 474 __le32 listen_interval_inms; /* Min Listen interval in ms for STA */
470 __le32 tx_pkts; /* # of packets transmitted */ 475 __le32 tx_pkts; /* # of packets transmitted */
471 __le32 tx_failures; /* # of packets failed */ 476 __le32 tx_failures; /* # of packets failed */
472 __le32 rx_ucast_pkts; /* # of unicast packets received */ 477 __le32 rx_ucast_pkts; /* # of unicast packets received */
473 __le32 rx_mcast_pkts; /* # of multicast packets received */ 478 __le32 rx_mcast_pkts; /* # of multicast packets received */
474 __le32 tx_rate; /* Rate of last successful tx frame */ 479 __le32 tx_rate; /* Rate of last successful tx frame */
475 __le32 rx_rate; /* Rate of last successful rx frame */ 480 __le32 rx_rate; /* Rate of last successful rx frame */
476 __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ 481 __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
477 __le32 rx_decrypt_failures; /* # of packet decrypted failed */ 482 __le32 rx_decrypt_failures; /* # of packet decrypted failed */
483 __le32 tx_tot_pkts; /* # of tx pkts (ucast + mcast) */
484 __le32 rx_tot_pkts; /* # of data packets recvd (uni + mcast) */
485 __le32 tx_mcast_pkts; /* # of mcast pkts txed */
486 __le64 tx_tot_bytes; /* data bytes txed (ucast + mcast) */
487 __le64 rx_tot_bytes; /* data bytes recvd (ucast + mcast) */
488 __le64 tx_ucast_bytes; /* data bytes txed (ucast) */
489 __le64 tx_mcast_bytes; /* # data bytes txed (mcast) */
490 __le64 rx_ucast_bytes; /* data bytes recvd (ucast) */
491 __le64 rx_mcast_bytes; /* data bytes recvd (mcast) */
492 s8 rssi[BRCMF_ANT_MAX]; /* per antenna rssi */
493 s8 nf[BRCMF_ANT_MAX]; /* per antenna noise floor */
494 __le16 aid; /* association ID */
495 __le16 ht_capabilities; /* advertised ht caps */
496 __le16 vht_flags; /* converted vht flags */
497 __le32 tx_pkts_retry_cnt; /* # of frames where a retry was
498 * exhausted.
499 */
500 __le32 tx_pkts_retry_exhausted; /* # of user frames where a retry
501 * was exhausted
502 */
503 s8 rx_lastpkt_rssi[BRCMF_ANT_MAX]; /* Per antenna RSSI of last
504 * received data frame.
505 */
506 /* TX WLAN retry/failure statistics:
507 * Separated for host requested frames and locally generated frames.
508 * Include unicast frame only where the retries/failures can be counted.
509 */
510 __le32 tx_pkts_total; /* # user frames sent successfully */
511 __le32 tx_pkts_retries; /* # user frames retries */
512 __le32 tx_pkts_fw_total; /* # FW generated sent successfully */
513 __le32 tx_pkts_fw_retries; /* # retries for FW generated frames */
514 __le32 tx_pkts_fw_retry_exhausted; /* # FW generated where a retry
515 * was exhausted
516 */
517 __le32 rx_pkts_retried; /* # rx with retry bit set */
518 __le32 tx_rate_fallback; /* lowest fallback TX rate */
478}; 519};
479 520
480struct brcmf_chanspec_list { 521struct brcmf_chanspec_list {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
index 1b47de067d25..898c3801e658 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -75,6 +75,8 @@
75 75
76#define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 96 76#define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 96
77#define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32 77#define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32
78#define BRCMF_MSGBUF_UPDATE_RX_PTR_THRS 48
79
78 80
79struct msgbuf_common_hdr { 81struct msgbuf_common_hdr {
80 u8 msgtype; 82 u8 msgtype;
@@ -1257,19 +1259,27 @@ static void brcmf_msgbuf_process_rx(struct brcmf_msgbuf *msgbuf,
1257{ 1259{
1258 void *buf; 1260 void *buf;
1259 u16 count; 1261 u16 count;
1262 u16 processed;
1260 1263
1261again: 1264again:
1262 buf = brcmf_commonring_get_read_ptr(commonring, &count); 1265 buf = brcmf_commonring_get_read_ptr(commonring, &count);
1263 if (buf == NULL) 1266 if (buf == NULL)
1264 return; 1267 return;
1265 1268
1269 processed = 0;
1266 while (count) { 1270 while (count) {
1267 brcmf_msgbuf_process_msgtype(msgbuf, 1271 brcmf_msgbuf_process_msgtype(msgbuf,
1268 buf + msgbuf->rx_dataoffset); 1272 buf + msgbuf->rx_dataoffset);
1269 buf += brcmf_commonring_len_item(commonring); 1273 buf += brcmf_commonring_len_item(commonring);
1274 processed++;
1275 if (processed == BRCMF_MSGBUF_UPDATE_RX_PTR_THRS) {
1276 brcmf_commonring_read_complete(commonring, processed);
1277 processed = 0;
1278 }
1270 count--; 1279 count--;
1271 } 1280 }
1272 brcmf_commonring_read_complete(commonring); 1281 if (processed)
1282 brcmf_commonring_read_complete(commonring, processed);
1273 1283
1274 if (commonring->r_ptr == 0) 1284 if (commonring->r_ptr == 0)
1275 goto again; 1285 goto again;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 710fbe570eb2..a9ba775a24c1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -16,6 +16,7 @@
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/netdevice.h> 17#include <linux/netdevice.h>
18#include <linux/etherdevice.h> 18#include <linux/etherdevice.h>
19#include <linux/rtnetlink.h>
19#include <net/cfg80211.h> 20#include <net/cfg80211.h>
20 21
21#include <brcmu_wifi.h> 22#include <brcmu_wifi.h>
@@ -1908,105 +1909,6 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
1908 1909
1909 1910
1910/** 1911/**
1911 * brcmf_p2p_attach() - attach for P2P.
1912 *
1913 * @cfg: driver private data for cfg80211 interface.
1914 */
1915s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
1916{
1917 struct brcmf_if *pri_ifp;
1918 struct brcmf_if *p2p_ifp;
1919 struct brcmf_cfg80211_vif *p2p_vif;
1920 struct brcmf_p2p_info *p2p;
1921 struct brcmf_pub *drvr;
1922 s32 bssidx;
1923 s32 err = 0;
1924
1925 p2p = &cfg->p2p;
1926 p2p->cfg = cfg;
1927
1928 drvr = cfg->pub;
1929
1930 pri_ifp = drvr->iflist[0];
1931 p2p_ifp = drvr->iflist[1];
1932
1933 p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
1934
1935 if (p2p_ifp) {
1936 p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE,
1937 false);
1938 if (IS_ERR(p2p_vif)) {
1939 brcmf_err("could not create discovery vif\n");
1940 err = -ENOMEM;
1941 goto exit;
1942 }
1943
1944 p2p_vif->ifp = p2p_ifp;
1945 p2p_ifp->vif = p2p_vif;
1946 p2p_vif->wdev.netdev = p2p_ifp->ndev;
1947 p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev;
1948 SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy));
1949
1950 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
1951
1952 brcmf_p2p_generate_bss_mac(p2p, NULL);
1953 memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
1954 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
1955
1956 /* Initialize P2P Discovery in the firmware */
1957 err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
1958 if (err < 0) {
1959 brcmf_err("set p2p_disc error\n");
1960 brcmf_free_vif(p2p_vif);
1961 goto exit;
1962 }
1963 /* obtain bsscfg index for P2P discovery */
1964 err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
1965 if (err < 0) {
1966 brcmf_err("retrieving discover bsscfg index failed\n");
1967 brcmf_free_vif(p2p_vif);
1968 goto exit;
1969 }
1970 /* Verify that firmware uses same bssidx as driver !! */
1971 if (p2p_ifp->bssidx != bssidx) {
1972 brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
1973 bssidx, p2p_ifp->bssidx);
1974 brcmf_free_vif(p2p_vif);
1975 goto exit;
1976 }
1977
1978 init_completion(&p2p->send_af_done);
1979 INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
1980 init_completion(&p2p->afx_hdl.act_frm_scan);
1981 init_completion(&p2p->wait_next_af);
1982 }
1983exit:
1984 return err;
1985}
1986
1987
1988/**
1989 * brcmf_p2p_detach() - detach P2P.
1990 *
1991 * @p2p: P2P specific data.
1992 */
1993void brcmf_p2p_detach(struct brcmf_p2p_info *p2p)
1994{
1995 struct brcmf_cfg80211_vif *vif;
1996
1997 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
1998 if (vif != NULL) {
1999 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
2000 brcmf_p2p_deinit_discovery(p2p);
2001 /* remove discovery interface */
2002 brcmf_free_vif(vif);
2003 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
2004 }
2005 /* just set it all to zero */
2006 memset(p2p, 0, sizeof(*p2p));
2007}
2008
2009/**
2010 * brcmf_p2p_get_current_chanspec() - Get current operation channel. 1912 * brcmf_p2p_get_current_chanspec() - Get current operation channel.
2011 * 1913 *
2012 * @p2p: P2P specific data. 1914 * @p2p: P2P specific data.
@@ -2238,6 +2140,7 @@ static void brcmf_p2p_delete_p2pdev(struct brcmf_p2p_info *p2p,
2238{ 2140{
2239 cfg80211_unregister_wdev(&vif->wdev); 2141 cfg80211_unregister_wdev(&vif->wdev);
2240 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; 2142 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
2143 brcmf_remove_interface(vif->ifp->drvr, vif->ifp->bssidx);
2241 brcmf_free_vif(vif); 2144 brcmf_free_vif(vif);
2242} 2145}
2243 2146
@@ -2364,6 +2267,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2364 break; 2267 break;
2365 2268
2366 case NL80211_IFTYPE_P2P_DEVICE: 2269 case NL80211_IFTYPE_P2P_DEVICE:
2270 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
2271 brcmf_p2p_deinit_discovery(p2p);
2367 brcmf_p2p_delete_p2pdev(p2p, vif); 2272 brcmf_p2p_delete_p2pdev(p2p, vif);
2368 return 0; 2273 return 0;
2369 default: 2274 default:
@@ -2425,3 +2330,103 @@ void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev)
2425 clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state); 2330 clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state);
2426 mutex_unlock(&cfg->usr_sync); 2331 mutex_unlock(&cfg->usr_sync);
2427} 2332}
2333
2334/**
2335 * brcmf_p2p_attach() - attach for P2P.
2336 *
2337 * @cfg: driver private data for cfg80211 interface.
2338 */
2339s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
2340{
2341 struct brcmf_if *pri_ifp;
2342 struct brcmf_if *p2p_ifp;
2343 struct brcmf_cfg80211_vif *p2p_vif;
2344 struct brcmf_p2p_info *p2p;
2345 struct brcmf_pub *drvr;
2346 s32 bssidx;
2347 s32 err = 0;
2348
2349 p2p = &cfg->p2p;
2350 p2p->cfg = cfg;
2351
2352 drvr = cfg->pub;
2353
2354 pri_ifp = drvr->iflist[0];
2355 p2p_ifp = drvr->iflist[1];
2356
2357 p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
2358
2359 if (p2p_ifp) {
2360 p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE,
2361 false);
2362 if (IS_ERR(p2p_vif)) {
2363 brcmf_err("could not create discovery vif\n");
2364 err = -ENOMEM;
2365 goto exit;
2366 }
2367
2368 p2p_vif->ifp = p2p_ifp;
2369 p2p_ifp->vif = p2p_vif;
2370 p2p_vif->wdev.netdev = p2p_ifp->ndev;
2371 p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev;
2372 SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy));
2373
2374 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
2375
2376 brcmf_p2p_generate_bss_mac(p2p, NULL);
2377 memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
2378 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
2379
2380 /* Initialize P2P Discovery in the firmware */
2381 err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
2382 if (err < 0) {
2383 brcmf_err("set p2p_disc error\n");
2384 brcmf_free_vif(p2p_vif);
2385 goto exit;
2386 }
2387 /* obtain bsscfg index for P2P discovery */
2388 err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
2389 if (err < 0) {
2390 brcmf_err("retrieving discover bsscfg index failed\n");
2391 brcmf_free_vif(p2p_vif);
2392 goto exit;
2393 }
2394 /* Verify that firmware uses same bssidx as driver !! */
2395 if (p2p_ifp->bssidx != bssidx) {
2396 brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
2397 bssidx, p2p_ifp->bssidx);
2398 brcmf_free_vif(p2p_vif);
2399 goto exit;
2400 }
2401
2402 init_completion(&p2p->send_af_done);
2403 INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
2404 init_completion(&p2p->afx_hdl.act_frm_scan);
2405 init_completion(&p2p->wait_next_af);
2406 }
2407exit:
2408 return err;
2409}
2410
2411/**
2412 * brcmf_p2p_detach() - detach P2P.
2413 *
2414 * @p2p: P2P specific data.
2415 */
2416void brcmf_p2p_detach(struct brcmf_p2p_info *p2p)
2417{
2418 struct brcmf_cfg80211_vif *vif;
2419
2420 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
2421 if (vif != NULL) {
2422 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
2423 brcmf_p2p_deinit_discovery(p2p);
2424 /* remove discovery interface */
2425 rtnl_lock();
2426 brcmf_p2p_delete_p2pdev(p2p, vif);
2427 rtnl_unlock();
2428 }
2429 /* just set it all to zero */
2430 memset(p2p, 0, sizeof(*p2p));
2431}
2432
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
index 37a2624d7bba..3a98c4306d1d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
@@ -1629,20 +1629,7 @@ static void brcmf_pcie_buscore_write32(void *ctx, u32 addr, u32 value)
1629 1629
1630static int brcmf_pcie_buscoreprep(void *ctx) 1630static int brcmf_pcie_buscoreprep(void *ctx)
1631{ 1631{
1632 struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; 1632 return brcmf_pcie_get_resource(ctx);
1633 int err;
1634
1635 err = brcmf_pcie_get_resource(devinfo);
1636 if (err == 0) {
1637 /* Set CC watchdog to reset all the cores on the chip to bring
1638 * back dongle to a sane state.
1639 */
1640 brcmf_pcie_buscore_write32(ctx, CORE_CC_REG(SI_ENUM_BASE,
1641 watchdog), 4);
1642 msleep(100);
1643 }
1644
1645 return err;
1646} 1633}
1647 1634
1648 1635
@@ -1824,6 +1811,7 @@ brcmf_pcie_remove(struct pci_dev *pdev)
1824 brcmf_pcie_intr_disable(devinfo); 1811 brcmf_pcie_intr_disable(devinfo);
1825 1812
1826 brcmf_detach(&pdev->dev); 1813 brcmf_detach(&pdev->dev);
1814 brcmf_pcie_reset_device(devinfo);
1827 1815
1828 kfree(bus->bus_priv.pcie); 1816 kfree(bus->bus_priv.pcie);
1829 kfree(bus->msgbuf->flowrings); 1817 kfree(bus->msgbuf->flowrings);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index bf7a8b1ad914..d36f5f3d931b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -2820,6 +2820,8 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2820 struct brcmf_sdio *bus = sdiodev->bus; 2820 struct brcmf_sdio *bus = sdiodev->bus;
2821 2821
2822 brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len); 2822 brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len);
2823 if (sdiodev->state != BRCMF_SDIOD_DATA)
2824 return -EIO;
2823 2825
2824 /* Add space for the header */ 2826 /* Add space for the header */
2825 skb_push(pkt, bus->tx_hdrlen); 2827 skb_push(pkt, bus->tx_hdrlen);
@@ -2948,6 +2950,8 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2948 int ret; 2950 int ret;
2949 2951
2950 brcmf_dbg(TRACE, "Enter\n"); 2952 brcmf_dbg(TRACE, "Enter\n");
2953 if (sdiodev->state != BRCMF_SDIOD_DATA)
2954 return -EIO;
2951 2955
2952 /* Send from dpc */ 2956 /* Send from dpc */
2953 bus->ctrl_frame_buf = msg; 2957 bus->ctrl_frame_buf = msg;
@@ -3238,6 +3242,8 @@ brcmf_sdio_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
3238 struct brcmf_sdio *bus = sdiodev->bus; 3242 struct brcmf_sdio *bus = sdiodev->bus;
3239 3243
3240 brcmf_dbg(TRACE, "Enter\n"); 3244 brcmf_dbg(TRACE, "Enter\n");
3245 if (sdiodev->state != BRCMF_SDIOD_DATA)
3246 return -EIO;
3241 3247
3242 /* Wait until control frame is available */ 3248 /* Wait until control frame is available */
3243 timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending); 3249 timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending);
diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.c b/drivers/net/wireless/mediatek/mt7601u/dma.c
index 9c9e1288644b..7217da4f1543 100644
--- a/drivers/net/wireless/mediatek/mt7601u/dma.c
+++ b/drivers/net/wireless/mediatek/mt7601u/dma.c
@@ -34,56 +34,32 @@ static unsigned int ieee80211_get_hdrlen_from_buf(const u8 *data, unsigned len)
34 34
35static struct sk_buff * 35static struct sk_buff *
36mt7601u_rx_skb_from_seg(struct mt7601u_dev *dev, struct mt7601u_rxwi *rxwi, 36mt7601u_rx_skb_from_seg(struct mt7601u_dev *dev, struct mt7601u_rxwi *rxwi,
37 u8 *data, u32 seg_len) 37 void *data, u32 seg_len, u32 truesize, struct page *p)
38{ 38{
39 struct sk_buff *skb; 39 struct sk_buff *skb;
40 u32 true_len; 40 u32 true_len, hdr_len = 0, copy, frag;
41 41
42 if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) 42 skb = alloc_skb(p ? 128 : seg_len, GFP_ATOMIC);
43 seg_len -= 2;
44
45 skb = alloc_skb(seg_len, GFP_ATOMIC);
46 if (!skb)
47 return NULL;
48
49 if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) {
50 int hdr_len = ieee80211_get_hdrlen_from_buf(data, seg_len);
51
52 memcpy(skb_put(skb, hdr_len), data, hdr_len);
53 data += hdr_len + 2;
54 seg_len -= hdr_len;
55 }
56
57 memcpy(skb_put(skb, seg_len), data, seg_len);
58
59 true_len = mt76_mac_process_rx(dev, skb, skb->data, rxwi);
60 skb_trim(skb, true_len);
61
62 return skb;
63}
64
65static struct sk_buff *
66mt7601u_rx_skb_from_seg_paged(struct mt7601u_dev *dev,
67 struct mt7601u_rxwi *rxwi, void *data,
68 u32 seg_len, u32 truesize, struct page *p)
69{
70 unsigned int hdr_len = ieee80211_get_hdrlen_from_buf(data, seg_len);
71 unsigned int true_len, copy, frag;
72 struct sk_buff *skb;
73
74 skb = alloc_skb(128, GFP_ATOMIC);
75 if (!skb) 43 if (!skb)
76 return NULL; 44 return NULL;
77 45
78 true_len = mt76_mac_process_rx(dev, skb, data, rxwi); 46 true_len = mt76_mac_process_rx(dev, skb, data, rxwi);
47 if (!true_len || true_len > seg_len)
48 goto bad_frame;
49
50 hdr_len = ieee80211_get_hdrlen_from_buf(data, true_len);
51 if (!hdr_len)
52 goto bad_frame;
79 53
80 if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) { 54 if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) {
81 memcpy(skb_put(skb, hdr_len), data, hdr_len); 55 memcpy(skb_put(skb, hdr_len), data, hdr_len);
56
82 data += hdr_len + 2; 57 data += hdr_len + 2;
83 true_len -= hdr_len; 58 true_len -= hdr_len;
84 hdr_len = 0; 59 hdr_len = 0;
85 } 60 }
86 61
62 /* If not doing paged RX allocated skb will always have enough space */
87 copy = (true_len <= skb_tailroom(skb)) ? true_len : hdr_len + 8; 63 copy = (true_len <= skb_tailroom(skb)) ? true_len : hdr_len + 8;
88 frag = true_len - copy; 64 frag = true_len - copy;
89 65
@@ -97,10 +73,16 @@ mt7601u_rx_skb_from_seg_paged(struct mt7601u_dev *dev,
97 } 73 }
98 74
99 return skb; 75 return skb;
76
77bad_frame:
78 dev_err_ratelimited(dev->dev, "Error: incorrect frame len:%u hdr:%u\n",
79 true_len, hdr_len);
80 dev_kfree_skb(skb);
81 return NULL;
100} 82}
101 83
102static void mt7601u_rx_process_seg(struct mt7601u_dev *dev, u8 *data, 84static void mt7601u_rx_process_seg(struct mt7601u_dev *dev, u8 *data,
103 u32 seg_len, struct page *p, bool paged) 85 u32 seg_len, struct page *p)
104{ 86{
105 struct sk_buff *skb; 87 struct sk_buff *skb;
106 struct mt7601u_rxwi *rxwi; 88 struct mt7601u_rxwi *rxwi;
@@ -126,11 +108,7 @@ static void mt7601u_rx_process_seg(struct mt7601u_dev *dev, u8 *data,
126 108
127 trace_mt_rx(dev, rxwi, fce_info); 109 trace_mt_rx(dev, rxwi, fce_info);
128 110
129 if (paged) 111 skb = mt7601u_rx_skb_from_seg(dev, rxwi, data, seg_len, truesize, p);
130 skb = mt7601u_rx_skb_from_seg_paged(dev, rxwi, data, seg_len,
131 truesize, p);
132 else
133 skb = mt7601u_rx_skb_from_seg(dev, rxwi, data, seg_len);
134 if (!skb) 112 if (!skb)
135 return; 113 return;
136 114
@@ -158,23 +136,17 @@ mt7601u_rx_process_entry(struct mt7601u_dev *dev, struct mt7601u_dma_buf_rx *e)
158 u32 seg_len, data_len = e->urb->actual_length; 136 u32 seg_len, data_len = e->urb->actual_length;
159 u8 *data = page_address(e->p); 137 u8 *data = page_address(e->p);
160 struct page *new_p = NULL; 138 struct page *new_p = NULL;
161 bool paged = true;
162 int cnt = 0; 139 int cnt = 0;
163 140
164 if (!test_bit(MT7601U_STATE_INITIALIZED, &dev->state)) 141 if (!test_bit(MT7601U_STATE_INITIALIZED, &dev->state))
165 return; 142 return;
166 143
167 /* Copy if there is very little data in the buffer. */ 144 /* Copy if there is very little data in the buffer. */
168 if (data_len < 512) { 145 if (data_len > 512)
169 paged = false;
170 } else {
171 new_p = dev_alloc_pages(MT_RX_ORDER); 146 new_p = dev_alloc_pages(MT_RX_ORDER);
172 if (!new_p)
173 paged = false;
174 }
175 147
176 while ((seg_len = mt7601u_rx_next_seg_len(data, data_len))) { 148 while ((seg_len = mt7601u_rx_next_seg_len(data, data_len))) {
177 mt7601u_rx_process_seg(dev, data, seg_len, e->p, paged); 149 mt7601u_rx_process_seg(dev, data, seg_len, new_p ? e->p : NULL);
178 150
179 data_len -= seg_len; 151 data_len -= seg_len;
180 data += seg_len; 152 data += seg_len;
@@ -182,9 +154,9 @@ mt7601u_rx_process_entry(struct mt7601u_dev *dev, struct mt7601u_dma_buf_rx *e)
182 } 154 }
183 155
184 if (cnt > 1) 156 if (cnt > 1)
185 trace_mt_rx_dma_aggr(dev, cnt, paged); 157 trace_mt_rx_dma_aggr(dev, cnt, !!new_p);
186 158
187 if (paged) { 159 if (new_p) {
188 /* we have one extra ref from the allocator */ 160 /* we have one extra ref from the allocator */
189 __free_pages(e->p, MT_RX_ORDER); 161 __free_pages(e->p, MT_RX_ORDER);
190 162
diff --git a/drivers/net/wireless/mediatek/mt7601u/eeprom.c b/drivers/net/wireless/mediatek/mt7601u/eeprom.c
index ce3837f270f0..8d8ee0344f7b 100644
--- a/drivers/net/wireless/mediatek/mt7601u/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt7601u/eeprom.c
@@ -277,6 +277,10 @@ mt7601u_extra_power_over_mac(struct mt7601u_dev *dev)
277static void 277static void
278mt7601u_set_power_rate(struct power_per_rate *rate, s8 delta, u8 value) 278mt7601u_set_power_rate(struct power_per_rate *rate, s8 delta, u8 value)
279{ 279{
280 /* Invalid? Note: vendor driver does not handle this */
281 if (value == 0xff)
282 return;
283
280 rate->raw = s6_validate(value); 284 rate->raw = s6_validate(value);
281 rate->bw20 = s6_to_int(value); 285 rate->bw20 = s6_to_int(value);
282 /* Note: vendor driver does cap the value to s6 right away */ 286 /* Note: vendor driver does cap the value to s6 right away */
diff --git a/drivers/net/wireless/mediatek/mt7601u/init.c b/drivers/net/wireless/mediatek/mt7601u/init.c
index ca1ea2e55ff4..df3dd56199a7 100644
--- a/drivers/net/wireless/mediatek/mt7601u/init.c
+++ b/drivers/net/wireless/mediatek/mt7601u/init.c
@@ -427,6 +427,9 @@ err:
427 427
428void mt7601u_cleanup(struct mt7601u_dev *dev) 428void mt7601u_cleanup(struct mt7601u_dev *dev)
429{ 429{
430 if (!test_and_clear_bit(MT7601U_STATE_INITIALIZED, &dev->state))
431 return;
432
430 mt7601u_stop_hardware(dev); 433 mt7601u_stop_hardware(dev);
431 mt7601u_dma_cleanup(dev); 434 mt7601u_dma_cleanup(dev);
432 mt7601u_mcu_cmd_deinit(dev); 435 mt7601u_mcu_cmd_deinit(dev);
diff --git a/drivers/net/wireless/mediatek/mt7601u/mac.c b/drivers/net/wireless/mediatek/mt7601u/mac.c
index c161bcc6a7fa..7514bce1ac91 100644
--- a/drivers/net/wireless/mediatek/mt7601u/mac.c
+++ b/drivers/net/wireless/mediatek/mt7601u/mac.c
@@ -450,10 +450,14 @@ u32 mt76_mac_process_rx(struct mt7601u_dev *dev, struct sk_buff *skb,
450{ 450{
451 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 451 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
452 struct mt7601u_rxwi *rxwi = rxi; 452 struct mt7601u_rxwi *rxwi = rxi;
453 u32 ctl = le32_to_cpu(rxwi->ctl); 453 u32 len, ctl = le32_to_cpu(rxwi->ctl);
454 u16 rate = le16_to_cpu(rxwi->rate); 454 u16 rate = le16_to_cpu(rxwi->rate);
455 int rssi; 455 int rssi;
456 456
457 len = MT76_GET(MT_RXWI_CTL_MPDU_LEN, ctl);
458 if (len < 10)
459 return 0;
460
457 if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_DECRYPT)) { 461 if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_DECRYPT)) {
458 status->flag |= RX_FLAG_DECRYPTED; 462 status->flag |= RX_FLAG_DECRYPTED;
459 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; 463 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
@@ -474,7 +478,7 @@ u32 mt76_mac_process_rx(struct mt7601u_dev *dev, struct sk_buff *skb,
474 dev->avg_rssi = (dev->avg_rssi * 15) / 16 + (rssi << 8); 478 dev->avg_rssi = (dev->avg_rssi * 15) / 16 + (rssi << 8);
475 spin_unlock_bh(&dev->con_mon_lock); 479 spin_unlock_bh(&dev->con_mon_lock);
476 480
477 return MT76_GET(MT_RXWI_CTL_MPDU_LEN, ctl); 481 return len;
478} 482}
479 483
480static enum mt76_cipher_type 484static enum mt76_cipher_type
diff --git a/drivers/net/wireless/mediatek/mt7601u/main.c b/drivers/net/wireless/mediatek/mt7601u/main.c
index ced82abb414f..169384b48b27 100644
--- a/drivers/net/wireless/mediatek/mt7601u/main.c
+++ b/drivers/net/wireless/mediatek/mt7601u/main.c
@@ -119,6 +119,7 @@ mt76_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
119 119
120 dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS; 120 dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS;
121 121
122 MT76_FILTER(OTHER_BSS, MT_RX_FILTR_CFG_PROMISC);
122 MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR); 123 MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR);
123 MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR); 124 MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR);
124 MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK | 125 MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK |
diff --git a/drivers/net/wireless/mediatek/mt7601u/usb.c b/drivers/net/wireless/mediatek/mt7601u/usb.c
index 99e2b3997bfa..54dba4001865 100644
--- a/drivers/net/wireless/mediatek/mt7601u/usb.c
+++ b/drivers/net/wireless/mediatek/mt7601u/usb.c
@@ -338,8 +338,15 @@ static int mt7601u_suspend(struct usb_interface *usb_intf, pm_message_t state)
338static int mt7601u_resume(struct usb_interface *usb_intf) 338static int mt7601u_resume(struct usb_interface *usb_intf)
339{ 339{
340 struct mt7601u_dev *dev = usb_get_intfdata(usb_intf); 340 struct mt7601u_dev *dev = usb_get_intfdata(usb_intf);
341 int ret;
342
343 ret = mt7601u_init_hardware(dev);
344 if (ret)
345 return ret;
346
347 set_bit(MT7601U_STATE_INITIALIZED, &dev->state);
341 348
342 return mt7601u_init_hardware(dev); 349 return 0;
343} 350}
344 351
345MODULE_DEVICE_TABLE(usb, mt7601u_device_table); 352MODULE_DEVICE_TABLE(usb, mt7601u_device_table);
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
index 65cd461c88db..71a1b580796f 100644
--- a/drivers/net/wireless/mwifiex/11h.c
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -161,19 +161,38 @@ int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv,
161 cr_req->chan_desc.chan_width = radar_params->chandef->width; 161 cr_req->chan_desc.chan_width = radar_params->chandef->width;
162 cr_req->msec_dwell_time = cpu_to_le32(radar_params->cac_time_ms); 162 cr_req->msec_dwell_time = cpu_to_le32(radar_params->cac_time_ms);
163 163
164 mwifiex_dbg(priv->adapter, MSG, 164 if (radar_params->cac_time_ms)
165 "11h: issuing DFS Radar check for channel=%d\n", 165 mwifiex_dbg(priv->adapter, MSG,
166 radar_params->chandef->chan->hw_value); 166 "11h: issuing DFS Radar check for channel=%d\n",
167 radar_params->chandef->chan->hw_value);
168 else
169 mwifiex_dbg(priv->adapter, MSG, "cancelling CAC\n");
167 170
168 return 0; 171 return 0;
169} 172}
170 173
174int mwifiex_stop_radar_detection(struct mwifiex_private *priv,
175 struct cfg80211_chan_def *chandef)
176{
177 struct mwifiex_radar_params radar_params;
178
179 memset(&radar_params, 0, sizeof(struct mwifiex_radar_params));
180 radar_params.chandef = chandef;
181 radar_params.cac_time_ms = 0;
182
183 return mwifiex_send_cmd(priv, HostCmd_CMD_CHAN_REPORT_REQUEST,
184 HostCmd_ACT_GEN_SET, 0, &radar_params, true);
185}
186
171/* This function is to abort ongoing CAC upon stopping AP operations 187/* This function is to abort ongoing CAC upon stopping AP operations
172 * or during unload. 188 * or during unload.
173 */ 189 */
174void mwifiex_abort_cac(struct mwifiex_private *priv) 190void mwifiex_abort_cac(struct mwifiex_private *priv)
175{ 191{
176 if (priv->wdev.cac_started) { 192 if (priv->wdev.cac_started) {
193 if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
194 mwifiex_dbg(priv->adapter, ERROR,
195 "failed to stop CAC in FW\n");
177 mwifiex_dbg(priv->adapter, MSG, 196 mwifiex_dbg(priv->adapter, MSG,
178 "Aborting delayed work for CAC.\n"); 197 "Aborting delayed work for CAC.\n");
179 cancel_delayed_work_sync(&priv->dfs_cac_work); 198 cancel_delayed_work_sync(&priv->dfs_cac_work);
@@ -245,6 +264,9 @@ int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,
245 if (le32_to_cpu(rdr_event->passed)) { 264 if (le32_to_cpu(rdr_event->passed)) {
246 mwifiex_dbg(priv->adapter, MSG, 265 mwifiex_dbg(priv->adapter, MSG,
247 "radar detected; indicating kernel\n"); 266 "radar detected; indicating kernel\n");
267 if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
268 mwifiex_dbg(priv->adapter, ERROR,
269 "Failed to stop CAC in FW\n");
248 cfg80211_radar_event(priv->adapter->wiphy, &priv->dfs_chandef, 270 cfg80211_radar_event(priv->adapter->wiphy, &priv->dfs_chandef,
249 GFP_KERNEL); 271 GFP_KERNEL);
250 mwifiex_dbg(priv->adapter, MSG, "regdomain: %d\n", 272 mwifiex_dbg(priv->adapter, MSG, "regdomain: %d\n",
@@ -252,7 +274,7 @@ int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,
252 mwifiex_dbg(priv->adapter, MSG, "radar detection type: %d\n", 274 mwifiex_dbg(priv->adapter, MSG, "radar detection type: %d\n",
253 rdr_event->det_type); 275 rdr_event->det_type);
254 } else { 276 } else {
255 mwifiex_dbg(priv->adapter, ERROR, 277 mwifiex_dbg(priv->adapter, MSG,
256 "false radar detection event!\n"); 278 "false radar detection event!\n");
257 } 279 }
258 280
@@ -283,7 +305,7 @@ void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work)
283 return; 305 return;
284 } 306 }
285 307
286 mwifiex_uap_set_channel(bss_cfg, priv->dfs_chandef); 308 mwifiex_uap_set_channel(priv, bss_cfg, priv->dfs_chandef);
287 309
288 if (mwifiex_config_start_uap(priv, bss_cfg)) { 310 if (mwifiex_config_start_uap(priv, bss_cfg)) {
289 mwifiex_dbg(priv->adapter, ERROR, 311 mwifiex_dbg(priv->adapter, ERROR,
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 8422986cd7a9..c174e79e6df2 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -156,7 +156,7 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
156int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, 156int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
157 struct host_cmd_ds_command *resp) 157 struct host_cmd_ds_command *resp)
158{ 158{
159 int tid; 159 int tid, tid_down;
160 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp; 160 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp;
161 struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; 161 struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
162 struct mwifiex_ra_list_tbl *ra_list; 162 struct mwifiex_ra_list_tbl *ra_list;
@@ -167,7 +167,9 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
167 167
168 tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK) 168 tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
169 >> BLOCKACKPARAM_TID_POS; 169 >> BLOCKACKPARAM_TID_POS;
170 ra_list = mwifiex_wmm_get_ralist_node(priv, tid, add_ba_rsp-> 170
171 tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
172 ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, add_ba_rsp->
171 peer_mac_addr); 173 peer_mac_addr);
172 if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) { 174 if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) {
173 if (ra_list) { 175 if (ra_list) {
@@ -530,13 +532,16 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
530 struct mwifiex_tx_ba_stream_tbl *new_node; 532 struct mwifiex_tx_ba_stream_tbl *new_node;
531 struct mwifiex_ra_list_tbl *ra_list; 533 struct mwifiex_ra_list_tbl *ra_list;
532 unsigned long flags; 534 unsigned long flags;
535 int tid_down;
533 536
534 if (!mwifiex_get_ba_tbl(priv, tid, ra)) { 537 if (!mwifiex_get_ba_tbl(priv, tid, ra)) {
535 new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl), 538 new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl),
536 GFP_ATOMIC); 539 GFP_ATOMIC);
537 if (!new_node) 540 if (!new_node)
538 return; 541 return;
539 ra_list = mwifiex_wmm_get_ralist_node(priv, tid, ra); 542
543 tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
544 ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, ra);
540 if (ra_list) { 545 if (ra_list) {
541 ra_list->ba_status = ba_status; 546 ra_list->ba_status = ba_status;
542 ra_list->amsdu_in_ampdu = false; 547 ra_list->amsdu_in_ampdu = false;
@@ -643,6 +648,30 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
643} 648}
644 649
645/* 650/*
651 * This function sends delba to specific tid
652 */
653void mwifiex_11n_delba(struct mwifiex_private *priv, int tid)
654{
655 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
656
657 if (list_empty(&priv->rx_reorder_tbl_ptr)) {
658 dev_dbg(priv->adapter->dev,
659 "mwifiex_11n_delba: rx_reorder_tbl_ptr empty\n");
660 return;
661 }
662
663 list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) {
664 if (rx_reor_tbl_ptr->tid == tid) {
665 dev_dbg(priv->adapter->dev,
666 "Send delba to tid=%d, %pM\n",
667 tid, rx_reor_tbl_ptr->ta);
668 mwifiex_send_delba(priv, tid, rx_reor_tbl_ptr->ta, 0);
669 return;
670 }
671 }
672}
673
674/*
646 * This function handles the command response of a delete BA request. 675 * This function handles the command response of a delete BA request.
647 */ 676 */
648void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba) 677void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba)
@@ -814,3 +843,72 @@ u8 mwifiex_get_sec_chan_offset(int chan)
814 843
815 return sec_offset; 844 return sec_offset;
816} 845}
846
847/* This function will send DELBA to entries in the priv's
848 * Tx BA stream table
849 */
850static void
851mwifiex_send_delba_txbastream_tbl(struct mwifiex_private *priv, u8 tid)
852{
853 struct mwifiex_adapter *adapter = priv->adapter;
854 struct mwifiex_tx_ba_stream_tbl *tx_ba_stream_tbl_ptr;
855
856 if (list_empty(&priv->tx_ba_stream_tbl_ptr))
857 return;
858
859 list_for_each_entry(tx_ba_stream_tbl_ptr,
860 &priv->tx_ba_stream_tbl_ptr, list) {
861 if (tx_ba_stream_tbl_ptr->ba_status == BA_SETUP_COMPLETE) {
862 if (tid == tx_ba_stream_tbl_ptr->tid) {
863 dev_dbg(adapter->dev,
864 "Tx:Send delba to tid=%d, %pM\n", tid,
865 tx_ba_stream_tbl_ptr->ra);
866 mwifiex_send_delba(priv,
867 tx_ba_stream_tbl_ptr->tid,
868 tx_ba_stream_tbl_ptr->ra, 1);
869 return;
870 }
871 }
872 }
873}
874
875/* This function updates all the tx_win_size
876 */
877void mwifiex_update_ampdu_txwinsize(struct mwifiex_adapter *adapter)
878{
879 u8 i;
880 u32 tx_win_size;
881 struct mwifiex_private *priv;
882
883 for (i = 0; i < adapter->priv_num; i++) {
884 if (!adapter->priv[i])
885 continue;
886 priv = adapter->priv[i];
887 tx_win_size = priv->add_ba_param.tx_win_size;
888
889 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA)
890 priv->add_ba_param.tx_win_size =
891 MWIFIEX_STA_AMPDU_DEF_TXWINSIZE;
892
893 if (priv->bss_type == MWIFIEX_BSS_TYPE_P2P)
894 priv->add_ba_param.tx_win_size =
895 MWIFIEX_STA_AMPDU_DEF_TXWINSIZE;
896
897 if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP)
898 priv->add_ba_param.tx_win_size =
899 MWIFIEX_UAP_AMPDU_DEF_TXWINSIZE;
900
901 if (adapter->coex_win_size) {
902 if (adapter->coex_tx_win_size)
903 priv->add_ba_param.tx_win_size =
904 adapter->coex_tx_win_size;
905 }
906
907 if (tx_win_size != priv->add_ba_param.tx_win_size) {
908 if (!priv->media_connected)
909 continue;
910 for (i = 0; i < MAX_NUM_TID; i++)
911 mwifiex_send_delba_txbastream_tbl(priv, i);
912 }
913 }
914}
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 39d7a957674c..2906cd543532 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -663,6 +663,7 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
663 struct mwifiex_ra_list_tbl *ra_list; 663 struct mwifiex_ra_list_tbl *ra_list;
664 u8 cleanup_rx_reorder_tbl; 664 u8 cleanup_rx_reorder_tbl;
665 unsigned long flags; 665 unsigned long flags;
666 int tid_down;
666 667
667 if (type == TYPE_DELBA_RECEIVE) 668 if (type == TYPE_DELBA_RECEIVE)
668 cleanup_rx_reorder_tbl = (initiator) ? true : false; 669 cleanup_rx_reorder_tbl = (initiator) ? true : false;
@@ -688,7 +689,9 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
688 "event: TID, RA not found in table\n"); 689 "event: TID, RA not found in table\n");
689 return; 690 return;
690 } 691 }
691 ra_list = mwifiex_wmm_get_ralist_node(priv, tid, peer_mac); 692
693 tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
694 ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, peer_mac);
692 if (ra_list) { 695 if (ra_list) {
693 ra_list->amsdu_in_ampdu = false; 696 ra_list->amsdu_in_ampdu = false;
694 ra_list->ba_status = BA_SETUP_NONE; 697 ra_list->ba_status = BA_SETUP_NONE;
@@ -825,3 +828,83 @@ void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
825 828
826 return; 829 return;
827} 830}
831
832/* This function update all the rx_win_size based on coex flag
833 */
834static void mwifiex_update_ampdu_rxwinsize(struct mwifiex_adapter *adapter,
835 bool coex_flag)
836{
837 u8 i;
838 u32 rx_win_size;
839 struct mwifiex_private *priv;
840
841 dev_dbg(adapter->dev, "Update rxwinsize %d\n", coex_flag);
842
843 for (i = 0; i < adapter->priv_num; i++) {
844 if (!adapter->priv[i])
845 continue;
846 priv = adapter->priv[i];
847 rx_win_size = priv->add_ba_param.rx_win_size;
848 if (coex_flag) {
849 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA)
850 priv->add_ba_param.rx_win_size =
851 MWIFIEX_STA_COEX_AMPDU_DEF_RXWINSIZE;
852 if (priv->bss_type == MWIFIEX_BSS_TYPE_P2P)
853 priv->add_ba_param.rx_win_size =
854 MWIFIEX_STA_COEX_AMPDU_DEF_RXWINSIZE;
855 if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP)
856 priv->add_ba_param.rx_win_size =
857 MWIFIEX_UAP_COEX_AMPDU_DEF_RXWINSIZE;
858 } else {
859 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA)
860 priv->add_ba_param.rx_win_size =
861 MWIFIEX_STA_AMPDU_DEF_RXWINSIZE;
862 if (priv->bss_type == MWIFIEX_BSS_TYPE_P2P)
863 priv->add_ba_param.rx_win_size =
864 MWIFIEX_STA_AMPDU_DEF_RXWINSIZE;
865 if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP)
866 priv->add_ba_param.rx_win_size =
867 MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE;
868 }
869
870 if (adapter->coex_win_size && adapter->coex_rx_win_size)
871 priv->add_ba_param.rx_win_size =
872 adapter->coex_rx_win_size;
873
874 if (rx_win_size != priv->add_ba_param.rx_win_size) {
875 if (!priv->media_connected)
876 continue;
877 for (i = 0; i < MAX_NUM_TID; i++)
878 mwifiex_11n_delba(priv, i);
879 }
880 }
881}
882
883/* This function check coex for RX BA
884 */
885void mwifiex_coex_ampdu_rxwinsize(struct mwifiex_adapter *adapter)
886{
887 u8 i;
888 struct mwifiex_private *priv;
889 u8 count = 0;
890
891 for (i = 0; i < adapter->priv_num; i++) {
892 if (adapter->priv[i]) {
893 priv = adapter->priv[i];
894 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
895 if (priv->media_connected)
896 count++;
897 }
898 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
899 if (priv->bss_started)
900 count++;
901 }
902 }
903 if (count >= MWIFIEX_BSS_COEX_COUNT)
904 break;
905 }
906 if (count >= MWIFIEX_BSS_COEX_COUNT)
907 mwifiex_update_ampdu_rxwinsize(adapter, true);
908 else
909 mwifiex_update_ampdu_rxwinsize(adapter, false);
910}
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 4eecedadefbf..b15e4c7acbec 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -67,6 +67,22 @@ u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
67 } 67 }
68} 68}
69 69
70/* This function maps IEEE HT secondary channel type to NL80211 channel type
71 */
72u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset)
73{
74 switch (second_chan_offset) {
75 case IEEE80211_HT_PARAM_CHA_SEC_NONE:
76 return NL80211_CHAN_HT20;
77 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
78 return NL80211_CHAN_HT40PLUS;
79 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
80 return NL80211_CHAN_HT40MINUS;
81 default:
82 return NL80211_CHAN_HT20;
83 }
84}
85
70/* 86/*
71 * This function checks whether WEP is set. 87 * This function checks whether WEP is set.
72 */ 88 */
@@ -1213,6 +1229,7 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
1213 */ 1229 */
1214static int 1230static int
1215mwifiex_dump_station_info(struct mwifiex_private *priv, 1231mwifiex_dump_station_info(struct mwifiex_private *priv,
1232 struct mwifiex_sta_node *node,
1216 struct station_info *sinfo) 1233 struct station_info *sinfo)
1217{ 1234{
1218 u32 rate; 1235 u32 rate;
@@ -1222,6 +1239,30 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
1222 BIT(NL80211_STA_INFO_TX_BITRATE) | 1239 BIT(NL80211_STA_INFO_TX_BITRATE) |
1223 BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_SIGNAL_AVG); 1240 BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_SIGNAL_AVG);
1224 1241
1242 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
1243 if (!node)
1244 return -ENOENT;
1245
1246 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME) |
1247 BIT(NL80211_STA_INFO_TX_FAILED);
1248 sinfo->inactive_time =
1249 jiffies_to_msecs(jiffies - node->stats.last_rx);
1250
1251 sinfo->signal = node->stats.rssi;
1252 sinfo->signal_avg = node->stats.rssi;
1253 sinfo->rx_bytes = node->stats.rx_bytes;
1254 sinfo->tx_bytes = node->stats.tx_bytes;
1255 sinfo->rx_packets = node->stats.rx_packets;
1256 sinfo->tx_packets = node->stats.tx_packets;
1257 sinfo->tx_failed = node->stats.tx_failed;
1258
1259 mwifiex_parse_htinfo(priv, node->stats.last_tx_htinfo,
1260 &sinfo->txrate);
1261 sinfo->txrate.legacy = node->stats.last_tx_rate * 5;
1262
1263 return 0;
1264 }
1265
1225 /* Get signal information from the firmware */ 1266 /* Get signal information from the firmware */
1226 if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, 1267 if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
1227 HostCmd_ACT_GEN_GET, 0, NULL, true)) { 1268 HostCmd_ACT_GEN_GET, 0, NULL, true)) {
@@ -1288,7 +1329,7 @@ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1288 if (memcmp(mac, priv->cfg_bssid, ETH_ALEN)) 1329 if (memcmp(mac, priv->cfg_bssid, ETH_ALEN))
1289 return -ENOENT; 1330 return -ENOENT;
1290 1331
1291 return mwifiex_dump_station_info(priv, sinfo); 1332 return mwifiex_dump_station_info(priv, NULL, sinfo);
1292} 1333}
1293 1334
1294/* 1335/*
@@ -1299,13 +1340,29 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
1299 int idx, u8 *mac, struct station_info *sinfo) 1340 int idx, u8 *mac, struct station_info *sinfo)
1300{ 1341{
1301 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1342 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1343 static struct mwifiex_sta_node *node;
1302 1344
1303 if (!priv->media_connected || idx) 1345 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
1304 return -ENOENT; 1346 priv->media_connected && idx == 0) {
1347 ether_addr_copy(mac, priv->cfg_bssid);
1348 return mwifiex_dump_station_info(priv, NULL, sinfo);
1349 } else if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
1350 mwifiex_send_cmd(priv, HOST_CMD_APCMD_STA_LIST,
1351 HostCmd_ACT_GEN_GET, 0, NULL, true);
1352
1353 if (node && (&node->list == &priv->sta_list)) {
1354 node = NULL;
1355 return -ENOENT;
1356 }
1305 1357
1306 memcpy(mac, priv->cfg_bssid, ETH_ALEN); 1358 node = list_prepare_entry(node, &priv->sta_list, list);
1359 list_for_each_entry_continue(node, &priv->sta_list, list) {
1360 ether_addr_copy(mac, node->mac_addr);
1361 return mwifiex_dump_station_info(priv, node, sinfo);
1362 }
1363 }
1307 1364
1308 return mwifiex_dump_station_info(priv, sinfo); 1365 return -ENOENT;
1309} 1366}
1310 1367
1311static int 1368static int
@@ -1725,6 +1782,13 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1725 return -1; 1782 return -1;
1726 } 1783 }
1727 1784
1785 if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET,
1786 HostCmd_ACT_GEN_SET, 0, NULL, true)) {
1787 mwifiex_dbg(priv->adapter, ERROR,
1788 "Failed to reset BSS\n");
1789 return -1;
1790 }
1791
1728 return 0; 1792 return 0;
1729} 1793}
1730 1794
@@ -1778,7 +1842,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1778 return -EINVAL; 1842 return -EINVAL;
1779 } 1843 }
1780 1844
1781 mwifiex_uap_set_channel(bss_cfg, params->chandef); 1845 mwifiex_uap_set_channel(priv, bss_cfg, params->chandef);
1782 mwifiex_set_uap_rates(bss_cfg, params); 1846 mwifiex_set_uap_rates(bss_cfg, params);
1783 1847
1784 if (mwifiex_set_secure_params(priv, bss_cfg, params)) { 1848 if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
@@ -1803,6 +1867,9 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1803 1867
1804 mwifiex_set_wmm_params(priv, bss_cfg, params); 1868 mwifiex_set_wmm_params(priv, bss_cfg, params);
1805 1869
1870 if (mwifiex_is_11h_active(priv))
1871 mwifiex_set_tpc_params(priv, bss_cfg, params);
1872
1806 if (mwifiex_is_11h_active(priv) && 1873 if (mwifiex_is_11h_active(priv) &&
1807 !cfg80211_chandef_dfs_required(wiphy, &params->chandef, 1874 !cfg80211_chandef_dfs_required(wiphy, &params->chandef,
1808 priv->bss_mode)) { 1875 priv->bss_mode)) {
@@ -1813,7 +1880,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1813 "Failed to disable 11h extensions!!"); 1880 "Failed to disable 11h extensions!!");
1814 return -1; 1881 return -1;
1815 } 1882 }
1816 priv->state_11h.is_11h_active = true; 1883 priv->state_11h.is_11h_active = false;
1817 } 1884 }
1818 1885
1819 if (mwifiex_config_start_uap(priv, bss_cfg)) { 1886 if (mwifiex_config_start_uap(priv, bss_cfg)) {
@@ -2518,7 +2585,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2518 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; 2585 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
2519 priv->bss_priority = 0; 2586 priv->bss_priority = 0;
2520 priv->bss_role = MWIFIEX_BSS_ROLE_STA; 2587 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
2521 priv->bss_num = 0; 2588 priv->bss_num = adapter->curr_iface_comb.sta_intf;
2522 2589
2523 break; 2590 break;
2524 case NL80211_IFTYPE_AP: 2591 case NL80211_IFTYPE_AP:
@@ -2544,7 +2611,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2544 priv->bss_priority = 0; 2611 priv->bss_priority = 0;
2545 priv->bss_role = MWIFIEX_BSS_ROLE_UAP; 2612 priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
2546 priv->bss_started = 0; 2613 priv->bss_started = 0;
2547 priv->bss_num = 0; 2614 priv->bss_num = adapter->curr_iface_comb.uap_intf;
2548 priv->bss_mode = type; 2615 priv->bss_mode = type;
2549 2616
2550 break; 2617 break;
@@ -2580,7 +2647,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2580 priv->bss_priority = MWIFIEX_BSS_ROLE_STA; 2647 priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
2581 priv->bss_role = MWIFIEX_BSS_ROLE_STA; 2648 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
2582 priv->bss_started = 0; 2649 priv->bss_started = 0;
2583 priv->bss_num = 0; 2650 priv->bss_num = adapter->curr_iface_comb.p2p_intf;
2584 2651
2585 if (mwifiex_cfg80211_init_p2p_client(priv)) { 2652 if (mwifiex_cfg80211_init_p2p_client(priv)) {
2586 memset(&priv->wdev, 0, sizeof(priv->wdev)); 2653 memset(&priv->wdev, 0, sizeof(priv->wdev));
@@ -3366,6 +3433,45 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3366 return 0; 3433 return 0;
3367} 3434}
3368 3435
3436static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy,
3437 struct wireless_dev *wdev,
3438 struct cfg80211_chan_def *chandef)
3439{
3440 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
3441 struct mwifiex_bssdescriptor *curr_bss;
3442 struct ieee80211_channel *chan;
3443 u8 second_chan_offset;
3444 enum nl80211_channel_type chan_type;
3445 enum ieee80211_band band;
3446 int freq;
3447 int ret = -ENODATA;
3448
3449 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
3450 cfg80211_chandef_valid(&priv->bss_chandef)) {
3451 *chandef = priv->bss_chandef;
3452 ret = 0;
3453 } else if (priv->media_connected) {
3454 curr_bss = &priv->curr_bss_params.bss_descriptor;
3455 band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
3456 freq = ieee80211_channel_to_frequency(curr_bss->channel, band);
3457 chan = ieee80211_get_channel(wiphy, freq);
3458
3459 if (curr_bss->bcn_ht_oper) {
3460 second_chan_offset = curr_bss->bcn_ht_oper->ht_param &
3461 IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
3462 chan_type = mwifiex_sec_chan_offset_to_chan_type
3463 (second_chan_offset);
3464 cfg80211_chandef_create(chandef, chan, chan_type);
3465 } else {
3466 cfg80211_chandef_create(chandef, chan,
3467 NL80211_CHAN_NO_HT);
3468 }
3469 ret = 0;
3470 }
3471
3472 return ret;
3473}
3474
3369static int 3475static int
3370mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy, 3476mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
3371 struct net_device *dev, 3477 struct net_device *dev,
@@ -3471,6 +3577,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
3471 .tdls_oper = mwifiex_cfg80211_tdls_oper, 3577 .tdls_oper = mwifiex_cfg80211_tdls_oper,
3472 .add_station = mwifiex_cfg80211_add_station, 3578 .add_station = mwifiex_cfg80211_add_station,
3473 .change_station = mwifiex_cfg80211_change_station, 3579 .change_station = mwifiex_cfg80211_change_station,
3580 .get_channel = mwifiex_cfg80211_get_channel,
3474 .start_radar_detection = mwifiex_cfg80211_start_radar_detection, 3581 .start_radar_detection = mwifiex_cfg80211_start_radar_detection,
3475 .channel_switch = mwifiex_cfg80211_channel_switch, 3582 .channel_switch = mwifiex_cfg80211_channel_switch,
3476}; 3583};
@@ -3578,7 +3685,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
3578 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | 3685 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
3579 WIPHY_FLAG_AP_UAPSD | 3686 WIPHY_FLAG_AP_UAPSD |
3580 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | 3687 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3581 WIPHY_FLAG_HAS_CHANNEL_SWITCH; 3688 WIPHY_FLAG_HAS_CHANNEL_SWITCH |
3689 WIPHY_FLAG_PS_ON_BY_DEFAULT;
3582 3690
3583 if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info)) 3691 if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
3584 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | 3692 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index a1de83fd1dbe..207da40500f4 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -469,10 +469,11 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
469 memset(rx_info, 0, sizeof(*rx_info)); 469 memset(rx_info, 0, sizeof(*rx_info));
470 rx_info->bss_num = priv->bss_num; 470 rx_info->bss_num = priv->bss_num;
471 rx_info->bss_type = priv->bss_type; 471 rx_info->bss_type = priv->bss_type;
472 mwifiex_dbg_dump(adapter, EVT_D, "Event Buf:",
473 skb->data, skb->len);
472 } 474 }
473 475
474 mwifiex_dbg(adapter, EVENT, "EVENT: cause: %#x\n", eventcause); 476 mwifiex_dbg(adapter, EVENT, "EVENT: cause: %#x\n", eventcause);
475 mwifiex_dbg_dump(adapter, EVT_D, "Event Buf:", skb->data, skb->len);
476 477
477 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) 478 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
478 ret = mwifiex_process_uap_event(priv); 479 ret = mwifiex_process_uap_event(priv);
@@ -574,6 +575,8 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
574 case HostCmd_CMD_UAP_BSS_START: 575 case HostCmd_CMD_UAP_BSS_START:
575 case HostCmd_CMD_UAP_BSS_STOP: 576 case HostCmd_CMD_UAP_BSS_STOP:
576 case HostCmd_CMD_UAP_STA_DEAUTH: 577 case HostCmd_CMD_UAP_STA_DEAUTH:
578 case HOST_CMD_APCMD_SYS_RESET:
579 case HOST_CMD_APCMD_STA_LIST:
577 ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, 580 ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
578 cmd_oid, data_buf, 581 cmd_oid, data_buf,
579 cmd_ptr); 582 cmd_ptr);
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 38f24e0427d2..51e344789ba2 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -29,7 +29,7 @@
29#include <uapi/linux/if_arp.h> 29#include <uapi/linux/if_arp.h>
30#include <net/mac80211.h> 30#include <net/mac80211.h>
31 31
32 32#define MWIFIEX_BSS_COEX_COUNT 2
33#define MWIFIEX_MAX_BSS_NUM (3) 33#define MWIFIEX_MAX_BSS_NUM (3)
34 34
35#define MWIFIEX_DMA_ALIGN_SZ 64 35#define MWIFIEX_DMA_ALIGN_SZ 64
@@ -49,7 +49,12 @@
49 49
50#define MWIFIEX_STA_AMPDU_DEF_TXWINSIZE 64 50#define MWIFIEX_STA_AMPDU_DEF_TXWINSIZE 64
51#define MWIFIEX_STA_AMPDU_DEF_RXWINSIZE 64 51#define MWIFIEX_STA_AMPDU_DEF_RXWINSIZE 64
52#define MWIFIEX_STA_COEX_AMPDU_DEF_RXWINSIZE 16
53
52#define MWIFIEX_UAP_AMPDU_DEF_TXWINSIZE 32 54#define MWIFIEX_UAP_AMPDU_DEF_TXWINSIZE 32
55
56#define MWIFIEX_UAP_COEX_AMPDU_DEF_RXWINSIZE 16
57
53#define MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE 16 58#define MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE 16
54#define MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE 64 59#define MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE 64
55#define MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE 64 60#define MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE 64
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index c404390cb0fa..cd09051710e6 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -128,6 +128,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
128 128
129#define TLV_TYPE_UAP_SSID 0x0000 129#define TLV_TYPE_UAP_SSID 0x0000
130#define TLV_TYPE_UAP_RATES 0x0001 130#define TLV_TYPE_UAP_RATES 0x0001
131#define TLV_TYPE_PWR_CONSTRAINT 0x0020
131 132
132#define PROPRIETARY_TLV_BASE_ID 0x0100 133#define PROPRIETARY_TLV_BASE_ID 0x0100
133#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0) 134#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0)
@@ -174,6 +175,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
174#define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197) 175#define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197)
175#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199) 176#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199)
176#define TLV_TYPE_CHANNEL_STATS (PROPRIETARY_TLV_BASE_ID + 198) 177#define TLV_TYPE_CHANNEL_STATS (PROPRIETARY_TLV_BASE_ID + 198)
178#define TLV_BTCOEX_WL_AGGR_WINSIZE (PROPRIETARY_TLV_BASE_ID + 202)
179#define TLV_BTCOEX_WL_SCANTIME (PROPRIETARY_TLV_BASE_ID + 203)
177 180
178#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 181#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
179 182
@@ -330,9 +333,11 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
330#define HostCmd_CMD_RSSI_INFO 0x00a4 333#define HostCmd_CMD_RSSI_INFO 0x00a4
331#define HostCmd_CMD_FUNC_INIT 0x00a9 334#define HostCmd_CMD_FUNC_INIT 0x00a9
332#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa 335#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa
336#define HOST_CMD_APCMD_SYS_RESET 0x00af
333#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0 337#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0
334#define HostCmd_CMD_UAP_BSS_START 0x00b1 338#define HostCmd_CMD_UAP_BSS_START 0x00b1
335#define HostCmd_CMD_UAP_BSS_STOP 0x00b2 339#define HostCmd_CMD_UAP_BSS_STOP 0x00b2
340#define HOST_CMD_APCMD_STA_LIST 0x00b3
336#define HostCmd_CMD_UAP_STA_DEAUTH 0x00b5 341#define HostCmd_CMD_UAP_STA_DEAUTH 0x00b5
337#define HostCmd_CMD_11N_CFG 0x00cd 342#define HostCmd_CMD_11N_CFG 0x00cd
338#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce 343#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce
@@ -419,8 +424,12 @@ enum P2P_MODES {
419#define HS_CFG_COND_MAC_EVENT 0x00000004 424#define HS_CFG_COND_MAC_EVENT 0x00000004
420#define HS_CFG_COND_MULTICAST_DATA 0x00000008 425#define HS_CFG_COND_MULTICAST_DATA 0x00000008
421 426
422#define MWIFIEX_TIMEOUT_FOR_AP_RESP 0xfffc 427#define CONNECT_ERR_AUTH_ERR_STA_FAILURE 0xFFFB
423#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 428#define CONNECT_ERR_ASSOC_ERR_TIMEOUT 0xFFFC
429#define CONNECT_ERR_ASSOC_ERR_AUTH_REFUSED 0xFFFD
430#define CONNECT_ERR_AUTH_MSG_UNHANDLED 0xFFFE
431#define CONNECT_ERR_STA_FAILURE 0xFFFF
432
424 433
425#define CMD_F_HOSTCMD (1 << 0) 434#define CMD_F_HOSTCMD (1 << 0)
426#define CMD_F_CANCELED (1 << 1) 435#define CMD_F_CANCELED (1 << 1)
@@ -503,6 +512,7 @@ enum P2P_MODES {
503#define EVENT_EXT_SCAN_REPORT 0x00000058 512#define EVENT_EXT_SCAN_REPORT 0x00000058
504#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f 513#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f
505#define EVENT_TX_STATUS_REPORT 0x00000074 514#define EVENT_TX_STATUS_REPORT 0x00000074
515#define EVENT_BT_COEX_WLAN_PARA_CHANGE 0X00000076
506 516
507#define EVENT_ID_MASK 0xffff 517#define EVENT_ID_MASK 0xffff
508#define BSS_NUM_MASK 0xf 518#define BSS_NUM_MASK 0xf
@@ -627,7 +637,12 @@ struct uap_rxpd {
627 __le16 rx_pkt_type; 637 __le16 rx_pkt_type;
628 __le16 seq_num; 638 __le16 seq_num;
629 u8 priority; 639 u8 priority;
630 u8 reserved1; 640 u8 rx_rate;
641 s8 snr;
642 s8 nf;
643 u8 ht_info;
644 u8 reserved[3];
645 u8 flags;
631}; 646};
632 647
633struct mwifiex_fw_chan_stats { 648struct mwifiex_fw_chan_stats {
@@ -1151,6 +1166,13 @@ enum SNMP_MIB_INDEX {
1151 DOT11H_I = 10, 1166 DOT11H_I = 10,
1152}; 1167};
1153 1168
1169enum mwifiex_assocmd_failurepoint {
1170 MWIFIEX_ASSOC_CMD_SUCCESS = 0,
1171 MWIFIEX_ASSOC_CMD_FAILURE_ASSOC,
1172 MWIFIEX_ASSOC_CMD_FAILURE_AUTH,
1173 MWIFIEX_ASSOC_CMD_FAILURE_JOIN
1174};
1175
1154#define MAX_SNMP_BUF_SIZE 128 1176#define MAX_SNMP_BUF_SIZE 128
1155 1177
1156struct host_cmd_ds_802_11_snmp_mib { 1178struct host_cmd_ds_802_11_snmp_mib {
@@ -1448,6 +1470,18 @@ struct host_cmd_ds_sta_deauth {
1448 __le16 reason; 1470 __le16 reason;
1449} __packed; 1471} __packed;
1450 1472
1473struct mwifiex_ie_types_sta_info {
1474 struct mwifiex_ie_types_header header;
1475 u8 mac[ETH_ALEN];
1476 u8 power_mfg_status;
1477 s8 rssi;
1478};
1479
1480struct host_cmd_ds_sta_list {
1481 u16 sta_count;
1482 u8 tlv[0];
1483} __packed;
1484
1451struct mwifiex_ie_types_pwr_capability { 1485struct mwifiex_ie_types_pwr_capability {
1452 struct mwifiex_ie_types_header header; 1486 struct mwifiex_ie_types_header header;
1453 s8 min_pwr; 1487 s8 min_pwr;
@@ -1750,6 +1784,27 @@ struct host_cmd_tlv_ageout_timer {
1750 __le32 sta_ao_timer; 1784 __le32 sta_ao_timer;
1751} __packed; 1785} __packed;
1752 1786
1787struct host_cmd_tlv_power_constraint {
1788 struct mwifiex_ie_types_header header;
1789 u8 constraint;
1790} __packed;
1791
1792struct mwifiex_ie_types_btcoex_scan_time {
1793 struct mwifiex_ie_types_header header;
1794 u8 coex_scan;
1795 u8 reserved;
1796 u16 min_scan_time;
1797 u16 max_scan_time;
1798} __packed;
1799
1800struct mwifiex_ie_types_btcoex_aggr_win_size {
1801 struct mwifiex_ie_types_header header;
1802 u8 coex_win_size;
1803 u8 tx_win_size;
1804 u8 rx_win_size;
1805 u8 reserved;
1806} __packed;
1807
1753struct host_cmd_ds_version_ext { 1808struct host_cmd_ds_version_ext {
1754 u8 version_str_sel; 1809 u8 version_str_sel;
1755 char version_str[128]; 1810 char version_str[128];
@@ -1977,6 +2032,7 @@ struct host_cmd_ds_command {
1977 struct host_cmd_ds_802_11_subsc_evt subsc_evt; 2032 struct host_cmd_ds_802_11_subsc_evt subsc_evt;
1978 struct host_cmd_ds_sys_config uap_sys_config; 2033 struct host_cmd_ds_sys_config uap_sys_config;
1979 struct host_cmd_ds_sta_deauth sta_deauth; 2034 struct host_cmd_ds_sta_deauth sta_deauth;
2035 struct host_cmd_ds_sta_list sta_list;
1980 struct host_cmd_11ac_vht_cfg vht_cfg; 2036 struct host_cmd_11ac_vht_cfg vht_cfg;
1981 struct host_cmd_ds_coalesce_cfg coalesce_cfg; 2037 struct host_cmd_ds_coalesce_cfg coalesce_cfg;
1982 struct host_cmd_ds_tdls_oper tdls_oper; 2038 struct host_cmd_ds_tdls_oper tdls_oper;
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index f3b6ed249403..0ba894509413 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -320,63 +320,81 @@ done:
320/* This function parses head and tail IEs, from cfg80211_beacon_data and sets 320/* This function parses head and tail IEs, from cfg80211_beacon_data and sets
321 * these IE to FW. 321 * these IE to FW.
322 */ 322 */
323static int mwifiex_uap_set_head_tail_ies(struct mwifiex_private *priv, 323static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
324 struct cfg80211_beacon_data *info) 324 struct cfg80211_beacon_data *info)
325{ 325{
326 struct mwifiex_ie *gen_ie; 326 struct mwifiex_ie *gen_ie;
327 struct ieee_types_header *rsn_ie = NULL, *wpa_ie = NULL; 327 struct ieee_types_header *hdr;
328 struct ieee_types_header *chsw_ie = NULL; 328 struct ieee80211_vendor_ie *vendorhdr;
329 u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0; 329 u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0;
330 const u8 *vendor_ie; 330 int left_len, parsed_len = 0;
331
332 if (!info->tail || !info->tail_len)
333 return 0;
331 334
332 gen_ie = kzalloc(sizeof(*gen_ie), GFP_KERNEL); 335 gen_ie = kzalloc(sizeof(*gen_ie), GFP_KERNEL);
333 if (!gen_ie) 336 if (!gen_ie)
334 return -ENOMEM; 337 return -ENOMEM;
335 gen_ie->ie_index = cpu_to_le16(gen_idx);
336 gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
337 MGMT_MASK_PROBE_RESP |
338 MGMT_MASK_ASSOC_RESP);
339 338
340 if (info->tail && info->tail_len) { 339 left_len = info->tail_len;
341 rsn_ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, 340
342 info->tail, info->tail_len); 341 /* Many IEs are generated in FW by parsing bss configuration.
343 if (rsn_ie) { 342 * Let's not add them here; else we may end up duplicating these IEs
344 memcpy(gen_ie->ie_buffer, rsn_ie, rsn_ie->len + 2); 343 */
345 ie_len = rsn_ie->len + 2; 344 while (left_len > sizeof(struct ieee_types_header)) {
346 gen_ie->ie_length = cpu_to_le16(ie_len); 345 hdr = (void *)(info->tail + parsed_len);
346 switch (hdr->element_id) {
347 case WLAN_EID_SSID:
348 case WLAN_EID_SUPP_RATES:
349 case WLAN_EID_COUNTRY:
350 case WLAN_EID_PWR_CONSTRAINT:
351 case WLAN_EID_EXT_SUPP_RATES:
352 case WLAN_EID_HT_CAPABILITY:
353 case WLAN_EID_HT_OPERATION:
354 case WLAN_EID_VHT_CAPABILITY:
355 case WLAN_EID_VHT_OPERATION:
356 case WLAN_EID_VENDOR_SPECIFIC:
357 break;
358 default:
359 memcpy(gen_ie->ie_buffer + ie_len, hdr,
360 hdr->len + sizeof(struct ieee_types_header));
361 ie_len += hdr->len + sizeof(struct ieee_types_header);
362 break;
347 } 363 }
364 left_len -= hdr->len + sizeof(struct ieee_types_header);
365 parsed_len += hdr->len + sizeof(struct ieee_types_header);
366 }
348 367
349 vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 368 /* parse only WPA vendor IE from tail, WMM IE is configured by
369 * bss_config command
370 */
371 vendorhdr = (void *)cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
350 WLAN_OUI_TYPE_MICROSOFT_WPA, 372 WLAN_OUI_TYPE_MICROSOFT_WPA,
351 info->tail, 373 info->tail, info->tail_len);
352 info->tail_len); 374 if (vendorhdr) {
353 if (vendor_ie) { 375 memcpy(gen_ie->ie_buffer + ie_len, vendorhdr,
354 wpa_ie = (struct ieee_types_header *)vendor_ie; 376 vendorhdr->len + sizeof(struct ieee_types_header));
355 memcpy(gen_ie->ie_buffer + ie_len, 377 ie_len += vendorhdr->len + sizeof(struct ieee_types_header);
356 wpa_ie, wpa_ie->len + 2); 378 }
357 ie_len += wpa_ie->len + 2;
358 gen_ie->ie_length = cpu_to_le16(ie_len);
359 }
360 379
361 chsw_ie = (void *)cfg80211_find_ie(WLAN_EID_CHANNEL_SWITCH, 380 if (!ie_len) {
362 info->tail, info->tail_len); 381 kfree(gen_ie);
363 if (chsw_ie) { 382 return 0;
364 memcpy(gen_ie->ie_buffer + ie_len,
365 chsw_ie, chsw_ie->len + 2);
366 ie_len += chsw_ie->len + 2;
367 gen_ie->ie_length = cpu_to_le16(ie_len);
368 }
369 } 383 }
370 384
371 if (rsn_ie || wpa_ie || chsw_ie) { 385 gen_ie->ie_index = cpu_to_le16(gen_idx);
372 if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, 386 gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
373 NULL, NULL, NULL)) { 387 MGMT_MASK_PROBE_RESP |
374 kfree(gen_ie); 388 MGMT_MASK_ASSOC_RESP);
375 return -1; 389 gen_ie->ie_length = cpu_to_le16(ie_len);
376 } 390
377 priv->gen_idx = gen_idx; 391 if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL,
392 NULL, NULL)) {
393 kfree(gen_ie);
394 return -1;
378 } 395 }
379 396
397 priv->gen_idx = gen_idx;
380 kfree(gen_ie); 398 kfree(gen_ie);
381 return 0; 399 return 0;
382} 400}
@@ -390,7 +408,7 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
390{ 408{
391 int ret; 409 int ret;
392 410
393 ret = mwifiex_uap_set_head_tail_ies(priv, info); 411 ret = mwifiex_uap_parse_tail_ies(priv, info);
394 return ret; 412 return ret;
395 413
396 return mwifiex_set_mgmt_beacon_data_ies(priv, info); 414 return mwifiex_set_mgmt_beacon_data_ies(priv, info);
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 6f11a25a6b49..4f0174c64946 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -113,6 +113,7 @@ struct mwifiex_uap_bss_param {
113 u32 sta_ao_timer; 113 u32 sta_ao_timer;
114 u32 ps_sta_ao_timer; 114 u32 ps_sta_ao_timer;
115 u8 qos_info; 115 u8 qos_info;
116 u8 power_constraint;
116 struct mwifiex_types_wmm_info wmm_info; 117 struct mwifiex_types_wmm_info wmm_info;
117}; 118};
118 119
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index cce8e39aa45e..56b024a6aaa5 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -556,6 +556,23 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
556 return 0; 556 return 0;
557} 557}
558 558
559static const char *assoc_failure_reason_to_str(u16 cap_info)
560{
561 switch (cap_info) {
562 case CONNECT_ERR_AUTH_ERR_STA_FAILURE:
563 return "CONNECT_ERR_AUTH_ERR_STA_FAILURE";
564 case CONNECT_ERR_AUTH_MSG_UNHANDLED:
565 return "CONNECT_ERR_AUTH_MSG_UNHANDLED";
566 case CONNECT_ERR_ASSOC_ERR_TIMEOUT:
567 return "CONNECT_ERR_ASSOC_ERR_TIMEOUT";
568 case CONNECT_ERR_ASSOC_ERR_AUTH_REFUSED:
569 return "CONNECT_ERR_ASSOC_ERR_AUTH_REFUSED";
570 case CONNECT_ERR_STA_FAILURE:
571 return "CONNECT_ERR_STA_FAILURE";
572 }
573
574 return "Unknown connect failure";
575}
559/* 576/*
560 * Association firmware command response handler 577 * Association firmware command response handler
561 * 578 *
@@ -656,11 +673,18 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
656 status_code, cap_info, 673 status_code, cap_info,
657 le16_to_cpu(assoc_rsp->a_id)); 674 le16_to_cpu(assoc_rsp->a_id));
658 675
659 if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) { 676 mwifiex_dbg(priv->adapter, ERROR, "assoc failure: reason %s\n",
660 if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT) 677 assoc_failure_reason_to_str(cap_info));
678 if (cap_info == CONNECT_ERR_ASSOC_ERR_TIMEOUT) {
679 if (status_code == MWIFIEX_ASSOC_CMD_FAILURE_AUTH) {
661 ret = WLAN_STATUS_AUTH_TIMEOUT; 680 ret = WLAN_STATUS_AUTH_TIMEOUT;
662 else 681 mwifiex_dbg(priv->adapter, ERROR,
682 "ASSOC_RESP: AUTH timeout\n");
683 } else {
663 ret = WLAN_STATUS_UNSPECIFIED_FAILURE; 684 ret = WLAN_STATUS_UNSPECIFIED_FAILURE;
685 mwifiex_dbg(priv->adapter, ERROR,
686 "ASSOC_RESP: UNSPECIFIED failure\n");
687 }
664 } else { 688 } else {
665 ret = status_code; 689 ret = status_code;
666 } 690 }
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 5a6c1c76b33b..ae98b5b83b1f 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -642,6 +642,7 @@ struct mwifiex_private {
642 u8 del_list_idx; 642 u8 del_list_idx;
643 bool hs2_enabled; 643 bool hs2_enabled;
644 struct mwifiex_uap_bss_param bss_cfg; 644 struct mwifiex_uap_bss_param bss_cfg;
645 struct cfg80211_chan_def bss_chandef;
645 struct station_parameters *sta_params; 646 struct station_parameters *sta_params;
646 struct sk_buff_head tdls_txq; 647 struct sk_buff_head tdls_txq;
647 u8 check_tdls_tx; 648 u8 check_tdls_tx;
@@ -740,6 +741,18 @@ struct mwifiex_tdls_capab {
740 struct ieee80211_vht_operation vhtoper; 741 struct ieee80211_vht_operation vhtoper;
741}; 742};
742 743
744struct mwifiex_station_stats {
745 u64 last_rx;
746 s8 rssi;
747 u64 rx_bytes;
748 u64 tx_bytes;
749 u32 rx_packets;
750 u32 tx_packets;
751 u32 tx_failed;
752 u8 last_tx_rate;
753 u8 last_tx_htinfo;
754};
755
743/* This is AP/TDLS specific structure which stores information 756/* This is AP/TDLS specific structure which stores information
744 * about associated/peer STA 757 * about associated/peer STA
745 */ 758 */
@@ -754,6 +767,7 @@ struct mwifiex_sta_node {
754 u16 max_amsdu; 767 u16 max_amsdu;
755 u8 tdls_status; 768 u8 tdls_status;
756 struct mwifiex_tdls_capab tdls_cap; 769 struct mwifiex_tdls_capab tdls_cap;
770 struct mwifiex_station_stats stats;
757}; 771};
758 772
759struct mwifiex_auto_tdls_peer { 773struct mwifiex_auto_tdls_peer {
@@ -959,6 +973,12 @@ struct mwifiex_adapter {
959 u32 num_in_chan_stats; 973 u32 num_in_chan_stats;
960 int survey_idx; 974 int survey_idx;
961 bool auto_tdls; 975 bool auto_tdls;
976 u8 coex_scan;
977 u8 coex_min_scan_time;
978 u8 coex_max_scan_time;
979 u8 coex_win_size;
980 u8 coex_tx_win_size;
981 u8 coex_rx_win_size;
962}; 982};
963 983
964void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter); 984void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
@@ -1135,6 +1155,9 @@ void mwifiex_set_ht_params(struct mwifiex_private *priv,
1135void mwifiex_set_vht_params(struct mwifiex_private *priv, 1155void mwifiex_set_vht_params(struct mwifiex_private *priv,
1136 struct mwifiex_uap_bss_param *bss_cfg, 1156 struct mwifiex_uap_bss_param *bss_cfg,
1137 struct cfg80211_ap_settings *params); 1157 struct cfg80211_ap_settings *params);
1158void mwifiex_set_tpc_params(struct mwifiex_private *priv,
1159 struct mwifiex_uap_bss_param *bss_cfg,
1160 struct cfg80211_ap_settings *params);
1138void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, 1161void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
1139 struct cfg80211_ap_settings *params); 1162 struct cfg80211_ap_settings *params);
1140void mwifiex_set_vht_width(struct mwifiex_private *priv, 1163void mwifiex_set_vht_width(struct mwifiex_private *priv,
@@ -1145,6 +1168,11 @@ mwifiex_set_wmm_params(struct mwifiex_private *priv,
1145 struct mwifiex_uap_bss_param *bss_cfg, 1168 struct mwifiex_uap_bss_param *bss_cfg,
1146 struct cfg80211_ap_settings *params); 1169 struct cfg80211_ap_settings *params);
1147void mwifiex_set_ba_params(struct mwifiex_private *priv); 1170void mwifiex_set_ba_params(struct mwifiex_private *priv);
1171
1172void mwifiex_update_ampdu_txwinsize(struct mwifiex_adapter *pmadapter);
1173void mwifiex_bt_coex_wlan_param_update_event(struct mwifiex_private *priv,
1174 struct sk_buff *event_skb);
1175
1148void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv); 1176void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv);
1149int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv, 1177int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
1150 struct host_cmd_ds_command *cmd, 1178 struct host_cmd_ds_command *cmd,
@@ -1382,6 +1410,7 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1382 struct mwifiex_bssdescriptor *bss_desc); 1410 struct mwifiex_bssdescriptor *bss_desc);
1383 1411
1384u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type); 1412u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type);
1413u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset);
1385 1414
1386struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, 1415struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1387 const char *name, 1416 const char *name,
@@ -1399,7 +1428,8 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
1399 struct cfg80211_beacon_data *data); 1428 struct cfg80211_beacon_data *data);
1400int mwifiex_del_mgmt_ies(struct mwifiex_private *priv); 1429int mwifiex_del_mgmt_ies(struct mwifiex_private *priv);
1401u8 *mwifiex_11d_code_2_region(u8 code); 1430u8 *mwifiex_11d_code_2_region(u8 code);
1402void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg, 1431void mwifiex_uap_set_channel(struct mwifiex_private *priv,
1432 struct mwifiex_uap_bss_param *bss_cfg,
1403 struct cfg80211_chan_def chandef); 1433 struct cfg80211_chan_def chandef);
1404int mwifiex_config_start_uap(struct mwifiex_private *priv, 1434int mwifiex_config_start_uap(struct mwifiex_private *priv,
1405 struct mwifiex_uap_bss_param *bss_cfg); 1435 struct mwifiex_uap_bss_param *bss_cfg);
@@ -1473,6 +1503,8 @@ mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
1473void mwifiex_dfs_cac_work_queue(struct work_struct *work); 1503void mwifiex_dfs_cac_work_queue(struct work_struct *work);
1474void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work); 1504void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work);
1475void mwifiex_abort_cac(struct mwifiex_private *priv); 1505void mwifiex_abort_cac(struct mwifiex_private *priv);
1506int mwifiex_stop_radar_detection(struct mwifiex_private *priv,
1507 struct cfg80211_chan_def *chandef);
1476int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv, 1508int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,
1477 struct sk_buff *skb); 1509 struct sk_buff *skb);
1478 1510
@@ -1488,7 +1520,8 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter);
1488void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter); 1520void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter);
1489void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags); 1521void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags);
1490void mwifiex_queue_main_work(struct mwifiex_adapter *adapter); 1522void mwifiex_queue_main_work(struct mwifiex_adapter *adapter);
1491 1523void mwifiex_coex_ampdu_rxwinsize(struct mwifiex_adapter *adapter);
1524void mwifiex_11n_delba(struct mwifiex_private *priv, int tid);
1492#ifdef CONFIG_DEBUG_FS 1525#ifdef CONFIG_DEBUG_FS
1493void mwifiex_debugfs_init(void); 1526void mwifiex_debugfs_init(void);
1494void mwifiex_debugfs_remove(void); 1527void mwifiex_debugfs_remove(void);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index aa5b9a310340..b645884b3b97 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -958,6 +958,27 @@ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv,
958 return 0; 958 return 0;
959} 959}
960 960
961static int mwifiex_ret_uap_sta_list(struct mwifiex_private *priv,
962 struct host_cmd_ds_command *resp)
963{
964 struct host_cmd_ds_sta_list *sta_list =
965 &resp->params.sta_list;
966 struct mwifiex_ie_types_sta_info *sta_info = (void *)&sta_list->tlv;
967 int i;
968 struct mwifiex_sta_node *sta_node;
969
970 for (i = 0; i < sta_list->sta_count; i++) {
971 sta_node = mwifiex_get_sta_entry(priv, sta_info->mac);
972 if (unlikely(!sta_node))
973 continue;
974
975 sta_node->stats.rssi = sta_info->rssi;
976 sta_info++;
977 }
978
979 return 0;
980}
981
961/* This function handles the command response of set_cfg_data */ 982/* This function handles the command response of set_cfg_data */
962static int mwifiex_ret_cfg_data(struct mwifiex_private *priv, 983static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
963 struct host_cmd_ds_command *resp) 984 struct host_cmd_ds_command *resp)
@@ -1148,6 +1169,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
1148 break; 1169 break;
1149 case HostCmd_CMD_UAP_SYS_CONFIG: 1170 case HostCmd_CMD_UAP_SYS_CONFIG:
1150 break; 1171 break;
1172 case HOST_CMD_APCMD_STA_LIST:
1173 ret = mwifiex_ret_uap_sta_list(priv, resp);
1174 break;
1151 case HostCmd_CMD_UAP_BSS_START: 1175 case HostCmd_CMD_UAP_BSS_START:
1152 adapter->tx_lock_flag = false; 1176 adapter->tx_lock_flag = false;
1153 adapter->pps_uapsd_mode = false; 1177 adapter->pps_uapsd_mode = false;
@@ -1159,6 +1183,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
1159 break; 1183 break;
1160 case HostCmd_CMD_UAP_STA_DEAUTH: 1184 case HostCmd_CMD_UAP_STA_DEAUTH:
1161 break; 1185 break;
1186 case HOST_CMD_APCMD_SYS_RESET:
1187 break;
1162 case HostCmd_CMD_MEF_CFG: 1188 case HostCmd_CMD_MEF_CFG:
1163 break; 1189 break;
1164 case HostCmd_CMD_COALESCE_CFG: 1190 case HostCmd_CMD_COALESCE_CFG:
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 95203780010a..848de2621958 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -183,6 +183,63 @@ static int mwifiex_parse_tdls_event(struct mwifiex_private *priv,
183} 183}
184 184
185/* 185/*
186* This function handles coex events generated by firmware
187*/
188void mwifiex_bt_coex_wlan_param_update_event(struct mwifiex_private *priv,
189 struct sk_buff *event_skb)
190{
191 struct mwifiex_adapter *adapter = priv->adapter;
192 struct mwifiex_ie_types_header *tlv;
193 struct mwifiex_ie_types_btcoex_aggr_win_size *winsizetlv;
194 struct mwifiex_ie_types_btcoex_scan_time *scantlv;
195 s32 len = event_skb->len - sizeof(u32);
196 u8 *cur_ptr = event_skb->data + sizeof(u32);
197 u16 tlv_type, tlv_len;
198
199 while (len >= sizeof(struct mwifiex_ie_types_header)) {
200 tlv = (struct mwifiex_ie_types_header *)cur_ptr;
201 tlv_len = le16_to_cpu(tlv->len);
202 tlv_type = le16_to_cpu(tlv->type);
203
204 if ((tlv_len + sizeof(struct mwifiex_ie_types_header)) > len)
205 break;
206 switch (tlv_type) {
207 case TLV_BTCOEX_WL_AGGR_WINSIZE:
208 winsizetlv =
209 (struct mwifiex_ie_types_btcoex_aggr_win_size *)tlv;
210 adapter->coex_win_size = winsizetlv->coex_win_size;
211 adapter->coex_tx_win_size =
212 winsizetlv->tx_win_size;
213 adapter->coex_rx_win_size =
214 winsizetlv->rx_win_size;
215 mwifiex_coex_ampdu_rxwinsize(adapter);
216 mwifiex_update_ampdu_txwinsize(adapter);
217 break;
218
219 case TLV_BTCOEX_WL_SCANTIME:
220 scantlv =
221 (struct mwifiex_ie_types_btcoex_scan_time *)tlv;
222 adapter->coex_scan = scantlv->coex_scan;
223 adapter->coex_min_scan_time = scantlv->min_scan_time;
224 adapter->coex_max_scan_time = scantlv->max_scan_time;
225 break;
226
227 default:
228 break;
229 }
230
231 len -= tlv_len + sizeof(struct mwifiex_ie_types_header);
232 cur_ptr += tlv_len +
233 sizeof(struct mwifiex_ie_types_header);
234 }
235
236 dev_dbg(adapter->dev, "coex_scan=%d min_scan=%d coex_win=%d, tx_win=%d rx_win=%d\n",
237 adapter->coex_scan, adapter->coex_min_scan_time,
238 adapter->coex_win_size, adapter->coex_tx_win_size,
239 adapter->coex_rx_win_size);
240}
241
242/*
186 * This function handles events generated by firmware. 243 * This function handles events generated by firmware.
187 * 244 *
188 * This is a generic function and handles all events. 245 * This is a generic function and handles all events.
@@ -531,6 +588,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
531 ret = mwifiex_11h_handle_radar_detected(priv, 588 ret = mwifiex_11h_handle_radar_detected(priv,
532 adapter->event_skb); 589 adapter->event_skb);
533 break; 590 break;
591 case EVENT_BT_COEX_WLAN_PARA_CHANGE:
592 dev_dbg(adapter->dev, "EVENT: BT coex wlan param update\n");
593 mwifiex_bt_coex_wlan_param_update_event(priv,
594 adapter->event_skb);
595 break;
534 default: 596 default:
535 mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n", 597 mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n",
536 eventcause); 598 eventcause);
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 28dcc84a34d2..5ed9b794053e 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -88,13 +88,22 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
88 struct mwifiex_adapter *adapter = priv->adapter; 88 struct mwifiex_adapter *adapter = priv->adapter;
89 u8 *head_ptr; 89 u8 *head_ptr;
90 struct txpd *local_tx_pd = NULL; 90 struct txpd *local_tx_pd = NULL;
91 struct mwifiex_sta_node *dest_node;
92 struct ethhdr *hdr = (void *)skb->data;
91 93
92 hroom = (adapter->iface_type == MWIFIEX_USB) ? 0 : INTF_HEADER_LEN; 94 hroom = (adapter->iface_type == MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
93 95
94 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) 96 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) {
97 dest_node = mwifiex_get_sta_entry(priv, hdr->h_dest);
98 if (dest_node) {
99 dest_node->stats.tx_bytes += skb->len;
100 dest_node->stats.tx_packets++;
101 }
102
95 head_ptr = mwifiex_process_uap_txpd(priv, skb); 103 head_ptr = mwifiex_process_uap_txpd(priv, skb);
96 else 104 } else {
97 head_ptr = mwifiex_process_sta_txpd(priv, skb); 105 head_ptr = mwifiex_process_sta_txpd(priv, skb);
106 }
98 107
99 if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) { 108 if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) {
100 skb_queue_tail(&adapter->tx_data_q, skb); 109 skb_queue_tail(&adapter->tx_data_q, skb);
@@ -310,11 +319,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
310 priv->stats.tx_errors++; 319 priv->stats.tx_errors++;
311 } 320 }
312 321
313 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) { 322 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT)
314 atomic_dec_return(&adapter->pending_bridged_pkts); 323 atomic_dec_return(&adapter->pending_bridged_pkts);
315 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT) 324
316 goto done; 325 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
317 } 326 goto done;
318 327
319 if (aggr) 328 if (aggr)
320 /* For skb_aggr, do not wake up tx queue */ 329 /* For skb_aggr, do not wake up tx queue */
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index a4ae28353b6d..b74930054b8c 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -222,6 +222,23 @@ void mwifiex_set_vht_params(struct mwifiex_private *priv,
222 return; 222 return;
223} 223}
224 224
225/* This function updates 11ac related parameters from IE
226 * and sets them into bss_config structure.
227 */
228void mwifiex_set_tpc_params(struct mwifiex_private *priv,
229 struct mwifiex_uap_bss_param *bss_cfg,
230 struct cfg80211_ap_settings *params)
231{
232 const u8 *tpc_ie;
233
234 tpc_ie = cfg80211_find_ie(WLAN_EID_TPC_REQUEST, params->beacon.tail,
235 params->beacon.tail_len);
236 if (tpc_ie)
237 bss_cfg->power_constraint = *(tpc_ie + 2);
238 else
239 bss_cfg->power_constraint = 0;
240}
241
225/* Enable VHT only when cfg80211_ap_settings has VHT IE. 242/* Enable VHT only when cfg80211_ap_settings has VHT IE.
226 * Otherwise disable VHT. 243 * Otherwise disable VHT.
227 */ 244 */
@@ -466,6 +483,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
466 struct host_cmd_tlv_auth_type *auth_type; 483 struct host_cmd_tlv_auth_type *auth_type;
467 struct host_cmd_tlv_rates *tlv_rates; 484 struct host_cmd_tlv_rates *tlv_rates;
468 struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer; 485 struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer;
486 struct host_cmd_tlv_power_constraint *pwr_ct;
469 struct mwifiex_ie_types_htcap *htcap; 487 struct mwifiex_ie_types_htcap *htcap;
470 struct mwifiex_ie_types_wmmcap *wmm_cap; 488 struct mwifiex_ie_types_wmmcap *wmm_cap;
471 struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; 489 struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
@@ -644,6 +662,15 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
644 tlv += sizeof(*ao_timer); 662 tlv += sizeof(*ao_timer);
645 } 663 }
646 664
665 if (bss_cfg->power_constraint) {
666 pwr_ct = (void *)tlv;
667 pwr_ct->header.type = cpu_to_le16(TLV_TYPE_PWR_CONSTRAINT);
668 pwr_ct->header.len = cpu_to_le16(sizeof(u8));
669 pwr_ct->constraint = bss_cfg->power_constraint;
670 cmd_size += sizeof(*pwr_ct);
671 tlv += sizeof(*pwr_ct);
672 }
673
647 if (bss_cfg->ps_sta_ao_timer) { 674 if (bss_cfg->ps_sta_ao_timer) {
648 ps_ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv; 675 ps_ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
649 ps_ao_timer->header.type = 676 ps_ao_timer->header.type =
@@ -754,6 +781,8 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
754 break; 781 break;
755 case HostCmd_CMD_UAP_BSS_START: 782 case HostCmd_CMD_UAP_BSS_START:
756 case HostCmd_CMD_UAP_BSS_STOP: 783 case HostCmd_CMD_UAP_BSS_STOP:
784 case HOST_CMD_APCMD_SYS_RESET:
785 case HOST_CMD_APCMD_STA_LIST:
757 cmd->command = cpu_to_le16(cmd_no); 786 cmd->command = cpu_to_le16(cmd_no);
758 cmd->size = cpu_to_le16(S_DS_GEN); 787 cmd->size = cpu_to_le16(S_DS_GEN);
759 break; 788 break;
@@ -775,11 +804,14 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
775 return 0; 804 return 0;
776} 805}
777 806
778void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg, 807void mwifiex_uap_set_channel(struct mwifiex_private *priv,
808 struct mwifiex_uap_bss_param *bss_cfg,
779 struct cfg80211_chan_def chandef) 809 struct cfg80211_chan_def chandef)
780{ 810{
781 u8 config_bands = 0; 811 u8 config_bands = 0;
782 812
813 priv->bss_chandef = chandef;
814
783 bss_cfg->channel = ieee80211_frequency_to_channel( 815 bss_cfg->channel = ieee80211_frequency_to_channel(
784 chandef.chan->center_freq); 816 chandef.chan->center_freq);
785 817
@@ -800,19 +832,28 @@ void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg,
800 if (chandef.width > NL80211_CHAN_WIDTH_40) 832 if (chandef.width > NL80211_CHAN_WIDTH_40)
801 config_bands |= BAND_AAC; 833 config_bands |= BAND_AAC;
802 } 834 }
835
836 priv->adapter->config_bands = config_bands;
803} 837}
804 838
805int mwifiex_config_start_uap(struct mwifiex_private *priv, 839int mwifiex_config_start_uap(struct mwifiex_private *priv,
806 struct mwifiex_uap_bss_param *bss_cfg) 840 struct mwifiex_uap_bss_param *bss_cfg)
807{ 841{
842 enum state_11d_t state_11d;
843
808 if (mwifiex_del_mgmt_ies(priv)) 844 if (mwifiex_del_mgmt_ies(priv))
809 mwifiex_dbg(priv->adapter, ERROR, 845 mwifiex_dbg(priv->adapter, ERROR,
810 "Failed to delete mgmt IEs!\n"); 846 "Failed to delete mgmt IEs!\n");
811 847
812 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP, 848 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
813 HostCmd_ACT_GEN_SET, 0, NULL, true)) { 849 HostCmd_ACT_GEN_SET, 0, NULL, true)) {
814 mwifiex_dbg(priv->adapter, ERROR, 850 mwifiex_dbg(priv->adapter, ERROR, "Failed to stop the BSS\n");
815 "Failed to stop the BSS\n"); 851 return -1;
852 }
853
854 if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET,
855 HostCmd_ACT_GEN_SET, 0, NULL, true)) {
856 mwifiex_dbg(priv->adapter, ERROR, "Failed to reset BSS\n");
816 return -1; 857 return -1;
817 } 858 }
818 859
@@ -824,6 +865,16 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv,
824 return -1; 865 return -1;
825 } 866 }
826 867
868 /* Send cmd to FW to enable 11D function */
869 state_11d = ENABLE_11D;
870 if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
871 HostCmd_ACT_GEN_SET, DOT11D_I,
872 &state_11d, true)) {
873 mwifiex_dbg(priv->adapter, ERROR,
874 "11D: failed to enable 11D\n");
875 return -1;
876 }
877
827 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START, 878 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
828 HostCmd_ACT_GEN_SET, 0, NULL, false)) { 879 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
829 mwifiex_dbg(priv->adapter, ERROR, 880 mwifiex_dbg(priv->adapter, ERROR,
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 06ce3fe660f1..7bc1f850e3b7 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -21,8 +21,70 @@
21#include "main.h" 21#include "main.h"
22#include "11n.h" 22#include "11n.h"
23 23
24#define MWIFIEX_BSS_START_EVT_FIX_SIZE 12
24 25
26static int mwifiex_check_uap_capabilties(struct mwifiex_private *priv,
27 struct sk_buff *event)
28{
29 int evt_len;
30 u8 *curr;
31 u16 tlv_len;
32 struct mwifiex_ie_types_data *tlv_hdr;
33 struct ieee_types_wmm_parameter *wmm_param_ie = NULL;
34 int mask = IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK;
35
36 priv->wmm_enabled = false;
37 skb_pull(event, MWIFIEX_BSS_START_EVT_FIX_SIZE);
38 evt_len = event->len;
39 curr = event->data;
40
41 mwifiex_dbg_dump(priv->adapter, EVT_D, "uap capabilties:",
42 event->data, event->len);
25 43
44 while ((evt_len >= sizeof(tlv_hdr->header))) {
45 tlv_hdr = (struct mwifiex_ie_types_data *)curr;
46 tlv_len = le16_to_cpu(tlv_hdr->header.len);
47
48 if (evt_len < tlv_len + sizeof(tlv_hdr->header))
49 break;
50
51 switch (le16_to_cpu(tlv_hdr->header.type)) {
52 case WLAN_EID_HT_CAPABILITY:
53 priv->ap_11n_enabled = true;
54 break;
55
56 case WLAN_EID_VHT_CAPABILITY:
57 priv->ap_11ac_enabled = true;
58 break;
59
60 case WLAN_EID_VENDOR_SPECIFIC:
61 /* Point the regular IEEE IE 2 bytes into the Marvell IE
62 * and setup the IEEE IE type and length byte fields
63 */
64 wmm_param_ie = (void *)(curr + 2);
65 wmm_param_ie->vend_hdr.len = (u8)tlv_len;
66 wmm_param_ie->vend_hdr.element_id =
67 WLAN_EID_VENDOR_SPECIFIC;
68 mwifiex_dbg(priv->adapter, EVENT,
69 "info: check uap capabilities:\t"
70 "wmm parameter set count: %d\n",
71 wmm_param_ie->qos_info_bitmap & mask);
72
73 mwifiex_wmm_setup_ac_downgrade(priv);
74 priv->wmm_enabled = true;
75 mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie);
76 break;
77
78 default:
79 break;
80 }
81
82 curr += (tlv_len + sizeof(tlv_hdr->header));
83 evt_len -= (tlv_len + sizeof(tlv_hdr->header));
84 }
85
86 return 0;
87}
26 88
27/* 89/*
28 * This function handles AP interface specific events generated by firmware. 90 * This function handles AP interface specific events generated by firmware.
@@ -134,6 +196,7 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
134 ETH_ALEN); 196 ETH_ALEN);
135 if (priv->hist_data) 197 if (priv->hist_data)
136 mwifiex_hist_data_reset(priv); 198 mwifiex_hist_data_reset(priv);
199 mwifiex_check_uap_capabilties(priv, adapter->event_skb);
137 break; 200 break;
138 case EVENT_UAP_MIC_COUNTERMEASURES: 201 case EVENT_UAP_MIC_COUNTERMEASURES:
139 /* For future development */ 202 /* For future development */
@@ -229,6 +292,11 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
229 mwifiex_dbg(adapter, EVENT, "event: Radar detected\n"); 292 mwifiex_dbg(adapter, EVENT, "event: Radar detected\n");
230 mwifiex_11h_handle_radar_detected(priv, adapter->event_skb); 293 mwifiex_11h_handle_radar_detected(priv, adapter->event_skb);
231 break; 294 break;
295 case EVENT_BT_COEX_WLAN_PARA_CHANGE:
296 dev_err(adapter->dev, "EVENT: BT coex wlan param update\n");
297 mwifiex_bt_coex_wlan_param_update_event(priv,
298 adapter->event_skb);
299 break;
232 default: 300 default:
233 mwifiex_dbg(adapter, EVENT, 301 mwifiex_dbg(adapter, EVENT,
234 "event: unknown event id: %#x\n", eventcause); 302 "event: unknown event id: %#x\n", eventcause);
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index 61c52fdf945d..87667418af5f 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -97,6 +97,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
97 struct mwifiex_txinfo *tx_info; 97 struct mwifiex_txinfo *tx_info;
98 int hdr_chop; 98 int hdr_chop;
99 struct ethhdr *p_ethhdr; 99 struct ethhdr *p_ethhdr;
100 struct mwifiex_sta_node *src_node;
100 101
101 uap_rx_pd = (struct uap_rxpd *)(skb->data); 102 uap_rx_pd = (struct uap_rxpd *)(skb->data);
102 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); 103 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
@@ -180,6 +181,15 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
180 tx_info->bss_type = priv->bss_type; 181 tx_info->bss_type = priv->bss_type;
181 tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT; 182 tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
182 183
184 src_node = mwifiex_get_sta_entry(priv, rx_pkt_hdr->eth803_hdr.h_source);
185 if (src_node) {
186 src_node->stats.last_rx = jiffies;
187 src_node->stats.rx_bytes += skb->len;
188 src_node->stats.rx_packets++;
189 src_node->stats.last_tx_rate = uap_rx_pd->rx_rate;
190 src_node->stats.last_tx_htinfo = uap_rx_pd->ht_info;
191 }
192
183 if (is_unicast_ether_addr(rx_pkt_hdr->eth803_hdr.h_dest)) { 193 if (is_unicast_ether_addr(rx_pkt_hdr->eth803_hdr.h_dest)) {
184 /* Update bridge packet statistics as the 194 /* Update bridge packet statistics as the
185 * packet is not going to kernel/upper layer. 195 * packet is not going to kernel/upper layer.
@@ -275,6 +285,8 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
275 rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type); 285 rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type);
276 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); 286 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
277 287
288 ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source);
289
278 if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) + 290 if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
279 le16_to_cpu(uap_rx_pd->rx_pkt_length)) > (u16) skb->len) { 291 le16_to_cpu(uap_rx_pd->rx_pkt_length)) > (u16) skb->len) {
280 mwifiex_dbg(adapter, ERROR, 292 mwifiex_dbg(adapter, ERROR,
@@ -282,6 +294,11 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
282 skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset), 294 skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset),
283 le16_to_cpu(uap_rx_pd->rx_pkt_length)); 295 le16_to_cpu(uap_rx_pd->rx_pkt_length));
284 priv->stats.rx_dropped++; 296 priv->stats.rx_dropped++;
297
298 node = mwifiex_get_sta_entry(priv, ta);
299 if (node)
300 node->stats.tx_failed++;
301
285 dev_kfree_skb_any(skb); 302 dev_kfree_skb_any(skb);
286 return 0; 303 return 0;
287 } 304 }
@@ -295,7 +312,6 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
295 return ret; 312 return ret;
296 } 313 }
297 314
298 memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN);
299 315
300 if (rx_pkt_type != PKT_TYPE_BAR && uap_rx_pd->priority < MAX_NUM_TID) { 316 if (rx_pkt_type != PKT_TYPE_BAR && uap_rx_pd->priority < MAX_NUM_TID) {
301 spin_lock_irqsave(&priv->sta_list_spinlock, flags); 317 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 370323a47ecb..790e61953abf 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -329,7 +329,7 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len,
329 struct rxpd *rx_pd) 329 struct rxpd *rx_pd)
330{ 330{
331 u16 stype; 331 u16 stype;
332 u8 category, action_code; 332 u8 category, action_code, *addr2;
333 struct ieee80211_hdr *ieee_hdr = (void *)payload; 333 struct ieee80211_hdr *ieee_hdr = (void *)payload;
334 334
335 stype = (le16_to_cpu(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE); 335 stype = (le16_to_cpu(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE);
@@ -337,21 +337,35 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len,
337 switch (stype) { 337 switch (stype) {
338 case IEEE80211_STYPE_ACTION: 338 case IEEE80211_STYPE_ACTION:
339 category = *(payload + sizeof(struct ieee80211_hdr)); 339 category = *(payload + sizeof(struct ieee80211_hdr));
340 action_code = *(payload + sizeof(struct ieee80211_hdr) + 1); 340 switch (category) {
341 if (category == WLAN_CATEGORY_PUBLIC && 341 case WLAN_CATEGORY_PUBLIC:
342 action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) { 342 action_code = *(payload + sizeof(struct ieee80211_hdr)
343 + 1);
344 if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
345 addr2 = ieee_hdr->addr2;
346 mwifiex_dbg(priv->adapter, INFO,
347 "TDLS discovery response %pM nf=%d, snr=%d\n",
348 addr2, rx_pd->nf, rx_pd->snr);
349 mwifiex_auto_tdls_update_peer_signal(priv,
350 addr2,
351 rx_pd->snr,
352 rx_pd->nf);
353 }
354 break;
355 case WLAN_CATEGORY_BACK:
356 /*we dont indicate BACK action frames to cfg80211*/
357 mwifiex_dbg(priv->adapter, INFO,
358 "drop BACK action frames");
359 return -1;
360 default:
343 mwifiex_dbg(priv->adapter, INFO, 361 mwifiex_dbg(priv->adapter, INFO,
344 "TDLS discovery response %pM nf=%d, snr=%d\n", 362 "unknown public action frame category %d\n",
345 ieee_hdr->addr2, rx_pd->nf, rx_pd->snr); 363 category);
346 mwifiex_auto_tdls_update_peer_signal(priv,
347 ieee_hdr->addr2,
348 rx_pd->snr,
349 rx_pd->nf);
350 } 364 }
351 break;
352 default: 365 default:
353 mwifiex_dbg(priv->adapter, INFO, 366 mwifiex_dbg(priv->adapter, INFO,
354 "unknown mgmt frame subtype %#x\n", stype); 367 "unknown mgmt frame subtype %#x\n", stype);
368 return 0;
355 } 369 }
356 370
357 return 0; 371 return 0;
@@ -387,8 +401,9 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
387 401
388 ieee_hdr = (void *)skb->data; 402 ieee_hdr = (void *)skb->data;
389 if (ieee80211_is_mgmt(ieee_hdr->frame_control)) { 403 if (ieee80211_is_mgmt(ieee_hdr->frame_control)) {
390 mwifiex_parse_mgmt_packet(priv, (u8 *)ieee_hdr, 404 if (mwifiex_parse_mgmt_packet(priv, (u8 *)ieee_hdr,
391 pkt_len, rx_pd); 405 pkt_len, rx_pd))
406 return -1;
392 } 407 }
393 /* Remove address4 */ 408 /* Remove address4 */
394 memmove(skb->data + sizeof(struct ieee80211_hdr_3addr), 409 memmove(skb->data + sizeof(struct ieee80211_hdr_3addr),
@@ -416,12 +431,25 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
416 */ 431 */
417int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb) 432int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb)
418{ 433{
434 struct mwifiex_sta_node *src_node;
435 struct ethhdr *p_ethhdr;
436
419 if (!skb) 437 if (!skb)
420 return -1; 438 return -1;
421 439
422 priv->stats.rx_bytes += skb->len; 440 priv->stats.rx_bytes += skb->len;
423 priv->stats.rx_packets++; 441 priv->stats.rx_packets++;
424 442
443 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
444 p_ethhdr = (void *)skb->data;
445 src_node = mwifiex_get_sta_entry(priv, p_ethhdr->h_source);
446 if (src_node) {
447 src_node->stats.last_rx = jiffies;
448 src_node->stats.rx_bytes += skb->len;
449 src_node->stats.rx_packets++;
450 }
451 }
452
425 skb->dev = priv->netdev; 453 skb->dev = priv->netdev;
426 skb->protocol = eth_type_trans(skb, priv->netdev); 454 skb->protocol = eth_type_trans(skb, priv->netdev);
427 skb->ip_summed = CHECKSUM_NONE; 455 skb->ip_summed = CHECKSUM_NONE;
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index ebd5625d13f1..95c1d7c0a2f3 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2961,6 +2961,15 @@ enum rt2800_eeprom_word {
2961#define BCN_TBTT_OFFSET 64 2961#define BCN_TBTT_OFFSET 64
2962 2962
2963/* 2963/*
2964 * Hardware has 255 WCID table entries. First 32 entries are reserved for
2965 * shared keys. Since parts of the pairwise key table might be shared with
2966 * the beacon frame buffers 6 & 7 we could only use the first 222 entries.
2967 */
2968#define WCID_START 33
2969#define WCID_END 222
2970#define STA_IDS_SIZE (WCID_END - WCID_START + 2)
2971
2972/*
2964 * RT2800 driver data structure 2973 * RT2800 driver data structure
2965 */ 2974 */
2966struct rt2800_drv_data { 2975struct rt2800_drv_data {
@@ -2971,6 +2980,7 @@ struct rt2800_drv_data {
2971 u8 txmixer_gain_24g; 2980 u8 txmixer_gain_24g;
2972 u8 txmixer_gain_5g; 2981 u8 txmixer_gain_5g;
2973 unsigned int tbtt_tick; 2982 unsigned int tbtt_tick;
2983 DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
2974}; 2984};
2975 2985
2976#endif /* RT2800_H */ 2986#endif /* RT2800_H */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 0bc5ac56f283..9524564f873b 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1381,38 +1381,6 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
1381} 1381}
1382EXPORT_SYMBOL_GPL(rt2800_config_shared_key); 1382EXPORT_SYMBOL_GPL(rt2800_config_shared_key);
1383 1383
1384static inline int rt2800_find_wcid(struct rt2x00_dev *rt2x00dev)
1385{
1386 struct mac_wcid_entry wcid_entry;
1387 int idx;
1388 u32 offset;
1389
1390 /*
1391 * Search for the first free WCID entry and return the corresponding
1392 * index.
1393 *
1394 * Make sure the WCID starts _after_ the last possible shared key
1395 * entry (>32).
1396 *
1397 * Since parts of the pairwise key table might be shared with
1398 * the beacon frame buffers 6 & 7 we should only write into the
1399 * first 222 entries.
1400 */
1401 for (idx = 33; idx <= 222; idx++) {
1402 offset = MAC_WCID_ENTRY(idx);
1403 rt2800_register_multiread(rt2x00dev, offset, &wcid_entry,
1404 sizeof(wcid_entry));
1405 if (is_broadcast_ether_addr(wcid_entry.mac))
1406 return idx;
1407 }
1408
1409 /*
1410 * Use -1 to indicate that we don't have any more space in the WCID
1411 * table.
1412 */
1413 return -1;
1414}
1415
1416int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, 1384int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
1417 struct rt2x00lib_crypto *crypto, 1385 struct rt2x00lib_crypto *crypto,
1418 struct ieee80211_key_conf *key) 1386 struct ieee80211_key_conf *key)
@@ -1425,7 +1393,7 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
1425 * Allow key configuration only for STAs that are 1393 * Allow key configuration only for STAs that are
1426 * known by the hw. 1394 * known by the hw.
1427 */ 1395 */
1428 if (crypto->wcid < 0) 1396 if (crypto->wcid > WCID_END)
1429 return -ENOSPC; 1397 return -ENOSPC;
1430 key->hw_key_idx = crypto->wcid; 1398 key->hw_key_idx = crypto->wcid;
1431 1399
@@ -1455,11 +1423,13 @@ int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif,
1455{ 1423{
1456 int wcid; 1424 int wcid;
1457 struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); 1425 struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta);
1426 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
1458 1427
1459 /* 1428 /*
1460 * Find next free WCID. 1429 * Search for the first free WCID entry and return the corresponding
1430 * index.
1461 */ 1431 */
1462 wcid = rt2800_find_wcid(rt2x00dev); 1432 wcid = find_first_zero_bit(drv_data->sta_ids, STA_IDS_SIZE) + WCID_START;
1463 1433
1464 /* 1434 /*
1465 * Store selected wcid even if it is invalid so that we can 1435 * Store selected wcid even if it is invalid so that we can
@@ -1471,9 +1441,11 @@ int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif,
1471 * No space left in the device, however, we can still communicate 1441 * No space left in the device, however, we can still communicate
1472 * with the STA -> No error. 1442 * with the STA -> No error.
1473 */ 1443 */
1474 if (wcid < 0) 1444 if (wcid > WCID_END)
1475 return 0; 1445 return 0;
1476 1446
1447 __set_bit(wcid - WCID_START, drv_data->sta_ids);
1448
1477 /* 1449 /*
1478 * Clean up WCID attributes and write STA address to the device. 1450 * Clean up WCID attributes and write STA address to the device.
1479 */ 1451 */
@@ -1487,11 +1459,16 @@ EXPORT_SYMBOL_GPL(rt2800_sta_add);
1487 1459
1488int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, int wcid) 1460int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, int wcid)
1489{ 1461{
1462 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
1463
1464 if (wcid > WCID_END)
1465 return 0;
1490 /* 1466 /*
1491 * Remove WCID entry, no need to clean the attributes as they will 1467 * Remove WCID entry, no need to clean the attributes as they will
1492 * get renewed when the WCID is reused. 1468 * get renewed when the WCID is reused.
1493 */ 1469 */
1494 rt2800_config_wcid(rt2x00dev, NULL, wcid); 1470 rt2800_config_wcid(rt2x00dev, NULL, wcid);
1471 __clear_bit(wcid - WCID_START, drv_data->sta_ids);
1495 1472
1496 return 0; 1473 return 0;
1497} 1474}
@@ -7968,11 +7945,11 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
7968 /* 7945 /*
7969 * Don't allow aggregation for stations the hardware isn't aware 7946 * Don't allow aggregation for stations the hardware isn't aware
7970 * of because tx status reports for frames to an unknown station 7947 * of because tx status reports for frames to an unknown station
7971 * always contain wcid=255 and thus we can't distinguish between 7948 * always contain wcid=WCID_END+1 and thus we can't distinguish
7972 * multiple stations which leads to unwanted situations when the 7949 * between multiple stations which leads to unwanted situations
7973 * hw reorders frames due to aggregation. 7950 * when the hw reorders frames due to aggregation.
7974 */ 7951 */
7975 if (sta_priv->wcid < 0) 7952 if (sta_priv->wcid > WCID_END)
7976 return 1; 7953 return 1;
7977 7954
7978 switch (action) { 7955 switch (action) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 1b8a459a412b..3c26ee65a415 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -535,16 +535,8 @@ int rt2x00mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
535 struct ieee80211_sta *sta) 535 struct ieee80211_sta *sta)
536{ 536{
537 struct rt2x00_dev *rt2x00dev = hw->priv; 537 struct rt2x00_dev *rt2x00dev = hw->priv;
538 struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta);
539 538
540 /* 539 return rt2x00dev->ops->lib->sta_add(rt2x00dev, vif, sta);
541 * If there's no space left in the device table store
542 * -1 as wcid but tell mac80211 everything went ok.
543 */
544 if (rt2x00dev->ops->lib->sta_add(rt2x00dev, vif, sta))
545 sta_priv->wcid = -1;
546
547 return 0;
548} 540}
549EXPORT_SYMBOL_GPL(rt2x00mac_sta_add); 541EXPORT_SYMBOL_GPL(rt2x00mac_sta_add);
550 542
@@ -554,12 +546,6 @@ int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
554 struct rt2x00_dev *rt2x00dev = hw->priv; 546 struct rt2x00_dev *rt2x00dev = hw->priv;
555 struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); 547 struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta);
556 548
557 /*
558 * If we never sent the STA to the device no need to clean it up.
559 */
560 if (sta_priv->wcid < 0)
561 return 0;
562
563 return rt2x00dev->ops->lib->sta_remove(rt2x00dev, sta_priv->wcid); 549 return rt2x00dev->ops->lib->sta_remove(rt2x00dev, sta_priv->wcid);
564} 550}
565EXPORT_SYMBOL_GPL(rt2x00mac_sta_remove); 551EXPORT_SYMBOL_GPL(rt2x00mac_sta_remove);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
index d930c1f78721..ce4da9d79fbd 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
@@ -1123,23 +1123,22 @@ static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw *hw)
1123void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw) 1123void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1124{ 1124{
1125 struct rtl_priv *rtlpriv = rtl_priv(hw); 1125 struct rtl_priv *rtlpriv = rtl_priv(hw);
1126 static u8 tm_trigger;
1127 1126
1128 if (!rtlpriv->dm.txpower_tracking) 1127 if (!rtlpriv->dm.txpower_tracking)
1129 return; 1128 return;
1130 1129
1131 if (!tm_trigger) { 1130 if (!rtlpriv->dm.tm_trigger) {
1132 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17)|BIT(16), 1131 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17)|BIT(16),
1133 0x03); 1132 0x03);
1134 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1133 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1135 "Trigger 88E Thermal Meter!!\n"); 1134 "Trigger 88E Thermal Meter!!\n");
1136 tm_trigger = 1; 1135 rtlpriv->dm.tm_trigger = 1;
1137 return; 1136 return;
1138 } else { 1137 } else {
1139 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1138 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1140 "Schedule TxPowerTracking !!\n"); 1139 "Schedule TxPowerTracking !!\n");
1141 dm_txpower_track_cb_therm(hw); 1140 dm_txpower_track_cb_therm(hw);
1142 tm_trigger = 0; 1141 rtlpriv->dm.tm_trigger = 0;
1143 } 1142 }
1144} 1143}
1145 1144
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
index f5ee67cda73a..0aca6f47487c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
@@ -1169,23 +1169,22 @@ static void rtl92c_dm_check_txpower_tracking_thermal_meter(
1169 struct ieee80211_hw *hw) 1169 struct ieee80211_hw *hw)
1170{ 1170{
1171 struct rtl_priv *rtlpriv = rtl_priv(hw); 1171 struct rtl_priv *rtlpriv = rtl_priv(hw);
1172 static u8 tm_trigger;
1173 1172
1174 if (!rtlpriv->dm.txpower_tracking) 1173 if (!rtlpriv->dm.txpower_tracking)
1175 return; 1174 return;
1176 1175
1177 if (!tm_trigger) { 1176 if (!rtlpriv->dm.tm_trigger) {
1178 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, 1177 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK,
1179 0x60); 1178 0x60);
1180 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1179 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1181 "Trigger 92S Thermal Meter!!\n"); 1180 "Trigger 92S Thermal Meter!!\n");
1182 tm_trigger = 1; 1181 rtlpriv->dm.tm_trigger = 1;
1183 return; 1182 return;
1184 } else { 1183 } else {
1185 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1184 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1186 "Schedule TxPowerTracking direct call!!\n"); 1185 "Schedule TxPowerTracking direct call!!\n");
1187 rtl92c_dm_txpower_tracking_directcall(hw); 1186 rtl92c_dm_txpower_tracking_directcall(hw);
1188 tm_trigger = 0; 1187 rtlpriv->dm.tm_trigger = 0;
1189 } 1188 }
1190} 1189}
1191 1190
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index 29983bc96a89..14b819ea8b71 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -233,13 +233,14 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
233 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; 233 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
234 pfwdata = (u8 *)rtlhal->pfirmware; 234 pfwdata = (u8 *)rtlhal->pfirmware;
235 fwsize = rtlhal->fwsize; 235 fwsize = rtlhal->fwsize;
236
237 if (IS_FW_HEADER_EXIST(pfwheader)) { 236 if (IS_FW_HEADER_EXIST(pfwheader)) {
238 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 237 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
239 "Firmware Version(%d), Signature(%#x),Size(%d)\n", 238 "Firmware Version(%d), Signature(%#x),Size(%d)\n",
240 pfwheader->version, pfwheader->signature, 239 pfwheader->version, pfwheader->signature,
241 (int)sizeof(struct rtl92c_firmware_header)); 240 (int)sizeof(struct rtl92c_firmware_header));
242 241
242 rtlhal->fw_version = pfwheader->version;
243 rtlhal->fw_subversion = pfwheader->subversion;
243 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); 244 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
244 fwsize = fwsize - sizeof(struct rtl92c_firmware_header); 245 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
245 } 246 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 189859617db8..767358a553fb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -840,6 +840,26 @@ static void _rtl92cu_init_wmac_setting(struct ieee80211_hw *hw)
840 rtl92c_set_data_filter(hw, value16); 840 rtl92c_set_data_filter(hw, value16);
841} 841}
842 842
843static void _rtl92cu_init_beacon_parameters(struct ieee80211_hw *hw)
844{
845 struct rtl_priv *rtlpriv = rtl_priv(hw);
846 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
847
848 rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010);
849
850 /* TODO: Remove these magic number */
851 rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404);
852 rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);
853 rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
854 /* Change beacon AIFS to the largest number
855 * beacause test chip does not contension before sending beacon.
856 */
857 if (IS_NORMAL_CHIP(rtlhal->version))
858 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F);
859 else
860 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF);
861}
862
843static int _rtl92cu_init_mac(struct ieee80211_hw *hw) 863static int _rtl92cu_init_mac(struct ieee80211_hw *hw)
844{ 864{
845 struct rtl_priv *rtlpriv = rtl_priv(hw); 865 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -887,7 +907,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw)
887 _rtl92cu_init_usb_aggregation(hw); 907 _rtl92cu_init_usb_aggregation(hw);
888 rtlpriv->cfg->ops->set_bw_mode(hw, NL80211_CHAN_HT20); 908 rtlpriv->cfg->ops->set_bw_mode(hw, NL80211_CHAN_HT20);
889 rtl92c_set_min_space(hw, IS_92C_SERIAL(rtlhal->version)); 909 rtl92c_set_min_space(hw, IS_92C_SERIAL(rtlhal->version));
890 rtl92c_init_beacon_parameters(hw, rtlhal->version); 910 _rtl92cu_init_beacon_parameters(hw);
891 rtl92c_init_ampdu_aggregation(hw); 911 rtl92c_init_ampdu_aggregation(hw);
892 rtl92c_init_beacon_max_error(hw); 912 rtl92c_init_beacon_max_error(hw);
893 return err; 913 return err;
@@ -987,7 +1007,6 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
987 struct rtl_phy *rtlphy = &(rtlpriv->phy); 1007 struct rtl_phy *rtlphy = &(rtlpriv->phy);
988 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 1008 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
989 int err = 0; 1009 int err = 0;
990 static bool iqk_initialized;
991 unsigned long flags; 1010 unsigned long flags;
992 1011
993 /* As this function can take a very long time (up to 350 ms) 1012 /* As this function can take a very long time (up to 350 ms)
@@ -1038,11 +1057,11 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
1038 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); 1057 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1039 if (ppsc->rfpwr_state == ERFON) { 1058 if (ppsc->rfpwr_state == ERFON) {
1040 rtl92c_phy_set_rfpath_switch(hw, 1); 1059 rtl92c_phy_set_rfpath_switch(hw, 1);
1041 if (iqk_initialized) { 1060 if (rtlphy->iqk_initialized) {
1042 rtl92c_phy_iq_calibrate(hw, true); 1061 rtl92c_phy_iq_calibrate(hw, true);
1043 } else { 1062 } else {
1044 rtl92c_phy_iq_calibrate(hw, false); 1063 rtl92c_phy_iq_calibrate(hw, false);
1045 iqk_initialized = true; 1064 rtlphy->iqk_initialized = true;
1046 } 1065 }
1047 rtl92c_dm_check_txpower_tracking(hw); 1066 rtl92c_dm_check_txpower_tracking(hw);
1048 rtl92c_phy_lc_calibrate(hw); 1067 rtl92c_phy_lc_calibrate(hw);
@@ -1391,6 +1410,9 @@ void rtl92cu_card_disable(struct ieee80211_hw *hw)
1391 _CardDisableHWSM(hw); 1410 _CardDisableHWSM(hw);
1392 else 1411 else
1393 _CardDisableWithoutHWSM(hw); 1412 _CardDisableWithoutHWSM(hw);
1413
1414 /* after power off we should do iqk again */
1415 rtlpriv->phy.iqk_initialized = false;
1394} 1416}
1395 1417
1396void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 1418void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
@@ -1451,25 +1473,6 @@ int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
1451 return 0; 1473 return 0;
1452} 1474}
1453 1475
1454static void _InitBeaconParameters(struct ieee80211_hw *hw)
1455{
1456 struct rtl_priv *rtlpriv = rtl_priv(hw);
1457 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1458
1459 rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010);
1460
1461 /* TODO: Remove these magic number */
1462 rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404);
1463 rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);
1464 rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
1465 /* Change beacon AIFS to the largest number
1466 * beacause test chip does not contension before sending beacon. */
1467 if (IS_NORMAL_CHIP(rtlhal->version))
1468 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F);
1469 else
1470 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF);
1471}
1472
1473static void _beacon_function_enable(struct ieee80211_hw *hw) 1476static void _beacon_function_enable(struct ieee80211_hw *hw)
1474{ 1477{
1475 struct rtl_priv *rtlpriv = rtl_priv(hw); 1478 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1490,7 +1493,7 @@ void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw)
1490 atim_window = 2; /*FIX MERGE */ 1493 atim_window = 2; /*FIX MERGE */
1491 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); 1494 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1492 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); 1495 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1493 _InitBeaconParameters(hw); 1496 _rtl92cu_init_beacon_parameters(hw);
1494 rtl_write_byte(rtlpriv, REG_SLOT, 0x09); 1497 rtl_write_byte(rtlpriv, REG_SLOT, 0x09);
1495 /* 1498 /*
1496 * Force beacon frame transmission even after receiving beacon frame 1499 * Force beacon frame transmission even after receiving beacon frame
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
index f3db6bc8596a..490a7cf7c702 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
@@ -641,21 +641,6 @@ void rtl92c_init_retry_function(struct ieee80211_hw *hw)
641 rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); 641 rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
642} 642}
643 643
644void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw,
645 enum version_8192c version)
646{
647 struct rtl_priv *rtlpriv = rtl_priv(hw);
648 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
649
650 rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404);/* ms */
651 rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);/*ms*/
652 rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
653 if (IS_NORMAL_CHIP(rtlhal->version))
654 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F);
655 else
656 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF);
657}
658
659void rtl92c_disable_fast_edca(struct ieee80211_hw *hw) 644void rtl92c_disable_fast_edca(struct ieee80211_hw *hw)
660{ 645{
661 struct rtl_priv *rtlpriv = rtl_priv(hw); 646 struct rtl_priv *rtlpriv = rtl_priv(hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
index 58548e8f2c41..e34f0f14ccd7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
@@ -70,9 +70,6 @@ void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw);
70void rtl92c_init_rdg_setting(struct ieee80211_hw *hw); 70void rtl92c_init_rdg_setting(struct ieee80211_hw *hw);
71void rtl92c_init_retry_function(struct ieee80211_hw *hw); 71void rtl92c_init_retry_function(struct ieee80211_hw *hw);
72 72
73void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw,
74 enum version_8192c version);
75
76void rtl92c_disable_fast_edca(struct ieee80211_hw *hw); 73void rtl92c_disable_fast_edca(struct ieee80211_hw *hw);
77void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T); 74void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T);
78 75
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
index 12f6d474b492..c972fa50926d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
@@ -108,13 +108,8 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
108bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw) 108bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw)
109{ 109{
110 bool rtstatus; 110 bool rtstatus;
111 struct rtl_priv *rtlpriv = rtl_priv(hw);
112 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
113 bool is92c = IS_92C_SERIAL(rtlhal->version);
114 111
115 rtstatus = _rtl92cu_phy_config_mac_with_headerfile(hw); 112 rtstatus = _rtl92cu_phy_config_mac_with_headerfile(hw);
116 if (is92c && IS_HARDWARE_TYPE_8192CE(rtlhal))
117 rtl_write_byte(rtlpriv, 0x14, 0x71);
118 return rtstatus; 113 return rtstatus;
119} 114}
120 115
@@ -122,7 +117,6 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
122{ 117{
123 bool rtstatus = true; 118 bool rtstatus = true;
124 struct rtl_priv *rtlpriv = rtl_priv(hw); 119 struct rtl_priv *rtlpriv = rtl_priv(hw);
125 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
126 u16 regval; 120 u16 regval;
127 u32 regval32; 121 u32 regval32;
128 u8 b_reg_hwparafile = 1; 122 u8 b_reg_hwparafile = 1;
@@ -134,17 +128,11 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
134 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); 128 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
135 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); 129 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
136 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); 130 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
137 if (IS_HARDWARE_TYPE_8192CE(rtlhal)) { 131 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |
138 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA | 132 FEN_BB_GLB_RSTn | FEN_BBRSTB);
139 FEN_DIO_PCIE | FEN_BB_GLB_RSTn | FEN_BBRSTB);
140 } else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) {
141 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |
142 FEN_BB_GLB_RSTn | FEN_BBRSTB);
143 }
144 regval32 = rtl_read_dword(rtlpriv, 0x87c); 133 regval32 = rtl_read_dword(rtlpriv, 0x87c);
145 rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31))); 134 rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31)));
146 if (IS_HARDWARE_TYPE_8192CU(rtlhal)) 135 rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
147 rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
148 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); 136 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
149 if (b_reg_hwparafile == 1) 137 if (b_reg_hwparafile == 1)
150 rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); 138 rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
@@ -162,7 +150,7 @@ bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
162 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); 150 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
163 arraylength = rtlphy->hwparam_tables[MAC_REG].length ; 151 arraylength = rtlphy->hwparam_tables[MAC_REG].length ;
164 ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata; 152 ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata;
165 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n"); 153 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CUMAC_2T_ARRAY\n");
166 for (i = 0; i < arraylength; i = i + 2) 154 for (i = 0; i < arraylength; i = i + 2)
167 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); 155 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
168 return true; 156 return true;
@@ -259,18 +247,18 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
259 radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length; 247 radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length;
260 radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata; 248 radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata;
261 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 249 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
262 "Radio_A:RTL8192CERADIOA_2TARRAY\n"); 250 "Radio_A:RTL8192CURADIOA_2TARRAY\n");
263 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 251 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
264 "Radio_B:RTL8192CE_RADIOB_2TARRAY\n"); 252 "Radio_B:RTL8192CU_RADIOB_2TARRAY\n");
265 } else { 253 } else {
266 radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length; 254 radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length;
267 radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata; 255 radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata;
268 radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length; 256 radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length;
269 radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata; 257 radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata;
270 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 258 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
271 "Radio_A:RTL8192CE_RADIOA_1TARRAY\n"); 259 "Radio_A:RTL8192CU_RADIOA_1TARRAY\n");
272 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 260 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
273 "Radio_B:RTL8192CE_RADIOB_1TARRAY\n"); 261 "Radio_B:RTL8192CU_RADIOB_1TARRAY\n");
274 } 262 }
275 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); 263 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
276 switch (rfpath) { 264 switch (rfpath) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
index b878d56d2f4d..5624ade92cc0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
@@ -66,7 +66,6 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
66{ 66{
67 struct rtl_priv *rtlpriv = rtl_priv(hw); 67 struct rtl_priv *rtlpriv = rtl_priv(hw);
68 struct rtl_phy *rtlphy = &(rtlpriv->phy); 68 struct rtl_phy *rtlphy = &(rtlpriv->phy);
69 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
70 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 69 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
71 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 70 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
72 u32 tx_agc[2] = { 0, 0 }, tmpval = 0; 71 u32 tx_agc[2] = { 0, 0 }, tmpval = 0;
@@ -74,14 +73,8 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
74 u8 idx1, idx2; 73 u8 idx1, idx2;
75 u8 *ptr; 74 u8 *ptr;
76 75
77 if (rtlhal->interface == INTF_PCI) { 76 if ((rtlefuse->eeprom_regulatory != 0) || (rtlefuse->external_pa))
78 if (rtlefuse->eeprom_regulatory != 0) 77 turbo_scanoff = true;
79 turbo_scanoff = true;
80 } else {
81 if ((rtlefuse->eeprom_regulatory != 0) ||
82 (rtlefuse->external_pa))
83 turbo_scanoff = true;
84 }
85 if (mac->act_scanning) { 78 if (mac->act_scanning) {
86 tx_agc[RF90_PATH_A] = 0x3f3f3f3f; 79 tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
87 tx_agc[RF90_PATH_B] = 0x3f3f3f3f; 80 tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
@@ -90,11 +83,8 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
90 (ppowerlevel[idx1] << 8) | 83 (ppowerlevel[idx1] << 8) |
91 (ppowerlevel[idx1] << 16) | 84 (ppowerlevel[idx1] << 16) |
92 (ppowerlevel[idx1] << 24); 85 (ppowerlevel[idx1] << 24);
93 if (rtlhal->interface == INTF_USB) { 86 if (tx_agc[idx1] > 0x20 && rtlefuse->external_pa)
94 if (tx_agc[idx1] > 0x20 && 87 tx_agc[idx1] = 0x20;
95 rtlefuse->external_pa)
96 tx_agc[idx1] = 0x20;
97 }
98 } 88 }
99 } else { 89 } else {
100 if (rtlpriv->dm.dynamic_txhighpower_lvl == 90 if (rtlpriv->dm.dynamic_txhighpower_lvl ==
@@ -452,9 +442,6 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
452 udelay(1); 442 udelay(1);
453 switch (rfpath) { 443 switch (rfpath) {
454 case RF90_PATH_A: 444 case RF90_PATH_A:
455 rtstatus = rtl92cu_phy_config_rf_with_headerfile(hw,
456 (enum radio_path) rfpath);
457 break;
458 case RF90_PATH_B: 445 case RF90_PATH_B:
459 rtstatus = rtl92cu_phy_config_rf_with_headerfile(hw, 446 rtstatus = rtl92cu_phy_config_rf_with_headerfile(hw,
460 (enum radio_path) rfpath); 447 (enum radio_path) rfpath);
@@ -483,7 +470,6 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
483 } 470 }
484 } 471 }
485 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); 472 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
486 return rtstatus;
487phy_rf_cfg_fail: 473phy_rf_cfg_fail:
488 return rtstatus; 474 return rtstatus;
489} 475}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index cbead007171f..95880fe4106e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -321,7 +321,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
321 stats->rate = (u8) GET_RX_DESC_RX_MCS(pdesc); 321 stats->rate = (u8) GET_RX_DESC_RX_MCS(pdesc);
322 stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); 322 stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
323 stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); 323 stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
324 stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) 324 stats->isfirst_ampdu = (bool)((GET_RX_DESC_PAGGR(pdesc) == 1)
325 && (GET_RX_DESC_FAGGR(pdesc) == 1)); 325 && (GET_RX_DESC_FAGGR(pdesc) == 1));
326 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); 326 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
327 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); 327 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
index a1be5a68edfb..587b8c505a76 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
@@ -1240,23 +1240,22 @@ static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
1240void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw) 1240void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw)
1241{ 1241{
1242 struct rtl_priv *rtlpriv = rtl_priv(hw); 1242 struct rtl_priv *rtlpriv = rtl_priv(hw);
1243 static u8 tm_trigger;
1244 1243
1245 if (!rtlpriv->dm.txpower_tracking) 1244 if (!rtlpriv->dm.txpower_tracking)
1246 return; 1245 return;
1247 1246
1248 if (!tm_trigger) { 1247 if (!rtlpriv->dm.tm_trigger) {
1249 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | 1248 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) |
1250 BIT(16), 0x03); 1249 BIT(16), 0x03);
1251 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1250 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1252 "Trigger 92S Thermal Meter!!\n"); 1251 "Trigger 92S Thermal Meter!!\n");
1253 tm_trigger = 1; 1252 rtlpriv->dm.tm_trigger = 1;
1254 return; 1253 return;
1255 } else { 1254 } else {
1256 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1255 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1257 "Schedule TxPowerTracking direct call!!\n"); 1256 "Schedule TxPowerTracking direct call!!\n");
1258 rtl92d_dm_txpower_tracking_callback_thermalmeter(hw); 1257 rtl92d_dm_txpower_tracking_callback_thermalmeter(hw);
1259 tm_trigger = 0; 1258 rtlpriv->dm.tm_trigger = 0;
1260 } 1259 }
1261} 1260}
1262 1261
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
index 575980b88658..9bae5a92e30f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
@@ -200,7 +200,6 @@ static void _rtl92s_dm_check_txpowertracking_thermalmeter(
200{ 200{
201 struct rtl_priv *rtlpriv = rtl_priv(hw); 201 struct rtl_priv *rtlpriv = rtl_priv(hw);
202 struct rtl_phy *rtlphy = &(rtlpriv->phy); 202 struct rtl_phy *rtlphy = &(rtlpriv->phy);
203 static u8 tm_trigger;
204 u8 tx_power_checkcnt = 5; 203 u8 tx_power_checkcnt = 5;
205 204
206 /* 2T2R TP issue */ 205 /* 2T2R TP issue */
@@ -215,13 +214,13 @@ static void _rtl92s_dm_check_txpowertracking_thermalmeter(
215 return; 214 return;
216 } 215 }
217 216
218 if (!tm_trigger) { 217 if (!rtlpriv->dm.tm_trigger) {
219 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, 218 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER,
220 RFREG_OFFSET_MASK, 0x60); 219 RFREG_OFFSET_MASK, 0x60);
221 tm_trigger = 1; 220 rtlpriv->dm.tm_trigger = 1;
222 } else { 221 } else {
223 _rtl92s_dm_txpowertracking_callback_thermalmeter(hw); 222 _rtl92s_dm_txpowertracking_callback_thermalmeter(hw);
224 tm_trigger = 0; 223 rtlpriv->dm.tm_trigger = 0;
225 } 224 }
226} 225}
227 226
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
index e77c3a46c94a..3a81cdba8ca3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
@@ -909,23 +909,22 @@ static void rtl8723be_dm_txpower_tracking_callback_thermalmeter(
909void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw) 909void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw)
910{ 910{
911 struct rtl_priv *rtlpriv = rtl_priv(hw); 911 struct rtl_priv *rtlpriv = rtl_priv(hw);
912 static u8 tm_trigger;
913 912
914 if (!rtlpriv->dm.txpower_tracking) 913 if (!rtlpriv->dm.txpower_tracking)
915 return; 914 return;
916 915
917 if (!tm_trigger) { 916 if (!rtlpriv->dm.tm_trigger) {
918 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16), 917 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16),
919 0x03); 918 0x03);
920 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 919 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
921 "Trigger 8723be Thermal Meter!!\n"); 920 "Trigger 8723be Thermal Meter!!\n");
922 tm_trigger = 1; 921 rtlpriv->dm.tm_trigger = 1;
923 return; 922 return;
924 } else { 923 } else {
925 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 924 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
926 "Schedule TxPowerTracking !!\n"); 925 "Schedule TxPowerTracking !!\n");
927 rtl8723be_dm_txpower_tracking_callback_thermalmeter(hw); 926 rtl8723be_dm_txpower_tracking_callback_thermalmeter(hw);
928 tm_trigger = 0; 927 rtlpriv->dm.tm_trigger = 0;
929 } 928 }
930} 929}
931 930
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c
index 342678d2ed42..b57cfd965196 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c
@@ -1068,20 +1068,18 @@ static void rtl8812ae_dm_check_txpower_tracking_thermalmeter(
1068 struct ieee80211_hw *hw) 1068 struct ieee80211_hw *hw)
1069{ 1069{
1070 struct rtl_priv *rtlpriv = rtl_priv(hw); 1070 struct rtl_priv *rtlpriv = rtl_priv(hw);
1071 static u8 tm_trigger;
1072 1071
1073 if (!tm_trigger) { 1072 if (!rtlpriv->dm.tm_trigger) {
1074 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, 1073 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E,
1075 BIT(17) | BIT(16), 0x03); 1074 BIT(17) | BIT(16), 0x03);
1076 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1075 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1077 "Trigger 8812 Thermal Meter!!\n"); 1076 "Trigger 8812 Thermal Meter!!\n");
1078 tm_trigger = 1; 1077 rtlpriv->dm.tm_trigger = 1;
1079 return; 1078 return;
1080 } 1079 }
1081 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1080 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1082 "Schedule TxPowerTracking direct call!!\n"); 1081 "Schedule TxPowerTracking direct call!!\n");
1083 rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw); 1082 rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw);
1084 tm_trigger = 0;
1085} 1083}
1086 1084
1087static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw) 1085static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw)
@@ -2519,21 +2517,19 @@ void rtl8821ae_dm_txpower_tracking_callback_thermalmeter(
2519void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw) 2517void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw)
2520{ 2518{
2521 struct rtl_priv *rtlpriv = rtl_priv(hw); 2519 struct rtl_priv *rtlpriv = rtl_priv(hw);
2522 static u8 tm_trigger; 2520 if (!rtlpriv->dm.tm_trigger) {
2523
2524 if (!tm_trigger) {
2525 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16), 2521 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16),
2526 0x03); 2522 0x03);
2527 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2523 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2528 "Trigger 8821ae Thermal Meter!!\n"); 2524 "Trigger 8821ae Thermal Meter!!\n");
2529 tm_trigger = 1; 2525 rtlpriv->dm.tm_trigger = 1;
2530 return; 2526 return;
2531 } else { 2527 } else {
2532 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2528 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2533 "Schedule TxPowerTracking !!\n"); 2529 "Schedule TxPowerTracking !!\n");
2534 2530
2535 rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw); 2531 rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw);
2536 tm_trigger = 0; 2532 rtlpriv->dm.tm_trigger = 0;
2537 } 2533 }
2538} 2534}
2539 2535
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 51572912c53d..2b770b5e2620 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -1665,6 +1665,7 @@ struct rtl_dm {
1665 u8 last_dtp_lvl; 1665 u8 last_dtp_lvl;
1666 u8 thermalvalue_avg[AVG_THERMAL_NUM]; 1666 u8 thermalvalue_avg[AVG_THERMAL_NUM];
1667 u8 thermalvalue_avg_index; 1667 u8 thermalvalue_avg_index;
1668 u8 tm_trigger;
1668 bool done_txpower; 1669 bool done_txpower;
1669 u8 dynamic_txhighpower_lvl; /*Tx high power level */ 1670 u8 dynamic_txhighpower_lvl; /*Tx high power level */
1670 u8 dm_flag; /*Indicate each dynamic mechanism's status. */ 1671 u8 dm_flag; /*Indicate each dynamic mechanism's status. */
diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c
index 5695628757ee..d6fbdda2cba3 100644
--- a/drivers/net/wireless/ti/wl1251/acx.c
+++ b/drivers/net/wireless/ti/wl1251/acx.c
@@ -53,10 +53,7 @@ int wl1251_acx_station_id(struct wl1251 *wl)
53 mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i]; 53 mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
54 54
55 ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac)); 55 ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
56 if (ret < 0)
57 goto out;
58 56
59out:
60 kfree(mac); 57 kfree(mac);
61 return ret; 58 return ret;
62} 59}