diff options
Diffstat (limited to 'drivers/net/wireless')
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 | ||
44 | struct ce_desc { | 44 | struct 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 | ||
437 | static void ath10k_core_free_firmware_files(struct ath10k *ar) | 437 | static 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 | ||
162 | struct 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 | |||
162 | struct ath10k_fw_stats_pdev { | 181 | struct 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 | ||
221 | struct ath10k_fw_stats { | 240 | struct 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 | ||
246 | static 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 | |||
246 | static void ath10k_debug_fw_stats_peers_free(struct list_head *head) | 256 | static 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 | ||
287 | static 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 | |||
276 | void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) | 298 | void 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 | ||
345 | unlock: | 377 | unlock: |
@@ -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 | ||
1257 | static 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 | |||
1256 | static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) | 1271 | static 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 | ||
1810 | static 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 */ |
1785 | static void ath10k_bss_assoc(struct ieee80211_hw *hw, | 1873 | static 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 | ||
1858 | static void ath10k_bss_disassoc(struct ieee80211_hw *hw, | 1967 | static 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 | ||
818 | static inline int | 817 | static inline int |
819 | ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) | 818 | ath10k_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 | ||
872 | static 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 | |||
872 | static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, | 908 | static 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 | ||
2082 | static struct sk_buff * | 2183 | static struct sk_buff * |
2083 | ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, | 2184 | ath10k_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 | ||
1305 | struct wmi_tlv_vdev_wmm_params { | ||
1306 | __le32 dummy; | ||
1307 | struct wmi_wmm_params params; | ||
1308 | } __packed; | ||
1309 | |||
1305 | struct wmi_tlv_vdev_set_wmm_cmd { | 1310 | struct 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 | ||
1309 | struct wmi_tlv_phyerr_ev { | 1315 | struct 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 | ||
1448 | struct 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 | |||
1442 | void ath10k_wmi_tlv_attach(struct ath10k *ar); | 1457 | void 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 | ||
1128 | static 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 | |||
1128 | static void ath10k_wmi_event_scan_completed(struct ath10k *ar) | 1147 | static 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 | ||
4956 | static struct sk_buff * | 4976 | static struct sk_buff * |
4957 | ath10k_wmi_op_gen_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) | 4977 | ath10k_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 | ||
3059 | enum wmi_stats_id { | 3059 | enum 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 | ||
3064 | struct wlan_inst_rssi_args { | 3068 | struct wlan_inst_rssi_args { |
@@ -3093,7 +3097,7 @@ struct wmi_pdev_suspend_cmd { | |||
3093 | } __packed; | 3097 | } __packed; |
3094 | 3098 | ||
3095 | struct wmi_stats_event { | 3099 | struct 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 | ||
4442 | struct wmi_peer_set_param_cmd { | 4452 | struct 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 | ||
772 | static void ar9003_mci_mute_bt(struct ath_hw *ah) | 772 | static 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 | ||
831 | static 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 | |||
850 | static 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 | |||
869 | static 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 | |||
888 | static 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 | |||
824 | int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | 905 | int 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 | ||
1367 | u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more) | 1445 | u32 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 | |||
103 | enum mci_message_header { /* length of payload */ | 125 | enum 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 | ||
213 | enum 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 */ |
192 | enum mci_state_type { | 221 | enum 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, | |||
255 | void ar9003_mci_cleanup(struct ath_hw *ah); | 312 | void ar9003_mci_cleanup(struct ath_hw *ah); |
256 | void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, | 313 | void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, |
257 | u32 *rx_msg_intr); | 314 | u32 *rx_msg_intr); |
258 | u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more); | 315 | u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, u32 *more); |
259 | void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor); | 316 | void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor); |
260 | void ar9003_mci_send_wlan_channels(struct ath_hw *ah); | 317 | void 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 | ||
23 | static 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; | ||
33 | set: | ||
34 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | ||
35 | } | ||
36 | |||
23 | static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) | 37 | static 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 | ||
105 | int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, | 121 | int 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); |
646 | void ath9k_calculate_summary_state(struct ath_softc *sc, | 646 | void ath9k_calculate_summary_state(struct ath_softc *sc, |
647 | struct ath_chanctx *ctx); | 647 | struct ath_chanctx *ctx); |
648 | void 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 | ||
312 | static 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 | |||
310 | void ath9k_hw_btcoex_enable(struct ath_hw *ah) | 324 | void 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 | ||
63 | struct ath9k_hw_mci { | 64 | struct 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 | ||
274 | static int ath_init_btcoex_timer(struct ath_softc *sc) | 270 | static 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 | */ |
319 | void ath9k_btcoex_timer_pause(struct ath_softc *sc) | 317 | void 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 | ||
374 | void ath9k_stop_btcoex(struct ath_softc *sc) | 378 | void 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 | ||
388 | void ath9k_deinit_btcoex(struct ath_softc *sc) | 393 | void 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 | ||
1175 | static 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. */ | ||
1184 | void 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 | |||
1175 | static void ath9k_assign_hw_queues(struct ieee80211_hw *hw, | 1207 | static 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 | 1178 | out: | |
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 | ||
1171 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, | 1185 | static 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 @@ | |||
29 | static u32 mem_addr; | 29 | static u32 mem_addr; |
30 | static u32 dbg_txdesc_index; | 30 | static u32 dbg_txdesc_index; |
31 | static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */ | 31 | static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */ |
32 | u32 vring_idle_trsh = 16; /* HW fetches up to 16 descriptors at once */ | ||
32 | 33 | ||
33 | enum dbg_off_type { | 34 | enum 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 */ |
1394 | static const struct dbg_off dbg_wil_off[] = { | 1402 | static 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 | ||
22 | MODULE_FIRMWARE(WIL_FW_NAME); | 22 | MODULE_FIRMWARE(WIL_FW_NAME); |
23 | MODULE_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 | ||
169 | static | 169 | void wil_configure_interrupt_moderation(struct wil6210_priv *wil) |
170 | void 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 | ||
209 | static | ||
210 | void 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 | ||
224 | void 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 | |||
245 | static irqreturn_t wil6210_irq_rx(int irq, void *cookie) | 218 | static 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; | |||
29 | module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); | 29 | module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); |
30 | MODULE_PARM_DESC(no_fw_recovery, " disable automatic FW error recovery"); | 30 | MODULE_PARM_DESC(no_fw_recovery, " disable automatic FW error recovery"); |
31 | 31 | ||
32 | static bool no_fw_load = true; | ||
33 | module_param(no_fw_load, bool, S_IRUGO | S_IWUSR); | ||
34 | MODULE_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 | |||
611 | void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) | 590 | void 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 | ||
599 | static 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 | |||
620 | static int wil_wait_for_fw_ready(struct wil6210_priv *wil) | 625 | static 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 | */ |
640 | int wil_reset(struct wil6210_priv *wil) | 645 | int 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 | |||
718 | void wil_fw_error_recovery(struct wil6210_priv *wil) | 736 | void 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 | ||
74 | void wil_disable_irq(struct wil6210_priv *wil) | 55 | void 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 | ||
307 | static const struct pci_device_id wil6210_pcie_ids[] = { | 288 | static 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 | 57 | static inline int wil_vring_used_tx(struct vring *vring) |
58 | */ | ||
59 | static 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 */ |
65 | static 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 | */ | ||
71 | static inline int wil_vring_wmark_low(struct vring *vring) | 71 | static 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 | */ | ||
79 | static inline int wil_vring_wmark_high(struct vring *vring) | 77 | static 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) */ | ||
83 | static inline bool wil_val_in_range(int val, int min, int max) | ||
84 | { | ||
85 | return val >= min && val < max; | ||
86 | } | ||
87 | |||
84 | static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) | 88 | static 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 | */ | ||
352 | static void wil_swap_u16(u16 *a, u16 *b) | ||
353 | { | ||
354 | *a ^= *b; | ||
355 | *b ^= *a; | ||
356 | *a ^= *b; | ||
357 | } | ||
358 | |||
359 | static 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; | |||
27 | extern unsigned int mtu_max; | 27 | extern unsigned int mtu_max; |
28 | extern unsigned short rx_ring_overflow_thrsh; | 28 | extern unsigned short rx_ring_overflow_thrsh; |
29 | extern int agg_wsize; | 29 | extern int agg_wsize; |
30 | extern 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 | ||
125 | struct 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 | ||
237 | enum { | 254 | enum { |
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 | ||
484 | enum { | 498 | enum { |
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); | |||
658 | void wil_if_remove(struct wil6210_priv *wil); | 670 | void wil_if_remove(struct wil6210_priv *wil); |
659 | int wil_priv_init(struct wil6210_priv *wil); | 671 | int wil_priv_init(struct wil6210_priv *wil); |
660 | void wil_priv_deinit(struct wil6210_priv *wil); | 672 | void wil_priv_deinit(struct wil6210_priv *wil); |
661 | int wil_reset(struct wil6210_priv *wil); | 673 | int wil_reset(struct wil6210_priv *wil, bool no_fw); |
662 | void wil_fw_error_recovery(struct wil6210_priv *wil); | 674 | void wil_fw_error_recovery(struct wil6210_priv *wil); |
663 | void wil_set_recovery_state(struct wil6210_priv *wil, int state); | 675 | void wil_set_recovery_state(struct wil6210_priv *wil, int state); |
664 | int wil_up(struct wil6210_priv *wil); | 676 | int 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 ===*/ |
282 | static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) | 282 | static 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 | ||
61 | struct 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 | |||
61 | static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE; | 69 | static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE; |
62 | module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0); | 70 | module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0); |
63 | MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]"); | 71 | MODULE_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 | ||
208 | void 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 | |||
200 | static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, | 232 | static 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 | ||
272 | static 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 | |||
278 | static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | 304 | static 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 | ||
907 | static 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 | |||
919 | static 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 | |||
927 | static 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 | |||
944 | static 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 | |||
953 | bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev) | ||
954 | { | ||
955 | return atomic_read(&sdiodev->freezer->freezing); | ||
956 | } | ||
957 | |||
958 | void 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 | |||
967 | void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev) | ||
968 | { | ||
969 | atomic_inc(&sdiodev->freezer->thread_count); | ||
970 | } | ||
971 | |||
972 | void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev) | ||
973 | { | ||
974 | atomic_dec(&sdiodev->freezer->thread_count); | ||
975 | } | ||
976 | #else | ||
977 | static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev) | ||
978 | { | ||
979 | return 0; | ||
980 | } | ||
981 | |||
982 | static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev) | ||
983 | { | ||
984 | } | ||
985 | #endif /* CONFIG_PM_SLEEP */ | ||
986 | |||
880 | static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) | 987 | static 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 |
1115 | static int brcmf_ops_sdio_suspend(struct device *dev) | 1226 | static 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 | ||
1117 | scan_out: | 1117 | scan_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 | ||
947 | static 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 | |||
947 | int brcmf_bus_start(struct device *dev) | 975 | int 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")); |
1073 | done: | 1073 | done: |
@@ -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 | ||
2606 | static 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 | |||
2621 | static void brcmf_sdio_dpc(struct brcmf_sdio *bus) | 2606 | static 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 | ||
3417 | err: | 3392 | err: |
@@ -3548,6 +3523,14 @@ done: | |||
3548 | return err; | 3523 | return err; |
3549 | } | 3524 | } |
3550 | 3525 | ||
3526 | void 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 | |||
3551 | void brcmf_sdio_isr(struct brcmf_sdio *bus) | 3534 | void 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 | ||
3672 | static void | 3659 | static void |
@@ -3944,13 +3931,19 @@ static int | |||
3944 | brcmf_sdio_watchdog_thread(void *data) | 3931 | brcmf_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 | |||
4306 | int 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 | /** |
159 | enum 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 | */ | ||
165 | enum brcmf_sdiod_state { | ||
166 | BRCMF_SDIOD_DOWN, | ||
167 | BRCMF_SDIOD_DATA, | ||
168 | BRCMF_SDIOD_NOMEDIUM | ||
163 | }; | 169 | }; |
164 | 170 | ||
165 | struct brcmf_sdreg { | 171 | struct brcmf_sdreg { |
@@ -169,15 +175,13 @@ struct brcmf_sdreg { | |||
169 | }; | 175 | }; |
170 | 176 | ||
171 | struct brcmf_sdio; | 177 | struct brcmf_sdio; |
178 | struct brcmf_sdiod_freezer; | ||
172 | 179 | ||
173 | struct brcmf_sdio_dev { | 180 | struct 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 */ |
339 | int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); | 344 | int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); |
345 | void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, | ||
346 | enum brcmf_sdiod_state state); | ||
347 | #ifdef CONFIG_PM_SLEEP | ||
348 | bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev); | ||
349 | void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev); | ||
350 | void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev); | ||
351 | void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev); | ||
352 | #else | ||
353 | static inline bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev) | ||
354 | { | ||
355 | return false; | ||
356 | } | ||
357 | static inline void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev) | ||
358 | { | ||
359 | } | ||
360 | static inline void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev) | ||
361 | { | ||
362 | } | ||
363 | static inline void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev) | ||
364 | { | ||
365 | } | ||
366 | #endif /* CONFIG_PM_SLEEP */ | ||
340 | 367 | ||
341 | struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); | 368 | struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); |
342 | void brcmf_sdio_remove(struct brcmf_sdio *bus); | 369 | void brcmf_sdio_remove(struct brcmf_sdio *bus); |
@@ -344,5 +371,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus); | |||
344 | 371 | ||
345 | void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); | 372 | void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); |
346 | void brcmf_sdio_wowl_config(struct device *dev, bool enabled); | 373 | void brcmf_sdio_wowl_config(struct device *dev, bool enabled); |
374 | int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep); | ||
375 | void 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 | ||
490 | TRACE_EVENT(iwlwifi_dev_ucode_event, | 492 | TRACE_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 | */ |
86 | enum iwl_fw_error_dump_type { | 88 | enum 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 | */ | ||
254 | enum 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 | */ | ||
274 | struct 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 */ |
71 | struct iwl_ucode_header { | 72 | struct 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 | ||
140 | struct iwl_ucode_tlv { | 143 | struct 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 | */ |
254 | enum iwl_ucode_tlv_api { | 259 | enum 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 | */ |
288 | enum iwl_ucode_tlv_capa { | 296 | enum 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 | */ |
460 | struct iwl_fw_dbg_trigger { | 468 | enum 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 | */ | ||
483 | enum 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 | */ | ||
508 | struct 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 | */ | ||
534 | struct 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 | */ |
473 | enum iwl_fw_dbg_conf { | 547 | struct 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 | */ | ||
561 | struct 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 | */ |
572 | struct 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 | */ |
492 | struct iwl_fw_dbg_conf_tlv { | 587 | struct 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 | */ |
162 | struct iwl_fw { | 165 | struct 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 | ||
209 | static inline const struct iwl_fw_dbg_trigger * | 213 | static inline bool |
210 | iwl_fw_dbg_conf_get_trigger(const struct iwl_fw *fw, u8 id) | 214 | iwl_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 | |||
228 | static inline bool | ||
229 | iwl_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 | ||
240 | static inline bool | 224 | #define iwl_fw_dbg_trigger_enabled(fw, id) ({ \ |
241 | iwl_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) | 229 | static inline struct iwl_fw_dbg_trigger_tlv* |
246 | return false; | 230 | iwl_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 | ||
78 | struct iwl_phy_db_entry { | 78 | struct 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 | */ |
600 | struct iwl_trans { | 601 | struct 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 | ||
1170 | bool 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 | |||
1176 | bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm) | 1170 | bool 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 | ||
1182 | bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm, | 1176 | bool 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: | 1894 | out_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 | ||
1900 | out: | ||
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 | ||
548 | static 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 | |||
586 | static 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); | |||
560 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256); | 611 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256); |
561 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10); | 612 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10); |
562 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20); | 613 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20); |
614 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(rx_phyinfo, 10); | ||
563 | 615 | ||
564 | void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 616 | void 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 | ||
74 | enum iwl_ac { | 75 | enum 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 | */ | ||
112 | struct 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 | */ | ||
145 | enum 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 | */ | ||
164 | enum 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 | */ | ||
199 | struct 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 | */ | ||
264 | struct 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 | ||
69 | struct mvm_statistics_dbg { | 70 | struct 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 | ||
221 | struct mvm_statistics_general { | 222 | struct 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 | ||
248 | struct 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 | |||
247 | struct mvm_statistics_rx { | 281 | struct 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 | ||
270 | struct iwl_notif_statistics { | 296 | struct 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 | ||
303 | struct 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 | |||
313 | struct 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 | ||
434 | struct mvm_alive_resp { | 435 | struct 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 | ||
486 | struct 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 */ |
486 | enum { | 511 | enum { |
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 | ||
454 | void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm) | 482 | int 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 | ||
467 | int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id) | 511 | int 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 | |||
527 | int 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 | |||
547 | static 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 | |||
555 | int 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, | |||
244 | unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, | 244 | unsigned 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 | ||
1383 | int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, | 1419 | int 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 | ||
889 | void 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 | |||
892 | void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) | 899 | void 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 | ||
1074 | struct 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 | |||
1046 | static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) | 1080 | static 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 | ||
1096 | int __iwl_mvm_mac_start(struct iwl_mvm *mvm) | 1136 | int __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 | ||
3635 | static 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 | |||
3684 | static 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 | |||
3584 | const struct ieee80211_ops iwl_mvm_hw_ops = { | 3724 | const 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 | */ | ||
154 | struct iwl_mvm_dump_desc { | ||
155 | size_t len; | ||
156 | /* must be last */ | ||
157 | struct iwl_fw_error_dump_trigger_desc trig_desc; | ||
158 | }; | ||
159 | |||
160 | extern struct iwl_mvm_dump_desc iwl_mvm_dump_desc_assert; | ||
161 | |||
148 | struct iwl_mvm_phy_ctxt { | 162 | struct 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 | */ |
341 | struct iwl_mvm_vif { | 358 | struct 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 | ||
829 | static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm) | 861 | static 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 | ||
918 | static 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 | |||
886 | extern const u8 iwl_mvm_ac_to_tx_fifo[]; | 924 | extern const u8 iwl_mvm_ac_to_tx_fifo[]; |
887 | 925 | ||
888 | struct iwl_rate_info { | 926 | struct 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 */ |
954 | int iwl_mvm_rx_reply_statistics(struct iwl_mvm *mvm, | 992 | void 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); | ||
957 | int iwl_mvm_rx_statistics(struct iwl_mvm *mvm, | 994 | int 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); |
997 | int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear); | ||
998 | void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm); | ||
960 | 999 | ||
961 | /* NVM */ | 1000 | /* NVM */ |
962 | int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic); | 1001 | int 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 */ |
1074 | int iwl_mvm_scan_size(struct iwl_mvm *mvm); | 1113 | int iwl_mvm_scan_size(struct iwl_mvm *mvm); |
1075 | int iwl_mvm_scan_request(struct iwl_mvm *mvm, | ||
1076 | struct ieee80211_vif *vif, | ||
1077 | struct cfg80211_scan_request *req); | ||
1078 | int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | ||
1079 | struct iwl_device_cmd *cmd); | ||
1080 | int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | ||
1081 | struct iwl_device_cmd *cmd); | ||
1082 | int iwl_mvm_cancel_scan(struct iwl_mvm *mvm); | 1114 | int iwl_mvm_cancel_scan(struct iwl_mvm *mvm); |
1083 | int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan); | 1115 | int 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, | |||
1089 | int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, | 1121 | int 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); |
1092 | int 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); | ||
1096 | int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, | 1124 | int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, |
1097 | struct cfg80211_sched_scan_request *req); | 1125 | struct cfg80211_sched_scan_request *req); |
1098 | int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, | ||
1099 | struct cfg80211_sched_scan_request *req); | ||
1100 | int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, | 1126 | int 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, | |||
1238 | u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, | 1264 | u8 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 | ||
1241 | bool iwl_mvm_bt_coex_is_ant_avail_old(struct iwl_mvm *mvm, u8 ant); | ||
1242 | bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm); | 1267 | bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm); |
1243 | void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm); | 1268 | void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm); |
1244 | int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm); | 1269 | int 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 */ | ||
1356 | bool iwl_mvm_is_idle(struct iwl_mvm *mvm); | ||
1357 | |||
1358 | /* Thermal management and CT-kill */ | 1380 | /* Thermal management and CT-kill */ |
1359 | void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); | 1381 | void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); |
1360 | void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp); | 1382 | void 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); | |||
1405 | void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error); | 1427 | void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error); |
1406 | void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm); | 1428 | void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm); |
1407 | 1429 | ||
1408 | int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf id); | 1430 | int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 id); |
1409 | void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm); | 1431 | int 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); | ||
1433 | int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm, | ||
1434 | struct iwl_mvm_dump_desc *desc, | ||
1435 | unsigned int delay); | ||
1436 | void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm); | ||
1437 | int 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 | |||
1441 | static inline bool | ||
1442 | iwl_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 | |||
1450 | static inline bool | ||
1451 | iwl_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 | |||
1459 | static inline bool | ||
1460 | iwl_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 | |||
1470 | static inline void | ||
1471 | iwl_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 | ||
688 | static 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 | |||
688 | static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode, | 720 | static 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) | |||
827 | static void iwl_mvm_fw_error_dump_wk(struct work_struct *work) | 861 | static 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 | ||
137 | struct rs_tx_column; | ||
138 | |||
137 | typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm, | 139 | typedef 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 | ||
141 | struct rs_tx_column { | 144 | struct 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 | ||
149 | static bool rs_ant_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | 152 | static 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 | ||
155 | static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | 159 | static 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 | ||
173 | static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | 186 | static 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 | ||
182 | static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | 196 | static 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 |
1005 | static 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 | */ | ||
1029 | static 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 */ | ||
1054 | static 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 | ||
1019 | static 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 | |||
1031 | static u8 rs_get_tid(struct ieee80211_hdr *hdr) | 1068 | static 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); |
1255 | done: | 1264 | done: |
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 | ||
418 | static void iwl_mvm_update_rx_statistics(struct iwl_mvm *mvm, | 437 | static 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 | ||
430 | struct iwl_mvm_stat_data { | 445 | struct 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 | ||
435 | static void iwl_mvm_stat_iterator(void *_data, u8 *mac, | 452 | static 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 | /* | 530 | static inline void |
504 | * iwl_mvm_rx_statistics - STATISTICS_NOTIFICATION handler | 531 | iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) |
505 | * | ||
506 | * TODO: This handler is implemented partially. | ||
507 | */ | ||
508 | int 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 | |||
558 | void 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 | |||
621 | int 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 | ||
194 | static 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 | */ | ||
228 | static 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 | |||
289 | static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac, | 195 | static 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 | ||
423 | int 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, ¶ms); | ||
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, ¶ms); | ||
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 | |||
535 | int 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 | |||
546 | int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, | 317 | int 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 | ||
559 | int 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 | |||
579 | int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm, | 330 | int 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 | ||
599 | static 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 | |||
637 | static 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 | |||
658 | out_remove_notif: | ||
659 | iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort); | ||
660 | return ret; | ||
661 | } | ||
662 | |||
663 | int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, | 340 | int 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 | ||
713 | static 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 | |||
737 | static 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 | |||
761 | static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list) | 379 | static 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 | ||
818 | static 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 | |||
867 | int 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, ¶ms); | ||
902 | iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, ¶ms); | ||
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, ¶ms); | ||
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, ¶ms); | ||
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 | |||
939 | int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, | 436 | int 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 | ||
1021 | int 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 | |||
1048 | int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, | 518 | int 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 | ||
914 | int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | 918 | int 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 | */ |
335 | struct iwl_error_event_table { | 335 | struct 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 | |||
382 | struct 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 | ||
452 | void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) | 500 | static 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 | ||
581 | void 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 | } | ||
533 | void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, | 667 | void 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 | ||
780 | int 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 | |||
806 | void 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 | |||
646 | static void iwl_mvm_diversity_iter(void *_data, u8 *mac, | 814 | static 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 | ||
720 | static 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 | |||
728 | bool 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 | |||
739 | struct iwl_bss_iter_data { | 888 | struct 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 | ||
743 | void lbs_debugfs_remove(void) | 743 | void lbs_debugfs_remove(void) |
744 | { | 744 | { |
745 | if (lbs_dir) | 745 | debugfs_remove(lbs_dir); |
746 | debugfs_remove(lbs_dir); | ||
747 | } | 746 | } |
748 | 747 | ||
749 | void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev) | 748 | void 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 | } |
199 | process_start: | 199 | process_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 | |||
143 | struct mwifiex_dbg { | 146 | struct 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 | ||
1419 | void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter); | 1423 | void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter); |
1424 | void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags); | ||
1420 | 1425 | ||
1421 | #ifdef CONFIG_DEBUG_FS | 1426 | #ifdef CONFIG_DEBUG_FS |
1422 | void mwifiex_debugfs_init(void); | 1427 | void 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); | |||
80 | int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, | 80 | int 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 | |||
635 | void *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 | } | ||
656 | EXPORT_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 | ||
40 | void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); | 38 | void 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 | ||
32 | void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, | 31 | void 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 | ||
37 | void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); | 36 | void 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 | ||
37 | void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); | 36 | void 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 | ||
32 | void rtl92ee_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, | 31 | void 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 | ||
32 | void rtl8723e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, | 31 | void 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 | ||
32 | void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, | 31 | void 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 | ||
32 | void rtl8821ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, | 31 | void 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 | ||
702 | static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw) | 702 | static 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); |