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/ce.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c8
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h27
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c101
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c164
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h7
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c132
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h15
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c27
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h18
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.c158
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.h61
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_wow.c61
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c95
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c52
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h275
-rw-r--r--drivers/net/wireless/ath/ath9k/reg_mci.h310
-rw-r--r--drivers/net/wireless/ath/ath9k/reg_wow.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c42
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c32
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c28
-rw-r--r--drivers/net/wireless/ath/wil6210/ethtool.c34
-rw-r--r--drivers/net/wireless/ath/wil6210/fw.c3
-rw-r--r--drivers/net/wireless/ath/wil6210/fw_inc.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c70
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c166
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c22
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c123
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h34
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c9
-rw-r--r--drivers/net/wireless/b43/main.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c166
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.c30
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c115
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.h47
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c11
-rw-r--r--drivers/net/wireless/iwlegacy/4965-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c68
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h151
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex_legacy.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c54
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h191
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h64
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c133
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c36
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c180
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h125
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c44
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c215
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c150
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c600
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c207
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c6
-rw-r--r--drivers/net/wireless/libertas/debugfs.c3
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c14
-rw-r--r--drivers/net/wireless/mwifiex/decl.h1
-rw-r--r--drivers/net/wireless/mwifiex/init.c1
-rw-r--r--drivers/net/wireless/mwifiex/main.c16
-rw-r--r--drivers/net/wireless/mwifiex/main.h5
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c10
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h6
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c13
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h62
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c8
-rw-r--r--drivers/net/wireless/mwifiex/util.c30
-rw-r--r--drivers/net/wireless/rtlwifi/base.h6
-rw-r--r--drivers/net/wireless/rtlwifi/cam.h2
-rw-r--r--drivers/net/wireless/rtlwifi/core.h2
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.h6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/def.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/phy.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/def.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/def.h39
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/def.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/def.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/def.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/hw.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c11
121 files changed, 3142 insertions, 2271 deletions
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h
index c18647b87f71..0eddb204d85b 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -39,7 +39,7 @@ struct ath10k_ce_pipe;
39#define CE_DESC_FLAGS_GATHER (1 << 0) 39#define CE_DESC_FLAGS_GATHER (1 << 0)
40#define CE_DESC_FLAGS_BYTE_SWAP (1 << 1) 40#define CE_DESC_FLAGS_BYTE_SWAP (1 << 1)
41#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC 41#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC
42#define CE_DESC_FLAGS_META_DATA_LSB 3 42#define CE_DESC_FLAGS_META_DATA_LSB 2
43 43
44struct ce_desc { 44struct ce_desc {
45 __le32 addr; 45 __le32 addr;
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 310e12bc078a..c0e454bb6a8d 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -436,16 +436,16 @@ static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
436 436
437static void ath10k_core_free_firmware_files(struct ath10k *ar) 437static void ath10k_core_free_firmware_files(struct ath10k *ar)
438{ 438{
439 if (ar->board && !IS_ERR(ar->board)) 439 if (!IS_ERR(ar->board))
440 release_firmware(ar->board); 440 release_firmware(ar->board);
441 441
442 if (ar->otp && !IS_ERR(ar->otp)) 442 if (!IS_ERR(ar->otp))
443 release_firmware(ar->otp); 443 release_firmware(ar->otp);
444 444
445 if (ar->firmware && !IS_ERR(ar->firmware)) 445 if (!IS_ERR(ar->firmware))
446 release_firmware(ar->firmware); 446 release_firmware(ar->firmware);
447 447
448 if (ar->cal_file && !IS_ERR(ar->cal_file)) 448 if (!IS_ERR(ar->cal_file))
449 release_firmware(ar->cal_file); 449 release_firmware(ar->cal_file);
450 450
451 ar->board = NULL; 451 ar->board = NULL;
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index d60e46fe6d19..f65310c3ba5f 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -159,6 +159,25 @@ struct ath10k_fw_stats_peer {
159 u32 peer_rx_rate; /* 10x only */ 159 u32 peer_rx_rate; /* 10x only */
160}; 160};
161 161
162struct ath10k_fw_stats_vdev {
163 struct list_head list;
164
165 u32 vdev_id;
166 u32 beacon_snr;
167 u32 data_snr;
168 u32 num_tx_frames[4];
169 u32 num_rx_frames;
170 u32 num_tx_frames_retries[4];
171 u32 num_tx_frames_failures[4];
172 u32 num_rts_fail;
173 u32 num_rts_success;
174 u32 num_rx_err;
175 u32 num_rx_discard;
176 u32 num_tx_not_acked;
177 u32 tx_rate_history[10];
178 u32 beacon_rssi_history[10];
179};
180
162struct ath10k_fw_stats_pdev { 181struct ath10k_fw_stats_pdev {
163 struct list_head list; 182 struct list_head list;
164 183
@@ -220,6 +239,7 @@ struct ath10k_fw_stats_pdev {
220 239
221struct ath10k_fw_stats { 240struct ath10k_fw_stats {
222 struct list_head pdevs; 241 struct list_head pdevs;
242 struct list_head vdevs;
223 struct list_head peers; 243 struct list_head peers;
224}; 244};
225 245
@@ -288,6 +308,7 @@ struct ath10k_vif {
288 bool is_started; 308 bool is_started;
289 bool is_up; 309 bool is_up;
290 bool spectral_enabled; 310 bool spectral_enabled;
311 bool ps;
291 u32 aid; 312 u32 aid;
292 u8 bssid[ETH_ALEN]; 313 u8 bssid[ETH_ALEN];
293 314
@@ -413,6 +434,12 @@ enum ath10k_fw_features {
413 */ 434 */
414 ATH10K_FW_FEATURE_WMI_10_2 = 4, 435 ATH10K_FW_FEATURE_WMI_10_2 = 4,
415 436
437 /* Some firmware revisions lack proper multi-interface client powersave
438 * implementation. Enabling PS could result in connection drops,
439 * traffic stalls, etc.
440 */
441 ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT = 5,
442
416 /* keep last */ 443 /* keep last */
417 ATH10K_FW_FEATURE_COUNT, 444 ATH10K_FW_FEATURE_COUNT,
418}; 445};
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index d2281e5c2ffe..301081db1ef6 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -243,6 +243,16 @@ static void ath10k_debug_fw_stats_pdevs_free(struct list_head *head)
243 } 243 }
244} 244}
245 245
246static void ath10k_debug_fw_stats_vdevs_free(struct list_head *head)
247{
248 struct ath10k_fw_stats_vdev *i, *tmp;
249
250 list_for_each_entry_safe(i, tmp, head, list) {
251 list_del(&i->list);
252 kfree(i);
253 }
254}
255
246static void ath10k_debug_fw_stats_peers_free(struct list_head *head) 256static void ath10k_debug_fw_stats_peers_free(struct list_head *head)
247{ 257{
248 struct ath10k_fw_stats_peer *i, *tmp; 258 struct ath10k_fw_stats_peer *i, *tmp;
@@ -258,6 +268,7 @@ static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
258 spin_lock_bh(&ar->data_lock); 268 spin_lock_bh(&ar->data_lock);
259 ar->debug.fw_stats_done = false; 269 ar->debug.fw_stats_done = false;
260 ath10k_debug_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); 270 ath10k_debug_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
271 ath10k_debug_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
261 ath10k_debug_fw_stats_peers_free(&ar->debug.fw_stats.peers); 272 ath10k_debug_fw_stats_peers_free(&ar->debug.fw_stats.peers);
262 spin_unlock_bh(&ar->data_lock); 273 spin_unlock_bh(&ar->data_lock);
263} 274}
@@ -273,14 +284,27 @@ static size_t ath10k_debug_fw_stats_num_peers(struct list_head *head)
273 return num; 284 return num;
274} 285}
275 286
287static size_t ath10k_debug_fw_stats_num_vdevs(struct list_head *head)
288{
289 struct ath10k_fw_stats_vdev *i;
290 size_t num = 0;
291
292 list_for_each_entry(i, head, list)
293 ++num;
294
295 return num;
296}
297
276void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) 298void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
277{ 299{
278 struct ath10k_fw_stats stats = {}; 300 struct ath10k_fw_stats stats = {};
279 bool is_start, is_started, is_end; 301 bool is_start, is_started, is_end;
280 size_t num_peers; 302 size_t num_peers;
303 size_t num_vdevs;
281 int ret; 304 int ret;
282 305
283 INIT_LIST_HEAD(&stats.pdevs); 306 INIT_LIST_HEAD(&stats.pdevs);
307 INIT_LIST_HEAD(&stats.vdevs);
284 INIT_LIST_HEAD(&stats.peers); 308 INIT_LIST_HEAD(&stats.peers);
285 309
286 spin_lock_bh(&ar->data_lock); 310 spin_lock_bh(&ar->data_lock);
@@ -308,6 +332,7 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
308 } 332 }
309 333
310 num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers); 334 num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers);
335 num_vdevs = ath10k_debug_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
311 is_start = (list_empty(&ar->debug.fw_stats.pdevs) && 336 is_start = (list_empty(&ar->debug.fw_stats.pdevs) &&
312 !list_empty(&stats.pdevs)); 337 !list_empty(&stats.pdevs));
313 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) && 338 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) &&
@@ -330,7 +355,13 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
330 goto free; 355 goto free;
331 } 356 }
332 357
358 if (num_vdevs >= BITS_PER_LONG) {
359 ath10k_warn(ar, "dropping fw vdev stats\n");
360 goto free;
361 }
362
333 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers); 363 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers);
364 list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs);
334 } 365 }
335 366
336 complete(&ar->debug.fw_stats_complete); 367 complete(&ar->debug.fw_stats_complete);
@@ -340,6 +371,7 @@ free:
340 * resources if that is not the case. 371 * resources if that is not the case.
341 */ 372 */
342 ath10k_debug_fw_stats_pdevs_free(&stats.pdevs); 373 ath10k_debug_fw_stats_pdevs_free(&stats.pdevs);
374 ath10k_debug_fw_stats_vdevs_free(&stats.vdevs);
343 ath10k_debug_fw_stats_peers_free(&stats.peers); 375 ath10k_debug_fw_stats_peers_free(&stats.peers);
344 376
345unlock: 377unlock:
@@ -363,7 +395,10 @@ static int ath10k_debug_fw_stats_request(struct ath10k *ar)
363 395
364 reinit_completion(&ar->debug.fw_stats_complete); 396 reinit_completion(&ar->debug.fw_stats_complete);
365 397
366 ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); 398 ret = ath10k_wmi_request_stats(ar,
399 WMI_STAT_PDEV |
400 WMI_STAT_VDEV |
401 WMI_STAT_PEER);
367 if (ret) { 402 if (ret) {
368 ath10k_warn(ar, "could not request stats (%d)\n", ret); 403 ath10k_warn(ar, "could not request stats (%d)\n", ret);
369 return ret; 404 return ret;
@@ -395,8 +430,11 @@ static void ath10k_fw_stats_fill(struct ath10k *ar,
395 unsigned int len = 0; 430 unsigned int len = 0;
396 unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE; 431 unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE;
397 const struct ath10k_fw_stats_pdev *pdev; 432 const struct ath10k_fw_stats_pdev *pdev;
433 const struct ath10k_fw_stats_vdev *vdev;
398 const struct ath10k_fw_stats_peer *peer; 434 const struct ath10k_fw_stats_peer *peer;
399 size_t num_peers; 435 size_t num_peers;
436 size_t num_vdevs;
437 int i;
400 438
401 spin_lock_bh(&ar->data_lock); 439 spin_lock_bh(&ar->data_lock);
402 440
@@ -408,6 +446,7 @@ static void ath10k_fw_stats_fill(struct ath10k *ar,
408 } 446 }
409 447
410 num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers); 448 num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers);
449 num_vdevs = ath10k_debug_fw_stats_num_vdevs(&fw_stats->vdevs);
411 450
412 len += scnprintf(buf + len, buf_len - len, "\n"); 451 len += scnprintf(buf + len, buf_len - len, "\n");
413 len += scnprintf(buf + len, buf_len - len, "%30s\n", 452 len += scnprintf(buf + len, buf_len - len, "%30s\n",
@@ -531,6 +570,65 @@ static void ath10k_fw_stats_fill(struct ath10k *ar,
531 570
532 len += scnprintf(buf + len, buf_len - len, "\n"); 571 len += scnprintf(buf + len, buf_len - len, "\n");
533 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n", 572 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
573 "ath10k VDEV stats", num_vdevs);
574 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
575 "=================");
576
577 list_for_each_entry(vdev, &fw_stats->vdevs, list) {
578 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
579 "vdev id", vdev->vdev_id);
580 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
581 "beacon snr", vdev->beacon_snr);
582 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
583 "data snr", vdev->data_snr);
584 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
585 "num rx frames", vdev->num_rx_frames);
586 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
587 "num rts fail", vdev->num_rts_fail);
588 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
589 "num rts success", vdev->num_rts_success);
590 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
591 "num rx err", vdev->num_rx_err);
592 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
593 "num rx discard", vdev->num_rx_discard);
594 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
595 "num tx not acked", vdev->num_tx_not_acked);
596
597 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++)
598 len += scnprintf(buf + len, buf_len - len,
599 "%25s [%02d] %u\n",
600 "num tx frames", i,
601 vdev->num_tx_frames[i]);
602
603 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++)
604 len += scnprintf(buf + len, buf_len - len,
605 "%25s [%02d] %u\n",
606 "num tx frames retries", i,
607 vdev->num_tx_frames_retries[i]);
608
609 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++)
610 len += scnprintf(buf + len, buf_len - len,
611 "%25s [%02d] %u\n",
612 "num tx frames failures", i,
613 vdev->num_tx_frames_failures[i]);
614
615 for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++)
616 len += scnprintf(buf + len, buf_len - len,
617 "%25s [%02d] 0x%08x\n",
618 "tx rate history", i,
619 vdev->tx_rate_history[i]);
620
621 for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++)
622 len += scnprintf(buf + len, buf_len - len,
623 "%25s [%02d] %u\n",
624 "beacon rssi history", i,
625 vdev->beacon_rssi_history[i]);
626
627 len += scnprintf(buf + len, buf_len - len, "\n");
628 }
629
630 len += scnprintf(buf + len, buf_len - len, "\n");
631 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
534 "ath10k PEER stats", num_peers); 632 "ath10k PEER stats", num_peers);
535 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 633 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
536 "================="); 634 "=================");
@@ -1900,6 +1998,7 @@ int ath10k_debug_create(struct ath10k *ar)
1900 return -ENOMEM; 1998 return -ENOMEM;
1901 1999
1902 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); 2000 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
2001 INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
1903 INIT_LIST_HEAD(&ar->debug.fw_stats.peers); 2002 INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
1904 2003
1905 return 0; 2004 return 0;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index c1da44f65a4d..01a2b384f358 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -176,7 +176,7 @@ static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt)
176 * automatically balances load wrt to CPU power. 176 * automatically balances load wrt to CPU power.
177 * 177 *
178 * This probably comes at a cost of lower maximum throughput but 178 * This probably comes at a cost of lower maximum throughput but
179 * improves the avarage and stability. */ 179 * improves the average and stability. */
180 spin_lock_bh(&htt->rx_ring.lock); 180 spin_lock_bh(&htt->rx_ring.lock);
181 num_deficit = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt; 181 num_deficit = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt;
182 num_to_fill = min(ATH10K_HTT_MAX_NUM_REFILL, num_deficit); 182 num_to_fill = min(ATH10K_HTT_MAX_NUM_REFILL, num_deficit);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 6c364bb98924..5d2db069d46e 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -611,7 +611,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
611 611
612 ret = ath10k_vdev_setup_sync(ar); 612 ret = ath10k_vdev_setup_sync(ar);
613 if (ret) { 613 if (ret) {
614 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i: %d\n", 614 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
615 vdev_id, ret); 615 vdev_id, ret);
616 return ret; 616 return ret;
617 } 617 }
@@ -658,7 +658,7 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar)
658 658
659 ret = ath10k_vdev_setup_sync(ar); 659 ret = ath10k_vdev_setup_sync(ar);
660 if (ret) 660 if (ret)
661 ath10k_warn(ar, "failed to synchronise monitor vdev %i: %d\n", 661 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
662 ar->monitor_vdev_id, ret); 662 ar->monitor_vdev_id, ret);
663 663
664 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n", 664 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
@@ -927,8 +927,9 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart)
927 927
928 ret = ath10k_vdev_setup_sync(ar); 928 ret = ath10k_vdev_setup_sync(ar);
929 if (ret) { 929 if (ret) {
930 ath10k_warn(ar, "failed to synchronise setup for vdev %i: %d\n", 930 ath10k_warn(ar,
931 arg.vdev_id, ret); 931 "failed to synchronize setup for vdev %i restart %d: %d\n",
932 arg.vdev_id, restart, ret);
932 return ret; 933 return ret;
933 } 934 }
934 935
@@ -966,7 +967,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
966 967
967 ret = ath10k_vdev_setup_sync(ar); 968 ret = ath10k_vdev_setup_sync(ar);
968 if (ret) { 969 if (ret) {
969 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n", 970 ath10k_warn(ar, "failed to synchronize setup for vdev %i stop: %d\n",
970 arvif->vdev_id, ret); 971 arvif->vdev_id, ret);
971 return ret; 972 return ret;
972 } 973 }
@@ -1253,6 +1254,20 @@ static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1253 return 0; 1254 return 0;
1254} 1255}
1255 1256
1257static int ath10k_mac_ps_vif_count(struct ath10k *ar)
1258{
1259 struct ath10k_vif *arvif;
1260 int num = 0;
1261
1262 lockdep_assert_held(&ar->conf_mutex);
1263
1264 list_for_each_entry(arvif, &ar->arvifs, list)
1265 if (arvif->ps)
1266 num++;
1267
1268 return num;
1269}
1270
1256static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) 1271static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
1257{ 1272{
1258 struct ath10k *ar = arvif->ar; 1273 struct ath10k *ar = arvif->ar;
@@ -1262,13 +1277,24 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
1262 enum wmi_sta_ps_mode psmode; 1277 enum wmi_sta_ps_mode psmode;
1263 int ret; 1278 int ret;
1264 int ps_timeout; 1279 int ps_timeout;
1280 bool enable_ps;
1265 1281
1266 lockdep_assert_held(&arvif->ar->conf_mutex); 1282 lockdep_assert_held(&arvif->ar->conf_mutex);
1267 1283
1268 if (arvif->vif->type != NL80211_IFTYPE_STATION) 1284 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1269 return 0; 1285 return 0;
1270 1286
1271 if (vif->bss_conf.ps) { 1287 enable_ps = arvif->ps;
1288
1289 if (enable_ps && ath10k_mac_ps_vif_count(ar) > 1 &&
1290 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
1291 ar->fw_features)) {
1292 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1293 arvif->vdev_id);
1294 enable_ps = false;
1295 }
1296
1297 if (enable_ps) {
1272 psmode = WMI_STA_PS_MODE_ENABLED; 1298 psmode = WMI_STA_PS_MODE_ENABLED;
1273 param = WMI_STA_PS_PARAM_INACTIVITY_TIME; 1299 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1274 1300
@@ -1781,6 +1807,68 @@ static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
1781 ath10k_smps_map[smps]); 1807 ath10k_smps_map[smps]);
1782} 1808}
1783 1809
1810static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
1811 struct ieee80211_vif *vif,
1812 struct ieee80211_sta_vht_cap vht_cap)
1813{
1814 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1815 int ret;
1816 u32 param;
1817 u32 value;
1818
1819 if (!(ar->vht_cap_info &
1820 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
1821 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
1822 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
1823 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
1824 return 0;
1825
1826 param = ar->wmi.vdev_param->txbf;
1827 value = 0;
1828
1829 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
1830 return 0;
1831
1832 /* The following logic is correct. If a remote STA advertises support
1833 * for being a beamformer then we should enable us being a beamformee.
1834 */
1835
1836 if (ar->vht_cap_info &
1837 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
1838 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
1839 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
1840 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
1841
1842 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
1843 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
1844 }
1845
1846 if (ar->vht_cap_info &
1847 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
1848 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
1849 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
1850 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
1851
1852 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
1853 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
1854 }
1855
1856 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
1857 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
1858
1859 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
1860 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
1861
1862 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
1863 if (ret) {
1864 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
1865 value, ret);
1866 return ret;
1867 }
1868
1869 return 0;
1870}
1871
1784/* can be called only in mac80211 callbacks due to `key_count` usage */ 1872/* can be called only in mac80211 callbacks due to `key_count` usage */
1785static void ath10k_bss_assoc(struct ieee80211_hw *hw, 1873static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1786 struct ieee80211_vif *vif, 1874 struct ieee80211_vif *vif,
@@ -1789,6 +1877,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1789 struct ath10k *ar = hw->priv; 1877 struct ath10k *ar = hw->priv;
1790 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 1878 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1791 struct ieee80211_sta_ht_cap ht_cap; 1879 struct ieee80211_sta_ht_cap ht_cap;
1880 struct ieee80211_sta_vht_cap vht_cap;
1792 struct wmi_peer_assoc_complete_arg peer_arg; 1881 struct wmi_peer_assoc_complete_arg peer_arg;
1793 struct ieee80211_sta *ap_sta; 1882 struct ieee80211_sta *ap_sta;
1794 int ret; 1883 int ret;
@@ -1811,6 +1900,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1811 /* ap_sta must be accessed only within rcu section which must be left 1900 /* ap_sta must be accessed only within rcu section which must be left
1812 * before calling ath10k_setup_peer_smps() which might sleep. */ 1901 * before calling ath10k_setup_peer_smps() which might sleep. */
1813 ht_cap = ap_sta->ht_cap; 1902 ht_cap = ap_sta->ht_cap;
1903 vht_cap = ap_sta->vht_cap;
1814 1904
1815 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg); 1905 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
1816 if (ret) { 1906 if (ret) {
@@ -1836,6 +1926,13 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1836 return; 1926 return;
1837 } 1927 }
1838 1928
1929 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
1930 if (ret) {
1931 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
1932 arvif->vdev_id, bss_conf->bssid, ret);
1933 return;
1934 }
1935
1839 ath10k_dbg(ar, ATH10K_DBG_MAC, 1936 ath10k_dbg(ar, ATH10K_DBG_MAC,
1840 "mac vdev %d up (associated) bssid %pM aid %d\n", 1937 "mac vdev %d up (associated) bssid %pM aid %d\n",
1841 arvif->vdev_id, bss_conf->bssid, bss_conf->aid); 1938 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
@@ -1853,6 +1950,18 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1853 } 1950 }
1854 1951
1855 arvif->is_up = true; 1952 arvif->is_up = true;
1953
1954 /* Workaround: Some firmware revisions (tested with qca6174
1955 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
1956 * poked with peer param command.
1957 */
1958 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
1959 WMI_PEER_DUMMY_VAR, 1);
1960 if (ret) {
1961 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
1962 arvif->bssid, arvif->vdev_id, ret);
1963 return;
1964 }
1856} 1965}
1857 1966
1858static void ath10k_bss_disassoc(struct ieee80211_hw *hw, 1967static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
@@ -1860,6 +1969,7 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
1860{ 1969{
1861 struct ath10k *ar = hw->priv; 1970 struct ath10k *ar = hw->priv;
1862 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 1971 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1972 struct ieee80211_sta_vht_cap vht_cap = {};
1863 int ret; 1973 int ret;
1864 1974
1865 lockdep_assert_held(&ar->conf_mutex); 1975 lockdep_assert_held(&ar->conf_mutex);
@@ -1874,6 +1984,13 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
1874 1984
1875 arvif->def_wep_key_idx = -1; 1985 arvif->def_wep_key_idx = -1;
1876 1986
1987 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
1988 if (ret) {
1989 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
1990 arvif->vdev_id, ret);
1991 return;
1992 }
1993
1877 arvif->is_up = false; 1994 arvif->is_up = false;
1878} 1995}
1879 1996
@@ -2554,6 +2671,17 @@ static int ath10k_start_scan(struct ath10k *ar,
2554 return -ETIMEDOUT; 2671 return -ETIMEDOUT;
2555 } 2672 }
2556 2673
2674 /* If we failed to start the scan, return error code at
2675 * this point. This is probably due to some issue in the
2676 * firmware, but no need to wedge the driver due to that...
2677 */
2678 spin_lock_bh(&ar->data_lock);
2679 if (ar->scan.state == ATH10K_SCAN_IDLE) {
2680 spin_unlock_bh(&ar->data_lock);
2681 return -EINVAL;
2682 }
2683 spin_unlock_bh(&ar->data_lock);
2684
2557 /* Add a 200ms margin to account for event/command processing */ 2685 /* Add a 200ms margin to account for event/command processing */
2558 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout, 2686 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
2559 msecs_to_jiffies(arg->max_scan_time+200)); 2687 msecs_to_jiffies(arg->max_scan_time+200));
@@ -3323,9 +3451,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
3323 list_del(&arvif->list); 3451 list_del(&arvif->list);
3324 3452
3325 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { 3453 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
3326 ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr); 3454 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
3455 vif->addr);
3327 if (ret) 3456 if (ret)
3328 ath10k_warn(ar, "failed to remove peer for AP vdev %i: %d\n", 3457 ath10k_warn(ar, "failed to submit AP self-peer removal on vdev %i: %d\n",
3329 arvif->vdev_id, ret); 3458 arvif->vdev_id, ret);
3330 3459
3331 kfree(arvif->u.ap.noa_data); 3460 kfree(arvif->u.ap.noa_data);
@@ -3339,6 +3468,21 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
3339 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n", 3468 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
3340 arvif->vdev_id, ret); 3469 arvif->vdev_id, ret);
3341 3470
3471 /* Some firmware revisions don't notify host about self-peer removal
3472 * until after associated vdev is deleted.
3473 */
3474 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
3475 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
3476 vif->addr);
3477 if (ret)
3478 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
3479 arvif->vdev_id, ret);
3480
3481 spin_lock_bh(&ar->data_lock);
3482 ar->num_peers--;
3483 spin_unlock_bh(&ar->data_lock);
3484 }
3485
3342 ath10k_peer_cleanup(ar, arvif->vdev_id); 3486 ath10k_peer_cleanup(ar, arvif->vdev_id);
3343 3487
3344 mutex_unlock(&ar->conf_mutex); 3488 mutex_unlock(&ar->conf_mutex);
@@ -3534,7 +3678,9 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
3534 } 3678 }
3535 3679
3536 if (changed & BSS_CHANGED_PS) { 3680 if (changed & BSS_CHANGED_PS) {
3537 ret = ath10k_mac_vif_setup_ps(arvif); 3681 arvif->ps = vif->bss_conf.ps;
3682
3683 ret = ath10k_config_ps(ar);
3538 if (ret) 3684 if (ret)
3539 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n", 3685 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
3540 arvif->vdev_id, ret); 3686 arvif->vdev_id, ret);
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index e6972b09333e..7681237fe298 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -104,7 +104,7 @@ static const struct ce_attr host_ce_config_wlan[] = {
104 { 104 {
105 .flags = CE_ATTR_FLAGS, 105 .flags = CE_ATTR_FLAGS,
106 .src_nentries = 0, 106 .src_nentries = 0,
107 .src_sz_max = 512, 107 .src_sz_max = 2048,
108 .dest_nentries = 512, 108 .dest_nentries = 512,
109 }, 109 },
110 110
@@ -174,7 +174,7 @@ static const struct ce_pipe_config target_ce_config_wlan[] = {
174 .pipenum = __cpu_to_le32(1), 174 .pipenum = __cpu_to_le32(1),
175 .pipedir = __cpu_to_le32(PIPEDIR_IN), 175 .pipedir = __cpu_to_le32(PIPEDIR_IN),
176 .nentries = __cpu_to_le32(32), 176 .nentries = __cpu_to_le32(32),
177 .nbytes_max = __cpu_to_le32(512), 177 .nbytes_max = __cpu_to_le32(2048),
178 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 178 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
179 .reserved = __cpu_to_le32(0), 179 .reserved = __cpu_to_le32(0),
180 }, 180 },
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 04dc4b9db04e..c8b64e7a6089 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -110,8 +110,7 @@ struct wmi_ops {
110 bool deliver_cab); 110 bool deliver_cab);
111 struct sk_buff *(*gen_pdev_set_wmm)(struct ath10k *ar, 111 struct sk_buff *(*gen_pdev_set_wmm)(struct ath10k *ar,
112 const struct wmi_wmm_params_all_arg *arg); 112 const struct wmi_wmm_params_all_arg *arg);
113 struct sk_buff *(*gen_request_stats)(struct ath10k *ar, 113 struct sk_buff *(*gen_request_stats)(struct ath10k *ar, u32 stats_mask);
114 enum wmi_stats_id stats_id);
115 struct sk_buff *(*gen_force_fw_hang)(struct ath10k *ar, 114 struct sk_buff *(*gen_force_fw_hang)(struct ath10k *ar,
116 enum wmi_force_fw_hang_type type, 115 enum wmi_force_fw_hang_type type,
117 u32 delay_ms); 116 u32 delay_ms);
@@ -816,14 +815,14 @@ ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
816} 815}
817 816
818static inline int 817static inline int
819ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) 818ath10k_wmi_request_stats(struct ath10k *ar, u32 stats_mask)
820{ 819{
821 struct sk_buff *skb; 820 struct sk_buff *skb;
822 821
823 if (!ar->wmi.ops->gen_request_stats) 822 if (!ar->wmi.ops->gen_request_stats)
824 return -EOPNOTSUPP; 823 return -EOPNOTSUPP;
825 824
826 skb = ar->wmi.ops->gen_request_stats(ar, stats_id); 825 skb = ar->wmi.ops->gen_request_stats(ar, stats_mask);
827 if (IS_ERR(skb)) 826 if (IS_ERR(skb))
828 return PTR_ERR(skb); 827 return PTR_ERR(skb);
829 828
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 71614ba1b145..ee0c5f602e29 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -869,16 +869,57 @@ static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
869 return 0; 869 return 0;
870} 870}
871 871
872static void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src,
873 struct ath10k_fw_stats_vdev *dst)
874{
875 int i;
876
877 dst->vdev_id = __le32_to_cpu(src->vdev_id);
878 dst->beacon_snr = __le32_to_cpu(src->beacon_snr);
879 dst->data_snr = __le32_to_cpu(src->data_snr);
880 dst->num_rx_frames = __le32_to_cpu(src->num_rx_frames);
881 dst->num_rts_fail = __le32_to_cpu(src->num_rts_fail);
882 dst->num_rts_success = __le32_to_cpu(src->num_rts_success);
883 dst->num_rx_err = __le32_to_cpu(src->num_rx_err);
884 dst->num_rx_discard = __le32_to_cpu(src->num_rx_discard);
885 dst->num_tx_not_acked = __le32_to_cpu(src->num_tx_not_acked);
886
887 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++)
888 dst->num_tx_frames[i] =
889 __le32_to_cpu(src->num_tx_frames[i]);
890
891 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++)
892 dst->num_tx_frames_retries[i] =
893 __le32_to_cpu(src->num_tx_frames_retries[i]);
894
895 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++)
896 dst->num_tx_frames_failures[i] =
897 __le32_to_cpu(src->num_tx_frames_failures[i]);
898
899 for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++)
900 dst->tx_rate_history[i] =
901 __le32_to_cpu(src->tx_rate_history[i]);
902
903 for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++)
904 dst->beacon_rssi_history[i] =
905 __le32_to_cpu(src->beacon_rssi_history[i]);
906}
907
872static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, 908static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
873 struct sk_buff *skb, 909 struct sk_buff *skb,
874 struct ath10k_fw_stats *stats) 910 struct ath10k_fw_stats *stats)
875{ 911{
876 const void **tb; 912 const void **tb;
877 const struct wmi_stats_event *ev; 913 const struct wmi_tlv_stats_ev *ev;
878 const void *data; 914 const void *data;
879 u32 num_pdev_stats, num_vdev_stats, num_peer_stats; 915 u32 num_pdev_stats;
916 u32 num_vdev_stats;
917 u32 num_peer_stats;
918 u32 num_bcnflt_stats;
919 u32 num_chan_stats;
880 size_t data_len; 920 size_t data_len;
881 int ret; 921 int ret;
922 int i;
882 923
883 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 924 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
884 if (IS_ERR(tb)) { 925 if (IS_ERR(tb)) {
@@ -899,8 +940,73 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
899 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); 940 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
900 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); 941 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
901 num_peer_stats = __le32_to_cpu(ev->num_peer_stats); 942 num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
943 num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats);
944 num_chan_stats = __le32_to_cpu(ev->num_chan_stats);
945
946 ath10k_dbg(ar, ATH10K_DBG_WMI,
947 "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i\n",
948 num_pdev_stats, num_vdev_stats, num_peer_stats,
949 num_bcnflt_stats, num_chan_stats);
950
951 for (i = 0; i < num_pdev_stats; i++) {
952 const struct wmi_pdev_stats *src;
953 struct ath10k_fw_stats_pdev *dst;
954
955 src = data;
956 if (data_len < sizeof(*src))
957 return -EPROTO;
958
959 data += sizeof(*src);
960 data_len -= sizeof(*src);
961
962 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
963 if (!dst)
964 continue;
965
966 ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
967 ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
968 ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
969 list_add_tail(&dst->list, &stats->pdevs);
970 }
971
972 for (i = 0; i < num_vdev_stats; i++) {
973 const struct wmi_tlv_vdev_stats *src;
974 struct ath10k_fw_stats_vdev *dst;
975
976 src = data;
977 if (data_len < sizeof(*src))
978 return -EPROTO;
979
980 data += sizeof(*src);
981 data_len -= sizeof(*src);
982
983 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
984 if (!dst)
985 continue;
902 986
903 WARN_ON(1); /* FIXME: not implemented yet */ 987 ath10k_wmi_tlv_pull_vdev_stats(src, dst);
988 list_add_tail(&dst->list, &stats->vdevs);
989 }
990
991 for (i = 0; i < num_peer_stats; i++) {
992 const struct wmi_10x_peer_stats *src;
993 struct ath10k_fw_stats_peer *dst;
994
995 src = data;
996 if (data_len < sizeof(*src))
997 return -EPROTO;
998
999 data += sizeof(*src);
1000 data_len -= sizeof(*src);
1001
1002 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
1003 if (!dst)
1004 continue;
1005
1006 ath10k_wmi_pull_peer_stats(&src->old, dst);
1007 dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
1008 list_add_tail(&dst->list, &stats->peers);
1009 }
904 1010
905 kfree(tb); 1011 kfree(tb);
906 return 0; 1012 return 0;
@@ -1604,14 +1710,12 @@ ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
1604 const struct wmi_wmm_params_all_arg *arg) 1710 const struct wmi_wmm_params_all_arg *arg)
1605{ 1711{
1606 struct wmi_tlv_vdev_set_wmm_cmd *cmd; 1712 struct wmi_tlv_vdev_set_wmm_cmd *cmd;
1607 struct wmi_wmm_params *wmm;
1608 struct wmi_tlv *tlv; 1713 struct wmi_tlv *tlv;
1609 struct sk_buff *skb; 1714 struct sk_buff *skb;
1610 size_t len; 1715 size_t len;
1611 void *ptr; 1716 void *ptr;
1612 1717
1613 len = (sizeof(*tlv) + sizeof(*cmd)) + 1718 len = sizeof(*tlv) + sizeof(*cmd);
1614 (4 * (sizeof(*tlv) + sizeof(*wmm)));
1615 skb = ath10k_wmi_alloc_skb(ar, len); 1719 skb = ath10k_wmi_alloc_skb(ar, len);
1616 if (!skb) 1720 if (!skb)
1617 return ERR_PTR(-ENOMEM); 1721 return ERR_PTR(-ENOMEM);
@@ -1623,13 +1727,10 @@ ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
1623 cmd = (void *)tlv->value; 1727 cmd = (void *)tlv->value;
1624 cmd->vdev_id = __cpu_to_le32(vdev_id); 1728 cmd->vdev_id = __cpu_to_le32(vdev_id);
1625 1729
1626 ptr += sizeof(*tlv); 1730 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[0].params, &arg->ac_be);
1627 ptr += sizeof(*cmd); 1731 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[1].params, &arg->ac_bk);
1628 1732 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[2].params, &arg->ac_vi);
1629 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be); 1733 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[3].params, &arg->ac_vo);
1630 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk);
1631 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi);
1632 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo);
1633 1734
1634 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n"); 1735 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n");
1635 return skb; 1736 return skb;
@@ -2080,8 +2181,7 @@ ath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar,
2080} 2181}
2081 2182
2082static struct sk_buff * 2183static struct sk_buff *
2083ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, 2184ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
2084 enum wmi_stats_id stats_id)
2085{ 2185{
2086 struct wmi_request_stats_cmd *cmd; 2186 struct wmi_request_stats_cmd *cmd;
2087 struct wmi_tlv *tlv; 2187 struct wmi_tlv *tlv;
@@ -2095,7 +2195,7 @@ ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar,
2095 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD); 2195 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD);
2096 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2196 tlv->len = __cpu_to_le16(sizeof(*cmd));
2097 cmd = (void *)tlv->value; 2197 cmd = (void *)tlv->value;
2098 cmd->stats_id = __cpu_to_le32(stats_id); 2198 cmd->stats_id = __cpu_to_le32(stats_mask);
2099 2199
2100 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n"); 2200 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n");
2101 return skb; 2201 return skb;
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index de68fe76eae6..a6c8280cc4b1 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1302,8 +1302,14 @@ struct wmi_tlv_pdev_set_wmm_cmd {
1302 __le32 dg_type; /* no idea.. */ 1302 __le32 dg_type; /* no idea.. */
1303} __packed; 1303} __packed;
1304 1304
1305struct wmi_tlv_vdev_wmm_params {
1306 __le32 dummy;
1307 struct wmi_wmm_params params;
1308} __packed;
1309
1305struct wmi_tlv_vdev_set_wmm_cmd { 1310struct wmi_tlv_vdev_set_wmm_cmd {
1306 __le32 vdev_id; 1311 __le32 vdev_id;
1312 struct wmi_tlv_vdev_wmm_params vdev_wmm_params[4];
1307} __packed; 1313} __packed;
1308 1314
1309struct wmi_tlv_phyerr_ev { 1315struct wmi_tlv_phyerr_ev {
@@ -1439,6 +1445,15 @@ struct wmi_tlv_sta_keepalive_cmd {
1439 __le32 interval; /* in seconds */ 1445 __le32 interval; /* in seconds */
1440} __packed; 1446} __packed;
1441 1447
1448struct wmi_tlv_stats_ev {
1449 __le32 stats_id; /* WMI_STAT_ */
1450 __le32 num_pdev_stats;
1451 __le32 num_vdev_stats;
1452 __le32 num_peer_stats;
1453 __le32 num_bcnflt_stats;
1454 __le32 num_chan_stats;
1455} __packed;
1456
1442void ath10k_wmi_tlv_attach(struct ath10k *ar); 1457void ath10k_wmi_tlv_attach(struct ath10k *ar);
1443 1458
1444#endif 1459#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index aeea1c793943..c7ea77edce24 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1125,6 +1125,25 @@ static void ath10k_wmi_event_scan_started(struct ath10k *ar)
1125 } 1125 }
1126} 1126}
1127 1127
1128static void ath10k_wmi_event_scan_start_failed(struct ath10k *ar)
1129{
1130 lockdep_assert_held(&ar->data_lock);
1131
1132 switch (ar->scan.state) {
1133 case ATH10K_SCAN_IDLE:
1134 case ATH10K_SCAN_RUNNING:
1135 case ATH10K_SCAN_ABORTING:
1136 ath10k_warn(ar, "received scan start failed event in an invalid scan state: %s (%d)\n",
1137 ath10k_scan_state_str(ar->scan.state),
1138 ar->scan.state);
1139 break;
1140 case ATH10K_SCAN_STARTING:
1141 complete(&ar->scan.started);
1142 __ath10k_scan_finish(ar);
1143 break;
1144 }
1145}
1146
1128static void ath10k_wmi_event_scan_completed(struct ath10k *ar) 1147static void ath10k_wmi_event_scan_completed(struct ath10k *ar)
1129{ 1148{
1130 lockdep_assert_held(&ar->data_lock); 1149 lockdep_assert_held(&ar->data_lock);
@@ -1292,6 +1311,7 @@ int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb)
1292 break; 1311 break;
1293 case WMI_SCAN_EVENT_START_FAILED: 1312 case WMI_SCAN_EVENT_START_FAILED:
1294 ath10k_warn(ar, "received scan start failure event\n"); 1313 ath10k_warn(ar, "received scan start failure event\n");
1314 ath10k_wmi_event_scan_start_failed(ar);
1295 break; 1315 break;
1296 case WMI_SCAN_EVENT_DEQUEUED: 1316 case WMI_SCAN_EVENT_DEQUEUED:
1297 case WMI_SCAN_EVENT_PREEMPTED: 1317 case WMI_SCAN_EVENT_PREEMPTED:
@@ -4954,7 +4974,7 @@ ath10k_wmi_op_gen_pdev_set_wmm(struct ath10k *ar,
4954} 4974}
4955 4975
4956static struct sk_buff * 4976static struct sk_buff *
4957ath10k_wmi_op_gen_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) 4977ath10k_wmi_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
4958{ 4978{
4959 struct wmi_request_stats_cmd *cmd; 4979 struct wmi_request_stats_cmd *cmd;
4960 struct sk_buff *skb; 4980 struct sk_buff *skb;
@@ -4964,9 +4984,10 @@ ath10k_wmi_op_gen_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id)
4964 return ERR_PTR(-ENOMEM); 4984 return ERR_PTR(-ENOMEM);
4965 4985
4966 cmd = (struct wmi_request_stats_cmd *)skb->data; 4986 cmd = (struct wmi_request_stats_cmd *)skb->data;
4967 cmd->stats_id = __cpu_to_le32(stats_id); 4987 cmd->stats_id = __cpu_to_le32(stats_mask);
4968 4988
4969 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); 4989 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats 0x%08x\n",
4990 stats_mask);
4970 return skb; 4991 return skb;
4971} 4992}
4972 4993
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 20ce3603e64b..adf935bf0580 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -3057,8 +3057,12 @@ struct wmi_pdev_stats_peer {
3057} __packed; 3057} __packed;
3058 3058
3059enum wmi_stats_id { 3059enum wmi_stats_id {
3060 WMI_REQUEST_PEER_STAT = 0x01, 3060 WMI_STAT_PEER = BIT(0),
3061 WMI_REQUEST_AP_STAT = 0x02 3061 WMI_STAT_AP = BIT(1),
3062 WMI_STAT_PDEV = BIT(2),
3063 WMI_STAT_VDEV = BIT(3),
3064 WMI_STAT_BCNFLT = BIT(4),
3065 WMI_STAT_VDEV_RATE = BIT(5),
3062}; 3066};
3063 3067
3064struct wlan_inst_rssi_args { 3068struct wlan_inst_rssi_args {
@@ -3093,7 +3097,7 @@ struct wmi_pdev_suspend_cmd {
3093} __packed; 3097} __packed;
3094 3098
3095struct wmi_stats_event { 3099struct wmi_stats_event {
3096 __le32 stats_id; /* %WMI_REQUEST_ */ 3100 __le32 stats_id; /* WMI_STAT_ */
3097 /* 3101 /*
3098 * number of pdev stats event structures 3102 * number of pdev stats event structures
3099 * (wmi_pdev_stats) 0 or 1 3103 * (wmi_pdev_stats) 0 or 1
@@ -3745,6 +3749,11 @@ enum wmi_10x_vdev_param {
3745 WMI_10X_VDEV_PARAM_VHT80_RATEMASK, 3749 WMI_10X_VDEV_PARAM_VHT80_RATEMASK,
3746}; 3750};
3747 3751
3752#define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0)
3753#define WMI_VDEV_PARAM_TXBF_MU_TX_BFEE BIT(1)
3754#define WMI_VDEV_PARAM_TXBF_SU_TX_BFER BIT(2)
3755#define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3)
3756
3748/* slot time long */ 3757/* slot time long */
3749#define WMI_VDEV_SLOT_TIME_LONG 0x1 3758#define WMI_VDEV_SLOT_TIME_LONG 0x1
3750/* slot time short */ 3759/* slot time short */
@@ -4436,7 +4445,8 @@ enum wmi_peer_param {
4436 WMI_PEER_AUTHORIZE = 0x3, 4445 WMI_PEER_AUTHORIZE = 0x3,
4437 WMI_PEER_CHAN_WIDTH = 0x4, 4446 WMI_PEER_CHAN_WIDTH = 0x4,
4438 WMI_PEER_NSS = 0x5, 4447 WMI_PEER_NSS = 0x5,
4439 WMI_PEER_USE_4ADDR = 0x6 4448 WMI_PEER_USE_4ADDR = 0x6,
4449 WMI_PEER_DUMMY_VAR = 0xff, /* dummy parameter for STA PS workaround */
4440}; 4450};
4441 4451
4442struct wmi_peer_set_param_cmd { 4452struct wmi_peer_set_param_cmd {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index 7b94a6c7db3d..bd169fae32a1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
@@ -284,12 +284,12 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah)
284 AR_MCI_INTERRUPT_RX_MSG_CONT_RST); 284 AR_MCI_INTERRUPT_RX_MSG_CONT_RST);
285 REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI); 285 REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI);
286 286
287 if (mci->is_2g) { 287 if (mci->is_2g && MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
288 ar9003_mci_send_lna_transfer(ah, true); 288 ar9003_mci_send_lna_transfer(ah, true);
289 udelay(5); 289 udelay(5);
290 } 290 }
291 291
292 if ((mci->is_2g && !mci->update_2g5g)) { 292 if (mci->is_2g && !mci->update_2g5g && MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
293 if (ar9003_mci_wait_for_interrupt(ah, 293 if (ar9003_mci_wait_for_interrupt(ah,
294 AR_MCI_INTERRUPT_RX_MSG_RAW, 294 AR_MCI_INTERRUPT_RX_MSG_RAW,
295 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, 295 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO,
@@ -593,7 +593,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
593 if (!time_out) 593 if (!time_out)
594 break; 594 break;
595 595
596 offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data); 596 offset = ar9003_mci_get_next_gpm_offset(ah, &more_data);
597 597
598 if (offset == MCI_GPM_INVALID) 598 if (offset == MCI_GPM_INVALID)
599 continue; 599 continue;
@@ -657,7 +657,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
657 time_out = 0; 657 time_out = 0;
658 658
659 while (more_data == MCI_GPM_MORE) { 659 while (more_data == MCI_GPM_MORE) {
660 offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data); 660 offset = ar9003_mci_get_next_gpm_offset(ah, &more_data);
661 if (offset == MCI_GPM_INVALID) 661 if (offset == MCI_GPM_INVALID)
662 break; 662 break;
663 663
@@ -771,8 +771,14 @@ exit:
771 771
772static void ar9003_mci_mute_bt(struct ath_hw *ah) 772static void ar9003_mci_mute_bt(struct ath_hw *ah)
773{ 773{
774 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
775
774 /* disable all MCI messages */ 776 /* disable all MCI messages */
775 REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000); 777 REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000);
778 REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff);
779 REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff);
780 REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff);
781 REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff);
776 REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 782 REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
777 783
778 /* wait pending HW messages to flush out */ 784 /* wait pending HW messages to flush out */
@@ -783,9 +789,10 @@ static void ar9003_mci_mute_bt(struct ath_hw *ah)
783 * 1. reset not after resuming from full sleep 789 * 1. reset not after resuming from full sleep
784 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment 790 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
785 */ 791 */
786 ar9003_mci_send_lna_take(ah, true); 792 if (MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
787 793 ar9003_mci_send_lna_take(ah, true);
788 udelay(5); 794 udelay(5);
795 }
789 796
790 ar9003_mci_send_sys_sleeping(ah, true); 797 ar9003_mci_send_sys_sleeping(ah, true);
791} 798}
@@ -821,6 +828,80 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable)
821 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); 828 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);
822} 829}
823 830
831static void ar9003_mci_stat_setup(struct ath_hw *ah)
832{
833 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
834
835 if (!AR_SREV_9565(ah))
836 return;
837
838 if (mci->config & ATH_MCI_CONFIG_MCI_STAT_DBG) {
839 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
840 AR_MCI_DBG_CNT_CTRL_ENABLE, 1);
841 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
842 AR_MCI_DBG_CNT_CTRL_BT_LINKID,
843 MCI_STAT_ALL_BT_LINKID);
844 } else {
845 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
846 AR_MCI_DBG_CNT_CTRL_ENABLE, 0);
847 }
848}
849
850static void ar9003_mci_set_btcoex_ctrl_9565_1ANT(struct ath_hw *ah)
851{
852 u32 regval;
853
854 regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
855 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
856 SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
857 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
858 SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
859 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
860 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
861 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
862 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
863
864 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
865 AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x1);
866 REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
867}
868
869static void ar9003_mci_set_btcoex_ctrl_9565_2ANT(struct ath_hw *ah)
870{
871 u32 regval;
872
873 regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
874 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
875 SM(0, AR_BTCOEX_CTRL_PA_SHARED) |
876 SM(0, AR_BTCOEX_CTRL_LNA_SHARED) |
877 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
878 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
879 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
880 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
881 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
882
883 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
884 AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x0);
885 REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
886}
887
888static void ar9003_mci_set_btcoex_ctrl_9462(struct ath_hw *ah)
889{
890 u32 regval;
891
892 regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
893 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
894 SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
895 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
896 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
897 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
898 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
899 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
900 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
901
902 REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
903}
904
824int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, 905int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
825 bool is_full_sleep) 906 bool is_full_sleep)
826{ 907{
@@ -831,11 +912,6 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
831 ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n", 912 ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n",
832 is_full_sleep, is_2g); 913 is_full_sleep, is_2g);
833 914
834 if (!mci->gpm_addr && !mci->sched_addr) {
835 ath_err(common, "MCI GPM and schedule buffers are not allocated\n");
836 return -ENOMEM;
837 }
838
839 if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { 915 if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
840 ath_err(common, "BTCOEX control register is dead\n"); 916 ath_err(common, "BTCOEX control register is dead\n");
841 return -EINVAL; 917 return -EINVAL;
@@ -850,26 +926,17 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
850 * To avoid MCI state machine be affected by incoming remote MCI msgs, 926 * To avoid MCI state machine be affected by incoming remote MCI msgs,
851 * MCI mode will be enabled later, right before reset the MCI TX and RX. 927 * MCI mode will be enabled later, right before reset the MCI TX and RX.
852 */ 928 */
853
854 regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
855 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
856 SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
857 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
858 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
859 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
860 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
861 if (AR_SREV_9565(ah)) { 929 if (AR_SREV_9565(ah)) {
862 regval |= SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS) | 930 u8 ant = MS(mci->config, ATH_MCI_CONFIG_ANT_ARCH);
863 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK); 931
864 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, 932 if (ant == ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED)
865 AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x1); 933 ar9003_mci_set_btcoex_ctrl_9565_1ANT(ah);
934 else
935 ar9003_mci_set_btcoex_ctrl_9565_2ANT(ah);
866 } else { 936 } else {
867 regval |= SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) | 937 ar9003_mci_set_btcoex_ctrl_9462(ah);
868 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK);
869 } 938 }
870 939
871 REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
872
873 if (is_2g && !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) 940 if (is_2g && !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA))
874 ar9003_mci_osla_setup(ah, true); 941 ar9003_mci_osla_setup(ah, true);
875 else 942 else
@@ -926,23 +993,26 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
926 regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX); 993 regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
927 REG_WRITE(ah, AR_MCI_COMMAND2, regval); 994 REG_WRITE(ah, AR_MCI_COMMAND2, regval);
928 995
929 ar9003_mci_get_next_gpm_offset(ah, true, NULL); 996 /* Init GPM offset after MCI Reset Rx */
997 ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET);
930 998
931 REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 999 REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
932 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) | 1000 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
933 SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM))); 1001 SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM)));
934 1002
935 REG_CLR_BIT(ah, AR_MCI_TX_CTRL, 1003 if (MCI_ANT_ARCH_PA_LNA_SHARED(mci))
936 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 1004 REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
1005 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
1006 else
1007 REG_SET_BIT(ah, AR_MCI_TX_CTRL,
1008 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
937 1009
938 ar9003_mci_observation_set_up(ah); 1010 ar9003_mci_observation_set_up(ah);
939 1011
940 mci->ready = true; 1012 mci->ready = true;
941 ar9003_mci_prep_interface(ah); 1013 ar9003_mci_prep_interface(ah);
1014 ar9003_mci_stat_setup(ah);
942 1015
943 if (AR_SREV_9565(ah))
944 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
945 AR_MCI_DBG_CNT_CTRL_ENABLE, 0);
946 if (en_int) 1016 if (en_int)
947 ar9003_mci_enable_interrupt(ah); 1017 ar9003_mci_enable_interrupt(ah);
948 1018
@@ -1218,6 +1288,14 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type)
1218 } 1288 }
1219 value &= AR_BTCOEX_CTRL_MCI_MODE_EN; 1289 value &= AR_BTCOEX_CTRL_MCI_MODE_EN;
1220 break; 1290 break;
1291 case MCI_STATE_INIT_GPM_OFFSET:
1292 value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1293
1294 if (value < mci->gpm_len)
1295 mci->gpm_idx = value;
1296 else
1297 mci->gpm_idx = 0;
1298 break;
1221 case MCI_STATE_LAST_SCHD_MSG_OFFSET: 1299 case MCI_STATE_LAST_SCHD_MSG_OFFSET:
1222 value = MS(REG_READ(ah, AR_MCI_RX_STATUS), 1300 value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
1223 AR_MCI_RX_LAST_SCHD_MSG_INDEX); 1301 AR_MCI_RX_LAST_SCHD_MSG_INDEX);
@@ -1364,21 +1442,11 @@ void ar9003_mci_check_gpm_offset(struct ath_hw *ah)
1364 mci->gpm_idx = 0; 1442 mci->gpm_idx = 0;
1365} 1443}
1366 1444
1367u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more) 1445u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, u32 *more)
1368{ 1446{
1369 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; 1447 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1370 u32 offset, more_gpm = 0, gpm_ptr; 1448 u32 offset, more_gpm = 0, gpm_ptr;
1371 1449
1372 if (first) {
1373 gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1374
1375 if (gpm_ptr >= mci->gpm_len)
1376 gpm_ptr = 0;
1377
1378 mci->gpm_idx = gpm_ptr;
1379 return gpm_ptr;
1380 }
1381
1382 /* 1450 /*
1383 * This could be useful to avoid new GPM message interrupt which 1451 * This could be useful to avoid new GPM message interrupt which
1384 * may lead to spurious interrupt after power sleep, or multiple 1452 * may lead to spurious interrupt after power sleep, or multiple
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h
index 66d7ab9f920d..e288611c12d5 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h
@@ -92,14 +92,36 @@ enum mci_gpm_coex_bt_update_flags_op {
92#define ATH_MCI_CONFIG_CLK_DIV 0x00003000 92#define ATH_MCI_CONFIG_CLK_DIV 0x00003000
93#define ATH_MCI_CONFIG_CLK_DIV_S 12 93#define ATH_MCI_CONFIG_CLK_DIV_S 12
94#define ATH_MCI_CONFIG_DISABLE_TUNING 0x00004000 94#define ATH_MCI_CONFIG_DISABLE_TUNING 0x00004000
95#define ATH_MCI_CONFIG_DISABLE_AIC 0x00008000
96#define ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN 0x007f0000
97#define ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN_S 16
98#define ATH_MCI_CONFIG_NO_QUIET_ACK 0x00800000
99#define ATH_MCI_CONFIG_NO_QUIET_ACK_S 23
100#define ATH_MCI_CONFIG_ANT_ARCH 0x07000000
101#define ATH_MCI_CONFIG_ANT_ARCH_S 24
102#define ATH_MCI_CONFIG_FORCE_QUIET_ACK 0x08000000
103#define ATH_MCI_CONFIG_FORCE_QUIET_ACK_S 27
104#define ATH_MCI_CONFIG_FORCE_2CHAIN_ACK 0x10000000
105#define ATH_MCI_CONFIG_MCI_STAT_DBG 0x20000000
95#define ATH_MCI_CONFIG_MCI_WEIGHT_DBG 0x40000000 106#define ATH_MCI_CONFIG_MCI_WEIGHT_DBG 0x40000000
96#define ATH_MCI_CONFIG_DISABLE_MCI 0x80000000 107#define ATH_MCI_CONFIG_DISABLE_MCI 0x80000000
97 108
98#define ATH_MCI_CONFIG_MCI_OBS_MASK (ATH_MCI_CONFIG_MCI_OBS_MCI | \ 109#define ATH_MCI_CONFIG_MCI_OBS_MASK (ATH_MCI_CONFIG_MCI_OBS_MCI | \
99 ATH_MCI_CONFIG_MCI_OBS_TXRX | \ 110 ATH_MCI_CONFIG_MCI_OBS_TXRX | \
100 ATH_MCI_CONFIG_MCI_OBS_BT) 111 ATH_MCI_CONFIG_MCI_OBS_BT)
112
101#define ATH_MCI_CONFIG_MCI_OBS_GPIO 0x0000002F 113#define ATH_MCI_CONFIG_MCI_OBS_GPIO 0x0000002F
102 114
115#define ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_NON_SHARED 0x00
116#define ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED 0x01
117#define ATH_MCI_ANT_ARCH_2_ANT_PA_LNA_NON_SHARED 0x02
118#define ATH_MCI_ANT_ARCH_2_ANT_PA_LNA_SHARED 0x03
119#define ATH_MCI_ANT_ARCH_3_ANT 0x04
120
121#define MCI_ANT_ARCH_PA_LNA_SHARED(mci) \
122 ((MS(mci->config, ATH_MCI_CONFIG_ANT_ARCH) == ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED) || \
123 (MS(mci->config, ATH_MCI_CONFIG_ANT_ARCH) == ATH_MCI_ANT_ARCH_2_ANT_PA_LNA_SHARED))
124
103enum mci_message_header { /* length of payload */ 125enum mci_message_header { /* length of payload */
104 MCI_LNA_CTRL = 0x10, /* len = 0 */ 126 MCI_LNA_CTRL = 0x10, /* len = 0 */
105 MCI_CONT_NACK = 0x20, /* len = 0 */ 127 MCI_CONT_NACK = 0x20, /* len = 0 */
@@ -188,20 +210,55 @@ enum mci_bt_state {
188 MCI_BT_CAL 210 MCI_BT_CAL
189}; 211};
190 212
213enum mci_ps_state {
214 MCI_PS_DISABLE,
215 MCI_PS_ENABLE,
216 MCI_PS_ENABLE_OFF,
217 MCI_PS_ENABLE_ON
218};
219
191/* Type of state query */ 220/* Type of state query */
192enum mci_state_type { 221enum mci_state_type {
193 MCI_STATE_ENABLE, 222 MCI_STATE_ENABLE,
223 MCI_STATE_INIT_GPM_OFFSET,
224 MCI_STATE_CHECK_GPM_OFFSET,
225 MCI_STATE_NEXT_GPM_OFFSET,
226 MCI_STATE_LAST_GPM_OFFSET,
227 MCI_STATE_BT,
228 MCI_STATE_SET_BT_SLEEP,
194 MCI_STATE_SET_BT_AWAKE, 229 MCI_STATE_SET_BT_AWAKE,
230 MCI_STATE_SET_BT_CAL_START,
231 MCI_STATE_SET_BT_CAL,
195 MCI_STATE_LAST_SCHD_MSG_OFFSET, 232 MCI_STATE_LAST_SCHD_MSG_OFFSET,
196 MCI_STATE_REMOTE_SLEEP, 233 MCI_STATE_REMOTE_SLEEP,
234 MCI_STATE_CONT_STATUS,
197 MCI_STATE_RESET_REQ_WAKE, 235 MCI_STATE_RESET_REQ_WAKE,
198 MCI_STATE_SEND_WLAN_COEX_VERSION, 236 MCI_STATE_SEND_WLAN_COEX_VERSION,
237 MCI_STATE_SET_BT_COEX_VERSION,
238 MCI_STATE_SEND_WLAN_CHANNELS,
199 MCI_STATE_SEND_VERSION_QUERY, 239 MCI_STATE_SEND_VERSION_QUERY,
200 MCI_STATE_SEND_STATUS_QUERY, 240 MCI_STATE_SEND_STATUS_QUERY,
241 MCI_STATE_NEED_FLUSH_BT_INFO,
242 MCI_STATE_SET_CONCUR_TX_PRI,
201 MCI_STATE_RECOVER_RX, 243 MCI_STATE_RECOVER_RX,
202 MCI_STATE_NEED_FTP_STOMP, 244 MCI_STATE_NEED_FTP_STOMP,
245 MCI_STATE_NEED_TUNING,
246 MCI_STATE_NEED_STAT_DEBUG,
247 MCI_STATE_SHARED_CHAIN_CONCUR_TX,
248 MCI_STATE_AIC_CAL,
249 MCI_STATE_AIC_START,
250 MCI_STATE_AIC_CAL_RESET,
251 MCI_STATE_AIC_CAL_SINGLE,
252 MCI_STATE_IS_AR9462,
253 MCI_STATE_IS_AR9565_1ANT,
254 MCI_STATE_IS_AR9565_2ANT,
255 MCI_STATE_WLAN_WEAK_SIGNAL,
256 MCI_STATE_SET_WLAN_PS_STATE,
257 MCI_STATE_GET_WLAN_PS_STATE,
203 MCI_STATE_DEBUG, 258 MCI_STATE_DEBUG,
204 MCI_STATE_NEED_FLUSH_BT_INFO, 259 MCI_STATE_STAT_DEBUG,
260 MCI_STATE_ALLOW_FCS,
261 MCI_STATE_SET_2G_CONTENTION,
205 MCI_STATE_MAX 262 MCI_STATE_MAX
206}; 263};
207 264
@@ -255,7 +312,7 @@ int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
255void ar9003_mci_cleanup(struct ath_hw *ah); 312void ar9003_mci_cleanup(struct ath_hw *ah);
256void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, 313void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
257 u32 *rx_msg_intr); 314 u32 *rx_msg_intr);
258u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more); 315u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, u32 *more);
259void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor); 316void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor);
260void ar9003_mci_send_wlan_channels(struct ath_hw *ah); 317void ar9003_mci_send_wlan_channels(struct ath_hw *ah);
261/* 318/*
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
index 86bfc9604dca..bea41df9fbd7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_wow.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -20,11 +20,25 @@
20#include "reg_wow.h" 20#include "reg_wow.h"
21#include "hw-ops.h" 21#include "hw-ops.h"
22 22
23static void ath9k_hw_set_sta_powersave(struct ath_hw *ah)
24{
25 if (!ath9k_hw_mci_is_enabled(ah))
26 goto set;
27 /*
28 * If MCI is being used, set PWR_SAV only when MCI's
29 * PS state is disabled.
30 */
31 if (ar9003_mci_state(ah, MCI_STATE_GET_WLAN_PS_STATE) != MCI_PS_DISABLE)
32 return;
33set:
34 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
35}
36
23static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) 37static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
24{ 38{
25 struct ath_common *common = ath9k_hw_common(ah); 39 struct ath_common *common = ath9k_hw_common(ah);
26 40
27 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 41 ath9k_hw_set_sta_powersave(ah);
28 42
29 /* set rx disable bit */ 43 /* set rx disable bit */
30 REG_WRITE(ah, AR_CR, AR_CR_RXD); 44 REG_WRITE(ah, AR_CR, AR_CR_RXD);
@@ -44,6 +58,9 @@ static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
44 REG_CLR_BIT(ah, AR_DIRECT_CONNECT, AR_DC_TSF2_ENABLE); 58 REG_CLR_BIT(ah, AR_DIRECT_CONNECT, AR_DC_TSF2_ENABLE);
45 } 59 }
46 60
61 if (ath9k_hw_mci_is_enabled(ah))
62 REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
63
47 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); 64 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
48} 65}
49 66
@@ -74,8 +91,6 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
74 for (i = 0; i < KAL_NUM_DESC_WORDS; i++) 91 for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
75 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); 92 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
76 93
77 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
78
79 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) | 94 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
80 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16); 95 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
81 data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) | 96 data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
@@ -88,9 +103,11 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
88 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); 103 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
89 data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); 104 data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
90 105
91 if (AR_SREV_9462_20(ah)) { 106 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
92 /* AR9462 2.0 has an extra descriptor word (time based 107 /*
93 * discard) compared to other chips */ 108 * AR9462 2.0 and AR9565 have an extra descriptor word
109 * (time based discard) compared to other chips.
110 */
94 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0); 111 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
95 wow_ka_data_word0 = AR_WOW_TXBUF(13); 112 wow_ka_data_word0 = AR_WOW_TXBUF(13);
96 } else { 113 } else {
@@ -99,7 +116,6 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
99 116
100 for (i = 0; i < KAL_NUM_DATA_WORDS; i++) 117 for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
101 REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]); 118 REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
102
103} 119}
104 120
105int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, 121int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
@@ -170,18 +186,17 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
170 u32 val = 0, rval; 186 u32 val = 0, rval;
171 187
172 /* 188 /*
173 * read the WoW status register to know 189 * Read the WoW status register to know
174 * the wakeup reason 190 * the wakeup reason.
175 */ 191 */
176 rval = REG_READ(ah, AR_WOW_PATTERN); 192 rval = REG_READ(ah, AR_WOW_PATTERN);
177 val = AR_WOW_STATUS(rval); 193 val = AR_WOW_STATUS(rval);
178 194
179 /* 195 /*
180 * mask only the WoW events that we have enabled. Sometimes 196 * Mask only the WoW events that we have enabled. Sometimes
181 * we have spurious WoW events from the AR_WOW_PATTERN 197 * we have spurious WoW events from the AR_WOW_PATTERN
182 * register. This mask will clean it up. 198 * register. This mask will clean it up.
183 */ 199 */
184
185 val &= ah->wow.wow_event_mask; 200 val &= ah->wow.wow_event_mask;
186 201
187 if (val) { 202 if (val) {
@@ -195,6 +210,15 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
195 wow_status |= AH_WOW_BEACON_MISS; 210 wow_status |= AH_WOW_BEACON_MISS;
196 } 211 }
197 212
213 rval = REG_READ(ah, AR_MAC_PCU_WOW4);
214 val = AR_WOW_STATUS2(rval);
215 val &= ah->wow.wow_event_mask2;
216
217 if (val) {
218 if (AR_WOW2_PATTERN_FOUND(val))
219 wow_status |= AH_WOW_USER_PATTERN_EN;
220 }
221
198 /* 222 /*
199 * set and clear WOW_PME_CLEAR registers for the chip to 223 * set and clear WOW_PME_CLEAR registers for the chip to
200 * generate next wow signal. 224 * generate next wow signal.
@@ -206,10 +230,12 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
206 AR_PMCTRL_PWR_STATE_D1D3); 230 AR_PMCTRL_PWR_STATE_D1D3);
207 231
208 /* 232 /*
209 * clear all events 233 * Clear all events.
210 */ 234 */
211 REG_WRITE(ah, AR_WOW_PATTERN, 235 REG_WRITE(ah, AR_WOW_PATTERN,
212 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN))); 236 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
237 REG_WRITE(ah, AR_MAC_PCU_WOW4,
238 AR_WOW_CLEAR_EVENTS2(REG_READ(ah, AR_MAC_PCU_WOW4)));
213 239
214 /* 240 /*
215 * restore the beacon threshold to init value 241 * restore the beacon threshold to init value
@@ -226,7 +252,15 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
226 if (ah->is_pciexpress) 252 if (ah->is_pciexpress)
227 ath9k_hw_configpcipowersave(ah, false); 253 ath9k_hw_configpcipowersave(ah, false);
228 254
255 if (AR_SREV_9462(ah) || AR_SREV_9565(ah) || AR_SREV_9485(ah)) {
256 u32 dc = REG_READ(ah, AR_DIRECT_CONNECT);
257
258 if (!(dc & AR_DC_TSF2_ENABLE))
259 ath9k_hw_gen_timer_start_tsf2(ah);
260 }
261
229 ah->wow.wow_event_mask = 0; 262 ah->wow.wow_event_mask = 0;
263 ah->wow.wow_event_mask2 = 0;
230 264
231 return wow_status; 265 return wow_status;
232} 266}
@@ -408,6 +442,9 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
408 442
409 ath9k_hw_wow_set_arwr_reg(ah); 443 ath9k_hw_wow_set_arwr_reg(ah);
410 444
445 if (ath9k_hw_mci_is_enabled(ah))
446 REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
447
411 /* HW WoW */ 448 /* HW WoW */
412 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, BIT(5)); 449 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, BIT(5));
413 450
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0f8e9464e4ab..7e89236c0e13 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -645,6 +645,7 @@ void ath9k_calculate_iter_data(struct ath_softc *sc,
645 struct ath9k_vif_iter_data *iter_data); 645 struct ath9k_vif_iter_data *iter_data);
646void ath9k_calculate_summary_state(struct ath_softc *sc, 646void ath9k_calculate_summary_state(struct ath_softc *sc,
647 struct ath_chanctx *ctx); 647 struct ath_chanctx *ctx);
648void ath9k_set_txpower(struct ath_softc *sc, struct ieee80211_vif *vif);
648 649
649/*******************/ 650/*******************/
650/* Beacon Handling */ 651/* Beacon Handling */
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 3dfc2c7f1f07..5a084d94ed90 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -103,7 +103,9 @@ void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah)
103 return; 103 return;
104 } 104 }
105 105
106 if (AR_SREV_9300_20_OR_LATER(ah)) { 106 if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) {
107 btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI;
108 } else if (AR_SREV_9300_20_OR_LATER(ah)) {
107 btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; 109 btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
108 btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; 110 btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
109 btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; 111 btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
@@ -307,6 +309,18 @@ static void ath9k_hw_btcoex_enable_mci(struct ath_hw *ah)
307 btcoex->enabled = true; 309 btcoex->enabled = true;
308} 310}
309 311
312static void ath9k_hw_btcoex_disable_mci(struct ath_hw *ah)
313{
314 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
315 int i;
316
317 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
318
319 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++)
320 REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i),
321 btcoex_hw->wlan_weight[i]);
322}
323
310void ath9k_hw_btcoex_enable(struct ath_hw *ah) 324void ath9k_hw_btcoex_enable(struct ath_hw *ah)
311{ 325{
312 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 326 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
@@ -318,17 +332,18 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah)
318 ath9k_hw_btcoex_enable_2wire(ah); 332 ath9k_hw_btcoex_enable_2wire(ah);
319 break; 333 break;
320 case ATH_BTCOEX_CFG_3WIRE: 334 case ATH_BTCOEX_CFG_3WIRE:
321 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
322 ath9k_hw_btcoex_enable_mci(ah);
323 return;
324 }
325 ath9k_hw_btcoex_enable_3wire(ah); 335 ath9k_hw_btcoex_enable_3wire(ah);
326 break; 336 break;
337 case ATH_BTCOEX_CFG_MCI:
338 ath9k_hw_btcoex_enable_mci(ah);
339 break;
327 } 340 }
328 341
329 REG_RMW(ah, AR_GPIO_PDPU, 342 if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI) {
330 (0x2 << (btcoex_hw->btactive_gpio * 2)), 343 REG_RMW(ah, AR_GPIO_PDPU,
331 (0x3 << (btcoex_hw->btactive_gpio * 2))); 344 (0x2 << (btcoex_hw->btactive_gpio * 2)),
345 (0x3 << (btcoex_hw->btactive_gpio * 2)));
346 }
332 347
333 ah->btcoex_hw.enabled = true; 348 ah->btcoex_hw.enabled = true;
334} 349}
@@ -340,14 +355,14 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
340 int i; 355 int i;
341 356
342 btcoex_hw->enabled = false; 357 btcoex_hw->enabled = false;
343 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { 358
344 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); 359 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI) {
345 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) 360 ath9k_hw_btcoex_disable_mci(ah);
346 REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i),
347 btcoex_hw->wlan_weight[i]);
348 return; 361 return;
349 } 362 }
350 ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0); 363
364 if (!AR_SREV_9300_20_OR_LATER(ah))
365 ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0);
351 366
352 ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, 367 ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
353 AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 368 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 6de26ea5d5fa..5fe62ff2223b 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -58,6 +58,7 @@ enum ath_btcoex_scheme {
58 ATH_BTCOEX_CFG_NONE, 58 ATH_BTCOEX_CFG_NONE,
59 ATH_BTCOEX_CFG_2WIRE, 59 ATH_BTCOEX_CFG_2WIRE,
60 ATH_BTCOEX_CFG_3WIRE, 60 ATH_BTCOEX_CFG_3WIRE,
61 ATH_BTCOEX_CFG_MCI,
61}; 62};
62 63
63struct ath9k_hw_mci { 64struct ath9k_hw_mci {
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 50a2e0ac3b8b..dbf8f4959642 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1156,7 +1156,10 @@ static ssize_t write_file_tpc(struct file *file, const char __user *user_buf,
1156 1156
1157 if (tpc_enabled != ah->tpc_enabled) { 1157 if (tpc_enabled != ah->tpc_enabled) {
1158 ah->tpc_enabled = tpc_enabled; 1158 ah->tpc_enabled = tpc_enabled;
1159 ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false); 1159
1160 mutex_lock(&sc->mutex);
1161 ath9k_set_txpower(sc, NULL);
1162 mutex_unlock(&sc->mutex);
1160 } 1163 }
1161 1164
1162 return count; 1165 return count;
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index da344b27326c..86d46c196966 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -202,17 +202,16 @@ static void ath_btcoex_period_timer(unsigned long data)
202 } 202 }
203 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 203 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
204 204
205 ath9k_mci_update_rssi(sc);
206
207 ath9k_ps_wakeup(sc); 205 ath9k_ps_wakeup(sc);
206 spin_lock_bh(&btcoex->btcoex_lock);
208 207
209 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) 208 if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) {
210 ath_detect_bt_priority(sc); 209 ath9k_mci_update_rssi(sc);
211
212 if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI)
213 ath_mci_ftp_adjust(sc); 210 ath_mci_ftp_adjust(sc);
211 }
214 212
215 spin_lock_bh(&btcoex->btcoex_lock); 213 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
214 ath_detect_bt_priority(sc);
216 215
217 stomp_type = btcoex->bt_stomp_type; 216 stomp_type = btcoex->bt_stomp_type;
218 timer_period = btcoex->btcoex_no_stomp; 217 timer_period = btcoex->btcoex_no_stomp;
@@ -252,9 +251,6 @@ static void ath_btcoex_no_stomp_timer(unsigned long arg)
252 struct ath_softc *sc = (struct ath_softc *)arg; 251 struct ath_softc *sc = (struct ath_softc *)arg;
253 struct ath_hw *ah = sc->sc_ah; 252 struct ath_hw *ah = sc->sc_ah;
254 struct ath_btcoex *btcoex = &sc->btcoex; 253 struct ath_btcoex *btcoex = &sc->btcoex;
255 struct ath_common *common = ath9k_hw_common(ah);
256
257 ath_dbg(common, BTCOEX, "no stomp timer running\n");
258 254
259 ath9k_ps_wakeup(sc); 255 ath9k_ps_wakeup(sc);
260 spin_lock_bh(&btcoex->btcoex_lock); 256 spin_lock_bh(&btcoex->btcoex_lock);
@@ -271,7 +267,7 @@ static void ath_btcoex_no_stomp_timer(unsigned long arg)
271 ath9k_ps_restore(sc); 267 ath9k_ps_restore(sc);
272} 268}
273 269
274static int ath_init_btcoex_timer(struct ath_softc *sc) 270static void ath_init_btcoex_timer(struct ath_softc *sc)
275{ 271{
276 struct ath_btcoex *btcoex = &sc->btcoex; 272 struct ath_btcoex *btcoex = &sc->btcoex;
277 273
@@ -280,6 +276,7 @@ static int ath_init_btcoex_timer(struct ath_softc *sc)
280 btcoex->btcoex_period / 100; 276 btcoex->btcoex_period / 100;
281 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 277 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
282 btcoex->btcoex_period / 100; 278 btcoex->btcoex_period / 100;
279 btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
283 280
284 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, 281 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
285 (unsigned long) sc); 282 (unsigned long) sc);
@@ -287,8 +284,6 @@ static int ath_init_btcoex_timer(struct ath_softc *sc)
287 (unsigned long) sc); 284 (unsigned long) sc);
288 285
289 spin_lock_init(&btcoex->btcoex_lock); 286 spin_lock_init(&btcoex->btcoex_lock);
290
291 return 0;
292} 287}
293 288
294/* 289/*
@@ -299,6 +294,10 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
299 struct ath_btcoex *btcoex = &sc->btcoex; 294 struct ath_btcoex *btcoex = &sc->btcoex;
300 struct ath_hw *ah = sc->sc_ah; 295 struct ath_hw *ah = sc->sc_ah;
301 296
297 if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_3WIRE &&
298 ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI)
299 return;
300
302 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); 301 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n");
303 302
304 /* make sure duty cycle timer is also stopped when resuming */ 303 /* make sure duty cycle timer is also stopped when resuming */
@@ -312,13 +311,19 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
312 mod_timer(&btcoex->period_timer, jiffies); 311 mod_timer(&btcoex->period_timer, jiffies);
313} 312}
314 313
315
316/* 314/*
317 * Pause btcoex timer and bt duty cycle timer 315 * Pause btcoex timer and bt duty cycle timer
318 */ 316 */
319void ath9k_btcoex_timer_pause(struct ath_softc *sc) 317void ath9k_btcoex_timer_pause(struct ath_softc *sc)
320{ 318{
321 struct ath_btcoex *btcoex = &sc->btcoex; 319 struct ath_btcoex *btcoex = &sc->btcoex;
320 struct ath_hw *ah = sc->sc_ah;
321
322 if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_3WIRE &&
323 ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI)
324 return;
325
326 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Stopping btcoex timers\n");
322 327
323 del_timer_sync(&btcoex->period_timer); 328 del_timer_sync(&btcoex->period_timer);
324 del_timer_sync(&btcoex->no_stomp_timer); 329 del_timer_sync(&btcoex->no_stomp_timer);
@@ -356,33 +361,33 @@ void ath9k_start_btcoex(struct ath_softc *sc)
356{ 361{
357 struct ath_hw *ah = sc->sc_ah; 362 struct ath_hw *ah = sc->sc_ah;
358 363
359 if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) && 364 if (ah->btcoex_hw.enabled ||
360 !ah->btcoex_hw.enabled) { 365 ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
361 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) 366 return;
362 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
363 AR_STOMP_LOW_WLAN_WGHT, 0);
364 else
365 ath9k_hw_btcoex_set_weight(ah, 0, 0,
366 ATH_BTCOEX_STOMP_NONE);
367 ath9k_hw_btcoex_enable(ah);
368 367
369 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) 368 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
370 ath9k_btcoex_timer_resume(sc); 369 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
371 } 370 AR_STOMP_LOW_WLAN_WGHT, 0);
371 else
372 ath9k_hw_btcoex_set_weight(ah, 0, 0,
373 ATH_BTCOEX_STOMP_NONE);
374 ath9k_hw_btcoex_enable(ah);
375 ath9k_btcoex_timer_resume(sc);
372} 376}
373 377
374void ath9k_stop_btcoex(struct ath_softc *sc) 378void ath9k_stop_btcoex(struct ath_softc *sc)
375{ 379{
376 struct ath_hw *ah = sc->sc_ah; 380 struct ath_hw *ah = sc->sc_ah;
377 381
378 if (ah->btcoex_hw.enabled && 382 if (!ah->btcoex_hw.enabled ||
379 ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { 383 ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
380 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) 384 return;
381 ath9k_btcoex_timer_pause(sc); 385
382 ath9k_hw_btcoex_disable(ah); 386 ath9k_btcoex_timer_pause(sc);
383 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) 387 ath9k_hw_btcoex_disable(ah);
384 ath_mci_flush_profile(&sc->btcoex.mci); 388
385 } 389 if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI)
390 ath_mci_flush_profile(&sc->btcoex.mci);
386} 391}
387 392
388void ath9k_deinit_btcoex(struct ath_softc *sc) 393void ath9k_deinit_btcoex(struct ath_softc *sc)
@@ -409,22 +414,20 @@ int ath9k_init_btcoex(struct ath_softc *sc)
409 break; 414 break;
410 case ATH_BTCOEX_CFG_3WIRE: 415 case ATH_BTCOEX_CFG_3WIRE:
411 ath9k_hw_btcoex_init_3wire(sc->sc_ah); 416 ath9k_hw_btcoex_init_3wire(sc->sc_ah);
412 r = ath_init_btcoex_timer(sc); 417 ath_init_btcoex_timer(sc);
413 if (r)
414 return -1;
415 txq = sc->tx.txq_map[IEEE80211_AC_BE]; 418 txq = sc->tx.txq_map[IEEE80211_AC_BE];
416 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); 419 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
417 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; 420 break;
418 if (ath9k_hw_mci_is_enabled(ah)) { 421 case ATH_BTCOEX_CFG_MCI:
419 sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; 422 ath_init_btcoex_timer(sc);
420 INIT_LIST_HEAD(&sc->btcoex.mci.info);
421 423
422 r = ath_mci_setup(sc); 424 sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
423 if (r) 425 INIT_LIST_HEAD(&sc->btcoex.mci.info);
424 return r; 426 ath9k_hw_btcoex_init_mci(ah);
425 427
426 ath9k_hw_btcoex_init_mci(ah); 428 r = ath_mci_setup(sc);
427 } 429 if (r)
430 return r;
428 431
429 break; 432 break;
430 default: 433 default:
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 8e7153b186ed..10c02f5cbc5e 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -40,6 +40,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
40 { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */ 40 { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
41 { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */ 41 { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
42 { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */ 42 { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
43 { USB_DEVICE(0x0471, 0x209e) }, /* Philips (or NXP) PTA01 */
43 44
44 { USB_DEVICE(0x0cf3, 0x7015), 45 { USB_DEVICE(0x0cf3, 0x7015),
45 .driver_info = AR9287_USB }, /* Atheros */ 46 .driver_info = AR9287_USB }, /* Atheros */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index e82e570de330..29a25d92add7 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -27,6 +27,7 @@
27#include "eeprom.h" 27#include "eeprom.h"
28#include "calib.h" 28#include "calib.h"
29#include "reg.h" 29#include "reg.h"
30#include "reg_mci.h"
30#include "phy.h" 31#include "phy.h"
31#include "btcoex.h" 32#include "btcoex.h"
32#include "dynack.h" 33#include "dynack.h"
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 93ed99a72542..b0badef71ce7 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1172,6 +1172,38 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1172 ath9k_ps_restore(sc); 1172 ath9k_ps_restore(sc);
1173} 1173}
1174 1174
1175static void ath9k_tpc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1176{
1177 int *power = (int *)data;
1178
1179 if (*power < vif->bss_conf.txpower)
1180 *power = vif->bss_conf.txpower;
1181}
1182
1183/* Called with sc->mutex held. */
1184void ath9k_set_txpower(struct ath_softc *sc, struct ieee80211_vif *vif)
1185{
1186 int power;
1187 struct ath_hw *ah = sc->sc_ah;
1188 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
1189
1190 ath9k_ps_wakeup(sc);
1191 if (ah->tpc_enabled) {
1192 power = (vif) ? vif->bss_conf.txpower : -1;
1193 ieee80211_iterate_active_interfaces_atomic(
1194 sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1195 ath9k_tpc_vif_iter, &power);
1196 if (power == -1)
1197 power = sc->hw->conf.power_level;
1198 } else {
1199 power = sc->hw->conf.power_level;
1200 }
1201 sc->cur_chan->txpower = 2 * power;
1202 ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
1203 sc->cur_chan->cur_txpower = reg->max_power_level;
1204 ath9k_ps_restore(sc);
1205}
1206
1175static void ath9k_assign_hw_queues(struct ieee80211_hw *hw, 1207static void ath9k_assign_hw_queues(struct ieee80211_hw *hw,
1176 struct ieee80211_vif *vif) 1208 struct ieee80211_vif *vif)
1177{ 1209{
@@ -1225,6 +1257,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1225 1257
1226 ath9k_assign_hw_queues(hw, vif); 1258 ath9k_assign_hw_queues(hw, vif);
1227 1259
1260 ath9k_set_txpower(sc, vif);
1261
1228 an->sc = sc; 1262 an->sc = sc;
1229 an->sta = NULL; 1263 an->sta = NULL;
1230 an->vif = vif; 1264 an->vif = vif;
@@ -1265,6 +1299,8 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1265 ath9k_assign_hw_queues(hw, vif); 1299 ath9k_assign_hw_queues(hw, vif);
1266 ath9k_calculate_summary_state(sc, avp->chanctx); 1300 ath9k_calculate_summary_state(sc, avp->chanctx);
1267 1301
1302 ath9k_set_txpower(sc, vif);
1303
1268 mutex_unlock(&sc->mutex); 1304 mutex_unlock(&sc->mutex);
1269 return 0; 1305 return 0;
1270} 1306}
@@ -1294,6 +1330,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1294 1330
1295 ath9k_calculate_summary_state(sc, avp->chanctx); 1331 ath9k_calculate_summary_state(sc, avp->chanctx);
1296 1332
1333 ath9k_set_txpower(sc, NULL);
1334
1297 mutex_unlock(&sc->mutex); 1335 mutex_unlock(&sc->mutex);
1298} 1336}
1299 1337
@@ -1397,14 +1435,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1397 ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef); 1435 ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef);
1398 } 1436 }
1399 1437
1400 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1401 ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
1402 sc->cur_chan->txpower = 2 * conf->power_level;
1403 ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
1404 sc->cur_chan->txpower,
1405 &sc->cur_chan->cur_txpower);
1406 }
1407
1408 mutex_unlock(&sc->mutex); 1438 mutex_unlock(&sc->mutex);
1409 ath9k_ps_restore(sc); 1439 ath9k_ps_restore(sc);
1410 1440
@@ -1764,6 +1794,12 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1764 if (changed & CHECK_ANI) 1794 if (changed & CHECK_ANI)
1765 ath_check_ani(sc); 1795 ath_check_ani(sc);
1766 1796
1797 if (changed & BSS_CHANGED_TXPOWER) {
1798 ath_dbg(common, CONFIG, "vif %pM power %d dbm power_type %d\n",
1799 vif->addr, bss_conf->txpower, bss_conf->txpower_type);
1800 ath9k_set_txpower(sc, vif);
1801 }
1802
1767 mutex_unlock(&sc->mutex); 1803 mutex_unlock(&sc->mutex);
1768 ath9k_ps_restore(sc); 1804 ath9k_ps_restore(sc);
1769 1805
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index 3f7a11edb82a..66596b95273f 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -495,7 +495,7 @@ void ath_mci_intr(struct ath_softc *sc)
495 ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); 495 ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg);
496 496
497 if (ar9003_mci_state(ah, MCI_STATE_ENABLE) == 0) { 497 if (ar9003_mci_state(ah, MCI_STATE_ENABLE) == 0) {
498 ar9003_mci_get_next_gpm_offset(ah, true, NULL); 498 ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET);
499 return; 499 return;
500 } 500 }
501 501
@@ -559,8 +559,7 @@ void ath_mci_intr(struct ath_softc *sc)
559 return; 559 return;
560 560
561 pgpm = mci->gpm_buf.bf_addr; 561 pgpm = mci->gpm_buf.bf_addr;
562 offset = ar9003_mci_get_next_gpm_offset(ah, false, 562 offset = ar9003_mci_get_next_gpm_offset(ah, &more_data);
563 &more_data);
564 563
565 if (offset == MCI_GPM_INVALID) 564 if (offset == MCI_GPM_INVALID)
566 break; 565 break;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 9587ec655680..1234399a43dd 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -2044,279 +2044,4 @@ enum {
2044#define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0 2044#define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0
2045#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6 2045#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6
2046 2046
2047/* MCI Registers */
2048
2049#define AR_MCI_COMMAND0 0x1800
2050#define AR_MCI_COMMAND0_HEADER 0xFF
2051#define AR_MCI_COMMAND0_HEADER_S 0
2052#define AR_MCI_COMMAND0_LEN 0x1f00
2053#define AR_MCI_COMMAND0_LEN_S 8
2054#define AR_MCI_COMMAND0_DISABLE_TIMESTAMP 0x2000
2055#define AR_MCI_COMMAND0_DISABLE_TIMESTAMP_S 13
2056
2057#define AR_MCI_COMMAND1 0x1804
2058
2059#define AR_MCI_COMMAND2 0x1808
2060#define AR_MCI_COMMAND2_RESET_TX 0x01
2061#define AR_MCI_COMMAND2_RESET_TX_S 0
2062#define AR_MCI_COMMAND2_RESET_RX 0x02
2063#define AR_MCI_COMMAND2_RESET_RX_S 1
2064#define AR_MCI_COMMAND2_RESET_RX_NUM_CYCLES 0x3FC
2065#define AR_MCI_COMMAND2_RESET_RX_NUM_CYCLES_S 2
2066#define AR_MCI_COMMAND2_RESET_REQ_WAKEUP 0x400
2067#define AR_MCI_COMMAND2_RESET_REQ_WAKEUP_S 10
2068
2069#define AR_MCI_RX_CTRL 0x180c
2070
2071#define AR_MCI_TX_CTRL 0x1810
2072/* 0 = no division, 1 = divide by 2, 2 = divide by 4, 3 = divide by 8 */
2073#define AR_MCI_TX_CTRL_CLK_DIV 0x03
2074#define AR_MCI_TX_CTRL_CLK_DIV_S 0
2075#define AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE 0x04
2076#define AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE_S 2
2077#define AR_MCI_TX_CTRL_GAIN_UPDATE_FREQ 0xFFFFF8
2078#define AR_MCI_TX_CTRL_GAIN_UPDATE_FREQ_S 3
2079#define AR_MCI_TX_CTRL_GAIN_UPDATE_NUM 0xF000000
2080#define AR_MCI_TX_CTRL_GAIN_UPDATE_NUM_S 24
2081
2082#define AR_MCI_MSG_ATTRIBUTES_TABLE 0x1814
2083#define AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM 0xFFFF
2084#define AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM_S 0
2085#define AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR 0xFFFF0000
2086#define AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR_S 16
2087
2088#define AR_MCI_SCHD_TABLE_0 0x1818
2089#define AR_MCI_SCHD_TABLE_1 0x181c
2090#define AR_MCI_GPM_0 0x1820
2091#define AR_MCI_GPM_1 0x1824
2092#define AR_MCI_GPM_WRITE_PTR 0xFFFF0000
2093#define AR_MCI_GPM_WRITE_PTR_S 16
2094#define AR_MCI_GPM_BUF_LEN 0x0000FFFF
2095#define AR_MCI_GPM_BUF_LEN_S 0
2096
2097#define AR_MCI_INTERRUPT_RAW 0x1828
2098#define AR_MCI_INTERRUPT_EN 0x182c
2099#define AR_MCI_INTERRUPT_SW_MSG_DONE 0x00000001
2100#define AR_MCI_INTERRUPT_SW_MSG_DONE_S 0
2101#define AR_MCI_INTERRUPT_CPU_INT_MSG 0x00000002
2102#define AR_MCI_INTERRUPT_CPU_INT_MSG_S 1
2103#define AR_MCI_INTERRUPT_RX_CKSUM_FAIL 0x00000004
2104#define AR_MCI_INTERRUPT_RX_CKSUM_FAIL_S 2
2105#define AR_MCI_INTERRUPT_RX_INVALID_HDR 0x00000008
2106#define AR_MCI_INTERRUPT_RX_INVALID_HDR_S 3
2107#define AR_MCI_INTERRUPT_RX_HW_MSG_FAIL 0x00000010
2108#define AR_MCI_INTERRUPT_RX_HW_MSG_FAIL_S 4
2109#define AR_MCI_INTERRUPT_RX_SW_MSG_FAIL 0x00000020
2110#define AR_MCI_INTERRUPT_RX_SW_MSG_FAIL_S 5
2111#define AR_MCI_INTERRUPT_TX_HW_MSG_FAIL 0x00000080
2112#define AR_MCI_INTERRUPT_TX_HW_MSG_FAIL_S 7
2113#define AR_MCI_INTERRUPT_TX_SW_MSG_FAIL 0x00000100
2114#define AR_MCI_INTERRUPT_TX_SW_MSG_FAIL_S 8
2115#define AR_MCI_INTERRUPT_RX_MSG 0x00000200
2116#define AR_MCI_INTERRUPT_RX_MSG_S 9
2117#define AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE 0x00000400
2118#define AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE_S 10
2119#define AR_MCI_INTERRUPT_BT_PRI 0x07fff800
2120#define AR_MCI_INTERRUPT_BT_PRI_S 11
2121#define AR_MCI_INTERRUPT_BT_PRI_THRESH 0x08000000
2122#define AR_MCI_INTERRUPT_BT_PRI_THRESH_S 27
2123#define AR_MCI_INTERRUPT_BT_FREQ 0x10000000
2124#define AR_MCI_INTERRUPT_BT_FREQ_S 28
2125#define AR_MCI_INTERRUPT_BT_STOMP 0x20000000
2126#define AR_MCI_INTERRUPT_BT_STOMP_S 29
2127#define AR_MCI_INTERRUPT_BB_AIC_IRQ 0x40000000
2128#define AR_MCI_INTERRUPT_BB_AIC_IRQ_S 30
2129#define AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT 0x80000000
2130#define AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT_S 31
2131
2132#define AR_MCI_INTERRUPT_DEFAULT (AR_MCI_INTERRUPT_SW_MSG_DONE | \
2133 AR_MCI_INTERRUPT_RX_INVALID_HDR | \
2134 AR_MCI_INTERRUPT_RX_HW_MSG_FAIL | \
2135 AR_MCI_INTERRUPT_RX_SW_MSG_FAIL | \
2136 AR_MCI_INTERRUPT_TX_HW_MSG_FAIL | \
2137 AR_MCI_INTERRUPT_TX_SW_MSG_FAIL | \
2138 AR_MCI_INTERRUPT_RX_MSG | \
2139 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE | \
2140 AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)
2141
2142#define AR_MCI_INTERRUPT_MSG_FAIL_MASK (AR_MCI_INTERRUPT_RX_HW_MSG_FAIL | \
2143 AR_MCI_INTERRUPT_RX_SW_MSG_FAIL | \
2144 AR_MCI_INTERRUPT_TX_HW_MSG_FAIL | \
2145 AR_MCI_INTERRUPT_TX_SW_MSG_FAIL)
2146
2147#define AR_MCI_REMOTE_CPU_INT 0x1830
2148#define AR_MCI_REMOTE_CPU_INT_EN 0x1834
2149#define AR_MCI_INTERRUPT_RX_MSG_RAW 0x1838
2150#define AR_MCI_INTERRUPT_RX_MSG_EN 0x183c
2151#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET 0x00000001
2152#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET_S 0
2153#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL 0x00000002
2154#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL_S 1
2155#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK 0x00000004
2156#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK_S 2
2157#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO 0x00000008
2158#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO_S 3
2159#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST 0x00000010
2160#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST_S 4
2161#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO 0x00000020
2162#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO_S 5
2163#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT 0x00000040
2164#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT_S 6
2165#define AR_MCI_INTERRUPT_RX_MSG_GPM 0x00000100
2166#define AR_MCI_INTERRUPT_RX_MSG_GPM_S 8
2167#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO 0x00000200
2168#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO_S 9
2169#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING 0x00000400
2170#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING_S 10
2171#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING 0x00000800
2172#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING_S 11
2173#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE 0x00001000
2174#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE_S 12
2175#define AR_MCI_INTERRUPT_RX_HW_MSG_MASK (AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO | \
2176 AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL| \
2177 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO | \
2178 AR_MCI_INTERRUPT_RX_MSG_CONT_NACK | \
2179 AR_MCI_INTERRUPT_RX_MSG_CONT_INFO | \
2180 AR_MCI_INTERRUPT_RX_MSG_CONT_RST)
2181
2182#define AR_MCI_INTERRUPT_RX_MSG_DEFAULT (AR_MCI_INTERRUPT_RX_MSG_GPM | \
2183 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET| \
2184 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING | \
2185 AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING| \
2186 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)
2187
2188#define AR_MCI_CPU_INT 0x1840
2189
2190#define AR_MCI_RX_STATUS 0x1844
2191#define AR_MCI_RX_LAST_SCHD_MSG_INDEX 0x00000F00
2192#define AR_MCI_RX_LAST_SCHD_MSG_INDEX_S 8
2193#define AR_MCI_RX_REMOTE_SLEEP 0x00001000
2194#define AR_MCI_RX_REMOTE_SLEEP_S 12
2195#define AR_MCI_RX_MCI_CLK_REQ 0x00002000
2196#define AR_MCI_RX_MCI_CLK_REQ_S 13
2197
2198#define AR_MCI_CONT_STATUS 0x1848
2199#define AR_MCI_CONT_RSSI_POWER 0x000000FF
2200#define AR_MCI_CONT_RSSI_POWER_S 0
2201#define AR_MCI_CONT_PRIORITY 0x0000FF00
2202#define AR_MCI_CONT_PRIORITY_S 8
2203#define AR_MCI_CONT_TXRX 0x00010000
2204#define AR_MCI_CONT_TXRX_S 16
2205
2206#define AR_MCI_BT_PRI0 0x184c
2207#define AR_MCI_BT_PRI1 0x1850
2208#define AR_MCI_BT_PRI2 0x1854
2209#define AR_MCI_BT_PRI3 0x1858
2210#define AR_MCI_BT_PRI 0x185c
2211#define AR_MCI_WL_FREQ0 0x1860
2212#define AR_MCI_WL_FREQ1 0x1864
2213#define AR_MCI_WL_FREQ2 0x1868
2214#define AR_MCI_GAIN 0x186c
2215#define AR_MCI_WBTIMER1 0x1870
2216#define AR_MCI_WBTIMER2 0x1874
2217#define AR_MCI_WBTIMER3 0x1878
2218#define AR_MCI_WBTIMER4 0x187c
2219#define AR_MCI_MAXGAIN 0x1880
2220#define AR_MCI_HW_SCHD_TBL_CTL 0x1884
2221#define AR_MCI_HW_SCHD_TBL_D0 0x1888
2222#define AR_MCI_HW_SCHD_TBL_D1 0x188c
2223#define AR_MCI_HW_SCHD_TBL_D2 0x1890
2224#define AR_MCI_HW_SCHD_TBL_D3 0x1894
2225#define AR_MCI_TX_PAYLOAD0 0x1898
2226#define AR_MCI_TX_PAYLOAD1 0x189c
2227#define AR_MCI_TX_PAYLOAD2 0x18a0
2228#define AR_MCI_TX_PAYLOAD3 0x18a4
2229#define AR_BTCOEX_WBTIMER 0x18a8
2230
2231#define AR_BTCOEX_CTRL 0x18ac
2232#define AR_BTCOEX_CTRL_AR9462_MODE 0x00000001
2233#define AR_BTCOEX_CTRL_AR9462_MODE_S 0
2234#define AR_BTCOEX_CTRL_WBTIMER_EN 0x00000002
2235#define AR_BTCOEX_CTRL_WBTIMER_EN_S 1
2236#define AR_BTCOEX_CTRL_MCI_MODE_EN 0x00000004
2237#define AR_BTCOEX_CTRL_MCI_MODE_EN_S 2
2238#define AR_BTCOEX_CTRL_LNA_SHARED 0x00000008
2239#define AR_BTCOEX_CTRL_LNA_SHARED_S 3
2240#define AR_BTCOEX_CTRL_PA_SHARED 0x00000010
2241#define AR_BTCOEX_CTRL_PA_SHARED_S 4
2242#define AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN 0x00000020
2243#define AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN_S 5
2244#define AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN 0x00000040
2245#define AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN_S 6
2246#define AR_BTCOEX_CTRL_NUM_ANTENNAS 0x00000180
2247#define AR_BTCOEX_CTRL_NUM_ANTENNAS_S 7
2248#define AR_BTCOEX_CTRL_RX_CHAIN_MASK 0x00000E00
2249#define AR_BTCOEX_CTRL_RX_CHAIN_MASK_S 9
2250#define AR_BTCOEX_CTRL_AGGR_THRESH 0x00007000
2251#define AR_BTCOEX_CTRL_AGGR_THRESH_S 12
2252#define AR_BTCOEX_CTRL_1_CHAIN_BCN 0x00080000
2253#define AR_BTCOEX_CTRL_1_CHAIN_BCN_S 19
2254#define AR_BTCOEX_CTRL_1_CHAIN_ACK 0x00100000
2255#define AR_BTCOEX_CTRL_1_CHAIN_ACK_S 20
2256#define AR_BTCOEX_CTRL_WAIT_BA_MARGIN 0x1FE00000
2257#define AR_BTCOEX_CTRL_WAIT_BA_MARGIN_S 28
2258#define AR_BTCOEX_CTRL_REDUCE_TXPWR 0x20000000
2259#define AR_BTCOEX_CTRL_REDUCE_TXPWR_S 29
2260#define AR_BTCOEX_CTRL_SPDT_ENABLE_10 0x40000000
2261#define AR_BTCOEX_CTRL_SPDT_ENABLE_10_S 30
2262#define AR_BTCOEX_CTRL_SPDT_POLARITY 0x80000000
2263#define AR_BTCOEX_CTRL_SPDT_POLARITY_S 31
2264
2265#define AR_BTCOEX_MAX_TXPWR(_x) (0x18c0 + ((_x) << 2))
2266#define AR_BTCOEX_WL_LNA 0x1940
2267#define AR_BTCOEX_RFGAIN_CTRL 0x1944
2268#define AR_BTCOEX_WL_LNA_TIMEOUT 0x003FFFFF
2269#define AR_BTCOEX_WL_LNA_TIMEOUT_S 0
2270
2271#define AR_BTCOEX_CTRL2 0x1948
2272#define AR_BTCOEX_CTRL2_TXPWR_THRESH 0x0007F800
2273#define AR_BTCOEX_CTRL2_TXPWR_THRESH_S 11
2274#define AR_BTCOEX_CTRL2_TX_CHAIN_MASK 0x00380000
2275#define AR_BTCOEX_CTRL2_TX_CHAIN_MASK_S 19
2276#define AR_BTCOEX_CTRL2_RX_DEWEIGHT 0x00400000
2277#define AR_BTCOEX_CTRL2_RX_DEWEIGHT_S 22
2278#define AR_BTCOEX_CTRL2_GPIO_OBS_SEL 0x00800000
2279#define AR_BTCOEX_CTRL2_GPIO_OBS_SEL_S 23
2280#define AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL 0x01000000
2281#define AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL_S 24
2282#define AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE 0x02000000
2283#define AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE_S 25
2284
2285#define AR_BTCOEX_CTRL_SPDT_ENABLE 0x00000001
2286#define AR_BTCOEX_CTRL_SPDT_ENABLE_S 0
2287#define AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL 0x00000002
2288#define AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL_S 1
2289#define AR_BTCOEX_CTRL_USE_LATCHED_BT_ANT 0x00000004
2290#define AR_BTCOEX_CTRL_USE_LATCHED_BT_ANT_S 2
2291#define AR_GLB_WLAN_UART_INTF_EN 0x00020000
2292#define AR_GLB_WLAN_UART_INTF_EN_S 17
2293#define AR_GLB_DS_JTAG_DISABLE 0x00040000
2294#define AR_GLB_DS_JTAG_DISABLE_S 18
2295
2296#define AR_BTCOEX_RC 0x194c
2297#define AR_BTCOEX_MAX_RFGAIN(_x) (0x1950 + ((_x) << 2))
2298#define AR_BTCOEX_DBG 0x1a50
2299#define AR_MCI_LAST_HW_MSG_HDR 0x1a54
2300#define AR_MCI_LAST_HW_MSG_BDY 0x1a58
2301
2302#define AR_MCI_SCHD_TABLE_2 0x1a5c
2303#define AR_MCI_SCHD_TABLE_2_MEM_BASED 0x00000001
2304#define AR_MCI_SCHD_TABLE_2_MEM_BASED_S 0
2305#define AR_MCI_SCHD_TABLE_2_HW_BASED 0x00000002
2306#define AR_MCI_SCHD_TABLE_2_HW_BASED_S 1
2307
2308#define AR_BTCOEX_CTRL3 0x1a60
2309#define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT 0x00000fff
2310#define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT_S 0
2311
2312#define AR_GLB_SWREG_DISCONT_MODE 0x2002c
2313#define AR_GLB_SWREG_DISCONT_EN_BT_WLAN 0x3
2314
2315#define AR_MCI_MISC 0x1a74
2316#define AR_MCI_MISC_HW_FIX_EN 0x00000001
2317#define AR_MCI_MISC_HW_FIX_EN_S 0
2318#define AR_MCI_DBG_CNT_CTRL 0x1a78
2319#define AR_MCI_DBG_CNT_CTRL_ENABLE 0x00000001
2320#define AR_MCI_DBG_CNT_CTRL_ENABLE_S 0
2321
2322#endif 2047#endif
diff --git a/drivers/net/wireless/ath/ath9k/reg_mci.h b/drivers/net/wireless/ath/ath9k/reg_mci.h
new file mode 100644
index 000000000000..6251310704e3
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/reg_mci.h
@@ -0,0 +1,310 @@
1/*
2 * Copyright (c) 2015 Qualcomm Atheros Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef REG_MCI_H
18#define REG_MCI_H
19
20#define AR_MCI_COMMAND0 0x1800
21#define AR_MCI_COMMAND0_HEADER 0xFF
22#define AR_MCI_COMMAND0_HEADER_S 0
23#define AR_MCI_COMMAND0_LEN 0x1f00
24#define AR_MCI_COMMAND0_LEN_S 8
25#define AR_MCI_COMMAND0_DISABLE_TIMESTAMP 0x2000
26#define AR_MCI_COMMAND0_DISABLE_TIMESTAMP_S 13
27
28#define AR_MCI_COMMAND1 0x1804
29
30#define AR_MCI_COMMAND2 0x1808
31#define AR_MCI_COMMAND2_RESET_TX 0x01
32#define AR_MCI_COMMAND2_RESET_TX_S 0
33#define AR_MCI_COMMAND2_RESET_RX 0x02
34#define AR_MCI_COMMAND2_RESET_RX_S 1
35#define AR_MCI_COMMAND2_RESET_RX_NUM_CYCLES 0x3FC
36#define AR_MCI_COMMAND2_RESET_RX_NUM_CYCLES_S 2
37#define AR_MCI_COMMAND2_RESET_REQ_WAKEUP 0x400
38#define AR_MCI_COMMAND2_RESET_REQ_WAKEUP_S 10
39
40#define AR_MCI_RX_CTRL 0x180c
41
42#define AR_MCI_TX_CTRL 0x1810
43/*
44 * 0 = no division,
45 * 1 = divide by 2,
46 * 2 = divide by 4,
47 * 3 = divide by 8
48 */
49#define AR_MCI_TX_CTRL_CLK_DIV 0x03
50#define AR_MCI_TX_CTRL_CLK_DIV_S 0
51#define AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE 0x04
52#define AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE_S 2
53#define AR_MCI_TX_CTRL_GAIN_UPDATE_FREQ 0xFFFFF8
54#define AR_MCI_TX_CTRL_GAIN_UPDATE_FREQ_S 3
55#define AR_MCI_TX_CTRL_GAIN_UPDATE_NUM 0xF000000
56#define AR_MCI_TX_CTRL_GAIN_UPDATE_NUM_S 24
57
58#define AR_MCI_MSG_ATTRIBUTES_TABLE 0x1814
59#define AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM 0xFFFF
60#define AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM_S 0
61#define AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR 0xFFFF0000
62#define AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR_S 16
63
64#define AR_MCI_SCHD_TABLE_0 0x1818
65#define AR_MCI_SCHD_TABLE_1 0x181c
66#define AR_MCI_GPM_0 0x1820
67#define AR_MCI_GPM_1 0x1824
68#define AR_MCI_GPM_WRITE_PTR 0xFFFF0000
69#define AR_MCI_GPM_WRITE_PTR_S 16
70#define AR_MCI_GPM_BUF_LEN 0x0000FFFF
71#define AR_MCI_GPM_BUF_LEN_S 0
72
73#define AR_MCI_INTERRUPT_RAW 0x1828
74
75#define AR_MCI_INTERRUPT_EN 0x182c
76#define AR_MCI_INTERRUPT_SW_MSG_DONE 0x00000001
77#define AR_MCI_INTERRUPT_SW_MSG_DONE_S 0
78#define AR_MCI_INTERRUPT_CPU_INT_MSG 0x00000002
79#define AR_MCI_INTERRUPT_CPU_INT_MSG_S 1
80#define AR_MCI_INTERRUPT_RX_CKSUM_FAIL 0x00000004
81#define AR_MCI_INTERRUPT_RX_CKSUM_FAIL_S 2
82#define AR_MCI_INTERRUPT_RX_INVALID_HDR 0x00000008
83#define AR_MCI_INTERRUPT_RX_INVALID_HDR_S 3
84#define AR_MCI_INTERRUPT_RX_HW_MSG_FAIL 0x00000010
85#define AR_MCI_INTERRUPT_RX_HW_MSG_FAIL_S 4
86#define AR_MCI_INTERRUPT_RX_SW_MSG_FAIL 0x00000020
87#define AR_MCI_INTERRUPT_RX_SW_MSG_FAIL_S 5
88#define AR_MCI_INTERRUPT_TX_HW_MSG_FAIL 0x00000080
89#define AR_MCI_INTERRUPT_TX_HW_MSG_FAIL_S 7
90#define AR_MCI_INTERRUPT_TX_SW_MSG_FAIL 0x00000100
91#define AR_MCI_INTERRUPT_TX_SW_MSG_FAIL_S 8
92#define AR_MCI_INTERRUPT_RX_MSG 0x00000200
93#define AR_MCI_INTERRUPT_RX_MSG_S 9
94#define AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE 0x00000400
95#define AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE_S 10
96#define AR_MCI_INTERRUPT_BT_PRI 0x07fff800
97#define AR_MCI_INTERRUPT_BT_PRI_S 11
98#define AR_MCI_INTERRUPT_BT_PRI_THRESH 0x08000000
99#define AR_MCI_INTERRUPT_BT_PRI_THRESH_S 27
100#define AR_MCI_INTERRUPT_BT_FREQ 0x10000000
101#define AR_MCI_INTERRUPT_BT_FREQ_S 28
102#define AR_MCI_INTERRUPT_BT_STOMP 0x20000000
103#define AR_MCI_INTERRUPT_BT_STOMP_S 29
104#define AR_MCI_INTERRUPT_BB_AIC_IRQ 0x40000000
105#define AR_MCI_INTERRUPT_BB_AIC_IRQ_S 30
106#define AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT 0x80000000
107#define AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT_S 31
108
109#define AR_MCI_REMOTE_CPU_INT 0x1830
110#define AR_MCI_REMOTE_CPU_INT_EN 0x1834
111#define AR_MCI_INTERRUPT_RX_MSG_RAW 0x1838
112#define AR_MCI_INTERRUPT_RX_MSG_EN 0x183c
113#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET 0x00000001
114#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET_S 0
115#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL 0x00000002
116#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL_S 1
117#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK 0x00000004
118#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK_S 2
119#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO 0x00000008
120#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO_S 3
121#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST 0x00000010
122#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST_S 4
123#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO 0x00000020
124#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO_S 5
125#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT 0x00000040
126#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT_S 6
127#define AR_MCI_INTERRUPT_RX_MSG_GPM 0x00000100
128#define AR_MCI_INTERRUPT_RX_MSG_GPM_S 8
129#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO 0x00000200
130#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO_S 9
131#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING 0x00000400
132#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING_S 10
133#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING 0x00000800
134#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING_S 11
135#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE 0x00001000
136#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE_S 12
137
138#define AR_MCI_CPU_INT 0x1840
139
140#define AR_MCI_RX_STATUS 0x1844
141#define AR_MCI_RX_LAST_SCHD_MSG_INDEX 0x00000F00
142#define AR_MCI_RX_LAST_SCHD_MSG_INDEX_S 8
143#define AR_MCI_RX_REMOTE_SLEEP 0x00001000
144#define AR_MCI_RX_REMOTE_SLEEP_S 12
145#define AR_MCI_RX_MCI_CLK_REQ 0x00002000
146#define AR_MCI_RX_MCI_CLK_REQ_S 13
147
148#define AR_MCI_CONT_STATUS 0x1848
149#define AR_MCI_CONT_RSSI_POWER 0x000000FF
150#define AR_MCI_CONT_RSSI_POWER_S 0
151#define AR_MCI_CONT_PRIORITY 0x0000FF00
152#define AR_MCI_CONT_PRIORITY_S 8
153#define AR_MCI_CONT_TXRX 0x00010000
154#define AR_MCI_CONT_TXRX_S 16
155
156#define AR_MCI_BT_PRI0 0x184c
157#define AR_MCI_BT_PRI1 0x1850
158#define AR_MCI_BT_PRI2 0x1854
159#define AR_MCI_BT_PRI3 0x1858
160#define AR_MCI_BT_PRI 0x185c
161#define AR_MCI_WL_FREQ0 0x1860
162#define AR_MCI_WL_FREQ1 0x1864
163#define AR_MCI_WL_FREQ2 0x1868
164#define AR_MCI_GAIN 0x186c
165#define AR_MCI_WBTIMER1 0x1870
166#define AR_MCI_WBTIMER2 0x1874
167#define AR_MCI_WBTIMER3 0x1878
168#define AR_MCI_WBTIMER4 0x187c
169#define AR_MCI_MAXGAIN 0x1880
170#define AR_MCI_HW_SCHD_TBL_CTL 0x1884
171#define AR_MCI_HW_SCHD_TBL_D0 0x1888
172#define AR_MCI_HW_SCHD_TBL_D1 0x188c
173#define AR_MCI_HW_SCHD_TBL_D2 0x1890
174#define AR_MCI_HW_SCHD_TBL_D3 0x1894
175#define AR_MCI_TX_PAYLOAD0 0x1898
176#define AR_MCI_TX_PAYLOAD1 0x189c
177#define AR_MCI_TX_PAYLOAD2 0x18a0
178#define AR_MCI_TX_PAYLOAD3 0x18a4
179#define AR_BTCOEX_WBTIMER 0x18a8
180
181#define AR_BTCOEX_CTRL 0x18ac
182#define AR_BTCOEX_CTRL_AR9462_MODE 0x00000001
183#define AR_BTCOEX_CTRL_AR9462_MODE_S 0
184#define AR_BTCOEX_CTRL_WBTIMER_EN 0x00000002
185#define AR_BTCOEX_CTRL_WBTIMER_EN_S 1
186#define AR_BTCOEX_CTRL_MCI_MODE_EN 0x00000004
187#define AR_BTCOEX_CTRL_MCI_MODE_EN_S 2
188#define AR_BTCOEX_CTRL_LNA_SHARED 0x00000008
189#define AR_BTCOEX_CTRL_LNA_SHARED_S 3
190#define AR_BTCOEX_CTRL_PA_SHARED 0x00000010
191#define AR_BTCOEX_CTRL_PA_SHARED_S 4
192#define AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN 0x00000020
193#define AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN_S 5
194#define AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN 0x00000040
195#define AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN_S 6
196#define AR_BTCOEX_CTRL_NUM_ANTENNAS 0x00000180
197#define AR_BTCOEX_CTRL_NUM_ANTENNAS_S 7
198#define AR_BTCOEX_CTRL_RX_CHAIN_MASK 0x00000E00
199#define AR_BTCOEX_CTRL_RX_CHAIN_MASK_S 9
200#define AR_BTCOEX_CTRL_AGGR_THRESH 0x00007000
201#define AR_BTCOEX_CTRL_AGGR_THRESH_S 12
202#define AR_BTCOEX_CTRL_1_CHAIN_BCN 0x00080000
203#define AR_BTCOEX_CTRL_1_CHAIN_BCN_S 19
204#define AR_BTCOEX_CTRL_1_CHAIN_ACK 0x00100000
205#define AR_BTCOEX_CTRL_1_CHAIN_ACK_S 20
206#define AR_BTCOEX_CTRL_WAIT_BA_MARGIN 0x1FE00000
207#define AR_BTCOEX_CTRL_WAIT_BA_MARGIN_S 28
208#define AR_BTCOEX_CTRL_REDUCE_TXPWR 0x20000000
209#define AR_BTCOEX_CTRL_REDUCE_TXPWR_S 29
210#define AR_BTCOEX_CTRL_SPDT_ENABLE_10 0x40000000
211#define AR_BTCOEX_CTRL_SPDT_ENABLE_10_S 30
212#define AR_BTCOEX_CTRL_SPDT_POLARITY 0x80000000
213#define AR_BTCOEX_CTRL_SPDT_POLARITY_S 31
214
215#define AR_BTCOEX_WL_WEIGHTS0 0x18b0
216#define AR_BTCOEX_WL_WEIGHTS1 0x18b4
217#define AR_BTCOEX_WL_WEIGHTS2 0x18b8
218#define AR_BTCOEX_WL_WEIGHTS3 0x18bc
219
220#define AR_BTCOEX_MAX_TXPWR(_x) (0x18c0 + ((_x) << 2))
221#define AR_BTCOEX_WL_LNA 0x1940
222#define AR_BTCOEX_RFGAIN_CTRL 0x1944
223#define AR_BTCOEX_WL_LNA_TIMEOUT 0x003FFFFF
224#define AR_BTCOEX_WL_LNA_TIMEOUT_S 0
225
226#define AR_BTCOEX_CTRL2 0x1948
227#define AR_BTCOEX_CTRL2_TXPWR_THRESH 0x0007F800
228#define AR_BTCOEX_CTRL2_TXPWR_THRESH_S 11
229#define AR_BTCOEX_CTRL2_TX_CHAIN_MASK 0x00380000
230#define AR_BTCOEX_CTRL2_TX_CHAIN_MASK_S 19
231#define AR_BTCOEX_CTRL2_RX_DEWEIGHT 0x00400000
232#define AR_BTCOEX_CTRL2_RX_DEWEIGHT_S 22
233#define AR_BTCOEX_CTRL2_GPIO_OBS_SEL 0x00800000
234#define AR_BTCOEX_CTRL2_GPIO_OBS_SEL_S 23
235#define AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL 0x01000000
236#define AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL_S 24
237#define AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE 0x02000000
238#define AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE_S 25
239
240#define AR_BTCOEX_CTRL_SPDT_ENABLE 0x00000001
241#define AR_BTCOEX_CTRL_SPDT_ENABLE_S 0
242#define AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL 0x00000002
243#define AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL_S 1
244#define AR_BTCOEX_CTRL_USE_LATCHED_BT_ANT 0x00000004
245#define AR_BTCOEX_CTRL_USE_LATCHED_BT_ANT_S 2
246#define AR_GLB_WLAN_UART_INTF_EN 0x00020000
247#define AR_GLB_WLAN_UART_INTF_EN_S 17
248#define AR_GLB_DS_JTAG_DISABLE 0x00040000
249#define AR_GLB_DS_JTAG_DISABLE_S 18
250
251#define AR_BTCOEX_RC 0x194c
252#define AR_BTCOEX_MAX_RFGAIN(_x) (0x1950 + ((_x) << 2))
253#define AR_BTCOEX_DBG 0x1a50
254#define AR_MCI_LAST_HW_MSG_HDR 0x1a54
255#define AR_MCI_LAST_HW_MSG_BDY 0x1a58
256
257#define AR_MCI_SCHD_TABLE_2 0x1a5c
258#define AR_MCI_SCHD_TABLE_2_MEM_BASED 0x00000001
259#define AR_MCI_SCHD_TABLE_2_MEM_BASED_S 0
260#define AR_MCI_SCHD_TABLE_2_HW_BASED 0x00000002
261#define AR_MCI_SCHD_TABLE_2_HW_BASED_S 1
262
263#define AR_BTCOEX_CTRL3 0x1a60
264#define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT 0x00000fff
265#define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT_S 0
266
267#define AR_GLB_SWREG_DISCONT_MODE 0x2002c
268#define AR_GLB_SWREG_DISCONT_EN_BT_WLAN 0x3
269
270#define AR_MCI_MISC 0x1a74
271#define AR_MCI_MISC_HW_FIX_EN 0x00000001
272#define AR_MCI_MISC_HW_FIX_EN_S 0
273
274#define AR_MCI_DBG_CNT_CTRL 0x1a78
275#define AR_MCI_DBG_CNT_CTRL_ENABLE 0x00000001
276#define AR_MCI_DBG_CNT_CTRL_ENABLE_S 0
277#define AR_MCI_DBG_CNT_CTRL_BT_LINKID 0x000007f8
278#define AR_MCI_DBG_CNT_CTRL_BT_LINKID_S 3
279
280#define MCI_STAT_ALL_BT_LINKID 0xffff
281
282#define AR_MCI_INTERRUPT_DEFAULT (AR_MCI_INTERRUPT_SW_MSG_DONE | \
283 AR_MCI_INTERRUPT_RX_INVALID_HDR | \
284 AR_MCI_INTERRUPT_RX_HW_MSG_FAIL | \
285 AR_MCI_INTERRUPT_RX_SW_MSG_FAIL | \
286 AR_MCI_INTERRUPT_TX_HW_MSG_FAIL | \
287 AR_MCI_INTERRUPT_TX_SW_MSG_FAIL | \
288 AR_MCI_INTERRUPT_RX_MSG | \
289 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE | \
290 AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)
291
292#define AR_MCI_INTERRUPT_MSG_FAIL_MASK (AR_MCI_INTERRUPT_RX_HW_MSG_FAIL | \
293 AR_MCI_INTERRUPT_RX_SW_MSG_FAIL | \
294 AR_MCI_INTERRUPT_TX_HW_MSG_FAIL | \
295 AR_MCI_INTERRUPT_TX_SW_MSG_FAIL)
296
297#define AR_MCI_INTERRUPT_RX_HW_MSG_MASK (AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO | \
298 AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL | \
299 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO | \
300 AR_MCI_INTERRUPT_RX_MSG_CONT_NACK | \
301 AR_MCI_INTERRUPT_RX_MSG_CONT_INFO | \
302 AR_MCI_INTERRUPT_RX_MSG_CONT_RST)
303
304#define AR_MCI_INTERRUPT_RX_MSG_DEFAULT (AR_MCI_INTERRUPT_RX_MSG_GPM | \
305 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | \
306 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING | \
307 AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING | \
308 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)
309
310#endif /* REG_MCI_H */
diff --git a/drivers/net/wireless/ath/ath9k/reg_wow.h b/drivers/net/wireless/ath/ath9k/reg_wow.h
index 3abfca56ca58..453054078cc4 100644
--- a/drivers/net/wireless/ath/ath9k/reg_wow.h
+++ b/drivers/net/wireless/ath/ath9k/reg_wow.h
@@ -72,7 +72,7 @@
72#define AR_WOW_MAC_INTR_EN 0x00040000 72#define AR_WOW_MAC_INTR_EN 0x00040000
73#define AR_WOW_MAGIC_EN 0x00010000 73#define AR_WOW_MAGIC_EN 0x00010000
74#define AR_WOW_PATTERN_EN(x) (x & 0xff) 74#define AR_WOW_PATTERN_EN(x) (x & 0xff)
75#define AR_WOW_PAT_FOUND_SHIFT 8 75#define AR_WOW_PAT_FOUND_SHIFT 8
76#define AR_WOW_PATTERN_FOUND(x) (x & (0xff << AR_WOW_PAT_FOUND_SHIFT)) 76#define AR_WOW_PATTERN_FOUND(x) (x & (0xff << AR_WOW_PAT_FOUND_SHIFT))
77#define AR_WOW_PATTERN_FOUND_MASK ((0xff) << AR_WOW_PAT_FOUND_SHIFT) 77#define AR_WOW_PATTERN_FOUND_MASK ((0xff) << AR_WOW_PAT_FOUND_SHIFT)
78#define AR_WOW_MAGIC_PAT_FOUND 0x00020000 78#define AR_WOW_MAGIC_PAT_FOUND 0x00020000
@@ -90,6 +90,14 @@
90 AR_WOW_BEACON_FAIL | \ 90 AR_WOW_BEACON_FAIL | \
91 AR_WOW_KEEP_ALIVE_FAIL)) 91 AR_WOW_KEEP_ALIVE_FAIL))
92 92
93#define AR_WOW2_PATTERN_EN(x) ((x & 0xff) << 0)
94#define AR_WOW2_PATTERN_FOUND_SHIFT 8
95#define AR_WOW2_PATTERN_FOUND(x) (x & (0xff << AR_WOW2_PATTERN_FOUND_SHIFT))
96#define AR_WOW2_PATTERN_FOUND_MASK ((0xff) << AR_WOW2_PATTERN_FOUND_SHIFT)
97
98#define AR_WOW_STATUS2(x) (x & AR_WOW2_PATTERN_FOUND_MASK)
99#define AR_WOW_CLEAR_EVENTS2(x) (x & ~(AR_WOW2_PATTERN_EN(0xff)))
100
93#define AR_WOW_AIFS_CNT(x) (x & 0xff) 101#define AR_WOW_AIFS_CNT(x) (x & 0xff)
94#define AR_WOW_SLOT_CNT(x) ((x & 0xff) << 8) 102#define AR_WOW_SLOT_CNT(x) ((x & 0xff) << 8)
95#define AR_WOW_KEEP_ALIVE_CNT(x) ((x & 0xff) << 16) 103#define AR_WOW_KEEP_ALIVE_CNT(x) ((x & 0xff) << 16)
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 1b8e75c4d2c2..0acd079ba96b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1103,14 +1103,28 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
1103 struct sk_buff *skb; 1103 struct sk_buff *skb;
1104 struct ath_frame_info *fi; 1104 struct ath_frame_info *fi;
1105 struct ieee80211_tx_info *info; 1105 struct ieee80211_tx_info *info;
1106 struct ieee80211_vif *vif;
1106 struct ath_hw *ah = sc->sc_ah; 1107 struct ath_hw *ah = sc->sc_ah;
1107 1108
1108 if (sc->tx99_state || !ah->tpc_enabled) 1109 if (sc->tx99_state || !ah->tpc_enabled)
1109 return MAX_RATE_POWER; 1110 return MAX_RATE_POWER;
1110 1111
1111 skb = bf->bf_mpdu; 1112 skb = bf->bf_mpdu;
1112 fi = get_frame_info(skb);
1113 info = IEEE80211_SKB_CB(skb); 1113 info = IEEE80211_SKB_CB(skb);
1114 vif = info->control.vif;
1115
1116 if (!vif) {
1117 max_power = sc->cur_chan->cur_txpower;
1118 goto out;
1119 }
1120
1121 if (vif->bss_conf.txpower_type != NL80211_TX_POWER_LIMITED) {
1122 max_power = min_t(u8, sc->cur_chan->cur_txpower,
1123 2 * vif->bss_conf.txpower);
1124 goto out;
1125 }
1126
1127 fi = get_frame_info(skb);
1114 1128
1115 if (!AR_SREV_9300_20_OR_LATER(ah)) { 1129 if (!AR_SREV_9300_20_OR_LATER(ah)) {
1116 int txpower = fi->tx_power; 1130 int txpower = fi->tx_power;
@@ -1147,25 +1161,25 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
1147 txpower -= 2; 1161 txpower -= 2;
1148 1162
1149 txpower = max(txpower, 0); 1163 txpower = max(txpower, 0);
1150 max_power = min_t(u8, ah->tx_power[rateidx], txpower); 1164 max_power = min_t(u8, ah->tx_power[rateidx],
1151 1165 2 * vif->bss_conf.txpower);
1152 /* XXX: clamp minimum TX power at 1 for AR9160 since if 1166 max_power = min_t(u8, max_power, txpower);
1153 * max_power is set to 0, frames are transmitted at max
1154 * TX power
1155 */
1156 if (!max_power && !AR_SREV_9280_20_OR_LATER(ah))
1157 max_power = 1;
1158 } else if (!bf->bf_state.bfs_paprd) { 1167 } else if (!bf->bf_state.bfs_paprd) {
1159 if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC)) 1168 if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC))
1160 max_power = min(ah->tx_power_stbc[rateidx], 1169 max_power = min_t(u8, ah->tx_power_stbc[rateidx],
1161 fi->tx_power); 1170 2 * vif->bss_conf.txpower);
1162 else 1171 else
1163 max_power = min(ah->tx_power[rateidx], fi->tx_power); 1172 max_power = min_t(u8, ah->tx_power[rateidx],
1173 2 * vif->bss_conf.txpower);
1174 max_power = min(max_power, fi->tx_power);
1164 } else { 1175 } else {
1165 max_power = ah->paprd_training_power; 1176 max_power = ah->paprd_training_power;
1166 } 1177 }
1167 1178out:
1168 return max_power; 1179 /* XXX: clamp minimum TX power at 1 for AR9160 since if max_power
1180 * is set to 0, frames are transmitted at max TX power
1181 */
1182 return (!max_power && !AR_SREV_9280_20_OR_LATER(ah)) ? 1 : max_power;
1169} 1183}
1170 1184
1171static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, 1185static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 2d5ea21be47e..4bd708c8716c 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -387,11 +387,25 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
387 int ch; 387 int ch;
388 int rc = 0; 388 int rc = 0;
389 389
390 wil_print_connect_params(wil, sme);
391
390 if (test_bit(wil_status_fwconnecting, wil->status) || 392 if (test_bit(wil_status_fwconnecting, wil->status) ||
391 test_bit(wil_status_fwconnected, wil->status)) 393 test_bit(wil_status_fwconnected, wil->status))
392 return -EALREADY; 394 return -EALREADY;
393 395
394 wil_print_connect_params(wil, sme); 396 if (sme->ie_len > WMI_MAX_IE_LEN) {
397 wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len);
398 return -ERANGE;
399 }
400
401 rsn_eid = sme->ie ?
402 cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
403 NULL;
404
405 if (sme->privacy && !rsn_eid) {
406 wil_err(wil, "Missing RSN IE for secure connection\n");
407 return -EINVAL;
408 }
395 409
396 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, 410 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
397 sme->ssid, sme->ssid_len, 411 sme->ssid, sme->ssid_len,
@@ -407,17 +421,9 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
407 rc = -ENOENT; 421 rc = -ENOENT;
408 goto out; 422 goto out;
409 } 423 }
424 wil->privacy = sme->privacy;
410 425
411 rsn_eid = sme->ie ? 426 if (wil->privacy) {
412 cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
413 NULL;
414 if (rsn_eid) {
415 if (sme->ie_len > WMI_MAX_IE_LEN) {
416 rc = -ERANGE;
417 wil_err(wil, "IE too large (%td bytes)\n",
418 sme->ie_len);
419 goto out;
420 }
421 /* For secure assoc, send WMI_DELETE_CIPHER_KEY_CMD */ 427 /* For secure assoc, send WMI_DELETE_CIPHER_KEY_CMD */
422 rc = wmi_del_cipher_key(wil, 0, bss->bssid); 428 rc = wmi_del_cipher_key(wil, 0, bss->bssid);
423 if (rc) { 429 if (rc) {
@@ -450,7 +456,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
450 bss->capability); 456 bss->capability);
451 goto out; 457 goto out;
452 } 458 }
453 if (rsn_eid) { 459 if (wil->privacy) {
454 conn.dot11_auth_mode = WMI_AUTH11_SHARED; 460 conn.dot11_auth_mode = WMI_AUTH11_SHARED;
455 conn.auth_mode = WMI_AUTH_WPA2_PSK; 461 conn.auth_mode = WMI_AUTH_WPA2_PSK;
456 conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP; 462 conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP;
@@ -769,7 +775,7 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
769 wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len, 775 wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len,
770 bcon->assocresp_ies); 776 bcon->assocresp_ies);
771 777
772 wil->secure_pcp = info->privacy; 778 wil->privacy = info->privacy;
773 779
774 netif_carrier_on(ndev); 780 netif_carrier_on(ndev);
775 781
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 45c3558ec804..3830cc20d4fa 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -29,6 +29,7 @@
29static u32 mem_addr; 29static u32 mem_addr;
30static u32 dbg_txdesc_index; 30static u32 dbg_txdesc_index;
31static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */ 31static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */
32u32 vring_idle_trsh = 16; /* HW fetches up to 16 descriptors at once */
32 33
33enum dbg_off_type { 34enum dbg_off_type {
34 doff_u32 = 0, 35 doff_u32 = 0,
@@ -102,23 +103,30 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
102 % vring->size; 103 % vring->size;
103 int avail = vring->size - used - 1; 104 int avail = vring->size - used - 1;
104 char name[10]; 105 char name[10];
106 char sidle[10];
105 /* performance monitoring */ 107 /* performance monitoring */
106 cycles_t now = get_cycles(); 108 cycles_t now = get_cycles();
107 uint64_t idle = txdata->idle * 100; 109 uint64_t idle = txdata->idle * 100;
108 uint64_t total = now - txdata->begin; 110 uint64_t total = now - txdata->begin;
109 111
110 do_div(idle, total); 112 if (total != 0) {
113 do_div(idle, total);
114 snprintf(sidle, sizeof(sidle), "%3d%%",
115 (int)idle);
116 } else {
117 snprintf(sidle, sizeof(sidle), "N/A");
118 }
111 txdata->begin = now; 119 txdata->begin = now;
112 txdata->idle = 0ULL; 120 txdata->idle = 0ULL;
113 121
114 snprintf(name, sizeof(name), "tx_%2d", i); 122 snprintf(name, sizeof(name), "tx_%2d", i);
115 123
116 seq_printf(s, 124 seq_printf(s,
117 "\n%pM CID %d TID %d BACK([%d] %d TU A%s) [%3d|%3d] idle %3d%%\n", 125 "\n%pM CID %d TID %d BACK([%d] %d TU A%s) [%3d|%3d] idle %s\n",
118 wil->sta[cid].addr, cid, tid, 126 wil->sta[cid].addr, cid, tid,
119 txdata->agg_wsize, txdata->agg_timeout, 127 txdata->agg_wsize, txdata->agg_timeout,
120 txdata->agg_amsdu ? "+" : "-", 128 txdata->agg_amsdu ? "+" : "-",
121 used, avail, (int)idle); 129 used, avail, sidle);
122 130
123 wil_print_vring(s, wil, name, vring, '_', 'H'); 131 wil_print_vring(s, wil, name, vring, '_', 'H');
124 } 132 }
@@ -549,7 +557,7 @@ static ssize_t wil_write_file_reset(struct file *file, const char __user *buf,
549 dev_close(ndev); 557 dev_close(ndev);
550 ndev->flags &= ~IFF_UP; 558 ndev->flags &= ~IFF_UP;
551 rtnl_unlock(); 559 rtnl_unlock();
552 wil_reset(wil); 560 wil_reset(wil, true);
553 561
554 return len; 562 return len;
555} 563}
@@ -618,7 +626,7 @@ static ssize_t wil_write_back(struct file *file, const char __user *buf,
618 struct wil6210_priv *wil = file->private_data; 626 struct wil6210_priv *wil = file->private_data;
619 int rc; 627 int rc;
620 char *kbuf = kmalloc(len + 1, GFP_KERNEL); 628 char *kbuf = kmalloc(len + 1, GFP_KERNEL);
621 char cmd[8]; 629 char cmd[9];
622 int p1, p2, p3; 630 int p1, p2, p3;
623 631
624 if (!kbuf) 632 if (!kbuf)
@@ -1392,7 +1400,7 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,
1392 1400
1393/* fields in struct wil6210_priv */ 1401/* fields in struct wil6210_priv */
1394static const struct dbg_off dbg_wil_off[] = { 1402static const struct dbg_off dbg_wil_off[] = {
1395 WIL_FIELD(secure_pcp, S_IRUGO | S_IWUSR, doff_u32), 1403 WIL_FIELD(privacy, S_IRUGO, doff_u32),
1396 WIL_FIELD(status[0], S_IRUGO | S_IWUSR, doff_ulong), 1404 WIL_FIELD(status[0], S_IRUGO | S_IWUSR, doff_ulong),
1397 WIL_FIELD(fw_version, S_IRUGO, doff_u32), 1405 WIL_FIELD(fw_version, S_IRUGO, doff_u32),
1398 WIL_FIELD(hw_version, S_IRUGO, doff_x32), 1406 WIL_FIELD(hw_version, S_IRUGO, doff_x32),
@@ -1412,6 +1420,8 @@ static const struct dbg_off dbg_statics[] = {
1412 {"desc_index", S_IRUGO | S_IWUSR, (ulong)&dbg_txdesc_index, doff_u32}, 1420 {"desc_index", S_IRUGO | S_IWUSR, (ulong)&dbg_txdesc_index, doff_u32},
1413 {"vring_index", S_IRUGO | S_IWUSR, (ulong)&dbg_vring_index, doff_u32}, 1421 {"vring_index", S_IRUGO | S_IWUSR, (ulong)&dbg_vring_index, doff_u32},
1414 {"mem_addr", S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32}, 1422 {"mem_addr", S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32},
1423 {"vring_idle_trsh", S_IRUGO | S_IWUSR, (ulong)&vring_idle_trsh,
1424 doff_u32},
1415 {}, 1425 {},
1416}; 1426};
1417 1427
diff --git a/drivers/net/wireless/ath/wil6210/ethtool.c b/drivers/net/wireless/ath/wil6210/ethtool.c
index 4c44a82c34d7..0ea695ff98ad 100644
--- a/drivers/net/wireless/ath/wil6210/ethtool.c
+++ b/drivers/net/wireless/ath/wil6210/ethtool.c
@@ -50,27 +50,19 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev,
50 50
51 wil_dbg_misc(wil, "%s()\n", __func__); 51 wil_dbg_misc(wil, "%s()\n", __func__);
52 52
53 if (test_bit(hw_capability_advanced_itr_moderation, 53 tx_itr_en = ioread32(wil->csr +
54 wil->hw_capabilities)) { 54 HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL));
55 tx_itr_en = ioread32(wil->csr + 55 if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN)
56 HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL)); 56 tx_itr_val =
57 if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN) 57 ioread32(wil->csr +
58 tx_itr_val = 58 HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH));
59 ioread32(wil->csr + 59
60 HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH)); 60 rx_itr_en = ioread32(wil->csr +
61 61 HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL));
62 rx_itr_en = ioread32(wil->csr + 62 if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN)
63 HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL)); 63 rx_itr_val =
64 if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN) 64 ioread32(wil->csr +
65 rx_itr_val = 65 HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH));
66 ioread32(wil->csr +
67 HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH));
68 } else {
69 rx_itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL));
70 if (rx_itr_en & BIT_DMA_ITR_CNT_CRL_EN)
71 rx_itr_val = ioread32(wil->csr +
72 HOSTADDR(RGF_DMA_ITR_CNT_TRSH));
73 }
74 66
75 cp->tx_coalesce_usecs = tx_itr_val; 67 cp->tx_coalesce_usecs = tx_itr_val;
76 cp->rx_coalesce_usecs = rx_itr_val; 68 cp->rx_coalesce_usecs = rx_itr_val;
diff --git a/drivers/net/wireless/ath/wil6210/fw.c b/drivers/net/wireless/ath/wil6210/fw.c
index 93c5cc16c515..4428345e5a47 100644
--- a/drivers/net/wireless/ath/wil6210/fw.c
+++ b/drivers/net/wireless/ath/wil6210/fw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -20,6 +20,7 @@
20#include "fw.h" 20#include "fw.h"
21 21
22MODULE_FIRMWARE(WIL_FW_NAME); 22MODULE_FIRMWARE(WIL_FW_NAME);
23MODULE_FIRMWARE(WIL_FW2_NAME);
23 24
24/* target operations */ 25/* target operations */
25/* register read */ 26/* register read */
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c
index d4acf93a9a02..157f5ef384e0 100644
--- a/drivers/net/wireless/ath/wil6210/fw_inc.c
+++ b/drivers/net/wireless/ath/wil6210/fw_inc.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -451,8 +451,6 @@ static int wil_fw_load(struct wil6210_priv *wil, const void *data, size_t size)
451 } 451 }
452 return -EINVAL; 452 return -EINVAL;
453 } 453 }
454 /* Mark FW as loaded from host */
455 S(RGF_USER_USAGE_6, 1);
456 454
457 return rc; 455 return rc;
458} 456}
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index a6f923086f31..28ffc18466c4 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -166,9 +166,16 @@ void wil_unmask_irq(struct wil6210_priv *wil)
166/* target write operation */ 166/* target write operation */
167#define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0) 167#define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0)
168 168
169static 169void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
170void wil_configure_interrupt_moderation_new(struct wil6210_priv *wil)
171{ 170{
171 wil_dbg_irq(wil, "%s()\n", __func__);
172
173 /* disable interrupt moderation for monitor
174 * to get better timestamp precision
175 */
176 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR)
177 return;
178
172 /* Disable and clear tx counter before (re)configuration */ 179 /* Disable and clear tx counter before (re)configuration */
173 W(RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_CLR); 180 W(RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_CLR);
174 W(RGF_DMA_ITR_TX_CNT_TRSH, wil->tx_max_burst_duration); 181 W(RGF_DMA_ITR_TX_CNT_TRSH, wil->tx_max_burst_duration);
@@ -206,42 +213,8 @@ void wil_configure_interrupt_moderation_new(struct wil6210_priv *wil)
206 BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL); 213 BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL);
207} 214}
208 215
209static
210void wil_configure_interrupt_moderation_lgc(struct wil6210_priv *wil)
211{
212 /* disable, use usec resolution */
213 W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_CLR);
214
215 wil_info(wil, "set ITR_TRSH = %d usec\n", wil->rx_max_burst_duration);
216 W(RGF_DMA_ITR_CNT_TRSH, wil->rx_max_burst_duration);
217 /* start it */
218 W(RGF_DMA_ITR_CNT_CRL,
219 BIT_DMA_ITR_CNT_CRL_EN | BIT_DMA_ITR_CNT_CRL_EXT_TICK);
220}
221
222#undef W 216#undef W
223 217
224void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
225{
226 wil_dbg_irq(wil, "%s()\n", __func__);
227
228 /* disable interrupt moderation for monitor
229 * to get better timestamp precision
230 */
231 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR)
232 return;
233
234 if (test_bit(hw_capability_advanced_itr_moderation,
235 wil->hw_capabilities))
236 wil_configure_interrupt_moderation_new(wil);
237 else {
238 /* Advanced interrupt moderation is not available before
239 * Sparrow v2. Will use legacy interrupt moderation
240 */
241 wil_configure_interrupt_moderation_lgc(wil);
242 }
243}
244
245static irqreturn_t wil6210_irq_rx(int irq, void *cookie) 218static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
246{ 219{
247 struct wil6210_priv *wil = cookie; 220 struct wil6210_priv *wil = cookie;
@@ -253,7 +226,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
253 trace_wil6210_irq_rx(isr); 226 trace_wil6210_irq_rx(isr);
254 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); 227 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr);
255 228
256 if (!isr) { 229 if (unlikely(!isr)) {
257 wil_err(wil, "spurious IRQ: RX\n"); 230 wil_err(wil, "spurious IRQ: RX\n");
258 return IRQ_NONE; 231 return IRQ_NONE;
259 } 232 }
@@ -266,17 +239,18 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
266 * action is always the same - should empty the accumulated 239 * action is always the same - should empty the accumulated
267 * packets from the RX ring. 240 * packets from the RX ring.
268 */ 241 */
269 if (isr & (BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH)) { 242 if (likely(isr & (BIT_DMA_EP_RX_ICR_RX_DONE |
243 BIT_DMA_EP_RX_ICR_RX_HTRSH))) {
270 wil_dbg_irq(wil, "RX done\n"); 244 wil_dbg_irq(wil, "RX done\n");
271 245
272 if (isr & BIT_DMA_EP_RX_ICR_RX_HTRSH) 246 if (unlikely(isr & BIT_DMA_EP_RX_ICR_RX_HTRSH))
273 wil_err_ratelimited(wil, 247 wil_err_ratelimited(wil,
274 "Received \"Rx buffer is in risk of overflow\" interrupt\n"); 248 "Received \"Rx buffer is in risk of overflow\" interrupt\n");
275 249
276 isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE | 250 isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE |
277 BIT_DMA_EP_RX_ICR_RX_HTRSH); 251 BIT_DMA_EP_RX_ICR_RX_HTRSH);
278 if (test_bit(wil_status_reset_done, wil->status)) { 252 if (likely(test_bit(wil_status_reset_done, wil->status))) {
279 if (test_bit(wil_status_napi_en, wil->status)) { 253 if (likely(test_bit(wil_status_napi_en, wil->status))) {
280 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); 254 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n");
281 need_unmask = false; 255 need_unmask = false;
282 napi_schedule(&wil->napi_rx); 256 napi_schedule(&wil->napi_rx);
@@ -289,7 +263,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
289 } 263 }
290 } 264 }
291 265
292 if (isr) 266 if (unlikely(isr))
293 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); 267 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr);
294 268
295 /* Rx IRQ will be enabled when NAPI processing finished */ 269 /* Rx IRQ will be enabled when NAPI processing finished */
@@ -313,19 +287,19 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
313 trace_wil6210_irq_tx(isr); 287 trace_wil6210_irq_tx(isr);
314 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); 288 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr);
315 289
316 if (!isr) { 290 if (unlikely(!isr)) {
317 wil_err(wil, "spurious IRQ: TX\n"); 291 wil_err(wil, "spurious IRQ: TX\n");
318 return IRQ_NONE; 292 return IRQ_NONE;
319 } 293 }
320 294
321 wil6210_mask_irq_tx(wil); 295 wil6210_mask_irq_tx(wil);
322 296
323 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) { 297 if (likely(isr & BIT_DMA_EP_TX_ICR_TX_DONE)) {
324 wil_dbg_irq(wil, "TX done\n"); 298 wil_dbg_irq(wil, "TX done\n");
325 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; 299 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
326 /* clear also all VRING interrupts */ 300 /* clear also all VRING interrupts */
327 isr &= ~(BIT(25) - 1UL); 301 isr &= ~(BIT(25) - 1UL);
328 if (test_bit(wil_status_reset_done, wil->status)) { 302 if (likely(test_bit(wil_status_reset_done, wil->status))) {
329 wil_dbg_txrx(wil, "NAPI(Tx) schedule\n"); 303 wil_dbg_txrx(wil, "NAPI(Tx) schedule\n");
330 need_unmask = false; 304 need_unmask = false;
331 napi_schedule(&wil->napi_tx); 305 napi_schedule(&wil->napi_tx);
@@ -334,7 +308,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
334 } 308 }
335 } 309 }
336 310
337 if (isr) 311 if (unlikely(isr))
338 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr); 312 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr);
339 313
340 /* Tx IRQ will be enabled when NAPI processing finished */ 314 /* Tx IRQ will be enabled when NAPI processing finished */
@@ -523,11 +497,11 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
523 /** 497 /**
524 * pseudo_cause is Clear-On-Read, no need to ACK 498 * pseudo_cause is Clear-On-Read, no need to ACK
525 */ 499 */
526 if ((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff)) 500 if (unlikely((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff)))
527 return IRQ_NONE; 501 return IRQ_NONE;
528 502
529 /* FIXME: IRQ mask debug */ 503 /* FIXME: IRQ mask debug */
530 if (wil6210_debug_irq_mask(wil, pseudo_cause)) 504 if (unlikely(wil6210_debug_irq_mask(wil, pseudo_cause)))
531 return IRQ_NONE; 505 return IRQ_NONE;
532 506
533 trace_wil6210_irq_pseudo(pseudo_cause); 507 trace_wil6210_irq_pseudo(pseudo_cause);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index b04e0afdcb21..db74e811f5c4 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -29,10 +29,6 @@ bool no_fw_recovery;
29module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); 29module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR);
30MODULE_PARM_DESC(no_fw_recovery, " disable automatic FW error recovery"); 30MODULE_PARM_DESC(no_fw_recovery, " disable automatic FW error recovery");
31 31
32static bool no_fw_load = true;
33module_param(no_fw_load, bool, S_IRUGO | S_IWUSR);
34MODULE_PARM_DESC(no_fw_load, " do not download FW, use one in on-card flash.");
35
36/* if not set via modparam, will be set to default value of 1/8 of 32/* if not set via modparam, will be set to default value of 1/8 of
37 * rx ring size during init flow 33 * rx ring size during init flow
38 */ 34 */
@@ -520,8 +516,6 @@ static int wil_target_reset(struct wil6210_priv *wil)
520{ 516{
521 int delay = 0; 517 int delay = 0;
522 u32 x; 518 u32 x;
523 bool is_reset_v2 = test_bit(hw_capability_reset_v2,
524 wil->hw_capabilities);
525 519
526 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->hw_name); 520 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->hw_name);
527 521
@@ -532,82 +526,67 @@ static int wil_target_reset(struct wil6210_priv *wil)
532 526
533 wil_halt_cpu(wil); 527 wil_halt_cpu(wil);
534 528
529 /* clear all boot loader "ready" bits */
530 W(RGF_USER_BL + offsetof(struct RGF_BL, ready), 0);
535 /* Clear Fw Download notification */ 531 /* Clear Fw Download notification */
536 C(RGF_USER_USAGE_6, BIT(0)); 532 C(RGF_USER_USAGE_6, BIT(0));
537 533
538 if (is_reset_v2) { 534 S(RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN);
539 S(RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN); 535 /* XTAL stabilization should take about 3ms */
540 /* XTAL stabilization should take about 3ms */ 536 usleep_range(5000, 7000);
541 usleep_range(5000, 7000); 537 x = R(RGF_CAF_PLL_LOCK_STATUS);
542 x = R(RGF_CAF_PLL_LOCK_STATUS); 538 if (!(x & BIT_CAF_OSC_DIG_XTAL_STABLE)) {
543 if (!(x & BIT_CAF_OSC_DIG_XTAL_STABLE)) { 539 wil_err(wil, "Xtal stabilization timeout\n"
544 wil_err(wil, "Xtal stabilization timeout\n" 540 "RGF_CAF_PLL_LOCK_STATUS = 0x%08x\n", x);
545 "RGF_CAF_PLL_LOCK_STATUS = 0x%08x\n", x); 541 return -ETIME;
546 return -ETIME;
547 }
548 /* switch 10k to XTAL*/
549 C(RGF_USER_SPARROW_M_4, BIT_SPARROW_M_4_SEL_SLEEP_OR_REF);
550 /* 40 MHz */
551 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL);
552
553 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f);
554 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0xf);
555 } 542 }
543 /* switch 10k to XTAL*/
544 C(RGF_USER_SPARROW_M_4, BIT_SPARROW_M_4_SEL_SLEEP_OR_REF);
545 /* 40 MHz */
546 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL);
547
548 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f);
549 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0xf);
556 550
557 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 551 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
558 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 552 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
559 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 553 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x000000f0);
560 is_reset_v2 ? 0x000000f0 : 0x00000170);
561 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00); 554 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00);
562 555
563 if (is_reset_v2) { 556 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0);
564 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0); 557 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0);
565 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0);
566 }
567 558
568 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); 559 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
569 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); 560 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
570 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 561 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
571 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 562 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
572 563
573 if (is_reset_v2) { 564 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003);
574 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003); 565 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); /* reset A2 PCIE AHB */
575 /* reset A2 PCIE AHB */
576 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
577 } else {
578 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
579 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
580 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
581 }
582 566
583 /* TODO: check order here!!! Erez code is different */
584 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 567 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
585 568
586 /* wait until device ready. typical time is 200..250 msec */ 569 /* wait until device ready. typical time is 20..80 msec */
587 do { 570 do {
588 msleep(RST_DELAY); 571 msleep(RST_DELAY);
589 x = R(RGF_USER_HW_MACHINE_STATE); 572 x = R(RGF_USER_BL + offsetof(struct RGF_BL, ready));
590 if (delay++ > RST_COUNT) { 573 if (delay++ > RST_COUNT) {
591 wil_err(wil, "Reset not completed, hw_state 0x%08x\n", 574 wil_err(wil, "Reset not completed, bl.ready 0x%08x\n",
592 x); 575 x);
593 return -ETIME; 576 return -ETIME;
594 } 577 }
595 } while (x != HW_MACHINE_BOOT_DONE); 578 } while (!(x & BIT_BL_READY));
596
597 if (!is_reset_v2)
598 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8));
599 579
600 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); 580 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
601 581
582 /* enable fix for HW bug related to the SA/DA swap in AP Rx */
583 S(RGF_DMA_OFUL_NID_0, BIT_DMA_OFUL_NID_0_RX_EXT_TR_EN |
584 BIT_DMA_OFUL_NID_0_RX_EXT_A3_SRC);
585
602 wil_dbg_misc(wil, "Reset completed in %d ms\n", delay * RST_DELAY); 586 wil_dbg_misc(wil, "Reset completed in %d ms\n", delay * RST_DELAY);
603 return 0; 587 return 0;
604} 588}
605 589
606#undef R
607#undef W
608#undef S
609#undef C
610
611void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) 590void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
612{ 591{
613 le32_to_cpus(&r->base); 592 le32_to_cpus(&r->base);
@@ -617,6 +596,32 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
617 le32_to_cpus(&r->head); 596 le32_to_cpus(&r->head);
618} 597}
619 598
599static int wil_get_bl_info(struct wil6210_priv *wil)
600{
601 struct net_device *ndev = wil_to_ndev(wil);
602 struct RGF_BL bl;
603
604 wil_memcpy_fromio_32(&bl, wil->csr + HOSTADDR(RGF_USER_BL), sizeof(bl));
605 le32_to_cpus(&bl.ready);
606 le32_to_cpus(&bl.version);
607 le32_to_cpus(&bl.rf_type);
608 le32_to_cpus(&bl.baseband_type);
609
610 if (!is_valid_ether_addr(bl.mac_address)) {
611 wil_err(wil, "BL: Invalid MAC %pM\n", bl.mac_address);
612 return -EINVAL;
613 }
614
615 ether_addr_copy(ndev->perm_addr, bl.mac_address);
616 if (!is_valid_ether_addr(ndev->dev_addr))
617 ether_addr_copy(ndev->dev_addr, bl.mac_address);
618 wil_info(wil,
619 "Boot Loader: ver = %d MAC = %pM RF = 0x%08x bband = 0x%08x\n",
620 bl.version, bl.mac_address, bl.rf_type, bl.baseband_type);
621
622 return 0;
623}
624
620static int wil_wait_for_fw_ready(struct wil6210_priv *wil) 625static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
621{ 626{
622 ulong to = msecs_to_jiffies(1000); 627 ulong to = msecs_to_jiffies(1000);
@@ -637,7 +642,7 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
637 * After calling this routine, you're expected to reload 642 * After calling this routine, you're expected to reload
638 * the firmware. 643 * the firmware.
639 */ 644 */
640int wil_reset(struct wil6210_priv *wil) 645int wil_reset(struct wil6210_priv *wil, bool load_fw)
641{ 646{
642 int rc; 647 int rc;
643 648
@@ -675,30 +680,36 @@ int wil_reset(struct wil6210_priv *wil)
675 if (rc) 680 if (rc)
676 return rc; 681 return rc;
677 682
678 if (!no_fw_load) { 683 rc = wil_get_bl_info(wil);
679 wil_info(wil, "Use firmware <%s>\n", WIL_FW_NAME); 684 if (rc)
685 return rc;
686
687 if (load_fw) {
688 wil_info(wil, "Use firmware <%s> + board <%s>\n", WIL_FW_NAME,
689 WIL_FW2_NAME);
690
680 wil_halt_cpu(wil); 691 wil_halt_cpu(wil);
681 /* Loading f/w from the file */ 692 /* Loading f/w from the file */
682 rc = wil_request_firmware(wil, WIL_FW_NAME); 693 rc = wil_request_firmware(wil, WIL_FW_NAME);
683 if (rc) 694 if (rc)
684 return rc; 695 return rc;
696 rc = wil_request_firmware(wil, WIL_FW2_NAME);
697 if (rc)
698 return rc;
685 699
686 /* clear any interrupts which on-card-firmware may have set */ 700 /* Mark FW as loaded from host */
701 S(RGF_USER_USAGE_6, 1);
702
703 /* clear any interrupts which on-card-firmware
704 * may have set
705 */
687 wil6210_clear_irq(wil); 706 wil6210_clear_irq(wil);
688 { /* CAF_ICR - clear and mask */ 707 /* CAF_ICR - clear and mask */
689 u32 a = HOSTADDR(RGF_CAF_ICR) + 708 /* it is W1C, clear by writing back same value */
690 offsetof(struct RGF_ICR, ICR); 709 S(RGF_CAF_ICR + offsetof(struct RGF_ICR, ICR), 0);
691 u32 m = HOSTADDR(RGF_CAF_ICR) + 710 W(RGF_CAF_ICR + offsetof(struct RGF_ICR, IMV), ~0);
692 offsetof(struct RGF_ICR, IMV); 711
693 u32 icr = ioread32(wil->csr + a);
694
695 iowrite32(icr, wil->csr + a); /* W1C */
696 iowrite32(~0, wil->csr + m);
697 wmb(); /* wait for completion */
698 }
699 wil_release_cpu(wil); 712 wil_release_cpu(wil);
700 } else {
701 wil_info(wil, "Use firmware from on-card flash\n");
702 } 713 }
703 714
704 /* init after reset */ 715 /* init after reset */
@@ -706,15 +717,22 @@ int wil_reset(struct wil6210_priv *wil)
706 reinit_completion(&wil->wmi_ready); 717 reinit_completion(&wil->wmi_ready);
707 reinit_completion(&wil->wmi_call); 718 reinit_completion(&wil->wmi_call);
708 719
709 wil_configure_interrupt_moderation(wil); 720 if (load_fw) {
710 wil_unmask_irq(wil); 721 wil_configure_interrupt_moderation(wil);
722 wil_unmask_irq(wil);
711 723
712 /* we just started MAC, wait for FW ready */ 724 /* we just started MAC, wait for FW ready */
713 rc = wil_wait_for_fw_ready(wil); 725 rc = wil_wait_for_fw_ready(wil);
726 }
714 727
715 return rc; 728 return rc;
716} 729}
717 730
731#undef R
732#undef W
733#undef S
734#undef C
735
718void wil_fw_error_recovery(struct wil6210_priv *wil) 736void wil_fw_error_recovery(struct wil6210_priv *wil)
719{ 737{
720 wil_dbg_misc(wil, "starting fw error recovery\n"); 738 wil_dbg_misc(wil, "starting fw error recovery\n");
@@ -730,7 +748,7 @@ int __wil_up(struct wil6210_priv *wil)
730 748
731 WARN_ON(!mutex_is_locked(&wil->mutex)); 749 WARN_ON(!mutex_is_locked(&wil->mutex));
732 750
733 rc = wil_reset(wil); 751 rc = wil_reset(wil, true);
734 if (rc) 752 if (rc)
735 return rc; 753 return rc;
736 754
@@ -837,7 +855,7 @@ int __wil_down(struct wil6210_priv *wil)
837 if (!iter) 855 if (!iter)
838 wil_err(wil, "timeout waiting for idle FW/HW\n"); 856 wil_err(wil, "timeout waiting for idle FW/HW\n");
839 857
840 wil_rx_fini(wil); 858 wil_reset(wil, false);
841 859
842 return 0; 860 return 0;
843} 861}
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 3dd26709ccb2..25343cffe229 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -39,18 +39,6 @@ void wil_set_capabilities(struct wil6210_priv *wil)
39 bitmap_zero(wil->hw_capabilities, hw_capability_last); 39 bitmap_zero(wil->hw_capabilities, hw_capability_last);
40 40
41 switch (rev_id) { 41 switch (rev_id) {
42 case JTAG_DEV_ID_MARLON_B0:
43 wil->hw_name = "Marlon B0";
44 wil->hw_version = HW_VER_MARLON_B0;
45 break;
46 case JTAG_DEV_ID_SPARROW_A0:
47 wil->hw_name = "Sparrow A0";
48 wil->hw_version = HW_VER_SPARROW_A0;
49 break;
50 case JTAG_DEV_ID_SPARROW_A1:
51 wil->hw_name = "Sparrow A1";
52 wil->hw_version = HW_VER_SPARROW_A1;
53 break;
54 case JTAG_DEV_ID_SPARROW_B0: 42 case JTAG_DEV_ID_SPARROW_B0:
55 wil->hw_name = "Sparrow B0"; 43 wil->hw_name = "Sparrow B0";
56 wil->hw_version = HW_VER_SPARROW_B0; 44 wil->hw_version = HW_VER_SPARROW_B0;
@@ -62,13 +50,6 @@ void wil_set_capabilities(struct wil6210_priv *wil)
62 } 50 }
63 51
64 wil_info(wil, "Board hardware is %s\n", wil->hw_name); 52 wil_info(wil, "Board hardware is %s\n", wil->hw_name);
65
66 if (wil->hw_version >= HW_VER_SPARROW_A0)
67 set_bit(hw_capability_reset_v2, wil->hw_capabilities);
68
69 if (wil->hw_version >= HW_VER_SPARROW_B0)
70 set_bit(hw_capability_advanced_itr_moderation,
71 wil->hw_capabilities);
72} 53}
73 54
74void wil_disable_irq(struct wil6210_priv *wil) 55void wil_disable_irq(struct wil6210_priv *wil)
@@ -150,7 +131,7 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
150 131
151 /* need reset here to obtain MAC */ 132 /* need reset here to obtain MAC */
152 mutex_lock(&wil->mutex); 133 mutex_lock(&wil->mutex);
153 rc = wil_reset(wil); 134 rc = wil_reset(wil, false);
154 mutex_unlock(&wil->mutex); 135 mutex_unlock(&wil->mutex);
155 if (debug_fw) 136 if (debug_fw)
156 rc = 0; 137 rc = 0;
@@ -305,7 +286,6 @@ static void wil_pcie_remove(struct pci_dev *pdev)
305} 286}
306 287
307static const struct pci_device_id wil6210_pcie_ids[] = { 288static const struct pci_device_id wil6210_pcie_ids[] = {
308 { PCI_DEVICE(0x1ae9, 0x0301) },
309 { PCI_DEVICE(0x1ae9, 0x0310) }, 289 { PCI_DEVICE(0x1ae9, 0x0310) },
310 { PCI_DEVICE(0x1ae9, 0x0302) }, /* same as above, firmware broken */ 290 { PCI_DEVICE(0x1ae9, 0x0302) }, /* same as above, firmware broken */
311 { /* end: all zeroes */ }, 291 { /* end: all zeroes */ },
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 8439f65db259..7f2f560b8638 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -53,34 +53,38 @@ static inline int wil_vring_is_full(struct vring *vring)
53 return wil_vring_next_tail(vring) == vring->swhead; 53 return wil_vring_next_tail(vring) == vring->swhead;
54} 54}
55 55
56/* 56/* Used space in Tx Vring */
57 * Available space in Tx Vring 57static inline int wil_vring_used_tx(struct vring *vring)
58 */
59static inline int wil_vring_avail_tx(struct vring *vring)
60{ 58{
61 u32 swhead = vring->swhead; 59 u32 swhead = vring->swhead;
62 u32 swtail = vring->swtail; 60 u32 swtail = vring->swtail;
63 int used = (vring->size + swhead - swtail) % vring->size; 61 return (vring->size + swhead - swtail) % vring->size;
62}
64 63
65 return vring->size - used - 1; 64/* Available space in Tx Vring */
65static inline int wil_vring_avail_tx(struct vring *vring)
66{
67 return vring->size - wil_vring_used_tx(vring) - 1;
66} 68}
67 69
68/** 70/* wil_vring_wmark_low - low watermark for available descriptor space */
69 * wil_vring_wmark_low - low watermark for available descriptor space
70 */
71static inline int wil_vring_wmark_low(struct vring *vring) 71static inline int wil_vring_wmark_low(struct vring *vring)
72{ 72{
73 return vring->size/8; 73 return vring->size/8;
74} 74}
75 75
76/** 76/* wil_vring_wmark_high - high watermark for available descriptor space */
77 * wil_vring_wmark_high - high watermark for available descriptor space
78 */
79static inline int wil_vring_wmark_high(struct vring *vring) 77static inline int wil_vring_wmark_high(struct vring *vring)
80{ 78{
81 return vring->size/4; 79 return vring->size/4;
82} 80}
83 81
82/* wil_val_in_range - check if value in [min,max) */
83static inline bool wil_val_in_range(int val, int min, int max)
84{
85 return val >= min && val < max;
86}
87
84static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) 88static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
85{ 89{
86 struct device *dev = wil_to_dev(wil); 90 struct device *dev = wil_to_dev(wil);
@@ -98,8 +102,7 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
98 vring->va = NULL; 102 vring->va = NULL;
99 return -ENOMEM; 103 return -ENOMEM;
100 } 104 }
101 /* 105 /* vring->va should be aligned on its size rounded up to power of 2
102 * vring->va should be aligned on its size rounded up to power of 2
103 * This is granted by the dma_alloc_coherent 106 * This is granted by the dma_alloc_coherent
104 */ 107 */
105 vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL); 108 vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL);
@@ -346,27 +349,6 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
346 } 349 }
347} 350}
348 351
349/*
350 * Fast swap in place between 2 registers
351 */
352static void wil_swap_u16(u16 *a, u16 *b)
353{
354 *a ^= *b;
355 *b ^= *a;
356 *a ^= *b;
357}
358
359static void wil_swap_ethaddr(void *data)
360{
361 struct ethhdr *eth = data;
362 u16 *s = (u16 *)eth->h_source;
363 u16 *d = (u16 *)eth->h_dest;
364
365 wil_swap_u16(s++, d++);
366 wil_swap_u16(s++, d++);
367 wil_swap_u16(s, d);
368}
369
370/** 352/**
371 * reap 1 frame from @swhead 353 * reap 1 frame from @swhead
372 * 354 *
@@ -386,17 +368,16 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
386 unsigned int sz = mtu_max + ETH_HLEN; 368 unsigned int sz = mtu_max + ETH_HLEN;
387 u16 dmalen; 369 u16 dmalen;
388 u8 ftype; 370 u8 ftype;
389 u8 ds_bits;
390 int cid; 371 int cid;
391 struct wil_net_stats *stats; 372 struct wil_net_stats *stats;
392 373
393 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); 374 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
394 375
395 if (wil_vring_is_empty(vring)) 376 if (unlikely(wil_vring_is_empty(vring)))
396 return NULL; 377 return NULL;
397 378
398 _d = &vring->va[vring->swhead].rx; 379 _d = &vring->va[vring->swhead].rx;
399 if (!(_d->dma.status & RX_DMA_STATUS_DU)) { 380 if (unlikely(!(_d->dma.status & RX_DMA_STATUS_DU))) {
400 /* it is not error, we just reached end of Rx done area */ 381 /* it is not error, we just reached end of Rx done area */
401 return NULL; 382 return NULL;
402 } 383 }
@@ -416,7 +397,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
416 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4, 397 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
417 (const void *)d, sizeof(*d), false); 398 (const void *)d, sizeof(*d), false);
418 399
419 if (dmalen > sz) { 400 if (unlikely(dmalen > sz)) {
420 wil_err(wil, "Rx size too large: %d bytes!\n", dmalen); 401 wil_err(wil, "Rx size too large: %d bytes!\n", dmalen);
421 kfree_skb(skb); 402 kfree_skb(skb);
422 return NULL; 403 return NULL;
@@ -445,14 +426,14 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
445 * in Rx descriptor. If type is not data, it is 802.11 frame as is 426 * in Rx descriptor. If type is not data, it is 802.11 frame as is
446 */ 427 */
447 ftype = wil_rxdesc_ftype(d) << 2; 428 ftype = wil_rxdesc_ftype(d) << 2;
448 if (ftype != IEEE80211_FTYPE_DATA) { 429 if (unlikely(ftype != IEEE80211_FTYPE_DATA)) {
449 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype); 430 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
450 /* TODO: process it */ 431 /* TODO: process it */
451 kfree_skb(skb); 432 kfree_skb(skb);
452 return NULL; 433 return NULL;
453 } 434 }
454 435
455 if (skb->len < ETH_HLEN) { 436 if (unlikely(skb->len < ETH_HLEN)) {
456 wil_err(wil, "Short frame, len = %d\n", skb->len); 437 wil_err(wil, "Short frame, len = %d\n", skb->len);
457 /* TODO: process it (i.e. BAR) */ 438 /* TODO: process it (i.e. BAR) */
458 kfree_skb(skb); 439 kfree_skb(skb);
@@ -463,9 +444,9 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
463 * and in case of error drop the packet 444 * and in case of error drop the packet
464 * higher stack layers will handle retransmission (if required) 445 * higher stack layers will handle retransmission (if required)
465 */ 446 */
466 if (d->dma.status & RX_DMA_STATUS_L4I) { 447 if (likely(d->dma.status & RX_DMA_STATUS_L4I)) {
467 /* L4 protocol identified, csum calculated */ 448 /* L4 protocol identified, csum calculated */
468 if ((d->dma.error & RX_DMA_ERROR_L4_ERR) == 0) 449 if (likely((d->dma.error & RX_DMA_ERROR_L4_ERR) == 0))
469 skb->ip_summed = CHECKSUM_UNNECESSARY; 450 skb->ip_summed = CHECKSUM_UNNECESSARY;
470 /* If HW reports bad checksum, let IP stack re-check it 451 /* If HW reports bad checksum, let IP stack re-check it
471 * For example, HW don't understand Microsoft IP stack that 452 * For example, HW don't understand Microsoft IP stack that
@@ -474,15 +455,6 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
474 */ 455 */
475 } 456 }
476 457
477 ds_bits = wil_rxdesc_ds_bits(d);
478 if (ds_bits == 1) {
479 /*
480 * HW bug - in ToDS mode, i.e. Rx on AP side,
481 * addresses get swapped
482 */
483 wil_swap_ethaddr(skb->data);
484 }
485
486 return skb; 458 return skb;
487} 459}
488 460
@@ -503,7 +475,7 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count)
503 (next_tail != v->swhead) && (count-- > 0); 475 (next_tail != v->swhead) && (count-- > 0);
504 v->swtail = next_tail) { 476 v->swtail = next_tail) {
505 rc = wil_vring_alloc_skb(wil, v, v->swtail, headroom); 477 rc = wil_vring_alloc_skb(wil, v, v->swtail, headroom);
506 if (rc) { 478 if (unlikely(rc)) {
507 wil_err(wil, "Error %d in wil_rx_refill[%d]\n", 479 wil_err(wil, "Error %d in wil_rx_refill[%d]\n",
508 rc, v->swtail); 480 rc, v->swtail);
509 break; 481 break;
@@ -565,7 +537,7 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota)
565 struct vring *v = &wil->vring_rx; 537 struct vring *v = &wil->vring_rx;
566 struct sk_buff *skb; 538 struct sk_buff *skb;
567 539
568 if (!v->va) { 540 if (unlikely(!v->va)) {
569 wil_err(wil, "Rx IRQ while Rx not yet initialized\n"); 541 wil_err(wil, "Rx IRQ while Rx not yet initialized\n");
570 return; 542 return;
571 } 543 }
@@ -952,13 +924,14 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
952 struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index]; 924 struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index];
953 uint i = swhead; 925 uint i = swhead;
954 dma_addr_t pa; 926 dma_addr_t pa;
927 int used;
955 928
956 wil_dbg_txrx(wil, "%s()\n", __func__); 929 wil_dbg_txrx(wil, "%s()\n", __func__);
957 930
958 if (unlikely(!txdata->enabled)) 931 if (unlikely(!txdata->enabled))
959 return -EINVAL; 932 return -EINVAL;
960 933
961 if (avail < 1 + nr_frags) { 934 if (unlikely(avail < 1 + nr_frags)) {
962 wil_err_ratelimited(wil, 935 wil_err_ratelimited(wil,
963 "Tx ring[%2d] full. No space for %d fragments\n", 936 "Tx ring[%2d] full. No space for %d fragments\n",
964 vring_index, 1 + nr_frags); 937 vring_index, 1 + nr_frags);
@@ -979,7 +952,7 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
979 /* 1-st segment */ 952 /* 1-st segment */
980 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); 953 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index);
981 /* Process TCP/UDP checksum offloading */ 954 /* Process TCP/UDP checksum offloading */
982 if (wil_tx_desc_offload_cksum_set(wil, d, skb)) { 955 if (unlikely(wil_tx_desc_offload_cksum_set(wil, d, skb))) {
983 wil_err(wil, "Tx[%2d] Failed to set cksum, drop packet\n", 956 wil_err(wil, "Tx[%2d] Failed to set cksum, drop packet\n",
984 vring_index); 957 vring_index);
985 goto dma_error; 958 goto dma_error;
@@ -1027,8 +1000,14 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1027 */ 1000 */
1028 vring->ctx[i].skb = skb_get(skb); 1001 vring->ctx[i].skb = skb_get(skb);
1029 1002
1030 if (wil_vring_is_empty(vring)) /* performance monitoring */ 1003 /* performance monitoring */
1004 used = wil_vring_used_tx(vring);
1005 if (wil_val_in_range(vring_idle_trsh,
1006 used, used + nr_frags + 1)) {
1031 txdata->idle += get_cycles() - txdata->last_idle; 1007 txdata->idle += get_cycles() - txdata->last_idle;
1008 wil_dbg_txrx(wil, "Ring[%2d] not idle %d -> %d\n",
1009 vring_index, used, used + nr_frags + 1);
1010 }
1032 1011
1033 /* advance swhead */ 1012 /* advance swhead */
1034 wil_vring_advance_head(vring, nr_frags + 1); 1013 wil_vring_advance_head(vring, nr_frags + 1);
@@ -1082,18 +1061,18 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1082 int rc; 1061 int rc;
1083 1062
1084 wil_dbg_txrx(wil, "%s()\n", __func__); 1063 wil_dbg_txrx(wil, "%s()\n", __func__);
1085 if (!test_bit(wil_status_fwready, wil->status)) { 1064 if (unlikely(!test_bit(wil_status_fwready, wil->status))) {
1086 if (!pr_once_fw) { 1065 if (!pr_once_fw) {
1087 wil_err(wil, "FW not ready\n"); 1066 wil_err(wil, "FW not ready\n");
1088 pr_once_fw = true; 1067 pr_once_fw = true;
1089 } 1068 }
1090 goto drop; 1069 goto drop;
1091 } 1070 }
1092 if (!test_bit(wil_status_fwconnected, wil->status)) { 1071 if (unlikely(!test_bit(wil_status_fwconnected, wil->status))) {
1093 wil_err(wil, "FW not connected\n"); 1072 wil_err(wil, "FW not connected\n");
1094 goto drop; 1073 goto drop;
1095 } 1074 }
1096 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { 1075 if (unlikely(wil->wdev->iftype == NL80211_IFTYPE_MONITOR)) {
1097 wil_err(wil, "Xmit in monitor mode not supported\n"); 1076 wil_err(wil, "Xmit in monitor mode not supported\n");
1098 goto drop; 1077 goto drop;
1099 } 1078 }
@@ -1109,7 +1088,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1109 else 1088 else
1110 vring = wil_tx_bcast(wil, skb); 1089 vring = wil_tx_bcast(wil, skb);
1111 } 1090 }
1112 if (!vring) { 1091 if (unlikely(!vring)) {
1113 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); 1092 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
1114 goto drop; 1093 goto drop;
1115 } 1094 }
@@ -1117,7 +1096,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1117 rc = wil_tx_vring(wil, vring, skb); 1096 rc = wil_tx_vring(wil, vring, skb);
1118 1097
1119 /* do we still have enough room in the vring? */ 1098 /* do we still have enough room in the vring? */
1120 if (wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring)) { 1099 if (unlikely(wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring))) {
1121 netif_tx_stop_all_queues(wil_to_ndev(wil)); 1100 netif_tx_stop_all_queues(wil_to_ndev(wil));
1122 wil_dbg_txrx(wil, "netif_tx_stop : ring full\n"); 1101 wil_dbg_txrx(wil, "netif_tx_stop : ring full\n");
1123 } 1102 }
@@ -1172,19 +1151,23 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1172 int cid = wil->vring2cid_tid[ringid][0]; 1151 int cid = wil->vring2cid_tid[ringid][0];
1173 struct wil_net_stats *stats = &wil->sta[cid].stats; 1152 struct wil_net_stats *stats = &wil->sta[cid].stats;
1174 volatile struct vring_tx_desc *_d; 1153 volatile struct vring_tx_desc *_d;
1154 int used_before_complete;
1155 int used_new;
1175 1156
1176 if (!vring->va) { 1157 if (unlikely(!vring->va)) {
1177 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); 1158 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid);
1178 return 0; 1159 return 0;
1179 } 1160 }
1180 1161
1181 if (!txdata->enabled) { 1162 if (unlikely(!txdata->enabled)) {
1182 wil_info(wil, "Tx irq[%d]: vring disabled\n", ringid); 1163 wil_info(wil, "Tx irq[%d]: vring disabled\n", ringid);
1183 return 0; 1164 return 0;
1184 } 1165 }
1185 1166
1186 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); 1167 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
1187 1168
1169 used_before_complete = wil_vring_used_tx(vring);
1170
1188 while (!wil_vring_is_empty(vring)) { 1171 while (!wil_vring_is_empty(vring)) {
1189 int new_swtail; 1172 int new_swtail;
1190 struct wil_ctx *ctx = &vring->ctx[vring->swtail]; 1173 struct wil_ctx *ctx = &vring->ctx[vring->swtail];
@@ -1196,7 +1179,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1196 /* TODO: check we are not past head */ 1179 /* TODO: check we are not past head */
1197 1180
1198 _d = &vring->va[lf].tx; 1181 _d = &vring->va[lf].tx;
1199 if (!(_d->dma.status & TX_DMA_STATUS_DU)) 1182 if (unlikely(!(_d->dma.status & TX_DMA_STATUS_DU)))
1200 break; 1183 break;
1201 1184
1202 new_swtail = (lf + 1) % vring->size; 1185 new_swtail = (lf + 1) % vring->size;
@@ -1224,7 +1207,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1224 wil_txdesc_unmap(dev, d, ctx); 1207 wil_txdesc_unmap(dev, d, ctx);
1225 1208
1226 if (skb) { 1209 if (skb) {
1227 if (d->dma.error == 0) { 1210 if (likely(d->dma.error == 0)) {
1228 ndev->stats.tx_packets++; 1211 ndev->stats.tx_packets++;
1229 stats->tx_packets++; 1212 stats->tx_packets++;
1230 ndev->stats.tx_bytes += skb->len; 1213 ndev->stats.tx_bytes += skb->len;
@@ -1246,8 +1229,12 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1246 } 1229 }
1247 } 1230 }
1248 1231
1249 if (wil_vring_is_empty(vring)) { /* performance monitoring */ 1232 /* performance monitoring */
1250 wil_dbg_txrx(wil, "Ring[%2d] empty\n", ringid); 1233 used_new = wil_vring_used_tx(vring);
1234 if (wil_val_in_range(vring_idle_trsh,
1235 used_new, used_before_complete)) {
1236 wil_dbg_txrx(wil, "Ring[%2d] idle %d -> %d\n",
1237 ringid, used_before_complete, used_new);
1251 txdata->last_idle = get_cycles(); 1238 txdata->last_idle = get_cycles();
1252 } 1239 }
1253 1240
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 94611568fc9a..b6e65c37d410 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -27,9 +27,11 @@ extern bool no_fw_recovery;
27extern unsigned int mtu_max; 27extern unsigned int mtu_max;
28extern unsigned short rx_ring_overflow_thrsh; 28extern unsigned short rx_ring_overflow_thrsh;
29extern int agg_wsize; 29extern int agg_wsize;
30extern u32 vring_idle_trsh;
30 31
31#define WIL_NAME "wil6210" 32#define WIL_NAME "wil6210"
32#define WIL_FW_NAME "wil6210.fw" 33#define WIL_FW_NAME "wil6210.fw" /* code */
34#define WIL_FW2_NAME "wil6210.board" /* board & radio parameters */
33 35
34#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */ 36#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
35 37
@@ -120,6 +122,16 @@ struct RGF_ICR {
120 u32 IMC; /* Mask Clear, write 1 to clear */ 122 u32 IMC; /* Mask Clear, write 1 to clear */
121} __packed; 123} __packed;
122 124
125struct RGF_BL {
126 u32 ready; /* 0x880A3C bit [0] */
127#define BIT_BL_READY BIT(0)
128 u32 version; /* 0x880A40 version of the BL struct */
129 u32 rf_type; /* 0x880A44 ID of the connected RF */
130 u32 baseband_type; /* 0x880A48 ID of the baseband */
131 u8 mac_address[ETH_ALEN]; /* 0x880A4C permanent MAC */
132 u8 pad[2];
133} __packed;
134
123/* registers - FW addresses */ 135/* registers - FW addresses */
124#define RGF_USER_USAGE_1 (0x880004) 136#define RGF_USER_USAGE_1 (0x880004)
125#define RGF_USER_USAGE_6 (0x880018) 137#define RGF_USER_USAGE_6 (0x880018)
@@ -130,6 +142,7 @@ struct RGF_ICR {
130#define RGF_USER_MAC_CPU_0 (0x8801fc) 142#define RGF_USER_MAC_CPU_0 (0x8801fc)
131 #define BIT_USER_MAC_CPU_MAN_RST BIT(1) /* mac_cpu_man_rst */ 143 #define BIT_USER_MAC_CPU_MAN_RST BIT(1) /* mac_cpu_man_rst */
132#define RGF_USER_USER_SCRATCH_PAD (0x8802bc) 144#define RGF_USER_USER_SCRATCH_PAD (0x8802bc)
145#define RGF_USER_BL (0x880A3C) /* Boot Loader */
133#define RGF_USER_FW_REV_ID (0x880a8c) /* chip revision */ 146#define RGF_USER_FW_REV_ID (0x880a8c) /* chip revision */
134#define RGF_USER_CLKS_CTL_0 (0x880abc) 147#define RGF_USER_CLKS_CTL_0 (0x880abc)
135 #define BIT_USER_CLKS_CAR_AHB_SW_SEL BIT(1) /* ref clk/PLL */ 148 #define BIT_USER_CLKS_CAR_AHB_SW_SEL BIT(1) /* ref clk/PLL */
@@ -169,6 +182,13 @@ struct RGF_ICR {
169 #define BIT_DMA_ITR_CNT_CRL_CLR BIT(3) 182 #define BIT_DMA_ITR_CNT_CRL_CLR BIT(3)
170 #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH BIT(4) 183 #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH BIT(4)
171 184
185/* Offload control (Sparrow B0+) */
186#define RGF_DMA_OFUL_NID_0 (0x881cd4)
187 #define BIT_DMA_OFUL_NID_0_RX_EXT_TR_EN BIT(0)
188 #define BIT_DMA_OFUL_NID_0_TX_EXT_TR_EN BIT(1)
189 #define BIT_DMA_OFUL_NID_0_RX_EXT_A3_SRC BIT(2)
190 #define BIT_DMA_OFUL_NID_0_TX_EXT_A3_SRC BIT(3)
191
172/* New (sparrow v2+) interrupt moderation control */ 192/* New (sparrow v2+) interrupt moderation control */
173#define RGF_DMA_ITR_TX_DESQ_NO_MOD (0x881d40) 193#define RGF_DMA_ITR_TX_DESQ_NO_MOD (0x881d40)
174#define RGF_DMA_ITR_TX_CNT_TRSH (0x881d34) 194#define RGF_DMA_ITR_TX_CNT_TRSH (0x881d34)
@@ -229,16 +249,10 @@ struct RGF_ICR {
229 #define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0) 249 #define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0)
230 250
231#define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */ 251#define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */
232 #define JTAG_DEV_ID_MARLON_B0 (0x0612072f)
233 #define JTAG_DEV_ID_SPARROW_A0 (0x0632072f)
234 #define JTAG_DEV_ID_SPARROW_A1 (0x1632072f)
235 #define JTAG_DEV_ID_SPARROW_B0 (0x2632072f) 252 #define JTAG_DEV_ID_SPARROW_B0 (0x2632072f)
236 253
237enum { 254enum {
238 HW_VER_UNKNOWN, 255 HW_VER_UNKNOWN,
239 HW_VER_MARLON_B0, /* JTAG_DEV_ID_MARLON_B0 */
240 HW_VER_SPARROW_A0, /* JTAG_DEV_ID_SPARROW_A0 */
241 HW_VER_SPARROW_A1, /* JTAG_DEV_ID_SPARROW_A1 */
242 HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */ 256 HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */
243}; 257};
244 258
@@ -482,8 +496,6 @@ enum {
482}; 496};
483 497
484enum { 498enum {
485 hw_capability_reset_v2 = 0,
486 hw_capability_advanced_itr_moderation = 1,
487 hw_capability_last 499 hw_capability_last
488}; 500};
489 501
@@ -528,7 +540,7 @@ struct wil6210_priv {
528 wait_queue_head_t wq; /* for all wait_event() use */ 540 wait_queue_head_t wq; /* for all wait_event() use */
529 /* profile */ 541 /* profile */
530 u32 monitor_flags; 542 u32 monitor_flags;
531 u32 secure_pcp; /* create secure PCP? */ 543 u32 privacy; /* secure connection? */
532 int sinfo_gen; 544 int sinfo_gen;
533 /* interrupt moderation */ 545 /* interrupt moderation */
534 u32 tx_max_burst_duration; 546 u32 tx_max_burst_duration;
@@ -658,7 +670,7 @@ int wil_if_add(struct wil6210_priv *wil);
658void wil_if_remove(struct wil6210_priv *wil); 670void wil_if_remove(struct wil6210_priv *wil);
659int wil_priv_init(struct wil6210_priv *wil); 671int wil_priv_init(struct wil6210_priv *wil);
660void wil_priv_deinit(struct wil6210_priv *wil); 672void wil_priv_deinit(struct wil6210_priv *wil);
661int wil_reset(struct wil6210_priv *wil); 673int wil_reset(struct wil6210_priv *wil, bool no_fw);
662void wil_fw_error_recovery(struct wil6210_priv *wil); 674void wil_fw_error_recovery(struct wil6210_priv *wil);
663void wil_set_recovery_state(struct wil6210_priv *wil, int state); 675void wil_set_recovery_state(struct wil6210_priv *wil, int state);
664int wil_up(struct wil6210_priv *wil); 676int wil_up(struct wil6210_priv *wil);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 0f3e4334c8e3..021313524913 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -281,7 +281,6 @@ int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
281/*=== Event handlers ===*/ 281/*=== Event handlers ===*/
282static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) 282static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
283{ 283{
284 struct net_device *ndev = wil_to_ndev(wil);
285 struct wireless_dev *wdev = wil->wdev; 284 struct wireless_dev *wdev = wil->wdev;
286 struct wmi_ready_event *evt = d; 285 struct wmi_ready_event *evt = d;
287 286
@@ -290,11 +289,7 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
290 289
291 wil_info(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version, 290 wil_info(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version,
292 evt->mac, wil->n_mids); 291 evt->mac, wil->n_mids);
293 292 /* ignore MAC address, we already have it from the boot loader */
294 if (!is_valid_ether_addr(ndev->dev_addr)) {
295 memcpy(ndev->dev_addr, evt->mac, ETH_ALEN);
296 memcpy(ndev->perm_addr, evt->mac, ETH_ALEN);
297 }
298 snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version), 293 snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version),
299 "%d", wil->fw_version); 294 "%d", wil->fw_version);
300} 295}
@@ -879,7 +874,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
879 struct wmi_pcp_started_event evt; 874 struct wmi_pcp_started_event evt;
880 } __packed reply; 875 } __packed reply;
881 876
882 if (!wil->secure_pcp) 877 if (!wil->privacy)
883 cmd.disable_sec = 1; 878 cmd.disable_sec = 1;
884 879
885 if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) || 880 if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) ||
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 31c7e4d41a9a..ac99798570e8 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4819,7 +4819,7 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4819 switch (dev->dev->bus_type) { 4819 switch (dev->dev->bus_type) {
4820#ifdef CONFIG_B43_BCMA 4820#ifdef CONFIG_B43_BCMA
4821 case B43_BUS_BCMA: 4821 case B43_BUS_BCMA:
4822 bcma_core_pci_down(dev->dev->bdev->bus); 4822 bcma_host_pci_down(dev->dev->bdev->bus);
4823 break; 4823 break;
4824#endif 4824#endif
4825#ifdef CONFIG_B43_SSB 4825#ifdef CONFIG_B43_SSB
@@ -4866,9 +4866,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4866 switch (dev->dev->bus_type) { 4866 switch (dev->dev->bus_type) {
4867#ifdef CONFIG_B43_BCMA 4867#ifdef CONFIG_B43_BCMA
4868 case B43_BUS_BCMA: 4868 case B43_BUS_BCMA:
4869 bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0], 4869 bcma_core_pci_irq_ctl(dev->dev->bdev->bus,
4870 dev->dev->bdev, true); 4870 dev->dev->bdev, true);
4871 bcma_core_pci_up(dev->dev->bdev->bus); 4871 bcma_host_pci_up(dev->dev->bdev->bus);
4872 break; 4872 break;
4873#endif 4873#endif
4874#ifdef CONFIG_B43_SSB 4874#ifdef CONFIG_B43_SSB
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 7944224e3fc9..c438ccdb6ed8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -58,6 +58,14 @@
58#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */ 58#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
59#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */ 59#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
60 60
61struct brcmf_sdiod_freezer {
62 atomic_t freezing;
63 atomic_t thread_count;
64 u32 frozen_count;
65 wait_queue_head_t thread_freeze;
66 struct completion resumed;
67};
68
61static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE; 69static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
62module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0); 70module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
63MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]"); 71MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
@@ -197,6 +205,30 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
197 return 0; 205 return 0;
198} 206}
199 207
208void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
209 enum brcmf_sdiod_state state)
210{
211 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM ||
212 state == sdiodev->state)
213 return;
214
215 brcmf_dbg(TRACE, "%d -> %d\n", sdiodev->state, state);
216 switch (sdiodev->state) {
217 case BRCMF_SDIOD_DATA:
218 /* any other state means bus interface is down */
219 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
220 break;
221 case BRCMF_SDIOD_DOWN:
222 /* transition from DOWN to DATA means bus interface is up */
223 if (state == BRCMF_SDIOD_DATA)
224 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_UP);
225 break;
226 default:
227 break;
228 }
229 sdiodev->state = state;
230}
231
200static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, 232static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
201 uint regaddr, u8 byte) 233 uint regaddr, u8 byte)
202{ 234{
@@ -269,12 +301,6 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
269 return ret; 301 return ret;
270} 302}
271 303
272static void brcmf_sdiod_nomedium_state(struct brcmf_sdio_dev *sdiodev)
273{
274 sdiodev->state = BRCMF_STATE_NOMEDIUM;
275 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
276}
277
278static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, 304static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
279 u8 regsz, void *data, bool write) 305 u8 regsz, void *data, bool write)
280{ 306{
@@ -282,7 +308,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
282 s32 retry = 0; 308 s32 retry = 0;
283 int ret; 309 int ret;
284 310
285 if (sdiodev->state == BRCMF_STATE_NOMEDIUM) 311 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
286 return -ENOMEDIUM; 312 return -ENOMEDIUM;
287 313
288 /* 314 /*
@@ -308,7 +334,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
308 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); 334 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
309 335
310 if (ret == -ENOMEDIUM) 336 if (ret == -ENOMEDIUM)
311 brcmf_sdiod_nomedium_state(sdiodev); 337 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
312 else if (ret != 0) { 338 else if (ret != 0) {
313 /* 339 /*
314 * SleepCSR register access can fail when 340 * SleepCSR register access can fail when
@@ -331,7 +357,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
331 int err = 0, i; 357 int err = 0, i;
332 u8 addr[3]; 358 u8 addr[3];
333 359
334 if (sdiodev->state == BRCMF_STATE_NOMEDIUM) 360 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
335 return -ENOMEDIUM; 361 return -ENOMEDIUM;
336 362
337 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; 363 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
@@ -460,7 +486,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
460 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, 486 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
461 req_sz); 487 req_sz);
462 if (err == -ENOMEDIUM) 488 if (err == -ENOMEDIUM)
463 brcmf_sdiod_nomedium_state(sdiodev); 489 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
464 return err; 490 return err;
465} 491}
466 492
@@ -595,7 +621,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
595 621
596 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; 622 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
597 if (ret == -ENOMEDIUM) { 623 if (ret == -ENOMEDIUM) {
598 brcmf_sdiod_nomedium_state(sdiodev); 624 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
599 break; 625 break;
600 } else if (ret != 0) { 626 } else if (ret != 0) {
601 brcmf_err("CMD53 sg block %s failed %d\n", 627 brcmf_err("CMD53 sg block %s failed %d\n",
@@ -877,6 +903,87 @@ static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
877 sdiodev->txglomsz = brcmf_sdiod_txglomsz; 903 sdiodev->txglomsz = brcmf_sdiod_txglomsz;
878} 904}
879 905
906#ifdef CONFIG_PM_SLEEP
907static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev)
908{
909 sdiodev->freezer = kzalloc(sizeof(*sdiodev->freezer), GFP_KERNEL);
910 if (!sdiodev->freezer)
911 return -ENOMEM;
912 atomic_set(&sdiodev->freezer->thread_count, 0);
913 atomic_set(&sdiodev->freezer->freezing, 0);
914 init_waitqueue_head(&sdiodev->freezer->thread_freeze);
915 init_completion(&sdiodev->freezer->resumed);
916 return 0;
917}
918
919static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
920{
921 if (sdiodev->freezer) {
922 WARN_ON(atomic_read(&sdiodev->freezer->freezing));
923 kfree(sdiodev->freezer);
924 }
925}
926
927static int brcmf_sdiod_freezer_on(struct brcmf_sdio_dev *sdiodev)
928{
929 atomic_t *expect = &sdiodev->freezer->thread_count;
930 int res = 0;
931
932 sdiodev->freezer->frozen_count = 0;
933 reinit_completion(&sdiodev->freezer->resumed);
934 atomic_set(&sdiodev->freezer->freezing, 1);
935 brcmf_sdio_trigger_dpc(sdiodev->bus);
936 wait_event(sdiodev->freezer->thread_freeze,
937 atomic_read(expect) == sdiodev->freezer->frozen_count);
938 sdio_claim_host(sdiodev->func[1]);
939 res = brcmf_sdio_sleep(sdiodev->bus, true);
940 sdio_release_host(sdiodev->func[1]);
941 return res;
942}
943
944static void brcmf_sdiod_freezer_off(struct brcmf_sdio_dev *sdiodev)
945{
946 sdio_claim_host(sdiodev->func[1]);
947 brcmf_sdio_sleep(sdiodev->bus, false);
948 sdio_release_host(sdiodev->func[1]);
949 atomic_set(&sdiodev->freezer->freezing, 0);
950 complete_all(&sdiodev->freezer->resumed);
951}
952
953bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev)
954{
955 return atomic_read(&sdiodev->freezer->freezing);
956}
957
958void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev)
959{
960 if (!brcmf_sdiod_freezing(sdiodev))
961 return;
962 sdiodev->freezer->frozen_count++;
963 wake_up(&sdiodev->freezer->thread_freeze);
964 wait_for_completion(&sdiodev->freezer->resumed);
965}
966
967void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev)
968{
969 atomic_inc(&sdiodev->freezer->thread_count);
970}
971
972void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev)
973{
974 atomic_dec(&sdiodev->freezer->thread_count);
975}
976#else
977static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev)
978{
979 return 0;
980}
981
982static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
983{
984}
985#endif /* CONFIG_PM_SLEEP */
986
880static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) 987static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
881{ 988{
882 if (sdiodev->bus) { 989 if (sdiodev->bus) {
@@ -884,6 +991,8 @@ static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
884 sdiodev->bus = NULL; 991 sdiodev->bus = NULL;
885 } 992 }
886 993
994 brcmf_sdiod_freezer_detach(sdiodev);
995
887 /* Disable Function 2 */ 996 /* Disable Function 2 */
888 sdio_claim_host(sdiodev->func[2]); 997 sdio_claim_host(sdiodev->func[2]);
889 sdio_disable_func(sdiodev->func[2]); 998 sdio_disable_func(sdiodev->func[2]);
@@ -955,6 +1064,10 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
955 */ 1064 */
956 brcmf_sdiod_sgtable_alloc(sdiodev); 1065 brcmf_sdiod_sgtable_alloc(sdiodev);
957 1066
1067 ret = brcmf_sdiod_freezer_attach(sdiodev);
1068 if (ret)
1069 goto out;
1070
958 /* try to attach to the target device */ 1071 /* try to attach to the target device */
959 sdiodev->bus = brcmf_sdio_probe(sdiodev); 1072 sdiodev->bus = brcmf_sdio_probe(sdiodev);
960 if (!sdiodev->bus) { 1073 if (!sdiodev->bus) {
@@ -1050,9 +1163,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
1050 bus_if->wowl_supported = true; 1163 bus_if->wowl_supported = true;
1051#endif 1164#endif
1052 1165
1053 sdiodev->sleeping = false; 1166 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
1054 atomic_set(&sdiodev->suspend, false);
1055 init_waitqueue_head(&sdiodev->idle_wait);
1056 1167
1057 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n"); 1168 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n");
1058 err = brcmf_sdiod_probe(sdiodev); 1169 err = brcmf_sdiod_probe(sdiodev);
@@ -1114,24 +1225,22 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
1114#ifdef CONFIG_PM_SLEEP 1225#ifdef CONFIG_PM_SLEEP
1115static int brcmf_ops_sdio_suspend(struct device *dev) 1226static int brcmf_ops_sdio_suspend(struct device *dev)
1116{ 1227{
1228 struct sdio_func *func;
1117 struct brcmf_bus *bus_if; 1229 struct brcmf_bus *bus_if;
1118 struct brcmf_sdio_dev *sdiodev; 1230 struct brcmf_sdio_dev *sdiodev;
1119 mmc_pm_flag_t sdio_flags; 1231 mmc_pm_flag_t sdio_flags;
1120 1232
1121 brcmf_dbg(SDIO, "Enter\n"); 1233 func = container_of(dev, struct sdio_func, dev);
1234 brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
1235 if (func->num != SDIO_FUNC_1)
1236 return 0;
1237
1122 1238
1123 bus_if = dev_get_drvdata(dev); 1239 bus_if = dev_get_drvdata(dev);
1124 sdiodev = bus_if->bus_priv.sdio; 1240 sdiodev = bus_if->bus_priv.sdio;
1125 1241
1126 /* wait for watchdog to go idle */ 1242 brcmf_sdiod_freezer_on(sdiodev);
1127 if (wait_event_timeout(sdiodev->idle_wait, sdiodev->sleeping,
1128 msecs_to_jiffies(3 * BRCMF_WD_POLL_MS)) == 0) {
1129 brcmf_err("bus still active\n");
1130 return -EBUSY;
1131 }
1132 /* disable watchdog */
1133 brcmf_sdio_wd_timer(sdiodev->bus, 0); 1243 brcmf_sdio_wd_timer(sdiodev->bus, 0);
1134 atomic_set(&sdiodev->suspend, true);
1135 1244
1136 if (sdiodev->wowl_enabled) { 1245 if (sdiodev->wowl_enabled) {
1137 sdio_flags = MMC_PM_KEEP_POWER; 1246 sdio_flags = MMC_PM_KEEP_POWER;
@@ -1149,12 +1258,13 @@ static int brcmf_ops_sdio_resume(struct device *dev)
1149{ 1258{
1150 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1259 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1151 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 1260 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1261 struct sdio_func *func = container_of(dev, struct sdio_func, dev);
1152 1262
1153 brcmf_dbg(SDIO, "Enter\n"); 1263 brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
1154 if (sdiodev->pdata && sdiodev->pdata->oob_irq_supported) 1264 if (func->num != SDIO_FUNC_2)
1155 disable_irq_wake(sdiodev->pdata->oob_irq_nr); 1265 return 0;
1156 brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); 1266
1157 atomic_set(&sdiodev->suspend, false); 1267 brcmf_sdiod_freezer_off(sdiodev);
1158 return 0; 1268 return 0;
1159} 1269}
1160 1270
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
index 06727a61b438..9b805c9fd51e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -1050,10 +1050,6 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1050 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) 1050 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1051 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; 1051 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1052 1052
1053 /* Arm scan timeout timer */
1054 mod_timer(&cfg->escan_timeout, jiffies +
1055 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1056
1057 escan_req = false; 1053 escan_req = false;
1058 if (request) { 1054 if (request) {
1059 /* scan bss */ 1055 /* scan bss */
@@ -1112,12 +1108,14 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1112 } 1108 }
1113 } 1109 }
1114 1110
1111 /* Arm scan timeout timer */
1112 mod_timer(&cfg->escan_timeout, jiffies +
1113 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1114
1115 return 0; 1115 return 0;
1116 1116
1117scan_out: 1117scan_out:
1118 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 1118 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1119 if (timer_pending(&cfg->escan_timeout))
1120 del_timer_sync(&cfg->escan_timeout);
1121 cfg->scan_request = NULL; 1119 cfg->scan_request = NULL;
1122 return err; 1120 return err;
1123} 1121}
@@ -2252,7 +2250,6 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2252 2250
2253 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) { 2251 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2254 /* we ignore this key index in this case */ 2252 /* we ignore this key index in this case */
2255 brcmf_err("invalid key index (%d)\n", key_idx);
2256 return -EINVAL; 2253 return -EINVAL;
2257 } 2254 }
2258 2255
@@ -4272,7 +4269,7 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4272 return -EIO; 4269 return -EIO;
4273 4270
4274 memcpy(&scbval.ea, params->mac, ETH_ALEN); 4271 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4275 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING); 4272 scbval.val = cpu_to_le32(params->reason_code);
4276 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, 4273 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4277 &scbval, sizeof(scbval)); 4274 &scbval, sizeof(scbval));
4278 if (err) 4275 if (err)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c
index 2d6e2cc1b12c..f8f47dcfa886 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -944,6 +944,34 @@ fail:
944 return ret; 944 return ret;
945} 945}
946 946
947static int brcmf_revinfo_read(struct seq_file *s, void *data)
948{
949 struct brcmf_bus *bus_if = dev_get_drvdata(s->private);
950 struct brcmf_rev_info *ri = &bus_if->drvr->revinfo;
951 char drev[BRCMU_DOTREV_LEN];
952 char brev[BRCMU_BOARDREV_LEN];
953
954 seq_printf(s, "vendorid: 0x%04x\n", ri->vendorid);
955 seq_printf(s, "deviceid: 0x%04x\n", ri->deviceid);
956 seq_printf(s, "radiorev: %s\n", brcmu_dotrev_str(ri->radiorev, drev));
957 seq_printf(s, "chipnum: %u (%x)\n", ri->chipnum, ri->chipnum);
958 seq_printf(s, "chiprev: %u\n", ri->chiprev);
959 seq_printf(s, "chippkg: %u\n", ri->chippkg);
960 seq_printf(s, "corerev: %u\n", ri->corerev);
961 seq_printf(s, "boardid: 0x%04x\n", ri->boardid);
962 seq_printf(s, "boardvendor: 0x%04x\n", ri->boardvendor);
963 seq_printf(s, "boardrev: %s\n", brcmu_boardrev_str(ri->boardrev, brev));
964 seq_printf(s, "driverrev: %s\n", brcmu_dotrev_str(ri->driverrev, drev));
965 seq_printf(s, "ucoderev: %u\n", ri->ucoderev);
966 seq_printf(s, "bus: %u\n", ri->bus);
967 seq_printf(s, "phytype: %u\n", ri->phytype);
968 seq_printf(s, "phyrev: %u\n", ri->phyrev);
969 seq_printf(s, "anarev: %u\n", ri->anarev);
970 seq_printf(s, "nvramrev: %08x\n", ri->nvramrev);
971
972 return 0;
973}
974
947int brcmf_bus_start(struct device *dev) 975int brcmf_bus_start(struct device *dev)
948{ 976{
949 int ret = -1; 977 int ret = -1;
@@ -974,6 +1002,8 @@ int brcmf_bus_start(struct device *dev)
974 if (ret < 0) 1002 if (ret < 0)
975 goto fail; 1003 goto fail;
976 1004
1005 brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read);
1006
977 /* assure we have chipid before feature attach */ 1007 /* assure we have chipid before feature attach */
978 if (!bus_if->chip) { 1008 if (!bus_if->chip) {
979 bus_if->chip = drvr->revinfo.chipnum; 1009 bus_if->chip = drvr->revinfo.chipnum;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index faec35c899ec..257ee70feb5b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -515,6 +515,7 @@ struct brcmf_sdio {
515 bool txoff; /* Transmit flow-controlled */ 515 bool txoff; /* Transmit flow-controlled */
516 struct brcmf_sdio_count sdcnt; 516 struct brcmf_sdio_count sdcnt;
517 bool sr_enabled; /* SaveRestore enabled */ 517 bool sr_enabled; /* SaveRestore enabled */
518 bool sleeping;
518 519
519 u8 tx_hdrlen; /* sdio bus header length for tx packet */ 520 u8 tx_hdrlen; /* sdio bus header length for tx packet */
520 bool txglom; /* host tx glomming enable flag */ 521 bool txglom; /* host tx glomming enable flag */
@@ -1013,12 +1014,12 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1013 1014
1014 brcmf_dbg(SDIO, "Enter: request %s currently %s\n", 1015 brcmf_dbg(SDIO, "Enter: request %s currently %s\n",
1015 (sleep ? "SLEEP" : "WAKE"), 1016 (sleep ? "SLEEP" : "WAKE"),
1016 (bus->sdiodev->sleeping ? "SLEEP" : "WAKE")); 1017 (bus->sleeping ? "SLEEP" : "WAKE"));
1017 1018
1018 /* If SR is enabled control bus state with KSO */ 1019 /* If SR is enabled control bus state with KSO */
1019 if (bus->sr_enabled) { 1020 if (bus->sr_enabled) {
1020 /* Done if we're already in the requested state */ 1021 /* Done if we're already in the requested state */
1021 if (sleep == bus->sdiodev->sleeping) 1022 if (sleep == bus->sleeping)
1022 goto end; 1023 goto end;
1023 1024
1024 /* Going to sleep */ 1025 /* Going to sleep */
@@ -1026,6 +1027,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1026 /* Don't sleep if something is pending */ 1027 /* Don't sleep if something is pending */
1027 if (atomic_read(&bus->intstatus) || 1028 if (atomic_read(&bus->intstatus) ||
1028 atomic_read(&bus->ipend) > 0 || 1029 atomic_read(&bus->ipend) > 0 ||
1030 bus->ctrl_frame_stat ||
1029 (!atomic_read(&bus->fcstate) && 1031 (!atomic_read(&bus->fcstate) &&
1030 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && 1032 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
1031 data_ok(bus))) { 1033 data_ok(bus))) {
@@ -1065,9 +1067,7 @@ end:
1065 } else { 1067 } else {
1066 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok); 1068 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
1067 } 1069 }
1068 bus->sdiodev->sleeping = sleep; 1070 bus->sleeping = sleep;
1069 if (sleep)
1070 wake_up(&bus->sdiodev->idle_wait);
1071 brcmf_dbg(SDIO, "new state %s\n", 1071 brcmf_dbg(SDIO, "new state %s\n",
1072 (sleep ? "SLEEP" : "WAKE")); 1072 (sleep ? "SLEEP" : "WAKE"));
1073done: 1073done:
@@ -1909,7 +1909,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1909 bus->rxpending = true; 1909 bus->rxpending = true;
1910 1910
1911 for (rd->seq_num = bus->rx_seq, rxleft = maxframes; 1911 for (rd->seq_num = bus->rx_seq, rxleft = maxframes;
1912 !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_STATE_DATA; 1912 !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_SDIOD_DATA;
1913 rd->seq_num++, rxleft--) { 1913 rd->seq_num++, rxleft--) {
1914 1914
1915 /* Handle glomming separately */ 1915 /* Handle glomming separately */
@@ -2415,7 +2415,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2415 } 2415 }
2416 2416
2417 /* Deflow-control stack if needed */ 2417 /* Deflow-control stack if needed */
2418 if ((bus->sdiodev->state == BRCMF_STATE_DATA) && 2418 if ((bus->sdiodev->state == BRCMF_SDIOD_DATA) &&
2419 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { 2419 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
2420 bus->txoff = false; 2420 bus->txoff = false;
2421 brcmf_txflowblock(bus->sdiodev->dev, false); 2421 brcmf_txflowblock(bus->sdiodev->dev, false);
@@ -2503,7 +2503,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
2503 bus->watchdog_tsk = NULL; 2503 bus->watchdog_tsk = NULL;
2504 } 2504 }
2505 2505
2506 if (sdiodev->state != BRCMF_STATE_NOMEDIUM) { 2506 if (sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
2507 sdio_claim_host(sdiodev->func[1]); 2507 sdio_claim_host(sdiodev->func[1]);
2508 2508
2509 /* Enable clock for device interrupts */ 2509 /* Enable clock for device interrupts */
@@ -2603,21 +2603,6 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2603 return ret; 2603 return ret;
2604} 2604}
2605 2605
2606static int brcmf_sdio_pm_resume_wait(struct brcmf_sdio_dev *sdiodev)
2607{
2608#ifdef CONFIG_PM_SLEEP
2609 int retry;
2610
2611 /* Wait for possible resume to complete */
2612 retry = 0;
2613 while ((atomic_read(&sdiodev->suspend)) && (retry++ != 50))
2614 msleep(20);
2615 if (atomic_read(&sdiodev->suspend))
2616 return -EIO;
2617#endif
2618 return 0;
2619}
2620
2621static void brcmf_sdio_dpc(struct brcmf_sdio *bus) 2606static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2622{ 2607{
2623 u32 newstatus = 0; 2608 u32 newstatus = 0;
@@ -2628,9 +2613,6 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2628 2613
2629 brcmf_dbg(TRACE, "Enter\n"); 2614 brcmf_dbg(TRACE, "Enter\n");
2630 2615
2631 if (brcmf_sdio_pm_resume_wait(bus->sdiodev))
2632 return;
2633
2634 sdio_claim_host(bus->sdiodev->func[1]); 2616 sdio_claim_host(bus->sdiodev->func[1]);
2635 2617
2636 /* If waiting for HTAVAIL, check status */ 2618 /* If waiting for HTAVAIL, check status */
@@ -2755,7 +2737,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2755 brcmf_sdio_sendfromq(bus, framecnt); 2737 brcmf_sdio_sendfromq(bus, framecnt);
2756 } 2738 }
2757 2739
2758 if ((bus->sdiodev->state != BRCMF_STATE_DATA) || (err != 0)) { 2740 if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) {
2759 brcmf_err("failed backplane access over SDIO, halting operation\n"); 2741 brcmf_err("failed backplane access over SDIO, halting operation\n");
2760 atomic_set(&bus->intstatus, 0); 2742 atomic_set(&bus->intstatus, 0);
2761 } else if (atomic_read(&bus->intstatus) || 2743 } else if (atomic_read(&bus->intstatus) ||
@@ -2862,11 +2844,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2862 qcount[prec] = pktq_plen(&bus->txq, prec); 2844 qcount[prec] = pktq_plen(&bus->txq, prec);
2863#endif 2845#endif
2864 2846
2865 if (atomic_read(&bus->dpc_tskcnt) == 0) { 2847 brcmf_sdio_trigger_dpc(bus);
2866 atomic_inc(&bus->dpc_tskcnt);
2867 queue_work(bus->brcmf_wq, &bus->datawork);
2868 }
2869
2870 return ret; 2848 return ret;
2871} 2849}
2872 2850
@@ -2964,11 +2942,8 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2964 bus->ctrl_frame_buf = msg; 2942 bus->ctrl_frame_buf = msg;
2965 bus->ctrl_frame_len = msglen; 2943 bus->ctrl_frame_len = msglen;
2966 bus->ctrl_frame_stat = true; 2944 bus->ctrl_frame_stat = true;
2967 if (atomic_read(&bus->dpc_tskcnt) == 0) {
2968 atomic_inc(&bus->dpc_tskcnt);
2969 queue_work(bus->brcmf_wq, &bus->datawork);
2970 }
2971 2945
2946 brcmf_sdio_trigger_dpc(bus);
2972 wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat, 2947 wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat,
2973 msecs_to_jiffies(CTL_DONE_TIMEOUT)); 2948 msecs_to_jiffies(CTL_DONE_TIMEOUT));
2974 2949
@@ -3411,7 +3386,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
3411 } 3386 }
3412 3387
3413 /* Allow full data communication using DPC from now on. */ 3388 /* Allow full data communication using DPC from now on. */
3414 bus->sdiodev->state = BRCMF_STATE_DATA; 3389 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
3415 bcmerror = 0; 3390 bcmerror = 0;
3416 3391
3417err: 3392err:
@@ -3548,6 +3523,14 @@ done:
3548 return err; 3523 return err;
3549} 3524}
3550 3525
3526void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus)
3527{
3528 if (atomic_read(&bus->dpc_tskcnt) == 0) {
3529 atomic_inc(&bus->dpc_tskcnt);
3530 queue_work(bus->brcmf_wq, &bus->datawork);
3531 }
3532}
3533
3551void brcmf_sdio_isr(struct brcmf_sdio *bus) 3534void brcmf_sdio_isr(struct brcmf_sdio *bus)
3552{ 3535{
3553 brcmf_dbg(TRACE, "Enter\n"); 3536 brcmf_dbg(TRACE, "Enter\n");
@@ -3557,7 +3540,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
3557 return; 3540 return;
3558 } 3541 }
3559 3542
3560 if (bus->sdiodev->state != BRCMF_STATE_DATA) { 3543 if (bus->sdiodev->state != BRCMF_SDIOD_DATA) {
3561 brcmf_err("bus is down. we have nothing to do\n"); 3544 brcmf_err("bus is down. we have nothing to do\n");
3562 return; 3545 return;
3563 } 3546 }
@@ -3602,9 +3585,8 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3602 SDIO_CCCR_INTx, 3585 SDIO_CCCR_INTx,
3603 NULL); 3586 NULL);
3604 sdio_release_host(bus->sdiodev->func[1]); 3587 sdio_release_host(bus->sdiodev->func[1]);
3605 intstatus = 3588 intstatus = devpend & (INTR_STATUS_FUNC1 |
3606 devpend & (INTR_STATUS_FUNC1 | 3589 INTR_STATUS_FUNC2);
3607 INTR_STATUS_FUNC2);
3608 } 3590 }
3609 3591
3610 /* If there is something, make like the ISR and 3592 /* If there is something, make like the ISR and
@@ -3623,7 +3605,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3623 } 3605 }
3624#ifdef DEBUG 3606#ifdef DEBUG
3625 /* Poll for console output periodically */ 3607 /* Poll for console output periodically */
3626 if (bus->sdiodev->state == BRCMF_STATE_DATA && 3608 if (bus->sdiodev->state == BRCMF_SDIOD_DATA &&
3627 bus->console_interval != 0) { 3609 bus->console_interval != 0) {
3628 bus->console.count += BRCMF_WD_POLL_MS; 3610 bus->console.count += BRCMF_WD_POLL_MS;
3629 if (bus->console.count >= bus->console_interval) { 3611 if (bus->console.count >= bus->console_interval) {
@@ -3667,6 +3649,11 @@ static void brcmf_sdio_dataworker(struct work_struct *work)
3667 atomic_set(&bus->dpc_tskcnt, 0); 3649 atomic_set(&bus->dpc_tskcnt, 0);
3668 brcmf_sdio_dpc(bus); 3650 brcmf_sdio_dpc(bus);
3669 } 3651 }
3652 if (brcmf_sdiod_freezing(bus->sdiodev)) {
3653 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN);
3654 brcmf_sdiod_try_freeze(bus->sdiodev);
3655 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
3656 }
3670} 3657}
3671 3658
3672static void 3659static void
@@ -3944,13 +3931,19 @@ static int
3944brcmf_sdio_watchdog_thread(void *data) 3931brcmf_sdio_watchdog_thread(void *data)
3945{ 3932{
3946 struct brcmf_sdio *bus = (struct brcmf_sdio *)data; 3933 struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
3934 int wait;
3947 3935
3948 allow_signal(SIGTERM); 3936 allow_signal(SIGTERM);
3949 /* Run until signal received */ 3937 /* Run until signal received */
3938 brcmf_sdiod_freezer_count(bus->sdiodev);
3950 while (1) { 3939 while (1) {
3951 if (kthread_should_stop()) 3940 if (kthread_should_stop())
3952 break; 3941 break;
3953 if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { 3942 brcmf_sdiod_freezer_uncount(bus->sdiodev);
3943 wait = wait_for_completion_interruptible(&bus->watchdog_wait);
3944 brcmf_sdiod_freezer_count(bus->sdiodev);
3945 brcmf_sdiod_try_freeze(bus->sdiodev);
3946 if (!wait) {
3954 brcmf_sdio_bus_watchdog(bus); 3947 brcmf_sdio_bus_watchdog(bus);
3955 /* Count the tick for reference */ 3948 /* Count the tick for reference */
3956 bus->sdcnt.tickcnt++; 3949 bus->sdcnt.tickcnt++;
@@ -3971,7 +3964,7 @@ brcmf_sdio_watchdog(unsigned long data)
3971 /* Reschedule the watchdog */ 3964 /* Reschedule the watchdog */
3972 if (bus->wd_timer_valid) 3965 if (bus->wd_timer_valid)
3973 mod_timer(&bus->timer, 3966 mod_timer(&bus->timer,
3974 jiffies + BRCMF_WD_POLL_MS * HZ / 1000); 3967 jiffies + msecs_to_jiffies(BRCMF_WD_POLL_MS));
3975 } 3968 }
3976} 3969}
3977 3970
@@ -4089,6 +4082,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4089{ 4082{
4090 int ret; 4083 int ret;
4091 struct brcmf_sdio *bus; 4084 struct brcmf_sdio *bus;
4085 struct workqueue_struct *wq;
4092 4086
4093 brcmf_dbg(TRACE, "Enter\n"); 4087 brcmf_dbg(TRACE, "Enter\n");
4094 4088
@@ -4117,12 +4111,16 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4117 bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; 4111 bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
4118 } 4112 }
4119 4113
4120 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); 4114 /* single-threaded workqueue */
4121 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); 4115 wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
4122 if (bus->brcmf_wq == NULL) { 4116 dev_name(&sdiodev->func[1]->dev));
4117 if (!wq) {
4123 brcmf_err("insufficient memory to create txworkqueue\n"); 4118 brcmf_err("insufficient memory to create txworkqueue\n");
4124 goto fail; 4119 goto fail;
4125 } 4120 }
4121 brcmf_sdiod_freezer_count(sdiodev);
4122 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
4123 bus->brcmf_wq = wq;
4126 4124
4127 /* attempt to attach to the dongle */ 4125 /* attempt to attach to the dongle */
4128 if (!(brcmf_sdio_probe_attach(bus))) { 4126 if (!(brcmf_sdio_probe_attach(bus))) {
@@ -4143,7 +4141,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4143 /* Initialize watchdog thread */ 4141 /* Initialize watchdog thread */
4144 init_completion(&bus->watchdog_wait); 4142 init_completion(&bus->watchdog_wait);
4145 bus->watchdog_tsk = kthread_run(brcmf_sdio_watchdog_thread, 4143 bus->watchdog_tsk = kthread_run(brcmf_sdio_watchdog_thread,
4146 bus, "brcmf_watchdog"); 4144 bus, "brcmf_wdog/%s",
4145 dev_name(&sdiodev->func[1]->dev));
4147 if (IS_ERR(bus->watchdog_tsk)) { 4146 if (IS_ERR(bus->watchdog_tsk)) {
4148 pr_warn("brcmf_watchdog thread failed to start\n"); 4147 pr_warn("brcmf_watchdog thread failed to start\n");
4149 bus->watchdog_tsk = NULL; 4148 bus->watchdog_tsk = NULL;
@@ -4242,7 +4241,7 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4242 destroy_workqueue(bus->brcmf_wq); 4241 destroy_workqueue(bus->brcmf_wq);
4243 4242
4244 if (bus->ci) { 4243 if (bus->ci) {
4245 if (bus->sdiodev->state != BRCMF_STATE_NOMEDIUM) { 4244 if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
4246 sdio_claim_host(bus->sdiodev->func[1]); 4245 sdio_claim_host(bus->sdiodev->func[1]);
4247 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 4246 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
4248 /* Leave the device in state where it is 4247 /* Leave the device in state where it is
@@ -4277,7 +4276,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4277 } 4276 }
4278 4277
4279 /* don't start the wd until fw is loaded */ 4278 /* don't start the wd until fw is loaded */
4280 if (bus->sdiodev->state != BRCMF_STATE_DATA) 4279 if (bus->sdiodev->state != BRCMF_SDIOD_DATA)
4281 return; 4280 return;
4282 4281
4283 if (wdtick) { 4282 if (wdtick) {
@@ -4290,16 +4289,28 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4290 dynamically changed or in the first instance 4289 dynamically changed or in the first instance
4291 */ 4290 */
4292 bus->timer.expires = 4291 bus->timer.expires =
4293 jiffies + BRCMF_WD_POLL_MS * HZ / 1000; 4292 jiffies + msecs_to_jiffies(BRCMF_WD_POLL_MS);
4294 add_timer(&bus->timer); 4293 add_timer(&bus->timer);
4295 4294
4296 } else { 4295 } else {
4297 /* Re arm the timer, at last watchdog period */ 4296 /* Re arm the timer, at last watchdog period */
4298 mod_timer(&bus->timer, 4297 mod_timer(&bus->timer,
4299 jiffies + BRCMF_WD_POLL_MS * HZ / 1000); 4298 jiffies + msecs_to_jiffies(BRCMF_WD_POLL_MS));
4300 } 4299 }
4301 4300
4302 bus->wd_timer_valid = true; 4301 bus->wd_timer_valid = true;
4303 bus->save_ms = wdtick; 4302 bus->save_ms = wdtick;
4304 } 4303 }
4305} 4304}
4305
4306int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep)
4307{
4308 int ret;
4309
4310 sdio_claim_host(bus->sdiodev->func[1]);
4311 ret = brcmf_sdio_bus_sleep(bus, sleep, false);
4312 sdio_release_host(bus->sdiodev->func[1]);
4313
4314 return ret;
4315}
4316
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
index ec2586a8425c..7328478b2d7b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
@@ -155,11 +155,17 @@
155/* watchdog polling interval in ms */ 155/* watchdog polling interval in ms */
156#define BRCMF_WD_POLL_MS 10 156#define BRCMF_WD_POLL_MS 10
157 157
158/* The state of the bus */ 158/**
159enum brcmf_sdio_state { 159 * enum brcmf_sdiod_state - the state of the bus.
160 BRCMF_STATE_DOWN, /* Device available, still initialising */ 160 *
161 BRCMF_STATE_DATA, /* Ready for data transfers, DPC enabled */ 161 * @BRCMF_SDIOD_DOWN: Device can be accessed, no DPC.
162 BRCMF_STATE_NOMEDIUM /* No medium access to dongle possible */ 162 * @BRCMF_SDIOD_DATA: Ready for data transfers, DPC enabled.
163 * @BRCMF_SDIOD_NOMEDIUM: No medium access to dongle possible.
164 */
165enum brcmf_sdiod_state {
166 BRCMF_SDIOD_DOWN,
167 BRCMF_SDIOD_DATA,
168 BRCMF_SDIOD_NOMEDIUM
163}; 169};
164 170
165struct brcmf_sdreg { 171struct brcmf_sdreg {
@@ -169,15 +175,13 @@ struct brcmf_sdreg {
169}; 175};
170 176
171struct brcmf_sdio; 177struct brcmf_sdio;
178struct brcmf_sdiod_freezer;
172 179
173struct brcmf_sdio_dev { 180struct brcmf_sdio_dev {
174 struct sdio_func *func[SDIO_MAX_FUNCS]; 181 struct sdio_func *func[SDIO_MAX_FUNCS];
175 u8 num_funcs; /* Supported funcs on client */ 182 u8 num_funcs; /* Supported funcs on client */
176 u32 sbwad; /* Save backplane window address */ 183 u32 sbwad; /* Save backplane window address */
177 struct brcmf_sdio *bus; 184 struct brcmf_sdio *bus;
178 atomic_t suspend; /* suspend flag */
179 bool sleeping;
180 wait_queue_head_t idle_wait;
181 struct device *dev; 185 struct device *dev;
182 struct brcmf_bus *bus_if; 186 struct brcmf_bus *bus_if;
183 struct brcmfmac_sdio_platform_data *pdata; 187 struct brcmfmac_sdio_platform_data *pdata;
@@ -194,7 +198,8 @@ struct brcmf_sdio_dev {
194 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 198 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
195 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 199 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
196 bool wowl_enabled; 200 bool wowl_enabled;
197 enum brcmf_sdio_state state; 201 enum brcmf_sdiod_state state;
202 struct brcmf_sdiod_freezer *freezer;
198}; 203};
199 204
200/* sdio core registers */ 205/* sdio core registers */
@@ -337,6 +342,28 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
337 342
338/* Issue an abort to the specified function */ 343/* Issue an abort to the specified function */
339int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); 344int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
345void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
346 enum brcmf_sdiod_state state);
347#ifdef CONFIG_PM_SLEEP
348bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev);
349void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev);
350void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev);
351void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev);
352#else
353static inline bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev)
354{
355 return false;
356}
357static inline void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev)
358{
359}
360static inline void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev)
361{
362}
363static inline void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev)
364{
365}
366#endif /* CONFIG_PM_SLEEP */
340 367
341struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); 368struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
342void brcmf_sdio_remove(struct brcmf_sdio *bus); 369void brcmf_sdio_remove(struct brcmf_sdio *bus);
@@ -344,5 +371,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus);
344 371
345void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); 372void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick);
346void brcmf_sdio_wowl_config(struct device *dev, bool enabled); 373void brcmf_sdio_wowl_config(struct device *dev, bool enabled);
374int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep);
375void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus);
347 376
348#endif /* BRCMFMAC_SDIO_H */ 377#endif /* BRCMFMAC_SDIO_H */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index eb8584a9c49a..c84af1dfc88f 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4668,7 +4668,7 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4668 brcms_c_coredisable(wlc_hw); 4668 brcms_c_coredisable(wlc_hw);
4669 4669
4670 /* Match driver "down" state */ 4670 /* Match driver "down" state */
4671 bcma_core_pci_down(wlc_hw->d11core->bus); 4671 bcma_host_pci_down(wlc_hw->d11core->bus);
4672 4672
4673 /* turn off pll and xtal to match driver "down" state */ 4673 /* turn off pll and xtal to match driver "down" state */
4674 brcms_b_xtal(wlc_hw, OFF); 4674 brcms_b_xtal(wlc_hw, OFF);
@@ -4959,7 +4959,7 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
4959 * Configure pci/pcmcia here instead of in brcms_c_attach() 4959 * Configure pci/pcmcia here instead of in brcms_c_attach()
4960 * to allow mfg hotswap: down, hotswap (chip power cycle), up. 4960 * to allow mfg hotswap: down, hotswap (chip power cycle), up.
4961 */ 4961 */
4962 bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core, 4962 bcma_core_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core,
4963 true); 4963 true);
4964 4964
4965 /* 4965 /*
@@ -4969,12 +4969,12 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
4969 */ 4969 */
4970 if (brcms_b_radio_read_hwdisabled(wlc_hw)) { 4970 if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
4971 /* put SB PCI in down state again */ 4971 /* put SB PCI in down state again */
4972 bcma_core_pci_down(wlc_hw->d11core->bus); 4972 bcma_host_pci_down(wlc_hw->d11core->bus);
4973 brcms_b_xtal(wlc_hw, OFF); 4973 brcms_b_xtal(wlc_hw, OFF);
4974 return -ENOMEDIUM; 4974 return -ENOMEDIUM;
4975 } 4975 }
4976 4976
4977 bcma_core_pci_up(wlc_hw->d11core->bus); 4977 bcma_host_pci_up(wlc_hw->d11core->bus);
4978 4978
4979 /* reset the d11 core */ 4979 /* reset the d11 core */
4980 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); 4980 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
@@ -5171,7 +5171,7 @@ static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
5171 5171
5172 /* turn off primary xtal and pll */ 5172 /* turn off primary xtal and pll */
5173 if (!wlc_hw->noreset) { 5173 if (!wlc_hw->noreset) {
5174 bcma_core_pci_down(wlc_hw->d11core->bus); 5174 bcma_host_pci_down(wlc_hw->d11core->bus);
5175 brcms_b_xtal(wlc_hw, OFF); 5175 brcms_b_xtal(wlc_hw, OFF);
5176 } 5176 }
5177 } 5177 }
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
index 084f18f4f950..99dac9b8a082 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
@@ -23041,10 +23041,7 @@ static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type)
23041 else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL) 23041 else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL)
23042 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, 23042 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
23043 NPHY_RSSI_SEL_W1); 23043 NPHY_RSSI_SEL_W1);
23044 else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL) 23044 else /* RADIO_2055_WBRSSI_G2_SEL */
23045 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
23046 NPHY_RSSI_SEL_W2);
23047 else
23048 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, 23045 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
23049 NPHY_RSSI_SEL_W2); 23046 NPHY_RSSI_SEL_W2);
23050 if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL) 23047 if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL)
@@ -23053,13 +23050,9 @@ static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type)
23053 else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL) 23050 else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL)
23054 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, 23051 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
23055 NPHY_RSSI_SEL_W1); 23052 NPHY_RSSI_SEL_W1);
23056 else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL) 23053 else /* RADIO_2055_WBRSSI_G1_SEL */
23057 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, 23054 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
23058 NPHY_RSSI_SEL_W2); 23055 NPHY_RSSI_SEL_W2);
23059 else
23060 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
23061 NPHY_RSSI_SEL_W2);
23062
23063 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type); 23056 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type);
23064 23057
23065 write_phy_reg(pi, 0x91, rfctrlintc_state[0]); 23058 write_phy_reg(pi, 0x91, rfctrlintc_state[0]);
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c
index eaaeea19d8c5..bac60b2bc3f0 100644
--- a/drivers/net/wireless/iwlegacy/4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/4965-rs.c
@@ -1678,7 +1678,7 @@ il4965_rs_stay_in_table(struct il_lq_sta *lq_sta, bool force_search)
1678 lq_sta->total_success > lq_sta->max_success_limit || 1678 lq_sta->total_success > lq_sta->max_success_limit ||
1679 (!lq_sta->search_better_tbl && lq_sta->flush_timer && 1679 (!lq_sta->search_better_tbl && lq_sta->flush_timer &&
1680 flush_interval_passed)) { 1680 flush_interval_passed)) {
1681 D_RATE("LQ: stay is expired %d %d %d\n:", 1681 D_RATE("LQ: stay is expired %d %d %d\n",
1682 lq_sta->total_failed, lq_sta->total_success, 1682 lq_sta->total_failed, lq_sta->total_success,
1683 flush_interval_passed); 1683 flush_interval_passed);
1684 1684
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index c4d6dd7402d9..234e30f498b2 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -1549,7 +1549,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
1549 table.blink1, table.blink2, table.ilink1, 1549 table.blink1, table.blink2, table.ilink1,
1550 table.ilink2, table.bcon_time, table.gp1, 1550 table.ilink2, table.bcon_time, table.gp1,
1551 table.gp2, table.gp3, table.ucode_ver, 1551 table.gp2, table.gp3, table.ucode_ver,
1552 table.hw_ver, table.brd_ver); 1552 table.hw_ver, 0, table.brd_ver);
1553 IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id, 1553 IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id,
1554 desc_lookup(table.error_id)); 1554 desc_lookup(table.error_id));
1555 IWL_ERR(priv, "0x%08X | uPc\n", table.pc); 1555 IWL_ERR(priv, "0x%08X | uPc\n", table.pc);
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 97e38d2e2983..0597a9cfd2f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -77,8 +77,8 @@
77#define IWL3160_UCODE_API_OK 10 77#define IWL3160_UCODE_API_OK 10
78 78
79/* Lowest firmware API version supported */ 79/* Lowest firmware API version supported */
80#define IWL7260_UCODE_API_MIN 9 80#define IWL7260_UCODE_API_MIN 10
81#define IWL3160_UCODE_API_MIN 9 81#define IWL3160_UCODE_API_MIN 10
82 82
83/* NVM versions */ 83/* NVM versions */
84#define IWL7260_NVM_VERSION 0x0a1d 84#define IWL7260_NVM_VERSION 0x0a1d
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index 2f7fe8167dc9..d8dfa6da6307 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -75,7 +75,7 @@
75#define IWL8000_UCODE_API_OK 10 75#define IWL8000_UCODE_API_OK 10
76 76
77/* Lowest firmware API version supported */ 77/* Lowest firmware API version supported */
78#define IWL8000_UCODE_API_MIN 9 78#define IWL8000_UCODE_API_MIN 10
79 79
80/* NVM versions */ 80/* NVM versions */
81#define IWL8000_NVM_VERSION 0x0a1d 81#define IWL8000_NVM_VERSION 0x0a1d
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 78bd41bf34b0..53555a0fce56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -431,11 +431,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
431 TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, 431 TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low,
432 u32 data1, u32 data2, u32 line, u32 blink1, 432 u32 data1, u32 data2, u32 line, u32 blink1,
433 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, 433 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
434 u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, 434 u32 gp1, u32 gp2, u32 gp3, u32 major, u32 minor, u32 hw_ver,
435 u32 brd_ver), 435 u32 brd_ver),
436 TP_ARGS(dev, desc, tsf_low, data1, data2, line, 436 TP_ARGS(dev, desc, tsf_low, data1, data2, line,
437 blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, 437 blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
438 gp3, ucode_ver, hw_ver, brd_ver), 438 gp3, major, minor, hw_ver, brd_ver),
439 TP_STRUCT__entry( 439 TP_STRUCT__entry(
440 DEV_ENTRY 440 DEV_ENTRY
441 __field(u32, desc) 441 __field(u32, desc)
@@ -451,7 +451,8 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
451 __field(u32, gp1) 451 __field(u32, gp1)
452 __field(u32, gp2) 452 __field(u32, gp2)
453 __field(u32, gp3) 453 __field(u32, gp3)
454 __field(u32, ucode_ver) 454 __field(u32, major)
455 __field(u32, minor)
455 __field(u32, hw_ver) 456 __field(u32, hw_ver)
456 __field(u32, brd_ver) 457 __field(u32, brd_ver)
457 ), 458 ),
@@ -470,21 +471,22 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
470 __entry->gp1 = gp1; 471 __entry->gp1 = gp1;
471 __entry->gp2 = gp2; 472 __entry->gp2 = gp2;
472 __entry->gp3 = gp3; 473 __entry->gp3 = gp3;
473 __entry->ucode_ver = ucode_ver; 474 __entry->major = major;
475 __entry->minor = minor;
474 __entry->hw_ver = hw_ver; 476 __entry->hw_ver = hw_ver;
475 __entry->brd_ver = brd_ver; 477 __entry->brd_ver = brd_ver;
476 ), 478 ),
477 TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " 479 TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, "
478 "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " 480 "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
479 "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " 481 "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X major 0x%08X "
480 "hw 0x%08X brd 0x%08X", 482 "minor 0x%08X hw 0x%08X brd 0x%08X",
481 __get_str(dev), __entry->desc, __entry->tsf_low, 483 __get_str(dev), __entry->desc, __entry->tsf_low,
482 __entry->data1, 484 __entry->data1,
483 __entry->data2, __entry->line, __entry->blink1, 485 __entry->data2, __entry->line, __entry->blink1,
484 __entry->blink2, __entry->ilink1, __entry->ilink2, 486 __entry->blink2, __entry->ilink1, __entry->ilink2,
485 __entry->bcon_time, __entry->gp1, __entry->gp2, 487 __entry->bcon_time, __entry->gp1, __entry->gp2,
486 __entry->gp3, __entry->ucode_ver, __entry->hw_ver, 488 __entry->gp3, __entry->major, __entry->minor,
487 __entry->brd_ver) 489 __entry->hw_ver, __entry->brd_ver)
488); 490);
489 491
490TRACE_EVENT(iwlwifi_dev_ucode_event, 492TRACE_EVENT(iwlwifi_dev_ucode_event,
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 996e7f16adf9..141331d41abf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -175,6 +175,8 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
175 kfree(drv->fw.dbg_dest_tlv); 175 kfree(drv->fw.dbg_dest_tlv);
176 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++) 176 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++)
177 kfree(drv->fw.dbg_conf_tlv[i]); 177 kfree(drv->fw.dbg_conf_tlv[i]);
178 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++)
179 kfree(drv->fw.dbg_trigger_tlv[i]);
178 180
179 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) 181 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
180 iwl_free_fw_img(drv, drv->fw.img + i); 182 iwl_free_fw_img(drv, drv->fw.img + i);
@@ -293,8 +295,10 @@ struct iwl_firmware_pieces {
293 295
294 /* FW debug data parsed for driver usage */ 296 /* FW debug data parsed for driver usage */
295 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv; 297 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
296 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX]; 298 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
297 size_t dbg_conf_tlv_len[FW_DBG_MAX]; 299 size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
300 struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
301 size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
298}; 302};
299 303
300/* 304/*
@@ -842,6 +846,23 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
842 capa->n_scan_channels = 846 capa->n_scan_channels =
843 le32_to_cpup((__le32 *)tlv_data); 847 le32_to_cpup((__le32 *)tlv_data);
844 break; 848 break;
849 case IWL_UCODE_TLV_FW_VERSION: {
850 __le32 *ptr = (void *)tlv_data;
851 u32 major, minor;
852 u8 local_comp;
853
854 if (tlv_len != sizeof(u32) * 3)
855 goto invalid_tlv_len;
856
857 major = le32_to_cpup(ptr++);
858 minor = le32_to_cpup(ptr++);
859 local_comp = le32_to_cpup(ptr);
860
861 snprintf(drv->fw.fw_version,
862 sizeof(drv->fw.fw_version), "%u.%u.%u",
863 major, minor, local_comp);
864 break;
865 }
845 case IWL_UCODE_TLV_FW_DBG_DEST: { 866 case IWL_UCODE_TLV_FW_DBG_DEST: {
846 struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data; 867 struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data;
847 868
@@ -897,6 +918,31 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
897 pieces->dbg_conf_tlv_len[conf->id] = tlv_len; 918 pieces->dbg_conf_tlv_len[conf->id] = tlv_len;
898 break; 919 break;
899 } 920 }
921 case IWL_UCODE_TLV_FW_DBG_TRIGGER: {
922 struct iwl_fw_dbg_trigger_tlv *trigger =
923 (void *)tlv_data;
924 u32 trigger_id = le32_to_cpu(trigger->id);
925
926 if (trigger_id >= ARRAY_SIZE(drv->fw.dbg_trigger_tlv)) {
927 IWL_ERR(drv,
928 "Skip unknown trigger: %u\n",
929 trigger->id);
930 break;
931 }
932
933 if (pieces->dbg_trigger_tlv[trigger_id]) {
934 IWL_ERR(drv,
935 "Ignore duplicate dbg trigger %u\n",
936 trigger->id);
937 break;
938 }
939
940 IWL_INFO(drv, "Found debug trigger: %u\n", trigger->id);
941
942 pieces->dbg_trigger_tlv[trigger_id] = trigger;
943 pieces->dbg_trigger_tlv_len[trigger_id] = tlv_len;
944 break;
945 }
900 case IWL_UCODE_TLV_SEC_RT_USNIFFER: 946 case IWL_UCODE_TLV_SEC_RT_USNIFFER:
901 usniffer_images = true; 947 usniffer_images = true;
902 iwl_store_ucode_sec(pieces, tlv_data, 948 iwl_store_ucode_sec(pieces, tlv_data,
@@ -1107,7 +1153,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1107 if (err) 1153 if (err)
1108 goto try_again; 1154 goto try_again;
1109 1155
1110 api_ver = IWL_UCODE_API(drv->fw.ucode_ver); 1156 if (drv->fw.ucode_capa.api[0] & IWL_UCODE_TLV_API_NEW_VERSION)
1157 api_ver = drv->fw.ucode_ver;
1158 else
1159 api_ver = IWL_UCODE_API(drv->fw.ucode_ver);
1111 1160
1112 /* 1161 /*
1113 * api_ver should match the api version forming part of the 1162 * api_ver should match the api version forming part of the
@@ -1178,6 +1227,19 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1178 } 1227 }
1179 } 1228 }
1180 1229
1230 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) {
1231 if (pieces->dbg_trigger_tlv[i]) {
1232 drv->fw.dbg_trigger_tlv_len[i] =
1233 pieces->dbg_trigger_tlv_len[i];
1234 drv->fw.dbg_trigger_tlv[i] =
1235 kmemdup(pieces->dbg_trigger_tlv[i],
1236 drv->fw.dbg_trigger_tlv_len[i],
1237 GFP_KERNEL);
1238 if (!drv->fw.dbg_trigger_tlv[i])
1239 goto out_free_fw;
1240 }
1241 }
1242
1181 /* Now that we can no longer fail, copy information */ 1243 /* Now that we can no longer fail, copy information */
1182 1244
1183 /* 1245 /*
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
index 919a2548a92c..37b38a585dd1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
@@ -82,6 +82,8 @@
82 * sections like this in a single file. 82 * sections like this in a single file.
83 * @IWL_FW_ERROR_DUMP_FH_REGS: range of FH registers 83 * @IWL_FW_ERROR_DUMP_FH_REGS: range of FH registers
84 * @IWL_FW_ERROR_DUMP_MEM: chunk of memory 84 * @IWL_FW_ERROR_DUMP_MEM: chunk of memory
85 * @IWL_FW_ERROR_DUMP_ERROR_INFO: description of what triggered this dump.
86 * Structured as &struct iwl_fw_error_dump_trigger_desc.
85 */ 87 */
86enum iwl_fw_error_dump_type { 88enum iwl_fw_error_dump_type {
87 /* 0 is deprecated */ 89 /* 0 is deprecated */
@@ -94,6 +96,7 @@ enum iwl_fw_error_dump_type {
94 IWL_FW_ERROR_DUMP_TXF = 7, 96 IWL_FW_ERROR_DUMP_TXF = 7,
95 IWL_FW_ERROR_DUMP_FH_REGS = 8, 97 IWL_FW_ERROR_DUMP_FH_REGS = 8,
96 IWL_FW_ERROR_DUMP_MEM = 9, 98 IWL_FW_ERROR_DUMP_MEM = 9,
99 IWL_FW_ERROR_DUMP_ERROR_INFO = 10,
97 100
98 IWL_FW_ERROR_DUMP_MAX, 101 IWL_FW_ERROR_DUMP_MAX,
99}; 102};
@@ -230,4 +233,47 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
230 return (void *)(data->data + le32_to_cpu(data->len)); 233 return (void *)(data->data + le32_to_cpu(data->len));
231} 234}
232 235
236/**
237 * enum iwl_fw_dbg_trigger - triggers available
238 *
239 * @FW_DBG_TRIGGER_USER: trigger log collection by user
240 * This should not be defined as a trigger to the driver, but a value the
241 * driver should set to indicate that the trigger was initiated by the
242 * user.
243 * @FW_DBG_TRIGGER_FW_ASSERT: trigger log collection when the firmware asserts
244 * @FW_DBG_TRIGGER_MISSED_BEACONS: trigger log collection when beacons are
245 * missed.
246 * @FW_DBG_TRIGGER_CHANNEL_SWITCH: trigger log collection upon channel switch.
247 * @FW_DBG_TRIGGER_FW_NOTIF: trigger log collection when the firmware sends a
248 * command response or a notification.
249 * @FW_DB_TRIGGER_RESERVED: reserved
250 * @FW_DBG_TRIGGER_STATS: trigger log collection upon statistics threshold.
251 * @FW_DBG_TRIGGER_RSSI: trigger log collection when the rssi of the beacon
252 * goes below a threshold.
253 */
254enum iwl_fw_dbg_trigger {
255 FW_DBG_TRIGGER_INVALID = 0,
256 FW_DBG_TRIGGER_USER,
257 FW_DBG_TRIGGER_FW_ASSERT,
258 FW_DBG_TRIGGER_MISSED_BEACONS,
259 FW_DBG_TRIGGER_CHANNEL_SWITCH,
260 FW_DBG_TRIGGER_FW_NOTIF,
261 FW_DB_TRIGGER_RESERVED,
262 FW_DBG_TRIGGER_STATS,
263 FW_DBG_TRIGGER_RSSI,
264
265 /* must be last */
266 FW_DBG_TRIGGER_MAX,
267};
268
269/**
270 * struct iwl_fw_error_dump_trigger_desc - describes the trigger condition
271 * @type: %enum iwl_fw_dbg_trigger
272 * @data: raw data about what happened
273 */
274struct iwl_fw_error_dump_trigger_desc {
275 __le32 type;
276 u8 data[];
277};
278
233#endif /* __fw_error_dump_h__ */ 279#endif /* __fw_error_dump_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 016d91384681..5ea381861d5d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -66,6 +66,7 @@
66#define __iwl_fw_file_h__ 66#define __iwl_fw_file_h__
67 67
68#include <linux/netdevice.h> 68#include <linux/netdevice.h>
69#include <linux/nl80211.h>
69 70
70/* v1/v2 uCode file layout */ 71/* v1/v2 uCode file layout */
71struct iwl_ucode_header { 72struct iwl_ucode_header {
@@ -133,8 +134,10 @@ enum iwl_ucode_tlv_type {
133 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31, 134 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
134 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34, 135 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34,
135 IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35, 136 IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35,
137 IWL_UCODE_TLV_FW_VERSION = 36,
136 IWL_UCODE_TLV_FW_DBG_DEST = 38, 138 IWL_UCODE_TLV_FW_DBG_DEST = 38,
137 IWL_UCODE_TLV_FW_DBG_CONF = 39, 139 IWL_UCODE_TLV_FW_DBG_CONF = 39,
140 IWL_UCODE_TLV_FW_DBG_TRIGGER = 40,
138}; 141};
139 142
140struct iwl_ucode_tlv { 143struct iwl_ucode_tlv {
@@ -156,7 +159,8 @@ struct iwl_tlv_ucode_header {
156 __le32 zero; 159 __le32 zero;
157 __le32 magic; 160 __le32 magic;
158 u8 human_readable[FW_VER_HUMAN_READABLE_SZ]; 161 u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
159 __le32 ver; /* major/minor/API/serial */ 162 /* major/minor/API/serial or major in new format */
163 __le32 ver;
160 __le32 build; 164 __le32 build;
161 __le64 ignore; 165 __le64 ignore;
162 /* 166 /*
@@ -237,7 +241,6 @@ enum iwl_ucode_tlv_flag {
237 * enum iwl_ucode_tlv_api - ucode api 241 * enum iwl_ucode_tlv_api - ucode api
238 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex 242 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
239 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. 243 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
240 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
241 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. 244 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
242 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time 245 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
243 * longer than the passive one, which is essential for fragmented scan. 246 * longer than the passive one, which is essential for fragmented scan.
@@ -250,11 +253,12 @@ enum iwl_ucode_tlv_flag {
250 * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too. 253 * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too.
251 * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported. 254 * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported.
252 * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params 255 * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params
256 * @IWL_UCODE_TLV_API_STATS_V10: uCode supports/uses statistics API version 10
257 * @IWL_UCODE_TLV_API_NEW_VERSION: new versioning format
253 */ 258 */
254enum iwl_ucode_tlv_api { 259enum iwl_ucode_tlv_api {
255 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), 260 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
256 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), 261 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
257 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
258 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), 262 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
259 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), 263 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
260 IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10), 264 IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10),
@@ -263,6 +267,8 @@ enum iwl_ucode_tlv_api {
263 IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), 267 IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16),
264 IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17), 268 IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17),
265 IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18), 269 IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18),
270 IWL_UCODE_TLV_API_STATS_V10 = BIT(19),
271 IWL_UCODE_TLV_API_NEW_VERSION = BIT(20),
266}; 272};
267 273
268/** 274/**
@@ -284,6 +290,8 @@ enum iwl_ucode_tlv_api {
284 * which also implies support for the scheduler configuration command 290 * which also implies support for the scheduler configuration command
285 * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching 291 * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching
286 * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command 292 * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command
293 * @IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS: support radio and beacon statistics
294 * @IWL_UCODE_TLV_CAPA_BT_COEX_PLCR: enabled BT Coex packet level co-running
287 */ 295 */
288enum iwl_ucode_tlv_capa { 296enum iwl_ucode_tlv_capa {
289 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0), 297 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
@@ -298,6 +306,8 @@ enum iwl_ucode_tlv_capa {
298 IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12), 306 IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12),
299 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = BIT(13), 307 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = BIT(13),
300 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18), 308 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18),
309 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS = BIT(22),
310 IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = BIT(28),
301}; 311};
302 312
303/* The default calibrate table size if not specified by firmware file */ 313/* The default calibrate table size if not specified by firmware file */
@@ -450,44 +460,129 @@ struct iwl_fw_dbg_conf_hcmd {
450} __packed; 460} __packed;
451 461
452/** 462/**
453 * struct iwl_fw_dbg_trigger - a TLV that describes a debug configuration 463 * enum iwl_fw_dbg_trigger_mode - triggers functionalities
454 * 464 *
455 * @enabled: is this trigger enabled 465 * @IWL_FW_DBG_TRIGGER_START: when trigger occurs re-conf the dbg mechanism
456 * @reserved: 466 * @IWL_FW_DBG_TRIGGER_STOP: when trigger occurs pull the dbg data
457 * @len: length, in bytes, of the %trigger field
458 * @trigger: pointer to a trigger struct
459 */ 467 */
460struct iwl_fw_dbg_trigger { 468enum iwl_fw_dbg_trigger_mode {
461 u8 enabled; 469 IWL_FW_DBG_TRIGGER_START = BIT(0),
462 u8 reserved; 470 IWL_FW_DBG_TRIGGER_STOP = BIT(1),
463 u8 len; 471};
464 u8 trigger[0]; 472
473/**
474 * enum iwl_fw_dbg_trigger_vif_type - define the VIF type for a trigger
475 * @IWL_FW_DBG_CONF_VIF_ANY: any vif type
476 * @IWL_FW_DBG_CONF_VIF_IBSS: IBSS mode
477 * @IWL_FW_DBG_CONF_VIF_STATION: BSS mode
478 * @IWL_FW_DBG_CONF_VIF_AP: AP mode
479 * @IWL_FW_DBG_CONF_VIF_P2P_CLIENT: P2P Client mode
480 * @IWL_FW_DBG_CONF_VIF_P2P_GO: P2P GO mode
481 * @IWL_FW_DBG_CONF_VIF_P2P_DEVICE: P2P device
482 */
483enum iwl_fw_dbg_trigger_vif_type {
484 IWL_FW_DBG_CONF_VIF_ANY = NL80211_IFTYPE_UNSPECIFIED,
485 IWL_FW_DBG_CONF_VIF_IBSS = NL80211_IFTYPE_ADHOC,
486 IWL_FW_DBG_CONF_VIF_STATION = NL80211_IFTYPE_STATION,
487 IWL_FW_DBG_CONF_VIF_AP = NL80211_IFTYPE_AP,
488 IWL_FW_DBG_CONF_VIF_P2P_CLIENT = NL80211_IFTYPE_P2P_CLIENT,
489 IWL_FW_DBG_CONF_VIF_P2P_GO = NL80211_IFTYPE_P2P_GO,
490 IWL_FW_DBG_CONF_VIF_P2P_DEVICE = NL80211_IFTYPE_P2P_DEVICE,
491};
492
493/**
494 * struct iwl_fw_dbg_trigger_tlv - a TLV that describes the trigger
495 * @id: %enum iwl_fw_dbg_trigger
496 * @vif_type: %enum iwl_fw_dbg_trigger_vif_type
497 * @stop_conf_ids: bitmap of configurations this trigger relates to.
498 * if the mode is %IWL_FW_DBG_TRIGGER_STOP, then if the bit corresponding
499 * to the currently running configuration is set, the data should be
500 * collected.
501 * @stop_delay: how many milliseconds to wait before collecting the data
502 * after the STOP trigger fires.
503 * @mode: %enum iwl_fw_dbg_trigger_mode - can be stop / start of both
504 * @start_conf_id: if mode is %IWL_FW_DBG_TRIGGER_START, this defines what
505 * configuration should be applied when the triggers kicks in.
506 * @occurrences: number of occurrences. 0 means the trigger will never fire.
507 */
508struct iwl_fw_dbg_trigger_tlv {
509 __le32 id;
510 __le32 vif_type;
511 __le32 stop_conf_ids;
512 __le32 stop_delay;
513 u8 mode;
514 u8 start_conf_id;
515 __le16 occurrences;
516 __le32 reserved[2];
517
518 u8 data[0];
465} __packed; 519} __packed;
466 520
521#define FW_DBG_START_FROM_ALIVE 0
522#define FW_DBG_CONF_MAX 32
523#define FW_DBG_INVALID 0xff
524
467/** 525/**
468 * enum iwl_fw_dbg_conf - configurations available 526 * struct iwl_fw_dbg_trigger_missed_bcon - configures trigger for missed beacons
469 * 527 * @stop_consec_missed_bcon: stop recording if threshold is crossed.
470 * @FW_DBG_CUSTOM: take this configuration from alive 528 * @stop_consec_missed_bcon_since_rx: stop recording if threshold is crossed.
471 * Note that the trigger is NO-OP for this configuration 529 * @start_consec_missed_bcon: start recording if threshold is crossed.
530 * @start_consec_missed_bcon_since_rx: start recording if threshold is crossed.
531 * @reserved1: reserved
532 * @reserved2: reserved
533 */
534struct iwl_fw_dbg_trigger_missed_bcon {
535 __le32 stop_consec_missed_bcon;
536 __le32 stop_consec_missed_bcon_since_rx;
537 __le32 reserved2[2];
538 __le32 start_consec_missed_bcon;
539 __le32 start_consec_missed_bcon_since_rx;
540 __le32 reserved1[2];
541} __packed;
542
543/**
544 * struct iwl_fw_dbg_trigger_cmd - configures trigger for messages from FW.
545 * cmds: the list of commands to trigger the collection on
472 */ 546 */
473enum iwl_fw_dbg_conf { 547struct iwl_fw_dbg_trigger_cmd {
474 FW_DBG_CUSTOM = 0, 548 struct cmd {
549 u8 cmd_id;
550 u8 group_id;
551 } __packed cmds[16];
552} __packed;
475 553
476 /* must be last */ 554/**
477 FW_DBG_MAX, 555 * iwl_fw_dbg_trigger_stats - configures trigger for statistics
478 FW_DBG_INVALID = 0xff, 556 * @stop_offset: the offset of the value to be monitored
479}; 557 * @stop_threshold: the threshold above which to collect
558 * @start_offset: the offset of the value to be monitored
559 * @start_threshold: the threshold above which to start recording
560 */
561struct iwl_fw_dbg_trigger_stats {
562 __le32 stop_offset;
563 __le32 stop_threshold;
564 __le32 start_offset;
565 __le32 start_threshold;
566} __packed;
480 567
481/** 568/**
482 * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration 569 * struct iwl_fw_dbg_trigger_low_rssi - trigger for low beacon RSSI
483 * 570 * @rssi: RSSI value to trigger at
484 * @id: %enum iwl_fw_dbg_conf 571 */
572struct iwl_fw_dbg_trigger_low_rssi {
573 __le32 rssi;
574} __packed;
575
576/**
577 * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration.
578 * @id: conf id
485 * @usniffer: should the uSniffer image be used 579 * @usniffer: should the uSniffer image be used
486 * @num_of_hcmds: how many HCMDs to send are present here 580 * @num_of_hcmds: how many HCMDs to send are present here
487 * @hcmd: a variable length host command to be sent to apply the configuration. 581 * @hcmd: a variable length host command to be sent to apply the configuration.
488 * If there is more than one HCMD to send, they will appear one after the 582 * If there is more than one HCMD to send, they will appear one after the
489 * other and be sent in the order that they appear in. 583 * other and be sent in the order that they appear in.
490 * This parses IWL_UCODE_TLV_FW_DBG_CONF 584 * This parses IWL_UCODE_TLV_FW_DBG_CONF. The user can add up-to
585 * %FW_DBG_CONF_MAX configuration per run.
491 */ 586 */
492struct iwl_fw_dbg_conf_tlv { 587struct iwl_fw_dbg_conf_tlv {
493 u8 id; 588 u8 id;
@@ -495,8 +590,6 @@ struct iwl_fw_dbg_conf_tlv {
495 u8 reserved; 590 u8 reserved;
496 u8 num_of_hcmds; 591 u8 num_of_hcmds;
497 struct iwl_fw_dbg_conf_hcmd hcmd; 592 struct iwl_fw_dbg_conf_hcmd hcmd;
498
499 /* struct iwl_fw_dbg_trigger sits after all variable length hcmds */
500} __packed; 593} __packed;
501 594
502#endif /* __iwl_fw_file_h__ */ 595#endif /* __iwl_fw_file_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index ffd785cc67d6..cf75bafae51d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -68,6 +68,7 @@
68#include <net/mac80211.h> 68#include <net/mac80211.h>
69 69
70#include "iwl-fw-file.h" 70#include "iwl-fw-file.h"
71#include "iwl-fw-error-dump.h"
71 72
72/** 73/**
73 * enum iwl_ucode_type 74 * enum iwl_ucode_type
@@ -157,6 +158,8 @@ struct iwl_fw_cscheme_list {
157 * @dbg_dest_tlv: points to the destination TLV for debug 158 * @dbg_dest_tlv: points to the destination TLV for debug
158 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug 159 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
159 * @dbg_conf_tlv_len: lengths of the @dbg_conf_tlv entries 160 * @dbg_conf_tlv_len: lengths of the @dbg_conf_tlv entries
161 * @dbg_trigger_tlv: array of pointers to triggers TLVs
162 * @dbg_trigger_tlv_len: lengths of the @dbg_trigger_tlv entries
160 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv 163 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
161 */ 164 */
162struct iwl_fw { 165struct iwl_fw {
@@ -186,9 +189,10 @@ struct iwl_fw {
186 u32 sdio_adma_addr; 189 u32 sdio_adma_addr;
187 190
188 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv; 191 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
189 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX]; 192 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
190 size_t dbg_conf_tlv_len[FW_DBG_MAX]; 193 size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
191 194 struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
195 size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
192 u8 dbg_dest_reg_num; 196 u8 dbg_dest_reg_num;
193}; 197};
194 198
@@ -206,46 +210,29 @@ static inline const char *get_fw_dbg_mode_string(int mode)
206 } 210 }
207} 211}
208 212
209static inline const struct iwl_fw_dbg_trigger * 213static inline bool
210iwl_fw_dbg_conf_get_trigger(const struct iwl_fw *fw, u8 id) 214iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id)
211{ 215{
212 const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id]; 216 const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id];
213 u8 *ptr;
214 int i;
215 217
216 if (!conf_tlv) 218 if (!conf_tlv)
217 return NULL;
218
219 ptr = (void *)&conf_tlv->hcmd;
220 for (i = 0; i < conf_tlv->num_of_hcmds; i++) {
221 ptr += sizeof(conf_tlv->hcmd);
222 ptr += le16_to_cpu(conf_tlv->hcmd.len);
223 }
224
225 return (const struct iwl_fw_dbg_trigger *)ptr;
226}
227
228static inline bool
229iwl_fw_dbg_conf_enabled(const struct iwl_fw *fw, u8 id)
230{
231 const struct iwl_fw_dbg_trigger *trigger =
232 iwl_fw_dbg_conf_get_trigger(fw, id);
233
234 if (!trigger)
235 return false; 219 return false;
236 220
237 return trigger->enabled; 221 return conf_tlv->usniffer;
238} 222}
239 223
240static inline bool 224#define iwl_fw_dbg_trigger_enabled(fw, id) ({ \
241iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id) 225 void *__dbg_trigger = (fw)->dbg_trigger_tlv[(id)]; \
242{ 226 unlikely(__dbg_trigger); \
243 const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id]; 227})
244 228
245 if (!conf_tlv) 229static inline struct iwl_fw_dbg_trigger_tlv*
246 return false; 230iwl_fw_dbg_get_trigger(const struct iwl_fw *fw, u8 id)
231{
232 if (WARN_ON(id >= ARRAY_SIZE(fw->dbg_trigger_tlv)))
233 return NULL;
247 234
248 return conf_tlv->usniffer; 235 return fw->dbg_trigger_tlv[id];
249} 236}
250 237
251#endif /* __iwl_fw_h__ */ 238#endif /* __iwl_fw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
index d4fb5cad07ea..e893c6eb260c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
@@ -72,7 +72,7 @@
72#include "iwl-trans.h" 72#include "iwl-trans.h"
73 73
74#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */ 74#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */
75#define IWL_NUM_PAPD_CH_GROUPS 7 75#define IWL_NUM_PAPD_CH_GROUPS 9
76#define IWL_NUM_TXP_CH_GROUPS 9 76#define IWL_NUM_TXP_CH_GROUPS 9
77 77
78struct iwl_phy_db_entry { 78struct iwl_phy_db_entry {
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 6221e4dfc64f..6095088b88d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -370,7 +370,6 @@ enum secure_load_status_reg {
370#define MON_BUFF_CYCLE_CNT (0xa03c48) 370#define MON_BUFF_CYCLE_CNT (0xa03c48)
371 371
372#define DBGC_IN_SAMPLE (0xa03c00) 372#define DBGC_IN_SAMPLE (0xa03c00)
373#define DBGC_OUT_CTRL (0xa03c0c)
374 373
375/* FW chicken bits */ 374/* FW chicken bits */
376#define LMPM_CHICK 0xA01FF8 375#define LMPM_CHICK 0xA01FF8
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index a96bd8db6ceb..542a6810c81c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -595,6 +595,7 @@ enum iwl_d0i3_mode {
595 * @dflt_pwr_limit: default power limit fetched from the platform (ACPI) 595 * @dflt_pwr_limit: default power limit fetched from the platform (ACPI)
596 * @dbg_dest_tlv: points to the destination TLV for debug 596 * @dbg_dest_tlv: points to the destination TLV for debug
597 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug 597 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
598 * @dbg_trigger_tlv: array of pointers to triggers TLVs for debug
598 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv 599 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
599 */ 600 */
600struct iwl_trans { 601struct iwl_trans {
@@ -628,7 +629,8 @@ struct iwl_trans {
628 u64 dflt_pwr_limit; 629 u64 dflt_pwr_limit;
629 630
630 const struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv; 631 const struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
631 const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX]; 632 const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
633 struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv;
632 u8 dbg_dest_reg_num; 634 u8 dbg_dest_reg_num;
633 635
634 enum iwl_d0i3_mode d0i3_mode; 636 enum iwl_d0i3_mode d0i3_mode;
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 1ec4d55155f7..ce99572a982d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -611,7 +611,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
611 bt_cmd->enabled_modules |= 611 bt_cmd->enabled_modules |=
612 cpu_to_le32(BT_COEX_SYNC2SCO_ENABLED); 612 cpu_to_le32(BT_COEX_SYNC2SCO_ENABLED);
613 613
614 if (IWL_MVM_BT_COEX_CORUNNING) 614 if (iwl_mvm_bt_is_plcr_supported(mvm))
615 bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_CORUN_ENABLED); 615 bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_CORUN_ENABLED);
616 616
617 if (IWL_MVM_BT_COEX_MPLUT) { 617 if (IWL_MVM_BT_COEX_MPLUT) {
@@ -1234,7 +1234,7 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
1234 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) 1234 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
1235 return iwl_mvm_rx_ant_coupling_notif_old(mvm, rxb, dev_cmd); 1235 return iwl_mvm_rx_ant_coupling_notif_old(mvm, rxb, dev_cmd);
1236 1236
1237 if (!IWL_MVM_BT_COEX_CORUNNING) 1237 if (!iwl_mvm_bt_is_plcr_supported(mvm))
1238 return 0; 1238 return 0;
1239 1239
1240 lockdep_assert_held(&mvm->mutex); 1240 lockdep_assert_held(&mvm->mutex);
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
index d530ef3da107..9717ee61928c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
@@ -619,7 +619,7 @@ int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm)
619 if (IWL_MVM_BT_COEX_SYNC2SCO) 619 if (IWL_MVM_BT_COEX_SYNC2SCO)
620 bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO); 620 bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO);
621 621
622 if (IWL_MVM_BT_COEX_CORUNNING) { 622 if (iwl_mvm_bt_is_plcr_supported(mvm)) {
623 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 | 623 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 |
624 BT_VALID_CORUN_LUT_40); 624 BT_VALID_CORUN_LUT_40);
625 bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING); 625 bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING);
@@ -1167,16 +1167,10 @@ bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm,
1167 return lut_type != BT_COEX_LOOSE_LUT; 1167 return lut_type != BT_COEX_LOOSE_LUT;
1168} 1168}
1169 1169
1170bool iwl_mvm_bt_coex_is_ant_avail_old(struct iwl_mvm *mvm, u8 ant)
1171{
1172 u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading);
1173 return ag < BT_HIGH_TRAFFIC;
1174}
1175
1176bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm) 1170bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm)
1177{ 1171{
1178 u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading); 1172 u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading);
1179 return ag == BT_OFF; 1173 return ag < BT_HIGH_TRAFFIC;
1180} 1174}
1181 1175
1182bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm, 1176bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm,
@@ -1213,7 +1207,7 @@ int iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,
1213 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 1207 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1214 }; 1208 };
1215 1209
1216 if (!IWL_MVM_BT_COEX_CORUNNING) 1210 if (!iwl_mvm_bt_is_plcr_supported(mvm))
1217 return 0; 1211 return 0;
1218 1212
1219 lockdep_assert_held(&mvm->mutex); 1213 lockdep_assert_held(&mvm->mutex);
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 14e8fd661889..9bdfa95d6ce7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1876,25 +1876,28 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1876 1876
1877 if (mvm->net_detect) { 1877 if (mvm->net_detect) {
1878 iwl_mvm_query_netdetect_reasons(mvm, vif); 1878 iwl_mvm_query_netdetect_reasons(mvm, vif);
1879 /* has unlocked the mutex, so skip that */
1880 goto out;
1879 } else { 1881 } else {
1880 keep = iwl_mvm_query_wakeup_reasons(mvm, vif); 1882 keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
1881#ifdef CONFIG_IWLWIFI_DEBUGFS 1883#ifdef CONFIG_IWLWIFI_DEBUGFS
1882 if (keep) 1884 if (keep)
1883 mvm->keep_vif = vif; 1885 mvm->keep_vif = vif;
1886 /* has unlocked the mutex, so skip that */
1887 goto out_iterate;
1884#endif 1888#endif
1885 } 1889 }
1886 /* has unlocked the mutex, so skip that */
1887 goto out;
1888 1890
1889 out_unlock: 1891 out_unlock:
1890 mutex_unlock(&mvm->mutex); 1892 mutex_unlock(&mvm->mutex);
1891 1893
1892 out: 1894out_iterate:
1893 if (!test) 1895 if (!test)
1894 ieee80211_iterate_active_interfaces_rtnl(mvm->hw, 1896 ieee80211_iterate_active_interfaces_rtnl(mvm->hw,
1895 IEEE80211_IFACE_ITER_NORMAL, 1897 IEEE80211_IFACE_ITER_NORMAL,
1896 iwl_mvm_d3_disconnect_iter, keep ? vif : NULL); 1898 iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);
1897 1899
1900out:
1898 /* return 1 to reconfigure the device */ 1901 /* return 1 to reconfigure the device */
1899 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); 1902 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1900 set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status); 1903 set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status);
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
index 5fe14591e1c4..7faad90386b8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -545,6 +545,57 @@ static ssize_t iwl_dbgfs_uapsd_misbehaving_write(struct ieee80211_vif *vif,
545 return ret ? count : -EINVAL; 545 return ret ? count : -EINVAL;
546} 546}
547 547
548static ssize_t iwl_dbgfs_rx_phyinfo_write(struct ieee80211_vif *vif, char *buf,
549 size_t count, loff_t *ppos)
550{
551 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
552 struct iwl_mvm *mvm = mvmvif->mvm;
553 struct ieee80211_chanctx_conf *chanctx_conf;
554 struct iwl_mvm_phy_ctxt *phy_ctxt;
555 u16 value;
556 int ret;
557
558 ret = kstrtou16(buf, 0, &value);
559 if (ret)
560 return ret;
561
562 mutex_lock(&mvm->mutex);
563 rcu_read_lock();
564
565 chanctx_conf = rcu_dereference(vif->chanctx_conf);
566 /* make sure the channel context is assigned */
567 if (!chanctx_conf) {
568 rcu_read_unlock();
569 mutex_unlock(&mvm->mutex);
570 return -EINVAL;
571 }
572
573 phy_ctxt = &mvm->phy_ctxts[*(u16 *)chanctx_conf->drv_priv];
574 rcu_read_unlock();
575
576 mvm->dbgfs_rx_phyinfo = value;
577
578 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chanctx_conf->min_def,
579 chanctx_conf->rx_chains_static,
580 chanctx_conf->rx_chains_dynamic);
581 mutex_unlock(&mvm->mutex);
582
583 return ret ?: count;
584}
585
586static ssize_t iwl_dbgfs_rx_phyinfo_read(struct file *file,
587 char __user *user_buf,
588 size_t count, loff_t *ppos)
589{
590 struct ieee80211_vif *vif = file->private_data;
591 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
592 char buf[8];
593
594 snprintf(buf, sizeof(buf), "0x%04x\n", mvmvif->mvm->dbgfs_rx_phyinfo);
595
596 return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
597}
598
548#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \ 599#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
549 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif) 600 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
550#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \ 601#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
@@ -560,6 +611,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
560MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256); 611MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
561MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10); 612MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10);
562MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20); 613MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20);
614MVM_DEBUGFS_READ_WRITE_FILE_OPS(rx_phyinfo, 10);
563 615
564void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 616void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
565{ 617{
@@ -595,6 +647,8 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
595 S_IRUSR | S_IWUSR); 647 S_IRUSR | S_IWUSR);
596 MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir, 648 MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir,
597 S_IRUSR | S_IWUSR); 649 S_IRUSR | S_IWUSR);
650 MVM_DEBUGFS_ADD_FILE_VIF(rx_phyinfo, mvmvif->dbgfs_dir,
651 S_IRUSR | S_IWUSR);
598 652
599 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p && 653 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
600 mvmvif == mvm->bf_allowed_vif) 654 mvmvif == mvm->bf_allowed_vif)
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 82c09d86af8c..8cbe77dc1dbb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -942,7 +942,7 @@ static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
942 size_t count, loff_t *ppos) 942 size_t count, loff_t *ppos)
943{ 943{
944 struct iwl_mvm *mvm = file->private_data; 944 struct iwl_mvm *mvm = file->private_data;
945 enum iwl_fw_dbg_conf conf; 945 int conf;
946 char buf[8]; 946 char buf[8];
947 const size_t bufsz = sizeof(buf); 947 const size_t bufsz = sizeof(buf);
948 int pos = 0; 948 int pos = 0;
@@ -966,7 +966,7 @@ static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
966 if (ret) 966 if (ret)
967 return ret; 967 return ret;
968 968
969 if (WARN_ON(conf_id >= FW_DBG_MAX)) 969 if (WARN_ON(conf_id >= FW_DBG_CONF_MAX))
970 return -EINVAL; 970 return -EINVAL;
971 971
972 mutex_lock(&mvm->mutex); 972 mutex_lock(&mvm->mutex);
@@ -985,7 +985,7 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
985 if (ret) 985 if (ret)
986 return ret; 986 return ret;
987 987
988 iwl_mvm_fw_dbg_collect(mvm); 988 iwl_mvm_fw_dbg_collect(mvm, FW_DBG_TRIGGER_USER, NULL, 0, 0);
989 989
990 iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE); 990 iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
991 991
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
index c405cda1025f..aabaedd3b3ee 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -70,6 +70,7 @@
70#define MAC_INDEX_AUX 4 70#define MAC_INDEX_AUX 4
71#define MAC_INDEX_MIN_DRIVER 0 71#define MAC_INDEX_MIN_DRIVER 0
72#define NUM_MAC_INDEX_DRIVER MAC_INDEX_AUX 72#define NUM_MAC_INDEX_DRIVER MAC_INDEX_AUX
73#define NUM_MAC_INDEX (MAC_INDEX_AUX + 1)
73 74
74enum iwl_ac { 75enum iwl_ac {
75 AC_BK, 76 AC_BK,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index cfc0e65b34a5..a5fbbd637070 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -70,55 +70,10 @@
70 70
71/* Scan Commands, Responses, Notifications */ 71/* Scan Commands, Responses, Notifications */
72 72
73/* Masks for iwl_scan_channel.type flags */
74#define SCAN_CHANNEL_TYPE_ACTIVE BIT(0)
75#define SCAN_CHANNEL_NARROW_BAND BIT(22)
76
77/* Max number of IEs for direct SSID scans in a command */ 73/* Max number of IEs for direct SSID scans in a command */
78#define PROBE_OPTION_MAX 20 74#define PROBE_OPTION_MAX 20
79 75
80/** 76/**
81 * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table
82 * @channel: band is selected by iwl_scan_cmd "flags" field
83 * @tx_gain: gain for analog radio
84 * @dsp_atten: gain for DSP
85 * @active_dwell: dwell time for active scan in TU, typically 5-50
86 * @passive_dwell: dwell time for passive scan in TU, typically 20-500
87 * @type: type is broken down to these bits:
88 * bit 0: 0 = passive, 1 = active
89 * bits 1-20: SSID direct bit map. If any of these bits is set then
90 * the corresponding SSID IE is transmitted in probe request
91 * (bit i adds IE in position i to the probe request)
92 * bit 22: channel width, 0 = regular, 1 = TGj narrow channel
93 *
94 * @iteration_count:
95 * @iteration_interval:
96 * This struct is used once for each channel in the scan list.
97 * Each channel can independently select:
98 * 1) SSID for directed active scans
99 * 2) Txpower setting (for rate specified within Tx command)
100 * 3) How long to stay on-channel (behavior may be modified by quiet_time,
101 * quiet_plcp_th, good_CRC_th)
102 *
103 * To avoid uCode errors, make sure the following are true (see comments
104 * under struct iwl_scan_cmd about max_out_time and quiet_time):
105 * 1) If using passive_dwell (i.e. passive_dwell != 0):
106 * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
107 * 2) quiet_time <= active_dwell
108 * 3) If restricting off-channel time (i.e. max_out_time !=0):
109 * passive_dwell < max_out_time
110 * active_dwell < max_out_time
111 */
112struct iwl_scan_channel {
113 __le32 type;
114 __le16 channel;
115 __le16 iteration_count;
116 __le32 iteration_interval;
117 __le16 active_dwell;
118 __le16 passive_dwell;
119} __packed; /* SCAN_CHANNEL_CONTROL_API_S_VER_1 */
120
121/**
122 * struct iwl_ssid_ie - directed scan network information element 77 * struct iwl_ssid_ie - directed scan network information element
123 * 78 *
124 * Up to 20 of these may appear in REPLY_SCAN_CMD, 79 * Up to 20 of these may appear in REPLY_SCAN_CMD,
@@ -132,152 +87,6 @@ struct iwl_ssid_ie {
132 u8 ssid[IEEE80211_MAX_SSID_LEN]; 87 u8 ssid[IEEE80211_MAX_SSID_LEN];
133} __packed; /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */ 88} __packed; /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */
134 89
135/**
136 * iwl_scan_flags - masks for scan command flags
137 *@SCAN_FLAGS_PERIODIC_SCAN:
138 *@SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX:
139 *@SCAN_FLAGS_DELAYED_SCAN_LOWBAND:
140 *@SCAN_FLAGS_DELAYED_SCAN_HIGHBAND:
141 *@SCAN_FLAGS_FRAGMENTED_SCAN:
142 *@SCAN_FLAGS_PASSIVE2ACTIVE: use active scan on channels that was active
143 * in the past hour, even if they are marked as passive.
144 */
145enum iwl_scan_flags {
146 SCAN_FLAGS_PERIODIC_SCAN = BIT(0),
147 SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX = BIT(1),
148 SCAN_FLAGS_DELAYED_SCAN_LOWBAND = BIT(2),
149 SCAN_FLAGS_DELAYED_SCAN_HIGHBAND = BIT(3),
150 SCAN_FLAGS_FRAGMENTED_SCAN = BIT(4),
151 SCAN_FLAGS_PASSIVE2ACTIVE = BIT(5),
152};
153
154/**
155 * enum iwl_scan_type - Scan types for scan command
156 * @SCAN_TYPE_FORCED:
157 * @SCAN_TYPE_BACKGROUND:
158 * @SCAN_TYPE_OS:
159 * @SCAN_TYPE_ROAMING:
160 * @SCAN_TYPE_ACTION:
161 * @SCAN_TYPE_DISCOVERY:
162 * @SCAN_TYPE_DISCOVERY_FORCED:
163 */
164enum iwl_scan_type {
165 SCAN_TYPE_FORCED = 0,
166 SCAN_TYPE_BACKGROUND = 1,
167 SCAN_TYPE_OS = 2,
168 SCAN_TYPE_ROAMING = 3,
169 SCAN_TYPE_ACTION = 4,
170 SCAN_TYPE_DISCOVERY = 5,
171 SCAN_TYPE_DISCOVERY_FORCED = 6,
172}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */
173
174/**
175 * struct iwl_scan_cmd - scan request command
176 * ( SCAN_REQUEST_CMD = 0x80 )
177 * @len: command length in bytes
178 * @scan_flags: scan flags from SCAN_FLAGS_*
179 * @channel_count: num of channels in channel list
180 * (1 - ucode_capa.n_scan_channels)
181 * @quiet_time: in msecs, dwell this time for active scan on quiet channels
182 * @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
183 * this number of packets were received (typically 1)
184 * @passive2active: is auto switching from passive to active during scan allowed
185 * @rxchain_sel_flags: RXON_RX_CHAIN_*
186 * @max_out_time: in TUs, max out of serving channel time
187 * @suspend_time: how long to pause scan when returning to service channel:
188 * bits 0-19: beacon interal in TUs (suspend before executing)
189 * bits 20-23: reserved
190 * bits 24-31: number of beacons (suspend between channels)
191 * @rxon_flags: RXON_FLG_*
192 * @filter_flags: RXON_FILTER_*
193 * @tx_cmd: for active scans (zero for passive), w/o payload,
194 * no RS so specify TX rate
195 * @direct_scan: direct scan SSIDs
196 * @type: one of SCAN_TYPE_*
197 * @repeats: how many time to repeat the scan
198 */
199struct iwl_scan_cmd {
200 __le16 len;
201 u8 scan_flags;
202 u8 channel_count;
203 __le16 quiet_time;
204 __le16 quiet_plcp_th;
205 __le16 passive2active;
206 __le16 rxchain_sel_flags;
207 __le32 max_out_time;
208 __le32 suspend_time;
209 /* RX_ON_FLAGS_API_S_VER_1 */
210 __le32 rxon_flags;
211 __le32 filter_flags;
212 struct iwl_tx_cmd tx_cmd;
213 struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
214 __le32 type;
215 __le32 repeats;
216
217 /*
218 * Probe request frame, followed by channel list.
219 *
220 * Size of probe request frame is specified by byte count in tx_cmd.
221 * Channel list follows immediately after probe request frame.
222 * Number of channels in list is specified by channel_count.
223 * Each channel in list is of type:
224 *
225 * struct iwl_scan_channel channels[0];
226 *
227 * NOTE: Only one band of channels can be scanned per pass. You
228 * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
229 * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
230 * before requesting another scan.
231 */
232 u8 data[0];
233} __packed; /* SCAN_REQUEST_FIXED_PART_API_S_VER_5 */
234
235/* Response to scan request contains only status with one of these values */
236#define SCAN_RESPONSE_OK 0x1
237#define SCAN_RESPONSE_ERROR 0x2
238
239/*
240 * SCAN_ABORT_CMD = 0x81
241 * When scan abort is requested, the command has no fields except the common
242 * header. The response contains only a status with one of these values.
243 */
244#define SCAN_ABORT_POSSIBLE 0x1
245#define SCAN_ABORT_IGNORED 0x2 /* no pending scans */
246
247/* TODO: complete documentation */
248#define SCAN_OWNER_STATUS 0x1
249#define MEASURE_OWNER_STATUS 0x2
250
251/**
252 * struct iwl_scan_start_notif - notifies start of scan in the device
253 * ( SCAN_START_NOTIFICATION = 0x82 )
254 * @tsf_low: TSF timer (lower half) in usecs
255 * @tsf_high: TSF timer (higher half) in usecs
256 * @beacon_timer: structured as follows:
257 * bits 0:19 - beacon interval in usecs
258 * bits 20:23 - reserved (0)
259 * bits 24:31 - number of beacons
260 * @channel: which channel is scanned
261 * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
262 * @status: one of *_OWNER_STATUS
263 */
264struct iwl_scan_start_notif {
265 __le32 tsf_low;
266 __le32 tsf_high;
267 __le32 beacon_timer;
268 u8 channel;
269 u8 band;
270 u8 reserved[2];
271 __le32 status;
272} __packed; /* SCAN_START_NTF_API_S_VER_1 */
273
274/* scan results probe_status first bit indicates success */
275#define SCAN_PROBE_STATUS_OK 0
276#define SCAN_PROBE_STATUS_TX_FAILED BIT(0)
277/* error statuses combined with TX_FAILED */
278#define SCAN_PROBE_STATUS_FAIL_TTL BIT(1)
279#define SCAN_PROBE_STATUS_FAIL_BT BIT(2)
280
281/* How many statistics are gathered for each channel */ 90/* How many statistics are gathered for each channel */
282#define SCAN_RESULTS_STATISTICS 1 91#define SCAN_RESULTS_STATISTICS 1
283 92
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h
index 928168b18346..709e28d8b1b0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h
@@ -65,6 +65,7 @@
65 65
66#ifndef __fw_api_stats_h__ 66#ifndef __fw_api_stats_h__
67#define __fw_api_stats_h__ 67#define __fw_api_stats_h__
68#include "fw-api-mac.h"
68 69
69struct mvm_statistics_dbg { 70struct mvm_statistics_dbg {
70 __le32 burst_check; 71 __le32 burst_check;
@@ -218,7 +219,7 @@ struct mvm_statistics_bt_activity {
218 __le32 lo_priority_rx_denied_cnt; 219 __le32 lo_priority_rx_denied_cnt;
219} __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */ 220} __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
220 221
221struct mvm_statistics_general { 222struct mvm_statistics_general_v5 {
222 __le32 radio_temperature; 223 __le32 radio_temperature;
223 __le32 radio_voltage; 224 __le32 radio_voltage;
224 struct mvm_statistics_dbg dbg; 225 struct mvm_statistics_dbg dbg;
@@ -244,6 +245,39 @@ struct mvm_statistics_general {
244 struct mvm_statistics_bt_activity bt_activity; 245 struct mvm_statistics_bt_activity bt_activity;
245} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */ 246} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
246 247
248struct mvm_statistics_general_v8 {
249 __le32 radio_temperature;
250 __le32 radio_voltage;
251 struct mvm_statistics_dbg dbg;
252 __le32 sleep_time;
253 __le32 slots_out;
254 __le32 slots_idle;
255 __le32 ttl_timestamp;
256 struct mvm_statistics_div slow_div;
257 __le32 rx_enable_counter;
258 /*
259 * num_of_sos_states:
260 * count the number of times we have to re-tune
261 * in order to get out of bad PHY status
262 */
263 __le32 num_of_sos_states;
264 __le32 beacon_filtered;
265 __le32 missed_beacons;
266 __s8 beacon_filter_average_energy;
267 __s8 beacon_filter_reason;
268 __s8 beacon_filter_current_energy;
269 __s8 beacon_filter_reserved;
270 __le32 beacon_filter_delta_time;
271 struct mvm_statistics_bt_activity bt_activity;
272 __le64 rx_time;
273 __le64 on_time_rf;
274 __le64 on_time_scan;
275 __le64 tx_time;
276 __le32 beacon_counter[NUM_MAC_INDEX];
277 u8 beacon_average_energy[NUM_MAC_INDEX];
278 u8 reserved[4 - (NUM_MAC_INDEX % 4)];
279} __packed; /* STATISTICS_GENERAL_API_S_VER_8 */
280
247struct mvm_statistics_rx { 281struct mvm_statistics_rx {
248 struct mvm_statistics_rx_phy ofdm; 282 struct mvm_statistics_rx_phy ofdm;
249 struct mvm_statistics_rx_phy cck; 283 struct mvm_statistics_rx_phy cck;
@@ -256,22 +290,28 @@ struct mvm_statistics_rx {
256 * 290 *
257 * By default, uCode issues this notification after receiving a beacon 291 * By default, uCode issues this notification after receiving a beacon
258 * while associated. To disable this behavior, set DISABLE_NOTIF flag in the 292 * while associated. To disable this behavior, set DISABLE_NOTIF flag in the
259 * REPLY_STATISTICS_CMD 0x9c, above. 293 * STATISTICS_CMD (0x9c), below.
260 *
261 * Statistics counters continue to increment beacon after beacon, but are
262 * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
263 * 0x9c with CLEAR_STATS bit set (see above).
264 *
265 * uCode also issues this notification during scans. uCode clears statistics
266 * appropriately so that each notification contains statistics for only the
267 * one channel that has just been scanned.
268 */ 294 */
269 295
270struct iwl_notif_statistics { 296struct iwl_notif_statistics_v8 {
271 __le32 flag; 297 __le32 flag;
272 struct mvm_statistics_rx rx; 298 struct mvm_statistics_rx rx;
273 struct mvm_statistics_tx tx; 299 struct mvm_statistics_tx tx;
274 struct mvm_statistics_general general; 300 struct mvm_statistics_general_v5 general;
275} __packed; /* STATISTICS_NTFY_API_S_VER_8 */ 301} __packed; /* STATISTICS_NTFY_API_S_VER_8 */
276 302
303struct iwl_notif_statistics_v10 {
304 __le32 flag;
305 struct mvm_statistics_rx rx;
306 struct mvm_statistics_tx tx;
307 struct mvm_statistics_general_v8 general;
308} __packed; /* STATISTICS_NTFY_API_S_VER_10 */
309
310#define IWL_STATISTICS_FLG_CLEAR 0x1
311#define IWL_STATISTICS_FLG_DISABLE_NOTIF 0x2
312
313struct iwl_statistics_cmd {
314 __le32 flags;
315} __packed; /* STATISTICS_CMD_API_S_VER_1 */
316
277#endif /* __fw_api_stats_h__ */ 317#endif /* __fw_api_stats_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index b56154fe8ec5..d95b47213731 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -192,6 +192,7 @@ enum {
192 BEACON_NOTIFICATION = 0x90, 192 BEACON_NOTIFICATION = 0x90,
193 BEACON_TEMPLATE_CMD = 0x91, 193 BEACON_TEMPLATE_CMD = 0x91,
194 TX_ANT_CONFIGURATION_CMD = 0x98, 194 TX_ANT_CONFIGURATION_CMD = 0x98,
195 STATISTICS_CMD = 0x9c,
195 STATISTICS_NOTIFICATION = 0x9d, 196 STATISTICS_NOTIFICATION = 0x9d,
196 EOSP_NOTIFICATION = 0x9e, 197 EOSP_NOTIFICATION = 0x9e,
197 REDUCE_TX_POWER_CMD = 0x9f, 198 REDUCE_TX_POWER_CMD = 0x9f,
@@ -431,7 +432,7 @@ enum {
431 432
432#define IWL_ALIVE_FLG_RFKILL BIT(0) 433#define IWL_ALIVE_FLG_RFKILL BIT(0)
433 434
434struct mvm_alive_resp { 435struct mvm_alive_resp_ver1 {
435 __le16 status; 436 __le16 status;
436 __le16 flags; 437 __le16 flags;
437 u8 ucode_minor; 438 u8 ucode_minor;
@@ -482,6 +483,30 @@ struct mvm_alive_resp_ver2 {
482 __le32 dbg_print_buff_addr; 483 __le32 dbg_print_buff_addr;
483} __packed; /* ALIVE_RES_API_S_VER_2 */ 484} __packed; /* ALIVE_RES_API_S_VER_2 */
484 485
486struct mvm_alive_resp {
487 __le16 status;
488 __le16 flags;
489 __le32 ucode_minor;
490 __le32 ucode_major;
491 u8 ver_subtype;
492 u8 ver_type;
493 u8 mac;
494 u8 opt;
495 __le32 timestamp;
496 __le32 error_event_table_ptr; /* SRAM address for error log */
497 __le32 log_event_table_ptr; /* SRAM address for LMAC event log */
498 __le32 cpu_register_ptr;
499 __le32 dbgm_config_ptr;
500 __le32 alive_counter_ptr;
501 __le32 scd_base_ptr; /* SRAM address for SCD */
502 __le32 st_fwrd_addr; /* pointer to Store and forward */
503 __le32 st_fwrd_size;
504 __le32 umac_minor; /* UMAC version: minor */
505 __le32 umac_major; /* UMAC version: major */
506 __le32 error_info_addr; /* SRAM address for UMAC error log */
507 __le32 dbg_print_buff_addr;
508} __packed; /* ALIVE_RES_API_S_VER_3 */
509
485/* Error response/notification */ 510/* Error response/notification */
486enum { 511enum {
487 FW_ERR_UNKNOWN_CMD = 0x0, 512 FW_ERR_UNKNOWN_CMD = 0x0,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index ca38e9817374..a81da4cde643 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -112,25 +112,27 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
112 struct iwl_mvm *mvm = 112 struct iwl_mvm *mvm =
113 container_of(notif_wait, struct iwl_mvm, notif_wait); 113 container_of(notif_wait, struct iwl_mvm, notif_wait);
114 struct iwl_mvm_alive_data *alive_data = data; 114 struct iwl_mvm_alive_data *alive_data = data;
115 struct mvm_alive_resp *palive; 115 struct mvm_alive_resp_ver1 *palive1;
116 struct mvm_alive_resp_ver2 *palive2; 116 struct mvm_alive_resp_ver2 *palive2;
117 struct mvm_alive_resp *palive;
117 118
118 if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) { 119 if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive1)) {
119 palive = (void *)pkt->data; 120 palive1 = (void *)pkt->data;
120 121
121 mvm->support_umac_log = false; 122 mvm->support_umac_log = false;
122 mvm->error_event_table = 123 mvm->error_event_table =
123 le32_to_cpu(palive->error_event_table_ptr); 124 le32_to_cpu(palive1->error_event_table_ptr);
124 mvm->log_event_table = le32_to_cpu(palive->log_event_table_ptr); 125 mvm->log_event_table =
125 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr); 126 le32_to_cpu(palive1->log_event_table_ptr);
127 alive_data->scd_base_addr = le32_to_cpu(palive1->scd_base_ptr);
126 128
127 alive_data->valid = le16_to_cpu(palive->status) == 129 alive_data->valid = le16_to_cpu(palive1->status) ==
128 IWL_ALIVE_STATUS_OK; 130 IWL_ALIVE_STATUS_OK;
129 IWL_DEBUG_FW(mvm, 131 IWL_DEBUG_FW(mvm,
130 "Alive VER1 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n", 132 "Alive VER1 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
131 le16_to_cpu(palive->status), palive->ver_type, 133 le16_to_cpu(palive1->status), palive1->ver_type,
132 palive->ver_subtype, palive->flags); 134 palive1->ver_subtype, palive1->flags);
133 } else { 135 } else if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive2)) {
134 palive2 = (void *)pkt->data; 136 palive2 = (void *)pkt->data;
135 137
136 mvm->error_event_table = 138 mvm->error_event_table =
@@ -156,6 +158,33 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
156 IWL_DEBUG_FW(mvm, 158 IWL_DEBUG_FW(mvm,
157 "UMAC version: Major - 0x%x, Minor - 0x%x\n", 159 "UMAC version: Major - 0x%x, Minor - 0x%x\n",
158 palive2->umac_major, palive2->umac_minor); 160 palive2->umac_major, palive2->umac_minor);
161 } else if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) {
162 palive = (void *)pkt->data;
163
164 mvm->error_event_table =
165 le32_to_cpu(palive->error_event_table_ptr);
166 mvm->log_event_table =
167 le32_to_cpu(palive->log_event_table_ptr);
168 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr);
169 mvm->umac_error_event_table =
170 le32_to_cpu(palive->error_info_addr);
171 mvm->sf_space.addr = le32_to_cpu(palive->st_fwrd_addr);
172 mvm->sf_space.size = le32_to_cpu(palive->st_fwrd_size);
173
174 alive_data->valid = le16_to_cpu(palive->status) ==
175 IWL_ALIVE_STATUS_OK;
176 if (mvm->umac_error_event_table)
177 mvm->support_umac_log = true;
178
179 IWL_DEBUG_FW(mvm,
180 "Alive VER3 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
181 le16_to_cpu(palive->status), palive->ver_type,
182 palive->ver_subtype, palive->flags);
183
184 IWL_DEBUG_FW(mvm,
185 "UMAC version: Major - 0x%x, Minor - 0x%x\n",
186 le32_to_cpu(palive->umac_major),
187 le32_to_cpu(palive->umac_minor));
159 } 188 }
160 189
161 return true; 190 return true;
@@ -188,8 +217,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
188 struct iwl_sf_region st_fwrd_space; 217 struct iwl_sf_region st_fwrd_space;
189 218
190 if (ucode_type == IWL_UCODE_REGULAR && 219 if (ucode_type == IWL_UCODE_REGULAR &&
191 iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_CUSTOM) && 220 iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE))
192 iwl_fw_dbg_conf_enabled(mvm->fw, FW_DBG_CUSTOM))
193 fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER); 221 fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER);
194 else 222 else
195 fw = iwl_get_ucode_image(mvm, ucode_type); 223 fw = iwl_get_ucode_image(mvm, ucode_type);
@@ -451,20 +479,80 @@ exit:
451 iwl_free_resp(&cmd); 479 iwl_free_resp(&cmd);
452} 480}
453 481
454void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm) 482int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
483 struct iwl_mvm_dump_desc *desc,
484 unsigned int delay)
455{ 485{
486 if (test_and_set_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, &mvm->status))
487 return -EBUSY;
488
489 if (WARN_ON(mvm->fw_dump_desc))
490 iwl_mvm_free_fw_dump_desc(mvm);
491
492 IWL_WARN(mvm, "Collecting data: trigger %d fired.\n",
493 le32_to_cpu(desc->trig_desc.type));
494
495 mvm->fw_dump_desc = desc;
496
456 /* stop recording */ 497 /* stop recording */
457 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 498 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
458 iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); 499 iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
459 } else { 500 } else {
460 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0); 501 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
461 iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0); 502 /* wait before we collect the data till the DBGC stop */
503 udelay(100);
462 } 504 }
463 505
464 schedule_work(&mvm->fw_error_dump_wk); 506 queue_delayed_work(system_wq, &mvm->fw_dump_wk, delay);
507
508 return 0;
465} 509}
466 510
467int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id) 511int iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm, enum iwl_fw_dbg_trigger trig,
512 const char *str, size_t len, unsigned int delay)
513{
514 struct iwl_mvm_dump_desc *desc;
515
516 desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
517 if (!desc)
518 return -ENOMEM;
519
520 desc->len = len;
521 desc->trig_desc.type = cpu_to_le32(trig);
522 memcpy(desc->trig_desc.data, str, len);
523
524 return iwl_mvm_fw_dbg_collect_desc(mvm, desc, delay);
525}
526
527int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
528 struct iwl_fw_dbg_trigger_tlv *trigger,
529 const char *str, size_t len)
530{
531 unsigned int delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay));
532 u16 occurrences = le16_to_cpu(trigger->occurrences);
533 int ret;
534
535 if (!occurrences)
536 return 0;
537
538 ret = iwl_mvm_fw_dbg_collect(mvm, le32_to_cpu(trigger->id), str,
539 len, delay);
540 if (ret)
541 return ret;
542
543 trigger->occurrences = cpu_to_le16(occurrences - 1);
544 return 0;
545}
546
547static inline void iwl_mvm_restart_early_start(struct iwl_mvm *mvm)
548{
549 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000)
550 iwl_clear_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
551 else
552 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 1);
553}
554
555int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
468{ 556{
469 u8 *ptr; 557 u8 *ptr;
470 int ret; 558 int ret;
@@ -474,6 +562,14 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id)
474 "Invalid configuration %d\n", conf_id)) 562 "Invalid configuration %d\n", conf_id))
475 return -EINVAL; 563 return -EINVAL;
476 564
565 /* EARLY START - firmware's configuration is hard coded */
566 if ((!mvm->fw->dbg_conf_tlv[conf_id] ||
567 !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) &&
568 conf_id == FW_DBG_START_FROM_ALIVE) {
569 iwl_mvm_restart_early_start(mvm);
570 return 0;
571 }
572
477 if (!mvm->fw->dbg_conf_tlv[conf_id]) 573 if (!mvm->fw->dbg_conf_tlv[conf_id])
478 return -EINVAL; 574 return -EINVAL;
479 575
@@ -583,7 +679,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
583 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n"); 679 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
584 680
585 mvm->fw_dbg_conf = FW_DBG_INVALID; 681 mvm->fw_dbg_conf = FW_DBG_INVALID;
586 iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_CUSTOM); 682 /* if we have a destination, assume EARLY START */
683 if (mvm->fw->dbg_dest_tlv)
684 mvm->fw_dbg_conf = FW_DBG_START_FROM_ALIVE;
685 iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_START_FROM_ALIVE);
587 686
588 ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm)); 687 ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
589 if (ret) 688 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 7bdc6220743f..581b3b8f29f9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -244,6 +244,7 @@ static void iwl_mvm_mac_sta_hw_queues_iter(void *_data,
244unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, 244unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
245 struct ieee80211_vif *exclude_vif) 245 struct ieee80211_vif *exclude_vif)
246{ 246{
247 u8 sta_id;
247 struct iwl_mvm_hw_queues_iface_iterator_data data = { 248 struct iwl_mvm_hw_queues_iface_iterator_data data = {
248 .exclude_vif = exclude_vif, 249 .exclude_vif = exclude_vif,
249 .used_hw_queues = 250 .used_hw_queues =
@@ -264,6 +265,13 @@ unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
264 iwl_mvm_mac_sta_hw_queues_iter, 265 iwl_mvm_mac_sta_hw_queues_iter,
265 &data); 266 &data);
266 267
268 /*
269 * Some TDLS stations may be removed but are in the process of being
270 * drained. Don't touch their queues.
271 */
272 for_each_set_bit(sta_id, mvm->sta_drained, IWL_MVM_STATION_COUNT)
273 data.used_hw_queues |= mvm->tfd_drained[sta_id];
274
267 return data.used_hw_queues; 275 return data.used_hw_queues;
268} 276}
269 277
@@ -1367,10 +1375,18 @@ static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
1367{ 1375{
1368 struct iwl_missed_beacons_notif *missed_beacons = _data; 1376 struct iwl_missed_beacons_notif *missed_beacons = _data;
1369 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1377 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1378 struct iwl_mvm *mvm = mvmvif->mvm;
1379 struct iwl_fw_dbg_trigger_missed_bcon *bcon_trig;
1380 struct iwl_fw_dbg_trigger_tlv *trigger;
1381 u32 stop_trig_missed_bcon, stop_trig_missed_bcon_since_rx;
1382 u32 rx_missed_bcon, rx_missed_bcon_since_rx;
1370 1383
1371 if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id)) 1384 if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id))
1372 return; 1385 return;
1373 1386
1387 rx_missed_bcon = le32_to_cpu(missed_beacons->consec_missed_beacons);
1388 rx_missed_bcon_since_rx =
1389 le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx);
1374 /* 1390 /*
1375 * TODO: the threshold should be adjusted based on latency conditions, 1391 * TODO: the threshold should be adjusted based on latency conditions,
1376 * and/or in case of a CS flow on one of the other AP vifs. 1392 * and/or in case of a CS flow on one of the other AP vifs.
@@ -1378,6 +1394,26 @@ static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
1378 if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) > 1394 if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) >
1379 IWL_MVM_MISSED_BEACONS_THRESHOLD) 1395 IWL_MVM_MISSED_BEACONS_THRESHOLD)
1380 ieee80211_beacon_loss(vif); 1396 ieee80211_beacon_loss(vif);
1397
1398 if (!iwl_fw_dbg_trigger_enabled(mvm->fw,
1399 FW_DBG_TRIGGER_MISSED_BEACONS))
1400 return;
1401
1402 trigger = iwl_fw_dbg_get_trigger(mvm->fw,
1403 FW_DBG_TRIGGER_MISSED_BEACONS);
1404 bcon_trig = (void *)trigger->data;
1405 stop_trig_missed_bcon = le32_to_cpu(bcon_trig->stop_consec_missed_bcon);
1406 stop_trig_missed_bcon_since_rx =
1407 le32_to_cpu(bcon_trig->stop_consec_missed_bcon_since_rx);
1408
1409 /* TODO: implement start trigger */
1410
1411 if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trigger))
1412 return;
1413
1414 if (rx_missed_bcon_since_rx >= stop_trig_missed_bcon_since_rx ||
1415 rx_missed_bcon >= stop_trig_missed_bcon)
1416 iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL, 0);
1381} 1417}
1382 1418
1383int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, 1419int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 1ff7ec08532d..5a5d5c8544fc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -339,13 +339,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
339 !iwlwifi_mod_params.sw_crypto) 339 !iwlwifi_mod_params.sw_crypto)
340 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 340 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
341 341
342 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN || 342 hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS;
343 mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { 343 hw->wiphy->features |=
344 hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS; 344 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
345 hw->wiphy->features |= 345 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
346 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
347 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
348 }
349 346
350 hw->sta_data_size = sizeof(struct iwl_mvm_sta); 347 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
351 hw->vif_data_size = sizeof(struct iwl_mvm_vif); 348 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
@@ -889,12 +886,23 @@ static void iwl_mvm_dump_fifos(struct iwl_mvm *mvm,
889 iwl_trans_release_nic_access(mvm->trans, &flags); 886 iwl_trans_release_nic_access(mvm->trans, &flags);
890} 887}
891 888
889void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm)
890{
891 if (mvm->fw_dump_desc == &iwl_mvm_dump_desc_assert ||
892 !mvm->fw_dump_desc)
893 return;
894
895 kfree(mvm->fw_dump_desc);
896 mvm->fw_dump_desc = NULL;
897}
898
892void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) 899void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
893{ 900{
894 struct iwl_fw_error_dump_file *dump_file; 901 struct iwl_fw_error_dump_file *dump_file;
895 struct iwl_fw_error_dump_data *dump_data; 902 struct iwl_fw_error_dump_data *dump_data;
896 struct iwl_fw_error_dump_info *dump_info; 903 struct iwl_fw_error_dump_info *dump_info;
897 struct iwl_fw_error_dump_mem *dump_mem; 904 struct iwl_fw_error_dump_mem *dump_mem;
905 struct iwl_fw_error_dump_trigger_desc *dump_trig;
898 struct iwl_mvm_dump_ptrs *fw_error_dump; 906 struct iwl_mvm_dump_ptrs *fw_error_dump;
899 u32 sram_len, sram_ofs; 907 u32 sram_len, sram_ofs;
900 u32 file_len, fifo_data_len = 0; 908 u32 file_len, fifo_data_len = 0;
@@ -964,6 +972,10 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
964 fifo_data_len + 972 fifo_data_len +
965 sizeof(*dump_info); 973 sizeof(*dump_info);
966 974
975 if (mvm->fw_dump_desc)
976 file_len += sizeof(*dump_data) + sizeof(*dump_trig) +
977 mvm->fw_dump_desc->len;
978
967 /* Make room for the SMEM, if it exists */ 979 /* Make room for the SMEM, if it exists */
968 if (smem_len) 980 if (smem_len)
969 file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len; 981 file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len;
@@ -975,6 +987,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
975 dump_file = vzalloc(file_len); 987 dump_file = vzalloc(file_len);
976 if (!dump_file) { 988 if (!dump_file) {
977 kfree(fw_error_dump); 989 kfree(fw_error_dump);
990 iwl_mvm_free_fw_dump_desc(mvm);
978 return; 991 return;
979 } 992 }
980 993
@@ -1003,6 +1016,19 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
1003 if (test_bit(STATUS_FW_ERROR, &mvm->trans->status)) 1016 if (test_bit(STATUS_FW_ERROR, &mvm->trans->status))
1004 iwl_mvm_dump_fifos(mvm, &dump_data); 1017 iwl_mvm_dump_fifos(mvm, &dump_data);
1005 1018
1019 if (mvm->fw_dump_desc) {
1020 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_ERROR_INFO);
1021 dump_data->len = cpu_to_le32(sizeof(*dump_trig) +
1022 mvm->fw_dump_desc->len);
1023 dump_trig = (void *)dump_data->data;
1024 memcpy(dump_trig, &mvm->fw_dump_desc->trig_desc,
1025 sizeof(*dump_trig) + mvm->fw_dump_desc->len);
1026
1027 /* now we can free this copy */
1028 iwl_mvm_free_fw_dump_desc(mvm);
1029 dump_data = iwl_fw_error_next_data(dump_data);
1030 }
1031
1006 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); 1032 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
1007 dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem)); 1033 dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem));
1008 dump_mem = (void *)dump_data->data; 1034 dump_mem = (void *)dump_data->data;
@@ -1041,16 +1067,26 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
1041 1067
1042 dev_coredumpm(mvm->trans->dev, THIS_MODULE, fw_error_dump, 0, 1068 dev_coredumpm(mvm->trans->dev, THIS_MODULE, fw_error_dump, 0,
1043 GFP_KERNEL, iwl_mvm_read_coredump, iwl_mvm_free_coredump); 1069 GFP_KERNEL, iwl_mvm_read_coredump, iwl_mvm_free_coredump);
1070
1071 clear_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, &mvm->status);
1044} 1072}
1045 1073
1074struct iwl_mvm_dump_desc iwl_mvm_dump_desc_assert = {
1075 .trig_desc = {
1076 .type = cpu_to_le32(FW_DBG_TRIGGER_FW_ASSERT),
1077 },
1078};
1079
1046static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) 1080static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
1047{ 1081{
1048 /* clear the D3 reconfig, we only need it to avoid dumping a 1082 /* clear the D3 reconfig, we only need it to avoid dumping a
1049 * firmware coredump on reconfiguration, we shouldn't do that 1083 * firmware coredump on reconfiguration, we shouldn't do that
1050 * on D3->D0 transition 1084 * on D3->D0 transition
1051 */ 1085 */
1052 if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status)) 1086 if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status)) {
1087 mvm->fw_dump_desc = &iwl_mvm_dump_desc_assert;
1053 iwl_mvm_fw_error_dump(mvm); 1088 iwl_mvm_fw_error_dump(mvm);
1089 }
1054 1090
1055 /* cleanup all stale references (scan, roc), but keep the 1091 /* cleanup all stale references (scan, roc), but keep the
1056 * ucode_down ref until reconfig is complete 1092 * ucode_down ref until reconfig is complete
@@ -1091,6 +1127,10 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
1091 1127
1092 mvm->vif_count = 0; 1128 mvm->vif_count = 0;
1093 mvm->rx_ba_sessions = 0; 1129 mvm->rx_ba_sessions = 0;
1130 mvm->fw_dbg_conf = FW_DBG_INVALID;
1131
1132 /* keep statistics ticking */
1133 iwl_mvm_accu_radio_stats(mvm);
1094} 1134}
1095 1135
1096int __iwl_mvm_mac_start(struct iwl_mvm *mvm) 1136int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
@@ -1213,6 +1253,11 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
1213{ 1253{
1214 lockdep_assert_held(&mvm->mutex); 1254 lockdep_assert_held(&mvm->mutex);
1215 1255
1256 /* firmware counters are obviously reset now, but we shouldn't
1257 * partially track so also clear the fw_reset_accu counters.
1258 */
1259 memset(&mvm->accu_radio_stats, 0, sizeof(mvm->accu_radio_stats));
1260
1216 /* 1261 /*
1217 * Disallow low power states when the FW is down by taking 1262 * Disallow low power states when the FW is down by taking
1218 * the UCODE_DOWN ref. in case of ongoing hw restart the 1263 * the UCODE_DOWN ref. in case of ongoing hw restart the
@@ -1252,7 +1297,8 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
1252 1297
1253 flush_work(&mvm->d0i3_exit_work); 1298 flush_work(&mvm->d0i3_exit_work);
1254 flush_work(&mvm->async_handlers_wk); 1299 flush_work(&mvm->async_handlers_wk);
1255 flush_work(&mvm->fw_error_dump_wk); 1300 cancel_delayed_work_sync(&mvm->fw_dump_wk);
1301 iwl_mvm_free_fw_dump_desc(mvm);
1256 1302
1257 mutex_lock(&mvm->mutex); 1303 mutex_lock(&mvm->mutex);
1258 __iwl_mvm_mac_stop(mvm); 1304 __iwl_mvm_mac_stop(mvm);
@@ -1317,6 +1363,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1317 1363
1318 mutex_lock(&mvm->mutex); 1364 mutex_lock(&mvm->mutex);
1319 1365
1366 /* make sure that beacon statistics don't go backwards with FW reset */
1367 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
1368 mvmvif->beacon_stats.accu_num_beacons +=
1369 mvmvif->beacon_stats.num_beacons;
1370
1320 /* Allocate resources for the MAC context, and add it to the fw */ 1371 /* Allocate resources for the MAC context, and add it to the fw */
1321 ret = iwl_mvm_mac_ctxt_init(mvm, vif); 1372 ret = iwl_mvm_mac_ctxt_init(mvm, vif);
1322 if (ret) 1373 if (ret)
@@ -1810,6 +1861,11 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1810 1861
1811 if (changes & BSS_CHANGED_ASSOC) { 1862 if (changes & BSS_CHANGED_ASSOC) {
1812 if (bss_conf->assoc) { 1863 if (bss_conf->assoc) {
1864 /* clear statistics to get clean beacon counter */
1865 iwl_mvm_request_statistics(mvm, true);
1866 memset(&mvmvif->beacon_stats, 0,
1867 sizeof(mvmvif->beacon_stats));
1868
1813 /* add quota for this interface */ 1869 /* add quota for this interface */
1814 ret = iwl_mvm_update_quotas(mvm, NULL); 1870 ret = iwl_mvm_update_quotas(mvm, NULL);
1815 if (ret) { 1871 if (ret) {
@@ -2196,10 +2252,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
2196 2252
2197 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) 2253 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)
2198 ret = iwl_mvm_scan_umac(mvm, vif, hw_req); 2254 ret = iwl_mvm_scan_umac(mvm, vif, hw_req);
2199 else if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
2200 ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req);
2201 else 2255 else
2202 ret = iwl_mvm_scan_request(mvm, vif, req); 2256 ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req);
2203 2257
2204 if (ret) 2258 if (ret)
2205 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 2259 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
@@ -2527,13 +2581,7 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
2527 2581
2528 mutex_lock(&mvm->mutex); 2582 mutex_lock(&mvm->mutex);
2529 2583
2530 /* Newest FW fixes sched scan while connected on another interface */ 2584 if (!vif->bss_conf.idle) {
2531 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) {
2532 if (!vif->bss_conf.idle) {
2533 ret = -EBUSY;
2534 goto out;
2535 }
2536 } else if (!iwl_mvm_is_idle(mvm)) {
2537 ret = -EBUSY; 2585 ret = -EBUSY;
2538 goto out; 2586 goto out;
2539 } 2587 }
@@ -3433,6 +3481,9 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
3433 IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n", 3481 IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n",
3434 chsw->chandef.center_freq1); 3482 chsw->chandef.center_freq1);
3435 3483
3484 iwl_fw_dbg_trigger_simple_stop(mvm, vif, FW_DBG_TRIGGER_CHANNEL_SWITCH,
3485 NULL, 0);
3486
3436 switch (vif->type) { 3487 switch (vif->type) {
3437 case NL80211_IFTYPE_AP: 3488 case NL80211_IFTYPE_AP:
3438 csa_vif = 3489 csa_vif =
@@ -3581,6 +3632,95 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
3581 } 3632 }
3582} 3633}
3583 3634
3635static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx,
3636 struct survey_info *survey)
3637{
3638 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3639 int ret;
3640
3641 memset(survey, 0, sizeof(*survey));
3642
3643 /* only support global statistics right now */
3644 if (idx != 0)
3645 return -ENOENT;
3646
3647 if (!(mvm->fw->ucode_capa.capa[0] &
3648 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
3649 return -ENOENT;
3650
3651 mutex_lock(&mvm->mutex);
3652
3653 if (mvm->ucode_loaded) {
3654 ret = iwl_mvm_request_statistics(mvm, false);
3655 if (ret)
3656 goto out;
3657 }
3658
3659 survey->filled = SURVEY_INFO_TIME |
3660 SURVEY_INFO_TIME_RX |
3661 SURVEY_INFO_TIME_TX |
3662 SURVEY_INFO_TIME_SCAN;
3663 survey->time = mvm->accu_radio_stats.on_time_rf +
3664 mvm->radio_stats.on_time_rf;
3665 do_div(survey->time, USEC_PER_MSEC);
3666
3667 survey->time_rx = mvm->accu_radio_stats.rx_time +
3668 mvm->radio_stats.rx_time;
3669 do_div(survey->time_rx, USEC_PER_MSEC);
3670
3671 survey->time_tx = mvm->accu_radio_stats.tx_time +
3672 mvm->radio_stats.tx_time;
3673 do_div(survey->time_tx, USEC_PER_MSEC);
3674
3675 survey->time_scan = mvm->accu_radio_stats.on_time_scan +
3676 mvm->radio_stats.on_time_scan;
3677 do_div(survey->time_scan, USEC_PER_MSEC);
3678
3679 out:
3680 mutex_unlock(&mvm->mutex);
3681 return ret;
3682}
3683
3684static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw,
3685 struct ieee80211_vif *vif,
3686 struct ieee80211_sta *sta,
3687 struct station_info *sinfo)
3688{
3689 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3690 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3691 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
3692
3693 if (!(mvm->fw->ucode_capa.capa[0] &
3694 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
3695 return;
3696
3697 /* if beacon filtering isn't on mac80211 does it anyway */
3698 if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
3699 return;
3700
3701 if (!vif->bss_conf.assoc)
3702 return;
3703
3704 mutex_lock(&mvm->mutex);
3705
3706 if (mvmvif->ap_sta_id != mvmsta->sta_id)
3707 goto unlock;
3708
3709 if (iwl_mvm_request_statistics(mvm, false))
3710 goto unlock;
3711
3712 sinfo->rx_beacon = mvmvif->beacon_stats.num_beacons +
3713 mvmvif->beacon_stats.accu_num_beacons;
3714 sinfo->filled |= BIT(NL80211_STA_INFO_BEACON_RX);
3715 if (mvmvif->beacon_stats.avg_signal) {
3716 /* firmware only reports a value after RXing a few beacons */
3717 sinfo->rx_beacon_signal_avg = mvmvif->beacon_stats.avg_signal;
3718 sinfo->filled |= BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG);
3719 }
3720 unlock:
3721 mutex_unlock(&mvm->mutex);
3722}
3723
3584const struct ieee80211_ops iwl_mvm_hw_ops = { 3724const struct ieee80211_ops iwl_mvm_hw_ops = {
3585 .tx = iwl_mvm_mac_tx, 3725 .tx = iwl_mvm_mac_tx,
3586 .ampdu_action = iwl_mvm_mac_ampdu_action, 3726 .ampdu_action = iwl_mvm_mac_ampdu_action,
@@ -3647,4 +3787,6 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
3647#endif 3787#endif
3648 .set_default_unicast_key = iwl_mvm_set_default_unicast_key, 3788 .set_default_unicast_key = iwl_mvm_set_default_unicast_key,
3649#endif 3789#endif
3790 .get_survey = iwl_mvm_mac_get_survey,
3791 .sta_statistics = iwl_mvm_mac_sta_statistics,
3650}; 3792};
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 6c69d0584f6c..f4ecd1bde1cf 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -75,6 +75,7 @@
75#include "iwl-trans.h" 75#include "iwl-trans.h"
76#include "iwl-notif-wait.h" 76#include "iwl-notif-wait.h"
77#include "iwl-eeprom-parse.h" 77#include "iwl-eeprom-parse.h"
78#include "iwl-fw-file.h"
78#include "sta.h" 79#include "sta.h"
79#include "fw-api.h" 80#include "fw-api.h"
80#include "constants.h" 81#include "constants.h"
@@ -145,6 +146,19 @@ struct iwl_mvm_dump_ptrs {
145 u32 op_mode_len; 146 u32 op_mode_len;
146}; 147};
147 148
149/**
150 * struct iwl_mvm_dump_desc - describes the dump
151 * @len: length of trig_desc->data
152 * @trig_desc: the description of the dump
153 */
154struct iwl_mvm_dump_desc {
155 size_t len;
156 /* must be last */
157 struct iwl_fw_error_dump_trigger_desc trig_desc;
158};
159
160extern struct iwl_mvm_dump_desc iwl_mvm_dump_desc_assert;
161
148struct iwl_mvm_phy_ctxt { 162struct iwl_mvm_phy_ctxt {
149 u16 id; 163 u16 id;
150 u16 color; 164 u16 color;
@@ -337,6 +351,9 @@ struct iwl_mvm_vif_bf_data {
337 * @beacon_skb: the skb used to hold the AP/GO beacon template 351 * @beacon_skb: the skb used to hold the AP/GO beacon template
338 * @smps_requests: the SMPS requests of differents parts of the driver, 352 * @smps_requests: the SMPS requests of differents parts of the driver,
339 * combined on update to yield the overall request to mac80211. 353 * combined on update to yield the overall request to mac80211.
354 * @beacon_stats: beacon statistics, containing the # of received beacons,
355 * # of received beacons accumulated over FW restart, and the current
356 * average signal of beacons retrieved from the firmware
340 */ 357 */
341struct iwl_mvm_vif { 358struct iwl_mvm_vif {
342 u16 id; 359 u16 id;
@@ -354,6 +371,11 @@ struct iwl_mvm_vif {
354 bool ps_disabled; 371 bool ps_disabled;
355 struct iwl_mvm_vif_bf_data bf_data; 372 struct iwl_mvm_vif_bf_data bf_data;
356 373
374 struct {
375 u32 num_beacons, accu_num_beacons;
376 u8 avg_signal;
377 } beacon_stats;
378
357 u32 ap_beacon_time; 379 u32 ap_beacon_time;
358 380
359 enum iwl_tsf_id tsf_id; 381 enum iwl_tsf_id tsf_id;
@@ -593,6 +615,13 @@ struct iwl_mvm {
593 615
594 struct mvm_statistics_rx rx_stats; 616 struct mvm_statistics_rx rx_stats;
595 617
618 struct {
619 u64 rx_time;
620 u64 tx_time;
621 u64 on_time_rf;
622 u64 on_time_scan;
623 } radio_stats, accu_radio_stats;
624
596 u8 queue_to_mac80211[IWL_MAX_HW_QUEUES]; 625 u8 queue_to_mac80211[IWL_MAX_HW_QUEUES];
597 atomic_t mac80211_queue_stop_count[IEEE80211_MAX_QUEUES]; 626 atomic_t mac80211_queue_stop_count[IEEE80211_MAX_QUEUES];
598 627
@@ -666,6 +695,7 @@ struct iwl_mvm {
666 695
667 struct iwl_mvm_frame_stats drv_rx_stats; 696 struct iwl_mvm_frame_stats drv_rx_stats;
668 spinlock_t drv_stats_lock; 697 spinlock_t drv_stats_lock;
698 u16 dbgfs_rx_phyinfo;
669#endif 699#endif
670 700
671 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX]; 701 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
@@ -687,8 +717,9 @@ struct iwl_mvm {
687 717
688 /* -1 for always, 0 for never, >0 for that many times */ 718 /* -1 for always, 0 for never, >0 for that many times */
689 s8 restart_fw; 719 s8 restart_fw;
690 struct work_struct fw_error_dump_wk; 720 u8 fw_dbg_conf;
691 enum iwl_fw_dbg_conf fw_dbg_conf; 721 struct delayed_work fw_dump_wk;
722 struct iwl_mvm_dump_desc *fw_dump_desc;
692 723
693#ifdef CONFIG_IWLWIFI_LEDS 724#ifdef CONFIG_IWLWIFI_LEDS
694 struct led_classdev led; 725 struct led_classdev led;
@@ -824,6 +855,7 @@ enum iwl_mvm_status {
824 IWL_MVM_STATUS_IN_D0I3, 855 IWL_MVM_STATUS_IN_D0I3,
825 IWL_MVM_STATUS_ROC_AUX_RUNNING, 856 IWL_MVM_STATUS_ROC_AUX_RUNNING,
826 IWL_MVM_STATUS_D3_RECONFIG, 857 IWL_MVM_STATUS_D3_RECONFIG,
858 IWL_MVM_STATUS_DUMPING_FW_LOG,
827}; 859};
828 860
829static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm) 861static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
@@ -883,6 +915,12 @@ static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm)
883 return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SCD_CFG; 915 return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SCD_CFG;
884} 916}
885 917
918static inline bool iwl_mvm_bt_is_plcr_supported(struct iwl_mvm *mvm)
919{
920 return (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_BT_COEX_PLCR) &&
921 IWL_MVM_BT_COEX_CORUNNING;
922}
923
886extern const u8 iwl_mvm_ac_to_tx_fifo[]; 924extern const u8 iwl_mvm_ac_to_tx_fifo[];
887 925
888struct iwl_rate_info { 926struct iwl_rate_info {
@@ -951,12 +989,13 @@ static inline void iwl_mvm_wait_for_async_handlers(struct iwl_mvm *mvm)
951} 989}
952 990
953/* Statistics */ 991/* Statistics */
954int iwl_mvm_rx_reply_statistics(struct iwl_mvm *mvm, 992void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
955 struct iwl_rx_cmd_buffer *rxb, 993 struct iwl_rx_packet *pkt);
956 struct iwl_device_cmd *cmd);
957int iwl_mvm_rx_statistics(struct iwl_mvm *mvm, 994int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
958 struct iwl_rx_cmd_buffer *rxb, 995 struct iwl_rx_cmd_buffer *rxb,
959 struct iwl_device_cmd *cmd); 996 struct iwl_device_cmd *cmd);
997int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear);
998void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm);
960 999
961/* NVM */ 1000/* NVM */
962int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic); 1001int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic);
@@ -1072,13 +1111,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
1072 1111
1073/* Scanning */ 1112/* Scanning */
1074int iwl_mvm_scan_size(struct iwl_mvm *mvm); 1113int iwl_mvm_scan_size(struct iwl_mvm *mvm);
1075int iwl_mvm_scan_request(struct iwl_mvm *mvm,
1076 struct ieee80211_vif *vif,
1077 struct cfg80211_scan_request *req);
1078int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
1079 struct iwl_device_cmd *cmd);
1080int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
1081 struct iwl_device_cmd *cmd);
1082int iwl_mvm_cancel_scan(struct iwl_mvm *mvm); 1114int iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
1083int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan); 1115int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan);
1084 1116
@@ -1089,14 +1121,8 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
1089int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, 1121int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
1090 struct iwl_rx_cmd_buffer *rxb, 1122 struct iwl_rx_cmd_buffer *rxb,
1091 struct iwl_device_cmd *cmd); 1123 struct iwl_device_cmd *cmd);
1092int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
1093 struct ieee80211_vif *vif,
1094 struct cfg80211_sched_scan_request *req,
1095 struct ieee80211_scan_ies *ies);
1096int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, 1124int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
1097 struct cfg80211_sched_scan_request *req); 1125 struct cfg80211_sched_scan_request *req);
1098int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
1099 struct cfg80211_sched_scan_request *req);
1100int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, 1126int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm,
1101 struct ieee80211_vif *vif, 1127 struct ieee80211_vif *vif,
1102 struct cfg80211_sched_scan_request *req, 1128 struct cfg80211_sched_scan_request *req,
@@ -1238,7 +1264,6 @@ bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
1238u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, 1264u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
1239 struct ieee80211_tx_info *info, u8 ac); 1265 struct ieee80211_tx_info *info, u8 ac);
1240 1266
1241bool iwl_mvm_bt_coex_is_ant_avail_old(struct iwl_mvm *mvm, u8 ant);
1242bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm); 1267bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm);
1243void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm); 1268void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm);
1244int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm); 1269int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm);
@@ -1352,9 +1377,6 @@ static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue,
1352 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg, wdg_timeout); 1377 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg, wdg_timeout);
1353} 1378}
1354 1379
1355/* Assoc status */
1356bool iwl_mvm_is_idle(struct iwl_mvm *mvm);
1357
1358/* Thermal management and CT-kill */ 1380/* Thermal management and CT-kill */
1359void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); 1381void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff);
1360void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp); 1382void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp);
@@ -1405,7 +1427,62 @@ struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm);
1405void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error); 1427void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error);
1406void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm); 1428void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
1407 1429
1408int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf id); 1430int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 id);
1409void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm); 1431int iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm, enum iwl_fw_dbg_trigger trig,
1432 const char *str, size_t len, unsigned int delay);
1433int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
1434 struct iwl_mvm_dump_desc *desc,
1435 unsigned int delay);
1436void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm);
1437int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
1438 struct iwl_fw_dbg_trigger_tlv *trigger,
1439 const char *str, size_t len);
1440
1441static inline bool
1442iwl_fw_dbg_trigger_vif_match(struct iwl_fw_dbg_trigger_tlv *trig,
1443 struct ieee80211_vif *vif)
1444{
1445 u32 trig_vif = le32_to_cpu(trig->vif_type);
1446
1447 return trig_vif == IWL_FW_DBG_CONF_VIF_ANY || vif->type == trig_vif;
1448}
1449
1450static inline bool
1451iwl_fw_dbg_trigger_stop_conf_match(struct iwl_mvm *mvm,
1452 struct iwl_fw_dbg_trigger_tlv *trig)
1453{
1454 return ((trig->mode & IWL_FW_DBG_TRIGGER_STOP) &&
1455 (mvm->fw_dbg_conf == FW_DBG_INVALID ||
1456 (BIT(mvm->fw_dbg_conf) & le32_to_cpu(trig->stop_conf_ids))));
1457}
1458
1459static inline bool
1460iwl_fw_dbg_trigger_check_stop(struct iwl_mvm *mvm,
1461 struct ieee80211_vif *vif,
1462 struct iwl_fw_dbg_trigger_tlv *trig)
1463{
1464 if (vif && !iwl_fw_dbg_trigger_vif_match(trig, vif))
1465 return false;
1466
1467 return iwl_fw_dbg_trigger_stop_conf_match(mvm, trig);
1468}
1469
1470static inline void
1471iwl_fw_dbg_trigger_simple_stop(struct iwl_mvm *mvm,
1472 struct ieee80211_vif *vif,
1473 enum iwl_fw_dbg_trigger trig,
1474 const char *str, size_t len)
1475{
1476 struct iwl_fw_dbg_trigger_tlv *trigger;
1477
1478 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, trig))
1479 return;
1480
1481 trigger = iwl_fw_dbg_get_trigger(mvm->fw, trig);
1482 if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trigger))
1483 return;
1484
1485 iwl_mvm_fw_dbg_collect_trig(mvm, trigger, str, len);
1486}
1410 1487
1411#endif /* __IWL_MVM_H__ */ 1488#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 2dffc3600ed3..fe40922a6b0d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -237,8 +237,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
237 237
238 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false), 238 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false),
239 239
240 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
241 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
242 RX_HANDLER(SCAN_ITERATION_COMPLETE, 240 RX_HANDLER(SCAN_ITERATION_COMPLETE,
243 iwl_mvm_rx_scan_offload_iter_complete_notif, false), 241 iwl_mvm_rx_scan_offload_iter_complete_notif, false),
244 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 242 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
@@ -311,6 +309,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
311 CMD(REPLY_RX_MPDU_CMD), 309 CMD(REPLY_RX_MPDU_CMD),
312 CMD(BEACON_NOTIFICATION), 310 CMD(BEACON_NOTIFICATION),
313 CMD(BEACON_TEMPLATE_CMD), 311 CMD(BEACON_TEMPLATE_CMD),
312 CMD(STATISTICS_CMD),
314 CMD(STATISTICS_NOTIFICATION), 313 CMD(STATISTICS_NOTIFICATION),
315 CMD(EOSP_NOTIFICATION), 314 CMD(EOSP_NOTIFICATION),
316 CMD(REDUCE_TX_POWER_CMD), 315 CMD(REDUCE_TX_POWER_CMD),
@@ -456,7 +455,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
456 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); 455 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk);
457 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk); 456 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk);
458 INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); 457 INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work);
459 INIT_WORK(&mvm->fw_error_dump_wk, iwl_mvm_fw_error_dump_wk); 458 INIT_DELAYED_WORK(&mvm->fw_dump_wk, iwl_mvm_fw_error_dump_wk);
460 INIT_DELAYED_WORK(&mvm->tdls_cs.dwork, iwl_mvm_tdls_ch_switch_work); 459 INIT_DELAYED_WORK(&mvm->tdls_cs.dwork, iwl_mvm_tdls_ch_switch_work);
461 460
462 spin_lock_init(&mvm->d0i3_tx_lock); 461 spin_lock_init(&mvm->d0i3_tx_lock);
@@ -504,6 +503,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
504 trans->dbg_dest_reg_num = mvm->fw->dbg_dest_reg_num; 503 trans->dbg_dest_reg_num = mvm->fw->dbg_dest_reg_num;
505 memcpy(trans->dbg_conf_tlv, mvm->fw->dbg_conf_tlv, 504 memcpy(trans->dbg_conf_tlv, mvm->fw->dbg_conf_tlv,
506 sizeof(trans->dbg_conf_tlv)); 505 sizeof(trans->dbg_conf_tlv));
506 trans->dbg_trigger_tlv = mvm->fw->dbg_trigger_tlv;
507 507
508 /* set up notification wait support */ 508 /* set up notification wait support */
509 iwl_notification_wait_init(&mvm->notif_wait); 509 iwl_notification_wait_init(&mvm->notif_wait);
@@ -685,6 +685,38 @@ static void iwl_mvm_async_handlers_wk(struct work_struct *wk)
685 mutex_unlock(&mvm->mutex); 685 mutex_unlock(&mvm->mutex);
686} 686}
687 687
688static inline void iwl_mvm_rx_check_trigger(struct iwl_mvm *mvm,
689 struct iwl_rx_packet *pkt)
690{
691 struct iwl_fw_dbg_trigger_tlv *trig;
692 struct iwl_fw_dbg_trigger_cmd *cmds_trig;
693 char buf[32];
694 int i;
695
696 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_FW_NOTIF))
697 return;
698
699 trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_FW_NOTIF);
700 cmds_trig = (void *)trig->data;
701
702 if (!iwl_fw_dbg_trigger_check_stop(mvm, NULL, trig))
703 return;
704
705 for (i = 0; i < ARRAY_SIZE(cmds_trig->cmds); i++) {
706 /* don't collect on CMD 0 */
707 if (!cmds_trig->cmds[i].cmd_id)
708 break;
709
710 if (cmds_trig->cmds[i].cmd_id != pkt->hdr.cmd)
711 continue;
712
713 memset(buf, 0, sizeof(buf));
714 snprintf(buf, sizeof(buf), "CMD 0x%02x received", pkt->hdr.cmd);
715 iwl_mvm_fw_dbg_collect_trig(mvm, trig, buf, sizeof(buf));
716 break;
717 }
718}
719
688static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode, 720static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
689 struct iwl_rx_cmd_buffer *rxb, 721 struct iwl_rx_cmd_buffer *rxb,
690 struct iwl_device_cmd *cmd) 722 struct iwl_device_cmd *cmd)
@@ -693,6 +725,8 @@ static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
693 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 725 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
694 u8 i; 726 u8 i;
695 727
728 iwl_mvm_rx_check_trigger(mvm, pkt);
729
696 /* 730 /*
697 * Do the notification wait before RX handlers so 731 * Do the notification wait before RX handlers so
698 * even if the RX handler consumes the RXB we have 732 * even if the RX handler consumes the RXB we have
@@ -827,7 +861,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk)
827static void iwl_mvm_fw_error_dump_wk(struct work_struct *work) 861static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
828{ 862{
829 struct iwl_mvm *mvm = 863 struct iwl_mvm *mvm =
830 container_of(work, struct iwl_mvm, fw_error_dump_wk); 864 container_of(work, struct iwl_mvm, fw_dump_wk.work);
831 865
832 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT)) 866 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT))
833 return; 867 return;
@@ -879,7 +913,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
879 * can't recover this since we're already half suspended. 913 * can't recover this since we're already half suspended.
880 */ 914 */
881 if (!mvm->restart_fw && fw_error) { 915 if (!mvm->restart_fw && fw_error) {
882 schedule_work(&mvm->fw_error_dump_wk); 916 iwl_mvm_fw_dbg_collect_desc(mvm, &iwl_mvm_dump_desc_assert, 0);
883 } else if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, 917 } else if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART,
884 &mvm->status)) { 918 &mvm->status)) {
885 struct iwl_mvm_reprobe *reprobe; 919 struct iwl_mvm_reprobe *reprobe;
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index 5b43616eeb06..1bd10eda01f9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -175,6 +175,8 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
175 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); 175 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
176 cmd->rxchain_info |= cpu_to_le32(active_cnt << 176 cmd->rxchain_info |= cpu_to_le32(active_cnt <<
177 PHY_RX_CHAIN_MIMO_CNT_POS); 177 PHY_RX_CHAIN_MIMO_CNT_POS);
178 if (unlikely(mvm->dbgfs_rx_phyinfo))
179 cmd->rxchain_info = cpu_to_le32(mvm->dbgfs_rx_phyinfo);
178 180
179 cmd->txchain_info = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm)); 181 cmd->txchain_info = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
180} 182}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 194bd1f939ca..6578498dd5af 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -134,9 +134,12 @@ enum rs_column_mode {
134#define MAX_NEXT_COLUMNS 7 134#define MAX_NEXT_COLUMNS 7
135#define MAX_COLUMN_CHECKS 3 135#define MAX_COLUMN_CHECKS 3
136 136
137struct rs_tx_column;
138
137typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm, 139typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm,
138 struct ieee80211_sta *sta, 140 struct ieee80211_sta *sta,
139 struct iwl_scale_tbl_info *tbl); 141 struct iwl_scale_tbl_info *tbl,
142 const struct rs_tx_column *next_col);
140 143
141struct rs_tx_column { 144struct rs_tx_column {
142 enum rs_column_mode mode; 145 enum rs_column_mode mode;
@@ -147,14 +150,19 @@ struct rs_tx_column {
147}; 150};
148 151
149static bool rs_ant_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 152static bool rs_ant_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
150 struct iwl_scale_tbl_info *tbl) 153 struct iwl_scale_tbl_info *tbl,
154 const struct rs_tx_column *next_col)
151{ 155{
152 return iwl_mvm_bt_coex_is_ant_avail(mvm, tbl->rate.ant); 156 return iwl_mvm_bt_coex_is_ant_avail(mvm, next_col->ant);
153} 157}
154 158
155static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 159static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
156 struct iwl_scale_tbl_info *tbl) 160 struct iwl_scale_tbl_info *tbl,
161 const struct rs_tx_column *next_col)
157{ 162{
163 struct iwl_mvm_sta *mvmsta;
164 struct iwl_mvm_vif *mvmvif;
165
158 if (!sta->ht_cap.ht_supported) 166 if (!sta->ht_cap.ht_supported)
159 return false; 167 return false;
160 168
@@ -167,11 +175,17 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
167 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) 175 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
168 return false; 176 return false;
169 177
178 mvmsta = iwl_mvm_sta_from_mac80211(sta);
179 mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
180 if (iwl_mvm_vif_low_latency(mvmvif) && mvmsta->vif->p2p)
181 return false;
182
170 return true; 183 return true;
171} 184}
172 185
173static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 186static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
174 struct iwl_scale_tbl_info *tbl) 187 struct iwl_scale_tbl_info *tbl,
188 const struct rs_tx_column *next_col)
175{ 189{
176 if (!sta->ht_cap.ht_supported) 190 if (!sta->ht_cap.ht_supported)
177 return false; 191 return false;
@@ -180,7 +194,8 @@ static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
180} 194}
181 195
182static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 196static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
183 struct iwl_scale_tbl_info *tbl) 197 struct iwl_scale_tbl_info *tbl,
198 const struct rs_tx_column *next_col)
184{ 199{
185 struct rs_rate *rate = &tbl->rate; 200 struct rs_rate *rate = &tbl->rate;
186 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 201 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
@@ -800,6 +815,8 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
800 rate->ldpc = true; 815 rate->ldpc = true;
801 if (ucode_rate & RATE_MCS_VHT_STBC_MSK) 816 if (ucode_rate & RATE_MCS_VHT_STBC_MSK)
802 rate->stbc = true; 817 rate->stbc = true;
818 if (ucode_rate & RATE_MCS_BF_MSK)
819 rate->bfer = true;
803 820
804 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; 821 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK;
805 822
@@ -809,7 +826,9 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
809 826
810 if (nss == 1) { 827 if (nss == 1) {
811 rate->type = LQ_HT_SISO; 828 rate->type = LQ_HT_SISO;
812 WARN_ON_ONCE(!rate->stbc && num_of_ant != 1); 829 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1,
830 "stbc %d bfer %d",
831 rate->stbc, rate->bfer);
813 } else if (nss == 2) { 832 } else if (nss == 2) {
814 rate->type = LQ_HT_MIMO2; 833 rate->type = LQ_HT_MIMO2;
815 WARN_ON_ONCE(num_of_ant != 2); 834 WARN_ON_ONCE(num_of_ant != 2);
@@ -822,7 +841,9 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
822 841
823 if (nss == 1) { 842 if (nss == 1) {
824 rate->type = LQ_VHT_SISO; 843 rate->type = LQ_VHT_SISO;
825 WARN_ON_ONCE(!rate->stbc && num_of_ant != 1); 844 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1,
845 "stbc %d bfer %d",
846 rate->stbc, rate->bfer);
826 } else if (nss == 2) { 847 } else if (nss == 2) {
827 rate->type = LQ_VHT_MIMO2; 848 rate->type = LQ_VHT_MIMO2;
828 WARN_ON_ONCE(num_of_ant != 2); 849 WARN_ON_ONCE(num_of_ant != 2);
@@ -1001,13 +1022,41 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
1001 rs_get_lower_rate_in_column(lq_sta, rate); 1022 rs_get_lower_rate_in_column(lq_sta, rate);
1002} 1023}
1003 1024
1004/* Simple function to compare two rate scale table types */ 1025/* Check if both rates are identical
1005static inline bool rs_rate_match(struct rs_rate *a, 1026 * allow_ant_mismatch enables matching a SISO rate on ANT_A or ANT_B
1006 struct rs_rate *b) 1027 * with a rate indicating STBC/BFER and ANT_AB.
1028 */
1029static inline bool rs_rate_equal(struct rs_rate *a,
1030 struct rs_rate *b,
1031 bool allow_ant_mismatch)
1032
1033{
1034 bool ant_match = (a->ant == b->ant) && (a->stbc == b->stbc) &&
1035 (a->bfer == b->bfer);
1036
1037 if (allow_ant_mismatch) {
1038 if (a->stbc || a->bfer) {
1039 WARN_ONCE(a->ant != ANT_AB, "stbc %d bfer %d ant %d",
1040 a->stbc, a->bfer, a->ant);
1041 ant_match |= (b->ant == ANT_A || b->ant == ANT_B);
1042 } else if (b->stbc || b->bfer) {
1043 WARN_ONCE(b->ant != ANT_AB, "stbc %d bfer %d ant %d",
1044 b->stbc, b->bfer, b->ant);
1045 ant_match |= (a->ant == ANT_A || a->ant == ANT_B);
1046 }
1047 }
1048
1049 return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) &&
1050 (a->ldpc == b->ldpc) && (a->index == b->index) && ant_match;
1051}
1052
1053/* Check if both rates share the same column */
1054static inline bool rs_rate_column_match(struct rs_rate *a,
1055 struct rs_rate *b)
1007{ 1056{
1008 bool ant_match; 1057 bool ant_match;
1009 1058
1010 if (a->stbc) 1059 if (a->stbc || a->bfer)
1011 ant_match = (b->ant == ANT_A || b->ant == ANT_B); 1060 ant_match = (b->ant == ANT_A || b->ant == ANT_B);
1012 else 1061 else
1013 ant_match = (a->ant == b->ant); 1062 ant_match = (a->ant == b->ant);
@@ -1016,18 +1065,6 @@ static inline bool rs_rate_match(struct rs_rate *a,
1016 && ant_match; 1065 && ant_match;
1017} 1066}
1018 1067
1019static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags)
1020{
1021 if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1022 return RATE_MCS_CHAN_WIDTH_40;
1023 else if (flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
1024 return RATE_MCS_CHAN_WIDTH_80;
1025 else if (flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
1026 return RATE_MCS_CHAN_WIDTH_160;
1027
1028 return RATE_MCS_CHAN_WIDTH_20;
1029}
1030
1031static u8 rs_get_tid(struct ieee80211_hdr *hdr) 1068static u8 rs_get_tid(struct ieee80211_hdr *hdr)
1032{ 1069{
1033 u8 tid = IWL_MAX_TID_COUNT; 1070 u8 tid = IWL_MAX_TID_COUNT;
@@ -1048,15 +1085,17 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1048{ 1085{
1049 int legacy_success; 1086 int legacy_success;
1050 int retries; 1087 int retries;
1051 int mac_index, i; 1088 int i;
1052 struct iwl_lq_cmd *table; 1089 struct iwl_lq_cmd *table;
1053 enum mac80211_rate_control_flags mac_flags; 1090 u32 lq_hwrate;
1054 u32 ucode_rate; 1091 struct rs_rate lq_rate, tx_resp_rate;
1055 struct rs_rate rate;
1056 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 1092 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
1057 u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0]; 1093 u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0];
1094 u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];
1058 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 1095 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1059 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta; 1096 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
1097 bool allow_ant_mismatch = mvm->fw->ucode_capa.api[0] &
1098 IWL_UCODE_TLV_API_LQ_SS_PARAMS;
1060 1099
1061 /* Treat uninitialized rate scaling data same as non-existing. */ 1100 /* Treat uninitialized rate scaling data same as non-existing. */
1062 if (!lq_sta) { 1101 if (!lq_sta) {
@@ -1079,39 +1118,6 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1079 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 1118 !(info->flags & IEEE80211_TX_STAT_AMPDU))
1080 return; 1119 return;
1081 1120
1082 /*
1083 * Ignore this Tx frame response if its initial rate doesn't match
1084 * that of latest Link Quality command. There may be stragglers
1085 * from a previous Link Quality command, but we're no longer interested
1086 * in those; they're either from the "active" mode while we're trying
1087 * to check "search" mode, or a prior "search" mode after we've moved
1088 * to a new "search" mode (which might become the new "active" mode).
1089 */
1090 table = &lq_sta->lq;
1091 ucode_rate = le32_to_cpu(table->rs_table[0]);
1092 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
1093 if (info->band == IEEE80211_BAND_5GHZ)
1094 rate.index -= IWL_FIRST_OFDM_RATE;
1095 mac_flags = info->status.rates[0].flags;
1096 mac_index = info->status.rates[0].idx;
1097 /* For HT packets, map MCS to PLCP */
1098 if (mac_flags & IEEE80211_TX_RC_MCS) {
1099 /* Remove # of streams */
1100 mac_index &= RATE_HT_MCS_RATE_CODE_MSK;
1101 if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
1102 mac_index++;
1103 /*
1104 * mac80211 HT index is always zero-indexed; we need to move
1105 * HT OFDM rates after CCK rates in 2.4 GHz band
1106 */
1107 if (info->band == IEEE80211_BAND_2GHZ)
1108 mac_index += IWL_FIRST_OFDM_RATE;
1109 } else if (mac_flags & IEEE80211_TX_RC_VHT_MCS) {
1110 mac_index &= RATE_VHT_MCS_RATE_CODE_MSK;
1111 if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
1112 mac_index++;
1113 }
1114
1115 if (time_after(jiffies, 1121 if (time_after(jiffies,
1116 (unsigned long)(lq_sta->last_tx + 1122 (unsigned long)(lq_sta->last_tx +
1117 (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) { 1123 (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
@@ -1126,21 +1132,24 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1126 } 1132 }
1127 lq_sta->last_tx = jiffies; 1133 lq_sta->last_tx = jiffies;
1128 1134
1135 /* Ignore this Tx frame response if its initial rate doesn't match
1136 * that of latest Link Quality command. There may be stragglers
1137 * from a previous Link Quality command, but we're no longer interested
1138 * in those; they're either from the "active" mode while we're trying
1139 * to check "search" mode, or a prior "search" mode after we've moved
1140 * to a new "search" mode (which might become the new "active" mode).
1141 */
1142 table = &lq_sta->lq;
1143 lq_hwrate = le32_to_cpu(table->rs_table[0]);
1144 rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate);
1145 rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, &tx_resp_rate);
1146
1129 /* Here we actually compare this rate to the latest LQ command */ 1147 /* Here we actually compare this rate to the latest LQ command */
1130 if ((mac_index < 0) || 1148 if (!rs_rate_equal(&tx_resp_rate, &lq_rate, allow_ant_mismatch)) {
1131 (rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
1132 (rate.bw != rs_ch_width_from_mac_flags(mac_flags)) ||
1133 (rate.ant != info->status.antenna) ||
1134 (!!(ucode_rate & RATE_MCS_HT_MSK) !=
1135 !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
1136 (!!(ucode_rate & RATE_MCS_VHT_MSK) !=
1137 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) ||
1138 (!!(ucode_rate & RATE_HT_MCS_GF_MSK) !=
1139 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
1140 (rate.index != mac_index)) {
1141 IWL_DEBUG_RATE(mvm, 1149 IWL_DEBUG_RATE(mvm,
1142 "initial rate %d does not match %d (0x%x)\n", 1150 "initial tx resp rate 0x%x does not match 0x%x\n",
1143 mac_index, rate.index, ucode_rate); 1151 tx_resp_hwrate, lq_hwrate);
1152
1144 /* 1153 /*
1145 * Since rates mis-match, the last LQ command may have failed. 1154 * Since rates mis-match, the last LQ command may have failed.
1146 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with 1155 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
@@ -1168,14 +1177,14 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1168 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1177 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1169 } 1178 }
1170 1179
1171 if (WARN_ON_ONCE(!rs_rate_match(&rate, &curr_tbl->rate))) { 1180 if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) {
1172 IWL_DEBUG_RATE(mvm, 1181 IWL_DEBUG_RATE(mvm,
1173 "Neither active nor search matches tx rate\n"); 1182 "Neither active nor search matches tx rate\n");
1174 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1183 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1175 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE"); 1184 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE");
1176 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 1185 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
1177 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH"); 1186 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");
1178 rs_dump_rate(mvm, &rate, "ACTUAL"); 1187 rs_dump_rate(mvm, &lq_rate, "ACTUAL");
1179 1188
1180 /* 1189 /*
1181 * no matching table found, let's by-pass the data collection 1190 * no matching table found, let's by-pass the data collection
@@ -1200,9 +1209,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1200 if (info->status.ampdu_ack_len == 0) 1209 if (info->status.ampdu_ack_len == 0)
1201 info->status.ampdu_len = 1; 1210 info->status.ampdu_len = 1;
1202 1211
1203 ucode_rate = le32_to_cpu(table->rs_table[0]); 1212 rs_collect_tx_data(mvm, lq_sta, curr_tbl, lq_rate.index,
1204 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
1205 rs_collect_tx_data(mvm, lq_sta, curr_tbl, rate.index,
1206 info->status.ampdu_len, 1213 info->status.ampdu_len,
1207 info->status.ampdu_ack_len, 1214 info->status.ampdu_ack_len,
1208 reduced_txp); 1215 reduced_txp);
@@ -1225,21 +1232,23 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1225 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); 1232 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
1226 /* Collect data for each rate used during failed TX attempts */ 1233 /* Collect data for each rate used during failed TX attempts */
1227 for (i = 0; i <= retries; ++i) { 1234 for (i = 0; i <= retries; ++i) {
1228 ucode_rate = le32_to_cpu(table->rs_table[i]); 1235 lq_hwrate = le32_to_cpu(table->rs_table[i]);
1229 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate); 1236 rs_rate_from_ucode_rate(lq_hwrate, info->band,
1237 &lq_rate);
1230 /* 1238 /*
1231 * Only collect stats if retried rate is in the same RS 1239 * Only collect stats if retried rate is in the same RS
1232 * table as active/search. 1240 * table as active/search.
1233 */ 1241 */
1234 if (rs_rate_match(&rate, &curr_tbl->rate)) 1242 if (rs_rate_column_match(&lq_rate, &curr_tbl->rate))
1235 tmp_tbl = curr_tbl; 1243 tmp_tbl = curr_tbl;
1236 else if (rs_rate_match(&rate, &other_tbl->rate)) 1244 else if (rs_rate_column_match(&lq_rate,
1245 &other_tbl->rate))
1237 tmp_tbl = other_tbl; 1246 tmp_tbl = other_tbl;
1238 else 1247 else
1239 continue; 1248 continue;
1240 1249
1241 rs_collect_tx_data(mvm, lq_sta, tmp_tbl, rate.index, 1, 1250 rs_collect_tx_data(mvm, lq_sta, tmp_tbl, lq_rate.index,
1242 i < retries ? 0 : legacy_success, 1251 1, i < retries ? 0 : legacy_success,
1243 reduced_txp); 1252 reduced_txp);
1244 } 1253 }
1245 1254
@@ -1250,7 +1259,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1250 } 1259 }
1251 } 1260 }
1252 /* The last TX rate is cached in lq_sta; it's set in if/else above */ 1261 /* The last TX rate is cached in lq_sta; it's set in if/else above */
1253 lq_sta->last_rate_n_flags = ucode_rate; 1262 lq_sta->last_rate_n_flags = lq_hwrate;
1254 IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp); 1263 IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp);
1255done: 1264done:
1256 /* See if there's a better rate or modulation mode to try. */ 1265 /* See if there's a better rate or modulation mode to try. */
@@ -1590,7 +1599,7 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1590 1599
1591 for (j = 0; j < MAX_COLUMN_CHECKS; j++) { 1600 for (j = 0; j < MAX_COLUMN_CHECKS; j++) {
1592 allow_func = next_col->checks[j]; 1601 allow_func = next_col->checks[j];
1593 if (allow_func && !allow_func(mvm, sta, tbl)) 1602 if (allow_func && !allow_func(mvm, sta, tbl, next_col))
1594 break; 1603 break;
1595 } 1604 }
1596 1605
@@ -2536,6 +2545,7 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
2536#ifdef CONFIG_MAC80211_DEBUGFS 2545#ifdef CONFIG_MAC80211_DEBUGFS
2537 lq_sta->pers.dbg_fixed_rate = 0; 2546 lq_sta->pers.dbg_fixed_rate = 0;
2538 lq_sta->pers.dbg_fixed_txp_reduction = TPC_INVALID; 2547 lq_sta->pers.dbg_fixed_txp_reduction = TPC_INVALID;
2548 lq_sta->pers.ss_force = RS_SS_FORCE_NONE;
2539#endif 2549#endif
2540 lq_sta->pers.chains = 0; 2550 lq_sta->pers.chains = 0;
2541 memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal)); 2551 memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal));
@@ -3058,19 +3068,21 @@ static void rs_set_lq_ss_params(struct iwl_mvm *mvm,
3058 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) 3068 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
3059 goto out; 3069 goto out;
3060 3070
3071#ifdef CONFIG_MAC80211_DEBUGFS
3061 /* Check if forcing the decision is configured. 3072 /* Check if forcing the decision is configured.
3062 * Note that SISO is forced by not allowing STBC or BFER 3073 * Note that SISO is forced by not allowing STBC or BFER
3063 */ 3074 */
3064 if (lq_sta->ss_force == RS_SS_FORCE_STBC) 3075 if (lq_sta->pers.ss_force == RS_SS_FORCE_STBC)
3065 ss_params |= (LQ_SS_STBC_1SS_ALLOWED | LQ_SS_FORCE); 3076 ss_params |= (LQ_SS_STBC_1SS_ALLOWED | LQ_SS_FORCE);
3066 else if (lq_sta->ss_force == RS_SS_FORCE_BFER) 3077 else if (lq_sta->pers.ss_force == RS_SS_FORCE_BFER)
3067 ss_params |= (LQ_SS_BFER_ALLOWED | LQ_SS_FORCE); 3078 ss_params |= (LQ_SS_BFER_ALLOWED | LQ_SS_FORCE);
3068 3079
3069 if (lq_sta->ss_force != RS_SS_FORCE_NONE) { 3080 if (lq_sta->pers.ss_force != RS_SS_FORCE_NONE) {
3070 IWL_DEBUG_RATE(mvm, "Forcing single stream Tx decision %d\n", 3081 IWL_DEBUG_RATE(mvm, "Forcing single stream Tx decision %d\n",
3071 lq_sta->ss_force); 3082 lq_sta->pers.ss_force);
3072 goto out; 3083 goto out;
3073 } 3084 }
3085#endif
3074 3086
3075 if (lq_sta->stbc_capable) 3087 if (lq_sta->stbc_capable)
3076 ss_params |= LQ_SS_STBC_1SS_ALLOWED; 3088 ss_params |= LQ_SS_STBC_1SS_ALLOWED;
@@ -3311,6 +3323,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3311 struct iwl_mvm *mvm; 3323 struct iwl_mvm *mvm;
3312 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 3324 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
3313 struct rs_rate *rate = &tbl->rate; 3325 struct rs_rate *rate = &tbl->rate;
3326 u32 ss_params;
3314 mvm = lq_sta->pers.drv; 3327 mvm = lq_sta->pers.drv;
3315 buff = kmalloc(2048, GFP_KERNEL); 3328 buff = kmalloc(2048, GFP_KERNEL);
3316 if (!buff) 3329 if (!buff)
@@ -3357,6 +3370,16 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3357 lq_sta->lq.agg_frame_cnt_limit); 3370 lq_sta->lq.agg_frame_cnt_limit);
3358 3371
3359 desc += sprintf(buff+desc, "reduced tpc=%d\n", lq_sta->lq.reduced_tpc); 3372 desc += sprintf(buff+desc, "reduced tpc=%d\n", lq_sta->lq.reduced_tpc);
3373 ss_params = le32_to_cpu(lq_sta->lq.ss_params);
3374 desc += sprintf(buff+desc, "single stream params: %s%s%s%s\n",
3375 (ss_params & LQ_SS_PARAMS_VALID) ?
3376 "VALID," : "INVALID",
3377 (ss_params & LQ_SS_BFER_ALLOWED) ?
3378 "BFER," : "",
3379 (ss_params & LQ_SS_STBC_1SS_ALLOWED) ?
3380 "STBC," : "",
3381 (ss_params & LQ_SS_FORCE) ?
3382 "FORCE" : "");
3360 desc += sprintf(buff+desc, 3383 desc += sprintf(buff+desc,
3361 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n", 3384 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
3362 lq_sta->lq.initial_rate_index[0], 3385 lq_sta->lq.initial_rate_index[0],
@@ -3533,7 +3556,7 @@ static ssize_t iwl_dbgfs_ss_force_read(struct file *file,
3533 }; 3556 };
3534 3557
3535 pos += scnprintf(buf+pos, bufsz-pos, "%s\n", 3558 pos += scnprintf(buf+pos, bufsz-pos, "%s\n",
3536 ss_force_name[lq_sta->ss_force]); 3559 ss_force_name[lq_sta->pers.ss_force]);
3537 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 3560 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
3538} 3561}
3539 3562
@@ -3544,12 +3567,12 @@ static ssize_t iwl_dbgfs_ss_force_write(struct iwl_lq_sta *lq_sta, char *buf,
3544 int ret = 0; 3567 int ret = 0;
3545 3568
3546 if (!strncmp("none", buf, 4)) { 3569 if (!strncmp("none", buf, 4)) {
3547 lq_sta->ss_force = RS_SS_FORCE_NONE; 3570 lq_sta->pers.ss_force = RS_SS_FORCE_NONE;
3548 } else if (!strncmp("siso", buf, 4)) { 3571 } else if (!strncmp("siso", buf, 4)) {
3549 lq_sta->ss_force = RS_SS_FORCE_SISO; 3572 lq_sta->pers.ss_force = RS_SS_FORCE_SISO;
3550 } else if (!strncmp("stbc", buf, 4)) { 3573 } else if (!strncmp("stbc", buf, 4)) {
3551 if (lq_sta->stbc_capable) { 3574 if (lq_sta->stbc_capable) {
3552 lq_sta->ss_force = RS_SS_FORCE_STBC; 3575 lq_sta->pers.ss_force = RS_SS_FORCE_STBC;
3553 } else { 3576 } else {
3554 IWL_ERR(mvm, 3577 IWL_ERR(mvm,
3555 "can't force STBC. peer doesn't support\n"); 3578 "can't force STBC. peer doesn't support\n");
@@ -3557,7 +3580,7 @@ static ssize_t iwl_dbgfs_ss_force_write(struct iwl_lq_sta *lq_sta, char *buf,
3557 } 3580 }
3558 } else if (!strncmp("bfer", buf, 4)) { 3581 } else if (!strncmp("bfer", buf, 4)) {
3559 if (lq_sta->bfer_capable) { 3582 if (lq_sta->bfer_capable) {
3560 lq_sta->ss_force = RS_SS_FORCE_BFER; 3583 lq_sta->pers.ss_force = RS_SS_FORCE_BFER;
3561 } else { 3584 } else {
3562 IWL_ERR(mvm, 3585 IWL_ERR(mvm,
3563 "can't force BFER. peer doesn't support\n"); 3586 "can't force BFER. peer doesn't support\n");
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index dc4ef3dfafe1..e4aa9346a231 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -170,6 +170,7 @@ struct rs_rate {
170 bool sgi; 170 bool sgi;
171 bool ldpc; 171 bool ldpc;
172 bool stbc; 172 bool stbc;
173 bool bfer;
173}; 174};
174 175
175 176
@@ -331,14 +332,14 @@ struct iwl_lq_sta {
331 /* tx power reduce for this sta */ 332 /* tx power reduce for this sta */
332 int tpc_reduce; 333 int tpc_reduce;
333 334
334 /* force STBC/BFER/SISO for testing */
335 enum rs_ss_force_opt ss_force;
336
337 /* persistent fields - initialized only once - keep last! */ 335 /* persistent fields - initialized only once - keep last! */
338 struct lq_sta_pers { 336 struct lq_sta_pers {
339#ifdef CONFIG_MAC80211_DEBUGFS 337#ifdef CONFIG_MAC80211_DEBUGFS
340 u32 dbg_fixed_rate; 338 u32 dbg_fixed_rate;
341 u8 dbg_fixed_txp_reduction; 339 u8 dbg_fixed_txp_reduction;
340
341 /* force STBC/BFER/SISO for testing */
342 enum rs_ss_force_opt ss_force;
342#endif 343#endif
343 u8 chains; 344 u8 chains;
344 s8 chain_signal[IEEE80211_MAX_CHAINS]; 345 s8 chain_signal[IEEE80211_MAX_CHAINS];
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index f922131b4eab..6177e24f4c01 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -6,7 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as 12 * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
32 * BSD LICENSE 32 * BSD LICENSE
33 * 33 *
34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 35 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
36 * All rights reserved. 36 * All rights reserved.
37 * 37 *
38 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -345,6 +345,25 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
345 struct iwl_mvm_sta *mvmsta; 345 struct iwl_mvm_sta *mvmsta;
346 mvmsta = iwl_mvm_sta_from_mac80211(sta); 346 mvmsta = iwl_mvm_sta_from_mac80211(sta);
347 rs_update_last_rssi(mvm, &mvmsta->lq_sta, rx_status); 347 rs_update_last_rssi(mvm, &mvmsta->lq_sta, rx_status);
348
349 if (iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_RSSI) &&
350 ieee80211_is_beacon(hdr->frame_control)) {
351 struct iwl_fw_dbg_trigger_tlv *trig;
352 struct iwl_fw_dbg_trigger_low_rssi *rssi_trig;
353 bool trig_check;
354 s32 rssi;
355
356 trig = iwl_fw_dbg_get_trigger(mvm->fw,
357 FW_DBG_TRIGGER_RSSI);
358 rssi_trig = (void *)trig->data;
359 rssi = le32_to_cpu(rssi_trig->rssi);
360
361 trig_check =
362 iwl_fw_dbg_trigger_check_stop(mvm, mvmsta->vif,
363 trig);
364 if (trig_check && rx_status->signal < rssi)
365 iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL, 0);
366 }
348 } 367 }
349 368
350 rcu_read_unlock(); 369 rcu_read_unlock();
@@ -416,35 +435,43 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
416} 435}
417 436
418static void iwl_mvm_update_rx_statistics(struct iwl_mvm *mvm, 437static void iwl_mvm_update_rx_statistics(struct iwl_mvm *mvm,
419 struct iwl_notif_statistics *stats) 438 struct mvm_statistics_rx *rx_stats)
420{ 439{
421 /*
422 * NOTE FW aggregates the statistics - BUT the statistics are cleared
423 * when the driver issues REPLY_STATISTICS_CMD 0x9c with CLEAR_STATS
424 * bit set.
425 */
426 lockdep_assert_held(&mvm->mutex); 440 lockdep_assert_held(&mvm->mutex);
427 memcpy(&mvm->rx_stats, &stats->rx, sizeof(struct mvm_statistics_rx)); 441
442 mvm->rx_stats = *rx_stats;
428} 443}
429 444
430struct iwl_mvm_stat_data { 445struct iwl_mvm_stat_data {
431 struct iwl_notif_statistics *stats;
432 struct iwl_mvm *mvm; 446 struct iwl_mvm *mvm;
447 __le32 mac_id;
448 __s8 beacon_filter_average_energy;
449 struct mvm_statistics_general_v8 *general;
433}; 450};
434 451
435static void iwl_mvm_stat_iterator(void *_data, u8 *mac, 452static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
436 struct ieee80211_vif *vif) 453 struct ieee80211_vif *vif)
437{ 454{
438 struct iwl_mvm_stat_data *data = _data; 455 struct iwl_mvm_stat_data *data = _data;
439 struct iwl_notif_statistics *stats = data->stats;
440 struct iwl_mvm *mvm = data->mvm; 456 struct iwl_mvm *mvm = data->mvm;
441 int sig = -stats->general.beacon_filter_average_energy; 457 int sig = -data->beacon_filter_average_energy;
442 int last_event; 458 int last_event;
443 int thold = vif->bss_conf.cqm_rssi_thold; 459 int thold = vif->bss_conf.cqm_rssi_thold;
444 int hyst = vif->bss_conf.cqm_rssi_hyst; 460 int hyst = vif->bss_conf.cqm_rssi_hyst;
445 u16 id = le32_to_cpu(stats->rx.general.mac_id); 461 u16 id = le32_to_cpu(data->mac_id);
446 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 462 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
447 463
464 /* This doesn't need the MAC ID check since it's not taking the
465 * data copied into the "data" struct, but rather the data from
466 * the notification directly.
467 */
468 if (data->general) {
469 mvmvif->beacon_stats.num_beacons =
470 le32_to_cpu(data->general->beacon_counter[mvmvif->id]);
471 mvmvif->beacon_stats.avg_signal =
472 -data->general->beacon_average_energy[mvmvif->id];
473 }
474
448 if (mvmvif->id != id) 475 if (mvmvif->id != id)
449 return; 476 return;
450 477
@@ -500,34 +527,101 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
500 } 527 }
501} 528}
502 529
503/* 530static inline void
504 * iwl_mvm_rx_statistics - STATISTICS_NOTIFICATION handler 531iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt)
505 *
506 * TODO: This handler is implemented partially.
507 */
508int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
509 struct iwl_rx_cmd_buffer *rxb,
510 struct iwl_device_cmd *cmd)
511{ 532{
512 struct iwl_rx_packet *pkt = rxb_addr(rxb); 533 struct iwl_fw_dbg_trigger_tlv *trig;
513 struct iwl_notif_statistics *stats = (void *)&pkt->data; 534 struct iwl_fw_dbg_trigger_stats *trig_stats;
535 u32 trig_offset, trig_thold;
536
537 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_STATS))
538 return;
539
540 trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_STATS);
541 trig_stats = (void *)trig->data;
542
543 if (!iwl_fw_dbg_trigger_check_stop(mvm, NULL, trig))
544 return;
545
546 trig_offset = le32_to_cpu(trig_stats->stop_offset);
547 trig_thold = le32_to_cpu(trig_stats->stop_threshold);
548
549 if (WARN_ON_ONCE(trig_offset >= iwl_rx_packet_payload_len(pkt)))
550 return;
551
552 if (le32_to_cpup((__le32 *) (pkt->data + trig_offset)) < trig_thold)
553 return;
554
555 iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL, 0);
556}
557
558void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
559 struct iwl_rx_packet *pkt)
560{
561 size_t v8_len = sizeof(struct iwl_notif_statistics_v8);
562 size_t v10_len = sizeof(struct iwl_notif_statistics_v10);
514 struct iwl_mvm_stat_data data = { 563 struct iwl_mvm_stat_data data = {
515 .stats = stats,
516 .mvm = mvm, 564 .mvm = mvm,
517 }; 565 };
566 u32 temperature;
567
568 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_STATS_V10) {
569 struct iwl_notif_statistics_v10 *stats = (void *)&pkt->data;
570
571 if (iwl_rx_packet_payload_len(pkt) != v10_len)
572 goto invalid;
573
574 temperature = le32_to_cpu(stats->general.radio_temperature);
575 data.mac_id = stats->rx.general.mac_id;
576 data.beacon_filter_average_energy =
577 stats->general.beacon_filter_average_energy;
578
579 iwl_mvm_update_rx_statistics(mvm, &stats->rx);
580
581 mvm->radio_stats.rx_time = le64_to_cpu(stats->general.rx_time);
582 mvm->radio_stats.tx_time = le64_to_cpu(stats->general.tx_time);
583 mvm->radio_stats.on_time_rf =
584 le64_to_cpu(stats->general.on_time_rf);
585 mvm->radio_stats.on_time_scan =
586 le64_to_cpu(stats->general.on_time_scan);
587
588 data.general = &stats->general;
589 } else {
590 struct iwl_notif_statistics_v8 *stats = (void *)&pkt->data;
591
592 if (iwl_rx_packet_payload_len(pkt) != v8_len)
593 goto invalid;
594
595 temperature = le32_to_cpu(stats->general.radio_temperature);
596 data.mac_id = stats->rx.general.mac_id;
597 data.beacon_filter_average_energy =
598 stats->general.beacon_filter_average_energy;
599
600 iwl_mvm_update_rx_statistics(mvm, &stats->rx);
601 }
602
603 iwl_mvm_rx_stats_check_trigger(mvm, pkt);
518 604
519 /* Only handle rx statistics temperature changes if async temp 605 /* Only handle rx statistics temperature changes if async temp
520 * notifications are not supported 606 * notifications are not supported
521 */ 607 */
522 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_ASYNC_DTM)) 608 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_ASYNC_DTM))
523 iwl_mvm_tt_temp_changed(mvm, 609 iwl_mvm_tt_temp_changed(mvm, temperature);
524 le32_to_cpu(stats->general.radio_temperature));
525
526 iwl_mvm_update_rx_statistics(mvm, stats);
527 610
528 ieee80211_iterate_active_interfaces(mvm->hw, 611 ieee80211_iterate_active_interfaces(mvm->hw,
529 IEEE80211_IFACE_ITER_NORMAL, 612 IEEE80211_IFACE_ITER_NORMAL,
530 iwl_mvm_stat_iterator, 613 iwl_mvm_stat_iterator,
531 &data); 614 &data);
615 return;
616 invalid:
617 IWL_ERR(mvm, "received invalid statistics size (%d)!\n",
618 iwl_rx_packet_payload_len(pkt));
619}
620
621int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
622 struct iwl_rx_cmd_buffer *rxb,
623 struct iwl_device_cmd *cmd)
624{
625 iwl_mvm_handle_rx_statistics(mvm, rxb_addr(rxb));
532 return 0; 626 return 0;
533} 627}
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 7e9aa3cb3254..f0946b5dd7c8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -82,6 +82,7 @@ struct iwl_mvm_scan_params {
82 struct _dwell { 82 struct _dwell {
83 u16 passive; 83 u16 passive;
84 u16 active; 84 u16 active;
85 u16 fragmented;
85 } dwell[IEEE80211_NUM_BANDS]; 86 } dwell[IEEE80211_NUM_BANDS];
86}; 87};
87 88
@@ -191,101 +192,6 @@ static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm,
191 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; 192 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10;
192} 193}
193 194
194static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
195 struct cfg80211_scan_request *req,
196 bool basic_ssid,
197 struct iwl_mvm_scan_params *params)
198{
199 struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
200 (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
201 int i;
202 int type = BIT(req->n_ssids) - 1;
203 enum ieee80211_band band = req->channels[0]->band;
204
205 if (!basic_ssid)
206 type |= BIT(req->n_ssids);
207
208 for (i = 0; i < cmd->channel_count; i++) {
209 chan->channel = cpu_to_le16(req->channels[i]->hw_value);
210 chan->type = cpu_to_le32(type);
211 if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
212 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
213 chan->active_dwell = cpu_to_le16(params->dwell[band].active);
214 chan->passive_dwell = cpu_to_le16(params->dwell[band].passive);
215 chan->iteration_count = cpu_to_le16(1);
216 chan++;
217 }
218}
219
220/*
221 * Fill in probe request with the following parameters:
222 * TA is our vif HW address, which mac80211 ensures we have.
223 * Packet is broadcasted, so this is both SA and DA.
224 * The probe request IE is made out of two: first comes the most prioritized
225 * SSID if a directed scan is requested. Second comes whatever extra
226 * information was given to us as the scan request IE.
227 */
228static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
229 int n_ssids, const u8 *ssid, int ssid_len,
230 const u8 *band_ie, int band_ie_len,
231 const u8 *common_ie, int common_ie_len,
232 int left)
233{
234 int len = 0;
235 u8 *pos = NULL;
236
237 /* Make sure there is enough space for the probe request,
238 * two mandatory IEs and the data */
239 left -= 24;
240 if (left < 0)
241 return 0;
242
243 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
244 eth_broadcast_addr(frame->da);
245 memcpy(frame->sa, ta, ETH_ALEN);
246 eth_broadcast_addr(frame->bssid);
247 frame->seq_ctrl = 0;
248
249 len += 24;
250
251 /* for passive scans, no need to fill anything */
252 if (n_ssids == 0)
253 return (u16)len;
254
255 /* points to the payload of the request */
256 pos = &frame->u.probe_req.variable[0];
257
258 /* fill in our SSID IE */
259 left -= ssid_len + 2;
260 if (left < 0)
261 return 0;
262 *pos++ = WLAN_EID_SSID;
263 *pos++ = ssid_len;
264 if (ssid && ssid_len) { /* ssid_len may be == 0 even if ssid is valid */
265 memcpy(pos, ssid, ssid_len);
266 pos += ssid_len;
267 }
268
269 len += ssid_len + 2;
270
271 if (WARN_ON(left < band_ie_len + common_ie_len))
272 return len;
273
274 if (band_ie && band_ie_len) {
275 memcpy(pos, band_ie, band_ie_len);
276 pos += band_ie_len;
277 len += band_ie_len;
278 }
279
280 if (common_ie && common_ie_len) {
281 memcpy(pos, common_ie, common_ie_len);
282 pos += common_ie_len;
283 len += common_ie_len;
284 }
285
286 return (u16)len;
287}
288
289static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac, 195static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
290 struct ieee80211_vif *vif) 196 struct ieee80211_vif *vif)
291{ 197{
@@ -325,7 +231,7 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
325 * If there is more than one active interface make 231 * If there is more than one active interface make
326 * passive scan more fragmented. 232 * passive scan more fragmented.
327 */ 233 */
328 frag_passive_dwell = (global_cnt < 2) ? 40 : 20; 234 frag_passive_dwell = 40;
329 params->max_out_time = frag_passive_dwell; 235 params->max_out_time = frag_passive_dwell;
330 } else { 236 } else {
331 params->suspend_time = 120; 237 params->suspend_time = 120;
@@ -358,10 +264,10 @@ not_bound:
358 264
359 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { 265 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
360 if (params->passive_fragmented) 266 if (params->passive_fragmented)
361 params->dwell[band].passive = frag_passive_dwell; 267 params->dwell[band].fragmented = frag_passive_dwell;
362 else 268
363 params->dwell[band].passive = 269 params->dwell[band].passive = iwl_mvm_get_passive_dwell(mvm,
364 iwl_mvm_get_passive_dwell(mvm, band); 270 band);
365 params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band, 271 params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band,
366 n_ssids); 272 n_ssids);
367 } 273 }
@@ -379,20 +285,11 @@ static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm,
379{ 285{
380 int max_probe_len; 286 int max_probe_len;
381 287
382 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) 288 max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE;
383 max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE;
384 else
385 max_probe_len = mvm->fw->ucode_capa.max_probe_length;
386 289
387 /* we create the 802.11 header and SSID element */ 290 /* we create the 802.11 header and SSID element */
388 max_probe_len -= 24 + 2; 291 max_probe_len -= 24 + 2;
389 292
390 /* basic ssid is added only for hw_scan with and old api */
391 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID) &&
392 !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) &&
393 !is_sched_scan)
394 max_probe_len -= 32;
395
396 /* DS parameter set element is added on 2.4GHZ band if required */ 293 /* DS parameter set element is added on 2.4GHZ band if required */
397 if (iwl_mvm_rrm_scan_needed(mvm)) 294 if (iwl_mvm_rrm_scan_needed(mvm))
398 max_probe_len -= 3; 295 max_probe_len -= 3;
@@ -404,9 +301,6 @@ int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan)
404{ 301{
405 int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan); 302 int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan);
406 303
407 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN))
408 return max_ie_len;
409
410 /* TODO: [BUG] This function should return the maximum allowed size of 304 /* TODO: [BUG] This function should return the maximum allowed size of
411 * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs 305 * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs
412 * in the same command. So the correct implementation of this function 306 * in the same command. So the correct implementation of this function
@@ -420,129 +314,6 @@ int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan)
420 return max_ie_len; 314 return max_ie_len;
421} 315}
422 316
423int iwl_mvm_scan_request(struct iwl_mvm *mvm,
424 struct ieee80211_vif *vif,
425 struct cfg80211_scan_request *req)
426{
427 struct iwl_host_cmd hcmd = {
428 .id = SCAN_REQUEST_CMD,
429 .len = { 0, },
430 .data = { mvm->scan_cmd, },
431 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
432 };
433 struct iwl_scan_cmd *cmd = mvm->scan_cmd;
434 int ret;
435 u32 status;
436 int ssid_len = 0;
437 u8 *ssid = NULL;
438 bool basic_ssid = !(mvm->fw->ucode_capa.flags &
439 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
440 struct iwl_mvm_scan_params params = {};
441
442 lockdep_assert_held(&mvm->mutex);
443
444 /* we should have failed registration if scan_cmd was NULL */
445 if (WARN_ON(mvm->scan_cmd == NULL))
446 return -ENOMEM;
447
448 IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n");
449 mvm->scan_status = IWL_MVM_SCAN_OS;
450 memset(cmd, 0, ksize(cmd));
451
452 cmd->channel_count = (u8)req->n_channels;
453 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
454 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
455 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
456
457 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, req->flags, &params);
458 cmd->max_out_time = cpu_to_le32(params.max_out_time);
459 cmd->suspend_time = cpu_to_le32(params.suspend_time);
460 if (params.passive_fragmented)
461 cmd->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
462
463 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
464 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
465 MAC_FILTER_IN_BEACON);
466
467 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
468 cmd->type = cpu_to_le32(SCAN_TYPE_DISCOVERY_FORCED);
469 else
470 cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
471
472 cmd->repeats = cpu_to_le32(1);
473
474 /*
475 * If the user asked for passive scan, don't change to active scan if
476 * you see any activity on the channel - remain passive.
477 */
478 if (req->n_ssids > 0) {
479 cmd->passive2active = cpu_to_le16(1);
480 cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE;
481 if (basic_ssid) {
482 ssid = req->ssids[0].ssid;
483 ssid_len = req->ssids[0].ssid_len;
484 }
485 } else {
486 cmd->passive2active = 0;
487 cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE;
488 }
489
490 iwl_mvm_scan_fill_ssids(cmd->direct_scan, req->ssids, req->n_ssids,
491 basic_ssid ? 1 : 0);
492
493 cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
494 3 << TX_CMD_FLG_BT_PRIO_POS);
495
496 cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id;
497 cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
498 cmd->tx_cmd.rate_n_flags =
499 iwl_mvm_scan_rate_n_flags(mvm, req->channels[0]->band,
500 req->no_cck);
501
502 cmd->tx_cmd.len =
503 cpu_to_le16(iwl_mvm_fill_probe_req(
504 (struct ieee80211_mgmt *)cmd->data,
505 vif->addr,
506 req->n_ssids, ssid, ssid_len,
507 req->ie, req->ie_len, NULL, 0,
508 mvm->fw->ucode_capa.max_probe_length));
509
510 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, &params);
511
512 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) +
513 le16_to_cpu(cmd->tx_cmd.len) +
514 (cmd->channel_count * sizeof(struct iwl_scan_channel)));
515 hcmd.len[0] = le16_to_cpu(cmd->len);
516
517 status = SCAN_RESPONSE_OK;
518 ret = iwl_mvm_send_cmd_status(mvm, &hcmd, &status);
519 if (!ret && status == SCAN_RESPONSE_OK) {
520 IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
521 } else {
522 /*
523 * If the scan failed, it usually means that the FW was unable
524 * to allocate the time events. Warn on it, but maybe we
525 * should try to send the command again with different params.
526 */
527 IWL_ERR(mvm, "Scan failed! status 0x%x ret %d\n",
528 status, ret);
529 mvm->scan_status = IWL_MVM_SCAN_NONE;
530 ret = -EIO;
531 }
532 return ret;
533}
534
535int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
536 struct iwl_device_cmd *cmd)
537{
538 struct iwl_rx_packet *pkt = rxb_addr(rxb);
539 struct iwl_cmd_response *resp = (void *)pkt->data;
540
541 IWL_DEBUG_SCAN(mvm, "Scan response received. status 0x%x\n",
542 le32_to_cpu(resp->status));
543 return 0;
544}
545
546int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, 317int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
547 struct iwl_rx_cmd_buffer *rxb, 318 struct iwl_rx_cmd_buffer *rxb,
548 struct iwl_device_cmd *cmd) 319 struct iwl_device_cmd *cmd)
@@ -556,130 +327,25 @@ int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
556 return 0; 327 return 0;
557} 328}
558 329
559int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
560 struct iwl_device_cmd *cmd)
561{
562 struct iwl_rx_packet *pkt = rxb_addr(rxb);
563 struct iwl_scan_complete_notif *notif = (void *)pkt->data;
564
565 lockdep_assert_held(&mvm->mutex);
566
567 IWL_DEBUG_SCAN(mvm, "Scan complete: status=0x%x scanned channels=%d\n",
568 notif->status, notif->scanned_channels);
569
570 if (mvm->scan_status == IWL_MVM_SCAN_OS)
571 mvm->scan_status = IWL_MVM_SCAN_NONE;
572 ieee80211_scan_completed(mvm->hw, notif->status != SCAN_COMP_STATUS_OK);
573
574 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
575
576 return 0;
577}
578
579int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm, 330int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm,
580 struct iwl_rx_cmd_buffer *rxb, 331 struct iwl_rx_cmd_buffer *rxb,
581 struct iwl_device_cmd *cmd) 332 struct iwl_device_cmd *cmd)
582{ 333{
583 struct iwl_rx_packet *pkt = rxb_addr(rxb);
584
585 if (!(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) &&
586 !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) {
587 struct iwl_sched_scan_results *notif = (void *)pkt->data;
588
589 if (!(notif->client_bitmap & SCAN_CLIENT_SCHED_SCAN))
590 return 0;
591 }
592
593 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n"); 334 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n");
594 ieee80211_sched_scan_results(mvm->hw); 335 ieee80211_sched_scan_results(mvm->hw);
595 336
596 return 0; 337 return 0;
597} 338}
598 339
599static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
600 struct iwl_rx_packet *pkt, void *data)
601{
602 struct iwl_mvm *mvm =
603 container_of(notif_wait, struct iwl_mvm, notif_wait);
604 struct iwl_scan_complete_notif *notif;
605 u32 *resp;
606
607 switch (pkt->hdr.cmd) {
608 case SCAN_ABORT_CMD:
609 resp = (void *)pkt->data;
610 if (*resp == CAN_ABORT_STATUS) {
611 IWL_DEBUG_SCAN(mvm,
612 "Scan can be aborted, wait until completion\n");
613 return false;
614 }
615
616 /*
617 * If scan cannot be aborted, it means that we had a
618 * SCAN_COMPLETE_NOTIFICATION in the pipe and it called
619 * ieee80211_scan_completed already.
620 */
621 IWL_DEBUG_SCAN(mvm, "Scan cannot be aborted, exit now: %d\n",
622 *resp);
623 return true;
624
625 case SCAN_COMPLETE_NOTIFICATION:
626 notif = (void *)pkt->data;
627 IWL_DEBUG_SCAN(mvm, "Scan aborted: status 0x%x\n",
628 notif->status);
629 return true;
630
631 default:
632 WARN_ON(1);
633 return false;
634 };
635}
636
637static int iwl_mvm_cancel_regular_scan(struct iwl_mvm *mvm)
638{
639 struct iwl_notification_wait wait_scan_abort;
640 static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD,
641 SCAN_COMPLETE_NOTIFICATION };
642 int ret;
643
644 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
645 scan_abort_notif,
646 ARRAY_SIZE(scan_abort_notif),
647 iwl_mvm_scan_abort_notif, NULL);
648
649 ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, 0, 0, NULL);
650 if (ret) {
651 IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret);
652 /* mac80211's state will be cleaned in the nic_restart flow */
653 goto out_remove_notif;
654 }
655
656 return iwl_wait_notification(&mvm->notif_wait, &wait_scan_abort, HZ);
657
658out_remove_notif:
659 iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort);
660 return ret;
661}
662
663int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, 340int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
664 struct iwl_rx_cmd_buffer *rxb, 341 struct iwl_rx_cmd_buffer *rxb,
665 struct iwl_device_cmd *cmd) 342 struct iwl_device_cmd *cmd)
666{ 343{
667 struct iwl_rx_packet *pkt = rxb_addr(rxb); 344 struct iwl_rx_packet *pkt = rxb_addr(rxb);
668 u8 status, ebs_status; 345 struct iwl_periodic_scan_complete *scan_notif;
669 346
670 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) { 347 scan_notif = (void *)pkt->data;
671 struct iwl_periodic_scan_complete *scan_notif;
672 348
673 scan_notif = (void *)pkt->data;
674 status = scan_notif->status;
675 ebs_status = scan_notif->ebs_status;
676 } else {
677 struct iwl_scan_offload_complete *scan_notif;
678
679 scan_notif = (void *)pkt->data;
680 status = scan_notif->status;
681 ebs_status = scan_notif->ebs_status;
682 }
683 /* scan status must be locked for proper checking */ 349 /* scan status must be locked for proper checking */
684 lockdep_assert_held(&mvm->mutex); 350 lockdep_assert_held(&mvm->mutex);
685 351
@@ -687,9 +353,9 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
687 "%s completed, status %s, EBS status %s\n", 353 "%s completed, status %s, EBS status %s\n",
688 mvm->scan_status == IWL_MVM_SCAN_SCHED ? 354 mvm->scan_status == IWL_MVM_SCAN_SCHED ?
689 "Scheduled scan" : "Scan", 355 "Scheduled scan" : "Scan",
690 status == IWL_SCAN_OFFLOAD_COMPLETED ? 356 scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
691 "completed" : "aborted", 357 "completed" : "aborted",
692 ebs_status == IWL_SCAN_EBS_SUCCESS ? 358 scan_notif->ebs_status == IWL_SCAN_EBS_SUCCESS ?
693 "success" : "failed"); 359 "success" : "failed");
694 360
695 361
@@ -700,64 +366,16 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
700 } else if (mvm->scan_status == IWL_MVM_SCAN_OS) { 366 } else if (mvm->scan_status == IWL_MVM_SCAN_OS) {
701 mvm->scan_status = IWL_MVM_SCAN_NONE; 367 mvm->scan_status = IWL_MVM_SCAN_NONE;
702 ieee80211_scan_completed(mvm->hw, 368 ieee80211_scan_completed(mvm->hw,
703 status == IWL_SCAN_OFFLOAD_ABORTED); 369 scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED);
704 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 370 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
705 } 371 }
706 372
707 if (ebs_status) 373 if (scan_notif->ebs_status)
708 mvm->last_ebs_successful = false; 374 mvm->last_ebs_successful = false;
709 375
710 return 0; 376 return 0;
711} 377}
712 378
713static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
714 struct ieee80211_vif *vif,
715 struct ieee80211_scan_ies *ies,
716 enum ieee80211_band band,
717 struct iwl_tx_cmd *cmd,
718 u8 *data)
719{
720 u16 cmd_len;
721
722 cmd->tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL);
723 cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
724 cmd->sta_id = mvm->aux_sta.sta_id;
725
726 cmd->rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm, band, false);
727
728 cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data,
729 vif->addr,
730 1, NULL, 0,
731 ies->ies[band], ies->len[band],
732 ies->common_ies, ies->common_ie_len,
733 SCAN_OFFLOAD_PROBE_REQ_SIZE);
734 cmd->len = cpu_to_le16(cmd_len);
735}
736
737static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
738 struct ieee80211_vif *vif,
739 struct cfg80211_sched_scan_request *req,
740 struct iwl_scan_offload_cmd *scan,
741 struct iwl_mvm_scan_params *params)
742{
743 scan->channel_count = req->n_channels;
744 scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
745 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
746 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
747 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
748
749 scan->max_out_time = cpu_to_le32(params->max_out_time);
750 scan->suspend_time = cpu_to_le32(params->suspend_time);
751
752 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
753 MAC_FILTER_IN_BEACON);
754 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);
755 scan->rep_count = cpu_to_le32(1);
756
757 if (params->passive_fragmented)
758 scan->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
759}
760
761static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list) 379static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
762{ 380{
763 int i; 381 int i;
@@ -815,127 +433,6 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
815 } 433 }
816} 434}
817 435
818static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
819 struct cfg80211_sched_scan_request *req,
820 u8 *channels_buffer,
821 enum ieee80211_band band,
822 int *head,
823 u32 ssid_bitmap,
824 struct iwl_mvm_scan_params *params)
825{
826 u32 n_channels = mvm->fw->ucode_capa.n_scan_channels;
827 __le32 *type = (__le32 *)channels_buffer;
828 __le16 *channel_number = (__le16 *)(type + n_channels);
829 __le16 *iter_count = channel_number + n_channels;
830 __le32 *iter_interval = (__le32 *)(iter_count + n_channels);
831 u8 *active_dwell = (u8 *)(iter_interval + n_channels);
832 u8 *passive_dwell = active_dwell + n_channels;
833 int i, index = 0;
834
835 for (i = 0; i < req->n_channels; i++) {
836 struct ieee80211_channel *chan = req->channels[i];
837
838 if (chan->band != band)
839 continue;
840
841 index = *head;
842 (*head)++;
843
844 channel_number[index] = cpu_to_le16(chan->hw_value);
845 active_dwell[index] = params->dwell[band].active;
846 passive_dwell[index] = params->dwell[band].passive;
847
848 iter_count[index] = cpu_to_le16(1);
849 iter_interval[index] = 0;
850
851 if (!(chan->flags & IEEE80211_CHAN_NO_IR))
852 type[index] |=
853 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
854
855 type[index] |= cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL |
856 IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL);
857
858 if (chan->flags & IEEE80211_CHAN_NO_HT40)
859 type[index] |=
860 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW);
861
862 /* scan for all SSIDs from req->ssids */
863 type[index] |= cpu_to_le32(ssid_bitmap);
864 }
865}
866
867int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
868 struct ieee80211_vif *vif,
869 struct cfg80211_sched_scan_request *req,
870 struct ieee80211_scan_ies *ies)
871{
872 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
873 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
874 int head = 0;
875 u32 ssid_bitmap;
876 int cmd_len;
877 int ret;
878 u8 *probes;
879 bool basic_ssid = !(mvm->fw->ucode_capa.flags &
880 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
881
882 struct iwl_scan_offload_cfg *scan_cfg;
883 struct iwl_host_cmd cmd = {
884 .id = SCAN_OFFLOAD_CONFIG_CMD,
885 };
886 struct iwl_mvm_scan_params params = {};
887
888 lockdep_assert_held(&mvm->mutex);
889
890 cmd_len = sizeof(struct iwl_scan_offload_cfg) +
891 mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE +
892 2 * SCAN_OFFLOAD_PROBE_REQ_SIZE;
893
894 scan_cfg = kzalloc(cmd_len, GFP_KERNEL);
895 if (!scan_cfg)
896 return -ENOMEM;
897
898 probes = scan_cfg->data +
899 mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE;
900
901 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);
902 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, &params);
903 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len);
904
905 iwl_scan_offload_build_ssid(req, scan_cfg->scan_cmd.direct_scan,
906 &ssid_bitmap, basic_ssid);
907 /* build tx frames for supported bands */
908 if (band_2ghz) {
909 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
910 IEEE80211_BAND_2GHZ,
911 &scan_cfg->scan_cmd.tx_cmd[0],
912 probes);
913 iwl_build_channel_cfg(mvm, req, scan_cfg->data,
914 IEEE80211_BAND_2GHZ, &head,
915 ssid_bitmap, &params);
916 }
917 if (band_5ghz) {
918 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
919 IEEE80211_BAND_5GHZ,
920 &scan_cfg->scan_cmd.tx_cmd[1],
921 probes +
922 SCAN_OFFLOAD_PROBE_REQ_SIZE);
923 iwl_build_channel_cfg(mvm, req, scan_cfg->data,
924 IEEE80211_BAND_5GHZ, &head,
925 ssid_bitmap, &params);
926 }
927
928 cmd.data[0] = scan_cfg;
929 cmd.len[0] = cmd_len;
930 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
931
932 IWL_DEBUG_SCAN(mvm, "Sending scheduled scan config\n");
933
934 ret = iwl_mvm_send_cmd(mvm, &cmd);
935 kfree(scan_cfg);
936 return ret;
937}
938
939int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, 436int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
940 struct cfg80211_sched_scan_request *req) 437 struct cfg80211_sched_scan_request *req)
941{ 438{
@@ -1018,33 +515,6 @@ static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm,
1018 return true; 515 return true;
1019} 516}
1020 517
1021int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
1022 struct cfg80211_sched_scan_request *req)
1023{
1024 struct iwl_scan_offload_req scan_req = {
1025 .watchdog = IWL_SCHED_SCAN_WATCHDOG,
1026
1027 .schedule_line[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS,
1028 .schedule_line[0].delay = cpu_to_le16(req->interval / 1000),
1029 .schedule_line[0].full_scan_mul = 1,
1030
1031 .schedule_line[1].iterations = 0xff,
1032 .schedule_line[1].delay = cpu_to_le16(req->interval / 1000),
1033 .schedule_line[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER,
1034 };
1035
1036 if (iwl_mvm_scan_pass_all(mvm, req))
1037 scan_req.flags |= cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_PASS_ALL);
1038
1039 if (mvm->last_ebs_successful &&
1040 mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT)
1041 scan_req.flags |=
1042 cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_EBS_ACCURATE_MODE);
1043
1044 return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, 0,
1045 sizeof(scan_req), &scan_req);
1046}
1047
1048int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, 518int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm,
1049 struct ieee80211_vif *vif, 519 struct ieee80211_vif *vif,
1050 struct cfg80211_sched_scan_request *req, 520 struct cfg80211_sched_scan_request *req,
@@ -1057,21 +527,12 @@ int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm,
1057 if (ret) 527 if (ret)
1058 return ret; 528 return ret;
1059 ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies); 529 ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies);
1060 } else if ((mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) {
1061 mvm->scan_status = IWL_MVM_SCAN_SCHED;
1062 ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
1063 if (ret)
1064 return ret;
1065 ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies);
1066 } else { 530 } else {
1067 mvm->scan_status = IWL_MVM_SCAN_SCHED; 531 mvm->scan_status = IWL_MVM_SCAN_SCHED;
1068 ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies);
1069 if (ret)
1070 return ret;
1071 ret = iwl_mvm_config_sched_scan_profiles(mvm, req); 532 ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
1072 if (ret) 533 if (ret)
1073 return ret; 534 return ret;
1074 ret = iwl_mvm_sched_scan_start(mvm, req); 535 ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies);
1075 } 536 }
1076 537
1077 return ret; 538 return ret;
@@ -1088,9 +549,7 @@ static int iwl_mvm_send_scan_offload_abort(struct iwl_mvm *mvm)
1088 /* Exit instantly with error when device is not ready 549 /* Exit instantly with error when device is not ready
1089 * to receive scan abort command or it does not perform 550 * to receive scan abort command or it does not perform
1090 * scheduled scan currently */ 551 * scheduled scan currently */
1091 if (mvm->scan_status != IWL_MVM_SCAN_SCHED && 552 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
1092 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
1093 mvm->scan_status != IWL_MVM_SCAN_OS))
1094 return -EIO; 553 return -EIO;
1095 554
1096 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status); 555 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
@@ -1131,13 +590,6 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
1131 if (iwl_mvm_is_radio_killed(mvm)) 590 if (iwl_mvm_is_radio_killed(mvm))
1132 goto out; 591 goto out;
1133 592
1134 if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
1135 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
1136 mvm->scan_status != IWL_MVM_SCAN_OS)) {
1137 IWL_DEBUG_SCAN(mvm, "No scan to stop\n");
1138 return 0;
1139 }
1140
1141 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done, 593 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done,
1142 scan_done_notif, 594 scan_done_notif,
1143 ARRAY_SIZE(scan_done_notif), 595 ARRAY_SIZE(scan_done_notif),
@@ -1317,7 +769,7 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
1317 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive; 769 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive;
1318 if (params->passive_fragmented) 770 if (params->passive_fragmented)
1319 cmd->fragmented_dwell = 771 cmd->fragmented_dwell =
1320 params->dwell[IEEE80211_BAND_2GHZ].passive; 772 params->dwell[IEEE80211_BAND_2GHZ].fragmented;
1321 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm); 773 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
1322 cmd->max_out_time = cpu_to_le32(params->max_out_time); 774 cmd->max_out_time = cpu_to_le32(params->max_out_time);
1323 cmd->suspend_time = cpu_to_le32(params->suspend_time); 775 cmd->suspend_time = cpu_to_le32(params->suspend_time);
@@ -1580,9 +1032,7 @@ int iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
1580 return 0; 1032 return 0;
1581 } 1033 }
1582 1034
1583 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) 1035 return iwl_mvm_scan_offload_stop(mvm, true);
1584 return iwl_mvm_scan_offload_stop(mvm, true);
1585 return iwl_mvm_cancel_regular_scan(mvm);
1586} 1036}
1587 1037
1588/* UMAC scan API */ 1038/* UMAC scan API */
@@ -1765,7 +1215,7 @@ iwl_mvm_build_generic_umac_scan_cmd(struct iwl_mvm *mvm,
1765 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive; 1215 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive;
1766 if (params->passive_fragmented) 1216 if (params->passive_fragmented)
1767 cmd->fragmented_dwell = 1217 cmd->fragmented_dwell =
1768 params->dwell[IEEE80211_BAND_2GHZ].passive; 1218 params->dwell[IEEE80211_BAND_2GHZ].fragmented;
1769 cmd->max_out_time = cpu_to_le32(params->max_out_time); 1219 cmd->max_out_time = cpu_to_le32(params->max_out_time);
1770 cmd->suspend_time = cpu_to_le32(params->suspend_time); 1220 cmd->suspend_time = cpu_to_le32(params->suspend_time);
1771 cmd->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); 1221 cmd->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH);
@@ -2159,14 +1609,8 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm)
2159 mvm->fw->ucode_capa.n_scan_channels + 1609 mvm->fw->ucode_capa.n_scan_channels +
2160 sizeof(struct iwl_scan_req_umac_tail); 1610 sizeof(struct iwl_scan_req_umac_tail);
2161 1611
2162 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) 1612 return sizeof(struct iwl_scan_req_unified_lmac) +
2163 return sizeof(struct iwl_scan_req_unified_lmac) + 1613 sizeof(struct iwl_scan_channel_cfg_lmac) *
2164 sizeof(struct iwl_scan_channel_cfg_lmac) * 1614 mvm->fw->ucode_capa.n_scan_channels +
2165 mvm->fw->ucode_capa.n_scan_channels + 1615 sizeof(struct iwl_scan_probe_req);
2166 sizeof(struct iwl_scan_probe_req);
2167
2168 return sizeof(struct iwl_scan_cmd) +
2169 mvm->fw->ucode_capa.max_probe_length +
2170 mvm->fw->ucode_capa.n_scan_channels *
2171 sizeof(struct iwl_scan_channel);
2172} 1616}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 07304e1fd64a..7906b97c81b9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -664,6 +664,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
664 info->status.rates[0].count = tx_resp->failure_frame + 1; 664 info->status.rates[0].count = tx_resp->failure_frame + 1;
665 iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate), 665 iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate),
666 info); 666 info);
667 info->status.status_driver_data[1] =
668 (void *)(uintptr_t)le32_to_cpu(tx_resp->initial_rate);
667 669
668 /* Single frame failure in an AMPDU queue => send BAR */ 670 /* Single frame failure in an AMPDU queue => send BAR */
669 if (txq_id >= mvm->first_agg_queue && 671 if (txq_id >= mvm->first_agg_queue &&
@@ -909,6 +911,8 @@ static void iwl_mvm_tx_info_from_ba_notif(struct ieee80211_tx_info *info,
909 info->status.tx_time = tid_data->tx_time; 911 info->status.tx_time = tid_data->tx_time;
910 info->status.status_driver_data[0] = 912 info->status.status_driver_data[0] =
911 (void *)(uintptr_t)tid_data->reduced_tpc; 913 (void *)(uintptr_t)tid_data->reduced_tpc;
914 info->status.status_driver_data[1] =
915 (void *)(uintptr_t)tid_data->rate_n_flags;
912} 916}
913 917
914int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, 918int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 8decf9953229..2b9de63951e6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -332,7 +332,7 @@ static const char *desc_lookup(u32 num)
332 * read with u32-sized accesses, any members with a different size 332 * read with u32-sized accesses, any members with a different size
333 * need to be ordered correctly though! 333 * need to be ordered correctly though!
334 */ 334 */
335struct iwl_error_event_table { 335struct iwl_error_event_table_v1 {
336 u32 valid; /* (nonzero) valid, (0) log is empty */ 336 u32 valid; /* (nonzero) valid, (0) log is empty */
337 u32 error_id; /* type of error */ 337 u32 error_id; /* type of error */
338 u32 pc; /* program counter */ 338 u32 pc; /* program counter */
@@ -377,7 +377,55 @@ struct iwl_error_event_table {
377 u32 u_timestamp; /* indicate when the date and time of the 377 u32 u_timestamp; /* indicate when the date and time of the
378 * compilation */ 378 * compilation */
379 u32 flow_handler; /* FH read/write pointers, RX credit */ 379 u32 flow_handler; /* FH read/write pointers, RX credit */
380} __packed; 380} __packed /* LOG_ERROR_TABLE_API_S_VER_1 */;
381
382struct iwl_error_event_table {
383 u32 valid; /* (nonzero) valid, (0) log is empty */
384 u32 error_id; /* type of error */
385 u32 pc; /* program counter */
386 u32 blink1; /* branch link */
387 u32 blink2; /* branch link */
388 u32 ilink1; /* interrupt link */
389 u32 ilink2; /* interrupt link */
390 u32 data1; /* error-specific data */
391 u32 data2; /* error-specific data */
392 u32 data3; /* error-specific data */
393 u32 bcon_time; /* beacon timer */
394 u32 tsf_low; /* network timestamp function timer */
395 u32 tsf_hi; /* network timestamp function timer */
396 u32 gp1; /* GP1 timer register */
397 u32 gp2; /* GP2 timer register */
398 u32 gp3; /* GP3 timer register */
399 u32 major; /* uCode version major */
400 u32 minor; /* uCode version minor */
401 u32 hw_ver; /* HW Silicon version */
402 u32 brd_ver; /* HW board version */
403 u32 log_pc; /* log program counter */
404 u32 frame_ptr; /* frame pointer */
405 u32 stack_ptr; /* stack pointer */
406 u32 hcmd; /* last host command header */
407 u32 isr0; /* isr status register LMPM_NIC_ISR0:
408 * rxtx_flag */
409 u32 isr1; /* isr status register LMPM_NIC_ISR1:
410 * host_flag */
411 u32 isr2; /* isr status register LMPM_NIC_ISR2:
412 * enc_flag */
413 u32 isr3; /* isr status register LMPM_NIC_ISR3:
414 * time_flag */
415 u32 isr4; /* isr status register LMPM_NIC_ISR4:
416 * wico interrupt */
417 u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
418 u32 wait_event; /* wait event() caller address */
419 u32 l2p_control; /* L2pControlField */
420 u32 l2p_duration; /* L2pDurationField */
421 u32 l2p_mhvalid; /* L2pMhValidBits */
422 u32 l2p_addr_match; /* L2pAddrMatchStat */
423 u32 lmpm_pmg_sel; /* indicate which clocks are turned on
424 * (LMPM_PMG_SEL) */
425 u32 u_timestamp; /* indicate when the date and time of the
426 * compilation */
427 u32 flow_handler; /* FH read/write pointers, RX credit */
428} __packed /* LOG_ERROR_TABLE_API_S_VER_2 */;
381 429
382/* 430/*
383 * UMAC error struct - relevant starting from family 8000 chip. 431 * UMAC error struct - relevant starting from family 8000 chip.
@@ -396,11 +444,11 @@ struct iwl_umac_error_event_table {
396 u32 data1; /* error-specific data */ 444 u32 data1; /* error-specific data */
397 u32 data2; /* error-specific data */ 445 u32 data2; /* error-specific data */
398 u32 data3; /* error-specific data */ 446 u32 data3; /* error-specific data */
399 u32 umac_fw_ver; /* UMAC version */ 447 u32 umac_major;
400 u32 umac_fw_api_ver; /* UMAC FW API ver */ 448 u32 umac_minor;
401 u32 frame_pointer; /* core register 27*/ 449 u32 frame_pointer; /* core register 27*/
402 u32 stack_pointer; /* core register 28 */ 450 u32 stack_pointer; /* core register 28 */
403 u32 cmd_header; /* latest host cmd sent to UMAC */ 451 u32 cmd_header; /* latest host cmd sent to UMAC */
404 u32 nic_isr_pref; /* ISR status register */ 452 u32 nic_isr_pref; /* ISR status register */
405} __packed; 453} __packed;
406 454
@@ -441,18 +489,18 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
441 IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1); 489 IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1);
442 IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2); 490 IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2);
443 IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3); 491 IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3);
444 IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_fw_ver); 492 IWL_ERR(mvm, "0x%08X | umac major\n", table.umac_major);
445 IWL_ERR(mvm, "0x%08X | umac api version\n", table.umac_fw_api_ver); 493 IWL_ERR(mvm, "0x%08X | umac minor\n", table.umac_minor);
446 IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer); 494 IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer);
447 IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer); 495 IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer);
448 IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header); 496 IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header);
449 IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref); 497 IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref);
450} 498}
451 499
452void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) 500static void iwl_mvm_dump_nic_error_log_old(struct iwl_mvm *mvm)
453{ 501{
454 struct iwl_trans *trans = mvm->trans; 502 struct iwl_trans *trans = mvm->trans;
455 struct iwl_error_event_table table; 503 struct iwl_error_event_table_v1 table;
456 u32 base; 504 u32 base;
457 505
458 base = mvm->error_event_table; 506 base = mvm->error_event_table;
@@ -489,7 +537,7 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
489 table.data1, table.data2, table.data3, 537 table.data1, table.data2, table.data3,
490 table.blink1, table.blink2, table.ilink1, 538 table.blink1, table.blink2, table.ilink1,
491 table.ilink2, table.bcon_time, table.gp1, 539 table.ilink2, table.bcon_time, table.gp1,
492 table.gp2, table.gp3, table.ucode_ver, 540 table.gp2, table.gp3, table.ucode_ver, 0,
493 table.hw_ver, table.brd_ver); 541 table.hw_ver, table.brd_ver);
494 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, 542 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
495 desc_lookup(table.error_id)); 543 desc_lookup(table.error_id));
@@ -530,6 +578,92 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
530 iwl_mvm_dump_umac_error_log(mvm); 578 iwl_mvm_dump_umac_error_log(mvm);
531} 579}
532 580
581void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
582{
583 struct iwl_trans *trans = mvm->trans;
584 struct iwl_error_event_table table;
585 u32 base;
586
587 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_NEW_VERSION)) {
588 iwl_mvm_dump_nic_error_log_old(mvm);
589 return;
590 }
591
592 base = mvm->error_event_table;
593 if (mvm->cur_ucode == IWL_UCODE_INIT) {
594 if (!base)
595 base = mvm->fw->init_errlog_ptr;
596 } else {
597 if (!base)
598 base = mvm->fw->inst_errlog_ptr;
599 }
600
601 if (base < 0x800000) {
602 IWL_ERR(mvm,
603 "Not valid error log pointer 0x%08X for %s uCode\n",
604 base,
605 (mvm->cur_ucode == IWL_UCODE_INIT)
606 ? "Init" : "RT");
607 return;
608 }
609
610 iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
611
612 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
613 IWL_ERR(trans, "Start IWL Error Log Dump:\n");
614 IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
615 mvm->status, table.valid);
616 }
617
618 /* Do not change this output - scripts rely on it */
619
620 IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version);
621
622 trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
623 table.data1, table.data2, table.data3,
624 table.blink1, table.blink2, table.ilink1,
625 table.ilink2, table.bcon_time, table.gp1,
626 table.gp2, table.gp3, table.major,
627 table.minor, table.hw_ver, table.brd_ver);
628 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
629 desc_lookup(table.error_id));
630 IWL_ERR(mvm, "0x%08X | uPc\n", table.pc);
631 IWL_ERR(mvm, "0x%08X | branchlink1\n", table.blink1);
632 IWL_ERR(mvm, "0x%08X | branchlink2\n", table.blink2);
633 IWL_ERR(mvm, "0x%08X | interruptlink1\n", table.ilink1);
634 IWL_ERR(mvm, "0x%08X | interruptlink2\n", table.ilink2);
635 IWL_ERR(mvm, "0x%08X | data1\n", table.data1);
636 IWL_ERR(mvm, "0x%08X | data2\n", table.data2);
637 IWL_ERR(mvm, "0x%08X | data3\n", table.data3);
638 IWL_ERR(mvm, "0x%08X | beacon time\n", table.bcon_time);
639 IWL_ERR(mvm, "0x%08X | tsf low\n", table.tsf_low);
640 IWL_ERR(mvm, "0x%08X | tsf hi\n", table.tsf_hi);
641 IWL_ERR(mvm, "0x%08X | time gp1\n", table.gp1);
642 IWL_ERR(mvm, "0x%08X | time gp2\n", table.gp2);
643 IWL_ERR(mvm, "0x%08X | time gp3\n", table.gp3);
644 IWL_ERR(mvm, "0x%08X | uCode version major\n", table.major);
645 IWL_ERR(mvm, "0x%08X | uCode version minor\n", table.minor);
646 IWL_ERR(mvm, "0x%08X | hw version\n", table.hw_ver);
647 IWL_ERR(mvm, "0x%08X | board version\n", table.brd_ver);
648 IWL_ERR(mvm, "0x%08X | hcmd\n", table.hcmd);
649 IWL_ERR(mvm, "0x%08X | isr0\n", table.isr0);
650 IWL_ERR(mvm, "0x%08X | isr1\n", table.isr1);
651 IWL_ERR(mvm, "0x%08X | isr2\n", table.isr2);
652 IWL_ERR(mvm, "0x%08X | isr3\n", table.isr3);
653 IWL_ERR(mvm, "0x%08X | isr4\n", table.isr4);
654 IWL_ERR(mvm, "0x%08X | isr_pref\n", table.isr_pref);
655 IWL_ERR(mvm, "0x%08X | wait_event\n", table.wait_event);
656 IWL_ERR(mvm, "0x%08X | l2p_control\n", table.l2p_control);
657 IWL_ERR(mvm, "0x%08X | l2p_duration\n", table.l2p_duration);
658 IWL_ERR(mvm, "0x%08X | l2p_mhvalid\n", table.l2p_mhvalid);
659 IWL_ERR(mvm, "0x%08X | l2p_addr_match\n", table.l2p_addr_match);
660 IWL_ERR(mvm, "0x%08X | lmpm_pmg_sel\n", table.lmpm_pmg_sel);
661 IWL_ERR(mvm, "0x%08X | timestamp\n", table.u_timestamp);
662 IWL_ERR(mvm, "0x%08X | flow_handler\n", table.flow_handler);
663
664 if (mvm->support_umac_log)
665 iwl_mvm_dump_umac_error_log(mvm);
666}
533void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, 667void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
534 const struct iwl_trans_txq_scd_cfg *cfg, 668 const struct iwl_trans_txq_scd_cfg *cfg,
535 unsigned int wdg_timeout) 669 unsigned int wdg_timeout)
@@ -643,6 +777,40 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
643 ieee80211_request_smps(vif, smps_mode); 777 ieee80211_request_smps(vif, smps_mode);
644} 778}
645 779
780int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear)
781{
782 struct iwl_statistics_cmd scmd = {
783 .flags = clear ? cpu_to_le32(IWL_STATISTICS_FLG_CLEAR) : 0,
784 };
785 struct iwl_host_cmd cmd = {
786 .id = STATISTICS_CMD,
787 .len[0] = sizeof(scmd),
788 .data[0] = &scmd,
789 .flags = CMD_WANT_SKB,
790 };
791 int ret;
792
793 ret = iwl_mvm_send_cmd(mvm, &cmd);
794 if (ret)
795 return ret;
796
797 iwl_mvm_handle_rx_statistics(mvm, cmd.resp_pkt);
798 iwl_free_resp(&cmd);
799
800 if (clear)
801 iwl_mvm_accu_radio_stats(mvm);
802
803 return 0;
804}
805
806void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm)
807{
808 mvm->accu_radio_stats.rx_time += mvm->radio_stats.rx_time;
809 mvm->accu_radio_stats.tx_time += mvm->radio_stats.tx_time;
810 mvm->accu_radio_stats.on_time_rf += mvm->radio_stats.on_time_rf;
811 mvm->accu_radio_stats.on_time_scan += mvm->radio_stats.on_time_scan;
812}
813
646static void iwl_mvm_diversity_iter(void *_data, u8 *mac, 814static void iwl_mvm_diversity_iter(void *_data, u8 *mac,
647 struct ieee80211_vif *vif) 815 struct ieee80211_vif *vif)
648{ 816{
@@ -717,25 +885,6 @@ bool iwl_mvm_low_latency(struct iwl_mvm *mvm)
717 return result; 885 return result;
718} 886}
719 887
720static void iwl_mvm_idle_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
721{
722 bool *idle = _data;
723
724 if (!vif->bss_conf.idle)
725 *idle = false;
726}
727
728bool iwl_mvm_is_idle(struct iwl_mvm *mvm)
729{
730 bool idle = true;
731
732 ieee80211_iterate_active_interfaces_atomic(
733 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
734 iwl_mvm_idle_iter, &idle);
735
736 return idle;
737}
738
739struct iwl_bss_iter_data { 888struct iwl_bss_iter_data {
740 struct ieee80211_vif *vif; 889 struct ieee80211_vif *vif;
741 bool error; 890 bool error;
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 69935aa5a1b3..f31a94160771 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -898,6 +898,9 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
898 IWL_DEBUG_FW(trans, "working with %s CPU\n", 898 IWL_DEBUG_FW(trans, "working with %s CPU\n",
899 image->is_dual_cpus ? "Dual" : "Single"); 899 image->is_dual_cpus ? "Dual" : "Single");
900 900
901 if (trans->dbg_dest_tlv)
902 iwl_pcie_apply_destination(trans);
903
901 /* configure the ucode to be ready to get the secured image */ 904 /* configure the ucode to be ready to get the secured image */
902 /* release CPU reset */ 905 /* release CPU reset */
903 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); 906 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
@@ -914,9 +917,6 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
914 if (ret) 917 if (ret)
915 return ret; 918 return ret;
916 919
917 if (trans->dbg_dest_tlv)
918 iwl_pcie_apply_destination(trans);
919
920 /* wait for image verification to complete */ 920 /* wait for image verification to complete */
921 ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0, 921 ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0,
922 LMPM_SECURE_BOOT_STATUS_SUCCESS, 922 LMPM_SECURE_BOOT_STATUS_SUCCESS,
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index cc6a0a586f0b..26cbf1dcc662 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -742,8 +742,7 @@ void lbs_debugfs_init(void)
742 742
743void lbs_debugfs_remove(void) 743void lbs_debugfs_remove(void)
744{ 744{
745 if (lbs_dir) 745 debugfs_remove(lbs_dir);
746 debugfs_remove(lbs_dir);
747} 746}
748 747
749void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev) 748void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 7c3ca2f50186..8e1f681f960b 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2397,7 +2397,6 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
2397 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 2397 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2398} 2398}
2399 2399
2400#define MWIFIEX_MAX_WQ_LEN 30
2401/* 2400/*
2402 * create a new virtual interface with the given name 2401 * create a new virtual interface with the given name
2403 */ 2402 */
@@ -2411,7 +2410,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2411 struct mwifiex_private *priv; 2410 struct mwifiex_private *priv;
2412 struct net_device *dev; 2411 struct net_device *dev;
2413 void *mdev_priv; 2412 void *mdev_priv;
2414 char dfs_cac_str[MWIFIEX_MAX_WQ_LEN], dfs_chsw_str[MWIFIEX_MAX_WQ_LEN];
2415 2413
2416 if (!adapter) 2414 if (!adapter)
2417 return ERR_PTR(-EFAULT); 2415 return ERR_PTR(-EFAULT);
@@ -2576,12 +2574,10 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2576 return ERR_PTR(-EFAULT); 2574 return ERR_PTR(-EFAULT);
2577 } 2575 }
2578 2576
2579 strcpy(dfs_cac_str, "MWIFIEX_DFS_CAC"); 2577 priv->dfs_cac_workqueue = alloc_workqueue("MWIFIEX_DFS_CAC%s",
2580 strcat(dfs_cac_str, name);
2581 priv->dfs_cac_workqueue = alloc_workqueue(dfs_cac_str,
2582 WQ_HIGHPRI | 2578 WQ_HIGHPRI |
2583 WQ_MEM_RECLAIM | 2579 WQ_MEM_RECLAIM |
2584 WQ_UNBOUND, 1); 2580 WQ_UNBOUND, 1, name);
2585 if (!priv->dfs_cac_workqueue) { 2581 if (!priv->dfs_cac_workqueue) {
2586 wiphy_err(wiphy, "cannot register virtual network device\n"); 2582 wiphy_err(wiphy, "cannot register virtual network device\n");
2587 free_netdev(dev); 2583 free_netdev(dev);
@@ -2594,11 +2590,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2594 2590
2595 INIT_DELAYED_WORK(&priv->dfs_cac_work, mwifiex_dfs_cac_work_queue); 2591 INIT_DELAYED_WORK(&priv->dfs_cac_work, mwifiex_dfs_cac_work_queue);
2596 2592
2597 strcpy(dfs_chsw_str, "MWIFIEX_DFS_CHSW"); 2593 priv->dfs_chan_sw_workqueue = alloc_workqueue("MWIFIEX_DFS_CHSW%s",
2598 strcat(dfs_chsw_str, name);
2599 priv->dfs_chan_sw_workqueue = alloc_workqueue(dfs_chsw_str,
2600 WQ_HIGHPRI | WQ_UNBOUND | 2594 WQ_HIGHPRI | WQ_UNBOUND |
2601 WQ_MEM_RECLAIM, 1); 2595 WQ_MEM_RECLAIM, 1, name);
2602 if (!priv->dfs_chan_sw_workqueue) { 2596 if (!priv->dfs_chan_sw_workqueue) {
2603 wiphy_err(wiphy, "cannot register virtual network device\n"); 2597 wiphy_err(wiphy, "cannot register virtual network device\n");
2604 free_netdev(dev); 2598 free_netdev(dev);
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 88d0eade6bb1..cf2fa110e251 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -33,6 +33,7 @@
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
36#define MWIFIEX_RX_HEADROOM 64
36#define MAX_TXPD_SZ 32 37#define MAX_TXPD_SZ 32
37#define INTF_HDR_ALIGN 4 38#define INTF_HDR_ALIGN 4
38 39
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 0978b1cc58b6..0153ce6d5879 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -296,7 +296,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
296 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); 296 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
297 adapter->arp_filter_size = 0; 297 adapter->arp_filter_size = 0;
298 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; 298 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
299 adapter->ext_scan = false;
300 adapter->key_api_major_ver = 0; 299 adapter->key_api_major_ver = 0;
301 adapter->key_api_minor_ver = 0; 300 adapter->key_api_minor_ver = 0;
302 eth_broadcast_addr(adapter->perm_addr); 301 eth_broadcast_addr(adapter->perm_addr);
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 7e74b4fccddd..74488aba92bd 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -190,14 +190,16 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
190 190
191 /* Check if already processing */ 191 /* Check if already processing */
192 if (adapter->mwifiex_processing) { 192 if (adapter->mwifiex_processing) {
193 adapter->more_task_flag = true;
193 spin_unlock_irqrestore(&adapter->main_proc_lock, flags); 194 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
194 goto exit_main_proc; 195 goto exit_main_proc;
195 } else { 196 } else {
196 adapter->mwifiex_processing = true; 197 adapter->mwifiex_processing = true;
197 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
198 } 198 }
199process_start: 199process_start:
200 do { 200 do {
201 adapter->more_task_flag = false;
202 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
201 if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) || 203 if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
202 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)) 204 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
203 break; 205 break;
@@ -238,6 +240,7 @@ process_start:
238 adapter->pm_wakeup_fw_try = true; 240 adapter->pm_wakeup_fw_try = true;
239 mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3)); 241 mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3));
240 adapter->if_ops.wakeup(adapter); 242 adapter->if_ops.wakeup(adapter);
243 spin_lock_irqsave(&adapter->main_proc_lock, flags);
241 continue; 244 continue;
242 } 245 }
243 246
@@ -295,8 +298,10 @@ process_start:
295 if ((adapter->ps_state == PS_STATE_SLEEP) || 298 if ((adapter->ps_state == PS_STATE_SLEEP) ||
296 (adapter->ps_state == PS_STATE_PRE_SLEEP) || 299 (adapter->ps_state == PS_STATE_PRE_SLEEP) ||
297 (adapter->ps_state == PS_STATE_SLEEP_CFM) || 300 (adapter->ps_state == PS_STATE_SLEEP_CFM) ||
298 adapter->tx_lock_flag) 301 adapter->tx_lock_flag){
302 spin_lock_irqsave(&adapter->main_proc_lock, flags);
299 continue; 303 continue;
304 }
300 305
301 if (!adapter->cmd_sent && !adapter->curr_cmd) { 306 if (!adapter->cmd_sent && !adapter->curr_cmd) {
302 if (mwifiex_exec_next_cmd(adapter) == -1) { 307 if (mwifiex_exec_next_cmd(adapter) == -1) {
@@ -330,15 +335,12 @@ process_start:
330 } 335 }
331 break; 336 break;
332 } 337 }
338 spin_lock_irqsave(&adapter->main_proc_lock, flags);
333 } while (true); 339 } while (true);
334 340
335 spin_lock_irqsave(&adapter->main_proc_lock, flags); 341 spin_lock_irqsave(&adapter->main_proc_lock, flags);
336 if (!adapter->delay_main_work && 342 if (adapter->more_task_flag)
337 (adapter->int_status || IS_CARD_RX_RCVD(adapter))) {
338 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
339 goto process_start; 343 goto process_start;
340 }
341
342 adapter->mwifiex_processing = false; 344 adapter->mwifiex_processing = false;
343 spin_unlock_irqrestore(&adapter->main_proc_lock, flags); 345 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
344 346
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index f0a6af179af0..16be45e9a66a 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -140,6 +140,9 @@ enum {
140 140
141#define MWIFIEX_DRV_INFO_SIZE_MAX 0x40000 141#define MWIFIEX_DRV_INFO_SIZE_MAX 0x40000
142 142
143/* Address alignment */
144#define MWIFIEX_ALIGN_ADDR(p, a) (((long)(p) + (a) - 1) & ~((a) - 1))
145
143struct mwifiex_dbg { 146struct mwifiex_dbg {
144 u32 num_cmd_host_to_card_failure; 147 u32 num_cmd_host_to_card_failure;
145 u32 num_cmd_sleep_cfm_host_to_card_failure; 148 u32 num_cmd_sleep_cfm_host_to_card_failure;
@@ -774,6 +777,7 @@ struct mwifiex_adapter {
774 /* spin lock for main process */ 777 /* spin lock for main process */
775 spinlock_t main_proc_lock; 778 spinlock_t main_proc_lock;
776 u32 mwifiex_processing; 779 u32 mwifiex_processing;
780 u8 more_task_flag;
777 u16 tx_buf_size; 781 u16 tx_buf_size;
778 u16 curr_tx_buf_size; 782 u16 curr_tx_buf_size;
779 u32 ioport; 783 u32 ioport;
@@ -1417,6 +1421,7 @@ u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
1417 u8 rx_rate, u8 ht_info); 1421 u8 rx_rate, u8 ht_info);
1418 1422
1419void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter); 1423void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter);
1424void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags);
1420 1425
1421#ifdef CONFIG_DEBUG_FS 1426#ifdef CONFIG_DEBUG_FS
1422void mwifiex_debugfs_init(void); 1427void mwifiex_debugfs_init(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index a5828da59365..4b463c3b9906 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -203,7 +203,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
203 card->pcie.reg = data->reg; 203 card->pcie.reg = data->reg;
204 card->pcie.blksz_fw_dl = data->blksz_fw_dl; 204 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
205 card->pcie.tx_buf_size = data->tx_buf_size; 205 card->pcie.tx_buf_size = data->tx_buf_size;
206 card->pcie.supports_fw_dump = data->supports_fw_dump; 206 card->pcie.can_dump_fw = data->can_dump_fw;
207 card->pcie.can_ext_scan = data->can_ext_scan; 207 card->pcie.can_ext_scan = data->can_ext_scan;
208 } 208 }
209 209
@@ -498,7 +498,8 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
498 498
499 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { 499 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
500 /* Allocate skb here so that firmware can DMA data from it */ 500 /* Allocate skb here so that firmware can DMA data from it */
501 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); 501 skb = mwifiex_alloc_rx_buf(MWIFIEX_RX_DATA_BUF_SIZE,
502 GFP_KERNEL | GFP_DMA);
502 if (!skb) { 503 if (!skb) {
503 dev_err(adapter->dev, 504 dev_err(adapter->dev,
504 "Unable to allocate skb for RX ring.\n"); 505 "Unable to allocate skb for RX ring.\n");
@@ -1297,7 +1298,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1297 } 1298 }
1298 } 1299 }
1299 1300
1300 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); 1301 skb_tmp = mwifiex_alloc_rx_buf(MWIFIEX_RX_DATA_BUF_SIZE,
1302 GFP_KERNEL | GFP_DMA);
1301 if (!skb_tmp) { 1303 if (!skb_tmp) {
1302 dev_err(adapter->dev, 1304 dev_err(adapter->dev,
1303 "Unable to allocate skb.\n"); 1305 "Unable to allocate skb.\n");
@@ -2271,7 +2273,7 @@ static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
2271 int ret; 2273 int ret;
2272 static char *env[] = { "DRIVER=mwifiex_pcie", "EVENT=fw_dump", NULL }; 2274 static char *env[] = { "DRIVER=mwifiex_pcie", "EVENT=fw_dump", NULL };
2273 2275
2274 if (!card->pcie.supports_fw_dump) 2276 if (!card->pcie.can_dump_fw)
2275 return; 2277 return;
2276 2278
2277 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) { 2279 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index 666d40e9dbc3..0e7ee8b72358 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -205,7 +205,7 @@ struct mwifiex_pcie_device {
205 const struct mwifiex_pcie_card_reg *reg; 205 const struct mwifiex_pcie_card_reg *reg;
206 u16 blksz_fw_dl; 206 u16 blksz_fw_dl;
207 u16 tx_buf_size; 207 u16 tx_buf_size;
208 bool supports_fw_dump; 208 bool can_dump_fw;
209 bool can_ext_scan; 209 bool can_ext_scan;
210}; 210};
211 211
@@ -214,7 +214,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
214 .reg = &mwifiex_reg_8766, 214 .reg = &mwifiex_reg_8766,
215 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 215 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
216 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 216 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
217 .supports_fw_dump = false, 217 .can_dump_fw = false,
218 .can_ext_scan = true, 218 .can_ext_scan = true,
219}; 219};
220 220
@@ -223,7 +223,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
223 .reg = &mwifiex_reg_8897, 223 .reg = &mwifiex_reg_8897,
224 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 224 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
225 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 225 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
226 .supports_fw_dump = true, 226 .can_dump_fw = true,
227 .can_ext_scan = true, 227 .can_ext_scan = true,
228}; 228};
229 229
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 91e36cda9543..57d85ab442bf 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -105,8 +105,8 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
105 card->tx_buf_size = data->tx_buf_size; 105 card->tx_buf_size = data->tx_buf_size;
106 card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size; 106 card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size;
107 card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size; 107 card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size;
108 card->supports_fw_dump = data->supports_fw_dump; 108 card->can_dump_fw = data->can_dump_fw;
109 card->auto_tdls = data->auto_tdls; 109 card->can_auto_tdls = data->can_auto_tdls;
110 card->can_ext_scan = data->can_ext_scan; 110 card->can_ext_scan = data->can_ext_scan;
111 } 111 }
112 112
@@ -1357,7 +1357,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1357 return -1; 1357 return -1;
1358 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); 1358 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1359 1359
1360 skb = dev_alloc_skb(rx_len); 1360 skb = mwifiex_alloc_rx_buf(rx_len, GFP_KERNEL | GFP_DMA);
1361 if (!skb) 1361 if (!skb)
1362 return -1; 1362 return -1;
1363 1363
@@ -1454,7 +1454,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1454 } 1454 }
1455 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); 1455 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1456 1456
1457 skb = dev_alloc_skb(rx_len); 1457 skb = mwifiex_alloc_rx_buf(rx_len,
1458 GFP_KERNEL | GFP_DMA);
1458 1459
1459 if (!skb) { 1460 if (!skb) {
1460 dev_err(adapter->dev, "%s: failed to alloc skb", 1461 dev_err(adapter->dev, "%s: failed to alloc skb",
@@ -1887,7 +1888,7 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
1887 return -1; 1888 return -1;
1888 } 1889 }
1889 1890
1890 adapter->auto_tdls = card->auto_tdls; 1891 adapter->auto_tdls = card->can_auto_tdls;
1891 adapter->ext_scan = card->can_ext_scan; 1892 adapter->ext_scan = card->can_ext_scan;
1892 return ret; 1893 return ret;
1893} 1894}
@@ -2032,7 +2033,7 @@ static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
2032 2033
2033 mwifiex_dump_drv_info(adapter); 2034 mwifiex_dump_drv_info(adapter);
2034 2035
2035 if (!card->supports_fw_dump) 2036 if (!card->can_dump_fw)
2036 return; 2037 return;
2037 2038
2038 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) { 2039 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 957cca246618..c636944c77bc 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -238,9 +238,6 @@ struct sdio_mmc_card {
238 const struct mwifiex_sdio_card_reg *reg; 238 const struct mwifiex_sdio_card_reg *reg;
239 u8 max_ports; 239 u8 max_ports;
240 u8 mp_agg_pkt_limit; 240 u8 mp_agg_pkt_limit;
241 bool supports_sdio_new_mode;
242 bool has_control_mask;
243 bool supports_fw_dump;
244 u16 tx_buf_size; 241 u16 tx_buf_size;
245 u32 mp_tx_agg_buf_size; 242 u32 mp_tx_agg_buf_size;
246 u32 mp_rx_agg_buf_size; 243 u32 mp_rx_agg_buf_size;
@@ -255,7 +252,10 @@ struct sdio_mmc_card {
255 u8 curr_wr_port; 252 u8 curr_wr_port;
256 253
257 u8 *mp_regs; 254 u8 *mp_regs;
258 u8 auto_tdls; 255 bool supports_sdio_new_mode;
256 bool has_control_mask;
257 bool can_dump_fw;
258 bool can_auto_tdls;
259 bool can_ext_scan; 259 bool can_ext_scan;
260 260
261 struct mwifiex_sdio_mpa_tx mpa_tx; 261 struct mwifiex_sdio_mpa_tx mpa_tx;
@@ -267,13 +267,13 @@ struct mwifiex_sdio_device {
267 const struct mwifiex_sdio_card_reg *reg; 267 const struct mwifiex_sdio_card_reg *reg;
268 u8 max_ports; 268 u8 max_ports;
269 u8 mp_agg_pkt_limit; 269 u8 mp_agg_pkt_limit;
270 bool supports_sdio_new_mode;
271 bool has_control_mask;
272 bool supports_fw_dump;
273 u16 tx_buf_size; 270 u16 tx_buf_size;
274 u32 mp_tx_agg_buf_size; 271 u32 mp_tx_agg_buf_size;
275 u32 mp_rx_agg_buf_size; 272 u32 mp_rx_agg_buf_size;
276 u8 auto_tdls; 273 bool supports_sdio_new_mode;
274 bool has_control_mask;
275 bool can_dump_fw;
276 bool can_auto_tdls;
277 bool can_ext_scan; 277 bool can_ext_scan;
278}; 278};
279 279
@@ -412,13 +412,13 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
412 .reg = &mwifiex_reg_sd87xx, 412 .reg = &mwifiex_reg_sd87xx,
413 .max_ports = 16, 413 .max_ports = 16,
414 .mp_agg_pkt_limit = 8, 414 .mp_agg_pkt_limit = 8,
415 .supports_sdio_new_mode = false,
416 .has_control_mask = true,
417 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 415 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
418 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 416 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
419 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 417 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
420 .supports_fw_dump = false, 418 .supports_sdio_new_mode = false,
421 .auto_tdls = false, 419 .has_control_mask = true,
420 .can_dump_fw = false,
421 .can_auto_tdls = false,
422 .can_ext_scan = false, 422 .can_ext_scan = false,
423}; 423};
424 424
@@ -427,13 +427,13 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
427 .reg = &mwifiex_reg_sd87xx, 427 .reg = &mwifiex_reg_sd87xx,
428 .max_ports = 16, 428 .max_ports = 16,
429 .mp_agg_pkt_limit = 8, 429 .mp_agg_pkt_limit = 8,
430 .supports_sdio_new_mode = false,
431 .has_control_mask = true,
432 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 430 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
433 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 431 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
434 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 432 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
435 .supports_fw_dump = false, 433 .supports_sdio_new_mode = false,
436 .auto_tdls = false, 434 .has_control_mask = true,
435 .can_dump_fw = false,
436 .can_auto_tdls = false,
437 .can_ext_scan = true, 437 .can_ext_scan = true,
438}; 438};
439 439
@@ -442,13 +442,13 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
442 .reg = &mwifiex_reg_sd87xx, 442 .reg = &mwifiex_reg_sd87xx,
443 .max_ports = 16, 443 .max_ports = 16,
444 .mp_agg_pkt_limit = 8, 444 .mp_agg_pkt_limit = 8,
445 .supports_sdio_new_mode = false,
446 .has_control_mask = true,
447 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 445 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
448 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 446 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
449 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 447 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
450 .supports_fw_dump = false, 448 .supports_sdio_new_mode = false,
451 .auto_tdls = false, 449 .has_control_mask = true,
450 .can_dump_fw = false,
451 .can_auto_tdls = false,
452 .can_ext_scan = true, 452 .can_ext_scan = true,
453}; 453};
454 454
@@ -457,13 +457,13 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
457 .reg = &mwifiex_reg_sd8897, 457 .reg = &mwifiex_reg_sd8897,
458 .max_ports = 32, 458 .max_ports = 32,
459 .mp_agg_pkt_limit = 16, 459 .mp_agg_pkt_limit = 16,
460 .supports_sdio_new_mode = true,
461 .has_control_mask = false,
462 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 460 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
463 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 461 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
464 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 462 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
465 .supports_fw_dump = true, 463 .supports_sdio_new_mode = true,
466 .auto_tdls = false, 464 .has_control_mask = false,
465 .can_dump_fw = true,
466 .can_auto_tdls = false,
467 .can_ext_scan = true, 467 .can_ext_scan = true,
468}; 468};
469 469
@@ -472,13 +472,13 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
472 .reg = &mwifiex_reg_sd8887, 472 .reg = &mwifiex_reg_sd8887,
473 .max_ports = 32, 473 .max_ports = 32,
474 .mp_agg_pkt_limit = 16, 474 .mp_agg_pkt_limit = 16,
475 .supports_sdio_new_mode = true, 475 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
476 .has_control_mask = false,
477 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
478 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 476 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
479 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 477 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
480 .supports_fw_dump = false, 478 .supports_sdio_new_mode = true,
481 .auto_tdls = true, 479 .has_control_mask = false,
480 .can_dump_fw = false,
481 .can_auto_tdls = true,
482 .can_ext_scan = true, 482 .can_ext_scan = true,
483}; 483};
484 484
@@ -492,8 +492,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
492 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 492 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
493 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 493 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
494 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 494 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
495 .supports_fw_dump = false, 495 .can_dump_fw = false,
496 .auto_tdls = false, 496 .can_auto_tdls = false,
497 .can_ext_scan = true, 497 .can_ext_scan = true,
498}; 498};
499 499
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index ac93557cbdc9..ea4549f0e0b9 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -80,11 +80,13 @@ EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
80int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, 80int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
81 struct mwifiex_tx_param *tx_param) 81 struct mwifiex_tx_param *tx_param)
82{ 82{
83 int ret = -1; 83 int hroom, ret = -1;
84 struct mwifiex_adapter *adapter = priv->adapter; 84 struct mwifiex_adapter *adapter = priv->adapter;
85 u8 *head_ptr; 85 u8 *head_ptr;
86 struct txpd *local_tx_pd = NULL; 86 struct txpd *local_tx_pd = NULL;
87 87
88 hroom = (adapter->iface_type == MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
89
88 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) 90 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
89 head_ptr = mwifiex_process_uap_txpd(priv, skb); 91 head_ptr = mwifiex_process_uap_txpd(priv, skb);
90 else 92 else
@@ -92,11 +94,9 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
92 94
93 if (head_ptr) { 95 if (head_ptr) {
94 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) 96 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
95 local_tx_pd = 97 local_tx_pd = (struct txpd *)(head_ptr + hroom);
96 (struct txpd *) (head_ptr + INTF_HEADER_LEN);
97 if (adapter->iface_type == MWIFIEX_USB) { 98 if (adapter->iface_type == MWIFIEX_USB) {
98 adapter->data_sent = true; 99 adapter->data_sent = true;
99 skb_pull(skb, INTF_HEADER_LEN);
100 ret = adapter->if_ops.host_to_card(adapter, 100 ret = adapter->if_ops.host_to_card(adapter,
101 MWIFIEX_USB_EP_DATA, 101 MWIFIEX_USB_EP_DATA,
102 skb, NULL); 102 skb, NULL);
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 308550611f22..2148a573396b 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -367,6 +367,13 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
367 if (!skb) 367 if (!skb)
368 return -1; 368 return -1;
369 369
370 if (!priv->mgmt_frame_mask ||
371 priv->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) {
372 dev_dbg(priv->adapter->dev,
373 "do not receive mgmt frames on uninitialized intf");
374 return -1;
375 }
376
370 rx_pd = (struct rxpd *)skb->data; 377 rx_pd = (struct rxpd *)skb->data;
371 378
372 skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset)); 379 skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset));
@@ -624,3 +631,26 @@ void mwifiex_hist_data_reset(struct mwifiex_private *priv)
624 for (ix = 0; ix < MWIFIEX_MAX_SIG_STRENGTH; ix++) 631 for (ix = 0; ix < MWIFIEX_MAX_SIG_STRENGTH; ix++)
625 atomic_set(&phist_data->sig_str[ix], 0); 632 atomic_set(&phist_data->sig_str[ix], 0);
626} 633}
634
635void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags)
636{
637 struct sk_buff *skb;
638 int buf_len, pad;
639
640 buf_len = rx_len + MWIFIEX_RX_HEADROOM + MWIFIEX_DMA_ALIGN_SZ;
641
642 skb = __dev_alloc_skb(buf_len, flags);
643
644 if (!skb)
645 return NULL;
646
647 skb_reserve(skb, MWIFIEX_RX_HEADROOM);
648
649 pad = MWIFIEX_ALIGN_ADDR(skb->data, MWIFIEX_DMA_ALIGN_SZ) -
650 (long)skb->data;
651
652 skb_reserve(skb, pad);
653
654 return skb;
655}
656EXPORT_SYMBOL_GPL(mwifiex_alloc_rx_buf);
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index c6cb49c3ee32..dee4ac2f27e2 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -45,9 +45,6 @@ enum ap_peer {
45#define RTL_TX_DESC_SIZE 32 45#define RTL_TX_DESC_SIZE 32
46#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE) 46#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE)
47 47
48#define HT_AMSDU_SIZE_4K 3839
49#define HT_AMSDU_SIZE_8K 7935
50
51#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */ 48#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
52#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */ 49#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
53 50
@@ -61,9 +58,6 @@ enum ap_peer {
61#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS9 390 /* Mbps */ 58#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS9 390 /* Mbps */
62#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS7 293 /* Mbps */ 59#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS7 293 /* Mbps */
63 60
64#define RTL_RATE_COUNT_LEGACY 12
65#define RTL_CHANNEL_COUNT 14
66
67#define FRAME_OFFSET_FRAME_CONTROL 0 61#define FRAME_OFFSET_FRAME_CONTROL 0
68#define FRAME_OFFSET_DURATION 2 62#define FRAME_OFFSET_DURATION 2
69#define FRAME_OFFSET_ADDRESS1 4 63#define FRAME_OFFSET_ADDRESS1 4
diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h
index 35508087c0c5..e2e647d511c1 100644
--- a/drivers/net/wireless/rtlwifi/cam.h
+++ b/drivers/net/wireless/rtlwifi/cam.h
@@ -28,13 +28,11 @@
28 28
29#define CAM_CONTENT_COUNT 8 29#define CAM_CONTENT_COUNT 8
30 30
31#define CFG_DEFAULT_KEY BIT(5)
32#define CFG_VALID BIT(15) 31#define CFG_VALID BIT(15)
33 32
34#define PAIRWISE_KEYIDX 0 33#define PAIRWISE_KEYIDX 0
35#define CAM_PAIRWISE_KEY_POSITION 4 34#define CAM_PAIRWISE_KEY_POSITION 4
36 35
37#define CAM_CONFIG_USEDK 1
38#define CAM_CONFIG_NO_USEDK 0 36#define CAM_CONFIG_NO_USEDK 0
39 37
40void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); 38void rtl_cam_reset_all_entry(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index 7b64e34f421e..82733c6b8c46 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -33,8 +33,6 @@
33 FIF_FCSFAIL | \ 33 FIF_FCSFAIL | \
34 FIF_BCN_PRBRESP_PROMISC) 34 FIF_BCN_PRBRESP_PROMISC)
35 35
36#define RTL_SUPPORTED_CTRL_FILTER 0xFF
37
38#define DM_DIG_THRESH_HIGH 40 36#define DM_DIG_THRESH_HIGH 40
39#define DM_DIG_THRESH_LOW 35 37#define DM_DIG_THRESH_LOW 35
40#define DM_FALSEALARM_THRESH_LOW 400 38#define DM_FALSEALARM_THRESH_LOW 400
diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h
index fdab8240a5d7..be02e7894c61 100644
--- a/drivers/net/wireless/rtlwifi/efuse.h
+++ b/drivers/net/wireless/rtlwifi/efuse.h
@@ -40,12 +40,6 @@
40#define PG_STATE_WORD_3 0x10 40#define PG_STATE_WORD_3 0x10
41#define PG_STATE_DATA 0x20 41#define PG_STATE_DATA 0x20
42 42
43#define PG_SWBYTE_H 0x01
44#define PG_SWBYTE_L 0x02
45
46#define _POWERON_DELAY_
47#define _PRE_EXECUTE_READ_CMD_
48
49#define EFUSE_REPEAT_THRESHOLD_ 3 43#define EFUSE_REPEAT_THRESHOLD_ 3
50#define EFUSE_ERROE_HANDLE 1 44#define EFUSE_ERROE_HANDLE 1
51 45
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/def.h b/drivers/net/wireless/rtlwifi/rtl8188ee/def.h
index d9ea9d0c79a5..0532b9852444 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/def.h
@@ -26,53 +26,12 @@
26#ifndef __RTL92C_DEF_H__ 26#ifndef __RTL92C_DEF_H__
27#define __RTL92C_DEF_H__ 27#define __RTL92C_DEF_H__
28 28
29#define HAL_RETRY_LIMIT_INFRA 48
30#define HAL_RETRY_LIMIT_AP_ADHOC 7
31
32#define RESET_DELAY_8185 20
33
34#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
35#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
36
37#define NUM_OF_FIRMWARE_QUEUE 10
38#define NUM_OF_PAGES_IN_FW 0x100
39#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
40#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
41#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
42#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
43#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
44#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
45#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
46#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
47#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
48#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
49
50#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
51#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
52#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
53#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
54#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
55
56#define MAX_LINES_HWCONFIG_TXT 1000
57#define MAX_BYTES_LINE_HWCONFIG_TXT 256
58
59#define SW_THREE_WIRE 0
60#define HW_THREE_WIRE 2
61
62#define BT_DEMO_BOARD 0
63#define BT_QA_BOARD 1
64#define BT_FPGA 2
65
66#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 29#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
67#define HAL_PRIME_CHNL_OFFSET_LOWER 1 30#define HAL_PRIME_CHNL_OFFSET_LOWER 1
68#define HAL_PRIME_CHNL_OFFSET_UPPER 2 31#define HAL_PRIME_CHNL_OFFSET_UPPER 2
69 32
70#define MAX_H2C_QUEUE_NUM 10
71
72#define RX_MPDU_QUEUE 0 33#define RX_MPDU_QUEUE 0
73#define RX_CMD_QUEUE 1 34#define RX_CMD_QUEUE 1
74#define RX_MAX_QUEUE 2
75#define AC2QUEUEID(_AC) (_AC)
76 35
77#define C2H_RX_CMD_HDR_LEN 8 36#define C2H_RX_CMD_HDR_LEN 8
78#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ 37#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
index f2b9713c456e..edc2cbb6253c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
@@ -566,7 +566,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
566 acm_ctrl &= (~ACMHW_VIQEN); 566 acm_ctrl &= (~ACMHW_VIQEN);
567 break; 567 break;
568 case AC3_VO: 568 case AC3_VO:
569 acm_ctrl &= (~ACMHW_BEQEN); 569 acm_ctrl &= (~ACMHW_VOQEN);
570 break; 570 break;
571 default: 571 default:
572 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 572 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
index 3f6c59cdeaba..a2bb02c7b837 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
@@ -452,9 +452,10 @@ static void handle_branch1(struct ieee80211_hw *hw, u16 arraylen,
452 READ_NEXT_PAIR(v1, v2, i); 452 READ_NEXT_PAIR(v1, v2, i);
453 while (v2 != 0xDEAD && 453 while (v2 != 0xDEAD &&
454 v2 != 0xCDEF && 454 v2 != 0xCDEF &&
455 v2 != 0xCDCD && i < arraylen - 2) 455 v2 != 0xCDCD && i < arraylen - 2) {
456 _rtl8188e_config_bb_reg(hw, v1, v2); 456 _rtl8188e_config_bb_reg(hw, v1, v2);
457 READ_NEXT_PAIR(v1, v2, i); 457 READ_NEXT_PAIR(v1, v2, i);
458 }
458 459
459 while (v2 != 0xDEAD && i < arraylen - 2) 460 while (v2 != 0xDEAD && i < arraylen - 2)
460 READ_NEXT_PAIR(v1, v2, i); 461 READ_NEXT_PAIR(v1, v2, i);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h b/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h
index 5c1472d88fd4..0eca030e3238 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h
@@ -27,7 +27,6 @@
27#define __RTL92C_RF_H__ 27#define __RTL92C_RF_H__
28 28
29#define RF6052_MAX_TX_PWR 0x3F 29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31 30
32void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, 31void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth); 32 u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
index 9b660df6fd71..690a7a1675e2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
@@ -30,59 +30,18 @@
30#ifndef __RTL92C_DEF_H__ 30#ifndef __RTL92C_DEF_H__
31#define __RTL92C_DEF_H__ 31#define __RTL92C_DEF_H__
32 32
33#define HAL_RETRY_LIMIT_INFRA 48
34#define HAL_RETRY_LIMIT_AP_ADHOC 7
35
36#define PHY_RSSI_SLID_WIN_MAX 100 33#define PHY_RSSI_SLID_WIN_MAX 100
37#define PHY_LINKQUALITY_SLID_WIN_MAX 20 34#define PHY_LINKQUALITY_SLID_WIN_MAX 20
38#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 35#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
39 36
40#define RESET_DELAY_8185 20
41
42#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
43#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
44
45#define NUM_OF_FIRMWARE_QUEUE 10
46#define NUM_OF_PAGES_IN_FW 0x100
47#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
48#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
49#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
50#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
51#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
52#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
53#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
54#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
55#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
56#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
57
58#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
59#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
60#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
61#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
62#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
63
64#define MAX_LINES_HWCONFIG_TXT 1000
65#define MAX_BYTES_LINE_HWCONFIG_TXT 256
66
67#define SW_THREE_WIRE 0
68#define HW_THREE_WIRE 2
69
70#define BT_DEMO_BOARD 0
71#define BT_QA_BOARD 1
72#define BT_FPGA 2
73
74#define RX_SMOOTH_FACTOR 20 37#define RX_SMOOTH_FACTOR 20
75 38
76#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 39#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
77#define HAL_PRIME_CHNL_OFFSET_LOWER 1 40#define HAL_PRIME_CHNL_OFFSET_LOWER 1
78#define HAL_PRIME_CHNL_OFFSET_UPPER 2 41#define HAL_PRIME_CHNL_OFFSET_UPPER 2
79 42
80#define MAX_H2C_QUEUE_NUM 10
81
82#define RX_MPDU_QUEUE 0 43#define RX_MPDU_QUEUE 0
83#define RX_CMD_QUEUE 1 44#define RX_CMD_QUEUE 1
84#define RX_MAX_QUEUE 2
85#define AC2QUEUEID(_AC) (_AC)
86 45
87#define C2H_RX_CMD_HDR_LEN 8 46#define C2H_RX_CMD_HDR_LEN 8
88#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ 47#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index 303b299376c9..04eb5c3f8464 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -363,7 +363,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
363 acm_ctrl &= (~AcmHw_ViqEn); 363 acm_ctrl &= (~AcmHw_ViqEn);
364 break; 364 break;
365 case AC3_VO: 365 case AC3_VO:
366 acm_ctrl &= (~AcmHw_BeqEn); 366 acm_ctrl &= (~AcmHw_VoqEn);
367 break; 367 break;
368 default: 368 default:
369 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 369 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
index d8fe68b389d2..ebd72cae10b6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
@@ -31,7 +31,6 @@
31#define __RTL92C_RF_H__ 31#define __RTL92C_RF_H__
32 32
33#define RF6052_MAX_TX_PWR 0x3F 33#define RF6052_MAX_TX_PWR 0x3F
34#define RF6052_MAX_REG 0x3F
35#define RF6052_MAX_PATH 2 34#define RF6052_MAX_PATH 2
36 35
37void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); 36void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index fe4b699a12f5..0c20dd74d6ec 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1589,6 +1589,8 @@ void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
1589 case HW_VAR_DATA_FILTER: 1589 case HW_VAR_DATA_FILTER:
1590 *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); 1590 *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2);
1591 break; 1591 break;
1592 case HAL_DEF_WOWLAN:
1593 break;
1592 default: 1594 default:
1593 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1595 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1594 "switch case not processed\n"); 1596 "switch case not processed\n");
@@ -1871,7 +1873,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
1871 acm_ctrl &= (~AcmHw_ViqEn); 1873 acm_ctrl &= (~AcmHw_ViqEn);
1872 break; 1874 break;
1873 case AC3_VO: 1875 case AC3_VO:
1874 acm_ctrl &= (~AcmHw_BeqEn); 1876 acm_ctrl &= (~AcmHw_VoqEn);
1875 break; 1877 break;
1876 default: 1878 default:
1877 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1879 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
index c1e33b0228c0..67588083e6cc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
@@ -32,8 +32,6 @@
32 32
33#define H2C_RA_MASK 6 33#define H2C_RA_MASK 6
34 34
35#define LLT_POLLING_LLT_THRESHOLD 20
36#define LLT_POLLING_READY_TIMEOUT_COUNT 100
37#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 35#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
38 36
39#define RX_PAGE_SIZE_REG_VALUE PBP_128 37#define RX_PAGE_SIZE_REG_VALUE PBP_128
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
index 11b439d6b671..6f987de5b441 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
@@ -31,7 +31,6 @@
31#define __RTL92CU_RF_H__ 31#define __RTL92CU_RF_H__
32 32
33#define RF6052_MAX_TX_PWR 0x3F 33#define RF6052_MAX_TX_PWR 0x3F
34#define RF6052_MAX_REG 0x3F
35#define RF6052_MAX_PATH 2 34#define RF6052_MAX_PATH 2
36 35
37void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); 36void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
index 939c905f547f..0a443ed17cf4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
@@ -35,61 +35,22 @@
35#define MAX_MSS_DENSITY_1T 0x0A 35#define MAX_MSS_DENSITY_1T 0x0A
36 36
37#define RF6052_MAX_TX_PWR 0x3F 37#define RF6052_MAX_TX_PWR 0x3F
38#define RF6052_MAX_REG 0x3F
39#define RF6052_MAX_PATH 2 38#define RF6052_MAX_PATH 2
40 39
41#define HAL_RETRY_LIMIT_INFRA 48
42#define HAL_RETRY_LIMIT_AP_ADHOC 7
43
44#define PHY_RSSI_SLID_WIN_MAX 100 40#define PHY_RSSI_SLID_WIN_MAX 100
45#define PHY_LINKQUALITY_SLID_WIN_MAX 20 41#define PHY_LINKQUALITY_SLID_WIN_MAX 20
46#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 42#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
47 43
48#define RESET_DELAY_8185 20
49
50#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
51#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) 44#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
52 45
53#define NUM_OF_FIRMWARE_QUEUE 10
54#define NUM_OF_PAGES_IN_FW 0x100
55#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
56#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
57#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
58#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
59#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
60#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
61#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
62#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
63#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
64#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
65
66#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
67#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
68#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
69#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
70#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
71
72#define MAX_LINES_HWCONFIG_TXT 1000
73#define MAX_BYTES_LINE_HWCONFIG_TXT 256
74
75#define SW_THREE_WIRE 0
76#define HW_THREE_WIRE 2
77
78#define BT_DEMO_BOARD 0
79#define BT_QA_BOARD 1
80#define BT_FPGA 2
81
82#define RX_SMOOTH_FACTOR 20 46#define RX_SMOOTH_FACTOR 20
83 47
84#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 48#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
85#define HAL_PRIME_CHNL_OFFSET_LOWER 1 49#define HAL_PRIME_CHNL_OFFSET_LOWER 1
86#define HAL_PRIME_CHNL_OFFSET_UPPER 2 50#define HAL_PRIME_CHNL_OFFSET_UPPER 2
87 51
88#define MAX_H2C_QUEUE_NUM 10
89
90#define RX_MPDU_QUEUE 0 52#define RX_MPDU_QUEUE 0
91#define RX_CMD_QUEUE 1 53#define RX_CMD_QUEUE 1
92#define RX_MAX_QUEUE 2
93 54
94#define C2H_RX_CMD_HDR_LEN 8 55#define C2H_RX_CMD_HDR_LEN 8
95#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ 56#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
index b461b3128da5..db230a3f0137 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
@@ -562,7 +562,7 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
562 acm_ctrl &= (~ACMHW_VIQEN); 562 acm_ctrl &= (~ACMHW_VIQEN);
563 break; 563 break;
564 case AC3_VO: 564 case AC3_VO:
565 acm_ctrl &= (~ACMHW_BEQEN); 565 acm_ctrl &= (~ACMHW_VOQEN);
566 break; 566 break;
567 default: 567 default:
568 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, 568 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ee/rf.h
index 8bdeed3c064e..039c0133ad6b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/rf.h
@@ -27,7 +27,6 @@
27#define __RTL92E_RF_H__ 27#define __RTL92E_RF_H__
28 28
29#define RF6052_MAX_TX_PWR 0x3F 29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31 30
32void rtl92ee_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, 31void rtl92ee_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth); 32 u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
index ef87c09b77d0..41466f957cdc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -31,7 +31,6 @@
31 31
32#define RX_MPDU_QUEUE 0 32#define RX_MPDU_QUEUE 0
33#define RX_CMD_QUEUE 1 33#define RX_CMD_QUEUE 1
34#define RX_MAX_QUEUE 2
35 34
36#define SHORT_SLOT_TIME 9 35#define SHORT_SLOT_TIME 9
37#define NON_SHORT_SLOT_TIME 20 36#define NON_SHORT_SLOT_TIME 20
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index 5761d5b49e39..dee88a80bee1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -293,7 +293,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
293 acm_ctrl &= (~AcmHw_ViqEn); 293 acm_ctrl &= (~AcmHw_ViqEn);
294 break; 294 break;
295 case AC3_VO: 295 case AC3_VO:
296 acm_ctrl &= (~AcmHw_BeqEn); 296 acm_ctrl &= (~AcmHw_VoqEn);
297 break; 297 break;
298 default: 298 default:
299 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 299 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
index 94bdd4bbca5d..bcdf2273688e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
@@ -26,53 +26,12 @@
26#ifndef __RTL8723E_DEF_H__ 26#ifndef __RTL8723E_DEF_H__
27#define __RTL8723E_DEF_H__ 27#define __RTL8723E_DEF_H__
28 28
29#define HAL_RETRY_LIMIT_INFRA 48
30#define HAL_RETRY_LIMIT_AP_ADHOC 7
31
32#define RESET_DELAY_8185 20
33
34#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
35#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
36
37#define NUM_OF_FIRMWARE_QUEUE 10
38#define NUM_OF_PAGES_IN_FW 0x100
39#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
40#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
41#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
42#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
43#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
44#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
45#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
46#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
47#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
48#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
49
50#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
51#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
52#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
53#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
54#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
55
56#define MAX_LINES_HWCONFIG_TXT 1000
57#define MAX_BYTES_LINE_HWCONFIG_TXT 256
58
59#define SW_THREE_WIRE 0
60#define HW_THREE_WIRE 2
61
62#define BT_DEMO_BOARD 0
63#define BT_QA_BOARD 1
64#define BT_FPGA 2
65
66#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 29#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
67#define HAL_PRIME_CHNL_OFFSET_LOWER 1 30#define HAL_PRIME_CHNL_OFFSET_LOWER 1
68#define HAL_PRIME_CHNL_OFFSET_UPPER 2 31#define HAL_PRIME_CHNL_OFFSET_UPPER 2
69 32
70#define MAX_H2C_QUEUE_NUM 10
71
72#define RX_MPDU_QUEUE 0 33#define RX_MPDU_QUEUE 0
73#define RX_CMD_QUEUE 1 34#define RX_CMD_QUEUE 1
74#define RX_MAX_QUEUE 2
75#define AC2QUEUEID(_AC) (_AC)
76 35
77#define C2H_RX_CMD_HDR_LEN 8 36#define C2H_RX_CMD_HDR_LEN 8
78#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ 37#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
index aa085462d0e9..b3b094759f6d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -362,7 +362,7 @@ void rtl8723e_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
362 acm_ctrl &= (~ACMHW_VIQEN); 362 acm_ctrl &= (~ACMHW_VIQEN);
363 break; 363 break;
364 case AC3_VO: 364 case AC3_VO:
365 acm_ctrl &= (~ACMHW_BEQEN); 365 acm_ctrl &= (~ACMHW_VOQEN);
366 break; 366 break;
367 default: 367 default:
368 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 368 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
index f3f45b16361f..7b44ebc0fac9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
@@ -27,7 +27,6 @@
27#define __RTL8723E_RF_H__ 27#define __RTL8723E_RF_H__
28 28
29#define RF6052_MAX_TX_PWR 0x3F 29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31 30
32void rtl8723e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, 31void rtl8723e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth); 32 u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
index 6dad28e77bbb..b46998341c40 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
@@ -603,7 +603,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
603 acm_ctrl &= (~ACMHW_VIQEN); 603 acm_ctrl &= (~ACMHW_VIQEN);
604 break; 604 break;
605 case AC3_VO: 605 case AC3_VO:
606 acm_ctrl &= (~ACMHW_BEQEN); 606 acm_ctrl &= (~ACMHW_VOQEN);
607 break; 607 break;
608 default: 608 default:
609 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 609 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/rf.h b/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
index a6fea106ced4..f423e157020f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
@@ -27,7 +27,6 @@
27#define __RTL8723BE_RF_H__ 27#define __RTL8723BE_RF_H__
28 28
29#define RF6052_MAX_TX_PWR 0x3F 29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31 30
32void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, 31void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth); 32 u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/def.h b/drivers/net/wireless/rtlwifi/rtl8821ae/def.h
index ee7c208bd070..dfbdf539de1a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/def.h
@@ -118,55 +118,14 @@
118#define WIFI_NAV_UPPER_US 30000 118#define WIFI_NAV_UPPER_US 30000
119#define HAL_92C_NAV_UPPER_UNIT 128 119#define HAL_92C_NAV_UPPER_UNIT 128
120 120
121#define HAL_RETRY_LIMIT_INFRA 48
122#define HAL_RETRY_LIMIT_AP_ADHOC 7
123
124#define RESET_DELAY_8185 20
125
126#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
127#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
128
129#define NUM_OF_FIRMWARE_QUEUE 10
130#define NUM_OF_PAGES_IN_FW 0x100
131#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
132#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
133#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
134#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
135#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
136#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
137#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
138#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
139#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
140#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
141
142#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
143#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
144#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
145#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
146#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
147
148#define MAX_RX_DMA_BUFFER_SIZE 0x3E80 121#define MAX_RX_DMA_BUFFER_SIZE 0x3E80
149 122
150#define MAX_LINES_HWCONFIG_TXT 1000
151#define MAX_BYTES_LINE_HWCONFIG_TXT 256
152
153#define SW_THREE_WIRE 0
154#define HW_THREE_WIRE 2
155
156#define BT_DEMO_BOARD 0
157#define BT_QA_BOARD 1
158#define BT_FPGA 2
159
160#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 123#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
161#define HAL_PRIME_CHNL_OFFSET_LOWER 1 124#define HAL_PRIME_CHNL_OFFSET_LOWER 1
162#define HAL_PRIME_CHNL_OFFSET_UPPER 2 125#define HAL_PRIME_CHNL_OFFSET_UPPER 2
163 126
164#define MAX_H2C_QUEUE_NUM 10
165
166#define RX_MPDU_QUEUE 0 127#define RX_MPDU_QUEUE 0
167#define RX_CMD_QUEUE 1 128#define RX_CMD_QUEUE 1
168#define RX_MAX_QUEUE 2
169#define AC2QUEUEID(_AC) (_AC)
170 129
171#define MAX_RX_DMA_BUFFER_SIZE_8812 0x3E80 130#define MAX_RX_DMA_BUFFER_SIZE_8812 0x3E80
172 131
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
index 8ec8200002c7..2a0a71bac00c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
@@ -667,7 +667,7 @@ void rtl8821ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
667 acm_ctrl &= (~ACMHW_VIQEN); 667 acm_ctrl &= (~ACMHW_VIQEN);
668 break; 668 break;
669 case AC3_VO: 669 case AC3_VO:
670 acm_ctrl &= (~ACMHW_BEQEN); 670 acm_ctrl &= (~ACMHW_VOQEN);
671 break; 671 break;
672 default: 672 default:
673 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 673 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
@@ -1515,7 +1515,7 @@ static bool _rtl8821ae_dynamic_rqpn(struct ieee80211_hw *hw, u32 boundary,
1515 (u8 *)(&support_remote_wakeup)); 1515 (u8 *)(&support_remote_wakeup));
1516 1516
1517 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 1517 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1518 "boundary=0x%#X, NPQ_RQPNValue=0x%#X, RQPNValue=0x%#X\n", 1518 "boundary=%#X, NPQ_RQPNValue=%#X, RQPNValue=%#X\n",
1519 boundary, npq_rqpn_value, rqpn_val); 1519 boundary, npq_rqpn_value, rqpn_val);
1520 1520
1521 /* stop PCIe DMA 1521 /* stop PCIe DMA
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/rf.h b/drivers/net/wireless/rtlwifi/rtl8821ae/rf.h
index d9582ee1c335..efd22bd0b139 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/rf.h
@@ -27,7 +27,6 @@
27#define __RTL8821AE_RF_H__ 27#define __RTL8821AE_RF_H__
28 28
29#define RF6052_MAX_TX_PWR 0x3F 29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31 30
32void rtl8821ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, 31void rtl8821ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth); 32 u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 46ee956d0235..f0188c83c79f 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -701,12 +701,18 @@ free:
701 701
702static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw) 702static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw)
703{ 703{
704 struct rtl_priv *rtlpriv = rtl_priv(hw);
704 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 705 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
705 struct urb *urb; 706 struct urb *urb;
706 707
707 usb_kill_anchored_urbs(&rtlusb->rx_submitted); 708 usb_kill_anchored_urbs(&rtlusb->rx_submitted);
708 709
709 tasklet_kill(&rtlusb->rx_work_tasklet); 710 tasklet_kill(&rtlusb->rx_work_tasklet);
711 cancel_work_sync(&rtlpriv->works.lps_change_work);
712
713 flush_workqueue(rtlpriv->works.rtl_wq);
714 destroy_workqueue(rtlpriv->works.rtl_wq);
715
710 skb_queue_purge(&rtlusb->rx_queue); 716 skb_queue_purge(&rtlusb->rx_queue);
711 717
712 while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) { 718 while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) {
@@ -794,8 +800,6 @@ static void rtl_usb_cleanup(struct ieee80211_hw *hw)
794 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 800 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
795 struct ieee80211_tx_info *txinfo; 801 struct ieee80211_tx_info *txinfo;
796 802
797 SET_USB_STOP(rtlusb);
798
799 /* clean up rx stuff. */ 803 /* clean up rx stuff. */
800 _rtl_usb_cleanup_rx(hw); 804 _rtl_usb_cleanup_rx(hw);
801 805
@@ -834,7 +838,6 @@ static void rtl_usb_stop(struct ieee80211_hw *hw)
834 cancel_work_sync(&rtlpriv->works.fill_h2c_cmd); 838 cancel_work_sync(&rtlpriv->works.fill_h2c_cmd);
835 /* Enable software */ 839 /* Enable software */
836 SET_USB_STOP(rtlusb); 840 SET_USB_STOP(rtlusb);
837 rtl_usb_deinit(hw);
838 rtlpriv->cfg->ops->hw_disable(hw); 841 rtlpriv->cfg->ops->hw_disable(hw);
839} 842}
840 843
@@ -1147,9 +1150,9 @@ void rtl_usb_disconnect(struct usb_interface *intf)
1147 1150
1148 if (unlikely(!rtlpriv)) 1151 if (unlikely(!rtlpriv))
1149 return; 1152 return;
1150
1151 /* just in case driver is removed before firmware callback */ 1153 /* just in case driver is removed before firmware callback */
1152 wait_for_completion(&rtlpriv->firmware_loading_complete); 1154 wait_for_completion(&rtlpriv->firmware_loading_complete);
1155 clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
1153 /*ieee80211_unregister_hw will call ops_stop */ 1156 /*ieee80211_unregister_hw will call ops_stop */
1154 if (rtlmac->mac80211_registered == 1) { 1157 if (rtlmac->mac80211_registered == 1) {
1155 ieee80211_unregister_hw(hw); 1158 ieee80211_unregister_hw(hw);