diff options
author | David S. Miller <davem@davemloft.net> | 2018-03-29 16:24:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-29 16:24:06 -0400 |
commit | 18845557fd6fc1998f2d0d8c30467f86db587529 (patch) | |
tree | 80e3f239192cb421b54f8e6d85c03270c5ac394d | |
parent | e15f20ea33b8e5074145abe464b4b48acea505d9 (diff) | |
parent | 14c99949a3398a655c47b262ca8e2e83edfae7fd (diff) |
Merge tag 'wireless-drivers-next-for-davem-2018-03-29' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says:
====================
wireless-drivers-next patches for 4.17
Smaller new features to various drivers but nothing really out of
ordinary.
Major changes:
ath10k
* enable chip temperature measurement for QCA6174/QCA9377
* add firmware memory dump for QCA9984
* enable buffer STA on TDLS link for QCA6174
* support different beacon internals in multiple interface scenario
for QCA988X/QCA99X0/QCA9984/QCA4019
iwlwifi
* support for new PCI IDs for the 9000 family
* support for a new firmware API version
* support for advanced dwell and Optimized Connectivity Experience
(OCE) in scanning
btrsi
* fix kconfig dependencies
wil6210
* support multiple virtual interfaces
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
173 files changed, 6233 insertions, 2505 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index d8bbd661dbdb..149a38ee1fce 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
@@ -393,9 +393,7 @@ config BT_QCOMSMD | |||
393 | kernel or say M to compile as a module. | 393 | kernel or say M to compile as a module. |
394 | 394 | ||
395 | config BT_HCIRSI | 395 | config BT_HCIRSI |
396 | tristate "Redpine HCI support" | 396 | tristate |
397 | default n | ||
398 | select RSI_COEX | ||
399 | help | 397 | help |
400 | Redpine BT driver. | 398 | Redpine BT driver. |
401 | This driver handles BT traffic from upper layers and pass | 399 | This driver handles BT traffic from upper layers and pass |
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index f3f2784f6ebd..7a364eca46d6 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -33,8 +33,6 @@ | |||
33 | */ | 33 | */ |
34 | #define ATH_KEYMAX 128 /* max key cache size we handle */ | 34 | #define ATH_KEYMAX 128 /* max key cache size we handle */ |
35 | 35 | ||
36 | static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
37 | |||
38 | struct ath_ani { | 36 | struct ath_ani { |
39 | bool caldone; | 37 | bool caldone; |
40 | unsigned int longcal_timer; | 38 | unsigned int longcal_timer; |
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index f3ec13b80b20..8a3020dbd4cf 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | 3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
4 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -2040,7 +2041,8 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) | |||
2040 | ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS; | 2041 | ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS; |
2041 | ar->num_tids = TARGET_10_4_TGT_NUM_TIDS; | 2042 | ar->num_tids = TARGET_10_4_TGT_NUM_TIDS; |
2042 | ar->fw_stats_req_mask = WMI_10_4_STAT_PEER | | 2043 | ar->fw_stats_req_mask = WMI_10_4_STAT_PEER | |
2043 | WMI_10_4_STAT_PEER_EXTD; | 2044 | WMI_10_4_STAT_PEER_EXTD | |
2045 | WMI_10_4_STAT_VDEV_EXTD; | ||
2044 | ar->max_spatial_stream = ar->hw_params.max_spatial_stream; | 2046 | ar->max_spatial_stream = ar->hw_params.max_spatial_stream; |
2045 | ar->max_num_tdls_vdevs = TARGET_10_4_NUM_TDLS_VDEVS; | 2047 | ar->max_num_tdls_vdevs = TARGET_10_4_NUM_TDLS_VDEVS; |
2046 | 2048 | ||
@@ -2281,6 +2283,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode, | |||
2281 | if (ath10k_peer_stats_enabled(ar)) | 2283 | if (ath10k_peer_stats_enabled(ar)) |
2282 | val = WMI_10_4_PEER_STATS; | 2284 | val = WMI_10_4_PEER_STATS; |
2283 | 2285 | ||
2286 | /* Enable vdev stats by default */ | ||
2287 | val |= WMI_10_4_VDEV_STATS; | ||
2288 | |||
2284 | if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map)) | 2289 | if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map)) |
2285 | val |= WMI_10_4_BSS_CHANNEL_INFO_64; | 2290 | val |= WMI_10_4_BSS_CHANNEL_INFO_64; |
2286 | 2291 | ||
@@ -2439,7 +2444,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar) | |||
2439 | 2444 | ||
2440 | ret = ath10k_hif_power_up(ar); | 2445 | ret = ath10k_hif_power_up(ar); |
2441 | if (ret) { | 2446 | if (ret) { |
2442 | ath10k_err(ar, "could not start pci hif (%d)\n", ret); | 2447 | ath10k_err(ar, "could not power on hif bus (%d)\n", ret); |
2443 | return ret; | 2448 | return ret; |
2444 | } | 2449 | } |
2445 | 2450 | ||
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index fe6b30356d3b..c17d805d68cc 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | 3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
4 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -221,6 +222,27 @@ struct ath10k_fw_stats_vdev { | |||
221 | u32 beacon_rssi_history[10]; | 222 | u32 beacon_rssi_history[10]; |
222 | }; | 223 | }; |
223 | 224 | ||
225 | struct ath10k_fw_stats_vdev_extd { | ||
226 | struct list_head list; | ||
227 | |||
228 | u32 vdev_id; | ||
229 | u32 ppdu_aggr_cnt; | ||
230 | u32 ppdu_noack; | ||
231 | u32 mpdu_queued; | ||
232 | u32 ppdu_nonaggr_cnt; | ||
233 | u32 mpdu_sw_requeued; | ||
234 | u32 mpdu_suc_retry; | ||
235 | u32 mpdu_suc_multitry; | ||
236 | u32 mpdu_fail_retry; | ||
237 | u32 tx_ftm_suc; | ||
238 | u32 tx_ftm_suc_retry; | ||
239 | u32 tx_ftm_fail; | ||
240 | u32 rx_ftmr_cnt; | ||
241 | u32 rx_ftmr_dup_cnt; | ||
242 | u32 rx_iftmr_cnt; | ||
243 | u32 rx_iftmr_dup_cnt; | ||
244 | }; | ||
245 | |||
224 | struct ath10k_fw_stats_pdev { | 246 | struct ath10k_fw_stats_pdev { |
225 | struct list_head list; | 247 | struct list_head list; |
226 | 248 | ||
@@ -324,6 +346,27 @@ struct ath10k_tpc_stats { | |||
324 | struct ath10k_tpc_table tpc_table[WMI_TPC_FLAG]; | 346 | struct ath10k_tpc_table tpc_table[WMI_TPC_FLAG]; |
325 | }; | 347 | }; |
326 | 348 | ||
349 | struct ath10k_tpc_table_final { | ||
350 | u32 pream_idx[WMI_TPC_FINAL_RATE_MAX]; | ||
351 | u8 rate_code[WMI_TPC_FINAL_RATE_MAX]; | ||
352 | char tpc_value[WMI_TPC_FINAL_RATE_MAX][WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE]; | ||
353 | }; | ||
354 | |||
355 | struct ath10k_tpc_stats_final { | ||
356 | u32 reg_domain; | ||
357 | u32 chan_freq; | ||
358 | u32 phy_mode; | ||
359 | u32 twice_antenna_reduction; | ||
360 | u32 twice_max_rd_power; | ||
361 | s32 twice_antenna_gain; | ||
362 | u32 power_limit; | ||
363 | u32 num_tx_chain; | ||
364 | u32 ctl; | ||
365 | u32 rate_max; | ||
366 | u8 flag[WMI_TPC_FLAG]; | ||
367 | struct ath10k_tpc_table_final tpc_table_final[WMI_TPC_FLAG]; | ||
368 | }; | ||
369 | |||
327 | struct ath10k_dfs_stats { | 370 | struct ath10k_dfs_stats { |
328 | u32 phy_errors; | 371 | u32 phy_errors; |
329 | u32 pulses_total; | 372 | u32 pulses_total; |
@@ -354,6 +397,45 @@ struct ath10k_txq { | |||
354 | unsigned long num_push_allowed; | 397 | unsigned long num_push_allowed; |
355 | }; | 398 | }; |
356 | 399 | ||
400 | enum ath10k_pkt_rx_err { | ||
401 | ATH10K_PKT_RX_ERR_FCS, | ||
402 | ATH10K_PKT_RX_ERR_TKIP, | ||
403 | ATH10K_PKT_RX_ERR_CRYPT, | ||
404 | ATH10K_PKT_RX_ERR_PEER_IDX_INVAL, | ||
405 | ATH10K_PKT_RX_ERR_MAX, | ||
406 | }; | ||
407 | |||
408 | enum ath10k_ampdu_subfrm_num { | ||
409 | ATH10K_AMPDU_SUBFRM_NUM_10, | ||
410 | ATH10K_AMPDU_SUBFRM_NUM_20, | ||
411 | ATH10K_AMPDU_SUBFRM_NUM_30, | ||
412 | ATH10K_AMPDU_SUBFRM_NUM_40, | ||
413 | ATH10K_AMPDU_SUBFRM_NUM_50, | ||
414 | ATH10K_AMPDU_SUBFRM_NUM_60, | ||
415 | ATH10K_AMPDU_SUBFRM_NUM_MORE, | ||
416 | ATH10K_AMPDU_SUBFRM_NUM_MAX, | ||
417 | }; | ||
418 | |||
419 | enum ath10k_amsdu_subfrm_num { | ||
420 | ATH10K_AMSDU_SUBFRM_NUM_1, | ||
421 | ATH10K_AMSDU_SUBFRM_NUM_2, | ||
422 | ATH10K_AMSDU_SUBFRM_NUM_3, | ||
423 | ATH10K_AMSDU_SUBFRM_NUM_4, | ||
424 | ATH10K_AMSDU_SUBFRM_NUM_MORE, | ||
425 | ATH10K_AMSDU_SUBFRM_NUM_MAX, | ||
426 | }; | ||
427 | |||
428 | struct ath10k_sta_tid_stats { | ||
429 | unsigned long int rx_pkt_from_fw; | ||
430 | unsigned long int rx_pkt_unchained; | ||
431 | unsigned long int rx_pkt_drop_chained; | ||
432 | unsigned long int rx_pkt_drop_filter; | ||
433 | unsigned long int rx_pkt_err[ATH10K_PKT_RX_ERR_MAX]; | ||
434 | unsigned long int rx_pkt_queued_for_mac; | ||
435 | unsigned long int rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MAX]; | ||
436 | unsigned long int rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_MAX]; | ||
437 | }; | ||
438 | |||
357 | struct ath10k_sta { | 439 | struct ath10k_sta { |
358 | struct ath10k_vif *arvif; | 440 | struct ath10k_vif *arvif; |
359 | 441 | ||
@@ -371,6 +453,9 @@ struct ath10k_sta { | |||
371 | #ifdef CONFIG_MAC80211_DEBUGFS | 453 | #ifdef CONFIG_MAC80211_DEBUGFS |
372 | /* protected by conf_mutex */ | 454 | /* protected by conf_mutex */ |
373 | bool aggr_mode; | 455 | bool aggr_mode; |
456 | |||
457 | /* Protected with ar->data_lock */ | ||
458 | struct ath10k_sta_tid_stats tid_stats[IEEE80211_NUM_TIDS + 1]; | ||
374 | #endif | 459 | #endif |
375 | }; | 460 | }; |
376 | 461 | ||
@@ -487,6 +572,7 @@ struct ath10k_debug { | |||
487 | 572 | ||
488 | /* used for tpc-dump storage, protected by data-lock */ | 573 | /* used for tpc-dump storage, protected by data-lock */ |
489 | struct ath10k_tpc_stats *tpc_stats; | 574 | struct ath10k_tpc_stats *tpc_stats; |
575 | struct ath10k_tpc_stats_final *tpc_stats_final; | ||
490 | 576 | ||
491 | struct completion tpc_complete; | 577 | struct completion tpc_complete; |
492 | 578 | ||
@@ -1019,6 +1105,8 @@ struct ath10k { | |||
1019 | 1105 | ||
1020 | void *ce_priv; | 1106 | void *ce_priv; |
1021 | 1107 | ||
1108 | u32 sta_tid_stats_mask; | ||
1109 | |||
1022 | /* must be last */ | 1110 | /* must be last */ |
1023 | u8 drv_priv[0] __aligned(sizeof(void *)); | 1111 | u8 drv_priv[0] __aligned(sizeof(void *)); |
1024 | }; | 1112 | }; |
diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c index 7173b3743b43..f90cec0ebb1c 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.c +++ b/drivers/net/wireless/ath/ath10k/coredump.c | |||
@@ -701,6 +701,89 @@ static const struct ath10k_mem_region qca988x_hw20_mem_regions[] = { | |||
701 | }, | 701 | }, |
702 | }; | 702 | }; |
703 | 703 | ||
704 | static const struct ath10k_mem_region qca9984_hw10_mem_regions[] = { | ||
705 | { | ||
706 | .type = ATH10K_MEM_REGION_TYPE_DRAM, | ||
707 | .start = 0x400000, | ||
708 | .len = 0x80000, | ||
709 | .name = "DRAM", | ||
710 | .section_table = { | ||
711 | .sections = NULL, | ||
712 | .size = 0, | ||
713 | }, | ||
714 | }, | ||
715 | { | ||
716 | .type = ATH10K_MEM_REGION_TYPE_REG, | ||
717 | .start = 0x98000, | ||
718 | .len = 0x50000, | ||
719 | .name = "IRAM", | ||
720 | .section_table = { | ||
721 | .sections = NULL, | ||
722 | .size = 0, | ||
723 | }, | ||
724 | }, | ||
725 | { | ||
726 | .type = ATH10K_MEM_REGION_TYPE_IOSRAM, | ||
727 | .start = 0xC0000, | ||
728 | .len = 0x40000, | ||
729 | .name = "SRAM", | ||
730 | .section_table = { | ||
731 | .sections = NULL, | ||
732 | .size = 0, | ||
733 | }, | ||
734 | }, | ||
735 | { | ||
736 | .type = ATH10K_MEM_REGION_TYPE_IOREG, | ||
737 | .start = 0x30000, | ||
738 | .len = 0x7000, | ||
739 | .name = "APB REG 1", | ||
740 | .section_table = { | ||
741 | .sections = NULL, | ||
742 | .size = 0, | ||
743 | }, | ||
744 | }, | ||
745 | { | ||
746 | .type = ATH10K_MEM_REGION_TYPE_IOREG, | ||
747 | .start = 0x3f000, | ||
748 | .len = 0x3000, | ||
749 | .name = "APB REG 2", | ||
750 | .section_table = { | ||
751 | .sections = NULL, | ||
752 | .size = 0, | ||
753 | }, | ||
754 | }, | ||
755 | { | ||
756 | .type = ATH10K_MEM_REGION_TYPE_IOREG, | ||
757 | .start = 0x43000, | ||
758 | .len = 0x3000, | ||
759 | .name = "WIFI REG", | ||
760 | .section_table = { | ||
761 | .sections = NULL, | ||
762 | .size = 0, | ||
763 | }, | ||
764 | }, | ||
765 | { | ||
766 | .type = ATH10K_MEM_REGION_TYPE_IOREG, | ||
767 | .start = 0x4A000, | ||
768 | .len = 0x5000, | ||
769 | .name = "CE REG", | ||
770 | .section_table = { | ||
771 | .sections = NULL, | ||
772 | .size = 0, | ||
773 | }, | ||
774 | }, | ||
775 | { | ||
776 | .type = ATH10K_MEM_REGION_TYPE_IOREG, | ||
777 | .start = 0x80000, | ||
778 | .len = 0x6000, | ||
779 | .name = "SOC REG", | ||
780 | .section_table = { | ||
781 | .sections = NULL, | ||
782 | .size = 0, | ||
783 | }, | ||
784 | }, | ||
785 | }; | ||
786 | |||
704 | static const struct ath10k_hw_mem_layout hw_mem_layouts[] = { | 787 | static const struct ath10k_hw_mem_layout hw_mem_layouts[] = { |
705 | { | 788 | { |
706 | .hw_id = QCA6174_HW_1_0_VERSION, | 789 | .hw_id = QCA6174_HW_1_0_VERSION, |
@@ -758,6 +841,13 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = { | |||
758 | .size = ARRAY_SIZE(qca988x_hw20_mem_regions), | 841 | .size = ARRAY_SIZE(qca988x_hw20_mem_regions), |
759 | }, | 842 | }, |
760 | }, | 843 | }, |
844 | { | ||
845 | .hw_id = QCA9984_HW_1_0_DEV_VERSION, | ||
846 | .region_table = { | ||
847 | .regions = qca9984_hw10_mem_regions, | ||
848 | .size = ARRAY_SIZE(qca9984_hw10_mem_regions), | ||
849 | }, | ||
850 | }, | ||
761 | }; | 851 | }; |
762 | 852 | ||
763 | static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar) | 853 | static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar) |
diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h index bfee13038e59..3baaf9d2cbcd 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.h +++ b/drivers/net/wireless/ath/ath10k/coredump.h | |||
@@ -124,6 +124,8 @@ enum ath10k_mem_region_type { | |||
124 | ATH10K_MEM_REGION_TYPE_AXI = 3, | 124 | ATH10K_MEM_REGION_TYPE_AXI = 3, |
125 | ATH10K_MEM_REGION_TYPE_IRAM1 = 4, | 125 | ATH10K_MEM_REGION_TYPE_IRAM1 = 4, |
126 | ATH10K_MEM_REGION_TYPE_IRAM2 = 5, | 126 | ATH10K_MEM_REGION_TYPE_IRAM2 = 5, |
127 | ATH10K_MEM_REGION_TYPE_IOSRAM = 6, | ||
128 | ATH10K_MEM_REGION_TYPE_IOREG = 7, | ||
127 | }; | 129 | }; |
128 | 130 | ||
129 | /* Define a section of the region which should be copied. As not all parts | 131 | /* Define a section of the region which should be copied. As not all parts |
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 554cd7856cb6..bac832ce1873 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c | |||
@@ -1480,6 +1480,19 @@ void ath10k_debug_tpc_stats_process(struct ath10k *ar, | |||
1480 | spin_unlock_bh(&ar->data_lock); | 1480 | spin_unlock_bh(&ar->data_lock); |
1481 | } | 1481 | } |
1482 | 1482 | ||
1483 | void | ||
1484 | ath10k_debug_tpc_stats_final_process(struct ath10k *ar, | ||
1485 | struct ath10k_tpc_stats_final *tpc_stats) | ||
1486 | { | ||
1487 | spin_lock_bh(&ar->data_lock); | ||
1488 | |||
1489 | kfree(ar->debug.tpc_stats_final); | ||
1490 | ar->debug.tpc_stats_final = tpc_stats; | ||
1491 | complete(&ar->debug.tpc_complete); | ||
1492 | |||
1493 | spin_unlock_bh(&ar->data_lock); | ||
1494 | } | ||
1495 | |||
1483 | static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats, | 1496 | static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats, |
1484 | unsigned int j, char *buf, size_t *len) | 1497 | unsigned int j, char *buf, size_t *len) |
1485 | { | 1498 | { |
@@ -2143,6 +2156,137 @@ static const struct file_operations fops_fw_checksums = { | |||
2143 | .llseek = default_llseek, | 2156 | .llseek = default_llseek, |
2144 | }; | 2157 | }; |
2145 | 2158 | ||
2159 | static ssize_t ath10k_sta_tid_stats_mask_read(struct file *file, | ||
2160 | char __user *user_buf, | ||
2161 | size_t count, loff_t *ppos) | ||
2162 | { | ||
2163 | struct ath10k *ar = file->private_data; | ||
2164 | char buf[32]; | ||
2165 | size_t len; | ||
2166 | |||
2167 | len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->sta_tid_stats_mask); | ||
2168 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
2169 | } | ||
2170 | |||
2171 | static ssize_t ath10k_sta_tid_stats_mask_write(struct file *file, | ||
2172 | const char __user *user_buf, | ||
2173 | size_t count, loff_t *ppos) | ||
2174 | { | ||
2175 | struct ath10k *ar = file->private_data; | ||
2176 | char buf[32]; | ||
2177 | ssize_t len; | ||
2178 | u32 mask; | ||
2179 | |||
2180 | len = min(count, sizeof(buf) - 1); | ||
2181 | if (copy_from_user(buf, user_buf, len)) | ||
2182 | return -EFAULT; | ||
2183 | |||
2184 | buf[len] = '\0'; | ||
2185 | if (kstrtoint(buf, 0, &mask)) | ||
2186 | return -EINVAL; | ||
2187 | |||
2188 | ar->sta_tid_stats_mask = mask; | ||
2189 | |||
2190 | return len; | ||
2191 | } | ||
2192 | |||
2193 | static const struct file_operations fops_sta_tid_stats_mask = { | ||
2194 | .read = ath10k_sta_tid_stats_mask_read, | ||
2195 | .write = ath10k_sta_tid_stats_mask_write, | ||
2196 | .open = simple_open, | ||
2197 | .owner = THIS_MODULE, | ||
2198 | .llseek = default_llseek, | ||
2199 | }; | ||
2200 | |||
2201 | static int ath10k_debug_tpc_stats_final_request(struct ath10k *ar) | ||
2202 | { | ||
2203 | int ret; | ||
2204 | unsigned long time_left; | ||
2205 | |||
2206 | lockdep_assert_held(&ar->conf_mutex); | ||
2207 | |||
2208 | reinit_completion(&ar->debug.tpc_complete); | ||
2209 | |||
2210 | ret = ath10k_wmi_pdev_get_tpc_table_cmdid(ar, WMI_TPC_CONFIG_PARAM); | ||
2211 | if (ret) { | ||
2212 | ath10k_warn(ar, "failed to request tpc table cmdid: %d\n", ret); | ||
2213 | return ret; | ||
2214 | } | ||
2215 | |||
2216 | time_left = wait_for_completion_timeout(&ar->debug.tpc_complete, | ||
2217 | 1 * HZ); | ||
2218 | if (time_left == 0) | ||
2219 | return -ETIMEDOUT; | ||
2220 | |||
2221 | return 0; | ||
2222 | } | ||
2223 | |||
2224 | static int ath10k_tpc_stats_final_open(struct inode *inode, struct file *file) | ||
2225 | { | ||
2226 | struct ath10k *ar = inode->i_private; | ||
2227 | void *buf; | ||
2228 | int ret; | ||
2229 | |||
2230 | mutex_lock(&ar->conf_mutex); | ||
2231 | |||
2232 | if (ar->state != ATH10K_STATE_ON) { | ||
2233 | ret = -ENETDOWN; | ||
2234 | goto err_unlock; | ||
2235 | } | ||
2236 | |||
2237 | buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE); | ||
2238 | if (!buf) { | ||
2239 | ret = -ENOMEM; | ||
2240 | goto err_unlock; | ||
2241 | } | ||
2242 | |||
2243 | ret = ath10k_debug_tpc_stats_final_request(ar); | ||
2244 | if (ret) { | ||
2245 | ath10k_warn(ar, "failed to request tpc stats final: %d\n", | ||
2246 | ret); | ||
2247 | goto err_free; | ||
2248 | } | ||
2249 | |||
2250 | ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf); | ||
2251 | file->private_data = buf; | ||
2252 | |||
2253 | mutex_unlock(&ar->conf_mutex); | ||
2254 | return 0; | ||
2255 | |||
2256 | err_free: | ||
2257 | vfree(buf); | ||
2258 | |||
2259 | err_unlock: | ||
2260 | mutex_unlock(&ar->conf_mutex); | ||
2261 | return ret; | ||
2262 | } | ||
2263 | |||
2264 | static int ath10k_tpc_stats_final_release(struct inode *inode, | ||
2265 | struct file *file) | ||
2266 | { | ||
2267 | vfree(file->private_data); | ||
2268 | |||
2269 | return 0; | ||
2270 | } | ||
2271 | |||
2272 | static ssize_t ath10k_tpc_stats_final_read(struct file *file, | ||
2273 | char __user *user_buf, | ||
2274 | size_t count, loff_t *ppos) | ||
2275 | { | ||
2276 | const char *buf = file->private_data; | ||
2277 | unsigned int len = strlen(buf); | ||
2278 | |||
2279 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
2280 | } | ||
2281 | |||
2282 | static const struct file_operations fops_tpc_stats_final = { | ||
2283 | .open = ath10k_tpc_stats_final_open, | ||
2284 | .release = ath10k_tpc_stats_final_release, | ||
2285 | .read = ath10k_tpc_stats_final_read, | ||
2286 | .owner = THIS_MODULE, | ||
2287 | .llseek = default_llseek, | ||
2288 | }; | ||
2289 | |||
2146 | int ath10k_debug_create(struct ath10k *ar) | 2290 | int ath10k_debug_create(struct ath10k *ar) |
2147 | { | 2291 | { |
2148 | ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN); | 2292 | ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN); |
@@ -2258,6 +2402,16 @@ int ath10k_debug_register(struct ath10k *ar) | |||
2258 | debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar, | 2402 | debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar, |
2259 | &fops_fw_checksums); | 2403 | &fops_fw_checksums); |
2260 | 2404 | ||
2405 | if (IS_ENABLED(CONFIG_MAC80211_DEBUGFS)) | ||
2406 | debugfs_create_file("sta_tid_stats_mask", 0600, | ||
2407 | ar->debug.debugfs_phy, | ||
2408 | ar, &fops_sta_tid_stats_mask); | ||
2409 | |||
2410 | if (test_bit(WMI_SERVICE_TPC_STATS_FINAL, ar->wmi.svc_map)) | ||
2411 | debugfs_create_file("tpc_stats_final", 0400, | ||
2412 | ar->debug.debugfs_phy, ar, | ||
2413 | &fops_tpc_stats_final); | ||
2414 | |||
2261 | return 0; | 2415 | return 0; |
2262 | } | 2416 | } |
2263 | 2417 | ||
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index e54308889e59..0afca5c106b6 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | 3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
4 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -101,6 +102,9 @@ void ath10k_debug_unregister(struct ath10k *ar); | |||
101 | void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb); | 102 | void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb); |
102 | void ath10k_debug_tpc_stats_process(struct ath10k *ar, | 103 | void ath10k_debug_tpc_stats_process(struct ath10k *ar, |
103 | struct ath10k_tpc_stats *tpc_stats); | 104 | struct ath10k_tpc_stats *tpc_stats); |
105 | void | ||
106 | ath10k_debug_tpc_stats_final_process(struct ath10k *ar, | ||
107 | struct ath10k_tpc_stats_final *tpc_stats); | ||
104 | void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); | 108 | void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); |
105 | 109 | ||
106 | #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) | 110 | #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) |
@@ -164,6 +168,13 @@ static inline void ath10k_debug_tpc_stats_process(struct ath10k *ar, | |||
164 | kfree(tpc_stats); | 168 | kfree(tpc_stats); |
165 | } | 169 | } |
166 | 170 | ||
171 | static inline void | ||
172 | ath10k_debug_tpc_stats_final_process(struct ath10k *ar, | ||
173 | struct ath10k_tpc_stats_final *tpc_stats) | ||
174 | { | ||
175 | kfree(tpc_stats); | ||
176 | } | ||
177 | |||
167 | static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, | 178 | static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, |
168 | int len) | 179 | int len) |
169 | { | 180 | { |
@@ -191,12 +202,42 @@ void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
191 | struct ieee80211_sta *sta, struct dentry *dir); | 202 | struct ieee80211_sta *sta, struct dentry *dir); |
192 | void ath10k_sta_update_rx_duration(struct ath10k *ar, | 203 | void ath10k_sta_update_rx_duration(struct ath10k *ar, |
193 | struct ath10k_fw_stats *stats); | 204 | struct ath10k_fw_stats *stats); |
205 | void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr, | ||
206 | unsigned long int num_msdus, | ||
207 | enum ath10k_pkt_rx_err err, | ||
208 | unsigned long int unchain_cnt, | ||
209 | unsigned long int drop_cnt, | ||
210 | unsigned long int drop_cnt_filter, | ||
211 | unsigned long int queued_msdus); | ||
212 | void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar, | ||
213 | u16 peer_id, u8 tid, | ||
214 | struct htt_rx_indication_mpdu_range *ranges, | ||
215 | int num_ranges); | ||
194 | #else | 216 | #else |
195 | static inline | 217 | static inline |
196 | void ath10k_sta_update_rx_duration(struct ath10k *ar, | 218 | void ath10k_sta_update_rx_duration(struct ath10k *ar, |
197 | struct ath10k_fw_stats *stats) | 219 | struct ath10k_fw_stats *stats) |
198 | { | 220 | { |
199 | } | 221 | } |
222 | |||
223 | static inline | ||
224 | void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr, | ||
225 | unsigned long int num_msdus, | ||
226 | enum ath10k_pkt_rx_err err, | ||
227 | unsigned long int unchain_cnt, | ||
228 | unsigned long int drop_cnt, | ||
229 | unsigned long int drop_cnt_filter, | ||
230 | unsigned long int queued_msdus) | ||
231 | { | ||
232 | } | ||
233 | |||
234 | static inline | ||
235 | void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar, | ||
236 | u16 peer_id, u8 tid, | ||
237 | struct htt_rx_indication_mpdu_range *ranges, | ||
238 | int num_ranges) | ||
239 | { | ||
240 | } | ||
200 | #endif /* CONFIG_MAC80211_DEBUGFS */ | 241 | #endif /* CONFIG_MAC80211_DEBUGFS */ |
201 | 242 | ||
202 | #ifdef CONFIG_ATH10K_DEBUG | 243 | #ifdef CONFIG_ATH10K_DEBUG |
diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c index b260b09dd4d3..8f688f136c22 100644 --- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -16,8 +17,125 @@ | |||
16 | 17 | ||
17 | #include "core.h" | 18 | #include "core.h" |
18 | #include "wmi-ops.h" | 19 | #include "wmi-ops.h" |
20 | #include "txrx.h" | ||
19 | #include "debug.h" | 21 | #include "debug.h" |
20 | 22 | ||
23 | static void ath10k_rx_stats_update_amsdu_subfrm(struct ath10k *ar, | ||
24 | struct ath10k_sta_tid_stats *stats, | ||
25 | u32 msdu_count) | ||
26 | { | ||
27 | if (msdu_count == 1) | ||
28 | stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_1]++; | ||
29 | else if (msdu_count == 2) | ||
30 | stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_2]++; | ||
31 | else if (msdu_count == 3) | ||
32 | stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_3]++; | ||
33 | else if (msdu_count == 4) | ||
34 | stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_4]++; | ||
35 | else if (msdu_count > 4) | ||
36 | stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_MORE]++; | ||
37 | } | ||
38 | |||
39 | static void ath10k_rx_stats_update_ampdu_subfrm(struct ath10k *ar, | ||
40 | struct ath10k_sta_tid_stats *stats, | ||
41 | u32 mpdu_count) | ||
42 | { | ||
43 | if (mpdu_count <= 10) | ||
44 | stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_10]++; | ||
45 | else if (mpdu_count <= 20) | ||
46 | stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_20]++; | ||
47 | else if (mpdu_count <= 30) | ||
48 | stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_30]++; | ||
49 | else if (mpdu_count <= 40) | ||
50 | stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_40]++; | ||
51 | else if (mpdu_count <= 50) | ||
52 | stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_50]++; | ||
53 | else if (mpdu_count <= 60) | ||
54 | stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_60]++; | ||
55 | else if (mpdu_count > 60) | ||
56 | stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MORE]++; | ||
57 | } | ||
58 | |||
59 | void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar, u16 peer_id, u8 tid, | ||
60 | struct htt_rx_indication_mpdu_range *ranges, | ||
61 | int num_ranges) | ||
62 | { | ||
63 | struct ath10k_sta *arsta; | ||
64 | struct ath10k_peer *peer; | ||
65 | int i; | ||
66 | |||
67 | if (tid > IEEE80211_NUM_TIDS || !(ar->sta_tid_stats_mask & BIT(tid))) | ||
68 | return; | ||
69 | |||
70 | rcu_read_lock(); | ||
71 | spin_lock_bh(&ar->data_lock); | ||
72 | |||
73 | peer = ath10k_peer_find_by_id(ar, peer_id); | ||
74 | if (!peer) | ||
75 | goto out; | ||
76 | |||
77 | arsta = (struct ath10k_sta *)peer->sta->drv_priv; | ||
78 | |||
79 | for (i = 0; i < num_ranges; i++) | ||
80 | ath10k_rx_stats_update_ampdu_subfrm(ar, | ||
81 | &arsta->tid_stats[tid], | ||
82 | ranges[i].mpdu_count); | ||
83 | |||
84 | out: | ||
85 | spin_unlock_bh(&ar->data_lock); | ||
86 | rcu_read_unlock(); | ||
87 | } | ||
88 | |||
89 | void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr, | ||
90 | unsigned long int num_msdus, | ||
91 | enum ath10k_pkt_rx_err err, | ||
92 | unsigned long int unchain_cnt, | ||
93 | unsigned long int drop_cnt, | ||
94 | unsigned long int drop_cnt_filter, | ||
95 | unsigned long int queued_msdus) | ||
96 | { | ||
97 | struct ieee80211_sta *sta; | ||
98 | struct ath10k_sta *arsta; | ||
99 | struct ieee80211_hdr *hdr; | ||
100 | struct ath10k_sta_tid_stats *stats; | ||
101 | u8 tid = IEEE80211_NUM_TIDS; | ||
102 | bool non_data_frm = false; | ||
103 | |||
104 | hdr = (struct ieee80211_hdr *)first_hdr; | ||
105 | if (!ieee80211_is_data(hdr->frame_control)) | ||
106 | non_data_frm = true; | ||
107 | |||
108 | if (ieee80211_is_data_qos(hdr->frame_control)) | ||
109 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | ||
110 | |||
111 | if (!(ar->sta_tid_stats_mask & BIT(tid)) || non_data_frm) | ||
112 | return; | ||
113 | |||
114 | rcu_read_lock(); | ||
115 | |||
116 | sta = ieee80211_find_sta_by_ifaddr(ar->hw, hdr->addr2, NULL); | ||
117 | if (!sta) | ||
118 | goto exit; | ||
119 | |||
120 | arsta = (struct ath10k_sta *)sta->drv_priv; | ||
121 | |||
122 | spin_lock_bh(&ar->data_lock); | ||
123 | stats = &arsta->tid_stats[tid]; | ||
124 | stats->rx_pkt_from_fw += num_msdus; | ||
125 | stats->rx_pkt_unchained += unchain_cnt; | ||
126 | stats->rx_pkt_drop_chained += drop_cnt; | ||
127 | stats->rx_pkt_drop_filter += drop_cnt_filter; | ||
128 | if (err != ATH10K_PKT_RX_ERR_MAX) | ||
129 | stats->rx_pkt_err[err] += queued_msdus; | ||
130 | stats->rx_pkt_queued_for_mac += queued_msdus; | ||
131 | ath10k_rx_stats_update_amsdu_subfrm(ar, &arsta->tid_stats[tid], | ||
132 | num_msdus); | ||
133 | spin_unlock_bh(&ar->data_lock); | ||
134 | |||
135 | exit: | ||
136 | rcu_read_unlock(); | ||
137 | } | ||
138 | |||
21 | static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar, | 139 | static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar, |
22 | struct ath10k_fw_stats *stats) | 140 | struct ath10k_fw_stats *stats) |
23 | { | 141 | { |
@@ -342,6 +460,172 @@ static const struct file_operations fops_peer_debug_trigger = { | |||
342 | .llseek = default_llseek, | 460 | .llseek = default_llseek, |
343 | }; | 461 | }; |
344 | 462 | ||
463 | static char *get_err_str(enum ath10k_pkt_rx_err i) | ||
464 | { | ||
465 | switch (i) { | ||
466 | case ATH10K_PKT_RX_ERR_FCS: | ||
467 | return "fcs_err"; | ||
468 | case ATH10K_PKT_RX_ERR_TKIP: | ||
469 | return "tkip_err"; | ||
470 | case ATH10K_PKT_RX_ERR_CRYPT: | ||
471 | return "crypt_err"; | ||
472 | case ATH10K_PKT_RX_ERR_PEER_IDX_INVAL: | ||
473 | return "peer_idx_inval"; | ||
474 | case ATH10K_PKT_RX_ERR_MAX: | ||
475 | return "unknown"; | ||
476 | } | ||
477 | |||
478 | return "unknown"; | ||
479 | } | ||
480 | |||
481 | static char *get_num_ampdu_subfrm_str(enum ath10k_ampdu_subfrm_num i) | ||
482 | { | ||
483 | switch (i) { | ||
484 | case ATH10K_AMPDU_SUBFRM_NUM_10: | ||
485 | return "upto 10"; | ||
486 | case ATH10K_AMPDU_SUBFRM_NUM_20: | ||
487 | return "11-20"; | ||
488 | case ATH10K_AMPDU_SUBFRM_NUM_30: | ||
489 | return "21-30"; | ||
490 | case ATH10K_AMPDU_SUBFRM_NUM_40: | ||
491 | return "31-40"; | ||
492 | case ATH10K_AMPDU_SUBFRM_NUM_50: | ||
493 | return "41-50"; | ||
494 | case ATH10K_AMPDU_SUBFRM_NUM_60: | ||
495 | return "51-60"; | ||
496 | case ATH10K_AMPDU_SUBFRM_NUM_MORE: | ||
497 | return ">60"; | ||
498 | case ATH10K_AMPDU_SUBFRM_NUM_MAX: | ||
499 | return "0"; | ||
500 | } | ||
501 | |||
502 | return "0"; | ||
503 | } | ||
504 | |||
505 | static char *get_num_amsdu_subfrm_str(enum ath10k_amsdu_subfrm_num i) | ||
506 | { | ||
507 | switch (i) { | ||
508 | case ATH10K_AMSDU_SUBFRM_NUM_1: | ||
509 | return "1"; | ||
510 | case ATH10K_AMSDU_SUBFRM_NUM_2: | ||
511 | return "2"; | ||
512 | case ATH10K_AMSDU_SUBFRM_NUM_3: | ||
513 | return "3"; | ||
514 | case ATH10K_AMSDU_SUBFRM_NUM_4: | ||
515 | return "4"; | ||
516 | case ATH10K_AMSDU_SUBFRM_NUM_MORE: | ||
517 | return ">4"; | ||
518 | case ATH10K_AMSDU_SUBFRM_NUM_MAX: | ||
519 | return "0"; | ||
520 | } | ||
521 | |||
522 | return "0"; | ||
523 | } | ||
524 | |||
525 | #define PRINT_TID_STATS(_field, _tabs) \ | ||
526 | do { \ | ||
527 | int k = 0; \ | ||
528 | for (j = 0; j <= IEEE80211_NUM_TIDS; j++) { \ | ||
529 | if (ar->sta_tid_stats_mask & BIT(j)) { \ | ||
530 | len += scnprintf(buf + len, buf_len - len, \ | ||
531 | "[%02d] %-10lu ", \ | ||
532 | j, stats[j]._field); \ | ||
533 | k++; \ | ||
534 | if (k % 8 == 0) { \ | ||
535 | len += scnprintf(buf + len, \ | ||
536 | buf_len - len, "\n"); \ | ||
537 | len += scnprintf(buf + len, \ | ||
538 | buf_len - len, \ | ||
539 | _tabs); \ | ||
540 | } \ | ||
541 | } \ | ||
542 | } \ | ||
543 | len += scnprintf(buf + len, buf_len - len, "\n"); \ | ||
544 | } while (0) | ||
545 | |||
546 | static ssize_t ath10k_dbg_sta_read_tid_stats(struct file *file, | ||
547 | char __user *user_buf, | ||
548 | size_t count, loff_t *ppos) | ||
549 | { | ||
550 | struct ieee80211_sta *sta = file->private_data; | ||
551 | struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; | ||
552 | struct ath10k *ar = arsta->arvif->ar; | ||
553 | struct ath10k_sta_tid_stats *stats = arsta->tid_stats; | ||
554 | size_t len = 0, buf_len = 1048 * IEEE80211_NUM_TIDS; | ||
555 | char *buf; | ||
556 | int i, j; | ||
557 | ssize_t ret; | ||
558 | |||
559 | buf = kzalloc(buf_len, GFP_KERNEL); | ||
560 | if (!buf) | ||
561 | return -ENOMEM; | ||
562 | |||
563 | mutex_lock(&ar->conf_mutex); | ||
564 | |||
565 | spin_lock_bh(&ar->data_lock); | ||
566 | |||
567 | len += scnprintf(buf + len, buf_len - len, | ||
568 | "\n\t\tDriver Rx pkt stats per tid, ([tid] count)\n"); | ||
569 | len += scnprintf(buf + len, buf_len - len, | ||
570 | "\t\t------------------------------------------\n"); | ||
571 | len += scnprintf(buf + len, buf_len - len, "MSDUs from FW\t\t\t"); | ||
572 | PRINT_TID_STATS(rx_pkt_from_fw, "\t\t\t\t"); | ||
573 | |||
574 | len += scnprintf(buf + len, buf_len - len, "MSDUs unchained\t\t\t"); | ||
575 | PRINT_TID_STATS(rx_pkt_unchained, "\t\t\t\t"); | ||
576 | |||
577 | len += scnprintf(buf + len, buf_len - len, | ||
578 | "MSDUs locally dropped:chained\t"); | ||
579 | PRINT_TID_STATS(rx_pkt_drop_chained, "\t\t\t\t"); | ||
580 | |||
581 | len += scnprintf(buf + len, buf_len - len, | ||
582 | "MSDUs locally dropped:filtered\t"); | ||
583 | PRINT_TID_STATS(rx_pkt_drop_filter, "\t\t\t\t"); | ||
584 | |||
585 | len += scnprintf(buf + len, buf_len - len, | ||
586 | "MSDUs queued for mac80211\t"); | ||
587 | PRINT_TID_STATS(rx_pkt_queued_for_mac, "\t\t\t\t"); | ||
588 | |||
589 | for (i = 0; i < ATH10K_PKT_RX_ERR_MAX; i++) { | ||
590 | len += scnprintf(buf + len, buf_len - len, | ||
591 | "MSDUs with error:%s\t", get_err_str(i)); | ||
592 | PRINT_TID_STATS(rx_pkt_err[i], "\t\t\t\t"); | ||
593 | } | ||
594 | |||
595 | len += scnprintf(buf + len, buf_len - len, "\n"); | ||
596 | for (i = 0; i < ATH10K_AMPDU_SUBFRM_NUM_MAX; i++) { | ||
597 | len += scnprintf(buf + len, buf_len - len, | ||
598 | "A-MPDU num subframes %s\t", | ||
599 | get_num_ampdu_subfrm_str(i)); | ||
600 | PRINT_TID_STATS(rx_pkt_ampdu[i], "\t\t\t\t"); | ||
601 | } | ||
602 | |||
603 | len += scnprintf(buf + len, buf_len - len, "\n"); | ||
604 | for (i = 0; i < ATH10K_AMSDU_SUBFRM_NUM_MAX; i++) { | ||
605 | len += scnprintf(buf + len, buf_len - len, | ||
606 | "A-MSDU num subframes %s\t\t", | ||
607 | get_num_amsdu_subfrm_str(i)); | ||
608 | PRINT_TID_STATS(rx_pkt_amsdu[i], "\t\t\t\t"); | ||
609 | } | ||
610 | |||
611 | spin_unlock_bh(&ar->data_lock); | ||
612 | |||
613 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
614 | |||
615 | kfree(buf); | ||
616 | |||
617 | mutex_unlock(&ar->conf_mutex); | ||
618 | |||
619 | return ret; | ||
620 | } | ||
621 | |||
622 | static const struct file_operations fops_tid_stats_dump = { | ||
623 | .open = simple_open, | ||
624 | .read = ath10k_dbg_sta_read_tid_stats, | ||
625 | .owner = THIS_MODULE, | ||
626 | .llseek = default_llseek, | ||
627 | }; | ||
628 | |||
345 | void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 629 | void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
346 | struct ieee80211_sta *sta, struct dentry *dir) | 630 | struct ieee80211_sta *sta, struct dentry *dir) |
347 | { | 631 | { |
@@ -351,4 +635,6 @@ void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
351 | debugfs_create_file("delba", 0200, dir, sta, &fops_delba); | 635 | debugfs_create_file("delba", 0200, dir, sta, &fops_delba); |
352 | debugfs_create_file("peer_debug_trigger", 0600, dir, sta, | 636 | debugfs_create_file("peer_debug_trigger", 0600, dir, sta, |
353 | &fops_peer_debug_trigger); | 637 | &fops_peer_debug_trigger); |
638 | debugfs_create_file("dump_tid_stats", 0400, dir, sta, | ||
639 | &fops_tid_stats_dump); | ||
354 | } | 640 | } |
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 6d96f9560950..5e02e26158f6 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | 3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
4 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -723,6 +724,28 @@ struct amsdu_subframe_hdr { | |||
723 | 724 | ||
724 | #define GROUP_ID_IS_SU_MIMO(x) ((x) == 0 || (x) == 63) | 725 | #define GROUP_ID_IS_SU_MIMO(x) ((x) == 0 || (x) == 63) |
725 | 726 | ||
727 | static inline u8 ath10k_bw_to_mac80211_bw(u8 bw) | ||
728 | { | ||
729 | u8 ret = 0; | ||
730 | |||
731 | switch (bw) { | ||
732 | case 0: | ||
733 | ret = RATE_INFO_BW_20; | ||
734 | break; | ||
735 | case 1: | ||
736 | ret = RATE_INFO_BW_40; | ||
737 | break; | ||
738 | case 2: | ||
739 | ret = RATE_INFO_BW_80; | ||
740 | break; | ||
741 | case 3: | ||
742 | ret = RATE_INFO_BW_160; | ||
743 | break; | ||
744 | } | ||
745 | |||
746 | return ret; | ||
747 | } | ||
748 | |||
726 | static void ath10k_htt_rx_h_rates(struct ath10k *ar, | 749 | static void ath10k_htt_rx_h_rates(struct ath10k *ar, |
727 | struct ieee80211_rx_status *status, | 750 | struct ieee80211_rx_status *status, |
728 | struct htt_rx_desc *rxd) | 751 | struct htt_rx_desc *rxd) |
@@ -825,23 +848,7 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, | |||
825 | if (sgi) | 848 | if (sgi) |
826 | status->enc_flags |= RX_ENC_FLAG_SHORT_GI; | 849 | status->enc_flags |= RX_ENC_FLAG_SHORT_GI; |
827 | 850 | ||
828 | switch (bw) { | 851 | status->bw = ath10k_bw_to_mac80211_bw(bw); |
829 | /* 20MHZ */ | ||
830 | case 0: | ||
831 | break; | ||
832 | /* 40MHZ */ | ||
833 | case 1: | ||
834 | status->bw = RATE_INFO_BW_40; | ||
835 | break; | ||
836 | /* 80MHZ */ | ||
837 | case 2: | ||
838 | status->bw = RATE_INFO_BW_80; | ||
839 | break; | ||
840 | case 3: | ||
841 | status->bw = RATE_INFO_BW_160; | ||
842 | break; | ||
843 | } | ||
844 | |||
845 | status->encoding = RX_ENC_VHT; | 852 | status->encoding = RX_ENC_VHT; |
846 | break; | 853 | break; |
847 | default: | 854 | default: |
@@ -1502,7 +1509,9 @@ static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu) | |||
1502 | static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, | 1509 | static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, |
1503 | struct sk_buff_head *amsdu, | 1510 | struct sk_buff_head *amsdu, |
1504 | struct ieee80211_rx_status *status, | 1511 | struct ieee80211_rx_status *status, |
1505 | bool fill_crypt_header) | 1512 | bool fill_crypt_header, |
1513 | u8 *rx_hdr, | ||
1514 | enum ath10k_pkt_rx_err *err) | ||
1506 | { | 1515 | { |
1507 | struct sk_buff *first; | 1516 | struct sk_buff *first; |
1508 | struct sk_buff *last; | 1517 | struct sk_buff *last; |
@@ -1538,6 +1547,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, | |||
1538 | hdr = (void *)rxd->rx_hdr_status; | 1547 | hdr = (void *)rxd->rx_hdr_status; |
1539 | memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN); | 1548 | memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN); |
1540 | 1549 | ||
1550 | if (rx_hdr) | ||
1551 | memcpy(rx_hdr, hdr, RX_HTT_HDR_STATUS_LEN); | ||
1552 | |||
1541 | /* Each A-MSDU subframe will use the original header as the base and be | 1553 | /* Each A-MSDU subframe will use the original header as the base and be |
1542 | * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl. | 1554 | * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl. |
1543 | */ | 1555 | */ |
@@ -1581,6 +1593,17 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, | |||
1581 | if (has_tkip_err) | 1593 | if (has_tkip_err) |
1582 | status->flag |= RX_FLAG_MMIC_ERROR; | 1594 | status->flag |= RX_FLAG_MMIC_ERROR; |
1583 | 1595 | ||
1596 | if (err) { | ||
1597 | if (has_fcs_err) | ||
1598 | *err = ATH10K_PKT_RX_ERR_FCS; | ||
1599 | else if (has_tkip_err) | ||
1600 | *err = ATH10K_PKT_RX_ERR_TKIP; | ||
1601 | else if (has_crypto_err) | ||
1602 | *err = ATH10K_PKT_RX_ERR_CRYPT; | ||
1603 | else if (has_peer_idx_invalid) | ||
1604 | *err = ATH10K_PKT_RX_ERR_PEER_IDX_INVAL; | ||
1605 | } | ||
1606 | |||
1584 | /* Firmware reports all necessary management frames via WMI already. | 1607 | /* Firmware reports all necessary management frames via WMI already. |
1585 | * They are not reported to monitor interfaces at all so pass the ones | 1608 | * They are not reported to monitor interfaces at all so pass the ones |
1586 | * coming via HTT to monitor interfaces instead. This simplifies | 1609 | * coming via HTT to monitor interfaces instead. This simplifies |
@@ -1651,11 +1674,13 @@ static void ath10k_htt_rx_h_enqueue(struct ath10k *ar, | |||
1651 | } | 1674 | } |
1652 | } | 1675 | } |
1653 | 1676 | ||
1654 | static int ath10k_unchain_msdu(struct sk_buff_head *amsdu) | 1677 | static int ath10k_unchain_msdu(struct sk_buff_head *amsdu, |
1678 | unsigned long int *unchain_cnt) | ||
1655 | { | 1679 | { |
1656 | struct sk_buff *skb, *first; | 1680 | struct sk_buff *skb, *first; |
1657 | int space; | 1681 | int space; |
1658 | int total_len = 0; | 1682 | int total_len = 0; |
1683 | int amsdu_len = skb_queue_len(amsdu); | ||
1659 | 1684 | ||
1660 | /* TODO: Might could optimize this by using | 1685 | /* TODO: Might could optimize this by using |
1661 | * skb_try_coalesce or similar method to | 1686 | * skb_try_coalesce or similar method to |
@@ -1691,11 +1716,16 @@ static int ath10k_unchain_msdu(struct sk_buff_head *amsdu) | |||
1691 | } | 1716 | } |
1692 | 1717 | ||
1693 | __skb_queue_head(amsdu, first); | 1718 | __skb_queue_head(amsdu, first); |
1719 | |||
1720 | *unchain_cnt += amsdu_len - 1; | ||
1721 | |||
1694 | return 0; | 1722 | return 0; |
1695 | } | 1723 | } |
1696 | 1724 | ||
1697 | static void ath10k_htt_rx_h_unchain(struct ath10k *ar, | 1725 | static void ath10k_htt_rx_h_unchain(struct ath10k *ar, |
1698 | struct sk_buff_head *amsdu) | 1726 | struct sk_buff_head *amsdu, |
1727 | unsigned long int *drop_cnt, | ||
1728 | unsigned long int *unchain_cnt) | ||
1699 | { | 1729 | { |
1700 | struct sk_buff *first; | 1730 | struct sk_buff *first; |
1701 | struct htt_rx_desc *rxd; | 1731 | struct htt_rx_desc *rxd; |
@@ -1713,11 +1743,12 @@ static void ath10k_htt_rx_h_unchain(struct ath10k *ar, | |||
1713 | */ | 1743 | */ |
1714 | if (decap != RX_MSDU_DECAP_RAW || | 1744 | if (decap != RX_MSDU_DECAP_RAW || |
1715 | skb_queue_len(amsdu) != 1 + rxd->frag_info.ring2_more_count) { | 1745 | skb_queue_len(amsdu) != 1 + rxd->frag_info.ring2_more_count) { |
1746 | *drop_cnt += skb_queue_len(amsdu); | ||
1716 | __skb_queue_purge(amsdu); | 1747 | __skb_queue_purge(amsdu); |
1717 | return; | 1748 | return; |
1718 | } | 1749 | } |
1719 | 1750 | ||
1720 | ath10k_unchain_msdu(amsdu); | 1751 | ath10k_unchain_msdu(amsdu, unchain_cnt); |
1721 | } | 1752 | } |
1722 | 1753 | ||
1723 | static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, | 1754 | static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, |
@@ -1743,7 +1774,8 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, | |||
1743 | 1774 | ||
1744 | static void ath10k_htt_rx_h_filter(struct ath10k *ar, | 1775 | static void ath10k_htt_rx_h_filter(struct ath10k *ar, |
1745 | struct sk_buff_head *amsdu, | 1776 | struct sk_buff_head *amsdu, |
1746 | struct ieee80211_rx_status *rx_status) | 1777 | struct ieee80211_rx_status *rx_status, |
1778 | unsigned long int *drop_cnt) | ||
1747 | { | 1779 | { |
1748 | if (skb_queue_empty(amsdu)) | 1780 | if (skb_queue_empty(amsdu)) |
1749 | return; | 1781 | return; |
@@ -1751,6 +1783,9 @@ static void ath10k_htt_rx_h_filter(struct ath10k *ar, | |||
1751 | if (ath10k_htt_rx_amsdu_allowed(ar, amsdu, rx_status)) | 1783 | if (ath10k_htt_rx_amsdu_allowed(ar, amsdu, rx_status)) |
1752 | return; | 1784 | return; |
1753 | 1785 | ||
1786 | if (drop_cnt) | ||
1787 | *drop_cnt += skb_queue_len(amsdu); | ||
1788 | |||
1754 | __skb_queue_purge(amsdu); | 1789 | __skb_queue_purge(amsdu); |
1755 | } | 1790 | } |
1756 | 1791 | ||
@@ -1760,6 +1795,12 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) | |||
1760 | struct ieee80211_rx_status *rx_status = &htt->rx_status; | 1795 | struct ieee80211_rx_status *rx_status = &htt->rx_status; |
1761 | struct sk_buff_head amsdu; | 1796 | struct sk_buff_head amsdu; |
1762 | int ret; | 1797 | int ret; |
1798 | unsigned long int drop_cnt = 0; | ||
1799 | unsigned long int unchain_cnt = 0; | ||
1800 | unsigned long int drop_cnt_filter = 0; | ||
1801 | unsigned long int msdus_to_queue, num_msdus; | ||
1802 | enum ath10k_pkt_rx_err err = ATH10K_PKT_RX_ERR_MAX; | ||
1803 | u8 first_hdr[RX_HTT_HDR_STATUS_LEN]; | ||
1763 | 1804 | ||
1764 | __skb_queue_head_init(&amsdu); | 1805 | __skb_queue_head_init(&amsdu); |
1765 | 1806 | ||
@@ -1781,16 +1822,23 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) | |||
1781 | return ret; | 1822 | return ret; |
1782 | } | 1823 | } |
1783 | 1824 | ||
1825 | num_msdus = skb_queue_len(&amsdu); | ||
1826 | |||
1784 | ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); | 1827 | ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); |
1785 | 1828 | ||
1786 | /* only for ret = 1 indicates chained msdus */ | 1829 | /* only for ret = 1 indicates chained msdus */ |
1787 | if (ret > 0) | 1830 | if (ret > 0) |
1788 | ath10k_htt_rx_h_unchain(ar, &amsdu); | 1831 | ath10k_htt_rx_h_unchain(ar, &amsdu, &drop_cnt, &unchain_cnt); |
1789 | 1832 | ||
1790 | ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); | 1833 | ath10k_htt_rx_h_filter(ar, &amsdu, rx_status, &drop_cnt_filter); |
1791 | ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true); | 1834 | ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err); |
1835 | msdus_to_queue = skb_queue_len(&amsdu); | ||
1792 | ath10k_htt_rx_h_enqueue(ar, &amsdu, rx_status); | 1836 | ath10k_htt_rx_h_enqueue(ar, &amsdu, rx_status); |
1793 | 1837 | ||
1838 | ath10k_sta_update_rx_tid_stats(ar, first_hdr, num_msdus, err, | ||
1839 | unchain_cnt, drop_cnt, drop_cnt_filter, | ||
1840 | msdus_to_queue); | ||
1841 | |||
1794 | return 0; | 1842 | return 0; |
1795 | } | 1843 | } |
1796 | 1844 | ||
@@ -1801,9 +1849,14 @@ static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt, | |||
1801 | struct htt_rx_indication_mpdu_range *mpdu_ranges; | 1849 | struct htt_rx_indication_mpdu_range *mpdu_ranges; |
1802 | int num_mpdu_ranges; | 1850 | int num_mpdu_ranges; |
1803 | int i, mpdu_count = 0; | 1851 | int i, mpdu_count = 0; |
1852 | u16 peer_id; | ||
1853 | u8 tid; | ||
1804 | 1854 | ||
1805 | num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1), | 1855 | num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1), |
1806 | HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); | 1856 | HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); |
1857 | peer_id = __le16_to_cpu(rx->hdr.peer_id); | ||
1858 | tid = MS(rx->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID); | ||
1859 | |||
1807 | mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx); | 1860 | mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx); |
1808 | 1861 | ||
1809 | ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", | 1862 | ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", |
@@ -1815,6 +1868,9 @@ static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt, | |||
1815 | mpdu_count += mpdu_ranges[i].mpdu_count; | 1868 | mpdu_count += mpdu_ranges[i].mpdu_count; |
1816 | 1869 | ||
1817 | atomic_add(mpdu_count, &htt->num_mpdus_ready); | 1870 | atomic_add(mpdu_count, &htt->num_mpdus_ready); |
1871 | |||
1872 | ath10k_sta_update_rx_tid_stats_ampdu(ar, peer_id, tid, mpdu_ranges, | ||
1873 | num_mpdu_ranges); | ||
1818 | } | 1874 | } |
1819 | 1875 | ||
1820 | static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, | 1876 | static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, |
@@ -2124,8 +2180,9 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) | |||
2124 | * should still give an idea about rx rate to the user. | 2180 | * should still give an idea about rx rate to the user. |
2125 | */ | 2181 | */ |
2126 | ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); | 2182 | ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); |
2127 | ath10k_htt_rx_h_filter(ar, &amsdu, status); | 2183 | ath10k_htt_rx_h_filter(ar, &amsdu, status, NULL); |
2128 | ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false); | 2184 | ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false, NULL, |
2185 | NULL); | ||
2129 | ath10k_htt_rx_h_enqueue(ar, &amsdu, status); | 2186 | ath10k_htt_rx_h_enqueue(ar, &amsdu, status); |
2130 | break; | 2187 | break; |
2131 | case -EAGAIN: | 2188 | case -EAGAIN: |
@@ -2499,7 +2556,7 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar, | |||
2499 | arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; | 2556 | arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; |
2500 | 2557 | ||
2501 | arsta->txrate.nss = txrate.nss; | 2558 | arsta->txrate.nss = txrate.nss; |
2502 | arsta->txrate.bw = txrate.bw + RATE_INFO_BW_20; | 2559 | arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw); |
2503 | } | 2560 | } |
2504 | 2561 | ||
2505 | static void ath10k_htt_fetch_peer_stats(struct ath10k *ar, | 2562 | static void ath10k_htt_fetch_peer_stats(struct ath10k *ar, |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index ebb3f1b046f3..bf05a3689558 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | 3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
4 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -2976,7 +2977,7 @@ static int ath10k_station_assoc(struct ath10k *ar, | |||
2976 | } | 2977 | } |
2977 | 2978 | ||
2978 | /* Plumb cached keys only for static WEP */ | 2979 | /* Plumb cached keys only for static WEP */ |
2979 | if (arvif->def_wep_key_idx != -1) { | 2980 | if ((arvif->def_wep_key_idx != -1) && (!sta->tdls)) { |
2980 | ret = ath10k_install_peer_wep_keys(arvif, sta->addr); | 2981 | ret = ath10k_install_peer_wep_keys(arvif, sta->addr); |
2981 | if (ret) { | 2982 | if (ret) { |
2982 | ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", | 2983 | ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", |
@@ -3808,6 +3809,7 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work) | |||
3808 | { | 3809 | { |
3809 | struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work); | 3810 | struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work); |
3810 | struct sk_buff *skb; | 3811 | struct sk_buff *skb; |
3812 | dma_addr_t paddr; | ||
3811 | int ret; | 3813 | int ret; |
3812 | 3814 | ||
3813 | for (;;) { | 3815 | for (;;) { |
@@ -3815,11 +3817,27 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work) | |||
3815 | if (!skb) | 3817 | if (!skb) |
3816 | break; | 3818 | break; |
3817 | 3819 | ||
3818 | ret = ath10k_wmi_mgmt_tx(ar, skb); | 3820 | if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF, |
3819 | if (ret) { | 3821 | ar->running_fw->fw_file.fw_features)) { |
3820 | ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n", | 3822 | paddr = dma_map_single(ar->dev, skb->data, |
3821 | ret); | 3823 | skb->len, DMA_TO_DEVICE); |
3822 | ieee80211_free_txskb(ar->hw, skb); | 3824 | if (!paddr) |
3825 | continue; | ||
3826 | ret = ath10k_wmi_mgmt_tx_send(ar, skb, paddr); | ||
3827 | if (ret) { | ||
3828 | ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n", | ||
3829 | ret); | ||
3830 | dma_unmap_single(ar->dev, paddr, skb->len, | ||
3831 | DMA_FROM_DEVICE); | ||
3832 | ieee80211_free_txskb(ar->hw, skb); | ||
3833 | } | ||
3834 | } else { | ||
3835 | ret = ath10k_wmi_mgmt_tx(ar, skb); | ||
3836 | if (ret) { | ||
3837 | ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n", | ||
3838 | ret); | ||
3839 | ieee80211_free_txskb(ar->hw, skb); | ||
3840 | } | ||
3823 | } | 3841 | } |
3824 | } | 3842 | } |
3825 | } | 3843 | } |
@@ -5914,6 +5932,10 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
5914 | ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr); | 5932 | ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr); |
5915 | spin_unlock_bh(&ar->data_lock); | 5933 | spin_unlock_bh(&ar->data_lock); |
5916 | 5934 | ||
5935 | if (sta && sta->tdls) | ||
5936 | ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, | ||
5937 | WMI_PEER_AUTHORIZE, 1); | ||
5938 | |||
5917 | exit: | 5939 | exit: |
5918 | mutex_unlock(&ar->conf_mutex); | 5940 | mutex_unlock(&ar->conf_mutex); |
5919 | return ret; | 5941 | return ret; |
@@ -6028,9 +6050,8 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk) | |||
6028 | sta->addr, smps, err); | 6050 | sta->addr, smps, err); |
6029 | } | 6051 | } |
6030 | 6052 | ||
6031 | if (changed & IEEE80211_RC_SUPP_RATES_CHANGED || | 6053 | if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { |
6032 | changed & IEEE80211_RC_NSS_CHANGED) { | 6054 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n", |
6033 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n", | ||
6034 | sta->addr); | 6055 | sta->addr); |
6035 | 6056 | ||
6036 | err = ath10k_station_assoc(ar, arvif->vif, sta, true); | 6057 | err = ath10k_station_assoc(ar, arvif->vif, sta, true); |
@@ -7085,10 +7106,20 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, | |||
7085 | { | 7106 | { |
7086 | struct ath10k *ar = hw->priv; | 7107 | struct ath10k *ar = hw->priv; |
7087 | struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; | 7108 | struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; |
7109 | struct ath10k_vif *arvif = (void *)vif->drv_priv; | ||
7110 | struct ath10k_peer *peer; | ||
7088 | u32 bw, smps; | 7111 | u32 bw, smps; |
7089 | 7112 | ||
7090 | spin_lock_bh(&ar->data_lock); | 7113 | spin_lock_bh(&ar->data_lock); |
7091 | 7114 | ||
7115 | peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr); | ||
7116 | if (!peer) { | ||
7117 | spin_unlock_bh(&ar->data_lock); | ||
7118 | ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n", | ||
7119 | sta->addr, arvif->vdev_id); | ||
7120 | return; | ||
7121 | } | ||
7122 | |||
7092 | ath10k_dbg(ar, ATH10K_DBG_MAC, | 7123 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
7093 | "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n", | 7124 | "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n", |
7094 | sta->addr, changed, sta->bandwidth, sta->rx_nss, | 7125 | sta->addr, changed, sta->bandwidth, sta->rx_nss, |
@@ -7874,6 +7905,7 @@ static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = { | |||
7874 | .max_interfaces = 8, | 7905 | .max_interfaces = 8, |
7875 | .num_different_channels = 1, | 7906 | .num_different_channels = 1, |
7876 | .beacon_int_infra_match = true, | 7907 | .beacon_int_infra_match = true, |
7908 | .beacon_int_min_gcd = 1, | ||
7877 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED | 7909 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED |
7878 | .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | | 7910 | .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | |
7879 | BIT(NL80211_CHAN_WIDTH_20) | | 7911 | BIT(NL80211_CHAN_WIDTH_20) | |
@@ -7997,6 +8029,7 @@ static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = { | |||
7997 | .max_interfaces = 16, | 8029 | .max_interfaces = 16, |
7998 | .num_different_channels = 1, | 8030 | .num_different_channels = 1, |
7999 | .beacon_int_infra_match = true, | 8031 | .beacon_int_infra_match = true, |
8032 | .beacon_int_min_gcd = 1, | ||
8000 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED | 8033 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED |
8001 | .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | | 8034 | .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | |
8002 | BIT(NL80211_CHAN_WIDTH_20) | | 8035 | BIT(NL80211_CHAN_WIDTH_20) | |
@@ -8298,6 +8331,9 @@ int ath10k_mac_register(struct ath10k *ar) | |||
8298 | ieee80211_hw_set(ar->hw, TDLS_WIDER_BW); | 8331 | ieee80211_hw_set(ar->hw, TDLS_WIDER_BW); |
8299 | } | 8332 | } |
8300 | 8333 | ||
8334 | if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map)) | ||
8335 | ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA); | ||
8336 | |||
8301 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 8337 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
8302 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; | 8338 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; |
8303 | ar->hw->wiphy->max_remain_on_channel_duration = 5000; | 8339 | ar->hw->wiphy->max_remain_on_channel_duration = 5000; |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 1b266cd0c2ec..fd1566cd7d2b 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
@@ -57,6 +57,10 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)"); | |||
57 | */ | 57 | */ |
58 | #define ATH10K_DIAG_TRANSFER_LIMIT 0x5000 | 58 | #define ATH10K_DIAG_TRANSFER_LIMIT 0x5000 |
59 | 59 | ||
60 | #define QCA99X0_PCIE_BAR0_START_REG 0x81030 | ||
61 | #define QCA99X0_CPU_MEM_ADDR_REG 0x4d00c | ||
62 | #define QCA99X0_CPU_MEM_DATA_REG 0x4d010 | ||
63 | |||
60 | static const struct pci_device_id ath10k_pci_id_table[] = { | 64 | static const struct pci_device_id ath10k_pci_id_table[] = { |
61 | /* PCI-E QCA988X V2 (Ubiquiti branded) */ | 65 | /* PCI-E QCA988X V2 (Ubiquiti branded) */ |
62 | { PCI_VDEVICE(UBIQUITI, QCA988X_2_0_DEVICE_ID_UBNT) }, | 66 | { PCI_VDEVICE(UBIQUITI, QCA988X_2_0_DEVICE_ID_UBNT) }, |
@@ -1584,6 +1588,69 @@ static int ath10k_pci_set_ram_config(struct ath10k *ar, u32 config) | |||
1584 | return 0; | 1588 | return 0; |
1585 | } | 1589 | } |
1586 | 1590 | ||
1591 | /* if an error happened returns < 0, otherwise the length */ | ||
1592 | static int ath10k_pci_dump_memory_sram(struct ath10k *ar, | ||
1593 | const struct ath10k_mem_region *region, | ||
1594 | u8 *buf) | ||
1595 | { | ||
1596 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
1597 | u32 base_addr, i; | ||
1598 | |||
1599 | base_addr = ioread32(ar_pci->mem + QCA99X0_PCIE_BAR0_START_REG); | ||
1600 | base_addr += region->start; | ||
1601 | |||
1602 | for (i = 0; i < region->len; i += 4) { | ||
1603 | iowrite32(base_addr + i, ar_pci->mem + QCA99X0_CPU_MEM_ADDR_REG); | ||
1604 | *(u32 *)(buf + i) = ioread32(ar_pci->mem + QCA99X0_CPU_MEM_DATA_REG); | ||
1605 | } | ||
1606 | |||
1607 | return region->len; | ||
1608 | } | ||
1609 | |||
1610 | /* if an error happened returns < 0, otherwise the length */ | ||
1611 | static int ath10k_pci_dump_memory_reg(struct ath10k *ar, | ||
1612 | const struct ath10k_mem_region *region, | ||
1613 | u8 *buf) | ||
1614 | { | ||
1615 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
1616 | u32 i; | ||
1617 | |||
1618 | for (i = 0; i < region->len; i += 4) | ||
1619 | *(u32 *)(buf + i) = ioread32(ar_pci->mem + region->start + i); | ||
1620 | |||
1621 | return region->len; | ||
1622 | } | ||
1623 | |||
1624 | /* if an error happened returns < 0, otherwise the length */ | ||
1625 | static int ath10k_pci_dump_memory_generic(struct ath10k *ar, | ||
1626 | const struct ath10k_mem_region *current_region, | ||
1627 | u8 *buf) | ||
1628 | { | ||
1629 | int ret; | ||
1630 | |||
1631 | if (current_region->section_table.size > 0) | ||
1632 | /* Copy each section individually. */ | ||
1633 | return ath10k_pci_dump_memory_section(ar, | ||
1634 | current_region, | ||
1635 | buf, | ||
1636 | current_region->len); | ||
1637 | |||
1638 | /* No individiual memory sections defined so we can | ||
1639 | * copy the entire memory region. | ||
1640 | */ | ||
1641 | ret = ath10k_pci_diag_read_mem(ar, | ||
1642 | current_region->start, | ||
1643 | buf, | ||
1644 | current_region->len); | ||
1645 | if (ret) { | ||
1646 | ath10k_warn(ar, "failed to copy ramdump region %s: %d\n", | ||
1647 | current_region->name, ret); | ||
1648 | return ret; | ||
1649 | } | ||
1650 | |||
1651 | return current_region->len; | ||
1652 | } | ||
1653 | |||
1587 | static void ath10k_pci_dump_memory(struct ath10k *ar, | 1654 | static void ath10k_pci_dump_memory(struct ath10k *ar, |
1588 | struct ath10k_fw_crash_data *crash_data) | 1655 | struct ath10k_fw_crash_data *crash_data) |
1589 | { | 1656 | { |
@@ -1642,27 +1709,20 @@ static void ath10k_pci_dump_memory(struct ath10k *ar, | |||
1642 | buf += sizeof(*hdr); | 1709 | buf += sizeof(*hdr); |
1643 | buf_len -= sizeof(*hdr); | 1710 | buf_len -= sizeof(*hdr); |
1644 | 1711 | ||
1645 | if (current_region->section_table.size > 0) { | 1712 | switch (current_region->type) { |
1646 | /* Copy each section individually. */ | 1713 | case ATH10K_MEM_REGION_TYPE_IOSRAM: |
1647 | count = ath10k_pci_dump_memory_section(ar, | 1714 | count = ath10k_pci_dump_memory_sram(ar, current_region, buf); |
1648 | current_region, | 1715 | break; |
1649 | buf, | 1716 | case ATH10K_MEM_REGION_TYPE_IOREG: |
1650 | current_region->len); | 1717 | count = ath10k_pci_dump_memory_reg(ar, current_region, buf); |
1651 | } else { | 1718 | break; |
1652 | /* No individiual memory sections defined so we can | 1719 | default: |
1653 | * copy the entire memory region. | 1720 | ret = ath10k_pci_dump_memory_generic(ar, current_region, buf); |
1654 | */ | 1721 | if (ret < 0) |
1655 | ret = ath10k_pci_diag_read_mem(ar, | ||
1656 | current_region->start, | ||
1657 | buf, | ||
1658 | current_region->len); | ||
1659 | if (ret) { | ||
1660 | ath10k_warn(ar, "failed to copy ramdump region %s: %d\n", | ||
1661 | current_region->name, ret); | ||
1662 | break; | 1722 | break; |
1663 | } | ||
1664 | 1723 | ||
1665 | count = current_region->len; | 1724 | count = ret; |
1725 | break; | ||
1666 | } | 1726 | } |
1667 | 1727 | ||
1668 | hdr->region_type = cpu_to_le32(current_region->type); | 1728 | hdr->region_type = cpu_to_le32(current_region->type); |
@@ -2221,7 +2281,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar) | |||
2221 | } | 2281 | } |
2222 | break; | 2282 | break; |
2223 | case QCA9377_1_0_DEVICE_ID: | 2283 | case QCA9377_1_0_DEVICE_ID: |
2224 | return 4; | 2284 | return 9; |
2225 | } | 2285 | } |
2226 | 2286 | ||
2227 | ath10k_warn(ar, "unknown number of banks, assuming 1\n"); | 2287 | ath10k_warn(ar, "unknown number of banks, assuming 1\n"); |
@@ -3718,5 +3778,6 @@ MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" QCA6174_HW_3_0_BOARD_DATA_FILE); | |||
3718 | MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_BOARD_API2_FILE); | 3778 | MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_BOARD_API2_FILE); |
3719 | 3779 | ||
3720 | /* QCA9377 1.0 firmware files */ | 3780 | /* QCA9377 1.0 firmware files */ |
3781 | MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" ATH10K_FW_API6_FILE); | ||
3721 | MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" ATH10K_FW_API5_FILE); | 3782 | MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" ATH10K_FW_API5_FILE); |
3722 | MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" QCA9377_HW_1_0_BOARD_DATA_FILE); | 3783 | MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" QCA9377_HW_1_0_BOARD_DATA_FILE); |
diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index e40edced1d82..7d2fac342150 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h | |||
@@ -152,10 +152,9 @@ TRACE_EVENT(ath10k_log_dbg_dump, | |||
152 | ); | 152 | ); |
153 | 153 | ||
154 | TRACE_EVENT(ath10k_wmi_cmd, | 154 | TRACE_EVENT(ath10k_wmi_cmd, |
155 | TP_PROTO(struct ath10k *ar, int id, const void *buf, size_t buf_len, | 155 | TP_PROTO(struct ath10k *ar, int id, const void *buf, size_t buf_len), |
156 | int ret), | ||
157 | 156 | ||
158 | TP_ARGS(ar, id, buf, buf_len, ret), | 157 | TP_ARGS(ar, id, buf, buf_len), |
159 | 158 | ||
160 | TP_STRUCT__entry( | 159 | TP_STRUCT__entry( |
161 | __string(device, dev_name(ar->dev)) | 160 | __string(device, dev_name(ar->dev)) |
@@ -163,7 +162,6 @@ TRACE_EVENT(ath10k_wmi_cmd, | |||
163 | __field(unsigned int, id) | 162 | __field(unsigned int, id) |
164 | __field(size_t, buf_len) | 163 | __field(size_t, buf_len) |
165 | __dynamic_array(u8, buf, buf_len) | 164 | __dynamic_array(u8, buf, buf_len) |
166 | __field(int, ret) | ||
167 | ), | 165 | ), |
168 | 166 | ||
169 | TP_fast_assign( | 167 | TP_fast_assign( |
@@ -171,17 +169,15 @@ TRACE_EVENT(ath10k_wmi_cmd, | |||
171 | __assign_str(driver, dev_driver_string(ar->dev)); | 169 | __assign_str(driver, dev_driver_string(ar->dev)); |
172 | __entry->id = id; | 170 | __entry->id = id; |
173 | __entry->buf_len = buf_len; | 171 | __entry->buf_len = buf_len; |
174 | __entry->ret = ret; | ||
175 | memcpy(__get_dynamic_array(buf), buf, buf_len); | 172 | memcpy(__get_dynamic_array(buf), buf, buf_len); |
176 | ), | 173 | ), |
177 | 174 | ||
178 | TP_printk( | 175 | TP_printk( |
179 | "%s %s id %d len %zu ret %d", | 176 | "%s %s id %d len %zu", |
180 | __get_str(driver), | 177 | __get_str(driver), |
181 | __get_str(device), | 178 | __get_str(device), |
182 | __entry->id, | 179 | __entry->id, |
183 | __entry->buf_len, | 180 | __entry->buf_len |
184 | __entry->ret | ||
185 | ) | 181 | ) |
186 | ); | 182 | ); |
187 | 183 | ||
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index 5b3b021526ab..70e23bbf7171 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c | |||
@@ -102,11 +102,6 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, | |||
102 | memset(&info->status, 0, sizeof(info->status)); | 102 | memset(&info->status, 0, sizeof(info->status)); |
103 | trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id); | 103 | trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id); |
104 | 104 | ||
105 | if (tx_done->status == HTT_TX_COMPL_STATE_DISCARD) { | ||
106 | ieee80211_free_txskb(htt->ar->hw, msdu); | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 105 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
111 | info->flags |= IEEE80211_TX_STAT_ACK; | 106 | info->flags |= IEEE80211_TX_STAT_ACK; |
112 | 107 | ||
@@ -117,6 +112,13 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, | |||
117 | (info->flags & IEEE80211_TX_CTL_NO_ACK)) | 112 | (info->flags & IEEE80211_TX_CTL_NO_ACK)) |
118 | info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; | 113 | info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; |
119 | 114 | ||
115 | if (tx_done->status == HTT_TX_COMPL_STATE_DISCARD) { | ||
116 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | ||
117 | info->flags &= ~IEEE80211_TX_STAT_NOACK_TRANSMITTED; | ||
118 | else | ||
119 | info->flags &= ~IEEE80211_TX_STAT_ACK; | ||
120 | } | ||
121 | |||
120 | ieee80211_tx_status(htt->ar->hw, msdu); | 122 | ieee80211_tx_status(htt->ar->hw, msdu); |
121 | /* we do not own the msdu anymore */ | 123 | /* we do not own the msdu anymore */ |
122 | 124 | ||
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h index 14093cfdc505..c35e45340b4f 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-ops.h +++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | 3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
4 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -125,6 +126,9 @@ struct wmi_ops { | |||
125 | enum wmi_force_fw_hang_type type, | 126 | enum wmi_force_fw_hang_type type, |
126 | u32 delay_ms); | 127 | u32 delay_ms); |
127 | struct sk_buff *(*gen_mgmt_tx)(struct ath10k *ar, struct sk_buff *skb); | 128 | struct sk_buff *(*gen_mgmt_tx)(struct ath10k *ar, struct sk_buff *skb); |
129 | struct sk_buff *(*gen_mgmt_tx_send)(struct ath10k *ar, | ||
130 | struct sk_buff *skb, | ||
131 | dma_addr_t paddr); | ||
128 | struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u64 module_enable, | 132 | struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u64 module_enable, |
129 | u32 log_level); | 133 | u32 log_level); |
130 | struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter); | 134 | struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter); |
@@ -197,6 +201,9 @@ struct wmi_ops { | |||
197 | (struct ath10k *ar, | 201 | (struct ath10k *ar, |
198 | enum wmi_bss_survey_req_type type); | 202 | enum wmi_bss_survey_req_type type); |
199 | struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value); | 203 | struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value); |
204 | struct sk_buff *(*gen_pdev_get_tpc_table_cmdid)(struct ath10k *ar, | ||
205 | u32 param); | ||
206 | |||
200 | }; | 207 | }; |
201 | 208 | ||
202 | int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); | 209 | int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); |
@@ -372,12 +379,33 @@ ath10k_wmi_get_txbf_conf_scheme(struct ath10k *ar) | |||
372 | } | 379 | } |
373 | 380 | ||
374 | static inline int | 381 | static inline int |
382 | ath10k_wmi_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu, | ||
383 | dma_addr_t paddr) | ||
384 | { | ||
385 | struct sk_buff *skb; | ||
386 | int ret; | ||
387 | |||
388 | if (!ar->wmi.ops->gen_mgmt_tx_send) | ||
389 | return -EOPNOTSUPP; | ||
390 | |||
391 | skb = ar->wmi.ops->gen_mgmt_tx_send(ar, msdu, paddr); | ||
392 | if (IS_ERR(skb)) | ||
393 | return PTR_ERR(skb); | ||
394 | |||
395 | ret = ath10k_wmi_cmd_send(ar, skb, | ||
396 | ar->wmi.cmd->mgmt_tx_send_cmdid); | ||
397 | if (ret) | ||
398 | return ret; | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | static inline int | ||
375 | ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) | 404 | ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) |
376 | { | 405 | { |
377 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu); | 406 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu); |
378 | struct sk_buff *skb; | 407 | struct sk_buff *skb; |
379 | int ret; | 408 | int ret; |
380 | u32 mgmt_tx_cmdid; | ||
381 | 409 | ||
382 | if (!ar->wmi.ops->gen_mgmt_tx) | 410 | if (!ar->wmi.ops->gen_mgmt_tx) |
383 | return -EOPNOTSUPP; | 411 | return -EOPNOTSUPP; |
@@ -386,13 +414,8 @@ ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) | |||
386 | if (IS_ERR(skb)) | 414 | if (IS_ERR(skb)) |
387 | return PTR_ERR(skb); | 415 | return PTR_ERR(skb); |
388 | 416 | ||
389 | if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF, | 417 | ret = ath10k_wmi_cmd_send(ar, skb, |
390 | ar->running_fw->fw_file.fw_features)) | 418 | ar->wmi.cmd->mgmt_tx_cmdid); |
391 | mgmt_tx_cmdid = ar->wmi.cmd->mgmt_tx_send_cmdid; | ||
392 | else | ||
393 | mgmt_tx_cmdid = ar->wmi.cmd->mgmt_tx_cmdid; | ||
394 | |||
395 | ret = ath10k_wmi_cmd_send(ar, skb, mgmt_tx_cmdid); | ||
396 | if (ret) | 419 | if (ret) |
397 | return ret; | 420 | return ret; |
398 | 421 | ||
@@ -1425,4 +1448,21 @@ ath10k_wmi_echo(struct ath10k *ar, u32 value) | |||
1425 | return ath10k_wmi_cmd_send(ar, skb, wmi->cmd->echo_cmdid); | 1448 | return ath10k_wmi_cmd_send(ar, skb, wmi->cmd->echo_cmdid); |
1426 | } | 1449 | } |
1427 | 1450 | ||
1451 | static inline int | ||
1452 | ath10k_wmi_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param) | ||
1453 | { | ||
1454 | struct sk_buff *skb; | ||
1455 | |||
1456 | if (!ar->wmi.ops->gen_pdev_get_tpc_table_cmdid) | ||
1457 | return -EOPNOTSUPP; | ||
1458 | |||
1459 | skb = ar->wmi.ops->gen_pdev_get_tpc_table_cmdid(ar, param); | ||
1460 | |||
1461 | if (IS_ERR(skb)) | ||
1462 | return PTR_ERR(skb); | ||
1463 | |||
1464 | return ath10k_wmi_cmd_send(ar, skb, | ||
1465 | ar->wmi.cmd->pdev_get_tpc_table_cmdid); | ||
1466 | } | ||
1467 | |||
1428 | #endif | 1468 | #endif |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index ae77a007ae07..9d1b0a459069 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | 3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
4 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -412,6 +413,62 @@ static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar, | |||
412 | return 0; | 413 | return 0; |
413 | } | 414 | } |
414 | 415 | ||
416 | static int ath10k_wmi_tlv_event_temperature(struct ath10k *ar, | ||
417 | struct sk_buff *skb) | ||
418 | { | ||
419 | const struct wmi_tlv_pdev_temperature_event *ev; | ||
420 | |||
421 | ev = (struct wmi_tlv_pdev_temperature_event *)skb->data; | ||
422 | if (WARN_ON(skb->len < sizeof(*ev))) | ||
423 | return -EPROTO; | ||
424 | |||
425 | ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature)); | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb) | ||
430 | { | ||
431 | struct ieee80211_sta *station; | ||
432 | const struct wmi_tlv_tdls_peer_event *ev; | ||
433 | const void **tb; | ||
434 | struct ath10k_vif *arvif; | ||
435 | |||
436 | tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); | ||
437 | if (IS_ERR(tb)) { | ||
438 | ath10k_warn(ar, "tdls peer failed to parse tlv"); | ||
439 | return; | ||
440 | } | ||
441 | ev = tb[WMI_TLV_TAG_STRUCT_TDLS_PEER_EVENT]; | ||
442 | if (!ev) { | ||
443 | kfree(tb); | ||
444 | ath10k_warn(ar, "tdls peer NULL event"); | ||
445 | return; | ||
446 | } | ||
447 | |||
448 | switch (__le32_to_cpu(ev->peer_reason)) { | ||
449 | case WMI_TDLS_TEARDOWN_REASON_TX: | ||
450 | case WMI_TDLS_TEARDOWN_REASON_RSSI: | ||
451 | case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: | ||
452 | station = ieee80211_find_sta_by_ifaddr(ar->hw, | ||
453 | ev->peer_macaddr.addr, | ||
454 | NULL); | ||
455 | if (!station) { | ||
456 | ath10k_warn(ar, "did not find station from tdls peer event"); | ||
457 | kfree(tb); | ||
458 | return; | ||
459 | } | ||
460 | arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id)); | ||
461 | ieee80211_tdls_oper_request( | ||
462 | arvif->vif, station->addr, | ||
463 | NL80211_TDLS_TEARDOWN, | ||
464 | WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, | ||
465 | GFP_ATOMIC | ||
466 | ); | ||
467 | break; | ||
468 | } | ||
469 | kfree(tb); | ||
470 | } | ||
471 | |||
415 | /***********/ | 472 | /***********/ |
416 | /* TLV ops */ | 473 | /* TLV ops */ |
417 | /***********/ | 474 | /***********/ |
@@ -552,6 +609,12 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
552 | case WMI_TLV_TX_PAUSE_EVENTID: | 609 | case WMI_TLV_TX_PAUSE_EVENTID: |
553 | ath10k_wmi_tlv_event_tx_pause(ar, skb); | 610 | ath10k_wmi_tlv_event_tx_pause(ar, skb); |
554 | break; | 611 | break; |
612 | case WMI_TLV_PDEV_TEMPERATURE_EVENTID: | ||
613 | ath10k_wmi_tlv_event_temperature(ar, skb); | ||
614 | break; | ||
615 | case WMI_TLV_TDLS_PEER_EVENTID: | ||
616 | ath10k_wmi_event_tdls_peer(ar, skb); | ||
617 | break; | ||
555 | default: | 618 | default: |
556 | ath10k_warn(ar, "Unknown eventid: %d\n", id); | 619 | ath10k_warn(ar, "Unknown eventid: %d\n", id); |
557 | break; | 620 | break; |
@@ -2484,19 +2547,19 @@ ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask) | |||
2484 | } | 2547 | } |
2485 | 2548 | ||
2486 | static struct sk_buff * | 2549 | static struct sk_buff * |
2487 | ath10k_wmi_tlv_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) | 2550 | ath10k_wmi_tlv_op_gen_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu, |
2551 | dma_addr_t paddr) | ||
2488 | { | 2552 | { |
2489 | struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); | 2553 | struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); |
2490 | struct wmi_tlv_mgmt_tx_cmd *cmd; | 2554 | struct wmi_tlv_mgmt_tx_cmd *cmd; |
2491 | struct wmi_tlv *tlv; | ||
2492 | struct ieee80211_hdr *hdr; | 2555 | struct ieee80211_hdr *hdr; |
2556 | struct ath10k_vif *arvif; | ||
2557 | u32 buf_len = msdu->len; | ||
2558 | struct wmi_tlv *tlv; | ||
2493 | struct sk_buff *skb; | 2559 | struct sk_buff *skb; |
2560 | u32 vdev_id; | ||
2494 | void *ptr; | 2561 | void *ptr; |
2495 | int len; | 2562 | int len; |
2496 | u32 buf_len = msdu->len; | ||
2497 | struct ath10k_vif *arvif; | ||
2498 | dma_addr_t mgmt_frame_dma; | ||
2499 | u32 vdev_id; | ||
2500 | 2563 | ||
2501 | if (!cb->vif) | 2564 | if (!cb->vif) |
2502 | return ERR_PTR(-EINVAL); | 2565 | return ERR_PTR(-EINVAL); |
@@ -2537,12 +2600,7 @@ ath10k_wmi_tlv_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) | |||
2537 | cmd->chanfreq = 0; | 2600 | cmd->chanfreq = 0; |
2538 | cmd->buf_len = __cpu_to_le32(buf_len); | 2601 | cmd->buf_len = __cpu_to_le32(buf_len); |
2539 | cmd->frame_len = __cpu_to_le32(msdu->len); | 2602 | cmd->frame_len = __cpu_to_le32(msdu->len); |
2540 | mgmt_frame_dma = dma_map_single(arvif->ar->dev, msdu->data, | 2603 | cmd->paddr = __cpu_to_le64(paddr); |
2541 | msdu->len, DMA_TO_DEVICE); | ||
2542 | if (!mgmt_frame_dma) | ||
2543 | return ERR_PTR(-ENOMEM); | ||
2544 | |||
2545 | cmd->paddr = __cpu_to_le64(mgmt_frame_dma); | ||
2546 | 2604 | ||
2547 | ptr += sizeof(*tlv); | 2605 | ptr += sizeof(*tlv); |
2548 | ptr += sizeof(*cmd); | 2606 | ptr += sizeof(*cmd); |
@@ -2662,6 +2720,25 @@ ath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter) | |||
2662 | } | 2720 | } |
2663 | 2721 | ||
2664 | static struct sk_buff * | 2722 | static struct sk_buff * |
2723 | ath10k_wmi_tlv_op_gen_pdev_get_temperature(struct ath10k *ar) | ||
2724 | { | ||
2725 | struct wmi_tlv_pdev_get_temp_cmd *cmd; | ||
2726 | struct wmi_tlv *tlv; | ||
2727 | struct sk_buff *skb; | ||
2728 | |||
2729 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); | ||
2730 | if (!skb) | ||
2731 | return ERR_PTR(-ENOMEM); | ||
2732 | |||
2733 | tlv = (void *)skb->data; | ||
2734 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_GET_TEMPERATURE_CMD); | ||
2735 | tlv->len = __cpu_to_le16(sizeof(*cmd)); | ||
2736 | cmd = (void *)tlv->value; | ||
2737 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature tlv\n"); | ||
2738 | return skb; | ||
2739 | } | ||
2740 | |||
2741 | static struct sk_buff * | ||
2665 | ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar) | 2742 | ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar) |
2666 | { | 2743 | { |
2667 | struct wmi_tlv_pktlog_disable *cmd; | 2744 | struct wmi_tlv_pktlog_disable *cmd; |
@@ -2855,6 +2932,15 @@ ath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id, | |||
2855 | */ | 2932 | */ |
2856 | u32 options = 0; | 2933 | u32 options = 0; |
2857 | 2934 | ||
2935 | if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map)) | ||
2936 | options |= WMI_TLV_TDLS_BUFFER_STA_EN; | ||
2937 | |||
2938 | /* WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL means firm will handle TDLS | ||
2939 | * link inactivity detecting logic. | ||
2940 | */ | ||
2941 | if (state == WMI_TDLS_ENABLE_ACTIVE) | ||
2942 | state = WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL; | ||
2943 | |||
2858 | len = sizeof(*tlv) + sizeof(*cmd); | 2944 | len = sizeof(*tlv) + sizeof(*cmd); |
2859 | skb = ath10k_wmi_alloc_skb(ar, len); | 2945 | skb = ath10k_wmi_alloc_skb(ar, len); |
2860 | if (!skb) | 2946 | if (!skb) |
@@ -3443,7 +3529,7 @@ static struct wmi_cmd_map wmi_tlv_cmd_map = { | |||
3443 | .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID, | 3529 | .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID, |
3444 | .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID, | 3530 | .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID, |
3445 | .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID, | 3531 | .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID, |
3446 | .pdev_get_temperature_cmdid = WMI_TLV_CMD_UNSUPPORTED, | 3532 | .pdev_get_temperature_cmdid = WMI_TLV_PDEV_GET_TEMPERATURE_CMDID, |
3447 | .vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID, | 3533 | .vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID, |
3448 | .tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID, | 3534 | .tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID, |
3449 | .tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID, | 3535 | .tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID, |
@@ -3701,12 +3787,12 @@ static const struct wmi_ops wmi_tlv_ops = { | |||
3701 | .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats, | 3787 | .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats, |
3702 | .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang, | 3788 | .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang, |
3703 | /* .gen_mgmt_tx = not implemented; HTT is used */ | 3789 | /* .gen_mgmt_tx = not implemented; HTT is used */ |
3704 | .gen_mgmt_tx = ath10k_wmi_tlv_op_gen_mgmt_tx, | 3790 | .gen_mgmt_tx_send = ath10k_wmi_tlv_op_gen_mgmt_tx_send, |
3705 | .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg, | 3791 | .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg, |
3706 | .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, | 3792 | .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, |
3707 | .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, | 3793 | .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, |
3708 | /* .gen_pdev_set_quiet_mode not implemented */ | 3794 | /* .gen_pdev_set_quiet_mode not implemented */ |
3709 | /* .gen_pdev_get_temperature not implemented */ | 3795 | .gen_pdev_get_temperature = ath10k_wmi_tlv_op_gen_pdev_get_temperature, |
3710 | /* .gen_addba_clear_resp not implemented */ | 3796 | /* .gen_addba_clear_resp not implemented */ |
3711 | /* .gen_addba_send not implemented */ | 3797 | /* .gen_addba_send not implemented */ |
3712 | /* .gen_addba_set_resp not implemented */ | 3798 | /* .gen_addba_set_resp not implemented */ |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index da89128e8dd6..fa3773ec7c68 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h | |||
@@ -1340,6 +1340,17 @@ struct wmi_tlv_init_cmd { | |||
1340 | __le32 num_host_mem_chunks; | 1340 | __le32 num_host_mem_chunks; |
1341 | } __packed; | 1341 | } __packed; |
1342 | 1342 | ||
1343 | struct wmi_tlv_pdev_get_temp_cmd { | ||
1344 | __le32 pdev_id; /* not used */ | ||
1345 | } __packed; | ||
1346 | |||
1347 | struct wmi_tlv_pdev_temperature_event { | ||
1348 | __le32 tlv_hdr; | ||
1349 | /* temperature value in Celcius degree */ | ||
1350 | __le32 temperature; | ||
1351 | __le32 pdev_id; | ||
1352 | } __packed; | ||
1353 | |||
1343 | struct wmi_tlv_pdev_set_param_cmd { | 1354 | struct wmi_tlv_pdev_set_param_cmd { |
1344 | __le32 pdev_id; /* not used yet */ | 1355 | __le32 pdev_id; /* not used yet */ |
1345 | __le32 param_id; | 1356 | __le32 param_id; |
@@ -1746,6 +1757,13 @@ struct wmi_tlv_tx_pause_ev { | |||
1746 | __le32 tid_map; | 1757 | __le32 tid_map; |
1747 | } __packed; | 1758 | } __packed; |
1748 | 1759 | ||
1760 | struct wmi_tlv_tdls_peer_event { | ||
1761 | struct wmi_mac_addr peer_macaddr; | ||
1762 | __le32 peer_status; | ||
1763 | __le32 peer_reason; | ||
1764 | __le32 vdev_id; | ||
1765 | } __packed; | ||
1766 | |||
1749 | void ath10k_wmi_tlv_attach(struct ath10k *ar); | 1767 | void ath10k_wmi_tlv_attach(struct ath10k *ar); |
1750 | 1768 | ||
1751 | struct wmi_tlv_mgmt_tx_cmd { | 1769 | struct wmi_tlv_mgmt_tx_cmd { |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 58dc2189ba49..c5e1ca5945db 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | 3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
4 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -196,6 +197,7 @@ static struct wmi_cmd_map wmi_cmd_map = { | |||
196 | .mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED, | 197 | .mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED, |
197 | .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED, | 198 | .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED, |
198 | .pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED, | 199 | .pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED, |
200 | .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED, | ||
199 | }; | 201 | }; |
200 | 202 | ||
201 | /* 10.X WMI cmd track */ | 203 | /* 10.X WMI cmd track */ |
@@ -362,6 +364,7 @@ static struct wmi_cmd_map wmi_10x_cmd_map = { | |||
362 | .mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED, | 364 | .mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED, |
363 | .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED, | 365 | .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED, |
364 | .pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED, | 366 | .pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED, |
367 | .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED, | ||
365 | }; | 368 | }; |
366 | 369 | ||
367 | /* 10.2.4 WMI cmd track */ | 370 | /* 10.2.4 WMI cmd track */ |
@@ -528,6 +531,7 @@ static struct wmi_cmd_map wmi_10_2_4_cmd_map = { | |||
528 | .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED, | 531 | .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED, |
529 | .pdev_bss_chan_info_request_cmdid = | 532 | .pdev_bss_chan_info_request_cmdid = |
530 | WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID, | 533 | WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID, |
534 | .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED, | ||
531 | }; | 535 | }; |
532 | 536 | ||
533 | /* 10.4 WMI cmd track */ | 537 | /* 10.4 WMI cmd track */ |
@@ -1480,6 +1484,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_map = { | |||
1480 | .pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED, | 1484 | .pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED, |
1481 | .pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED, | 1485 | .pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED, |
1482 | .pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED, | 1486 | .pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED, |
1487 | .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED, | ||
1483 | }; | 1488 | }; |
1484 | 1489 | ||
1485 | static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = { | 1490 | static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = { |
@@ -1742,8 +1747,8 @@ int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, | |||
1742 | cmd_hdr->cmd_id = __cpu_to_le32(cmd); | 1747 | cmd_hdr->cmd_id = __cpu_to_le32(cmd); |
1743 | 1748 | ||
1744 | memset(skb_cb, 0, sizeof(*skb_cb)); | 1749 | memset(skb_cb, 0, sizeof(*skb_cb)); |
1750 | trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len); | ||
1745 | ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); | 1751 | ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); |
1746 | trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len, ret); | ||
1747 | 1752 | ||
1748 | if (ret) | 1753 | if (ret) |
1749 | goto err_pull; | 1754 | goto err_pull; |
@@ -2703,6 +2708,28 @@ ath10k_wmi_10_4_pull_peer_stats(const struct wmi_10_4_peer_stats *src, | |||
2703 | dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); | 2708 | dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); |
2704 | } | 2709 | } |
2705 | 2710 | ||
2711 | static void | ||
2712 | ath10k_wmi_10_4_pull_vdev_stats(const struct wmi_vdev_stats_extd *src, | ||
2713 | struct ath10k_fw_stats_vdev_extd *dst) | ||
2714 | { | ||
2715 | dst->vdev_id = __le32_to_cpu(src->vdev_id); | ||
2716 | dst->ppdu_aggr_cnt = __le32_to_cpu(src->ppdu_aggr_cnt); | ||
2717 | dst->ppdu_noack = __le32_to_cpu(src->ppdu_noack); | ||
2718 | dst->mpdu_queued = __le32_to_cpu(src->mpdu_queued); | ||
2719 | dst->ppdu_nonaggr_cnt = __le32_to_cpu(src->ppdu_nonaggr_cnt); | ||
2720 | dst->mpdu_sw_requeued = __le32_to_cpu(src->mpdu_sw_requeued); | ||
2721 | dst->mpdu_suc_retry = __le32_to_cpu(src->mpdu_suc_retry); | ||
2722 | dst->mpdu_suc_multitry = __le32_to_cpu(src->mpdu_suc_multitry); | ||
2723 | dst->mpdu_fail_retry = __le32_to_cpu(src->mpdu_fail_retry); | ||
2724 | dst->tx_ftm_suc = __le32_to_cpu(src->tx_ftm_suc); | ||
2725 | dst->tx_ftm_suc_retry = __le32_to_cpu(src->tx_ftm_suc_retry); | ||
2726 | dst->tx_ftm_fail = __le32_to_cpu(src->tx_ftm_fail); | ||
2727 | dst->rx_ftmr_cnt = __le32_to_cpu(src->rx_ftmr_cnt); | ||
2728 | dst->rx_ftmr_dup_cnt = __le32_to_cpu(src->rx_ftmr_dup_cnt); | ||
2729 | dst->rx_iftmr_cnt = __le32_to_cpu(src->rx_iftmr_cnt); | ||
2730 | dst->rx_iftmr_dup_cnt = __le32_to_cpu(src->rx_iftmr_dup_cnt); | ||
2731 | } | ||
2732 | |||
2706 | static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar, | 2733 | static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar, |
2707 | struct sk_buff *skb, | 2734 | struct sk_buff *skb, |
2708 | struct ath10k_fw_stats *stats) | 2735 | struct ath10k_fw_stats *stats) |
@@ -3042,7 +3069,16 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, | |||
3042 | */ | 3069 | */ |
3043 | } | 3070 | } |
3044 | 3071 | ||
3045 | /* fw doesn't implement vdev stats */ | 3072 | for (i = 0; i < num_vdev_stats; i++) { |
3073 | const struct wmi_vdev_stats *src; | ||
3074 | |||
3075 | /* Ignore vdev stats here as it has only vdev id. Actual vdev | ||
3076 | * stats will be retrieved from vdev extended stats. | ||
3077 | */ | ||
3078 | src = (void *)skb->data; | ||
3079 | if (!skb_pull(skb, sizeof(*src))) | ||
3080 | return -EPROTO; | ||
3081 | } | ||
3046 | 3082 | ||
3047 | for (i = 0; i < num_peer_stats; i++) { | 3083 | for (i = 0; i < num_peer_stats; i++) { |
3048 | const struct wmi_10_4_peer_stats *src; | 3084 | const struct wmi_10_4_peer_stats *src; |
@@ -3074,26 +3110,43 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, | |||
3074 | */ | 3110 | */ |
3075 | } | 3111 | } |
3076 | 3112 | ||
3077 | if ((stats_id & WMI_10_4_STAT_PEER_EXTD) == 0) | 3113 | if (stats_id & WMI_10_4_STAT_PEER_EXTD) { |
3078 | return 0; | 3114 | stats->extended = true; |
3079 | 3115 | ||
3080 | stats->extended = true; | 3116 | for (i = 0; i < num_peer_stats; i++) { |
3117 | const struct wmi_10_4_peer_extd_stats *src; | ||
3118 | struct ath10k_fw_extd_stats_peer *dst; | ||
3081 | 3119 | ||
3082 | for (i = 0; i < num_peer_stats; i++) { | 3120 | src = (void *)skb->data; |
3083 | const struct wmi_10_4_peer_extd_stats *src; | 3121 | if (!skb_pull(skb, sizeof(*src))) |
3084 | struct ath10k_fw_extd_stats_peer *dst; | 3122 | return -EPROTO; |
3085 | 3123 | ||
3086 | src = (void *)skb->data; | 3124 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); |
3087 | if (!skb_pull(skb, sizeof(*src))) | 3125 | if (!dst) |
3088 | return -EPROTO; | 3126 | continue; |
3089 | 3127 | ||
3090 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | 3128 | ether_addr_copy(dst->peer_macaddr, |
3091 | if (!dst) | 3129 | src->peer_macaddr.addr); |
3092 | continue; | 3130 | dst->rx_duration = __le32_to_cpu(src->rx_duration); |
3131 | list_add_tail(&dst->list, &stats->peers_extd); | ||
3132 | } | ||
3133 | } | ||
3134 | |||
3135 | if (stats_id & WMI_10_4_STAT_VDEV_EXTD) { | ||
3136 | for (i = 0; i < num_vdev_stats; i++) { | ||
3137 | const struct wmi_vdev_stats_extd *src; | ||
3138 | struct ath10k_fw_stats_vdev_extd *dst; | ||
3093 | 3139 | ||
3094 | ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr); | 3140 | src = (void *)skb->data; |
3095 | dst->rx_duration = __le32_to_cpu(src->rx_duration); | 3141 | if (!skb_pull(skb, sizeof(*src))) |
3096 | list_add_tail(&dst->list, &stats->peers_extd); | 3142 | return -EPROTO; |
3143 | |||
3144 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | ||
3145 | if (!dst) | ||
3146 | continue; | ||
3147 | ath10k_wmi_10_4_pull_vdev_stats(src, dst); | ||
3148 | list_add_tail(&dst->list, &stats->vdevs); | ||
3149 | } | ||
3097 | } | 3150 | } |
3098 | 3151 | ||
3099 | return 0; | 3152 | return 0; |
@@ -4313,19 +4366,11 @@ static void ath10k_tpc_config_disp_tables(struct ath10k *ar, | |||
4313 | } | 4366 | } |
4314 | } | 4367 | } |
4315 | 4368 | ||
4316 | void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) | 4369 | void ath10k_wmi_tpc_config_get_rate_code(u8 *rate_code, u16 *pream_table, |
4370 | u32 num_tx_chain) | ||
4317 | { | 4371 | { |
4318 | u32 i, j, pream_idx, num_tx_chain; | 4372 | u32 i, j, pream_idx; |
4319 | u8 rate_code[WMI_TPC_RATE_MAX], rate_idx; | 4373 | u8 rate_idx; |
4320 | u16 pream_table[WMI_TPC_PREAM_TABLE_MAX]; | ||
4321 | struct wmi_pdev_tpc_config_event *ev; | ||
4322 | struct ath10k_tpc_stats *tpc_stats; | ||
4323 | |||
4324 | ev = (struct wmi_pdev_tpc_config_event *)skb->data; | ||
4325 | |||
4326 | tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC); | ||
4327 | if (!tpc_stats) | ||
4328 | return; | ||
4329 | 4374 | ||
4330 | /* Create the rate code table based on the chains supported */ | 4375 | /* Create the rate code table based on the chains supported */ |
4331 | rate_idx = 0; | 4376 | rate_idx = 0; |
@@ -4349,8 +4394,6 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) | |||
4349 | pream_table[pream_idx] = rate_idx; | 4394 | pream_table[pream_idx] = rate_idx; |
4350 | pream_idx++; | 4395 | pream_idx++; |
4351 | 4396 | ||
4352 | num_tx_chain = __le32_to_cpu(ev->num_tx_chain); | ||
4353 | |||
4354 | /* Fill HT20 rate code */ | 4397 | /* Fill HT20 rate code */ |
4355 | for (i = 0; i < num_tx_chain; i++) { | 4398 | for (i = 0; i < num_tx_chain; i++) { |
4356 | for (j = 0; j < 8; j++) { | 4399 | for (j = 0; j < 8; j++) { |
@@ -4374,7 +4417,7 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) | |||
4374 | pream_idx++; | 4417 | pream_idx++; |
4375 | 4418 | ||
4376 | /* Fill VHT20 rate code */ | 4419 | /* Fill VHT20 rate code */ |
4377 | for (i = 0; i < __le32_to_cpu(ev->num_tx_chain); i++) { | 4420 | for (i = 0; i < num_tx_chain; i++) { |
4378 | for (j = 0; j < 10; j++) { | 4421 | for (j = 0; j < 10; j++) { |
4379 | rate_code[rate_idx] = | 4422 | rate_code[rate_idx] = |
4380 | ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT); | 4423 | ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT); |
@@ -4418,6 +4461,26 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) | |||
4418 | ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM); | 4461 | ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM); |
4419 | 4462 | ||
4420 | pream_table[pream_idx] = ATH10K_TPC_PREAM_TABLE_END; | 4463 | pream_table[pream_idx] = ATH10K_TPC_PREAM_TABLE_END; |
4464 | } | ||
4465 | |||
4466 | void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) | ||
4467 | { | ||
4468 | u32 num_tx_chain; | ||
4469 | u8 rate_code[WMI_TPC_RATE_MAX]; | ||
4470 | u16 pream_table[WMI_TPC_PREAM_TABLE_MAX]; | ||
4471 | struct wmi_pdev_tpc_config_event *ev; | ||
4472 | struct ath10k_tpc_stats *tpc_stats; | ||
4473 | |||
4474 | ev = (struct wmi_pdev_tpc_config_event *)skb->data; | ||
4475 | |||
4476 | tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC); | ||
4477 | if (!tpc_stats) | ||
4478 | return; | ||
4479 | |||
4480 | num_tx_chain = __le32_to_cpu(ev->num_tx_chain); | ||
4481 | |||
4482 | ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table, | ||
4483 | num_tx_chain); | ||
4421 | 4484 | ||
4422 | tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq); | 4485 | tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq); |
4423 | tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode); | 4486 | tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode); |
@@ -4457,6 +4520,246 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) | |||
4457 | __le32_to_cpu(ev->rate_max)); | 4520 | __le32_to_cpu(ev->rate_max)); |
4458 | } | 4521 | } |
4459 | 4522 | ||
4523 | static u8 | ||
4524 | ath10k_wmi_tpc_final_get_rate(struct ath10k *ar, | ||
4525 | struct wmi_pdev_tpc_final_table_event *ev, | ||
4526 | u32 rate_idx, u32 num_chains, | ||
4527 | u32 rate_code, u8 type, u32 pream_idx) | ||
4528 | { | ||
4529 | u8 tpc, num_streams, preamble, ch, stm_idx; | ||
4530 | s8 pow_agcdd, pow_agstbc, pow_agtxbf; | ||
4531 | int pream; | ||
4532 | |||
4533 | num_streams = ATH10K_HW_NSS(rate_code); | ||
4534 | preamble = ATH10K_HW_PREAMBLE(rate_code); | ||
4535 | ch = num_chains - 1; | ||
4536 | stm_idx = num_streams - 1; | ||
4537 | pream = -1; | ||
4538 | |||
4539 | if (__le32_to_cpu(ev->chan_freq) <= 2483) { | ||
4540 | switch (pream_idx) { | ||
4541 | case WMI_TPC_PREAM_2GHZ_CCK: | ||
4542 | pream = 0; | ||
4543 | break; | ||
4544 | case WMI_TPC_PREAM_2GHZ_OFDM: | ||
4545 | pream = 1; | ||
4546 | break; | ||
4547 | case WMI_TPC_PREAM_2GHZ_HT20: | ||
4548 | case WMI_TPC_PREAM_2GHZ_VHT20: | ||
4549 | pream = 2; | ||
4550 | break; | ||
4551 | case WMI_TPC_PREAM_2GHZ_HT40: | ||
4552 | case WMI_TPC_PREAM_2GHZ_VHT40: | ||
4553 | pream = 3; | ||
4554 | break; | ||
4555 | case WMI_TPC_PREAM_2GHZ_VHT80: | ||
4556 | pream = 4; | ||
4557 | break; | ||
4558 | default: | ||
4559 | pream = -1; | ||
4560 | break; | ||
4561 | } | ||
4562 | } | ||
4563 | |||
4564 | if (__le32_to_cpu(ev->chan_freq) >= 5180) { | ||
4565 | switch (pream_idx) { | ||
4566 | case WMI_TPC_PREAM_5GHZ_OFDM: | ||
4567 | pream = 0; | ||
4568 | break; | ||
4569 | case WMI_TPC_PREAM_5GHZ_HT20: | ||
4570 | case WMI_TPC_PREAM_5GHZ_VHT20: | ||
4571 | pream = 1; | ||
4572 | break; | ||
4573 | case WMI_TPC_PREAM_5GHZ_HT40: | ||
4574 | case WMI_TPC_PREAM_5GHZ_VHT40: | ||
4575 | pream = 2; | ||
4576 | break; | ||
4577 | case WMI_TPC_PREAM_5GHZ_VHT80: | ||
4578 | pream = 3; | ||
4579 | break; | ||
4580 | case WMI_TPC_PREAM_5GHZ_HTCUP: | ||
4581 | pream = 4; | ||
4582 | break; | ||
4583 | default: | ||
4584 | pream = -1; | ||
4585 | break; | ||
4586 | } | ||
4587 | } | ||
4588 | |||
4589 | if (pream == 4) | ||
4590 | tpc = min_t(u8, ev->rates_array[rate_idx], | ||
4591 | ev->max_reg_allow_pow[ch]); | ||
4592 | else | ||
4593 | tpc = min_t(u8, min_t(u8, ev->rates_array[rate_idx], | ||
4594 | ev->max_reg_allow_pow[ch]), | ||
4595 | ev->ctl_power_table[0][pream][stm_idx]); | ||
4596 | |||
4597 | if (__le32_to_cpu(ev->num_tx_chain) <= 1) | ||
4598 | goto out; | ||
4599 | |||
4600 | if (preamble == WMI_RATE_PREAMBLE_CCK) | ||
4601 | goto out; | ||
4602 | |||
4603 | if (num_chains <= num_streams) | ||
4604 | goto out; | ||
4605 | |||
4606 | switch (type) { | ||
4607 | case WMI_TPC_TABLE_TYPE_STBC: | ||
4608 | pow_agstbc = ev->max_reg_allow_pow_agstbc[ch - 1][stm_idx]; | ||
4609 | if (pream == 4) | ||
4610 | tpc = min_t(u8, tpc, pow_agstbc); | ||
4611 | else | ||
4612 | tpc = min_t(u8, min_t(u8, tpc, pow_agstbc), | ||
4613 | ev->ctl_power_table[0][pream][stm_idx]); | ||
4614 | break; | ||
4615 | case WMI_TPC_TABLE_TYPE_TXBF: | ||
4616 | pow_agtxbf = ev->max_reg_allow_pow_agtxbf[ch - 1][stm_idx]; | ||
4617 | if (pream == 4) | ||
4618 | tpc = min_t(u8, tpc, pow_agtxbf); | ||
4619 | else | ||
4620 | tpc = min_t(u8, min_t(u8, tpc, pow_agtxbf), | ||
4621 | ev->ctl_power_table[1][pream][stm_idx]); | ||
4622 | break; | ||
4623 | case WMI_TPC_TABLE_TYPE_CDD: | ||
4624 | pow_agcdd = ev->max_reg_allow_pow_agcdd[ch - 1][stm_idx]; | ||
4625 | if (pream == 4) | ||
4626 | tpc = min_t(u8, tpc, pow_agcdd); | ||
4627 | else | ||
4628 | tpc = min_t(u8, min_t(u8, tpc, pow_agcdd), | ||
4629 | ev->ctl_power_table[0][pream][stm_idx]); | ||
4630 | break; | ||
4631 | default: | ||
4632 | ath10k_warn(ar, "unknown wmi tpc final table type: %d\n", type); | ||
4633 | tpc = 0; | ||
4634 | break; | ||
4635 | } | ||
4636 | |||
4637 | out: | ||
4638 | return tpc; | ||
4639 | } | ||
4640 | |||
4641 | static void | ||
4642 | ath10k_wmi_tpc_stats_final_disp_tables(struct ath10k *ar, | ||
4643 | struct wmi_pdev_tpc_final_table_event *ev, | ||
4644 | struct ath10k_tpc_stats_final *tpc_stats, | ||
4645 | u8 *rate_code, u16 *pream_table, u8 type) | ||
4646 | { | ||
4647 | u32 i, j, pream_idx, flags; | ||
4648 | u8 tpc[WMI_TPC_TX_N_CHAIN]; | ||
4649 | char tpc_value[WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE]; | ||
4650 | char buff[WMI_TPC_BUF_SIZE]; | ||
4651 | |||
4652 | flags = __le32_to_cpu(ev->flags); | ||
4653 | |||
4654 | switch (type) { | ||
4655 | case WMI_TPC_TABLE_TYPE_CDD: | ||
4656 | if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_CDD)) { | ||
4657 | ath10k_dbg(ar, ATH10K_DBG_WMI, "CDD not supported\n"); | ||
4658 | tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG; | ||
4659 | return; | ||
4660 | } | ||
4661 | break; | ||
4662 | case WMI_TPC_TABLE_TYPE_STBC: | ||
4663 | if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_STBC)) { | ||
4664 | ath10k_dbg(ar, ATH10K_DBG_WMI, "STBC not supported\n"); | ||
4665 | tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG; | ||
4666 | return; | ||
4667 | } | ||
4668 | break; | ||
4669 | case WMI_TPC_TABLE_TYPE_TXBF: | ||
4670 | if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_TXBF)) { | ||
4671 | ath10k_dbg(ar, ATH10K_DBG_WMI, "TXBF not supported\n"); | ||
4672 | tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG; | ||
4673 | return; | ||
4674 | } | ||
4675 | break; | ||
4676 | default: | ||
4677 | ath10k_dbg(ar, ATH10K_DBG_WMI, | ||
4678 | "invalid table type in wmi tpc event: %d\n", type); | ||
4679 | return; | ||
4680 | } | ||
4681 | |||
4682 | pream_idx = 0; | ||
4683 | for (i = 0; i < __le32_to_cpu(ev->rate_max); i++) { | ||
4684 | memset(tpc_value, 0, sizeof(tpc_value)); | ||
4685 | memset(buff, 0, sizeof(buff)); | ||
4686 | if (i == pream_table[pream_idx]) | ||
4687 | pream_idx++; | ||
4688 | |||
4689 | for (j = 0; j < WMI_TPC_TX_N_CHAIN; j++) { | ||
4690 | if (j >= __le32_to_cpu(ev->num_tx_chain)) | ||
4691 | break; | ||
4692 | |||
4693 | tpc[j] = ath10k_wmi_tpc_final_get_rate(ar, ev, i, j + 1, | ||
4694 | rate_code[i], | ||
4695 | type, pream_idx); | ||
4696 | snprintf(buff, sizeof(buff), "%8d ", tpc[j]); | ||
4697 | strncat(tpc_value, buff, strlen(buff)); | ||
4698 | } | ||
4699 | tpc_stats->tpc_table_final[type].pream_idx[i] = pream_idx; | ||
4700 | tpc_stats->tpc_table_final[type].rate_code[i] = rate_code[i]; | ||
4701 | memcpy(tpc_stats->tpc_table_final[type].tpc_value[i], | ||
4702 | tpc_value, sizeof(tpc_value)); | ||
4703 | } | ||
4704 | } | ||
4705 | |||
4706 | void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb) | ||
4707 | { | ||
4708 | u32 num_tx_chain; | ||
4709 | u8 rate_code[WMI_TPC_FINAL_RATE_MAX]; | ||
4710 | u16 pream_table[WMI_TPC_PREAM_TABLE_MAX]; | ||
4711 | struct wmi_pdev_tpc_final_table_event *ev; | ||
4712 | struct ath10k_tpc_stats_final *tpc_stats; | ||
4713 | |||
4714 | ev = (struct wmi_pdev_tpc_final_table_event *)skb->data; | ||
4715 | |||
4716 | tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC); | ||
4717 | if (!tpc_stats) | ||
4718 | return; | ||
4719 | |||
4720 | num_tx_chain = __le32_to_cpu(ev->num_tx_chain); | ||
4721 | |||
4722 | ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table, | ||
4723 | num_tx_chain); | ||
4724 | |||
4725 | tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq); | ||
4726 | tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode); | ||
4727 | tpc_stats->ctl = __le32_to_cpu(ev->ctl); | ||
4728 | tpc_stats->reg_domain = __le32_to_cpu(ev->reg_domain); | ||
4729 | tpc_stats->twice_antenna_gain = a_sle32_to_cpu(ev->twice_antenna_gain); | ||
4730 | tpc_stats->twice_antenna_reduction = | ||
4731 | __le32_to_cpu(ev->twice_antenna_reduction); | ||
4732 | tpc_stats->power_limit = __le32_to_cpu(ev->power_limit); | ||
4733 | tpc_stats->twice_max_rd_power = __le32_to_cpu(ev->twice_max_rd_power); | ||
4734 | tpc_stats->num_tx_chain = __le32_to_cpu(ev->num_tx_chain); | ||
4735 | tpc_stats->rate_max = __le32_to_cpu(ev->rate_max); | ||
4736 | |||
4737 | ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats, | ||
4738 | rate_code, pream_table, | ||
4739 | WMI_TPC_TABLE_TYPE_CDD); | ||
4740 | ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats, | ||
4741 | rate_code, pream_table, | ||
4742 | WMI_TPC_TABLE_TYPE_STBC); | ||
4743 | ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats, | ||
4744 | rate_code, pream_table, | ||
4745 | WMI_TPC_TABLE_TYPE_TXBF); | ||
4746 | |||
4747 | ath10k_debug_tpc_stats_final_process(ar, tpc_stats); | ||
4748 | |||
4749 | ath10k_dbg(ar, ATH10K_DBG_WMI, | ||
4750 | "wmi event tpc final table channel %d mode %d ctl %d regd %d gain %d %d limit %d max_power %d tx_chanins %d rates %d\n", | ||
4751 | __le32_to_cpu(ev->chan_freq), | ||
4752 | __le32_to_cpu(ev->phy_mode), | ||
4753 | __le32_to_cpu(ev->ctl), | ||
4754 | __le32_to_cpu(ev->reg_domain), | ||
4755 | a_sle32_to_cpu(ev->twice_antenna_gain), | ||
4756 | __le32_to_cpu(ev->twice_antenna_reduction), | ||
4757 | __le32_to_cpu(ev->power_limit), | ||
4758 | __le32_to_cpu(ev->twice_max_rd_power) / 2, | ||
4759 | __le32_to_cpu(ev->num_tx_chain), | ||
4760 | __le32_to_cpu(ev->rate_max)); | ||
4761 | } | ||
4762 | |||
4460 | static void | 4763 | static void |
4461 | ath10k_wmi_handle_tdls_peer_event(struct ath10k *ar, struct sk_buff *skb) | 4764 | ath10k_wmi_handle_tdls_peer_event(struct ath10k *ar, struct sk_buff *skb) |
4462 | { | 4765 | { |
@@ -5531,6 +5834,7 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5531 | case WMI_10_4_WOW_WAKEUP_HOST_EVENTID: | 5834 | case WMI_10_4_WOW_WAKEUP_HOST_EVENTID: |
5532 | case WMI_10_4_PEER_RATECODE_LIST_EVENTID: | 5835 | case WMI_10_4_PEER_RATECODE_LIST_EVENTID: |
5533 | case WMI_10_4_WDS_PEER_EVENTID: | 5836 | case WMI_10_4_WDS_PEER_EVENTID: |
5837 | case WMI_10_4_DEBUG_FATAL_CONDITION_EVENTID: | ||
5534 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 5838 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
5535 | "received event id %d not implemented\n", id); | 5839 | "received event id %d not implemented\n", id); |
5536 | break; | 5840 | break; |
@@ -5549,6 +5853,9 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5549 | case WMI_10_4_TDLS_PEER_EVENTID: | 5853 | case WMI_10_4_TDLS_PEER_EVENTID: |
5550 | ath10k_wmi_handle_tdls_peer_event(ar, skb); | 5854 | ath10k_wmi_handle_tdls_peer_event(ar, skb); |
5551 | break; | 5855 | break; |
5856 | case WMI_10_4_PDEV_TPC_TABLE_EVENTID: | ||
5857 | ath10k_wmi_event_tpc_final_table(ar, skb); | ||
5858 | break; | ||
5552 | default: | 5859 | default: |
5553 | ath10k_warn(ar, "Unknown eventid: %d\n", id); | 5860 | ath10k_warn(ar, "Unknown eventid: %d\n", id); |
5554 | break; | 5861 | break; |
@@ -7745,6 +8052,72 @@ ath10k_wmi_op_gen_pdev_enable_adaptive_cca(struct ath10k *ar, u8 enable, | |||
7745 | return skb; | 8052 | return skb; |
7746 | } | 8053 | } |
7747 | 8054 | ||
8055 | static void | ||
8056 | ath10k_wmi_fw_vdev_stats_extd_fill(const struct ath10k_fw_stats_vdev_extd *vdev, | ||
8057 | char *buf, u32 *length) | ||
8058 | { | ||
8059 | u32 len = *length; | ||
8060 | u32 buf_len = ATH10K_FW_STATS_BUF_SIZE; | ||
8061 | u32 val; | ||
8062 | |||
8063 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8064 | "vdev id", vdev->vdev_id); | ||
8065 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8066 | "ppdu aggr count", vdev->ppdu_aggr_cnt); | ||
8067 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8068 | "ppdu noack", vdev->ppdu_noack); | ||
8069 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8070 | "mpdu queued", vdev->mpdu_queued); | ||
8071 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8072 | "ppdu nonaggr count", vdev->ppdu_nonaggr_cnt); | ||
8073 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8074 | "mpdu sw requeued", vdev->mpdu_sw_requeued); | ||
8075 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8076 | "mpdu success retry", vdev->mpdu_suc_retry); | ||
8077 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8078 | "mpdu success multitry", vdev->mpdu_suc_multitry); | ||
8079 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8080 | "mpdu fail retry", vdev->mpdu_fail_retry); | ||
8081 | val = vdev->tx_ftm_suc; | ||
8082 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8083 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8084 | "tx ftm success", | ||
8085 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8086 | val = vdev->tx_ftm_suc_retry; | ||
8087 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8088 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8089 | "tx ftm success retry", | ||
8090 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8091 | val = vdev->tx_ftm_fail; | ||
8092 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8093 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8094 | "tx ftm fail", | ||
8095 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8096 | val = vdev->rx_ftmr_cnt; | ||
8097 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8098 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8099 | "rx ftm request count", | ||
8100 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8101 | val = vdev->rx_ftmr_dup_cnt; | ||
8102 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8103 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8104 | "rx ftm request dup count", | ||
8105 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8106 | val = vdev->rx_iftmr_cnt; | ||
8107 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8108 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8109 | "rx initial ftm req count", | ||
8110 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8111 | val = vdev->rx_iftmr_dup_cnt; | ||
8112 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8113 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8114 | "rx initial ftm req dup cnt", | ||
8115 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8116 | len += scnprintf(buf + len, buf_len - len, "\n"); | ||
8117 | |||
8118 | *length = len; | ||
8119 | } | ||
8120 | |||
7748 | void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, | 8121 | void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, |
7749 | struct ath10k_fw_stats *fw_stats, | 8122 | struct ath10k_fw_stats *fw_stats, |
7750 | char *buf) | 8123 | char *buf) |
@@ -7752,7 +8125,7 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, | |||
7752 | u32 len = 0; | 8125 | u32 len = 0; |
7753 | u32 buf_len = ATH10K_FW_STATS_BUF_SIZE; | 8126 | u32 buf_len = ATH10K_FW_STATS_BUF_SIZE; |
7754 | const struct ath10k_fw_stats_pdev *pdev; | 8127 | const struct ath10k_fw_stats_pdev *pdev; |
7755 | const struct ath10k_fw_stats_vdev *vdev; | 8128 | const struct ath10k_fw_stats_vdev_extd *vdev; |
7756 | const struct ath10k_fw_stats_peer *peer; | 8129 | const struct ath10k_fw_stats_peer *peer; |
7757 | size_t num_peers; | 8130 | size_t num_peers; |
7758 | size_t num_vdevs; | 8131 | size_t num_vdevs; |
@@ -7805,9 +8178,8 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, | |||
7805 | "ath10k VDEV stats", num_vdevs); | 8178 | "ath10k VDEV stats", num_vdevs); |
7806 | len += scnprintf(buf + len, buf_len - len, "%30s\n\n", | 8179 | len += scnprintf(buf + len, buf_len - len, "%30s\n\n", |
7807 | "================="); | 8180 | "================="); |
7808 | |||
7809 | list_for_each_entry(vdev, &fw_stats->vdevs, list) { | 8181 | list_for_each_entry(vdev, &fw_stats->vdevs, list) { |
7810 | ath10k_wmi_fw_vdev_stats_fill(vdev, buf, &len); | 8182 | ath10k_wmi_fw_vdev_stats_extd_fill(vdev, buf, &len); |
7811 | } | 8183 | } |
7812 | 8184 | ||
7813 | len += scnprintf(buf + len, buf_len - len, "\n"); | 8185 | len += scnprintf(buf + len, buf_len - len, "\n"); |
@@ -7990,6 +8362,24 @@ static u32 ath10k_wmi_prepare_peer_qos(u8 uapsd_queues, u8 sp) | |||
7990 | } | 8362 | } |
7991 | 8363 | ||
7992 | static struct sk_buff * | 8364 | static struct sk_buff * |
8365 | ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param) | ||
8366 | { | ||
8367 | struct wmi_pdev_get_tpc_table_cmd *cmd; | ||
8368 | struct sk_buff *skb; | ||
8369 | |||
8370 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); | ||
8371 | if (!skb) | ||
8372 | return ERR_PTR(-ENOMEM); | ||
8373 | |||
8374 | cmd = (struct wmi_pdev_get_tpc_table_cmd *)skb->data; | ||
8375 | cmd->param = __cpu_to_le32(param); | ||
8376 | |||
8377 | ath10k_dbg(ar, ATH10K_DBG_WMI, | ||
8378 | "wmi pdev get tpc table param:%d\n", param); | ||
8379 | return skb; | ||
8380 | } | ||
8381 | |||
8382 | static struct sk_buff * | ||
7993 | ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar, | 8383 | ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar, |
7994 | const struct wmi_tdls_peer_update_cmd_arg *arg, | 8384 | const struct wmi_tdls_peer_update_cmd_arg *arg, |
7995 | const struct wmi_tdls_peer_capab_arg *cap, | 8385 | const struct wmi_tdls_peer_capab_arg *cap, |
@@ -8430,6 +8820,8 @@ static const struct wmi_ops wmi_10_4_ops = { | |||
8430 | .ext_resource_config = ath10k_wmi_10_4_ext_resource_config, | 8820 | .ext_resource_config = ath10k_wmi_10_4_ext_resource_config, |
8431 | .gen_update_fw_tdls_state = ath10k_wmi_10_4_gen_update_fw_tdls_state, | 8821 | .gen_update_fw_tdls_state = ath10k_wmi_10_4_gen_update_fw_tdls_state, |
8432 | .gen_tdls_peer_update = ath10k_wmi_10_4_gen_tdls_peer_update, | 8822 | .gen_tdls_peer_update = ath10k_wmi_10_4_gen_tdls_peer_update, |
8823 | .gen_pdev_get_tpc_table_cmdid = | ||
8824 | ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid, | ||
8433 | 8825 | ||
8434 | /* shared with 10.2 */ | 8826 | /* shared with 10.2 */ |
8435 | .pull_echo_ev = ath10k_wmi_op_pull_echo_ev, | 8827 | .pull_echo_ev = ath10k_wmi_op_pull_echo_ev, |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index c7b30ed9015d..6fbc84c29521 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. | 3 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
4 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -197,6 +198,9 @@ enum wmi_service { | |||
197 | WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, | 198 | WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, |
198 | WMI_SERVICE_MGMT_TX_WMI, | 199 | WMI_SERVICE_MGMT_TX_WMI, |
199 | WMI_SERVICE_TDLS_WIDER_BANDWIDTH, | 200 | WMI_SERVICE_TDLS_WIDER_BANDWIDTH, |
201 | WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, | ||
202 | WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, | ||
203 | WMI_SERVICE_TPC_STATS_FINAL, | ||
200 | 204 | ||
201 | /* keep last */ | 205 | /* keep last */ |
202 | WMI_SERVICE_MAX, | 206 | WMI_SERVICE_MAX, |
@@ -339,6 +343,9 @@ enum wmi_10_4_service { | |||
339 | WMI_10_4_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE, | 343 | WMI_10_4_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE, |
340 | WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY, | 344 | WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY, |
341 | WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH, | 345 | WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH, |
346 | WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, | ||
347 | WMI_10_4_SERVICE_HOST_DFS_CHECK_SUPPORT, | ||
348 | WMI_10_4_SERVICE_TPC_STATS_FINAL, | ||
342 | }; | 349 | }; |
343 | 350 | ||
344 | static inline char *wmi_service_name(int service_id) | 351 | static inline char *wmi_service_name(int service_id) |
@@ -448,6 +455,9 @@ static inline char *wmi_service_name(int service_id) | |||
448 | SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE); | 455 | SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE); |
449 | SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY); | 456 | SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY); |
450 | SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH); | 457 | SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH); |
458 | SVCSTR(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS); | ||
459 | SVCSTR(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT); | ||
460 | SVCSTR(WMI_SERVICE_TPC_STATS_FINAL); | ||
451 | default: | 461 | default: |
452 | return NULL; | 462 | return NULL; |
453 | } | 463 | } |
@@ -746,6 +756,12 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out, | |||
746 | WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, len); | 756 | WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, len); |
747 | SVCMAP(WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH, | 757 | SVCMAP(WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH, |
748 | WMI_SERVICE_TDLS_WIDER_BANDWIDTH, len); | 758 | WMI_SERVICE_TDLS_WIDER_BANDWIDTH, len); |
759 | SVCMAP(WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, | ||
760 | WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, len); | ||
761 | SVCMAP(WMI_10_4_SERVICE_HOST_DFS_CHECK_SUPPORT, | ||
762 | WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, len); | ||
763 | SVCMAP(WMI_10_4_SERVICE_TPC_STATS_FINAL, | ||
764 | WMI_SERVICE_TPC_STATS_FINAL, len); | ||
749 | } | 765 | } |
750 | 766 | ||
751 | #undef SVCMAP | 767 | #undef SVCMAP |
@@ -3993,10 +4009,12 @@ struct wmi_pdev_get_tpc_config_cmd { | |||
3993 | 4009 | ||
3994 | #define WMI_TPC_CONFIG_PARAM 1 | 4010 | #define WMI_TPC_CONFIG_PARAM 1 |
3995 | #define WMI_TPC_RATE_MAX 160 | 4011 | #define WMI_TPC_RATE_MAX 160 |
4012 | #define WMI_TPC_FINAL_RATE_MAX 240 | ||
3996 | #define WMI_TPC_TX_N_CHAIN 4 | 4013 | #define WMI_TPC_TX_N_CHAIN 4 |
3997 | #define WMI_TPC_PREAM_TABLE_MAX 10 | 4014 | #define WMI_TPC_PREAM_TABLE_MAX 10 |
3998 | #define WMI_TPC_FLAG 3 | 4015 | #define WMI_TPC_FLAG 3 |
3999 | #define WMI_TPC_BUF_SIZE 10 | 4016 | #define WMI_TPC_BUF_SIZE 10 |
4017 | #define WMI_TPC_BEAMFORMING 2 | ||
4000 | 4018 | ||
4001 | enum wmi_tpc_table_type { | 4019 | enum wmi_tpc_table_type { |
4002 | WMI_TPC_TABLE_TYPE_CDD = 0, | 4020 | WMI_TPC_TABLE_TYPE_CDD = 0, |
@@ -4039,6 +4057,51 @@ enum wmi_tp_scale { | |||
4039 | WMI_TP_SCALE_SIZE = 5, /* max num of enum */ | 4057 | WMI_TP_SCALE_SIZE = 5, /* max num of enum */ |
4040 | }; | 4058 | }; |
4041 | 4059 | ||
4060 | struct wmi_pdev_tpc_final_table_event { | ||
4061 | __le32 reg_domain; | ||
4062 | __le32 chan_freq; | ||
4063 | __le32 phy_mode; | ||
4064 | __le32 twice_antenna_reduction; | ||
4065 | __le32 twice_max_rd_power; | ||
4066 | a_sle32 twice_antenna_gain; | ||
4067 | __le32 power_limit; | ||
4068 | __le32 rate_max; | ||
4069 | __le32 num_tx_chain; | ||
4070 | __le32 ctl; | ||
4071 | __le32 flags; | ||
4072 | s8 max_reg_allow_pow[WMI_TPC_TX_N_CHAIN]; | ||
4073 | s8 max_reg_allow_pow_agcdd[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN]; | ||
4074 | s8 max_reg_allow_pow_agstbc[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN]; | ||
4075 | s8 max_reg_allow_pow_agtxbf[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN]; | ||
4076 | u8 rates_array[WMI_TPC_FINAL_RATE_MAX]; | ||
4077 | u8 ctl_power_table[WMI_TPC_BEAMFORMING][WMI_TPC_TX_N_CHAIN] | ||
4078 | [WMI_TPC_TX_N_CHAIN]; | ||
4079 | } __packed; | ||
4080 | |||
4081 | struct wmi_pdev_get_tpc_table_cmd { | ||
4082 | __le32 param; | ||
4083 | } __packed; | ||
4084 | |||
4085 | enum wmi_tpc_pream_2ghz { | ||
4086 | WMI_TPC_PREAM_2GHZ_CCK = 0, | ||
4087 | WMI_TPC_PREAM_2GHZ_OFDM, | ||
4088 | WMI_TPC_PREAM_2GHZ_HT20, | ||
4089 | WMI_TPC_PREAM_2GHZ_HT40, | ||
4090 | WMI_TPC_PREAM_2GHZ_VHT20, | ||
4091 | WMI_TPC_PREAM_2GHZ_VHT40, | ||
4092 | WMI_TPC_PREAM_2GHZ_VHT80, | ||
4093 | }; | ||
4094 | |||
4095 | enum wmi_tpc_pream_5ghz { | ||
4096 | WMI_TPC_PREAM_5GHZ_OFDM = 1, | ||
4097 | WMI_TPC_PREAM_5GHZ_HT20, | ||
4098 | WMI_TPC_PREAM_5GHZ_HT40, | ||
4099 | WMI_TPC_PREAM_5GHZ_VHT20, | ||
4100 | WMI_TPC_PREAM_5GHZ_VHT40, | ||
4101 | WMI_TPC_PREAM_5GHZ_VHT80, | ||
4102 | WMI_TPC_PREAM_5GHZ_HTCUP, | ||
4103 | }; | ||
4104 | |||
4042 | struct wmi_pdev_chanlist_update_event { | 4105 | struct wmi_pdev_chanlist_update_event { |
4043 | /* number of channels */ | 4106 | /* number of channels */ |
4044 | __le32 num_chan; | 4107 | __le32 num_chan; |
@@ -4350,6 +4413,7 @@ enum wmi_10_4_stats_id { | |||
4350 | WMI_10_4_STAT_AP = BIT(1), | 4413 | WMI_10_4_STAT_AP = BIT(1), |
4351 | WMI_10_4_STAT_INST = BIT(2), | 4414 | WMI_10_4_STAT_INST = BIT(2), |
4352 | WMI_10_4_STAT_PEER_EXTD = BIT(3), | 4415 | WMI_10_4_STAT_PEER_EXTD = BIT(3), |
4416 | WMI_10_4_STAT_VDEV_EXTD = BIT(4), | ||
4353 | }; | 4417 | }; |
4354 | 4418 | ||
4355 | struct wlan_inst_rssi_args { | 4419 | struct wlan_inst_rssi_args { |
@@ -4489,12 +4553,36 @@ struct wmi_10_4_pdev_stats { | |||
4489 | 4553 | ||
4490 | /* | 4554 | /* |
4491 | * VDEV statistics | 4555 | * VDEV statistics |
4492 | * TODO: add all VDEV stats here | ||
4493 | */ | 4556 | */ |
4557 | |||
4558 | #define WMI_VDEV_STATS_FTM_COUNT_VALID BIT(31) | ||
4559 | #define WMI_VDEV_STATS_FTM_COUNT_LSB 0 | ||
4560 | #define WMI_VDEV_STATS_FTM_COUNT_MASK 0x7fffffff | ||
4561 | |||
4494 | struct wmi_vdev_stats { | 4562 | struct wmi_vdev_stats { |
4495 | __le32 vdev_id; | 4563 | __le32 vdev_id; |
4496 | } __packed; | 4564 | } __packed; |
4497 | 4565 | ||
4566 | struct wmi_vdev_stats_extd { | ||
4567 | __le32 vdev_id; | ||
4568 | __le32 ppdu_aggr_cnt; | ||
4569 | __le32 ppdu_noack; | ||
4570 | __le32 mpdu_queued; | ||
4571 | __le32 ppdu_nonaggr_cnt; | ||
4572 | __le32 mpdu_sw_requeued; | ||
4573 | __le32 mpdu_suc_retry; | ||
4574 | __le32 mpdu_suc_multitry; | ||
4575 | __le32 mpdu_fail_retry; | ||
4576 | __le32 tx_ftm_suc; | ||
4577 | __le32 tx_ftm_suc_retry; | ||
4578 | __le32 tx_ftm_fail; | ||
4579 | __le32 rx_ftmr_cnt; | ||
4580 | __le32 rx_ftmr_dup_cnt; | ||
4581 | __le32 rx_iftmr_cnt; | ||
4582 | __le32 rx_iftmr_dup_cnt; | ||
4583 | __le32 reserved[6]; | ||
4584 | } __packed; | ||
4585 | |||
4498 | /* | 4586 | /* |
4499 | * peer statistics. | 4587 | * peer statistics. |
4500 | * TODO: add more stats | 4588 | * TODO: add more stats |
@@ -6729,6 +6817,7 @@ enum wmi_tdls_state { | |||
6729 | WMI_TDLS_DISABLE, | 6817 | WMI_TDLS_DISABLE, |
6730 | WMI_TDLS_ENABLE_PASSIVE, | 6818 | WMI_TDLS_ENABLE_PASSIVE, |
6731 | WMI_TDLS_ENABLE_ACTIVE, | 6819 | WMI_TDLS_ENABLE_ACTIVE, |
6820 | WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL, | ||
6732 | }; | 6821 | }; |
6733 | 6822 | ||
6734 | enum wmi_tdls_peer_state { | 6823 | enum wmi_tdls_peer_state { |
@@ -6979,5 +7068,8 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, | |||
6979 | int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar, | 7068 | int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar, |
6980 | enum wmi_vdev_subtype subtype); | 7069 | enum wmi_vdev_subtype subtype); |
6981 | int ath10k_wmi_barrier(struct ath10k *ar); | 7070 | int ath10k_wmi_barrier(struct ath10k *ar); |
7071 | void ath10k_wmi_tpc_config_get_rate_code(u8 *rate_code, u16 *pream_table, | ||
7072 | u32 num_tx_chain); | ||
7073 | void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb); | ||
6982 | 7074 | ||
6983 | #endif /* _WMI_H_ */ | 7075 | #endif /* _WMI_H_ */ |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 233054bd6b52..12d3a6c92ba4 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -327,7 +327,7 @@ int ath5k_hw_init(struct ath5k_hw *ah) | |||
327 | ath5k_hw_set_lladdr(ah, zero_mac); | 327 | ath5k_hw_set_lladdr(ah, zero_mac); |
328 | 328 | ||
329 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ | 329 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ |
330 | memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); | 330 | eth_broadcast_addr(common->curbssid); |
331 | ath5k_hw_set_bssid(ah); | 331 | ath5k_hw_set_bssid(ah); |
332 | ath5k_hw_set_opmode(ah, ah->opmode); | 332 | ath5k_hw_set_opmode(ah, ah->opmode); |
333 | 333 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 527afcf39246..a2351ef45ae0 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -73,16 +73,16 @@ | |||
73 | #include "trace.h" | 73 | #include "trace.h" |
74 | 74 | ||
75 | bool ath5k_modparam_nohwcrypt; | 75 | bool ath5k_modparam_nohwcrypt; |
76 | module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO); | 76 | module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, 0444); |
77 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 77 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
78 | 78 | ||
79 | static bool modparam_fastchanswitch; | 79 | static bool modparam_fastchanswitch; |
80 | module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); | 80 | module_param_named(fastchanswitch, modparam_fastchanswitch, bool, 0444); |
81 | MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); | 81 | MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); |
82 | 82 | ||
83 | static bool ath5k_modparam_no_hw_rfkill_switch; | 83 | static bool ath5k_modparam_no_hw_rfkill_switch; |
84 | module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch, | 84 | module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch, |
85 | bool, S_IRUGO); | 85 | bool, 0444); |
86 | MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state"); | 86 | MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state"); |
87 | 87 | ||
88 | 88 | ||
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index bd7f6d7b199e..3513bbec4639 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -1004,32 +1004,17 @@ ath5k_debug_init_device(struct ath5k_hw *ah) | |||
1004 | if (!phydir) | 1004 | if (!phydir) |
1005 | return; | 1005 | return; |
1006 | 1006 | ||
1007 | debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, ah, | 1007 | debugfs_create_file("debug", 0600, phydir, ah, &fops_debug); |
1008 | &fops_debug); | 1008 | debugfs_create_file("registers", 0400, phydir, ah, &fops_registers); |
1009 | 1009 | debugfs_create_file("beacon", 0600, phydir, ah, &fops_beacon); | |
1010 | debugfs_create_file("registers", S_IRUSR, phydir, ah, &fops_registers); | 1010 | debugfs_create_file("reset", 0200, phydir, ah, &fops_reset); |
1011 | 1011 | debugfs_create_file("antenna", 0600, phydir, ah, &fops_antenna); | |
1012 | debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah, | 1012 | debugfs_create_file("misc", 0400, phydir, ah, &fops_misc); |
1013 | &fops_beacon); | 1013 | debugfs_create_file("eeprom", 0400, phydir, ah, &fops_eeprom); |
1014 | 1014 | debugfs_create_file("frameerrors", 0600, phydir, ah, &fops_frameerrors); | |
1015 | debugfs_create_file("reset", S_IWUSR, phydir, ah, &fops_reset); | 1015 | debugfs_create_file("ani", 0600, phydir, ah, &fops_ani); |
1016 | 1016 | debugfs_create_file("queue", 0600, phydir, ah, &fops_queue); | |
1017 | debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah, | 1017 | debugfs_create_bool("32khz_clock", 0600, phydir, |
1018 | &fops_antenna); | ||
1019 | |||
1020 | debugfs_create_file("misc", S_IRUSR, phydir, ah, &fops_misc); | ||
1021 | |||
1022 | debugfs_create_file("eeprom", S_IRUSR, phydir, ah, &fops_eeprom); | ||
1023 | |||
1024 | debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, ah, | ||
1025 | &fops_frameerrors); | ||
1026 | |||
1027 | debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, ah, &fops_ani); | ||
1028 | |||
1029 | debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, ah, | ||
1030 | &fops_queue); | ||
1031 | |||
1032 | debugfs_create_bool("32khz_clock", S_IWUSR | S_IRUSR, phydir, | ||
1033 | &ah->ah_use_32khz_clock); | 1018 | &ah->ah_use_32khz_clock); |
1034 | } | 1019 | } |
1035 | 1020 | ||
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index beda11ce34a7..147947f632f7 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -327,8 +327,6 @@ ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
327 | 327 | ||
328 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | 328 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); |
329 | 329 | ||
330 | tq = &ah->ah_txq[queue]; | ||
331 | |||
332 | /* Skip if queue inactive or if we are on AR5210 | 330 | /* Skip if queue inactive or if we are on AR5210 |
333 | * that doesn't have QCU/DCU */ | 331 | * that doesn't have QCU/DCU */ |
334 | if ((ah->ah_version == AR5K_AR5210) || | 332 | if ((ah->ah_version == AR5K_AR5210) || |
diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c index 25978c732fe1..8113baddd8fc 100644 --- a/drivers/net/wireless/ath/ath5k/sysfs.c +++ b/drivers/net/wireless/ath/ath5k/sysfs.c | |||
@@ -31,7 +31,7 @@ static ssize_t ath5k_attr_store_##name(struct device *dev, \ | |||
31 | set(ah, val); \ | 31 | set(ah, val); \ |
32 | return count; \ | 32 | return count; \ |
33 | } \ | 33 | } \ |
34 | static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, \ | 34 | static DEVICE_ATTR(name, 0644, \ |
35 | ath5k_attr_show_##name, ath5k_attr_store_##name) | 35 | ath5k_attr_show_##name, ath5k_attr_store_##name) |
36 | 36 | ||
37 | #define SIMPLE_SHOW(name, get) \ | 37 | #define SIMPLE_SHOW(name, get) \ |
@@ -43,7 +43,7 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \ | |||
43 | struct ath5k_hw *ah = hw->priv; \ | 43 | struct ath5k_hw *ah = hw->priv; \ |
44 | return snprintf(buf, PAGE_SIZE, "%d\n", get); \ | 44 | return snprintf(buf, PAGE_SIZE, "%d\n", get); \ |
45 | } \ | 45 | } \ |
46 | static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) | 46 | static DEVICE_ATTR(name, 0444, ath5k_attr_show_##name, NULL) |
47 | 47 | ||
48 | /*** ANI ***/ | 48 | /*** ANI ***/ |
49 | 49 | ||
@@ -66,7 +66,7 @@ static ssize_t ath5k_attr_show_noise_immunity_level_max(struct device *dev, | |||
66 | { | 66 | { |
67 | return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_NOISE_IMM_LVL); | 67 | return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_NOISE_IMM_LVL); |
68 | } | 68 | } |
69 | static DEVICE_ATTR(noise_immunity_level_max, S_IRUGO, | 69 | static DEVICE_ATTR(noise_immunity_level_max, 0444, |
70 | ath5k_attr_show_noise_immunity_level_max, NULL); | 70 | ath5k_attr_show_noise_immunity_level_max, NULL); |
71 | 71 | ||
72 | static ssize_t ath5k_attr_show_firstep_level_max(struct device *dev, | 72 | static ssize_t ath5k_attr_show_firstep_level_max(struct device *dev, |
@@ -75,7 +75,7 @@ static ssize_t ath5k_attr_show_firstep_level_max(struct device *dev, | |||
75 | { | 75 | { |
76 | return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_FIRSTEP_LVL); | 76 | return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_FIRSTEP_LVL); |
77 | } | 77 | } |
78 | static DEVICE_ATTR(firstep_level_max, S_IRUGO, | 78 | static DEVICE_ATTR(firstep_level_max, 0444, |
79 | ath5k_attr_show_firstep_level_max, NULL); | 79 | ath5k_attr_show_firstep_level_max, NULL); |
80 | 80 | ||
81 | static struct attribute *ath5k_sysfs_entries_ani[] = { | 81 | static struct attribute *ath5k_sysfs_entries_ani[] = { |
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 1eea6c23976f..0f965e9f38a4 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c | |||
@@ -1794,69 +1794,68 @@ int ath6kl_debug_init_fs(struct ath6kl *ar) | |||
1794 | if (!ar->debugfs_phy) | 1794 | if (!ar->debugfs_phy) |
1795 | return -ENOMEM; | 1795 | return -ENOMEM; |
1796 | 1796 | ||
1797 | debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar, | 1797 | debugfs_create_file("tgt_stats", 0400, ar->debugfs_phy, ar, |
1798 | &fops_tgt_stats); | 1798 | &fops_tgt_stats); |
1799 | 1799 | ||
1800 | if (ar->hif_type == ATH6KL_HIF_TYPE_SDIO) | 1800 | if (ar->hif_type == ATH6KL_HIF_TYPE_SDIO) |
1801 | debugfs_create_file("credit_dist_stats", S_IRUSR, | 1801 | debugfs_create_file("credit_dist_stats", 0400, |
1802 | ar->debugfs_phy, ar, | 1802 | ar->debugfs_phy, ar, |
1803 | &fops_credit_dist_stats); | 1803 | &fops_credit_dist_stats); |
1804 | 1804 | ||
1805 | debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR, | 1805 | debugfs_create_file("endpoint_stats", 0600, |
1806 | ar->debugfs_phy, ar, &fops_endpoint_stats); | 1806 | ar->debugfs_phy, ar, &fops_endpoint_stats); |
1807 | 1807 | ||
1808 | debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar, | 1808 | debugfs_create_file("fwlog", 0400, ar->debugfs_phy, ar, &fops_fwlog); |
1809 | &fops_fwlog); | ||
1810 | 1809 | ||
1811 | debugfs_create_file("fwlog_block", S_IRUSR, ar->debugfs_phy, ar, | 1810 | debugfs_create_file("fwlog_block", 0400, ar->debugfs_phy, ar, |
1812 | &fops_fwlog_block); | 1811 | &fops_fwlog_block); |
1813 | 1812 | ||
1814 | debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy, | 1813 | debugfs_create_file("fwlog_mask", 0600, ar->debugfs_phy, |
1815 | ar, &fops_fwlog_mask); | 1814 | ar, &fops_fwlog_mask); |
1816 | 1815 | ||
1817 | debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar, | 1816 | debugfs_create_file("reg_addr", 0600, ar->debugfs_phy, ar, |
1818 | &fops_diag_reg_read); | 1817 | &fops_diag_reg_read); |
1819 | 1818 | ||
1820 | debugfs_create_file("reg_dump", S_IRUSR, ar->debugfs_phy, ar, | 1819 | debugfs_create_file("reg_dump", 0400, ar->debugfs_phy, ar, |
1821 | &fops_reg_dump); | 1820 | &fops_reg_dump); |
1822 | 1821 | ||
1823 | debugfs_create_file("lrssi_roam_threshold", S_IRUSR | S_IWUSR, | 1822 | debugfs_create_file("lrssi_roam_threshold", 0600, |
1824 | ar->debugfs_phy, ar, &fops_lrssi_roam_threshold); | 1823 | ar->debugfs_phy, ar, &fops_lrssi_roam_threshold); |
1825 | 1824 | ||
1826 | debugfs_create_file("reg_write", S_IRUSR | S_IWUSR, | 1825 | debugfs_create_file("reg_write", 0600, |
1827 | ar->debugfs_phy, ar, &fops_diag_reg_write); | 1826 | ar->debugfs_phy, ar, &fops_diag_reg_write); |
1828 | 1827 | ||
1829 | debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar, | 1828 | debugfs_create_file("war_stats", 0400, ar->debugfs_phy, ar, |
1830 | &fops_war_stats); | 1829 | &fops_war_stats); |
1831 | 1830 | ||
1832 | debugfs_create_file("roam_table", S_IRUSR, ar->debugfs_phy, ar, | 1831 | debugfs_create_file("roam_table", 0400, ar->debugfs_phy, ar, |
1833 | &fops_roam_table); | 1832 | &fops_roam_table); |
1834 | 1833 | ||
1835 | debugfs_create_file("force_roam", S_IWUSR, ar->debugfs_phy, ar, | 1834 | debugfs_create_file("force_roam", 0200, ar->debugfs_phy, ar, |
1836 | &fops_force_roam); | 1835 | &fops_force_roam); |
1837 | 1836 | ||
1838 | debugfs_create_file("roam_mode", S_IWUSR, ar->debugfs_phy, ar, | 1837 | debugfs_create_file("roam_mode", 0200, ar->debugfs_phy, ar, |
1839 | &fops_roam_mode); | 1838 | &fops_roam_mode); |
1840 | 1839 | ||
1841 | debugfs_create_file("keepalive", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar, | 1840 | debugfs_create_file("keepalive", 0600, ar->debugfs_phy, ar, |
1842 | &fops_keepalive); | 1841 | &fops_keepalive); |
1843 | 1842 | ||
1844 | debugfs_create_file("disconnect_timeout", S_IRUSR | S_IWUSR, | 1843 | debugfs_create_file("disconnect_timeout", 0600, |
1845 | ar->debugfs_phy, ar, &fops_disconnect_timeout); | 1844 | ar->debugfs_phy, ar, &fops_disconnect_timeout); |
1846 | 1845 | ||
1847 | debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar, | 1846 | debugfs_create_file("create_qos", 0200, ar->debugfs_phy, ar, |
1848 | &fops_create_qos); | 1847 | &fops_create_qos); |
1849 | 1848 | ||
1850 | debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar, | 1849 | debugfs_create_file("delete_qos", 0200, ar->debugfs_phy, ar, |
1851 | &fops_delete_qos); | 1850 | &fops_delete_qos); |
1852 | 1851 | ||
1853 | debugfs_create_file("bgscan_interval", S_IWUSR, | 1852 | debugfs_create_file("bgscan_interval", 0200, |
1854 | ar->debugfs_phy, ar, &fops_bgscan_int); | 1853 | ar->debugfs_phy, ar, &fops_bgscan_int); |
1855 | 1854 | ||
1856 | debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR, | 1855 | debugfs_create_file("listen_interval", 0600, |
1857 | ar->debugfs_phy, ar, &fops_listen_int); | 1856 | ar->debugfs_phy, ar, &fops_listen_int); |
1858 | 1857 | ||
1859 | debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar, | 1858 | debugfs_create_file("power_params", 0200, ar->debugfs_phy, ar, |
1860 | &fops_power_params); | 1859 | &fops_power_params); |
1861 | 1860 | ||
1862 | return 0; | 1861 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/common-debug.c b/drivers/net/wireless/ath/ath9k/common-debug.c index 84afcf78151f..239429f10378 100644 --- a/drivers/net/wireless/ath/ath9k/common-debug.c +++ b/drivers/net/wireless/ath/ath9k/common-debug.c | |||
@@ -47,7 +47,7 @@ static const struct file_operations fops_modal_eeprom = { | |||
47 | void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy, | 47 | void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy, |
48 | struct ath_hw *ah) | 48 | struct ath_hw *ah) |
49 | { | 49 | { |
50 | debugfs_create_file("modal_eeprom", S_IRUSR, debugfs_phy, ah, | 50 | debugfs_create_file("modal_eeprom", 0400, debugfs_phy, ah, |
51 | &fops_modal_eeprom); | 51 | &fops_modal_eeprom); |
52 | } | 52 | } |
53 | EXPORT_SYMBOL(ath9k_cmn_debug_modal_eeprom); | 53 | EXPORT_SYMBOL(ath9k_cmn_debug_modal_eeprom); |
@@ -82,7 +82,7 @@ static const struct file_operations fops_base_eeprom = { | |||
82 | void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy, | 82 | void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy, |
83 | struct ath_hw *ah) | 83 | struct ath_hw *ah) |
84 | { | 84 | { |
85 | debugfs_create_file("base_eeprom", S_IRUSR, debugfs_phy, ah, | 85 | debugfs_create_file("base_eeprom", 0400, debugfs_phy, ah, |
86 | &fops_base_eeprom); | 86 | &fops_base_eeprom); |
87 | } | 87 | } |
88 | EXPORT_SYMBOL(ath9k_cmn_debug_base_eeprom); | 88 | EXPORT_SYMBOL(ath9k_cmn_debug_base_eeprom); |
@@ -178,8 +178,7 @@ static const struct file_operations fops_recv = { | |||
178 | void ath9k_cmn_debug_recv(struct dentry *debugfs_phy, | 178 | void ath9k_cmn_debug_recv(struct dentry *debugfs_phy, |
179 | struct ath_rx_stats *rxstats) | 179 | struct ath_rx_stats *rxstats) |
180 | { | 180 | { |
181 | debugfs_create_file("recv", S_IRUSR, debugfs_phy, rxstats, | 181 | debugfs_create_file("recv", 0400, debugfs_phy, rxstats, &fops_recv); |
182 | &fops_recv); | ||
183 | } | 182 | } |
184 | EXPORT_SYMBOL(ath9k_cmn_debug_recv); | 183 | EXPORT_SYMBOL(ath9k_cmn_debug_recv); |
185 | 184 | ||
@@ -255,7 +254,7 @@ static const struct file_operations fops_phy_err = { | |||
255 | void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy, | 254 | void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy, |
256 | struct ath_rx_stats *rxstats) | 255 | struct ath_rx_stats *rxstats) |
257 | { | 256 | { |
258 | debugfs_create_file("phy_err", S_IRUSR, debugfs_phy, rxstats, | 257 | debugfs_create_file("phy_err", 0400, debugfs_phy, rxstats, |
259 | &fops_phy_err); | 258 | &fops_phy_err); |
260 | } | 259 | } |
261 | EXPORT_SYMBOL(ath9k_cmn_debug_phy_err); | 260 | EXPORT_SYMBOL(ath9k_cmn_debug_phy_err); |
diff --git a/drivers/net/wireless/ath/ath9k/common-init.c b/drivers/net/wireless/ath/ath9k/common-init.c index 8b4f7fdabf58..82de0fadbc95 100644 --- a/drivers/net/wireless/ath/ath9k/common-init.c +++ b/drivers/net/wireless/ath/ath9k/common-init.c | |||
@@ -88,7 +88,7 @@ static const struct ieee80211_channel ath9k_5ghz_chantable[] = { | |||
88 | CHAN5G(5825, 37), /* Channel 165 */ | 88 | CHAN5G(5825, 37), /* Channel 165 */ |
89 | }; | 89 | }; |
90 | 90 | ||
91 | /* Atheros hardware rate code addition for short premble */ | 91 | /* Atheros hardware rate code addition for short preamble */ |
92 | #define SHPCHECK(__hw_rate, __flags) \ | 92 | #define SHPCHECK(__hw_rate, __flags) \ |
93 | ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) | 93 | ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) |
94 | 94 | ||
diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c index 5e77fe1f5b0d..440e16e641e4 100644 --- a/drivers/net/wireless/ath/ath9k/common-spectral.c +++ b/drivers/net/wireless/ath/ath9k/common-spectral.c | |||
@@ -479,14 +479,16 @@ ath_cmn_is_fft_buf_full(struct ath_spec_scan_priv *spec_priv) | |||
479 | { | 479 | { |
480 | int i = 0; | 480 | int i = 0; |
481 | int ret = 0; | 481 | int ret = 0; |
482 | struct rchan_buf *buf; | ||
482 | struct rchan *rc = spec_priv->rfs_chan_spec_scan; | 483 | struct rchan *rc = spec_priv->rfs_chan_spec_scan; |
483 | 484 | ||
484 | for_each_online_cpu(i) | 485 | for_each_possible_cpu(i) { |
485 | ret += relay_buf_full(*per_cpu_ptr(rc->buf, i)); | 486 | if ((buf = *per_cpu_ptr(rc->buf, i))) { |
486 | 487 | ret += relay_buf_full(buf); | |
487 | i = num_online_cpus(); | 488 | } |
489 | } | ||
488 | 490 | ||
489 | if (ret == i) | 491 | if (ret) |
490 | return 1; | 492 | return 1; |
491 | else | 493 | else |
492 | return 0; | 494 | return 0; |
@@ -1096,23 +1098,23 @@ void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, | |||
1096 | return; | 1098 | return; |
1097 | 1099 | ||
1098 | debugfs_create_file("spectral_scan_ctl", | 1100 | debugfs_create_file("spectral_scan_ctl", |
1099 | S_IRUSR | S_IWUSR, | 1101 | 0600, |
1100 | debugfs_phy, spec_priv, | 1102 | debugfs_phy, spec_priv, |
1101 | &fops_spec_scan_ctl); | 1103 | &fops_spec_scan_ctl); |
1102 | debugfs_create_file("spectral_short_repeat", | 1104 | debugfs_create_file("spectral_short_repeat", |
1103 | S_IRUSR | S_IWUSR, | 1105 | 0600, |
1104 | debugfs_phy, spec_priv, | 1106 | debugfs_phy, spec_priv, |
1105 | &fops_spectral_short_repeat); | 1107 | &fops_spectral_short_repeat); |
1106 | debugfs_create_file("spectral_count", | 1108 | debugfs_create_file("spectral_count", |
1107 | S_IRUSR | S_IWUSR, | 1109 | 0600, |
1108 | debugfs_phy, spec_priv, | 1110 | debugfs_phy, spec_priv, |
1109 | &fops_spectral_count); | 1111 | &fops_spectral_count); |
1110 | debugfs_create_file("spectral_period", | 1112 | debugfs_create_file("spectral_period", |
1111 | S_IRUSR | S_IWUSR, | 1113 | 0600, |
1112 | debugfs_phy, spec_priv, | 1114 | debugfs_phy, spec_priv, |
1113 | &fops_spectral_period); | 1115 | &fops_spectral_period); |
1114 | debugfs_create_file("spectral_fft_period", | 1116 | debugfs_create_file("spectral_fft_period", |
1115 | S_IRUSR | S_IWUSR, | 1117 | 0600, |
1116 | debugfs_phy, spec_priv, | 1118 | debugfs_phy, spec_priv, |
1117 | &fops_spectral_fft_period); | 1119 | &fops_spectral_fft_period); |
1118 | } | 1120 | } |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 9e8aed5c478c..f685843a2ff3 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -1385,7 +1385,7 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1385 | return -ENOMEM; | 1385 | return -ENOMEM; |
1386 | 1386 | ||
1387 | #ifdef CONFIG_ATH_DEBUG | 1387 | #ifdef CONFIG_ATH_DEBUG |
1388 | debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1388 | debugfs_create_file("debug", 0600, sc->debug.debugfs_phy, |
1389 | sc, &fops_debug); | 1389 | sc, &fops_debug); |
1390 | #endif | 1390 | #endif |
1391 | 1391 | ||
@@ -1409,22 +1409,22 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1409 | ath9k_cmn_debug_recv(sc->debug.debugfs_phy, &sc->debug.stats.rxstats); | 1409 | ath9k_cmn_debug_recv(sc->debug.debugfs_phy, &sc->debug.stats.rxstats); |
1410 | ath9k_cmn_debug_phy_err(sc->debug.debugfs_phy, &sc->debug.stats.rxstats); | 1410 | ath9k_cmn_debug_phy_err(sc->debug.debugfs_phy, &sc->debug.stats.rxstats); |
1411 | 1411 | ||
1412 | debugfs_create_u8("rx_chainmask", S_IRUSR, sc->debug.debugfs_phy, | 1412 | debugfs_create_u8("rx_chainmask", 0400, sc->debug.debugfs_phy, |
1413 | &ah->rxchainmask); | 1413 | &ah->rxchainmask); |
1414 | debugfs_create_u8("tx_chainmask", S_IRUSR, sc->debug.debugfs_phy, | 1414 | debugfs_create_u8("tx_chainmask", 0400, sc->debug.debugfs_phy, |
1415 | &ah->txchainmask); | 1415 | &ah->txchainmask); |
1416 | debugfs_create_file("ani", S_IRUSR | S_IWUSR, | 1416 | debugfs_create_file("ani", 0600, |
1417 | sc->debug.debugfs_phy, sc, &fops_ani); | 1417 | sc->debug.debugfs_phy, sc, &fops_ani); |
1418 | debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1418 | debugfs_create_bool("paprd", 0600, sc->debug.debugfs_phy, |
1419 | &sc->sc_ah->config.enable_paprd); | 1419 | &sc->sc_ah->config.enable_paprd); |
1420 | debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1420 | debugfs_create_file("regidx", 0600, sc->debug.debugfs_phy, |
1421 | sc, &fops_regidx); | 1421 | sc, &fops_regidx); |
1422 | debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1422 | debugfs_create_file("regval", 0600, sc->debug.debugfs_phy, |
1423 | sc, &fops_regval); | 1423 | sc, &fops_regval); |
1424 | debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR, | 1424 | debugfs_create_bool("ignore_extcca", 0600, |
1425 | sc->debug.debugfs_phy, | 1425 | sc->debug.debugfs_phy, |
1426 | &ah->config.cwm_ignore_extcca); | 1426 | &ah->config.cwm_ignore_extcca); |
1427 | debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, | 1427 | debugfs_create_file("regdump", 0400, sc->debug.debugfs_phy, sc, |
1428 | &fops_regdump); | 1428 | &fops_regdump); |
1429 | debugfs_create_devm_seqfile(sc->dev, "dump_nfcal", | 1429 | debugfs_create_devm_seqfile(sc->dev, "dump_nfcal", |
1430 | sc->debug.debugfs_phy, | 1430 | sc->debug.debugfs_phy, |
@@ -1433,35 +1433,33 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1433 | ath9k_cmn_debug_base_eeprom(sc->debug.debugfs_phy, sc->sc_ah); | 1433 | ath9k_cmn_debug_base_eeprom(sc->debug.debugfs_phy, sc->sc_ah); |
1434 | ath9k_cmn_debug_modal_eeprom(sc->debug.debugfs_phy, sc->sc_ah); | 1434 | ath9k_cmn_debug_modal_eeprom(sc->debug.debugfs_phy, sc->sc_ah); |
1435 | 1435 | ||
1436 | debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, | 1436 | debugfs_create_u32("gpio_mask", 0600, |
1437 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); | 1437 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); |
1438 | debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, | 1438 | debugfs_create_u32("gpio_val", 0600, |
1439 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); | 1439 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); |
1440 | debugfs_create_file("antenna_diversity", S_IRUSR, | 1440 | debugfs_create_file("antenna_diversity", 0400, |
1441 | sc->debug.debugfs_phy, sc, &fops_antenna_diversity); | 1441 | sc->debug.debugfs_phy, sc, &fops_antenna_diversity); |
1442 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 1442 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
1443 | debugfs_create_file("bt_ant_diversity", S_IRUSR | S_IWUSR, | 1443 | debugfs_create_file("bt_ant_diversity", 0600, |
1444 | sc->debug.debugfs_phy, sc, &fops_bt_ant_diversity); | 1444 | sc->debug.debugfs_phy, sc, &fops_bt_ant_diversity); |
1445 | debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, | 1445 | debugfs_create_file("btcoex", 0400, sc->debug.debugfs_phy, sc, |
1446 | &fops_btcoex); | 1446 | &fops_btcoex); |
1447 | #endif | 1447 | #endif |
1448 | 1448 | ||
1449 | #ifdef CONFIG_ATH9K_WOW | 1449 | #ifdef CONFIG_ATH9K_WOW |
1450 | debugfs_create_file("wow", S_IRUSR | S_IWUSR, | 1450 | debugfs_create_file("wow", 0600, sc->debug.debugfs_phy, sc, &fops_wow); |
1451 | sc->debug.debugfs_phy, sc, &fops_wow); | ||
1452 | #endif | 1451 | #endif |
1453 | 1452 | ||
1454 | #ifdef CONFIG_ATH9K_DYNACK | 1453 | #ifdef CONFIG_ATH9K_DYNACK |
1455 | debugfs_create_file("ack_to", S_IRUSR, sc->debug.debugfs_phy, | 1454 | debugfs_create_file("ack_to", 0400, sc->debug.debugfs_phy, |
1456 | sc, &fops_ackto); | 1455 | sc, &fops_ackto); |
1457 | #endif | 1456 | #endif |
1458 | debugfs_create_file("tpc", S_IRUSR | S_IWUSR, | 1457 | debugfs_create_file("tpc", 0600, sc->debug.debugfs_phy, sc, &fops_tpc); |
1459 | sc->debug.debugfs_phy, sc, &fops_tpc); | ||
1460 | 1458 | ||
1461 | debugfs_create_u16("airtime_flags", S_IRUSR | S_IWUSR, | 1459 | debugfs_create_u16("airtime_flags", 0600, |
1462 | sc->debug.debugfs_phy, &sc->airtime_flags); | 1460 | sc->debug.debugfs_phy, &sc->airtime_flags); |
1463 | 1461 | ||
1464 | debugfs_create_file("nf_override", S_IRUSR | S_IWUSR, | 1462 | debugfs_create_file("nf_override", 0600, |
1465 | sc->debug.debugfs_phy, sc, &fops_nf_override); | 1463 | sc->debug.debugfs_phy, sc, &fops_nf_override); |
1466 | 1464 | ||
1467 | return 0; | 1465 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c index efc692ee67d4..a6f45f1bb5bb 100644 --- a/drivers/net/wireless/ath/ath9k/debug_sta.c +++ b/drivers/net/wireless/ath/ath9k/debug_sta.c | |||
@@ -302,7 +302,7 @@ void ath9k_sta_add_debugfs(struct ieee80211_hw *hw, | |||
302 | { | 302 | { |
303 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | 303 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
304 | 304 | ||
305 | debugfs_create_file("node_aggr", S_IRUGO, dir, an, &fops_node_aggr); | 305 | debugfs_create_file("node_aggr", 0444, dir, an, &fops_node_aggr); |
306 | debugfs_create_file("node_recv", S_IRUGO, dir, an, &fops_node_recv); | 306 | debugfs_create_file("node_recv", 0444, dir, an, &fops_node_recv); |
307 | debugfs_create_file("airtime", S_IRUGO, dir, an, &fops_airtime); | 307 | debugfs_create_file("airtime", 0444, dir, an, &fops_airtime); |
308 | } | 308 | } |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.c b/drivers/net/wireless/ath/ath9k/dfs_debug.c index 8824610c21fb..3251c9abe270 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_debug.c +++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c | |||
@@ -144,8 +144,8 @@ static const struct file_operations fops_dfs_stats = { | |||
144 | 144 | ||
145 | void ath9k_dfs_init_debug(struct ath_softc *sc) | 145 | void ath9k_dfs_init_debug(struct ath_softc *sc) |
146 | { | 146 | { |
147 | debugfs_create_file("dfs_stats", S_IRUSR, | 147 | debugfs_create_file("dfs_stats", 0400, |
148 | sc->debug.debugfs_phy, sc, &fops_dfs_stats); | 148 | sc->debug.debugfs_phy, sc, &fops_dfs_stats); |
149 | debugfs_create_file("dfs_simulate_radar", S_IWUSR, | 149 | debugfs_create_file("dfs_simulate_radar", 0200, |
150 | sc->debug.debugfs_phy, sc, &fops_simulate_radar); | 150 | sc->debug.debugfs_phy, sc, &fops_simulate_radar); |
151 | } | 151 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index dc79afd7e151..b3ed65e5c4da 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c | |||
@@ -496,25 +496,25 @@ int ath9k_htc_init_debug(struct ath_hw *ah) | |||
496 | 496 | ||
497 | ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy); | 497 | ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy); |
498 | 498 | ||
499 | debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy, | 499 | debugfs_create_file("tgt_int_stats", 0400, priv->debug.debugfs_phy, |
500 | priv, &fops_tgt_int_stats); | 500 | priv, &fops_tgt_int_stats); |
501 | debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy, | 501 | debugfs_create_file("tgt_tx_stats", 0400, priv->debug.debugfs_phy, |
502 | priv, &fops_tgt_tx_stats); | 502 | priv, &fops_tgt_tx_stats); |
503 | debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy, | 503 | debugfs_create_file("tgt_rx_stats", 0400, priv->debug.debugfs_phy, |
504 | priv, &fops_tgt_rx_stats); | 504 | priv, &fops_tgt_rx_stats); |
505 | debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, | 505 | debugfs_create_file("xmit", 0400, priv->debug.debugfs_phy, |
506 | priv, &fops_xmit); | 506 | priv, &fops_xmit); |
507 | debugfs_create_file("skb_rx", S_IRUSR, priv->debug.debugfs_phy, | 507 | debugfs_create_file("skb_rx", 0400, priv->debug.debugfs_phy, |
508 | priv, &fops_skb_rx); | 508 | priv, &fops_skb_rx); |
509 | 509 | ||
510 | ath9k_cmn_debug_recv(priv->debug.debugfs_phy, &priv->debug.rx_stats); | 510 | ath9k_cmn_debug_recv(priv->debug.debugfs_phy, &priv->debug.rx_stats); |
511 | ath9k_cmn_debug_phy_err(priv->debug.debugfs_phy, &priv->debug.rx_stats); | 511 | ath9k_cmn_debug_phy_err(priv->debug.debugfs_phy, &priv->debug.rx_stats); |
512 | 512 | ||
513 | debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy, | 513 | debugfs_create_file("slot", 0400, priv->debug.debugfs_phy, |
514 | priv, &fops_slot); | 514 | priv, &fops_slot); |
515 | debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy, | 515 | debugfs_create_file("queue", 0400, priv->debug.debugfs_phy, |
516 | priv, &fops_queue); | 516 | priv, &fops_queue); |
517 | debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy, | 517 | debugfs_create_file("debug", 0600, priv->debug.debugfs_phy, |
518 | priv, &fops_debug); | 518 | priv, &fops_debug); |
519 | 519 | ||
520 | ath9k_cmn_debug_base_eeprom(priv->debug.debugfs_phy, priv->ah); | 520 | ath9k_cmn_debug_base_eeprom(priv->debug.debugfs_phy, priv->ah); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index f246e9ed4a81..214c68269a69 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -591,7 +591,7 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv) | |||
591 | { | 591 | { |
592 | struct ath_common *common = ath9k_hw_common(priv->ah); | 592 | struct ath_common *common = ath9k_hw_common(priv->ah); |
593 | 593 | ||
594 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 594 | eth_broadcast_addr(common->bssidmask); |
595 | 595 | ||
596 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; | 596 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; |
597 | priv->ah->opmode = NL80211_IFTYPE_STATION; | 597 | priv->ah->opmode = NL80211_IFTYPE_STATION; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index cd0f023ccf77..6b37036b2d36 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -184,7 +184,8 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah, | |||
184 | break; | 184 | break; |
185 | case WLAN_RC_PHY_OFDM: | 185 | case WLAN_RC_PHY_OFDM: |
186 | if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) { | 186 | if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) { |
187 | bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000; | 187 | bitsPerSymbol = |
188 | ((kbps >> 2) * OFDM_SYMBOL_TIME_QUARTER) / 1000; | ||
188 | numBits = OFDM_PLCP_BITS + (frameLen << 3); | 189 | numBits = OFDM_PLCP_BITS + (frameLen << 3); |
189 | numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); | 190 | numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); |
190 | txTime = OFDM_SIFS_TIME_QUARTER | 191 | txTime = OFDM_SIFS_TIME_QUARTER |
@@ -192,7 +193,8 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah, | |||
192 | + (numSymbols * OFDM_SYMBOL_TIME_QUARTER); | 193 | + (numSymbols * OFDM_SYMBOL_TIME_QUARTER); |
193 | } else if (ah->curchan && | 194 | } else if (ah->curchan && |
194 | IS_CHAN_HALF_RATE(ah->curchan)) { | 195 | IS_CHAN_HALF_RATE(ah->curchan)) { |
195 | bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000; | 196 | bitsPerSymbol = |
197 | ((kbps >> 1) * OFDM_SYMBOL_TIME_HALF) / 1000; | ||
196 | numBits = OFDM_PLCP_BITS + (frameLen << 3); | 198 | numBits = OFDM_PLCP_BITS + (frameLen << 3); |
197 | numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); | 199 | numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); |
198 | txTime = OFDM_SIFS_TIME_HALF + | 200 | txTime = OFDM_SIFS_TIME_HALF + |
@@ -1036,7 +1038,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
1036 | int acktimeout, ctstimeout, ack_offset = 0; | 1038 | int acktimeout, ctstimeout, ack_offset = 0; |
1037 | int slottime; | 1039 | int slottime; |
1038 | int sifstime; | 1040 | int sifstime; |
1039 | int rx_lat = 0, tx_lat = 0, eifs = 0; | 1041 | int rx_lat = 0, tx_lat = 0, eifs = 0, ack_shift = 0; |
1040 | u32 reg; | 1042 | u32 reg; |
1041 | 1043 | ||
1042 | ath_dbg(ath9k_hw_common(ah), RESET, "ah->misc_mode 0x%x\n", | 1044 | ath_dbg(ath9k_hw_common(ah), RESET, "ah->misc_mode 0x%x\n", |
@@ -1068,6 +1070,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
1068 | 1070 | ||
1069 | sifstime = 32; | 1071 | sifstime = 32; |
1070 | ack_offset = 16; | 1072 | ack_offset = 16; |
1073 | ack_shift = 3; | ||
1071 | slottime = 13; | 1074 | slottime = 13; |
1072 | } else if (IS_CHAN_QUARTER_RATE(chan)) { | 1075 | } else if (IS_CHAN_QUARTER_RATE(chan)) { |
1073 | eifs = 340; | 1076 | eifs = 340; |
@@ -1078,6 +1081,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
1078 | 1081 | ||
1079 | sifstime = 64; | 1082 | sifstime = 64; |
1080 | ack_offset = 32; | 1083 | ack_offset = 32; |
1084 | ack_shift = 1; | ||
1081 | slottime = 21; | 1085 | slottime = 21; |
1082 | } else { | 1086 | } else { |
1083 | if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) { | 1087 | if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) { |
@@ -1134,6 +1138,10 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
1134 | SM(tx_lat, AR_USEC_TX_LAT), | 1138 | SM(tx_lat, AR_USEC_TX_LAT), |
1135 | AR_USEC_TX_LAT | AR_USEC_RX_LAT | AR_USEC_USEC); | 1139 | AR_USEC_TX_LAT | AR_USEC_RX_LAT | AR_USEC_USEC); |
1136 | 1140 | ||
1141 | if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) | ||
1142 | REG_RMW(ah, AR_TXSIFS, | ||
1143 | sifstime | SM(ack_shift, AR_TXSIFS_ACK_SHIFT), | ||
1144 | (AR_TXSIFS_TIME | AR_TXSIFS_ACK_SHIFT)); | ||
1137 | } | 1145 | } |
1138 | EXPORT_SYMBOL(ath9k_hw_init_global_settings); | 1146 | EXPORT_SYMBOL(ath9k_hw_init_global_settings); |
1139 | 1147 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index e479fae5aab9..c070a9e51ebf 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -257,6 +257,11 @@ static void ath9k_reg_notifier(struct wiphy *wiphy, | |||
257 | 257 | ||
258 | ath_reg_notifier_apply(wiphy, request, reg); | 258 | ath_reg_notifier_apply(wiphy, request, reg); |
259 | 259 | ||
260 | /* synchronize DFS detector if regulatory domain changed */ | ||
261 | if (sc->dfs_detector != NULL) | ||
262 | sc->dfs_detector->set_dfs_domain(sc->dfs_detector, | ||
263 | request->dfs_region); | ||
264 | |||
260 | /* Set tx power */ | 265 | /* Set tx power */ |
261 | if (!ah->curchan) | 266 | if (!ah->curchan) |
262 | return; | 267 | return; |
@@ -267,10 +272,6 @@ static void ath9k_reg_notifier(struct wiphy *wiphy, | |||
267 | ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower, | 272 | ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower, |
268 | sc->cur_chan->txpower, | 273 | sc->cur_chan->txpower, |
269 | &sc->cur_chan->cur_txpower); | 274 | &sc->cur_chan->cur_txpower); |
270 | /* synchronize DFS detector if regulatory domain changed */ | ||
271 | if (sc->dfs_detector != NULL) | ||
272 | sc->dfs_detector->set_dfs_domain(sc->dfs_detector, | ||
273 | request->dfs_region); | ||
274 | ath9k_ps_restore(sc); | 275 | ath9k_ps_restore(sc); |
275 | } | 276 | } |
276 | 277 | ||
@@ -427,7 +428,7 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
427 | timer_setup(&common->ani.timer, ath_ani_calibrate, 0); | 428 | timer_setup(&common->ani.timer, ath_ani_calibrate, 0); |
428 | 429 | ||
429 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; | 430 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; |
430 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 431 | eth_broadcast_addr(common->bssidmask); |
431 | sc->beacon.slottime = 9; | 432 | sc->beacon.slottime = 9; |
432 | 433 | ||
433 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) | 434 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) |
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c index fe3a8263b224..ce50d8f5835e 100644 --- a/drivers/net/wireless/ath/ath9k/tx99.c +++ b/drivers/net/wireless/ath/ath9k/tx99.c | |||
@@ -278,10 +278,10 @@ void ath9k_tx99_init_debug(struct ath_softc *sc) | |||
278 | if (!AR_SREV_9280_20_OR_LATER(sc->sc_ah)) | 278 | if (!AR_SREV_9280_20_OR_LATER(sc->sc_ah)) |
279 | return; | 279 | return; |
280 | 280 | ||
281 | debugfs_create_file("tx99", S_IRUSR | S_IWUSR, | 281 | debugfs_create_file("tx99", 0600, |
282 | sc->debug.debugfs_phy, sc, | 282 | sc->debug.debugfs_phy, sc, |
283 | &fops_tx99); | 283 | &fops_tx99); |
284 | debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR, | 284 | debugfs_create_file("tx99_power", 0600, |
285 | sc->debug.debugfs_phy, sc, | 285 | sc->debug.debugfs_phy, sc, |
286 | &fops_tx99_power); | 286 | &fops_tx99_power); |
287 | } | 287 | } |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 396bf05c6bf6..d8b041f48ca8 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2892,6 +2892,8 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
2892 | struct ath_txq *txq; | 2892 | struct ath_txq *txq; |
2893 | int tidno; | 2893 | int tidno; |
2894 | 2894 | ||
2895 | rcu_read_lock(); | ||
2896 | |||
2895 | for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { | 2897 | for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { |
2896 | tid = ath_node_to_tid(an, tidno); | 2898 | tid = ath_node_to_tid(an, tidno); |
2897 | txq = tid->txq; | 2899 | txq = tid->txq; |
@@ -2909,6 +2911,8 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
2909 | if (!an->sta) | 2911 | if (!an->sta) |
2910 | break; /* just one multicast ath_atx_tid */ | 2912 | break; /* just one multicast ath_atx_tid */ |
2911 | } | 2913 | } |
2914 | |||
2915 | rcu_read_unlock(); | ||
2912 | } | 2916 | } |
2913 | 2917 | ||
2914 | #ifdef CONFIG_ATH9K_TX99 | 2918 | #ifdef CONFIG_ATH9K_TX99 |
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c index ec3a64e5d2bb..a9b6dc17e408 100644 --- a/drivers/net/wireless/ath/carl9170/debug.c +++ b/drivers/net/wireless/ath/carl9170/debug.c | |||
@@ -187,21 +187,21 @@ static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\ | |||
187 | 187 | ||
188 | #define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) \ | 188 | #define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) \ |
189 | DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ | 189 | DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ |
190 | NULL, _read_bufsize, S_IRUSR) | 190 | NULL, _read_bufsize, 0400) |
191 | 191 | ||
192 | #define DEBUGFS_DECLARE_WO_FILE(name) \ | 192 | #define DEBUGFS_DECLARE_WO_FILE(name) \ |
193 | DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\ | 193 | DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\ |
194 | 0, S_IWUSR) | 194 | 0, 0200) |
195 | 195 | ||
196 | #define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize) \ | 196 | #define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize) \ |
197 | DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ | 197 | DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ |
198 | carl9170_debugfs_##name ##_write, \ | 198 | carl9170_debugfs_##name ##_write, \ |
199 | _read_bufsize, S_IRUSR | S_IWUSR) | 199 | _read_bufsize, 0600) |
200 | 200 | ||
201 | #define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate) \ | 201 | #define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate) \ |
202 | __DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ | 202 | __DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ |
203 | carl9170_debugfs_##name ##_write, \ | 203 | carl9170_debugfs_##name ##_write, \ |
204 | _read_bufsize, S_IRUSR | S_IWUSR, _dstate) | 204 | _read_bufsize, 0600, _dstate) |
205 | 205 | ||
206 | #define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...) \ | 206 | #define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...) \ |
207 | static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar, \ | 207 | static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar, \ |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 988c8857d78c..29e93c953d93 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -48,11 +48,11 @@ | |||
48 | #include "cmd.h" | 48 | #include "cmd.h" |
49 | 49 | ||
50 | static bool modparam_nohwcrypt; | 50 | static bool modparam_nohwcrypt; |
51 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 51 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); |
52 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload."); | 52 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload."); |
53 | 53 | ||
54 | int modparam_noht; | 54 | int modparam_noht; |
55 | module_param_named(noht, modparam_noht, int, S_IRUGO); | 55 | module_param_named(noht, modparam_noht, int, 0444); |
56 | MODULE_PARM_DESC(noht, "Disable MPDU aggregation."); | 56 | MODULE_PARM_DESC(noht, "Disable MPDU aggregation."); |
57 | 57 | ||
58 | #define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ | 58 | #define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ |
diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c index 4100ffd42a43..448b83eea810 100644 --- a/drivers/net/wireless/ath/dfs_pattern_detector.c +++ b/drivers/net/wireless/ath/dfs_pattern_detector.c | |||
@@ -115,7 +115,7 @@ static const struct radar_detector_specs jp_radar_ref_types[] = { | |||
115 | JP_PATTERN(4, 0, 5, 150, 230, 1, 23, 50, false), | 115 | JP_PATTERN(4, 0, 5, 150, 230, 1, 23, 50, false), |
116 | JP_PATTERN(5, 6, 10, 200, 500, 1, 16, 50, false), | 116 | JP_PATTERN(5, 6, 10, 200, 500, 1, 16, 50, false), |
117 | JP_PATTERN(6, 11, 20, 200, 500, 1, 12, 50, false), | 117 | JP_PATTERN(6, 11, 20, 200, 500, 1, 12, 50, false), |
118 | JP_PATTERN(7, 50, 100, 1000, 2000, 1, 3, 50, false), | 118 | JP_PATTERN(7, 50, 100, 1000, 2000, 1, 3, 50, true), |
119 | JP_PATTERN(5, 0, 1, 333, 333, 1, 9, 50, false), | 119 | JP_PATTERN(5, 0, 1, 333, 333, 1, 9, 50, false), |
120 | }; | 120 | }; |
121 | 121 | ||
diff --git a/drivers/net/wireless/ath/wcn36xx/debug.c b/drivers/net/wireless/ath/wcn36xx/debug.c index 2a6bb62e785c..389b5e7129a6 100644 --- a/drivers/net/wireless/ath/wcn36xx/debug.c +++ b/drivers/net/wireless/ath/wcn36xx/debug.c | |||
@@ -161,9 +161,8 @@ void wcn36xx_debugfs_init(struct wcn36xx *wcn) | |||
161 | dfs->rootdir = NULL; | 161 | dfs->rootdir = NULL; |
162 | } | 162 | } |
163 | 163 | ||
164 | ADD_FILE(bmps_switcher, S_IRUSR | S_IWUSR, | 164 | ADD_FILE(bmps_switcher, 0600, &fops_wcn36xx_bmps, wcn); |
165 | &fops_wcn36xx_bmps, wcn); | 165 | ADD_FILE(dump, 0200, &fops_wcn36xx_dump, wcn); |
166 | ADD_FILE(dump, S_IWUSR, &fops_wcn36xx_dump, wcn); | ||
167 | } | 166 | } |
168 | 167 | ||
169 | void wcn36xx_debugfs_exit(struct wcn36xx *wcn) | 168 | void wcn36xx_debugfs_exit(struct wcn36xx *wcn) |
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c index a3f1f7d042a4..2c3b899a88fa 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c | |||
@@ -27,15 +27,6 @@ | |||
27 | #include "wcn36xx.h" | 27 | #include "wcn36xx.h" |
28 | #include "txrx.h" | 28 | #include "txrx.h" |
29 | 29 | ||
30 | void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low) | ||
31 | { | ||
32 | struct wcn36xx_dxe_ch *ch = is_low ? | ||
33 | &wcn->dxe_tx_l_ch : | ||
34 | &wcn->dxe_tx_h_ch; | ||
35 | |||
36 | return ch->head_blk_ctl->bd_cpu_addr; | ||
37 | } | ||
38 | |||
39 | static void wcn36xx_ccu_write_register(struct wcn36xx *wcn, int addr, int data) | 30 | static void wcn36xx_ccu_write_register(struct wcn36xx *wcn, int addr, int data) |
40 | { | 31 | { |
41 | wcn36xx_dbg(WCN36XX_DBG_DXE, | 32 | wcn36xx_dbg(WCN36XX_DBG_DXE, |
@@ -376,7 +367,7 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch) | |||
376 | spin_lock_irqsave(&ch->lock, flags); | 367 | spin_lock_irqsave(&ch->lock, flags); |
377 | ctl = ch->tail_blk_ctl; | 368 | ctl = ch->tail_blk_ctl; |
378 | do { | 369 | do { |
379 | if (ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK) | 370 | if (ctl->desc->ctrl & WCN36xx_DXE_CTRL_VLD) |
380 | break; | 371 | break; |
381 | if (ctl->skb) { | 372 | if (ctl->skb) { |
382 | dma_unmap_single(wcn->dev, ctl->desc->src_addr_l, | 373 | dma_unmap_single(wcn->dev, ctl->desc->src_addr_l, |
@@ -397,7 +388,7 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch) | |||
397 | } | 388 | } |
398 | ctl = ctl->next; | 389 | ctl = ctl->next; |
399 | } while (ctl != ch->head_blk_ctl && | 390 | } while (ctl != ch->head_blk_ctl && |
400 | !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)); | 391 | !(ctl->desc->ctrl & WCN36xx_DXE_CTRL_VLD)); |
401 | 392 | ||
402 | ch->tail_blk_ctl = ctl; | 393 | ch->tail_blk_ctl = ctl; |
403 | spin_unlock_irqrestore(&ch->lock, flags); | 394 | spin_unlock_irqrestore(&ch->lock, flags); |
@@ -415,14 +406,31 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev) | |||
415 | WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H, | 406 | WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H, |
416 | &int_reason); | 407 | &int_reason); |
417 | 408 | ||
418 | /* TODO: Check int_reason */ | ||
419 | |||
420 | wcn36xx_dxe_write_register(wcn, | 409 | wcn36xx_dxe_write_register(wcn, |
421 | WCN36XX_DXE_0_INT_CLR, | 410 | WCN36XX_DXE_0_INT_CLR, |
422 | WCN36XX_INT_MASK_CHAN_TX_H); | 411 | WCN36XX_INT_MASK_CHAN_TX_H); |
423 | 412 | ||
424 | wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ED_CLR, | 413 | if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK ) { |
425 | WCN36XX_INT_MASK_CHAN_TX_H); | 414 | wcn36xx_dxe_write_register(wcn, |
415 | WCN36XX_DXE_0_INT_ERR_CLR, | ||
416 | WCN36XX_INT_MASK_CHAN_TX_H); | ||
417 | |||
418 | wcn36xx_err("DXE IRQ reported error: 0x%x in high TX channel\n", | ||
419 | int_src); | ||
420 | } | ||
421 | |||
422 | if (int_reason & WCN36XX_CH_STAT_INT_DONE_MASK) { | ||
423 | wcn36xx_dxe_write_register(wcn, | ||
424 | WCN36XX_DXE_0_INT_DONE_CLR, | ||
425 | WCN36XX_INT_MASK_CHAN_TX_H); | ||
426 | } | ||
427 | |||
428 | if (int_reason & WCN36XX_CH_STAT_INT_ED_MASK) { | ||
429 | wcn36xx_dxe_write_register(wcn, | ||
430 | WCN36XX_DXE_0_INT_ED_CLR, | ||
431 | WCN36XX_INT_MASK_CHAN_TX_H); | ||
432 | } | ||
433 | |||
426 | wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready high\n"); | 434 | wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready high\n"); |
427 | reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch); | 435 | reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch); |
428 | } | 436 | } |
@@ -431,14 +439,33 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev) | |||
431 | wcn36xx_dxe_read_register(wcn, | 439 | wcn36xx_dxe_read_register(wcn, |
432 | WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L, | 440 | WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L, |
433 | &int_reason); | 441 | &int_reason); |
434 | /* TODO: Check int_reason */ | ||
435 | 442 | ||
436 | wcn36xx_dxe_write_register(wcn, | 443 | wcn36xx_dxe_write_register(wcn, |
437 | WCN36XX_DXE_0_INT_CLR, | 444 | WCN36XX_DXE_0_INT_CLR, |
438 | WCN36XX_INT_MASK_CHAN_TX_L); | 445 | WCN36XX_INT_MASK_CHAN_TX_L); |
439 | 446 | ||
440 | wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ED_CLR, | 447 | |
441 | WCN36XX_INT_MASK_CHAN_TX_L); | 448 | if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK ) { |
449 | wcn36xx_dxe_write_register(wcn, | ||
450 | WCN36XX_DXE_0_INT_ERR_CLR, | ||
451 | WCN36XX_INT_MASK_CHAN_TX_L); | ||
452 | |||
453 | wcn36xx_err("DXE IRQ reported error: 0x%x in low TX channel\n", | ||
454 | int_src); | ||
455 | } | ||
456 | |||
457 | if (int_reason & WCN36XX_CH_STAT_INT_DONE_MASK) { | ||
458 | wcn36xx_dxe_write_register(wcn, | ||
459 | WCN36XX_DXE_0_INT_DONE_CLR, | ||
460 | WCN36XX_INT_MASK_CHAN_TX_L); | ||
461 | } | ||
462 | |||
463 | if (int_reason & WCN36XX_CH_STAT_INT_ED_MASK) { | ||
464 | wcn36xx_dxe_write_register(wcn, | ||
465 | WCN36XX_DXE_0_INT_ED_CLR, | ||
466 | WCN36XX_INT_MASK_CHAN_TX_L); | ||
467 | } | ||
468 | |||
442 | wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready low\n"); | 469 | wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready low\n"); |
443 | reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch); | 470 | reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch); |
444 | } | 471 | } |
@@ -503,7 +530,7 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn, | |||
503 | int_mask = WCN36XX_DXE_INT_CH3_MASK; | 530 | int_mask = WCN36XX_DXE_INT_CH3_MASK; |
504 | } | 531 | } |
505 | 532 | ||
506 | while (!(dxe->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) { | 533 | while (!(dxe->ctrl & WCN36xx_DXE_CTRL_VLD)) { |
507 | skb = ctl->skb; | 534 | skb = ctl->skb; |
508 | dma_addr = dxe->dst_addr_l; | 535 | dma_addr = dxe->dst_addr_l; |
509 | ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl); | 536 | ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl); |
@@ -612,6 +639,7 @@ void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn) | |||
612 | 639 | ||
613 | int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, | 640 | int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, |
614 | struct wcn36xx_vif *vif_priv, | 641 | struct wcn36xx_vif *vif_priv, |
642 | struct wcn36xx_tx_bd *bd, | ||
615 | struct sk_buff *skb, | 643 | struct sk_buff *skb, |
616 | bool is_low) | 644 | bool is_low) |
617 | { | 645 | { |
@@ -645,6 +673,9 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, | |||
645 | ctl->skb = NULL; | 673 | ctl->skb = NULL; |
646 | desc = ctl->desc; | 674 | desc = ctl->desc; |
647 | 675 | ||
676 | /* write buffer descriptor */ | ||
677 | memcpy(ctl->bd_cpu_addr, bd, sizeof(*bd)); | ||
678 | |||
648 | /* Set source address of the BD we send */ | 679 | /* Set source address of the BD we send */ |
649 | desc->src_addr_l = ctl->bd_phy_addr; | 680 | desc->src_addr_l = ctl->bd_phy_addr; |
650 | 681 | ||
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h b/drivers/net/wireless/ath/wcn36xx/dxe.h index c012e807753b..ce580960d109 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.h +++ b/drivers/net/wireless/ath/wcn36xx/dxe.h | |||
@@ -33,15 +33,106 @@ H2H_TEST_RX_TX = DMA2 | |||
33 | #define WCN36XX_CCU_DXE_INT_SELECT_RIVA 0x310 | 33 | #define WCN36XX_CCU_DXE_INT_SELECT_RIVA 0x310 |
34 | #define WCN36XX_CCU_DXE_INT_SELECT_PRONTO 0x10dc | 34 | #define WCN36XX_CCU_DXE_INT_SELECT_PRONTO 0x10dc |
35 | 35 | ||
36 | /* TODO This must calculated properly but not hardcoded */ | 36 | /* Descriptor valid */ |
37 | #define WCN36XX_DXE_CTRL_TX_L 0x328a44 | 37 | #define WCN36xx_DXE_CTRL_VLD BIT(0) |
38 | #define WCN36XX_DXE_CTRL_TX_H 0x32ce44 | 38 | /* End of packet */ |
39 | #define WCN36XX_DXE_CTRL_RX_L 0x12ad2f | 39 | #define WCN36xx_DXE_CTRL_EOP BIT(3) |
40 | #define WCN36XX_DXE_CTRL_RX_H 0x12d12f | 40 | /* BD handling bit */ |
41 | #define WCN36XX_DXE_CTRL_TX_H_BD 0x30ce45 | 41 | #define WCN36xx_DXE_CTRL_BDH BIT(4) |
42 | #define WCN36XX_DXE_CTRL_TX_H_SKB 0x32ce4d | 42 | /* Source is a queue */ |
43 | #define WCN36XX_DXE_CTRL_TX_L_BD 0x308a45 | 43 | #define WCN36xx_DXE_CTRL_SIQ BIT(5) |
44 | #define WCN36XX_DXE_CTRL_TX_L_SKB 0x328a4d | 44 | /* Destination is a queue */ |
45 | #define WCN36xx_DXE_CTRL_DIQ BIT(6) | ||
46 | /* Pointer address is a queue */ | ||
47 | #define WCN36xx_DXE_CTRL_PIQ BIT(7) | ||
48 | /* Release PDU when done */ | ||
49 | #define WCN36xx_DXE_CTRL_PDU_REL BIT(8) | ||
50 | /* STOP channel processing */ | ||
51 | #define WCN36xx_DXE_CTRL_STOP BIT(16) | ||
52 | /* INT on descriptor done */ | ||
53 | #define WCN36xx_DXE_CTRL_INT BIT(17) | ||
54 | /* Endian byte swap enable */ | ||
55 | #define WCN36xx_DXE_CTRL_SWAP BIT(20) | ||
56 | /* Master endianness */ | ||
57 | #define WCN36xx_DXE_CTRL_ENDIANNESS BIT(21) | ||
58 | |||
59 | /* Transfer type */ | ||
60 | #define WCN36xx_DXE_CTRL_XTYPE_SHIFT 1 | ||
61 | #define WCN36xx_DXE_CTRL_XTYPE_MASK GENMASK(2, WCN36xx_DXE_CTRL_XTYPE_SHIFT) | ||
62 | #define WCN36xx_DXE_CTRL_XTYPE_SET(x) ((x) << WCN36xx_DXE_CTRL_XTYPE_SHIFT) | ||
63 | |||
64 | /* BMU Threshold select */ | ||
65 | #define WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT 9 | ||
66 | #define WCN36xx_DXE_CTRL_BTHLD_SEL_MASK GENMASK(12, WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT) | ||
67 | #define WCN36xx_DXE_CTRL_BTHLD_SEL_SET(x) ((x) << WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT) | ||
68 | |||
69 | /* Priority */ | ||
70 | #define WCN36xx_DXE_CTRL_PRIO_SHIFT 13 | ||
71 | #define WCN36xx_DXE_CTRL_PRIO_MASK GENMASK(15, WCN36xx_DXE_CTRL_PRIO_SHIFT) | ||
72 | #define WCN36xx_DXE_CTRL_PRIO_SET(x) ((x) << WCN36xx_DXE_CTRL_PRIO_SHIFT) | ||
73 | |||
74 | /* BD Template index */ | ||
75 | #define WCN36xx_DXE_CTRL_BDT_IDX_SHIFT 18 | ||
76 | #define WCN36xx_DXE_CTRL_BDT_IDX_MASK GENMASK(19, WCN36xx_DXE_CTRL_BDT_IDX_SHIFT) | ||
77 | #define WCN36xx_DXE_CTRL_BDT_IDX_SET(x) ((x) << WCN36xx_DXE_CTRL_BDT_IDX_SHIFT) | ||
78 | |||
79 | /* Transfer types: */ | ||
80 | /* Host to host */ | ||
81 | #define WCN36xx_DXE_XTYPE_H2H (0) | ||
82 | /* Host to BMU */ | ||
83 | #define WCN36xx_DXE_XTYPE_H2B (2) | ||
84 | /* BMU to host */ | ||
85 | #define WCN36xx_DXE_XTYPE_B2H (3) | ||
86 | |||
87 | #define WCN36XX_DXE_CTRL_TX_L (WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \ | ||
88 | WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | \ | ||
89 | WCN36xx_DXE_CTRL_PRIO_SET(4) | WCN36xx_DXE_CTRL_INT | \ | ||
90 | WCN36xx_DXE_CTRL_SWAP | WCN36xx_DXE_CTRL_ENDIANNESS) | ||
91 | |||
92 | #define WCN36XX_DXE_CTRL_TX_H (WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \ | ||
93 | WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | \ | ||
94 | WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_INT | \ | ||
95 | WCN36xx_DXE_CTRL_SWAP | WCN36xx_DXE_CTRL_ENDIANNESS) | ||
96 | |||
97 | #define WCN36XX_DXE_CTRL_RX_L (WCN36xx_DXE_CTRL_VLD | \ | ||
98 | WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \ | ||
99 | WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_SIQ | \ | ||
100 | WCN36xx_DXE_CTRL_PDU_REL | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(6) | \ | ||
101 | WCN36xx_DXE_CTRL_PRIO_SET(5) | WCN36xx_DXE_CTRL_INT | \ | ||
102 | WCN36xx_DXE_CTRL_SWAP) | ||
103 | |||
104 | #define WCN36XX_DXE_CTRL_RX_H (WCN36xx_DXE_CTRL_VLD | \ | ||
105 | WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \ | ||
106 | WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_SIQ | \ | ||
107 | WCN36xx_DXE_CTRL_PDU_REL | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(8) | \ | ||
108 | WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_INT | \ | ||
109 | WCN36xx_DXE_CTRL_SWAP) | ||
110 | |||
111 | #define WCN36XX_DXE_CTRL_TX_H_BD (WCN36xx_DXE_CTRL_VLD | \ | ||
112 | WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \ | ||
113 | WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | \ | ||
114 | WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_SWAP | \ | ||
115 | WCN36xx_DXE_CTRL_ENDIANNESS) | ||
116 | |||
117 | #define WCN36XX_DXE_CTRL_TX_H_SKB (WCN36xx_DXE_CTRL_VLD | \ | ||
118 | WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \ | ||
119 | WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_DIQ | \ | ||
120 | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | WCN36xx_DXE_CTRL_PRIO_SET(6) | \ | ||
121 | WCN36xx_DXE_CTRL_INT | WCN36xx_DXE_CTRL_SWAP | \ | ||
122 | WCN36xx_DXE_CTRL_ENDIANNESS) | ||
123 | |||
124 | #define WCN36XX_DXE_CTRL_TX_L_BD (WCN36xx_DXE_CTRL_VLD | \ | ||
125 | WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \ | ||
126 | WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | \ | ||
127 | WCN36xx_DXE_CTRL_PRIO_SET(4) | WCN36xx_DXE_CTRL_SWAP | \ | ||
128 | WCN36xx_DXE_CTRL_ENDIANNESS) | ||
129 | |||
130 | #define WCN36XX_DXE_CTRL_TX_L_SKB (WCN36xx_DXE_CTRL_VLD | \ | ||
131 | WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \ | ||
132 | WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_DIQ | \ | ||
133 | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | WCN36xx_DXE_CTRL_PRIO_SET(4) | \ | ||
134 | WCN36xx_DXE_CTRL_INT | WCN36xx_DXE_CTRL_SWAP | \ | ||
135 | WCN36xx_DXE_CTRL_ENDIANNESS) | ||
45 | 136 | ||
46 | /* TODO This must calculated properly but not hardcoded */ | 137 | /* TODO This must calculated properly but not hardcoded */ |
47 | #define WCN36XX_DXE_WQ_TX_L 0x17 | 138 | #define WCN36XX_DXE_WQ_TX_L 0x17 |
@@ -49,15 +140,106 @@ H2H_TEST_RX_TX = DMA2 | |||
49 | #define WCN36XX_DXE_WQ_RX_L 0xB | 140 | #define WCN36XX_DXE_WQ_RX_L 0xB |
50 | #define WCN36XX_DXE_WQ_RX_H 0x4 | 141 | #define WCN36XX_DXE_WQ_RX_H 0x4 |
51 | 142 | ||
52 | /* DXE descriptor control filed */ | 143 | /* Channel enable or restart */ |
53 | #define WCN36XX_DXE_CTRL_VALID_MASK (0x00000001) | 144 | #define WCN36xx_DXE_CH_CTRL_EN BIT(0) |
145 | /* End of packet bit */ | ||
146 | #define WCN36xx_DXE_CH_CTRL_EOP BIT(3) | ||
147 | /* BD Handling bit */ | ||
148 | #define WCN36xx_DXE_CH_CTRL_BDH BIT(4) | ||
149 | /* Source is queue */ | ||
150 | #define WCN36xx_DXE_CH_CTRL_SIQ BIT(5) | ||
151 | /* Destination is queue */ | ||
152 | #define WCN36xx_DXE_CH_CTRL_DIQ BIT(6) | ||
153 | /* Pointer descriptor is queue */ | ||
154 | #define WCN36xx_DXE_CH_CTRL_PIQ BIT(7) | ||
155 | /* Relase PDU when done */ | ||
156 | #define WCN36xx_DXE_CH_CTRL_PDU_REL BIT(8) | ||
157 | /* Stop channel processing */ | ||
158 | #define WCN36xx_DXE_CH_CTRL_STOP BIT(16) | ||
159 | /* Enable external descriptor interrupt */ | ||
160 | #define WCN36xx_DXE_CH_CTRL_INE_ED BIT(17) | ||
161 | /* Enable channel interrupt on errors */ | ||
162 | #define WCN36xx_DXE_CH_CTRL_INE_ERR BIT(18) | ||
163 | /* Enable Channel interrupt when done */ | ||
164 | #define WCN36xx_DXE_CH_CTRL_INE_DONE BIT(19) | ||
165 | /* External descriptor enable */ | ||
166 | #define WCN36xx_DXE_CH_CTRL_EDEN BIT(20) | ||
167 | /* Wait for valid bit */ | ||
168 | #define WCN36xx_DXE_CH_CTRL_EDVEN BIT(21) | ||
169 | /* Endianness is little endian*/ | ||
170 | #define WCN36xx_DXE_CH_CTRL_ENDIANNESS BIT(26) | ||
171 | /* Abort transfer */ | ||
172 | #define WCN36xx_DXE_CH_CTRL_ABORT BIT(27) | ||
173 | /* Long descriptor format */ | ||
174 | #define WCN36xx_DXE_CH_CTRL_DFMT BIT(28) | ||
175 | /* Endian byte swap enable */ | ||
176 | #define WCN36xx_DXE_CH_CTRL_SWAP BIT(31) | ||
177 | |||
178 | /* Transfer type */ | ||
179 | #define WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT 1 | ||
180 | #define WCN36xx_DXE_CH_CTRL_XTYPE_MASK GENMASK(2, WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT) | ||
181 | #define WCN36xx_DXE_CH_CTRL_XTYPE_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT) | ||
182 | |||
183 | /* Channel BMU Threshold select */ | ||
184 | #define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT 9 | ||
185 | #define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_MASK GENMASK(12, WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT) | ||
186 | #define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT) | ||
187 | |||
188 | /* Channel Priority */ | ||
189 | #define WCN36xx_DXE_CH_CTRL_PRIO_SHIFT 13 | ||
190 | #define WCN36xx_DXE_CH_CTRL_PRIO_MASK GENMASK(15, WCN36xx_DXE_CH_CTRL_PRIO_SHIFT) | ||
191 | #define WCN36xx_DXE_CH_CTRL_PRIO_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_PRIO_SHIFT) | ||
192 | |||
193 | /* Counter select */ | ||
194 | #define WCN36xx_DXE_CH_CTRL_SEL_SHIFT 22 | ||
195 | #define WCN36xx_DXE_CH_CTRL_SEL_MASK GENMASK(25, WCN36xx_DXE_CH_CTRL_SEL_SHIFT) | ||
196 | #define WCN36xx_DXE_CH_CTRL_SEL_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_SEL_SHIFT) | ||
197 | |||
198 | /* Channel BD template index */ | ||
199 | #define WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT 29 | ||
200 | #define WCN36xx_DXE_CH_CTRL_BDT_IDX_MASK GENMASK(30, WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT) | ||
201 | #define WCN36xx_DXE_CH_CTRL_BDT_IDX_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT) | ||
54 | 202 | ||
55 | /* TODO This must calculated properly but not hardcoded */ | ||
56 | /* DXE default control register values */ | 203 | /* DXE default control register values */ |
57 | #define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L 0x847EAD2F | 204 | #define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L (WCN36xx_DXE_CH_CTRL_EN | \ |
58 | #define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H 0x84FED12F | 205 | WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \ |
59 | #define WCN36XX_DXE_CH_DEFAULT_CTL_TX_H 0x853ECF4D | 206 | WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_SIQ | \ |
60 | #define WCN36XX_DXE_CH_DEFAULT_CTL_TX_L 0x843e8b4d | 207 | WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(6) | \ |
208 | WCN36xx_DXE_CH_CTRL_PRIO_SET(5) | WCN36xx_DXE_CH_CTRL_INE_ED | \ | ||
209 | WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \ | ||
210 | WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \ | ||
211 | WCN36xx_DXE_CH_CTRL_SEL_SET(1) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \ | ||
212 | WCN36xx_DXE_CH_CTRL_SWAP) | ||
213 | |||
214 | #define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H (WCN36xx_DXE_CH_CTRL_EN | \ | ||
215 | WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \ | ||
216 | WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_SIQ | \ | ||
217 | WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(8) | \ | ||
218 | WCN36xx_DXE_CH_CTRL_PRIO_SET(6) | WCN36xx_DXE_CH_CTRL_INE_ED | \ | ||
219 | WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \ | ||
220 | WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \ | ||
221 | WCN36xx_DXE_CH_CTRL_SEL_SET(3) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \ | ||
222 | WCN36xx_DXE_CH_CTRL_SWAP) | ||
223 | |||
224 | #define WCN36XX_DXE_CH_DEFAULT_CTL_TX_H (WCN36xx_DXE_CH_CTRL_EN | \ | ||
225 | WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \ | ||
226 | WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_DIQ | \ | ||
227 | WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(7) | \ | ||
228 | WCN36xx_DXE_CH_CTRL_PRIO_SET(6) | WCN36xx_DXE_CH_CTRL_INE_ED | \ | ||
229 | WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \ | ||
230 | WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \ | ||
231 | WCN36xx_DXE_CH_CTRL_SEL_SET(4) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \ | ||
232 | WCN36xx_DXE_CH_CTRL_SWAP) | ||
233 | |||
234 | #define WCN36XX_DXE_CH_DEFAULT_CTL_TX_L (WCN36xx_DXE_CH_CTRL_EN | \ | ||
235 | WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \ | ||
236 | WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_DIQ | \ | ||
237 | WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(5) | \ | ||
238 | WCN36xx_DXE_CH_CTRL_PRIO_SET(4) | WCN36xx_DXE_CH_CTRL_INE_ED | \ | ||
239 | WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \ | ||
240 | WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \ | ||
241 | WCN36xx_DXE_CH_CTRL_SEL_SET(0) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \ | ||
242 | WCN36xx_DXE_CH_CTRL_SWAP) | ||
61 | 243 | ||
62 | /* Common DXE registers */ | 244 | /* Common DXE registers */ |
63 | #define WCN36XX_DXE_MEM_CSR (WCN36XX_DXE_MEM_REG + 0x00) | 245 | #define WCN36XX_DXE_MEM_CSR (WCN36XX_DXE_MEM_REG + 0x00) |
@@ -80,6 +262,10 @@ H2H_TEST_RX_TX = DMA2 | |||
80 | #define WCN36XX_DXE_0_INT_DONE_CLR (WCN36XX_DXE_MEM_REG + 0x38) | 262 | #define WCN36XX_DXE_0_INT_DONE_CLR (WCN36XX_DXE_MEM_REG + 0x38) |
81 | #define WCN36XX_DXE_0_INT_ERR_CLR (WCN36XX_DXE_MEM_REG + 0x3C) | 263 | #define WCN36XX_DXE_0_INT_ERR_CLR (WCN36XX_DXE_MEM_REG + 0x3C) |
82 | 264 | ||
265 | #define WCN36XX_CH_STAT_INT_DONE_MASK 0x00008000 | ||
266 | #define WCN36XX_CH_STAT_INT_ERR_MASK 0x00004000 | ||
267 | #define WCN36XX_CH_STAT_INT_ED_MASK 0x00002000 | ||
268 | |||
83 | #define WCN36XX_DXE_0_CH0_STATUS (WCN36XX_DXE_MEM_REG + 0x404) | 269 | #define WCN36XX_DXE_0_CH0_STATUS (WCN36XX_DXE_MEM_REG + 0x404) |
84 | #define WCN36XX_DXE_0_CH1_STATUS (WCN36XX_DXE_MEM_REG + 0x444) | 270 | #define WCN36XX_DXE_0_CH1_STATUS (WCN36XX_DXE_MEM_REG + 0x444) |
85 | #define WCN36XX_DXE_0_CH2_STATUS (WCN36XX_DXE_MEM_REG + 0x484) | 271 | #define WCN36XX_DXE_0_CH2_STATUS (WCN36XX_DXE_MEM_REG + 0x484) |
@@ -266,6 +452,7 @@ struct wcn36xx_dxe_mem_pool { | |||
266 | dma_addr_t phy_addr; | 452 | dma_addr_t phy_addr; |
267 | }; | 453 | }; |
268 | 454 | ||
455 | struct wcn36xx_tx_bd; | ||
269 | struct wcn36xx_vif; | 456 | struct wcn36xx_vif; |
270 | int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn); | 457 | int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn); |
271 | void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn); | 458 | void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn); |
@@ -277,8 +464,8 @@ void wcn36xx_dxe_deinit(struct wcn36xx *wcn); | |||
277 | int wcn36xx_dxe_init_channels(struct wcn36xx *wcn); | 464 | int wcn36xx_dxe_init_channels(struct wcn36xx *wcn); |
278 | int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, | 465 | int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, |
279 | struct wcn36xx_vif *vif_priv, | 466 | struct wcn36xx_vif *vif_priv, |
467 | struct wcn36xx_tx_bd *bd, | ||
280 | struct sk_buff *skb, | 468 | struct sk_buff *skb, |
281 | bool is_low); | 469 | bool is_low); |
282 | void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status); | 470 | void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status); |
283 | void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low); | ||
284 | #endif /* _DXE_H_ */ | 471 | #endif /* _DXE_H_ */ |
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index ab5be6d2c691..69d6be59d97f 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c | |||
@@ -261,7 +261,7 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn) | |||
261 | 261 | ||
262 | for (i = 0; i < MAX_FEATURE_SUPPORTED; i++) { | 262 | for (i = 0; i < MAX_FEATURE_SUPPORTED; i++) { |
263 | if (get_feat_caps(wcn->fw_feat_caps, i)) | 263 | if (get_feat_caps(wcn->fw_feat_caps, i)) |
264 | wcn36xx_info("FW Cap %s\n", wcn36xx_get_cap_name(i)); | 264 | wcn36xx_dbg(WCN36XX_DBG_MAC, "FW Cap %s\n", wcn36xx_get_cap_name(i)); |
265 | } | 265 | } |
266 | } | 266 | } |
267 | 267 | ||
@@ -666,16 +666,13 @@ static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw, | |||
666 | { | 666 | { |
667 | struct wcn36xx *wcn = hw->priv; | 667 | struct wcn36xx *wcn = hw->priv; |
668 | 668 | ||
669 | if (!wcn36xx_smd_stop_hw_scan(wcn)) { | ||
670 | struct cfg80211_scan_info scan_info = { .aborted = true }; | ||
671 | |||
672 | ieee80211_scan_completed(wcn->hw, &scan_info); | ||
673 | } | ||
674 | |||
675 | mutex_lock(&wcn->scan_lock); | 669 | mutex_lock(&wcn->scan_lock); |
676 | wcn->scan_aborted = true; | 670 | wcn->scan_aborted = true; |
677 | mutex_unlock(&wcn->scan_lock); | 671 | mutex_unlock(&wcn->scan_lock); |
678 | 672 | ||
673 | /* ieee80211_scan_completed will be called on FW scan indication */ | ||
674 | wcn36xx_smd_stop_hw_scan(wcn); | ||
675 | |||
679 | cancel_work_sync(&wcn->scan_work); | 676 | cancel_work_sync(&wcn->scan_work); |
680 | } | 677 | } |
681 | 678 | ||
@@ -1155,8 +1152,6 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) | |||
1155 | wcn->hw->wiphy->cipher_suites = cipher_suites; | 1152 | wcn->hw->wiphy->cipher_suites = cipher_suites; |
1156 | wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); | 1153 | wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); |
1157 | 1154 | ||
1158 | wcn->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; | ||
1159 | |||
1160 | #ifdef CONFIG_PM | 1155 | #ifdef CONFIG_PM |
1161 | wcn->hw->wiphy->wowlan = &wowlan_support; | 1156 | wcn->hw->wiphy->wowlan = &wowlan_support; |
1162 | #endif | 1157 | #endif |
@@ -1283,6 +1278,7 @@ static int wcn36xx_probe(struct platform_device *pdev) | |||
1283 | wcn = hw->priv; | 1278 | wcn = hw->priv; |
1284 | wcn->hw = hw; | 1279 | wcn->hw = hw; |
1285 | wcn->dev = &pdev->dev; | 1280 | wcn->dev = &pdev->dev; |
1281 | wcn->first_boot = true; | ||
1286 | mutex_init(&wcn->conf_mutex); | 1282 | mutex_init(&wcn->conf_mutex); |
1287 | mutex_init(&wcn->hal_mutex); | 1283 | mutex_init(&wcn->hal_mutex); |
1288 | mutex_init(&wcn->scan_lock); | 1284 | mutex_init(&wcn->scan_lock); |
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 2a4871ca9c72..8932af5e4d8d 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c | |||
@@ -409,15 +409,17 @@ static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, void *buf, size_t len) | |||
409 | wcn->fw_minor = rsp->start_rsp_params.version.minor; | 409 | wcn->fw_minor = rsp->start_rsp_params.version.minor; |
410 | wcn->fw_major = rsp->start_rsp_params.version.major; | 410 | wcn->fw_major = rsp->start_rsp_params.version.major; |
411 | 411 | ||
412 | wcn36xx_info("firmware WLAN version '%s' and CRM version '%s'\n", | 412 | if (wcn->first_boot) { |
413 | wcn->wlan_version, wcn->crm_version); | 413 | wcn->first_boot = false; |
414 | 414 | wcn36xx_info("firmware WLAN version '%s' and CRM version '%s'\n", | |
415 | wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u bssids\n", | 415 | wcn->wlan_version, wcn->crm_version); |
416 | wcn->fw_major, wcn->fw_minor, | ||
417 | wcn->fw_version, wcn->fw_revision, | ||
418 | rsp->start_rsp_params.stations, | ||
419 | rsp->start_rsp_params.bssids); | ||
420 | 416 | ||
417 | wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u bssids\n", | ||
418 | wcn->fw_major, wcn->fw_minor, | ||
419 | wcn->fw_version, wcn->fw_revision, | ||
420 | rsp->start_rsp_params.stations, | ||
421 | rsp->start_rsp_params.bssids); | ||
422 | } | ||
421 | return 0; | 423 | return 0; |
422 | } | 424 | } |
423 | 425 | ||
@@ -2138,6 +2140,8 @@ static int wcn36xx_smd_hw_scan_ind(struct wcn36xx *wcn, void *buf, size_t len) | |||
2138 | case WCN36XX_HAL_SCAN_IND_COMPLETED: | 2140 | case WCN36XX_HAL_SCAN_IND_COMPLETED: |
2139 | mutex_lock(&wcn->scan_lock); | 2141 | mutex_lock(&wcn->scan_lock); |
2140 | wcn->scan_req = NULL; | 2142 | wcn->scan_req = NULL; |
2143 | if (wcn->scan_aborted) | ||
2144 | scan_info.aborted = true; | ||
2141 | mutex_unlock(&wcn->scan_lock); | 2145 | mutex_unlock(&wcn->scan_lock); |
2142 | ieee80211_scan_completed(wcn->hw, &scan_info); | 2146 | ieee80211_scan_completed(wcn->hw, &scan_info); |
2143 | break; | 2147 | break; |
@@ -2407,54 +2411,63 @@ static void wcn36xx_ind_smd_work(struct work_struct *work) | |||
2407 | { | 2411 | { |
2408 | struct wcn36xx *wcn = | 2412 | struct wcn36xx *wcn = |
2409 | container_of(work, struct wcn36xx, hal_ind_work); | 2413 | container_of(work, struct wcn36xx, hal_ind_work); |
2410 | struct wcn36xx_hal_msg_header *msg_header; | ||
2411 | struct wcn36xx_hal_ind_msg *hal_ind_msg; | ||
2412 | unsigned long flags; | ||
2413 | 2414 | ||
2414 | spin_lock_irqsave(&wcn->hal_ind_lock, flags); | 2415 | for (;;) { |
2416 | struct wcn36xx_hal_msg_header *msg_header; | ||
2417 | struct wcn36xx_hal_ind_msg *hal_ind_msg; | ||
2418 | unsigned long flags; | ||
2415 | 2419 | ||
2416 | hal_ind_msg = list_first_entry(&wcn->hal_ind_queue, | 2420 | spin_lock_irqsave(&wcn->hal_ind_lock, flags); |
2417 | struct wcn36xx_hal_ind_msg, | ||
2418 | list); | ||
2419 | list_del(wcn->hal_ind_queue.next); | ||
2420 | spin_unlock_irqrestore(&wcn->hal_ind_lock, flags); | ||
2421 | 2421 | ||
2422 | msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg; | 2422 | if (list_empty(&wcn->hal_ind_queue)) { |
2423 | spin_unlock_irqrestore(&wcn->hal_ind_lock, flags); | ||
2424 | return; | ||
2425 | } | ||
2423 | 2426 | ||
2424 | switch (msg_header->msg_type) { | 2427 | hal_ind_msg = list_first_entry(&wcn->hal_ind_queue, |
2425 | case WCN36XX_HAL_COEX_IND: | 2428 | struct wcn36xx_hal_ind_msg, |
2426 | case WCN36XX_HAL_DEL_BA_IND: | 2429 | list); |
2427 | case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: | 2430 | list_del(&hal_ind_msg->list); |
2428 | break; | 2431 | spin_unlock_irqrestore(&wcn->hal_ind_lock, flags); |
2429 | case WCN36XX_HAL_OTA_TX_COMPL_IND: | 2432 | |
2430 | wcn36xx_smd_tx_compl_ind(wcn, | 2433 | msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg; |
2431 | hal_ind_msg->msg, | 2434 | |
2432 | hal_ind_msg->msg_len); | 2435 | switch (msg_header->msg_type) { |
2433 | break; | 2436 | case WCN36XX_HAL_COEX_IND: |
2434 | case WCN36XX_HAL_MISSED_BEACON_IND: | 2437 | case WCN36XX_HAL_DEL_BA_IND: |
2435 | wcn36xx_smd_missed_beacon_ind(wcn, | 2438 | case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: |
2436 | hal_ind_msg->msg, | 2439 | break; |
2437 | hal_ind_msg->msg_len); | 2440 | case WCN36XX_HAL_OTA_TX_COMPL_IND: |
2438 | break; | 2441 | wcn36xx_smd_tx_compl_ind(wcn, |
2439 | case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: | 2442 | hal_ind_msg->msg, |
2440 | wcn36xx_smd_delete_sta_context_ind(wcn, | 2443 | hal_ind_msg->msg_len); |
2441 | hal_ind_msg->msg, | 2444 | break; |
2442 | hal_ind_msg->msg_len); | 2445 | case WCN36XX_HAL_MISSED_BEACON_IND: |
2443 | break; | 2446 | wcn36xx_smd_missed_beacon_ind(wcn, |
2444 | case WCN36XX_HAL_PRINT_REG_INFO_IND: | 2447 | hal_ind_msg->msg, |
2445 | wcn36xx_smd_print_reg_info_ind(wcn, | 2448 | hal_ind_msg->msg_len); |
2446 | hal_ind_msg->msg, | 2449 | break; |
2447 | hal_ind_msg->msg_len); | 2450 | case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: |
2448 | break; | 2451 | wcn36xx_smd_delete_sta_context_ind(wcn, |
2449 | case WCN36XX_HAL_SCAN_OFFLOAD_IND: | 2452 | hal_ind_msg->msg, |
2450 | wcn36xx_smd_hw_scan_ind(wcn, hal_ind_msg->msg, | 2453 | hal_ind_msg->msg_len); |
2451 | hal_ind_msg->msg_len); | 2454 | break; |
2452 | break; | 2455 | case WCN36XX_HAL_PRINT_REG_INFO_IND: |
2453 | default: | 2456 | wcn36xx_smd_print_reg_info_ind(wcn, |
2454 | wcn36xx_err("SMD_EVENT (%d) not supported\n", | 2457 | hal_ind_msg->msg, |
2455 | msg_header->msg_type); | 2458 | hal_ind_msg->msg_len); |
2459 | break; | ||
2460 | case WCN36XX_HAL_SCAN_OFFLOAD_IND: | ||
2461 | wcn36xx_smd_hw_scan_ind(wcn, hal_ind_msg->msg, | ||
2462 | hal_ind_msg->msg_len); | ||
2463 | break; | ||
2464 | default: | ||
2465 | wcn36xx_err("SMD_EVENT (%d) not supported\n", | ||
2466 | msg_header->msg_type); | ||
2467 | } | ||
2468 | |||
2469 | kfree(hal_ind_msg); | ||
2456 | } | 2470 | } |
2457 | kfree(hal_ind_msg); | ||
2458 | } | 2471 | } |
2459 | int wcn36xx_smd_open(struct wcn36xx *wcn) | 2472 | int wcn36xx_smd_open(struct wcn36xx *wcn) |
2460 | { | 2473 | { |
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index 22304edc5948..b1768ed6b0be 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c | |||
@@ -272,21 +272,9 @@ int wcn36xx_start_tx(struct wcn36xx *wcn, | |||
272 | bool is_low = ieee80211_is_data(hdr->frame_control); | 272 | bool is_low = ieee80211_is_data(hdr->frame_control); |
273 | bool bcast = is_broadcast_ether_addr(hdr->addr1) || | 273 | bool bcast = is_broadcast_ether_addr(hdr->addr1) || |
274 | is_multicast_ether_addr(hdr->addr1); | 274 | is_multicast_ether_addr(hdr->addr1); |
275 | struct wcn36xx_tx_bd *bd = wcn36xx_dxe_get_next_bd(wcn, is_low); | 275 | struct wcn36xx_tx_bd bd; |
276 | |||
277 | if (!bd) { | ||
278 | /* | ||
279 | * TX DXE are used in pairs. One for the BD and one for the | ||
280 | * actual frame. The BD DXE's has a preallocated buffer while | ||
281 | * the skb ones does not. If this isn't true something is really | ||
282 | * wierd. TODO: Recover from this situation | ||
283 | */ | ||
284 | |||
285 | wcn36xx_err("bd address may not be NULL for BD DXE\n"); | ||
286 | return -EINVAL; | ||
287 | } | ||
288 | 276 | ||
289 | memset(bd, 0, sizeof(*bd)); | 277 | memset(&bd, 0, sizeof(bd)); |
290 | 278 | ||
291 | wcn36xx_dbg(WCN36XX_DBG_TX, | 279 | wcn36xx_dbg(WCN36XX_DBG_TX, |
292 | "tx skb %p len %d fc %04x sn %d %s %s\n", | 280 | "tx skb %p len %d fc %04x sn %d %s %s\n", |
@@ -296,10 +284,10 @@ int wcn36xx_start_tx(struct wcn36xx *wcn, | |||
296 | 284 | ||
297 | wcn36xx_dbg_dump(WCN36XX_DBG_TX_DUMP, "", skb->data, skb->len); | 285 | wcn36xx_dbg_dump(WCN36XX_DBG_TX_DUMP, "", skb->data, skb->len); |
298 | 286 | ||
299 | bd->dpu_rf = WCN36XX_BMU_WQ_TX; | 287 | bd.dpu_rf = WCN36XX_BMU_WQ_TX; |
300 | 288 | ||
301 | bd->tx_comp = !!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS); | 289 | bd.tx_comp = !!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS); |
302 | if (bd->tx_comp) { | 290 | if (bd.tx_comp) { |
303 | wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n"); | 291 | wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n"); |
304 | spin_lock_irqsave(&wcn->dxe_lock, flags); | 292 | spin_lock_irqsave(&wcn->dxe_lock, flags); |
305 | if (wcn->tx_ack_skb) { | 293 | if (wcn->tx_ack_skb) { |
@@ -321,13 +309,13 @@ int wcn36xx_start_tx(struct wcn36xx *wcn, | |||
321 | 309 | ||
322 | /* Data frames served first*/ | 310 | /* Data frames served first*/ |
323 | if (is_low) | 311 | if (is_low) |
324 | wcn36xx_set_tx_data(bd, wcn, &vif_priv, sta_priv, skb, bcast); | 312 | wcn36xx_set_tx_data(&bd, wcn, &vif_priv, sta_priv, skb, bcast); |
325 | else | 313 | else |
326 | /* MGMT and CTRL frames are handeld here*/ | 314 | /* MGMT and CTRL frames are handeld here*/ |
327 | wcn36xx_set_tx_mgmt(bd, wcn, &vif_priv, skb, bcast); | 315 | wcn36xx_set_tx_mgmt(&bd, wcn, &vif_priv, skb, bcast); |
328 | 316 | ||
329 | buff_to_be((u32 *)bd, sizeof(*bd)/sizeof(u32)); | 317 | buff_to_be((u32 *)&bd, sizeof(bd)/sizeof(u32)); |
330 | bd->tx_bd_sign = 0xbdbdbdbd; | 318 | bd.tx_bd_sign = 0xbdbdbdbd; |
331 | 319 | ||
332 | return wcn36xx_dxe_tx_frame(wcn, vif_priv, skb, is_low); | 320 | return wcn36xx_dxe_tx_frame(wcn, vif_priv, &bd, skb, is_low); |
333 | } | 321 | } |
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h index 81017e6703b4..5854adf43f3a 100644 --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h | |||
@@ -192,6 +192,8 @@ struct wcn36xx { | |||
192 | u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; | 192 | u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; |
193 | u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1]; | 193 | u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1]; |
194 | 194 | ||
195 | bool first_boot; | ||
196 | |||
195 | /* IRQs */ | 197 | /* IRQs */ |
196 | int tx_irq; | 198 | int tx_irq; |
197 | int rx_irq; | 199 | int rx_irq; |
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index b799a5384abb..cdbb393863f3 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -17,8 +18,10 @@ | |||
17 | #include <linux/etherdevice.h> | 18 | #include <linux/etherdevice.h> |
18 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
19 | #include <net/netlink.h> | 20 | #include <net/netlink.h> |
21 | #include <net/cfg80211.h> | ||
20 | #include "wil6210.h" | 22 | #include "wil6210.h" |
21 | #include "wmi.h" | 23 | #include "wmi.h" |
24 | #include "fw.h" | ||
22 | 25 | ||
23 | #define WIL_MAX_ROC_DURATION_MS 5000 | 26 | #define WIL_MAX_ROC_DURATION_MS 5000 |
24 | 27 | ||
@@ -258,9 +261,10 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type) | |||
258 | return -EOPNOTSUPP; | 261 | return -EOPNOTSUPP; |
259 | } | 262 | } |
260 | 263 | ||
261 | int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, | 264 | int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid, |
262 | struct station_info *sinfo) | 265 | struct station_info *sinfo) |
263 | { | 266 | { |
267 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
264 | struct wmi_notify_req_cmd cmd = { | 268 | struct wmi_notify_req_cmd cmd = { |
265 | .cid = cid, | 269 | .cid = cid, |
266 | .interval_usec = 0, | 270 | .interval_usec = 0, |
@@ -272,17 +276,17 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, | |||
272 | struct wil_net_stats *stats = &wil->sta[cid].stats; | 276 | struct wil_net_stats *stats = &wil->sta[cid].stats; |
273 | int rc; | 277 | int rc; |
274 | 278 | ||
275 | rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd), | 279 | rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, vif->mid, &cmd, sizeof(cmd), |
276 | WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20); | 280 | WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20); |
277 | if (rc) | 281 | if (rc) |
278 | return rc; | 282 | return rc; |
279 | 283 | ||
280 | wil_dbg_wmi(wil, "Link status for CID %d: {\n" | 284 | wil_dbg_wmi(wil, "Link status for CID %d MID %d: {\n" |
281 | " MCS %d TSF 0x%016llx\n" | 285 | " MCS %d TSF 0x%016llx\n" |
282 | " BF status 0x%08x RSSI %d SQI %d%%\n" | 286 | " BF status 0x%08x RSSI %d SQI %d%%\n" |
283 | " Tx Tpt %d goodput %d Rx goodput %d\n" | 287 | " Tx Tpt %d goodput %d Rx goodput %d\n" |
284 | " Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n", | 288 | " Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n", |
285 | cid, le16_to_cpu(reply.evt.bf_mcs), | 289 | cid, vif->mid, le16_to_cpu(reply.evt.bf_mcs), |
286 | le64_to_cpu(reply.evt.tsf), reply.evt.status, | 290 | le64_to_cpu(reply.evt.tsf), reply.evt.status, |
287 | reply.evt.rssi, | 291 | reply.evt.rssi, |
288 | reply.evt.sqi, | 292 | reply.evt.sqi, |
@@ -315,7 +319,7 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, | |||
315 | sinfo->tx_packets = stats->tx_packets; | 319 | sinfo->tx_packets = stats->tx_packets; |
316 | sinfo->tx_failed = stats->tx_errors; | 320 | sinfo->tx_failed = stats->tx_errors; |
317 | 321 | ||
318 | if (test_bit(wil_status_fwconnected, wil->status)) { | 322 | if (test_bit(wil_vif_fwconnected, vif->status)) { |
319 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); | 323 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); |
320 | if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, | 324 | if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, |
321 | wil->fw_capabilities)) | 325 | wil->fw_capabilities)) |
@@ -331,30 +335,34 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy, | |||
331 | struct net_device *ndev, | 335 | struct net_device *ndev, |
332 | const u8 *mac, struct station_info *sinfo) | 336 | const u8 *mac, struct station_info *sinfo) |
333 | { | 337 | { |
338 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
334 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 339 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
335 | int rc; | 340 | int rc; |
336 | 341 | ||
337 | int cid = wil_find_cid(wil, mac); | 342 | int cid = wil_find_cid(wil, vif->mid, mac); |
338 | 343 | ||
339 | wil_dbg_misc(wil, "get_station: %pM CID %d\n", mac, cid); | 344 | wil_dbg_misc(wil, "get_station: %pM CID %d MID %d\n", mac, cid, |
345 | vif->mid); | ||
340 | if (cid < 0) | 346 | if (cid < 0) |
341 | return cid; | 347 | return cid; |
342 | 348 | ||
343 | rc = wil_cid_fill_sinfo(wil, cid, sinfo); | 349 | rc = wil_cid_fill_sinfo(vif, cid, sinfo); |
344 | 350 | ||
345 | return rc; | 351 | return rc; |
346 | } | 352 | } |
347 | 353 | ||
348 | /* | 354 | /* |
349 | * Find @idx-th active STA for station dump. | 355 | * Find @idx-th active STA for specific MID for station dump. |
350 | */ | 356 | */ |
351 | static int wil_find_cid_by_idx(struct wil6210_priv *wil, int idx) | 357 | static int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx) |
352 | { | 358 | { |
353 | int i; | 359 | int i; |
354 | 360 | ||
355 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { | 361 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { |
356 | if (wil->sta[i].status == wil_sta_unused) | 362 | if (wil->sta[i].status == wil_sta_unused) |
357 | continue; | 363 | continue; |
364 | if (wil->sta[i].mid != mid) | ||
365 | continue; | ||
358 | if (idx == 0) | 366 | if (idx == 0) |
359 | return i; | 367 | return i; |
360 | idx--; | 368 | idx--; |
@@ -367,17 +375,19 @@ static int wil_cfg80211_dump_station(struct wiphy *wiphy, | |||
367 | struct net_device *dev, int idx, | 375 | struct net_device *dev, int idx, |
368 | u8 *mac, struct station_info *sinfo) | 376 | u8 *mac, struct station_info *sinfo) |
369 | { | 377 | { |
378 | struct wil6210_vif *vif = ndev_to_vif(dev); | ||
370 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 379 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
371 | int rc; | 380 | int rc; |
372 | int cid = wil_find_cid_by_idx(wil, idx); | 381 | int cid = wil_find_cid_by_idx(wil, vif->mid, idx); |
373 | 382 | ||
374 | if (cid < 0) | 383 | if (cid < 0) |
375 | return -ENOENT; | 384 | return -ENOENT; |
376 | 385 | ||
377 | ether_addr_copy(mac, wil->sta[cid].addr); | 386 | ether_addr_copy(mac, wil->sta[cid].addr); |
378 | wil_dbg_misc(wil, "dump_station: %pM CID %d\n", mac, cid); | 387 | wil_dbg_misc(wil, "dump_station: %pM CID %d MID %d\n", mac, cid, |
388 | vif->mid); | ||
379 | 389 | ||
380 | rc = wil_cid_fill_sinfo(wil, cid, sinfo); | 390 | rc = wil_cid_fill_sinfo(vif, cid, sinfo); |
381 | 391 | ||
382 | return rc; | 392 | return rc; |
383 | } | 393 | } |
@@ -388,7 +398,7 @@ static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy, | |||
388 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 398 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
389 | 399 | ||
390 | wil_dbg_misc(wil, "start_p2p_device: entered\n"); | 400 | wil_dbg_misc(wil, "start_p2p_device: entered\n"); |
391 | wil->p2p.p2p_dev_started = 1; | 401 | wil->p2p_dev_started = 1; |
392 | return 0; | 402 | return 0; |
393 | } | 403 | } |
394 | 404 | ||
@@ -396,20 +406,66 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy, | |||
396 | struct wireless_dev *wdev) | 406 | struct wireless_dev *wdev) |
397 | { | 407 | { |
398 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 408 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
399 | struct wil_p2p_info *p2p = &wil->p2p; | ||
400 | 409 | ||
401 | if (!p2p->p2p_dev_started) | 410 | if (!wil->p2p_dev_started) |
402 | return; | 411 | return; |
403 | 412 | ||
404 | wil_dbg_misc(wil, "stop_p2p_device: entered\n"); | 413 | wil_dbg_misc(wil, "stop_p2p_device: entered\n"); |
405 | mutex_lock(&wil->mutex); | 414 | mutex_lock(&wil->mutex); |
406 | mutex_lock(&wil->p2p_wdev_mutex); | 415 | mutex_lock(&wil->vif_mutex); |
407 | wil_p2p_stop_radio_operations(wil); | 416 | wil_p2p_stop_radio_operations(wil); |
408 | p2p->p2p_dev_started = 0; | 417 | wil->p2p_dev_started = 0; |
409 | mutex_unlock(&wil->p2p_wdev_mutex); | 418 | mutex_unlock(&wil->vif_mutex); |
410 | mutex_unlock(&wil->mutex); | 419 | mutex_unlock(&wil->mutex); |
411 | } | 420 | } |
412 | 421 | ||
422 | static int wil_cfg80211_validate_add_iface(struct wil6210_priv *wil, | ||
423 | enum nl80211_iftype new_type) | ||
424 | { | ||
425 | int i; | ||
426 | struct wireless_dev *wdev; | ||
427 | struct iface_combination_params params = { | ||
428 | .num_different_channels = 1, | ||
429 | }; | ||
430 | |||
431 | for (i = 0; i < wil->max_vifs; i++) { | ||
432 | if (wil->vifs[i]) { | ||
433 | wdev = vif_to_wdev(wil->vifs[i]); | ||
434 | params.iftype_num[wdev->iftype]++; | ||
435 | } | ||
436 | } | ||
437 | params.iftype_num[new_type]++; | ||
438 | return cfg80211_check_combinations(wil->wiphy, ¶ms); | ||
439 | } | ||
440 | |||
441 | static int wil_cfg80211_validate_change_iface(struct wil6210_priv *wil, | ||
442 | struct wil6210_vif *vif, | ||
443 | enum nl80211_iftype new_type) | ||
444 | { | ||
445 | int i, ret = 0; | ||
446 | struct wireless_dev *wdev; | ||
447 | struct iface_combination_params params = { | ||
448 | .num_different_channels = 1, | ||
449 | }; | ||
450 | bool check_combos = false; | ||
451 | |||
452 | for (i = 0; i < wil->max_vifs; i++) { | ||
453 | struct wil6210_vif *vif_pos = wil->vifs[i]; | ||
454 | |||
455 | if (vif_pos && vif != vif_pos) { | ||
456 | wdev = vif_to_wdev(vif_pos); | ||
457 | params.iftype_num[wdev->iftype]++; | ||
458 | check_combos = true; | ||
459 | } | ||
460 | } | ||
461 | |||
462 | if (check_combos) { | ||
463 | params.iftype_num[new_type]++; | ||
464 | ret = cfg80211_check_combinations(wil->wiphy, ¶ms); | ||
465 | } | ||
466 | return ret; | ||
467 | } | ||
468 | |||
413 | static struct wireless_dev * | 469 | static struct wireless_dev * |
414 | wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name, | 470 | wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name, |
415 | unsigned char name_assign_type, | 471 | unsigned char name_assign_type, |
@@ -417,51 +473,137 @@ wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name, | |||
417 | struct vif_params *params) | 473 | struct vif_params *params) |
418 | { | 474 | { |
419 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 475 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
420 | struct net_device *ndev = wil_to_ndev(wil); | 476 | struct net_device *ndev_main = wil->main_ndev, *ndev; |
421 | struct wireless_dev *p2p_wdev; | 477 | struct wil6210_vif *vif; |
478 | struct wireless_dev *p2p_wdev, *wdev; | ||
479 | int rc; | ||
422 | 480 | ||
423 | wil_dbg_misc(wil, "add_iface\n"); | 481 | wil_dbg_misc(wil, "add_iface, type %d\n", type); |
424 | 482 | ||
425 | if (type != NL80211_IFTYPE_P2P_DEVICE) { | 483 | /* P2P device is not a real virtual interface, it is a management-only |
426 | wil_err(wil, "unsupported iftype %d\n", type); | 484 | * interface that shares the main interface. |
427 | return ERR_PTR(-EINVAL); | 485 | * Skip concurrency checks here. |
486 | */ | ||
487 | if (type == NL80211_IFTYPE_P2P_DEVICE) { | ||
488 | if (wil->p2p_wdev) { | ||
489 | wil_err(wil, "P2P_DEVICE interface already created\n"); | ||
490 | return ERR_PTR(-EINVAL); | ||
491 | } | ||
492 | |||
493 | p2p_wdev = kzalloc(sizeof(*p2p_wdev), GFP_KERNEL); | ||
494 | if (!p2p_wdev) | ||
495 | return ERR_PTR(-ENOMEM); | ||
496 | |||
497 | p2p_wdev->iftype = type; | ||
498 | p2p_wdev->wiphy = wiphy; | ||
499 | /* use our primary ethernet address */ | ||
500 | ether_addr_copy(p2p_wdev->address, ndev_main->perm_addr); | ||
501 | |||
502 | wil->p2p_wdev = p2p_wdev; | ||
503 | |||
504 | return p2p_wdev; | ||
428 | } | 505 | } |
429 | 506 | ||
430 | if (wil->p2p_wdev) { | 507 | if (!wil->wiphy->n_iface_combinations) { |
431 | wil_err(wil, "P2P_DEVICE interface already created\n"); | 508 | wil_err(wil, "virtual interfaces not supported\n"); |
432 | return ERR_PTR(-EINVAL); | 509 | return ERR_PTR(-EINVAL); |
433 | } | 510 | } |
434 | 511 | ||
435 | p2p_wdev = kzalloc(sizeof(*p2p_wdev), GFP_KERNEL); | 512 | rc = wil_cfg80211_validate_add_iface(wil, type); |
436 | if (!p2p_wdev) | 513 | if (rc) { |
437 | return ERR_PTR(-ENOMEM); | 514 | wil_err(wil, "iface validation failed, err=%d\n", rc); |
515 | return ERR_PTR(rc); | ||
516 | } | ||
438 | 517 | ||
439 | p2p_wdev->iftype = type; | 518 | vif = wil_vif_alloc(wil, name, name_assign_type, type); |
440 | p2p_wdev->wiphy = wiphy; | 519 | if (IS_ERR(vif)) |
441 | /* use our primary ethernet address */ | 520 | return ERR_CAST(vif); |
442 | ether_addr_copy(p2p_wdev->address, ndev->perm_addr); | 521 | |
522 | ndev = vif_to_ndev(vif); | ||
523 | ether_addr_copy(ndev->perm_addr, ndev_main->perm_addr); | ||
524 | if (is_valid_ether_addr(params->macaddr)) { | ||
525 | ether_addr_copy(ndev->dev_addr, params->macaddr); | ||
526 | } else { | ||
527 | ether_addr_copy(ndev->dev_addr, ndev_main->perm_addr); | ||
528 | ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << vif->mid)) | | ||
529 | 0x2; /* locally administered */ | ||
530 | } | ||
531 | wdev = vif_to_wdev(vif); | ||
532 | ether_addr_copy(wdev->address, ndev->dev_addr); | ||
443 | 533 | ||
444 | wil->p2p_wdev = p2p_wdev; | 534 | rc = wil_vif_add(wil, vif); |
535 | if (rc) | ||
536 | goto out; | ||
445 | 537 | ||
446 | return p2p_wdev; | 538 | wil_info(wil, "added VIF, mid %d iftype %d MAC %pM\n", |
539 | vif->mid, type, wdev->address); | ||
540 | return wdev; | ||
541 | out: | ||
542 | wil_vif_free(vif); | ||
543 | return ERR_PTR(rc); | ||
544 | } | ||
545 | |||
546 | int wil_vif_prepare_stop(struct wil6210_vif *vif) | ||
547 | { | ||
548 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
549 | struct wireless_dev *wdev = vif_to_wdev(vif); | ||
550 | struct net_device *ndev; | ||
551 | int rc; | ||
552 | |||
553 | if (wdev->iftype != NL80211_IFTYPE_AP) | ||
554 | return 0; | ||
555 | |||
556 | ndev = vif_to_ndev(vif); | ||
557 | if (netif_carrier_ok(ndev)) { | ||
558 | rc = wmi_pcp_stop(vif); | ||
559 | if (rc) { | ||
560 | wil_info(wil, "failed to stop AP, status %d\n", | ||
561 | rc); | ||
562 | /* continue */ | ||
563 | } | ||
564 | wil_bcast_fini(vif); | ||
565 | netif_carrier_off(ndev); | ||
566 | } | ||
567 | |||
568 | return 0; | ||
447 | } | 569 | } |
448 | 570 | ||
449 | static int wil_cfg80211_del_iface(struct wiphy *wiphy, | 571 | static int wil_cfg80211_del_iface(struct wiphy *wiphy, |
450 | struct wireless_dev *wdev) | 572 | struct wireless_dev *wdev) |
451 | { | 573 | { |
452 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 574 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
575 | struct wil6210_vif *vif = wdev_to_vif(wil, wdev); | ||
576 | int rc; | ||
453 | 577 | ||
454 | wil_dbg_misc(wil, "del_iface\n"); | 578 | wil_dbg_misc(wil, "del_iface\n"); |
455 | 579 | ||
456 | if (wdev != wil->p2p_wdev) { | 580 | if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { |
457 | wil_err(wil, "delete of incorrect interface 0x%p\n", wdev); | 581 | if (wdev != wil->p2p_wdev) { |
582 | wil_err(wil, "delete of incorrect interface 0x%p\n", | ||
583 | wdev); | ||
584 | return -EINVAL; | ||
585 | } | ||
586 | |||
587 | wil_cfg80211_stop_p2p_device(wiphy, wdev); | ||
588 | wil_p2p_wdev_free(wil); | ||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | if (vif->mid == 0) { | ||
593 | wil_err(wil, "cannot remove the main interface\n"); | ||
458 | return -EINVAL; | 594 | return -EINVAL; |
459 | } | 595 | } |
460 | 596 | ||
461 | wil_cfg80211_stop_p2p_device(wiphy, wdev); | 597 | rc = wil_vif_prepare_stop(vif); |
462 | wil_p2p_wdev_free(wil); | 598 | if (rc) |
599 | goto out; | ||
600 | |||
601 | wil_info(wil, "deleted VIF, mid %d iftype %d MAC %pM\n", | ||
602 | vif->mid, wdev->iftype, wdev->address); | ||
463 | 603 | ||
464 | return 0; | 604 | wil_vif_remove(wil, vif->mid); |
605 | out: | ||
606 | return rc; | ||
465 | } | 607 | } |
466 | 608 | ||
467 | static int wil_cfg80211_change_iface(struct wiphy *wiphy, | 609 | static int wil_cfg80211_change_iface(struct wiphy *wiphy, |
@@ -470,12 +612,26 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy, | |||
470 | struct vif_params *params) | 612 | struct vif_params *params) |
471 | { | 613 | { |
472 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 614 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
473 | struct wireless_dev *wdev = wil_to_wdev(wil); | 615 | struct wil6210_vif *vif = ndev_to_vif(ndev); |
616 | struct wireless_dev *wdev = vif_to_wdev(vif); | ||
474 | int rc; | 617 | int rc; |
618 | bool fw_reset = false; | ||
475 | 619 | ||
476 | wil_dbg_misc(wil, "change_iface: type=%d\n", type); | 620 | wil_dbg_misc(wil, "change_iface: type=%d\n", type); |
477 | 621 | ||
478 | if (netif_running(wil_to_ndev(wil)) && !wil_is_recovery_blocked(wil)) { | 622 | if (wiphy->n_iface_combinations) { |
623 | rc = wil_cfg80211_validate_change_iface(wil, vif, type); | ||
624 | if (rc) { | ||
625 | wil_err(wil, "iface validation failed, err=%d\n", rc); | ||
626 | return rc; | ||
627 | } | ||
628 | } | ||
629 | |||
630 | /* do not reset FW when there are active VIFs, | ||
631 | * because it can cause significant disruption | ||
632 | */ | ||
633 | if (!wil_has_other_active_ifaces(wil, ndev, true, false) && | ||
634 | netif_running(ndev) && !wil_is_recovery_blocked(wil)) { | ||
479 | wil_dbg_misc(wil, "interface is up. resetting...\n"); | 635 | wil_dbg_misc(wil, "interface is up. resetting...\n"); |
480 | mutex_lock(&wil->mutex); | 636 | mutex_lock(&wil->mutex); |
481 | __wil_down(wil); | 637 | __wil_down(wil); |
@@ -484,6 +640,7 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy, | |||
484 | 640 | ||
485 | if (rc) | 641 | if (rc) |
486 | return rc; | 642 | return rc; |
643 | fw_reset = true; | ||
487 | } | 644 | } |
488 | 645 | ||
489 | switch (type) { | 646 | switch (type) { |
@@ -500,8 +657,18 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy, | |||
500 | return -EOPNOTSUPP; | 657 | return -EOPNOTSUPP; |
501 | } | 658 | } |
502 | 659 | ||
503 | wdev->iftype = type; | 660 | if (vif->mid != 0 && wil_has_active_ifaces(wil, true, false)) { |
661 | if (!fw_reset) | ||
662 | wil_vif_prepare_stop(vif); | ||
663 | rc = wmi_port_delete(wil, vif->mid); | ||
664 | if (rc) | ||
665 | return rc; | ||
666 | rc = wmi_port_allocate(wil, vif->mid, ndev->dev_addr, type); | ||
667 | if (rc) | ||
668 | return rc; | ||
669 | } | ||
504 | 670 | ||
671 | wdev->iftype = type; | ||
505 | return 0; | 672 | return 0; |
506 | } | 673 | } |
507 | 674 | ||
@@ -510,6 +677,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, | |||
510 | { | 677 | { |
511 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 678 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
512 | struct wireless_dev *wdev = request->wdev; | 679 | struct wireless_dev *wdev = request->wdev; |
680 | struct wil6210_vif *vif = wdev_to_vif(wil, wdev); | ||
513 | struct { | 681 | struct { |
514 | struct wmi_start_scan_cmd cmd; | 682 | struct wmi_start_scan_cmd cmd; |
515 | u16 chnl[4]; | 683 | u16 chnl[4]; |
@@ -537,35 +705,38 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, | |||
537 | 705 | ||
538 | mutex_lock(&wil->mutex); | 706 | mutex_lock(&wil->mutex); |
539 | 707 | ||
540 | mutex_lock(&wil->p2p_wdev_mutex); | 708 | mutex_lock(&wil->vif_mutex); |
541 | if (wil->scan_request || wil->p2p.discovery_started) { | 709 | if (vif->scan_request || vif->p2p.discovery_started) { |
542 | wil_err(wil, "Already scanning\n"); | 710 | wil_err(wil, "Already scanning\n"); |
543 | mutex_unlock(&wil->p2p_wdev_mutex); | 711 | mutex_unlock(&wil->vif_mutex); |
544 | rc = -EAGAIN; | 712 | rc = -EAGAIN; |
545 | goto out; | 713 | goto out; |
546 | } | 714 | } |
547 | mutex_unlock(&wil->p2p_wdev_mutex); | 715 | mutex_unlock(&wil->vif_mutex); |
548 | 716 | ||
549 | if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { | 717 | if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { |
550 | if (!wil->p2p.p2p_dev_started) { | 718 | if (!wil->p2p_dev_started) { |
551 | wil_err(wil, "P2P search requested on stopped P2P device\n"); | 719 | wil_err(wil, "P2P search requested on stopped P2P device\n"); |
552 | rc = -EIO; | 720 | rc = -EIO; |
553 | goto out; | 721 | goto out; |
554 | } | 722 | } |
555 | /* social scan on P2P_DEVICE is handled as p2p search */ | 723 | /* social scan on P2P_DEVICE is handled as p2p search */ |
556 | if (wil_p2p_is_social_scan(request)) { | 724 | if (wil_p2p_is_social_scan(request)) { |
557 | wil->scan_request = request; | 725 | vif->scan_request = request; |
558 | wil->radio_wdev = wdev; | 726 | if (vif->mid == 0) |
559 | rc = wil_p2p_search(wil, request); | 727 | wil->radio_wdev = wdev; |
728 | rc = wil_p2p_search(vif, request); | ||
560 | if (rc) { | 729 | if (rc) { |
561 | wil->radio_wdev = wil_to_wdev(wil); | 730 | if (vif->mid == 0) |
562 | wil->scan_request = NULL; | 731 | wil->radio_wdev = |
732 | wil->main_ndev->ieee80211_ptr; | ||
733 | vif->scan_request = NULL; | ||
563 | } | 734 | } |
564 | goto out; | 735 | goto out; |
565 | } | 736 | } |
566 | } | 737 | } |
567 | 738 | ||
568 | (void)wil_p2p_stop_discovery(wil); | 739 | (void)wil_p2p_stop_discovery(vif); |
569 | 740 | ||
570 | wil_dbg_misc(wil, "Start scan_request 0x%p\n", request); | 741 | wil_dbg_misc(wil, "Start scan_request 0x%p\n", request); |
571 | wil_dbg_misc(wil, "SSID count: %d", request->n_ssids); | 742 | wil_dbg_misc(wil, "SSID count: %d", request->n_ssids); |
@@ -578,18 +749,18 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, | |||
578 | } | 749 | } |
579 | 750 | ||
580 | if (request->n_ssids) | 751 | if (request->n_ssids) |
581 | rc = wmi_set_ssid(wil, request->ssids[0].ssid_len, | 752 | rc = wmi_set_ssid(vif, request->ssids[0].ssid_len, |
582 | request->ssids[0].ssid); | 753 | request->ssids[0].ssid); |
583 | else | 754 | else |
584 | rc = wmi_set_ssid(wil, 0, NULL); | 755 | rc = wmi_set_ssid(vif, 0, NULL); |
585 | 756 | ||
586 | if (rc) { | 757 | if (rc) { |
587 | wil_err(wil, "set SSID for scan request failed: %d\n", rc); | 758 | wil_err(wil, "set SSID for scan request failed: %d\n", rc); |
588 | goto out; | 759 | goto out; |
589 | } | 760 | } |
590 | 761 | ||
591 | wil->scan_request = request; | 762 | vif->scan_request = request; |
592 | mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO); | 763 | mod_timer(&vif->scan_timer, jiffies + WIL6210_SCAN_TO); |
593 | 764 | ||
594 | memset(&cmd, 0, sizeof(cmd)); | 765 | memset(&cmd, 0, sizeof(cmd)); |
595 | cmd.cmd.scan_type = WMI_ACTIVE_SCAN; | 766 | cmd.cmd.scan_type = WMI_ACTIVE_SCAN; |
@@ -616,7 +787,8 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, | |||
616 | else | 787 | else |
617 | wil_dbg_misc(wil, "Scan has no IE's\n"); | 788 | wil_dbg_misc(wil, "Scan has no IE's\n"); |
618 | 789 | ||
619 | rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie); | 790 | rc = wmi_set_ie(vif, WMI_FRAME_PROBE_REQ, |
791 | request->ie_len, request->ie); | ||
620 | if (rc) | 792 | if (rc) |
621 | goto out_restore; | 793 | goto out_restore; |
622 | 794 | ||
@@ -625,15 +797,18 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, | |||
625 | wil_dbg_misc(wil, "active scan with discovery_mode=1\n"); | 797 | wil_dbg_misc(wil, "active scan with discovery_mode=1\n"); |
626 | } | 798 | } |
627 | 799 | ||
628 | wil->radio_wdev = wdev; | 800 | if (vif->mid == 0) |
629 | rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) + | 801 | wil->radio_wdev = wdev; |
630 | cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0])); | 802 | rc = wmi_send(wil, WMI_START_SCAN_CMDID, vif->mid, |
803 | &cmd, sizeof(cmd.cmd) + | ||
804 | cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0])); | ||
631 | 805 | ||
632 | out_restore: | 806 | out_restore: |
633 | if (rc) { | 807 | if (rc) { |
634 | del_timer_sync(&wil->scan_timer); | 808 | del_timer_sync(&vif->scan_timer); |
635 | wil->radio_wdev = wil_to_wdev(wil); | 809 | if (vif->mid == 0) |
636 | wil->scan_request = NULL; | 810 | wil->radio_wdev = wil->main_ndev->ieee80211_ptr; |
811 | vif->scan_request = NULL; | ||
637 | } | 812 | } |
638 | out: | 813 | out: |
639 | mutex_unlock(&wil->mutex); | 814 | mutex_unlock(&wil->mutex); |
@@ -644,27 +819,28 @@ static void wil_cfg80211_abort_scan(struct wiphy *wiphy, | |||
644 | struct wireless_dev *wdev) | 819 | struct wireless_dev *wdev) |
645 | { | 820 | { |
646 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 821 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
822 | struct wil6210_vif *vif = wdev_to_vif(wil, wdev); | ||
647 | 823 | ||
648 | wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype); | 824 | wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype); |
649 | 825 | ||
650 | mutex_lock(&wil->mutex); | 826 | mutex_lock(&wil->mutex); |
651 | mutex_lock(&wil->p2p_wdev_mutex); | 827 | mutex_lock(&wil->vif_mutex); |
652 | 828 | ||
653 | if (!wil->scan_request) | 829 | if (!vif->scan_request) |
654 | goto out; | 830 | goto out; |
655 | 831 | ||
656 | if (wdev != wil->scan_request->wdev) { | 832 | if (wdev != vif->scan_request->wdev) { |
657 | wil_dbg_misc(wil, "abort scan was called on the wrong iface\n"); | 833 | wil_dbg_misc(wil, "abort scan was called on the wrong iface\n"); |
658 | goto out; | 834 | goto out; |
659 | } | 835 | } |
660 | 836 | ||
661 | if (wil->radio_wdev == wil->p2p_wdev) | 837 | if (wdev == wil->p2p_wdev && wil->radio_wdev == wil->p2p_wdev) |
662 | wil_p2p_stop_radio_operations(wil); | 838 | wil_p2p_stop_radio_operations(wil); |
663 | else | 839 | else |
664 | wil_abort_scan(wil, true); | 840 | wil_abort_scan(vif, true); |
665 | 841 | ||
666 | out: | 842 | out: |
667 | mutex_unlock(&wil->p2p_wdev_mutex); | 843 | mutex_unlock(&wil->vif_mutex); |
668 | mutex_unlock(&wil->mutex); | 844 | mutex_unlock(&wil->mutex); |
669 | } | 845 | } |
670 | 846 | ||
@@ -715,6 +891,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, | |||
715 | struct cfg80211_connect_params *sme) | 891 | struct cfg80211_connect_params *sme) |
716 | { | 892 | { |
717 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 893 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
894 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
718 | struct cfg80211_bss *bss; | 895 | struct cfg80211_bss *bss; |
719 | struct wmi_connect_cmd conn; | 896 | struct wmi_connect_cmd conn; |
720 | const u8 *ssid_eid; | 897 | const u8 *ssid_eid; |
@@ -723,11 +900,11 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, | |||
723 | int rc = 0; | 900 | int rc = 0; |
724 | enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS; | 901 | enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS; |
725 | 902 | ||
726 | wil_dbg_misc(wil, "connect\n"); | 903 | wil_dbg_misc(wil, "connect, mid=%d\n", vif->mid); |
727 | wil_print_connect_params(wil, sme); | 904 | wil_print_connect_params(wil, sme); |
728 | 905 | ||
729 | if (test_bit(wil_status_fwconnecting, wil->status) || | 906 | if (test_bit(wil_vif_fwconnecting, vif->status) || |
730 | test_bit(wil_status_fwconnected, wil->status)) | 907 | test_bit(wil_vif_fwconnected, vif->status)) |
731 | return -EALREADY; | 908 | return -EALREADY; |
732 | 909 | ||
733 | if (sme->ie_len > WMI_MAX_IE_LEN) { | 910 | if (sme->ie_len > WMI_MAX_IE_LEN) { |
@@ -758,18 +935,18 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, | |||
758 | rc = -ENOENT; | 935 | rc = -ENOENT; |
759 | goto out; | 936 | goto out; |
760 | } | 937 | } |
761 | wil->privacy = sme->privacy; | 938 | vif->privacy = sme->privacy; |
762 | wil->pbss = sme->pbss; | 939 | vif->pbss = sme->pbss; |
763 | 940 | ||
764 | if (wil->privacy) { | 941 | if (vif->privacy) { |
765 | /* For secure assoc, remove old keys */ | 942 | /* For secure assoc, remove old keys */ |
766 | rc = wmi_del_cipher_key(wil, 0, bss->bssid, | 943 | rc = wmi_del_cipher_key(vif, 0, bss->bssid, |
767 | WMI_KEY_USE_PAIRWISE); | 944 | WMI_KEY_USE_PAIRWISE); |
768 | if (rc) { | 945 | if (rc) { |
769 | wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n"); | 946 | wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n"); |
770 | goto out; | 947 | goto out; |
771 | } | 948 | } |
772 | rc = wmi_del_cipher_key(wil, 0, bss->bssid, | 949 | rc = wmi_del_cipher_key(vif, 0, bss->bssid, |
773 | WMI_KEY_USE_RX_GROUP); | 950 | WMI_KEY_USE_RX_GROUP); |
774 | if (rc) { | 951 | if (rc) { |
775 | wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n"); | 952 | wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n"); |
@@ -781,7 +958,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, | |||
781 | * elements. Send it also in case it's empty, to erase previously set | 958 | * elements. Send it also in case it's empty, to erase previously set |
782 | * ies in FW. | 959 | * ies in FW. |
783 | */ | 960 | */ |
784 | rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); | 961 | rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); |
785 | if (rc) | 962 | if (rc) |
786 | goto out; | 963 | goto out; |
787 | 964 | ||
@@ -799,7 +976,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, | |||
799 | bss->capability); | 976 | bss->capability); |
800 | goto out; | 977 | goto out; |
801 | } | 978 | } |
802 | if (wil->privacy) { | 979 | if (vif->privacy) { |
803 | if (rsn_eid) { /* regular secure connection */ | 980 | if (rsn_eid) { /* regular secure connection */ |
804 | conn.dot11_auth_mode = WMI_AUTH11_SHARED; | 981 | conn.dot11_auth_mode = WMI_AUTH11_SHARED; |
805 | conn.auth_mode = WMI_AUTH_WPA2_PSK; | 982 | conn.auth_mode = WMI_AUTH_WPA2_PSK; |
@@ -831,18 +1008,19 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, | |||
831 | ether_addr_copy(conn.bssid, bss->bssid); | 1008 | ether_addr_copy(conn.bssid, bss->bssid); |
832 | ether_addr_copy(conn.dst_mac, bss->bssid); | 1009 | ether_addr_copy(conn.dst_mac, bss->bssid); |
833 | 1010 | ||
834 | set_bit(wil_status_fwconnecting, wil->status); | 1011 | set_bit(wil_vif_fwconnecting, vif->status); |
835 | 1012 | ||
836 | rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn)); | 1013 | rc = wmi_send(wil, WMI_CONNECT_CMDID, vif->mid, &conn, sizeof(conn)); |
837 | if (rc == 0) { | 1014 | if (rc == 0) { |
838 | netif_carrier_on(ndev); | 1015 | netif_carrier_on(ndev); |
839 | wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS); | 1016 | if (!wil_has_other_active_ifaces(wil, ndev, false, true)) |
840 | wil->bss = bss; | 1017 | wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS); |
1018 | vif->bss = bss; | ||
841 | /* Connect can take lots of time */ | 1019 | /* Connect can take lots of time */ |
842 | mod_timer(&wil->connect_timer, | 1020 | mod_timer(&vif->connect_timer, |
843 | jiffies + msecs_to_jiffies(5000)); | 1021 | jiffies + msecs_to_jiffies(5000)); |
844 | } else { | 1022 | } else { |
845 | clear_bit(wil_status_fwconnecting, wil->status); | 1023 | clear_bit(wil_vif_fwconnecting, vif->status); |
846 | } | 1024 | } |
847 | 1025 | ||
848 | out: | 1026 | out: |
@@ -857,17 +1035,19 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy, | |||
857 | { | 1035 | { |
858 | int rc; | 1036 | int rc; |
859 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1037 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1038 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
860 | 1039 | ||
861 | wil_dbg_misc(wil, "disconnect: reason=%d\n", reason_code); | 1040 | wil_dbg_misc(wil, "disconnect: reason=%d, mid=%d\n", |
1041 | reason_code, vif->mid); | ||
862 | 1042 | ||
863 | if (!(test_bit(wil_status_fwconnecting, wil->status) || | 1043 | if (!(test_bit(wil_vif_fwconnecting, vif->status) || |
864 | test_bit(wil_status_fwconnected, wil->status))) { | 1044 | test_bit(wil_vif_fwconnected, vif->status))) { |
865 | wil_err(wil, "Disconnect was called while disconnected\n"); | 1045 | wil_err(wil, "Disconnect was called while disconnected\n"); |
866 | return 0; | 1046 | return 0; |
867 | } | 1047 | } |
868 | 1048 | ||
869 | wil->locally_generated_disc = true; | 1049 | vif->locally_generated_disc = true; |
870 | rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0, | 1050 | rc = wmi_call(wil, WMI_DISCONNECT_CMDID, vif->mid, NULL, 0, |
871 | WMI_DISCONNECT_EVENTID, NULL, 0, | 1051 | WMI_DISCONNECT_EVENTID, NULL, 0, |
872 | WIL6210_DISCONNECT_TO_MS); | 1052 | WIL6210_DISCONNECT_TO_MS); |
873 | if (rc) | 1053 | if (rc) |
@@ -903,6 +1083,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
903 | const u8 *buf = params->buf; | 1083 | const u8 *buf = params->buf; |
904 | size_t len = params->len, total; | 1084 | size_t len = params->len, total; |
905 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1085 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1086 | struct wil6210_vif *vif = wdev_to_vif(wil, wdev); | ||
906 | int rc; | 1087 | int rc; |
907 | bool tx_status = false; | 1088 | bool tx_status = false; |
908 | struct ieee80211_mgmt *mgmt_frame = (void *)buf; | 1089 | struct ieee80211_mgmt *mgmt_frame = (void *)buf; |
@@ -919,7 +1100,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
919 | * different from currently "listened" channel and fail if it is. | 1100 | * different from currently "listened" channel and fail if it is. |
920 | */ | 1101 | */ |
921 | 1102 | ||
922 | wil_dbg_misc(wil, "mgmt_tx\n"); | 1103 | wil_dbg_misc(wil, "mgmt_tx mid %d\n", vif->mid); |
923 | wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf, | 1104 | wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf, |
924 | len, true); | 1105 | len, true); |
925 | 1106 | ||
@@ -940,7 +1121,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
940 | cmd->len = cpu_to_le16(len); | 1121 | cmd->len = cpu_to_le16(len); |
941 | memcpy(cmd->payload, buf, len); | 1122 | memcpy(cmd->payload, buf, len); |
942 | 1123 | ||
943 | rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, total, | 1124 | rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, vif->mid, cmd, total, |
944 | WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000); | 1125 | WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000); |
945 | if (rc == 0) | 1126 | if (rc == 0) |
946 | tx_status = !evt.evt.status; | 1127 | tx_status = !evt.evt.status; |
@@ -962,10 +1143,10 @@ static int wil_cfg80211_set_channel(struct wiphy *wiphy, | |||
962 | return 0; | 1143 | return 0; |
963 | } | 1144 | } |
964 | 1145 | ||
965 | static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil, | 1146 | static enum wmi_key_usage wil_detect_key_usage(struct wireless_dev *wdev, |
966 | bool pairwise) | 1147 | bool pairwise) |
967 | { | 1148 | { |
968 | struct wireless_dev *wdev = wil_to_wdev(wil); | 1149 | struct wil6210_priv *wil = wdev_to_wil(wdev); |
969 | enum wmi_key_usage rc; | 1150 | enum wmi_key_usage rc; |
970 | 1151 | ||
971 | if (pairwise) { | 1152 | if (pairwise) { |
@@ -993,7 +1174,7 @@ static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil, | |||
993 | } | 1174 | } |
994 | 1175 | ||
995 | static struct wil_sta_info * | 1176 | static struct wil_sta_info * |
996 | wil_find_sta_by_key_usage(struct wil6210_priv *wil, | 1177 | wil_find_sta_by_key_usage(struct wil6210_priv *wil, u8 mid, |
997 | enum wmi_key_usage key_usage, const u8 *mac_addr) | 1178 | enum wmi_key_usage key_usage, const u8 *mac_addr) |
998 | { | 1179 | { |
999 | int cid = -EINVAL; | 1180 | int cid = -EINVAL; |
@@ -1003,9 +1184,9 @@ wil_find_sta_by_key_usage(struct wil6210_priv *wil, | |||
1003 | 1184 | ||
1004 | /* supplicant provides Rx group key in STA mode with NULL MAC address */ | 1185 | /* supplicant provides Rx group key in STA mode with NULL MAC address */ |
1005 | if (mac_addr) | 1186 | if (mac_addr) |
1006 | cid = wil_find_cid(wil, mac_addr); | 1187 | cid = wil_find_cid(wil, mid, mac_addr); |
1007 | else if (key_usage == WMI_KEY_USE_RX_GROUP) | 1188 | else if (key_usage == WMI_KEY_USE_RX_GROUP) |
1008 | cid = wil_find_cid_by_idx(wil, 0); | 1189 | cid = wil_find_cid_by_idx(wil, mid, 0); |
1009 | if (cid < 0) { | 1190 | if (cid < 0) { |
1010 | wil_err(wil, "No CID for %pM %s\n", mac_addr, | 1191 | wil_err(wil, "No CID for %pM %s\n", mac_addr, |
1011 | key_usage_str[key_usage]); | 1192 | key_usage_str[key_usage]); |
@@ -1082,9 +1263,12 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy, | |||
1082 | struct key_params *params) | 1263 | struct key_params *params) |
1083 | { | 1264 | { |
1084 | int rc; | 1265 | int rc; |
1266 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
1085 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1267 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1086 | enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise); | 1268 | struct wireless_dev *wdev = vif_to_wdev(vif); |
1087 | struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage, | 1269 | enum wmi_key_usage key_usage = wil_detect_key_usage(wdev, pairwise); |
1270 | struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, vif->mid, | ||
1271 | key_usage, | ||
1088 | mac_addr); | 1272 | mac_addr); |
1089 | 1273 | ||
1090 | if (!params) { | 1274 | if (!params) { |
@@ -1114,7 +1298,7 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy, | |||
1114 | return -EINVAL; | 1298 | return -EINVAL; |
1115 | } | 1299 | } |
1116 | 1300 | ||
1117 | rc = wmi_add_cipher_key(wil, key_index, mac_addr, params->key_len, | 1301 | rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len, |
1118 | params->key, key_usage); | 1302 | params->key, key_usage); |
1119 | if (!rc) | 1303 | if (!rc) |
1120 | wil_set_crypto_rx(key_index, key_usage, cs, params); | 1304 | wil_set_crypto_rx(key_index, key_usage, cs, params); |
@@ -1127,9 +1311,12 @@ static int wil_cfg80211_del_key(struct wiphy *wiphy, | |||
1127 | u8 key_index, bool pairwise, | 1311 | u8 key_index, bool pairwise, |
1128 | const u8 *mac_addr) | 1312 | const u8 *mac_addr) |
1129 | { | 1313 | { |
1314 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
1130 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1315 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1131 | enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise); | 1316 | struct wireless_dev *wdev = vif_to_wdev(vif); |
1132 | struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage, | 1317 | enum wmi_key_usage key_usage = wil_detect_key_usage(wdev, pairwise); |
1318 | struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, vif->mid, | ||
1319 | key_usage, | ||
1133 | mac_addr); | 1320 | mac_addr); |
1134 | 1321 | ||
1135 | wil_dbg_misc(wil, "del_key: %pM %s[%d]\n", mac_addr, | 1322 | wil_dbg_misc(wil, "del_key: %pM %s[%d]\n", mac_addr, |
@@ -1142,7 +1329,7 @@ static int wil_cfg80211_del_key(struct wiphy *wiphy, | |||
1142 | if (!IS_ERR_OR_NULL(cs)) | 1329 | if (!IS_ERR_OR_NULL(cs)) |
1143 | wil_del_rx_key(key_index, key_usage, cs); | 1330 | wil_del_rx_key(key_index, key_usage, cs); |
1144 | 1331 | ||
1145 | return wmi_del_cipher_key(wil, key_index, mac_addr, key_usage); | 1332 | return wmi_del_cipher_key(vif, key_index, mac_addr, key_usage); |
1146 | } | 1333 | } |
1147 | 1334 | ||
1148 | /* Need to be present or wiphy_new() will WARN */ | 1335 | /* Need to be present or wiphy_new() will WARN */ |
@@ -1179,10 +1366,11 @@ static int wil_cancel_remain_on_channel(struct wiphy *wiphy, | |||
1179 | u64 cookie) | 1366 | u64 cookie) |
1180 | { | 1367 | { |
1181 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1368 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1369 | struct wil6210_vif *vif = wdev_to_vif(wil, wdev); | ||
1182 | 1370 | ||
1183 | wil_dbg_misc(wil, "cancel_remain_on_channel\n"); | 1371 | wil_dbg_misc(wil, "cancel_remain_on_channel\n"); |
1184 | 1372 | ||
1185 | return wil_p2p_cancel_listen(wil, cookie); | 1373 | return wil_p2p_cancel_listen(vif, cookie); |
1186 | } | 1374 | } |
1187 | 1375 | ||
1188 | /** | 1376 | /** |
@@ -1275,11 +1463,10 @@ static void wil_print_bcon_data(struct cfg80211_beacon_data *b) | |||
1275 | } | 1463 | } |
1276 | 1464 | ||
1277 | /* internal functions for device reset and starting AP */ | 1465 | /* internal functions for device reset and starting AP */ |
1278 | static int _wil_cfg80211_set_ies(struct wiphy *wiphy, | 1466 | static int _wil_cfg80211_set_ies(struct wil6210_vif *vif, |
1279 | struct cfg80211_beacon_data *bcon) | 1467 | struct cfg80211_beacon_data *bcon) |
1280 | { | 1468 | { |
1281 | int rc; | 1469 | int rc; |
1282 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | ||
1283 | u16 len = 0, proberesp_len = 0; | 1470 | u16 len = 0, proberesp_len = 0; |
1284 | u8 *ies = NULL, *proberesp = NULL; | 1471 | u8 *ies = NULL, *proberesp = NULL; |
1285 | 1472 | ||
@@ -1300,20 +1487,21 @@ static int _wil_cfg80211_set_ies(struct wiphy *wiphy, | |||
1300 | if (rc) | 1487 | if (rc) |
1301 | goto out; | 1488 | goto out; |
1302 | 1489 | ||
1303 | rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, len, ies); | 1490 | rc = wmi_set_ie(vif, WMI_FRAME_PROBE_RESP, len, ies); |
1304 | if (rc) | 1491 | if (rc) |
1305 | goto out; | 1492 | goto out; |
1306 | 1493 | ||
1307 | if (bcon->assocresp_ies) | 1494 | if (bcon->assocresp_ies) |
1308 | rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, | 1495 | rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_RESP, |
1309 | bcon->assocresp_ies_len, bcon->assocresp_ies); | 1496 | bcon->assocresp_ies_len, bcon->assocresp_ies); |
1310 | else | 1497 | else |
1311 | rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, len, ies); | 1498 | rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_RESP, len, ies); |
1312 | #if 0 /* to use beacon IE's, remove this #if 0 */ | 1499 | #if 0 /* to use beacon IE's, remove this #if 0 */ |
1313 | if (rc) | 1500 | if (rc) |
1314 | goto out; | 1501 | goto out; |
1315 | 1502 | ||
1316 | rc = wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->tail_len, bcon->tail); | 1503 | rc = wmi_set_ie(vif, WMI_FRAME_BEACON, |
1504 | bcon->tail_len, bcon->tail); | ||
1317 | #endif | 1505 | #endif |
1318 | out: | 1506 | out: |
1319 | kfree(ies); | 1507 | kfree(ies); |
@@ -1328,6 +1516,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy, | |||
1328 | u8 hidden_ssid, u32 pbss) | 1516 | u8 hidden_ssid, u32 pbss) |
1329 | { | 1517 | { |
1330 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1518 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1519 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
1331 | int rc; | 1520 | int rc; |
1332 | struct wireless_dev *wdev = ndev->ieee80211_ptr; | 1521 | struct wireless_dev *wdev = ndev->ieee80211_ptr; |
1333 | u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); | 1522 | u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); |
@@ -1336,7 +1525,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy, | |||
1336 | if (pbss) | 1525 | if (pbss) |
1337 | wmi_nettype = WMI_NETTYPE_P2P; | 1526 | wmi_nettype = WMI_NETTYPE_P2P; |
1338 | 1527 | ||
1339 | wil_dbg_misc(wil, "start_ap: is_go=%d\n", is_go); | 1528 | wil_dbg_misc(wil, "start_ap: mid=%d, is_go=%d\n", vif->mid, is_go); |
1340 | if (is_go && !pbss) { | 1529 | if (is_go && !pbss) { |
1341 | wil_err(wil, "P2P GO must be in PBSS\n"); | 1530 | wil_err(wil, "P2P GO must be in PBSS\n"); |
1342 | return -ENOTSUPP; | 1531 | return -ENOTSUPP; |
@@ -1346,42 +1535,46 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy, | |||
1346 | 1535 | ||
1347 | mutex_lock(&wil->mutex); | 1536 | mutex_lock(&wil->mutex); |
1348 | 1537 | ||
1349 | __wil_down(wil); | 1538 | if (!wil_has_other_active_ifaces(wil, ndev, true, false)) { |
1350 | rc = __wil_up(wil); | 1539 | __wil_down(wil); |
1351 | if (rc) | 1540 | rc = __wil_up(wil); |
1352 | goto out; | 1541 | if (rc) |
1542 | goto out; | ||
1543 | } | ||
1353 | 1544 | ||
1354 | rc = wmi_set_ssid(wil, ssid_len, ssid); | 1545 | rc = wmi_set_ssid(vif, ssid_len, ssid); |
1355 | if (rc) | 1546 | if (rc) |
1356 | goto out; | 1547 | goto out; |
1357 | 1548 | ||
1358 | rc = _wil_cfg80211_set_ies(wiphy, bcon); | 1549 | rc = _wil_cfg80211_set_ies(vif, bcon); |
1359 | if (rc) | 1550 | if (rc) |
1360 | goto out; | 1551 | goto out; |
1361 | 1552 | ||
1362 | wil->privacy = privacy; | 1553 | vif->privacy = privacy; |
1363 | wil->channel = chan; | 1554 | vif->channel = chan; |
1364 | wil->hidden_ssid = hidden_ssid; | 1555 | vif->hidden_ssid = hidden_ssid; |
1365 | wil->pbss = pbss; | 1556 | vif->pbss = pbss; |
1366 | 1557 | ||
1367 | netif_carrier_on(ndev); | 1558 | netif_carrier_on(ndev); |
1368 | wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS); | 1559 | if (!wil_has_other_active_ifaces(wil, ndev, false, true)) |
1560 | wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS); | ||
1369 | 1561 | ||
1370 | rc = wmi_pcp_start(wil, bi, wmi_nettype, chan, hidden_ssid, is_go); | 1562 | rc = wmi_pcp_start(vif, bi, wmi_nettype, chan, hidden_ssid, is_go); |
1371 | if (rc) | 1563 | if (rc) |
1372 | goto err_pcp_start; | 1564 | goto err_pcp_start; |
1373 | 1565 | ||
1374 | rc = wil_bcast_init(wil); | 1566 | rc = wil_bcast_init(vif); |
1375 | if (rc) | 1567 | if (rc) |
1376 | goto err_bcast; | 1568 | goto err_bcast; |
1377 | 1569 | ||
1378 | goto out; /* success */ | 1570 | goto out; /* success */ |
1379 | 1571 | ||
1380 | err_bcast: | 1572 | err_bcast: |
1381 | wmi_pcp_stop(wil); | 1573 | wmi_pcp_stop(vif); |
1382 | err_pcp_start: | 1574 | err_pcp_start: |
1383 | netif_carrier_off(ndev); | 1575 | netif_carrier_off(ndev); |
1384 | wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); | 1576 | if (!wil_has_other_active_ifaces(wil, ndev, false, true)) |
1577 | wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); | ||
1385 | out: | 1578 | out: |
1386 | mutex_unlock(&wil->mutex); | 1579 | mutex_unlock(&wil->mutex); |
1387 | return rc; | 1580 | return rc; |
@@ -1392,10 +1585,11 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy, | |||
1392 | struct cfg80211_beacon_data *bcon) | 1585 | struct cfg80211_beacon_data *bcon) |
1393 | { | 1586 | { |
1394 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1587 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1588 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
1395 | int rc; | 1589 | int rc; |
1396 | u32 privacy = 0; | 1590 | u32 privacy = 0; |
1397 | 1591 | ||
1398 | wil_dbg_misc(wil, "change_beacon\n"); | 1592 | wil_dbg_misc(wil, "change_beacon, mid=%d\n", vif->mid); |
1399 | wil_print_bcon_data(bcon); | 1593 | wil_print_bcon_data(bcon); |
1400 | 1594 | ||
1401 | if (bcon->tail && | 1595 | if (bcon->tail && |
@@ -1404,20 +1598,20 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy, | |||
1404 | privacy = 1; | 1598 | privacy = 1; |
1405 | 1599 | ||
1406 | /* in case privacy has changed, need to restart the AP */ | 1600 | /* in case privacy has changed, need to restart the AP */ |
1407 | if (wil->privacy != privacy) { | 1601 | if (vif->privacy != privacy) { |
1408 | struct wireless_dev *wdev = ndev->ieee80211_ptr; | 1602 | struct wireless_dev *wdev = ndev->ieee80211_ptr; |
1409 | 1603 | ||
1410 | wil_dbg_misc(wil, "privacy changed %d=>%d. Restarting AP\n", | 1604 | wil_dbg_misc(wil, "privacy changed %d=>%d. Restarting AP\n", |
1411 | wil->privacy, privacy); | 1605 | vif->privacy, privacy); |
1412 | 1606 | ||
1413 | rc = _wil_cfg80211_start_ap(wiphy, ndev, wdev->ssid, | 1607 | rc = _wil_cfg80211_start_ap(wiphy, ndev, wdev->ssid, |
1414 | wdev->ssid_len, privacy, | 1608 | wdev->ssid_len, privacy, |
1415 | wdev->beacon_interval, | 1609 | wdev->beacon_interval, |
1416 | wil->channel, bcon, | 1610 | vif->channel, bcon, |
1417 | wil->hidden_ssid, | 1611 | vif->hidden_ssid, |
1418 | wil->pbss); | 1612 | vif->pbss); |
1419 | } else { | 1613 | } else { |
1420 | rc = _wil_cfg80211_set_ies(wiphy, bcon); | 1614 | rc = _wil_cfg80211_set_ies(vif, bcon); |
1421 | } | 1615 | } |
1422 | 1616 | ||
1423 | return rc; | 1617 | return rc; |
@@ -1484,20 +1678,27 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy, | |||
1484 | struct net_device *ndev) | 1678 | struct net_device *ndev) |
1485 | { | 1679 | { |
1486 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1680 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1681 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
1682 | bool last; | ||
1487 | 1683 | ||
1488 | wil_dbg_misc(wil, "stop_ap\n"); | 1684 | wil_dbg_misc(wil, "stop_ap, mid=%d\n", vif->mid); |
1489 | 1685 | ||
1490 | netif_carrier_off(ndev); | 1686 | netif_carrier_off(ndev); |
1491 | wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); | 1687 | last = !wil_has_other_active_ifaces(wil, ndev, false, true); |
1492 | wil_set_recovery_state(wil, fw_recovery_idle); | 1688 | if (last) { |
1493 | 1689 | wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); | |
1494 | set_bit(wil_status_resetting, wil->status); | 1690 | wil_set_recovery_state(wil, fw_recovery_idle); |
1691 | set_bit(wil_status_resetting, wil->status); | ||
1692 | } | ||
1495 | 1693 | ||
1496 | mutex_lock(&wil->mutex); | 1694 | mutex_lock(&wil->mutex); |
1497 | 1695 | ||
1498 | wmi_pcp_stop(wil); | 1696 | wmi_pcp_stop(vif); |
1499 | 1697 | ||
1500 | __wil_down(wil); | 1698 | if (last) |
1699 | __wil_down(wil); | ||
1700 | else | ||
1701 | wil_bcast_fini(vif); | ||
1501 | 1702 | ||
1502 | mutex_unlock(&wil->mutex); | 1703 | mutex_unlock(&wil->mutex); |
1503 | 1704 | ||
@@ -1509,9 +1710,11 @@ static int wil_cfg80211_add_station(struct wiphy *wiphy, | |||
1509 | const u8 *mac, | 1710 | const u8 *mac, |
1510 | struct station_parameters *params) | 1711 | struct station_parameters *params) |
1511 | { | 1712 | { |
1713 | struct wil6210_vif *vif = ndev_to_vif(dev); | ||
1512 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1714 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1513 | 1715 | ||
1514 | wil_dbg_misc(wil, "add station %pM aid %d\n", mac, params->aid); | 1716 | wil_dbg_misc(wil, "add station %pM aid %d mid %d\n", |
1717 | mac, params->aid, vif->mid); | ||
1515 | 1718 | ||
1516 | if (!disable_ap_sme) { | 1719 | if (!disable_ap_sme) { |
1517 | wil_err(wil, "not supported with AP SME enabled\n"); | 1720 | wil_err(wil, "not supported with AP SME enabled\n"); |
@@ -1523,20 +1726,21 @@ static int wil_cfg80211_add_station(struct wiphy *wiphy, | |||
1523 | return -EINVAL; | 1726 | return -EINVAL; |
1524 | } | 1727 | } |
1525 | 1728 | ||
1526 | return wmi_new_sta(wil, mac, params->aid); | 1729 | return wmi_new_sta(vif, mac, params->aid); |
1527 | } | 1730 | } |
1528 | 1731 | ||
1529 | static int wil_cfg80211_del_station(struct wiphy *wiphy, | 1732 | static int wil_cfg80211_del_station(struct wiphy *wiphy, |
1530 | struct net_device *dev, | 1733 | struct net_device *dev, |
1531 | struct station_del_parameters *params) | 1734 | struct station_del_parameters *params) |
1532 | { | 1735 | { |
1736 | struct wil6210_vif *vif = ndev_to_vif(dev); | ||
1533 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1737 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1534 | 1738 | ||
1535 | wil_dbg_misc(wil, "del_station: %pM, reason=%d\n", params->mac, | 1739 | wil_dbg_misc(wil, "del_station: %pM, reason=%d mid=%d\n", |
1536 | params->reason_code); | 1740 | params->mac, params->reason_code, vif->mid); |
1537 | 1741 | ||
1538 | mutex_lock(&wil->mutex); | 1742 | mutex_lock(&wil->mutex); |
1539 | wil6210_disconnect(wil, params->mac, params->reason_code, false); | 1743 | wil6210_disconnect(vif, params->mac, params->reason_code, false); |
1540 | mutex_unlock(&wil->mutex); | 1744 | mutex_unlock(&wil->mutex); |
1541 | 1745 | ||
1542 | return 0; | 1746 | return 0; |
@@ -1547,13 +1751,15 @@ static int wil_cfg80211_change_station(struct wiphy *wiphy, | |||
1547 | const u8 *mac, | 1751 | const u8 *mac, |
1548 | struct station_parameters *params) | 1752 | struct station_parameters *params) |
1549 | { | 1753 | { |
1754 | struct wil6210_vif *vif = ndev_to_vif(dev); | ||
1550 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1755 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1551 | int authorize; | 1756 | int authorize; |
1552 | int cid, i; | 1757 | int cid, i; |
1553 | struct vring_tx_data *txdata = NULL; | 1758 | struct vring_tx_data *txdata = NULL; |
1554 | 1759 | ||
1555 | wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x\n", mac, | 1760 | wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x mid %d\n", |
1556 | params->sta_flags_mask, params->sta_flags_set); | 1761 | mac, params->sta_flags_mask, params->sta_flags_set, |
1762 | vif->mid); | ||
1557 | 1763 | ||
1558 | if (!disable_ap_sme) { | 1764 | if (!disable_ap_sme) { |
1559 | wil_dbg_misc(wil, "not supported with AP SME enabled\n"); | 1765 | wil_dbg_misc(wil, "not supported with AP SME enabled\n"); |
@@ -1563,7 +1769,7 @@ static int wil_cfg80211_change_station(struct wiphy *wiphy, | |||
1563 | if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))) | 1769 | if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))) |
1564 | return 0; | 1770 | return 0; |
1565 | 1771 | ||
1566 | cid = wil_find_cid(wil, mac); | 1772 | cid = wil_find_cid(wil, vif->mid, mac); |
1567 | if (cid < 0) { | 1773 | if (cid < 0) { |
1568 | wil_err(wil, "station not found\n"); | 1774 | wil_err(wil, "station not found\n"); |
1569 | return -ENOLINK; | 1775 | return -ENOLINK; |
@@ -1590,9 +1796,10 @@ static int wil_cfg80211_change_station(struct wiphy *wiphy, | |||
1590 | 1796 | ||
1591 | /* probe_client handling */ | 1797 | /* probe_client handling */ |
1592 | static void wil_probe_client_handle(struct wil6210_priv *wil, | 1798 | static void wil_probe_client_handle(struct wil6210_priv *wil, |
1799 | struct wil6210_vif *vif, | ||
1593 | struct wil_probe_client_req *req) | 1800 | struct wil_probe_client_req *req) |
1594 | { | 1801 | { |
1595 | struct net_device *ndev = wil_to_ndev(wil); | 1802 | struct net_device *ndev = vif_to_ndev(vif); |
1596 | struct wil_sta_info *sta = &wil->sta[req->cid]; | 1803 | struct wil_sta_info *sta = &wil->sta[req->cid]; |
1597 | /* assume STA is alive if it is still connected, | 1804 | /* assume STA is alive if it is still connected, |
1598 | * else FW will disconnect it | 1805 | * else FW will disconnect it |
@@ -1603,51 +1810,53 @@ static void wil_probe_client_handle(struct wil6210_priv *wil, | |||
1603 | 0, false, GFP_KERNEL); | 1810 | 0, false, GFP_KERNEL); |
1604 | } | 1811 | } |
1605 | 1812 | ||
1606 | static struct list_head *next_probe_client(struct wil6210_priv *wil) | 1813 | static struct list_head *next_probe_client(struct wil6210_vif *vif) |
1607 | { | 1814 | { |
1608 | struct list_head *ret = NULL; | 1815 | struct list_head *ret = NULL; |
1609 | 1816 | ||
1610 | mutex_lock(&wil->probe_client_mutex); | 1817 | mutex_lock(&vif->probe_client_mutex); |
1611 | 1818 | ||
1612 | if (!list_empty(&wil->probe_client_pending)) { | 1819 | if (!list_empty(&vif->probe_client_pending)) { |
1613 | ret = wil->probe_client_pending.next; | 1820 | ret = vif->probe_client_pending.next; |
1614 | list_del(ret); | 1821 | list_del(ret); |
1615 | } | 1822 | } |
1616 | 1823 | ||
1617 | mutex_unlock(&wil->probe_client_mutex); | 1824 | mutex_unlock(&vif->probe_client_mutex); |
1618 | 1825 | ||
1619 | return ret; | 1826 | return ret; |
1620 | } | 1827 | } |
1621 | 1828 | ||
1622 | void wil_probe_client_worker(struct work_struct *work) | 1829 | void wil_probe_client_worker(struct work_struct *work) |
1623 | { | 1830 | { |
1624 | struct wil6210_priv *wil = container_of(work, struct wil6210_priv, | 1831 | struct wil6210_vif *vif = container_of(work, struct wil6210_vif, |
1625 | probe_client_worker); | 1832 | probe_client_worker); |
1833 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1626 | struct wil_probe_client_req *req; | 1834 | struct wil_probe_client_req *req; |
1627 | struct list_head *lh; | 1835 | struct list_head *lh; |
1628 | 1836 | ||
1629 | while ((lh = next_probe_client(wil)) != NULL) { | 1837 | while ((lh = next_probe_client(vif)) != NULL) { |
1630 | req = list_entry(lh, struct wil_probe_client_req, list); | 1838 | req = list_entry(lh, struct wil_probe_client_req, list); |
1631 | 1839 | ||
1632 | wil_probe_client_handle(wil, req); | 1840 | wil_probe_client_handle(wil, vif, req); |
1633 | kfree(req); | 1841 | kfree(req); |
1634 | } | 1842 | } |
1635 | } | 1843 | } |
1636 | 1844 | ||
1637 | void wil_probe_client_flush(struct wil6210_priv *wil) | 1845 | void wil_probe_client_flush(struct wil6210_vif *vif) |
1638 | { | 1846 | { |
1639 | struct wil_probe_client_req *req, *t; | 1847 | struct wil_probe_client_req *req, *t; |
1848 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1640 | 1849 | ||
1641 | wil_dbg_misc(wil, "probe_client_flush\n"); | 1850 | wil_dbg_misc(wil, "probe_client_flush\n"); |
1642 | 1851 | ||
1643 | mutex_lock(&wil->probe_client_mutex); | 1852 | mutex_lock(&vif->probe_client_mutex); |
1644 | 1853 | ||
1645 | list_for_each_entry_safe(req, t, &wil->probe_client_pending, list) { | 1854 | list_for_each_entry_safe(req, t, &vif->probe_client_pending, list) { |
1646 | list_del(&req->list); | 1855 | list_del(&req->list); |
1647 | kfree(req); | 1856 | kfree(req); |
1648 | } | 1857 | } |
1649 | 1858 | ||
1650 | mutex_unlock(&wil->probe_client_mutex); | 1859 | mutex_unlock(&vif->probe_client_mutex); |
1651 | } | 1860 | } |
1652 | 1861 | ||
1653 | static int wil_cfg80211_probe_client(struct wiphy *wiphy, | 1862 | static int wil_cfg80211_probe_client(struct wiphy *wiphy, |
@@ -1655,10 +1864,12 @@ static int wil_cfg80211_probe_client(struct wiphy *wiphy, | |||
1655 | const u8 *peer, u64 *cookie) | 1864 | const u8 *peer, u64 *cookie) |
1656 | { | 1865 | { |
1657 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1866 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1867 | struct wil6210_vif *vif = ndev_to_vif(dev); | ||
1658 | struct wil_probe_client_req *req; | 1868 | struct wil_probe_client_req *req; |
1659 | int cid = wil_find_cid(wil, peer); | 1869 | int cid = wil_find_cid(wil, vif->mid, peer); |
1660 | 1870 | ||
1661 | wil_dbg_misc(wil, "probe_client: %pM => CID %d\n", peer, cid); | 1871 | wil_dbg_misc(wil, "probe_client: %pM => CID %d MID %d\n", |
1872 | peer, cid, vif->mid); | ||
1662 | 1873 | ||
1663 | if (cid < 0) | 1874 | if (cid < 0) |
1664 | return -ENOLINK; | 1875 | return -ENOLINK; |
@@ -1670,12 +1881,12 @@ static int wil_cfg80211_probe_client(struct wiphy *wiphy, | |||
1670 | req->cid = cid; | 1881 | req->cid = cid; |
1671 | req->cookie = cid; | 1882 | req->cookie = cid; |
1672 | 1883 | ||
1673 | mutex_lock(&wil->probe_client_mutex); | 1884 | mutex_lock(&vif->probe_client_mutex); |
1674 | list_add_tail(&req->list, &wil->probe_client_pending); | 1885 | list_add_tail(&req->list, &vif->probe_client_pending); |
1675 | mutex_unlock(&wil->probe_client_mutex); | 1886 | mutex_unlock(&vif->probe_client_mutex); |
1676 | 1887 | ||
1677 | *cookie = req->cookie; | 1888 | *cookie = req->cookie; |
1678 | queue_work(wil->wq_service, &wil->probe_client_worker); | 1889 | queue_work(wil->wq_service, &vif->probe_client_worker); |
1679 | return 0; | 1890 | return 0; |
1680 | } | 1891 | } |
1681 | 1892 | ||
@@ -1684,11 +1895,12 @@ static int wil_cfg80211_change_bss(struct wiphy *wiphy, | |||
1684 | struct bss_parameters *params) | 1895 | struct bss_parameters *params) |
1685 | { | 1896 | { |
1686 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1897 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1898 | struct wil6210_vif *vif = ndev_to_vif(dev); | ||
1687 | 1899 | ||
1688 | if (params->ap_isolate >= 0) { | 1900 | if (params->ap_isolate >= 0) { |
1689 | wil_dbg_misc(wil, "change_bss: ap_isolate %d => %d\n", | 1901 | wil_dbg_misc(wil, "change_bss: ap_isolate MID %d, %d => %d\n", |
1690 | wil->ap_isolate, params->ap_isolate); | 1902 | vif->mid, vif->ap_isolate, params->ap_isolate); |
1691 | wil->ap_isolate = params->ap_isolate; | 1903 | vif->ap_isolate = params->ap_isolate; |
1692 | } | 1904 | } |
1693 | 1905 | ||
1694 | return 0; | 1906 | return 0; |
@@ -1732,10 +1944,10 @@ static int wil_cfg80211_suspend(struct wiphy *wiphy, | |||
1732 | wil_dbg_pm(wil, "suspending\n"); | 1944 | wil_dbg_pm(wil, "suspending\n"); |
1733 | 1945 | ||
1734 | mutex_lock(&wil->mutex); | 1946 | mutex_lock(&wil->mutex); |
1735 | mutex_lock(&wil->p2p_wdev_mutex); | 1947 | mutex_lock(&wil->vif_mutex); |
1736 | wil_p2p_stop_radio_operations(wil); | 1948 | wil_p2p_stop_radio_operations(wil); |
1737 | wil_abort_scan(wil, true); | 1949 | wil_abort_scan_all_vifs(wil, true); |
1738 | mutex_unlock(&wil->p2p_wdev_mutex); | 1950 | mutex_unlock(&wil->vif_mutex); |
1739 | mutex_unlock(&wil->mutex); | 1951 | mutex_unlock(&wil->mutex); |
1740 | 1952 | ||
1741 | out: | 1953 | out: |
@@ -1757,8 +1969,12 @@ wil_cfg80211_sched_scan_start(struct wiphy *wiphy, | |||
1757 | struct cfg80211_sched_scan_request *request) | 1969 | struct cfg80211_sched_scan_request *request) |
1758 | { | 1970 | { |
1759 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 1971 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
1972 | struct wil6210_vif *vif = ndev_to_vif(dev); | ||
1760 | int i, rc; | 1973 | int i, rc; |
1761 | 1974 | ||
1975 | if (vif->mid != 0) | ||
1976 | return -EOPNOTSUPP; | ||
1977 | |||
1762 | wil_dbg_misc(wil, | 1978 | wil_dbg_misc(wil, |
1763 | "sched scan start: n_ssids %d, ie_len %zu, flags 0x%x\n", | 1979 | "sched scan start: n_ssids %d, ie_len %zu, flags 0x%x\n", |
1764 | request->n_ssids, request->ie_len, request->flags); | 1980 | request->n_ssids, request->ie_len, request->flags); |
@@ -1792,7 +2008,8 @@ wil_cfg80211_sched_scan_start(struct wiphy *wiphy, | |||
1792 | i, sp->interval, sp->iterations); | 2008 | i, sp->interval, sp->iterations); |
1793 | } | 2009 | } |
1794 | 2010 | ||
1795 | rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie); | 2011 | rc = wmi_set_ie(vif, WMI_FRAME_PROBE_REQ, |
2012 | request->ie_len, request->ie); | ||
1796 | if (rc) | 2013 | if (rc) |
1797 | return rc; | 2014 | return rc; |
1798 | return wmi_start_sched_scan(wil, request); | 2015 | return wmi_start_sched_scan(wil, request); |
@@ -1803,8 +2020,12 @@ wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev, | |||
1803 | u64 reqid) | 2020 | u64 reqid) |
1804 | { | 2021 | { |
1805 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 2022 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
2023 | struct wil6210_vif *vif = ndev_to_vif(dev); | ||
1806 | int rc; | 2024 | int rc; |
1807 | 2025 | ||
2026 | if (vif->mid != 0) | ||
2027 | return -EOPNOTSUPP; | ||
2028 | |||
1808 | rc = wmi_stop_sched_scan(wil); | 2029 | rc = wmi_stop_sched_scan(wil); |
1809 | /* device would return error if it thinks PNO is already stopped. | 2030 | /* device would return error if it thinks PNO is already stopped. |
1810 | * ignore the return code so user space and driver gets back in-sync | 2031 | * ignore the return code so user space and driver gets back in-sync |
@@ -1893,57 +2114,132 @@ static void wil_wiphy_init(struct wiphy *wiphy) | |||
1893 | #endif | 2114 | #endif |
1894 | } | 2115 | } |
1895 | 2116 | ||
1896 | struct wireless_dev *wil_cfg80211_init(struct device *dev) | 2117 | int wil_cfg80211_iface_combinations_from_fw( |
2118 | struct wil6210_priv *wil, const struct wil_fw_record_concurrency *conc) | ||
1897 | { | 2119 | { |
1898 | int rc = 0; | 2120 | struct wiphy *wiphy = wil_to_wiphy(wil); |
1899 | struct wireless_dev *wdev; | 2121 | u32 total_limits = 0; |
2122 | u16 n_combos; | ||
2123 | const struct wil_fw_concurrency_combo *combo; | ||
2124 | const struct wil_fw_concurrency_limit *limit; | ||
2125 | struct ieee80211_iface_combination *iface_combinations; | ||
2126 | struct ieee80211_iface_limit *iface_limit; | ||
2127 | int i, j; | ||
2128 | |||
2129 | if (wiphy->iface_combinations) { | ||
2130 | wil_dbg_misc(wil, "iface_combinations already set, skipping\n"); | ||
2131 | return 0; | ||
2132 | } | ||
1900 | 2133 | ||
1901 | dev_dbg(dev, "%s()\n", __func__); | 2134 | combo = conc->combos; |
2135 | n_combos = le16_to_cpu(conc->n_combos); | ||
2136 | for (i = 0; i < n_combos; i++) { | ||
2137 | total_limits += combo->n_limits; | ||
2138 | limit = combo->limits + combo->n_limits; | ||
2139 | combo = (struct wil_fw_concurrency_combo *)limit; | ||
2140 | } | ||
1902 | 2141 | ||
1903 | wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); | 2142 | iface_combinations = |
1904 | if (!wdev) | 2143 | kzalloc(n_combos * sizeof(struct ieee80211_iface_combination) + |
1905 | return ERR_PTR(-ENOMEM); | 2144 | total_limits * sizeof(struct ieee80211_iface_limit), |
2145 | GFP_KERNEL); | ||
2146 | if (!iface_combinations) | ||
2147 | return -ENOMEM; | ||
2148 | iface_limit = (struct ieee80211_iface_limit *)(iface_combinations + | ||
2149 | n_combos); | ||
2150 | combo = conc->combos; | ||
2151 | for (i = 0; i < n_combos; i++) { | ||
2152 | iface_combinations[i].max_interfaces = combo->max_interfaces; | ||
2153 | iface_combinations[i].num_different_channels = | ||
2154 | combo->n_diff_channels; | ||
2155 | iface_combinations[i].beacon_int_infra_match = | ||
2156 | combo->same_bi; | ||
2157 | iface_combinations[i].n_limits = combo->n_limits; | ||
2158 | wil_dbg_misc(wil, | ||
2159 | "iface_combination %d: max_if %d, num_ch %d, bi_match %d\n", | ||
2160 | i, iface_combinations[i].max_interfaces, | ||
2161 | iface_combinations[i].num_different_channels, | ||
2162 | iface_combinations[i].beacon_int_infra_match); | ||
2163 | limit = combo->limits; | ||
2164 | for (j = 0; j < combo->n_limits; j++) { | ||
2165 | iface_limit[j].max = le16_to_cpu(limit[j].max); | ||
2166 | iface_limit[j].types = le16_to_cpu(limit[j].types); | ||
2167 | wil_dbg_misc(wil, | ||
2168 | "limit %d: max %d types 0x%x\n", j, | ||
2169 | iface_limit[j].max, iface_limit[j].types); | ||
2170 | } | ||
2171 | iface_combinations[i].limits = iface_limit; | ||
2172 | iface_limit += combo->n_limits; | ||
2173 | limit += combo->n_limits; | ||
2174 | combo = (struct wil_fw_concurrency_combo *)limit; | ||
2175 | } | ||
1906 | 2176 | ||
1907 | wdev->wiphy = wiphy_new(&wil_cfg80211_ops, | 2177 | wil_dbg_misc(wil, "multiple VIFs supported, n_mids %d\n", conc->n_mids); |
1908 | sizeof(struct wil6210_priv)); | 2178 | wil->max_vifs = conc->n_mids + 1; /* including main interface */ |
1909 | if (!wdev->wiphy) { | 2179 | if (wil->max_vifs > WIL_MAX_VIFS) { |
1910 | rc = -ENOMEM; | 2180 | wil_info(wil, "limited number of VIFs supported(%d, FW %d)\n", |
1911 | goto out; | 2181 | WIL_MAX_VIFS, wil->max_vifs); |
2182 | wil->max_vifs = WIL_MAX_VIFS; | ||
1912 | } | 2183 | } |
2184 | wiphy->n_iface_combinations = n_combos; | ||
2185 | wiphy->iface_combinations = iface_combinations; | ||
2186 | return 0; | ||
2187 | } | ||
1913 | 2188 | ||
1914 | set_wiphy_dev(wdev->wiphy, dev); | 2189 | struct wil6210_priv *wil_cfg80211_init(struct device *dev) |
1915 | wil_wiphy_init(wdev->wiphy); | 2190 | { |
2191 | struct wiphy *wiphy; | ||
2192 | struct wil6210_priv *wil; | ||
2193 | struct ieee80211_channel *ch; | ||
1916 | 2194 | ||
1917 | return wdev; | 2195 | dev_dbg(dev, "%s()\n", __func__); |
1918 | 2196 | ||
1919 | out: | 2197 | /* Note: the wireless_dev structure is no longer allocated here. |
1920 | kfree(wdev); | 2198 | * Instead, it is allocated as part of the net_device structure |
2199 | * for main interface and each VIF. | ||
2200 | */ | ||
2201 | wiphy = wiphy_new(&wil_cfg80211_ops, sizeof(struct wil6210_priv)); | ||
2202 | if (!wiphy) | ||
2203 | return ERR_PTR(-ENOMEM); | ||
1921 | 2204 | ||
1922 | return ERR_PTR(rc); | 2205 | set_wiphy_dev(wiphy, dev); |
2206 | wil_wiphy_init(wiphy); | ||
2207 | |||
2208 | wil = wiphy_to_wil(wiphy); | ||
2209 | wil->wiphy = wiphy; | ||
2210 | |||
2211 | /* default monitor channel */ | ||
2212 | ch = wiphy->bands[NL80211_BAND_60GHZ]->channels; | ||
2213 | cfg80211_chandef_create(&wil->monitor_chandef, ch, NL80211_CHAN_NO_HT); | ||
2214 | |||
2215 | return wil; | ||
1923 | } | 2216 | } |
1924 | 2217 | ||
1925 | void wil_wdev_free(struct wil6210_priv *wil) | 2218 | void wil_cfg80211_deinit(struct wil6210_priv *wil) |
1926 | { | 2219 | { |
1927 | struct wireless_dev *wdev = wil_to_wdev(wil); | 2220 | struct wiphy *wiphy = wil_to_wiphy(wil); |
1928 | 2221 | ||
1929 | dev_dbg(wil_to_dev(wil), "%s()\n", __func__); | 2222 | dev_dbg(wil_to_dev(wil), "%s()\n", __func__); |
1930 | 2223 | ||
1931 | if (!wdev) | 2224 | if (!wiphy) |
1932 | return; | 2225 | return; |
1933 | 2226 | ||
1934 | wiphy_free(wdev->wiphy); | 2227 | kfree(wiphy->iface_combinations); |
1935 | kfree(wdev); | 2228 | wiphy->iface_combinations = NULL; |
2229 | |||
2230 | wiphy_free(wiphy); | ||
2231 | /* do not access wil6210_priv after returning from here */ | ||
1936 | } | 2232 | } |
1937 | 2233 | ||
1938 | void wil_p2p_wdev_free(struct wil6210_priv *wil) | 2234 | void wil_p2p_wdev_free(struct wil6210_priv *wil) |
1939 | { | 2235 | { |
1940 | struct wireless_dev *p2p_wdev; | 2236 | struct wireless_dev *p2p_wdev; |
1941 | 2237 | ||
1942 | mutex_lock(&wil->p2p_wdev_mutex); | 2238 | mutex_lock(&wil->vif_mutex); |
1943 | p2p_wdev = wil->p2p_wdev; | 2239 | p2p_wdev = wil->p2p_wdev; |
1944 | wil->p2p_wdev = NULL; | 2240 | wil->p2p_wdev = NULL; |
1945 | wil->radio_wdev = wil_to_wdev(wil); | 2241 | wil->radio_wdev = wil->main_ndev->ieee80211_ptr; |
1946 | mutex_unlock(&wil->p2p_wdev_mutex); | 2242 | mutex_unlock(&wil->vif_mutex); |
1947 | if (p2p_wdev) { | 2243 | if (p2p_wdev) { |
1948 | cfg80211_unregister_wdev(p2p_wdev); | 2244 | cfg80211_unregister_wdev(p2p_wdev); |
1949 | kfree(p2p_wdev); | 2245 | kfree(p2p_wdev); |
@@ -1971,6 +2267,7 @@ static int wil_rf_sector_get_cfg(struct wiphy *wiphy, | |||
1971 | const void *data, int data_len) | 2267 | const void *data, int data_len) |
1972 | { | 2268 | { |
1973 | struct wil6210_priv *wil = wdev_to_wil(wdev); | 2269 | struct wil6210_priv *wil = wdev_to_wil(wdev); |
2270 | struct wil6210_vif *vif = wdev_to_vif(wil, wdev); | ||
1974 | int rc; | 2271 | int rc; |
1975 | struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; | 2272 | struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; |
1976 | u16 sector_index; | 2273 | u16 sector_index; |
@@ -2027,8 +2324,8 @@ static int wil_rf_sector_get_cfg(struct wiphy *wiphy, | |||
2027 | cmd.sector_type = sector_type; | 2324 | cmd.sector_type = sector_type; |
2028 | cmd.rf_modules_vec = rf_modules_vec & 0xFF; | 2325 | cmd.rf_modules_vec = rf_modules_vec & 0xFF; |
2029 | memset(&reply, 0, sizeof(reply)); | 2326 | memset(&reply, 0, sizeof(reply)); |
2030 | rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, &cmd, sizeof(cmd), | 2327 | rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, vif->mid, |
2031 | WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID, | 2328 | &cmd, sizeof(cmd), WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID, |
2032 | &reply, sizeof(reply), | 2329 | &reply, sizeof(reply), |
2033 | 500); | 2330 | 500); |
2034 | if (rc) | 2331 | if (rc) |
@@ -2090,6 +2387,7 @@ static int wil_rf_sector_set_cfg(struct wiphy *wiphy, | |||
2090 | const void *data, int data_len) | 2387 | const void *data, int data_len) |
2091 | { | 2388 | { |
2092 | struct wil6210_priv *wil = wdev_to_wil(wdev); | 2389 | struct wil6210_priv *wil = wdev_to_wil(wdev); |
2390 | struct wil6210_vif *vif = wdev_to_vif(wil, wdev); | ||
2093 | int rc, tmp; | 2391 | int rc, tmp; |
2094 | struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; | 2392 | struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; |
2095 | struct nlattr *tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1]; | 2393 | struct nlattr *tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1]; |
@@ -2184,8 +2482,8 @@ static int wil_rf_sector_set_cfg(struct wiphy *wiphy, | |||
2184 | 2482 | ||
2185 | cmd.rf_modules_vec = rf_modules_vec & 0xFF; | 2483 | cmd.rf_modules_vec = rf_modules_vec & 0xFF; |
2186 | memset(&reply, 0, sizeof(reply)); | 2484 | memset(&reply, 0, sizeof(reply)); |
2187 | rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, &cmd, sizeof(cmd), | 2485 | rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, vif->mid, |
2188 | WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID, | 2486 | &cmd, sizeof(cmd), WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID, |
2189 | &reply, sizeof(reply), | 2487 | &reply, sizeof(reply), |
2190 | 500); | 2488 | 500); |
2191 | if (rc) | 2489 | if (rc) |
@@ -2198,6 +2496,7 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy, | |||
2198 | const void *data, int data_len) | 2496 | const void *data, int data_len) |
2199 | { | 2497 | { |
2200 | struct wil6210_priv *wil = wdev_to_wil(wdev); | 2498 | struct wil6210_priv *wil = wdev_to_wil(wdev); |
2499 | struct wil6210_vif *vif = wdev_to_vif(wil, wdev); | ||
2201 | int rc; | 2500 | int rc; |
2202 | struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; | 2501 | struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; |
2203 | u8 sector_type, mac_addr[ETH_ALEN]; | 2502 | u8 sector_type, mac_addr[ETH_ALEN]; |
@@ -2231,13 +2530,13 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy, | |||
2231 | 2530 | ||
2232 | if (tb[QCA_ATTR_MAC_ADDR]) { | 2531 | if (tb[QCA_ATTR_MAC_ADDR]) { |
2233 | ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR])); | 2532 | ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR])); |
2234 | cid = wil_find_cid(wil, mac_addr); | 2533 | cid = wil_find_cid(wil, vif->mid, mac_addr); |
2235 | if (cid < 0) { | 2534 | if (cid < 0) { |
2236 | wil_err(wil, "invalid MAC address %pM\n", mac_addr); | 2535 | wil_err(wil, "invalid MAC address %pM\n", mac_addr); |
2237 | return -ENOENT; | 2536 | return -ENOENT; |
2238 | } | 2537 | } |
2239 | } else { | 2538 | } else { |
2240 | if (test_bit(wil_status_fwconnected, wil->status)) { | 2539 | if (test_bit(wil_vif_fwconnected, vif->status)) { |
2241 | wil_err(wil, "must specify MAC address when connected\n"); | 2540 | wil_err(wil, "must specify MAC address when connected\n"); |
2242 | return -EINVAL; | 2541 | return -EINVAL; |
2243 | } | 2542 | } |
@@ -2247,7 +2546,7 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy, | |||
2247 | cmd.cid = (u8)cid; | 2546 | cmd.cid = (u8)cid; |
2248 | cmd.sector_type = sector_type; | 2547 | cmd.sector_type = sector_type; |
2249 | memset(&reply, 0, sizeof(reply)); | 2548 | memset(&reply, 0, sizeof(reply)); |
2250 | rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID, | 2549 | rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID, vif->mid, |
2251 | &cmd, sizeof(cmd), | 2550 | &cmd, sizeof(cmd), |
2252 | WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID, | 2551 | WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID, |
2253 | &reply, sizeof(reply), | 2552 | &reply, sizeof(reply), |
@@ -2280,7 +2579,7 @@ nla_put_failure: | |||
2280 | } | 2579 | } |
2281 | 2580 | ||
2282 | static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil, | 2581 | static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil, |
2283 | u16 sector_index, | 2582 | u8 mid, u16 sector_index, |
2284 | u8 sector_type, u8 cid) | 2583 | u8 sector_type, u8 cid) |
2285 | { | 2584 | { |
2286 | struct wmi_set_selected_rf_sector_index_cmd cmd; | 2585 | struct wmi_set_selected_rf_sector_index_cmd cmd; |
@@ -2295,7 +2594,7 @@ static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil, | |||
2295 | cmd.sector_type = sector_type; | 2594 | cmd.sector_type = sector_type; |
2296 | cmd.cid = (u8)cid; | 2595 | cmd.cid = (u8)cid; |
2297 | memset(&reply, 0, sizeof(reply)); | 2596 | memset(&reply, 0, sizeof(reply)); |
2298 | rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID, | 2597 | rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID, mid, |
2299 | &cmd, sizeof(cmd), | 2598 | &cmd, sizeof(cmd), |
2300 | WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID, | 2599 | WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID, |
2301 | &reply, sizeof(reply), | 2600 | &reply, sizeof(reply), |
@@ -2310,6 +2609,7 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy, | |||
2310 | const void *data, int data_len) | 2609 | const void *data, int data_len) |
2311 | { | 2610 | { |
2312 | struct wil6210_priv *wil = wdev_to_wil(wdev); | 2611 | struct wil6210_priv *wil = wdev_to_wil(wdev); |
2612 | struct wil6210_vif *vif = wdev_to_vif(wil, wdev); | ||
2313 | int rc; | 2613 | int rc; |
2314 | struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; | 2614 | struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; |
2315 | u16 sector_index; | 2615 | u16 sector_index; |
@@ -2349,7 +2649,7 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy, | |||
2349 | if (tb[QCA_ATTR_MAC_ADDR]) { | 2649 | if (tb[QCA_ATTR_MAC_ADDR]) { |
2350 | ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR])); | 2650 | ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR])); |
2351 | if (!is_broadcast_ether_addr(mac_addr)) { | 2651 | if (!is_broadcast_ether_addr(mac_addr)) { |
2352 | cid = wil_find_cid(wil, mac_addr); | 2652 | cid = wil_find_cid(wil, vif->mid, mac_addr); |
2353 | if (cid < 0) { | 2653 | if (cid < 0) { |
2354 | wil_err(wil, "invalid MAC address %pM\n", | 2654 | wil_err(wil, "invalid MAC address %pM\n", |
2355 | mac_addr); | 2655 | mac_addr); |
@@ -2363,7 +2663,7 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy, | |||
2363 | cid = -1; | 2663 | cid = -1; |
2364 | } | 2664 | } |
2365 | } else { | 2665 | } else { |
2366 | if (test_bit(wil_status_fwconnected, wil->status)) { | 2666 | if (test_bit(wil_vif_fwconnected, vif->status)) { |
2367 | wil_err(wil, "must specify MAC address when connected\n"); | 2667 | wil_err(wil, "must specify MAC address when connected\n"); |
2368 | return -EINVAL; | 2668 | return -EINVAL; |
2369 | } | 2669 | } |
@@ -2371,17 +2671,20 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy, | |||
2371 | } | 2671 | } |
2372 | 2672 | ||
2373 | if (cid >= 0) { | 2673 | if (cid >= 0) { |
2374 | rc = wil_rf_sector_wmi_set_selected(wil, sector_index, | 2674 | rc = wil_rf_sector_wmi_set_selected(wil, vif->mid, sector_index, |
2375 | sector_type, cid); | 2675 | sector_type, cid); |
2376 | } else { | 2676 | } else { |
2377 | /* unlock all cids */ | 2677 | /* unlock all cids */ |
2378 | rc = wil_rf_sector_wmi_set_selected( | 2678 | rc = wil_rf_sector_wmi_set_selected( |
2379 | wil, WMI_INVALID_RF_SECTOR_INDEX, sector_type, | 2679 | wil, vif->mid, WMI_INVALID_RF_SECTOR_INDEX, |
2380 | WIL_CID_ALL); | 2680 | sector_type, WIL_CID_ALL); |
2381 | if (rc == -EINVAL) { | 2681 | if (rc == -EINVAL) { |
2382 | for (i = 0; i < WIL6210_MAX_CID; i++) { | 2682 | for (i = 0; i < WIL6210_MAX_CID; i++) { |
2683 | if (wil->sta[i].mid != vif->mid) | ||
2684 | continue; | ||
2383 | rc = wil_rf_sector_wmi_set_selected( | 2685 | rc = wil_rf_sector_wmi_set_selected( |
2384 | wil, WMI_INVALID_RF_SECTOR_INDEX, | 2686 | wil, vif->mid, |
2687 | WMI_INVALID_RF_SECTOR_INDEX, | ||
2385 | sector_type, i); | 2688 | sector_type, i); |
2386 | /* the FW will silently ignore and return | 2689 | /* the FW will silently ignore and return |
2387 | * success for unused cid, so abort the loop | 2690 | * success for unused cid, so abort the loop |
diff --git a/drivers/net/wireless/ath/wil6210/debug.c b/drivers/net/wireless/ath/wil6210/debug.c index 217a4591bde4..a9befb971cc4 100644 --- a/drivers/net/wireless/ath/wil6210/debug.c +++ b/drivers/net/wireless/ath/wil6210/debug.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2013,2016 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2013,2016 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -25,7 +26,7 @@ void __wil_err(struct wil6210_priv *wil, const char *fmt, ...) | |||
25 | va_start(args, fmt); | 26 | va_start(args, fmt); |
26 | vaf.fmt = fmt; | 27 | vaf.fmt = fmt; |
27 | vaf.va = &args; | 28 | vaf.va = &args; |
28 | netdev_err(wil_to_ndev(wil), "%pV", &vaf); | 29 | netdev_err(wil->main_ndev, "%pV", &vaf); |
29 | trace_wil6210_log_err(&vaf); | 30 | trace_wil6210_log_err(&vaf); |
30 | va_end(args); | 31 | va_end(args); |
31 | } | 32 | } |
@@ -41,7 +42,7 @@ void __wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...) | |||
41 | va_start(args, fmt); | 42 | va_start(args, fmt); |
42 | vaf.fmt = fmt; | 43 | vaf.fmt = fmt; |
43 | vaf.va = &args; | 44 | vaf.va = &args; |
44 | netdev_err(wil_to_ndev(wil), "%pV", &vaf); | 45 | netdev_err(wil->main_ndev, "%pV", &vaf); |
45 | trace_wil6210_log_err(&vaf); | 46 | trace_wil6210_log_err(&vaf); |
46 | va_end(args); | 47 | va_end(args); |
47 | } | 48 | } |
@@ -57,7 +58,7 @@ void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...) | |||
57 | va_start(args, fmt); | 58 | va_start(args, fmt); |
58 | vaf.fmt = fmt; | 59 | vaf.fmt = fmt; |
59 | vaf.va = &args; | 60 | vaf.va = &args; |
60 | netdev_dbg(wil_to_ndev(wil), "%pV", &vaf); | 61 | netdev_dbg(wil->main_ndev, "%pV", &vaf); |
61 | trace_wil6210_log_dbg(&vaf); | 62 | trace_wil6210_log_dbg(&vaf); |
62 | va_end(args); | 63 | va_end(args); |
63 | } | 64 | } |
@@ -70,7 +71,7 @@ void __wil_info(struct wil6210_priv *wil, const char *fmt, ...) | |||
70 | va_start(args, fmt); | 71 | va_start(args, fmt); |
71 | vaf.fmt = fmt; | 72 | vaf.fmt = fmt; |
72 | vaf.va = &args; | 73 | vaf.va = &args; |
73 | netdev_info(wil_to_ndev(wil), "%pV", &vaf); | 74 | netdev_info(wil->main_ndev, "%pV", &vaf); |
74 | trace_wil6210_log_info(&vaf); | 75 | trace_wil6210_log_info(&vaf); |
75 | va_end(args); | 76 | va_end(args); |
76 | } | 77 | } |
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 4a4888246e8c..8c90b3111f0b 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -621,7 +622,7 @@ static ssize_t wil_write_file_reset(struct file *file, const char __user *buf, | |||
621 | size_t len, loff_t *ppos) | 622 | size_t len, loff_t *ppos) |
622 | { | 623 | { |
623 | struct wil6210_priv *wil = file->private_data; | 624 | struct wil6210_priv *wil = file->private_data; |
624 | struct net_device *ndev = wil_to_ndev(wil); | 625 | struct net_device *ndev = wil->main_ndev; |
625 | 626 | ||
626 | /** | 627 | /** |
627 | * BUG: | 628 | * BUG: |
@@ -716,27 +717,44 @@ static ssize_t wil_write_back(struct file *file, const char __user *buf, | |||
716 | if (rc < 2) | 717 | if (rc < 2) |
717 | return -EINVAL; | 718 | return -EINVAL; |
718 | 719 | ||
719 | if (0 == strcmp(cmd, "add")) { | 720 | if ((strcmp(cmd, "add") == 0) || |
720 | if (rc < 3) { | 721 | (strcmp(cmd, "del_tx") == 0)) { |
721 | wil_err(wil, "BACK: add require at least 2 params\n"); | 722 | struct vring_tx_data *txdata; |
723 | |||
724 | if (p1 < 0 || p1 >= WIL6210_MAX_TX_RINGS) { | ||
725 | wil_err(wil, "BACK: invalid ring id %d\n", p1); | ||
722 | return -EINVAL; | 726 | return -EINVAL; |
723 | } | 727 | } |
724 | if (rc < 4) | 728 | txdata = &wil->vring_tx_data[p1]; |
725 | p3 = 0; | 729 | if (strcmp(cmd, "add") == 0) { |
726 | wmi_addba(wil, p1, p2, p3); | 730 | if (rc < 3) { |
727 | } else if (0 == strcmp(cmd, "del_tx")) { | 731 | wil_err(wil, "BACK: add require at least 2 params\n"); |
728 | if (rc < 3) | 732 | return -EINVAL; |
729 | p2 = WLAN_REASON_QSTA_LEAVE_QBSS; | 733 | } |
730 | wmi_delba_tx(wil, p1, p2); | 734 | if (rc < 4) |
731 | } else if (0 == strcmp(cmd, "del_rx")) { | 735 | p3 = 0; |
736 | wmi_addba(wil, txdata->mid, p1, p2, p3); | ||
737 | } else { | ||
738 | if (rc < 3) | ||
739 | p2 = WLAN_REASON_QSTA_LEAVE_QBSS; | ||
740 | wmi_delba_tx(wil, txdata->mid, p1, p2); | ||
741 | } | ||
742 | } else if (strcmp(cmd, "del_rx") == 0) { | ||
743 | struct wil_sta_info *sta; | ||
744 | |||
732 | if (rc < 3) { | 745 | if (rc < 3) { |
733 | wil_err(wil, | 746 | wil_err(wil, |
734 | "BACK: del_rx require at least 2 params\n"); | 747 | "BACK: del_rx require at least 2 params\n"); |
735 | return -EINVAL; | 748 | return -EINVAL; |
736 | } | 749 | } |
750 | if (p1 < 0 || p1 >= WIL6210_MAX_CID) { | ||
751 | wil_err(wil, "BACK: invalid CID %d\n", p1); | ||
752 | return -EINVAL; | ||
753 | } | ||
737 | if (rc < 4) | 754 | if (rc < 4) |
738 | p3 = WLAN_REASON_QSTA_LEAVE_QBSS; | 755 | p3 = WLAN_REASON_QSTA_LEAVE_QBSS; |
739 | wmi_delba_rx(wil, mk_cidxtid(p1, p2), p3); | 756 | sta = &wil->sta[p1]; |
757 | wmi_delba_rx(wil, sta->mid, mk_cidxtid(p1, p2), p3); | ||
740 | } else { | 758 | } else { |
741 | wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd); | 759 | wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd); |
742 | return -EINVAL; | 760 | return -EINVAL; |
@@ -855,7 +873,7 @@ static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf, | |||
855 | { | 873 | { |
856 | struct wil6210_priv *wil = file->private_data; | 874 | struct wil6210_priv *wil = file->private_data; |
857 | struct wiphy *wiphy = wil_to_wiphy(wil); | 875 | struct wiphy *wiphy = wil_to_wiphy(wil); |
858 | struct wireless_dev *wdev = wil_to_wdev(wil); | 876 | struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr; |
859 | struct cfg80211_mgmt_tx_params params; | 877 | struct cfg80211_mgmt_tx_params params; |
860 | int rc; | 878 | int rc; |
861 | void *frame; | 879 | void *frame; |
@@ -890,6 +908,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf, | |||
890 | size_t len, loff_t *ppos) | 908 | size_t len, loff_t *ppos) |
891 | { | 909 | { |
892 | struct wil6210_priv *wil = file->private_data; | 910 | struct wil6210_priv *wil = file->private_data; |
911 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
893 | struct wmi_cmd_hdr *wmi; | 912 | struct wmi_cmd_hdr *wmi; |
894 | void *cmd; | 913 | void *cmd; |
895 | int cmdlen = len - sizeof(struct wmi_cmd_hdr); | 914 | int cmdlen = len - sizeof(struct wmi_cmd_hdr); |
@@ -912,7 +931,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf, | |||
912 | cmd = (cmdlen > 0) ? &wmi[1] : NULL; | 931 | cmd = (cmdlen > 0) ? &wmi[1] : NULL; |
913 | cmdid = le16_to_cpu(wmi->command_id); | 932 | cmdid = le16_to_cpu(wmi->command_id); |
914 | 933 | ||
915 | rc1 = wmi_send(wil, cmdid, cmd, cmdlen); | 934 | rc1 = wmi_send(wil, cmdid, vif->mid, cmd, cmdlen); |
916 | kfree(wmi); | 935 | kfree(wmi); |
917 | 936 | ||
918 | wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1); | 937 | wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1); |
@@ -1050,6 +1069,7 @@ static int wil_bf_debugfs_show(struct seq_file *s, void *data) | |||
1050 | int rc; | 1069 | int rc; |
1051 | int i; | 1070 | int i; |
1052 | struct wil6210_priv *wil = s->private; | 1071 | struct wil6210_priv *wil = s->private; |
1072 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
1053 | struct wmi_notify_req_cmd cmd = { | 1073 | struct wmi_notify_req_cmd cmd = { |
1054 | .interval_usec = 0, | 1074 | .interval_usec = 0, |
1055 | }; | 1075 | }; |
@@ -1062,7 +1082,8 @@ static int wil_bf_debugfs_show(struct seq_file *s, void *data) | |||
1062 | u32 status; | 1082 | u32 status; |
1063 | 1083 | ||
1064 | cmd.cid = i; | 1084 | cmd.cid = i; |
1065 | rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd), | 1085 | rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, vif->mid, |
1086 | &cmd, sizeof(cmd), | ||
1066 | WMI_NOTIFY_REQ_DONE_EVENTID, &reply, | 1087 | WMI_NOTIFY_REQ_DONE_EVENTID, &reply, |
1067 | sizeof(reply), 20); | 1088 | sizeof(reply), 20); |
1068 | /* if reply is all-0, ignore this CID */ | 1089 | /* if reply is all-0, ignore this CID */ |
@@ -1155,7 +1176,7 @@ static const struct file_operations fops_temp = { | |||
1155 | static int wil_freq_debugfs_show(struct seq_file *s, void *data) | 1176 | static int wil_freq_debugfs_show(struct seq_file *s, void *data) |
1156 | { | 1177 | { |
1157 | struct wil6210_priv *wil = s->private; | 1178 | struct wil6210_priv *wil = s->private; |
1158 | struct wireless_dev *wdev = wil_to_wdev(wil); | 1179 | struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr; |
1159 | u16 freq = wdev->chandef.chan ? wdev->chandef.chan->center_freq : 0; | 1180 | u16 freq = wdev->chandef.chan ? wdev->chandef.chan->center_freq : 0; |
1160 | 1181 | ||
1161 | seq_printf(s, "Freq = %d\n", freq); | 1182 | seq_printf(s, "Freq = %d\n", freq); |
@@ -1185,6 +1206,8 @@ static int wil_link_debugfs_show(struct seq_file *s, void *data) | |||
1185 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { | 1206 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { |
1186 | struct wil_sta_info *p = &wil->sta[i]; | 1207 | struct wil_sta_info *p = &wil->sta[i]; |
1187 | char *status = "unknown"; | 1208 | char *status = "unknown"; |
1209 | struct wil6210_vif *vif; | ||
1210 | u8 mid; | ||
1188 | 1211 | ||
1189 | switch (p->status) { | 1212 | switch (p->status) { |
1190 | case wil_sta_unused: | 1213 | case wil_sta_unused: |
@@ -1197,16 +1220,24 @@ static int wil_link_debugfs_show(struct seq_file *s, void *data) | |||
1197 | status = "connected"; | 1220 | status = "connected"; |
1198 | break; | 1221 | break; |
1199 | } | 1222 | } |
1200 | seq_printf(s, "[%d] %pM %s\n", i, p->addr, status); | 1223 | mid = (p->status != wil_sta_unused) ? p->mid : U8_MAX; |
1224 | seq_printf(s, "[%d][MID %d] %pM %s\n", | ||
1225 | i, mid, p->addr, status); | ||
1201 | 1226 | ||
1202 | if (p->status == wil_sta_connected) { | 1227 | if (p->status != wil_sta_connected) |
1203 | rc = wil_cid_fill_sinfo(wil, i, &sinfo); | 1228 | continue; |
1229 | |||
1230 | vif = (mid < wil->max_vifs) ? wil->vifs[mid] : NULL; | ||
1231 | if (vif) { | ||
1232 | rc = wil_cid_fill_sinfo(vif, i, &sinfo); | ||
1204 | if (rc) | 1233 | if (rc) |
1205 | return rc; | 1234 | return rc; |
1206 | 1235 | ||
1207 | seq_printf(s, " Tx_mcs = %d\n", sinfo.txrate.mcs); | 1236 | seq_printf(s, " Tx_mcs = %d\n", sinfo.txrate.mcs); |
1208 | seq_printf(s, " Rx_mcs = %d\n", sinfo.rxrate.mcs); | 1237 | seq_printf(s, " Rx_mcs = %d\n", sinfo.rxrate.mcs); |
1209 | seq_printf(s, " SQ = %d\n", sinfo.signal); | 1238 | seq_printf(s, " SQ = %d\n", sinfo.signal); |
1239 | } else { | ||
1240 | seq_puts(s, " INVALID MID\n"); | ||
1210 | } | 1241 | } |
1211 | } | 1242 | } |
1212 | 1243 | ||
@@ -1229,7 +1260,7 @@ static const struct file_operations fops_link = { | |||
1229 | static int wil_info_debugfs_show(struct seq_file *s, void *data) | 1260 | static int wil_info_debugfs_show(struct seq_file *s, void *data) |
1230 | { | 1261 | { |
1231 | struct wil6210_priv *wil = s->private; | 1262 | struct wil6210_priv *wil = s->private; |
1232 | struct net_device *ndev = wil_to_ndev(wil); | 1263 | struct net_device *ndev = wil->main_ndev; |
1233 | int is_ac = power_supply_is_system_supplied(); | 1264 | int is_ac = power_supply_is_system_supplied(); |
1234 | int rx = atomic_xchg(&wil->isr_count_rx, 0); | 1265 | int rx = atomic_xchg(&wil->isr_count_rx, 0); |
1235 | int tx = atomic_xchg(&wil->isr_count_tx, 0); | 1266 | int tx = atomic_xchg(&wil->isr_count_tx, 0); |
@@ -1398,6 +1429,7 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock) | |||
1398 | struct wil_sta_info *p = &wil->sta[i]; | 1429 | struct wil_sta_info *p = &wil->sta[i]; |
1399 | char *status = "unknown"; | 1430 | char *status = "unknown"; |
1400 | u8 aid = 0; | 1431 | u8 aid = 0; |
1432 | u8 mid; | ||
1401 | 1433 | ||
1402 | switch (p->status) { | 1434 | switch (p->status) { |
1403 | case wil_sta_unused: | 1435 | case wil_sta_unused: |
@@ -1411,7 +1443,9 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock) | |||
1411 | aid = p->aid; | 1443 | aid = p->aid; |
1412 | break; | 1444 | break; |
1413 | } | 1445 | } |
1414 | seq_printf(s, "[%d] %pM %s AID %d\n", i, p->addr, status, aid); | 1446 | mid = (p->status != wil_sta_unused) ? p->mid : U8_MAX; |
1447 | seq_printf(s, "[%d] %pM %s MID %d AID %d\n", i, p->addr, status, | ||
1448 | mid, aid); | ||
1415 | 1449 | ||
1416 | if (p->status == wil_sta_connected) { | 1450 | if (p->status == wil_sta_connected) { |
1417 | spin_lock_bh(&p->tid_rx_lock); | 1451 | spin_lock_bh(&p->tid_rx_lock); |
@@ -1461,6 +1495,42 @@ static const struct file_operations fops_sta = { | |||
1461 | .llseek = seq_lseek, | 1495 | .llseek = seq_lseek, |
1462 | }; | 1496 | }; |
1463 | 1497 | ||
1498 | static int wil_mids_debugfs_show(struct seq_file *s, void *data) | ||
1499 | { | ||
1500 | struct wil6210_priv *wil = s->private; | ||
1501 | struct wil6210_vif *vif; | ||
1502 | struct net_device *ndev; | ||
1503 | int i; | ||
1504 | |||
1505 | mutex_lock(&wil->vif_mutex); | ||
1506 | for (i = 0; i < wil->max_vifs; i++) { | ||
1507 | vif = wil->vifs[i]; | ||
1508 | |||
1509 | if (vif) { | ||
1510 | ndev = vif_to_ndev(vif); | ||
1511 | seq_printf(s, "[%d] %pM %s\n", i, ndev->dev_addr, | ||
1512 | ndev->name); | ||
1513 | } else { | ||
1514 | seq_printf(s, "[%d] unused\n", i); | ||
1515 | } | ||
1516 | } | ||
1517 | mutex_unlock(&wil->vif_mutex); | ||
1518 | |||
1519 | return 0; | ||
1520 | } | ||
1521 | |||
1522 | static int wil_mids_seq_open(struct inode *inode, struct file *file) | ||
1523 | { | ||
1524 | return single_open(file, wil_mids_debugfs_show, inode->i_private); | ||
1525 | } | ||
1526 | |||
1527 | static const struct file_operations fops_mids = { | ||
1528 | .open = wil_mids_seq_open, | ||
1529 | .release = single_release, | ||
1530 | .read = seq_read, | ||
1531 | .llseek = seq_lseek, | ||
1532 | }; | ||
1533 | |||
1464 | static ssize_t wil_read_file_led_cfg(struct file *file, char __user *user_buf, | 1534 | static ssize_t wil_read_file_led_cfg(struct file *file, char __user *user_buf, |
1465 | size_t count, loff_t *ppos) | 1535 | size_t count, loff_t *ppos) |
1466 | { | 1536 | { |
@@ -1715,6 +1785,7 @@ static const struct { | |||
1715 | {"mbox", 0444, &fops_mbox}, | 1785 | {"mbox", 0444, &fops_mbox}, |
1716 | {"vrings", 0444, &fops_vring}, | 1786 | {"vrings", 0444, &fops_vring}, |
1717 | {"stations", 0444, &fops_sta}, | 1787 | {"stations", 0444, &fops_sta}, |
1788 | {"mids", 0444, &fops_mids}, | ||
1718 | {"desc", 0444, &fops_txdesc}, | 1789 | {"desc", 0444, &fops_txdesc}, |
1719 | {"bf", 0444, &fops_bf}, | 1790 | {"bf", 0444, &fops_bf}, |
1720 | {"mem_val", 0644, &fops_memread}, | 1791 | {"mem_val", 0644, &fops_memread}, |
@@ -1773,11 +1844,9 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil, | |||
1773 | 1844 | ||
1774 | /* fields in struct wil6210_priv */ | 1845 | /* fields in struct wil6210_priv */ |
1775 | static const struct dbg_off dbg_wil_off[] = { | 1846 | static const struct dbg_off dbg_wil_off[] = { |
1776 | WIL_FIELD(privacy, 0444, doff_u32), | ||
1777 | WIL_FIELD(status[0], 0644, doff_ulong), | 1847 | WIL_FIELD(status[0], 0644, doff_ulong), |
1778 | WIL_FIELD(hw_version, 0444, doff_x32), | 1848 | WIL_FIELD(hw_version, 0444, doff_x32), |
1779 | WIL_FIELD(recovery_count, 0444, doff_u32), | 1849 | WIL_FIELD(recovery_count, 0444, doff_u32), |
1780 | WIL_FIELD(ap_isolate, 0444, doff_u32), | ||
1781 | WIL_FIELD(discovery_mode, 0644, doff_u8), | 1850 | WIL_FIELD(discovery_mode, 0644, doff_u8), |
1782 | WIL_FIELD(chip_revision, 0444, doff_u8), | 1851 | WIL_FIELD(chip_revision, 0444, doff_u8), |
1783 | WIL_FIELD(abft_len, 0644, doff_u8), | 1852 | WIL_FIELD(abft_len, 0644, doff_u8), |
diff --git a/drivers/net/wireless/ath/wil6210/ethtool.c b/drivers/net/wireless/ath/wil6210/ethtool.c index 66200f616a37..e7ff41e623d2 100644 --- a/drivers/net/wireless/ath/wil6210/ethtool.c +++ b/drivers/net/wireless/ath/wil6210/ethtool.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2014,2017 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2014,2017 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -74,12 +75,13 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, | |||
74 | struct ethtool_coalesce *cp) | 75 | struct ethtool_coalesce *cp) |
75 | { | 76 | { |
76 | struct wil6210_priv *wil = ndev_to_wil(ndev); | 77 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
78 | struct wireless_dev *wdev = ndev->ieee80211_ptr; | ||
77 | int ret; | 79 | int ret; |
78 | 80 | ||
79 | wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n", | 81 | wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n", |
80 | cp->rx_coalesce_usecs, cp->tx_coalesce_usecs); | 82 | cp->rx_coalesce_usecs, cp->tx_coalesce_usecs); |
81 | 83 | ||
82 | if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { | 84 | if (wdev->iftype == NL80211_IFTYPE_MONITOR) { |
83 | wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n"); | 85 | wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n"); |
84 | return -EINVAL; | 86 | return -EINVAL; |
85 | } | 87 | } |
diff --git a/drivers/net/wireless/ath/wil6210/fw.h b/drivers/net/wireless/ath/wil6210/fw.h index 2c7b24f61587..3e7a28045cab 100644 --- a/drivers/net/wireless/ath/wil6210/fw.h +++ b/drivers/net/wireless/ath/wil6210/fw.h | |||
@@ -14,6 +14,8 @@ | |||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | */ | 16 | */ |
17 | #ifndef __WIL_FW_H__ | ||
18 | #define __WIL_FW_H__ | ||
17 | 19 | ||
18 | #define WIL_FW_SIGNATURE (0x36323130) /* '0126' */ | 20 | #define WIL_FW_SIGNATURE (0x36323130) /* '0126' */ |
19 | #define WIL_FW_FMT_VERSION (1) /* format version driver supports */ | 21 | #define WIL_FW_FMT_VERSION (1) /* format version driver supports */ |
@@ -71,7 +73,39 @@ struct wil_fw_record_capabilities { /* type == wil_fw_type_comment */ | |||
71 | struct wil_fw_record_comment_hdr hdr; | 73 | struct wil_fw_record_comment_hdr hdr; |
72 | /* capabilities (variable size), see enum wmi_fw_capability */ | 74 | /* capabilities (variable size), see enum wmi_fw_capability */ |
73 | u8 capabilities[0]; | 75 | u8 capabilities[0]; |
74 | }; | 76 | } __packed; |
77 | |||
78 | /* FW VIF concurrency encoded inside a comment record | ||
79 | * Format is similar to wiphy->iface_combinations | ||
80 | */ | ||
81 | #define WIL_FW_CONCURRENCY_MAGIC (0xfedccdef) | ||
82 | #define WIL_FW_CONCURRENCY_REC_VER 1 | ||
83 | struct wil_fw_concurrency_limit { | ||
84 | __le16 max; /* maximum number of interfaces of these types */ | ||
85 | __le16 types; /* interface types (bit mask of enum nl80211_iftype) */ | ||
86 | } __packed; | ||
87 | |||
88 | struct wil_fw_concurrency_combo { | ||
89 | u8 n_limits; /* number of wil_fw_concurrency_limit entries */ | ||
90 | u8 max_interfaces; /* max number of concurrent interfaces allowed */ | ||
91 | u8 n_diff_channels; /* total number of different channels allowed */ | ||
92 | u8 same_bi; /* for APs, 1 if all APs must have same BI */ | ||
93 | /* keep last - concurrency limits, variable size by n_limits */ | ||
94 | struct wil_fw_concurrency_limit limits[0]; | ||
95 | } __packed; | ||
96 | |||
97 | struct wil_fw_record_concurrency { /* type == wil_fw_type_comment */ | ||
98 | /* identifies concurrency record */ | ||
99 | __le32 magic; | ||
100 | /* structure version, currently always 1 */ | ||
101 | u8 version; | ||
102 | /* maximum number of supported MIDs _in addition_ to MID 0 */ | ||
103 | u8 n_mids; | ||
104 | /* number of concurrency combinations that follow */ | ||
105 | __le16 n_combos; | ||
106 | /* keep last - combinations, variable size by n_combos */ | ||
107 | struct wil_fw_concurrency_combo combos[0]; | ||
108 | } __packed; | ||
75 | 109 | ||
76 | /* brd file info encoded inside a comment record */ | 110 | /* brd file info encoded inside a comment record */ |
77 | #define WIL_BRD_FILE_MAGIC (0xabcddcbb) | 111 | #define WIL_BRD_FILE_MAGIC (0xabcddcbb) |
@@ -175,3 +209,5 @@ struct wil_fw_record_gateway_data4 { /* type == wil_fw_type_gateway_data4 */ | |||
175 | __le32 command; | 209 | __le32 command; |
176 | struct wil_fw_data_gw4 data[0]; /* total size [data_size], see above */ | 210 | struct wil_fw_data_gw4 data[0]; /* total size [data_size], see above */ |
177 | } __packed; | 211 | } __packed; |
212 | |||
213 | #endif /* __WIL_FW_H__ */ | ||
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c index 914c0106e94b..718161b829c2 100644 --- a/drivers/net/wireless/ath/wil6210/fw_inc.c +++ b/drivers/net/wireless/ath/wil6210/fw_inc.c | |||
@@ -136,8 +136,8 @@ fw_handle_capabilities(struct wil6210_priv *wil, const void *data, | |||
136 | size_t capa_size; | 136 | size_t capa_size; |
137 | 137 | ||
138 | if (size < sizeof(*rec)) { | 138 | if (size < sizeof(*rec)) { |
139 | wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, | 139 | wil_err_fw(wil, "capabilities record too short: %zu\n", size); |
140 | data, size, true); | 140 | /* let the FW load anyway */ |
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
@@ -158,8 +158,7 @@ fw_handle_brd_file(struct wil6210_priv *wil, const void *data, | |||
158 | const struct wil_fw_record_brd_file *rec = data; | 158 | const struct wil_fw_record_brd_file *rec = data; |
159 | 159 | ||
160 | if (size < sizeof(*rec)) { | 160 | if (size < sizeof(*rec)) { |
161 | wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, | 161 | wil_err_fw(wil, "brd_file record too short: %zu\n", size); |
162 | data, size, true); | ||
163 | return 0; | 162 | return 0; |
164 | } | 163 | } |
165 | 164 | ||
@@ -173,6 +172,44 @@ fw_handle_brd_file(struct wil6210_priv *wil, const void *data, | |||
173 | } | 172 | } |
174 | 173 | ||
175 | static int | 174 | static int |
175 | fw_handle_concurrency(struct wil6210_priv *wil, const void *data, | ||
176 | size_t size) | ||
177 | { | ||
178 | const struct wil_fw_record_concurrency *rec = data; | ||
179 | const struct wil_fw_concurrency_combo *combo; | ||
180 | const struct wil_fw_concurrency_limit *limit; | ||
181 | size_t remain, lsize; | ||
182 | int i, n_combos; | ||
183 | |||
184 | if (size < sizeof(*rec)) { | ||
185 | wil_err_fw(wil, "concurrency record too short: %zu\n", size); | ||
186 | /* continue, let the FW load anyway */ | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | n_combos = le16_to_cpu(rec->n_combos); | ||
191 | remain = size - offsetof(struct wil_fw_record_concurrency, combos); | ||
192 | combo = rec->combos; | ||
193 | for (i = 0; i < n_combos; i++) { | ||
194 | if (remain < sizeof(*combo)) | ||
195 | goto out_short; | ||
196 | remain -= sizeof(*combo); | ||
197 | limit = combo->limits; | ||
198 | lsize = combo->n_limits * sizeof(*limit); | ||
199 | if (remain < lsize) | ||
200 | goto out_short; | ||
201 | remain -= lsize; | ||
202 | limit += combo->n_limits; | ||
203 | combo = (struct wil_fw_concurrency_combo *)limit; | ||
204 | } | ||
205 | |||
206 | return wil_cfg80211_iface_combinations_from_fw(wil, rec); | ||
207 | out_short: | ||
208 | wil_err_fw(wil, "concurrency record truncated\n"); | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int | ||
176 | fw_handle_comment(struct wil6210_priv *wil, const void *data, | 213 | fw_handle_comment(struct wil6210_priv *wil, const void *data, |
177 | size_t size) | 214 | size_t size) |
178 | { | 215 | { |
@@ -194,6 +231,13 @@ fw_handle_comment(struct wil6210_priv *wil, const void *data, | |||
194 | wil_dbg_fw(wil, "magic is WIL_BRD_FILE_MAGIC\n"); | 231 | wil_dbg_fw(wil, "magic is WIL_BRD_FILE_MAGIC\n"); |
195 | rc = fw_handle_brd_file(wil, data, size); | 232 | rc = fw_handle_brd_file(wil, data, size); |
196 | break; | 233 | break; |
234 | case WIL_FW_CONCURRENCY_MAGIC: | ||
235 | wil_dbg_fw(wil, "magic is WIL_FW_CONCURRENCY_MAGIC\n"); | ||
236 | rc = fw_handle_concurrency(wil, data, size); | ||
237 | break; | ||
238 | default: | ||
239 | wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, | ||
240 | data, size, true); | ||
197 | } | 241 | } |
198 | 242 | ||
199 | return rc; | 243 | return rc; |
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index 1835187ea075..84e9840c1752 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c | |||
@@ -127,7 +127,7 @@ void wil6210_unmask_irq_tx(struct wil6210_priv *wil) | |||
127 | 127 | ||
128 | void wil6210_unmask_irq_rx(struct wil6210_priv *wil) | 128 | void wil6210_unmask_irq_rx(struct wil6210_priv *wil) |
129 | { | 129 | { |
130 | bool unmask_rx_htrsh = test_bit(wil_status_fwconnected, wil->status); | 130 | bool unmask_rx_htrsh = atomic_read(&wil->connected_vifs) > 0; |
131 | 131 | ||
132 | wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, IMC), | 132 | wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, IMC), |
133 | unmask_rx_htrsh ? WIL6210_IMC_RX : WIL6210_IMC_RX_NO_RX_HTRSH); | 133 | unmask_rx_htrsh ? WIL6210_IMC_RX : WIL6210_IMC_RX_NO_RX_HTRSH); |
@@ -188,12 +188,14 @@ void wil_unmask_irq(struct wil6210_priv *wil) | |||
188 | 188 | ||
189 | void wil_configure_interrupt_moderation(struct wil6210_priv *wil) | 189 | void wil_configure_interrupt_moderation(struct wil6210_priv *wil) |
190 | { | 190 | { |
191 | struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr; | ||
192 | |||
191 | wil_dbg_irq(wil, "configure_interrupt_moderation\n"); | 193 | wil_dbg_irq(wil, "configure_interrupt_moderation\n"); |
192 | 194 | ||
193 | /* disable interrupt moderation for monitor | 195 | /* disable interrupt moderation for monitor |
194 | * to get better timestamp precision | 196 | * to get better timestamp precision |
195 | */ | 197 | */ |
196 | if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) | 198 | if (wdev->iftype == NL80211_IFTYPE_MONITOR) |
197 | return; | 199 | return; |
198 | 200 | ||
199 | /* Disable and clear tx counter before (re)configuration */ | 201 | /* Disable and clear tx counter before (re)configuration */ |
@@ -340,7 +342,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie) | |||
340 | 342 | ||
341 | static void wil_notify_fw_error(struct wil6210_priv *wil) | 343 | static void wil_notify_fw_error(struct wil6210_priv *wil) |
342 | { | 344 | { |
343 | struct device *dev = &wil_to_ndev(wil)->dev; | 345 | struct device *dev = &wil->main_ndev->dev; |
344 | char *envp[3] = { | 346 | char *envp[3] = { |
345 | [0] = "SOURCE=wil6210", | 347 | [0] = "SOURCE=wil6210", |
346 | [1] = "EVENT=FW_ERROR", | 348 | [1] = "EVENT=FW_ERROR", |
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 0c61a6c13991..a4b413e8d55a 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c | |||
@@ -160,24 +160,34 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, | |||
160 | } | 160 | } |
161 | } | 161 | } |
162 | 162 | ||
163 | static void wil_disconnect_cid(struct wil6210_priv *wil, int cid, | 163 | static void wil_disconnect_cid(struct wil6210_vif *vif, int cid, |
164 | u16 reason_code, bool from_event) | 164 | u16 reason_code, bool from_event) |
165 | __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | 165 | __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) |
166 | { | 166 | { |
167 | uint i; | 167 | uint i; |
168 | struct net_device *ndev = wil_to_ndev(wil); | 168 | struct wil6210_priv *wil = vif_to_wil(vif); |
169 | struct wireless_dev *wdev = wil->wdev; | 169 | struct net_device *ndev = vif_to_ndev(vif); |
170 | struct wireless_dev *wdev = vif_to_wdev(vif); | ||
170 | struct wil_sta_info *sta = &wil->sta[cid]; | 171 | struct wil_sta_info *sta = &wil->sta[cid]; |
171 | 172 | ||
172 | might_sleep(); | 173 | might_sleep(); |
173 | wil_dbg_misc(wil, "disconnect_cid: CID %d, status %d\n", | 174 | wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n", |
174 | cid, sta->status); | 175 | cid, sta->mid, sta->status); |
175 | /* inform upper/lower layers */ | 176 | /* inform upper/lower layers */ |
176 | if (sta->status != wil_sta_unused) { | 177 | if (sta->status != wil_sta_unused) { |
178 | if (vif->mid != sta->mid) { | ||
179 | wil_err(wil, "STA MID mismatch with VIF MID(%d)\n", | ||
180 | vif->mid); | ||
181 | /* let FW override sta->mid but be more strict with | ||
182 | * user space requests | ||
183 | */ | ||
184 | if (!from_event) | ||
185 | return; | ||
186 | } | ||
177 | if (!from_event) { | 187 | if (!from_event) { |
178 | bool del_sta = (wdev->iftype == NL80211_IFTYPE_AP) ? | 188 | bool del_sta = (wdev->iftype == NL80211_IFTYPE_AP) ? |
179 | disable_ap_sme : false; | 189 | disable_ap_sme : false; |
180 | wmi_disconnect_sta(wil, sta->addr, reason_code, | 190 | wmi_disconnect_sta(vif, sta->addr, reason_code, |
181 | true, del_sta); | 191 | true, del_sta); |
182 | } | 192 | } |
183 | 193 | ||
@@ -191,6 +201,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | |||
191 | break; | 201 | break; |
192 | } | 202 | } |
193 | sta->status = wil_sta_unused; | 203 | sta->status = wil_sta_unused; |
204 | sta->mid = U8_MAX; | ||
194 | } | 205 | } |
195 | /* reorder buffers */ | 206 | /* reorder buffers */ |
196 | for (i = 0; i < WIL_STA_TID_NUM; i++) { | 207 | for (i = 0; i < WIL_STA_TID_NUM; i++) { |
@@ -216,28 +227,33 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | |||
216 | memset(&sta->stats, 0, sizeof(sta->stats)); | 227 | memset(&sta->stats, 0, sizeof(sta->stats)); |
217 | } | 228 | } |
218 | 229 | ||
219 | static bool wil_is_connected(struct wil6210_priv *wil) | 230 | static bool wil_vif_is_connected(struct wil6210_priv *wil, u8 mid) |
220 | { | 231 | { |
221 | int i; | 232 | int i; |
222 | 233 | ||
223 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { | 234 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { |
224 | if (wil->sta[i].status == wil_sta_connected) | 235 | if (wil->sta[i].mid == mid && |
236 | wil->sta[i].status == wil_sta_connected) | ||
225 | return true; | 237 | return true; |
226 | } | 238 | } |
227 | 239 | ||
228 | return false; | 240 | return false; |
229 | } | 241 | } |
230 | 242 | ||
231 | static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, | 243 | static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid, |
232 | u16 reason_code, bool from_event) | 244 | u16 reason_code, bool from_event) |
233 | { | 245 | { |
246 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
234 | int cid = -ENOENT; | 247 | int cid = -ENOENT; |
235 | struct net_device *ndev = wil_to_ndev(wil); | 248 | struct net_device *ndev; |
236 | struct wireless_dev *wdev = wil->wdev; | 249 | struct wireless_dev *wdev; |
237 | 250 | ||
238 | if (unlikely(!ndev)) | 251 | if (unlikely(!vif)) |
239 | return; | 252 | return; |
240 | 253 | ||
254 | ndev = vif_to_ndev(vif); | ||
255 | wdev = vif_to_wdev(vif); | ||
256 | |||
241 | might_sleep(); | 257 | might_sleep(); |
242 | wil_info(wil, "bssid=%pM, reason=%d, ev%s\n", bssid, | 258 | wil_info(wil, "bssid=%pM, reason=%d, ev%s\n", bssid, |
243 | reason_code, from_event ? "+" : "-"); | 259 | reason_code, from_event ? "+" : "-"); |
@@ -254,48 +270,51 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, | |||
254 | */ | 270 | */ |
255 | if (bssid && !is_broadcast_ether_addr(bssid) && | 271 | if (bssid && !is_broadcast_ether_addr(bssid) && |
256 | !ether_addr_equal_unaligned(ndev->dev_addr, bssid)) { | 272 | !ether_addr_equal_unaligned(ndev->dev_addr, bssid)) { |
257 | cid = wil_find_cid(wil, bssid); | 273 | cid = wil_find_cid(wil, vif->mid, bssid); |
258 | wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n", | 274 | wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n", |
259 | bssid, cid, reason_code); | 275 | bssid, cid, reason_code); |
260 | if (cid >= 0) /* disconnect 1 peer */ | 276 | if (cid >= 0) /* disconnect 1 peer */ |
261 | wil_disconnect_cid(wil, cid, reason_code, from_event); | 277 | wil_disconnect_cid(vif, cid, reason_code, from_event); |
262 | } else { /* all */ | 278 | } else { /* all */ |
263 | wil_dbg_misc(wil, "Disconnect all\n"); | 279 | wil_dbg_misc(wil, "Disconnect all\n"); |
264 | for (cid = 0; cid < WIL6210_MAX_CID; cid++) | 280 | for (cid = 0; cid < WIL6210_MAX_CID; cid++) |
265 | wil_disconnect_cid(wil, cid, reason_code, from_event); | 281 | wil_disconnect_cid(vif, cid, reason_code, from_event); |
266 | } | 282 | } |
267 | 283 | ||
268 | /* link state */ | 284 | /* link state */ |
269 | switch (wdev->iftype) { | 285 | switch (wdev->iftype) { |
270 | case NL80211_IFTYPE_STATION: | 286 | case NL80211_IFTYPE_STATION: |
271 | case NL80211_IFTYPE_P2P_CLIENT: | 287 | case NL80211_IFTYPE_P2P_CLIENT: |
272 | wil_bcast_fini(wil); | 288 | wil_bcast_fini(vif); |
273 | wil_update_net_queues_bh(wil, NULL, true); | 289 | wil_update_net_queues_bh(wil, vif, NULL, true); |
274 | netif_carrier_off(ndev); | 290 | netif_carrier_off(ndev); |
275 | wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); | 291 | if (!wil_has_other_active_ifaces(wil, ndev, false, true)) |
292 | wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); | ||
276 | 293 | ||
277 | if (test_bit(wil_status_fwconnected, wil->status)) { | 294 | if (test_and_clear_bit(wil_vif_fwconnected, vif->status)) { |
278 | clear_bit(wil_status_fwconnected, wil->status); | 295 | atomic_dec(&wil->connected_vifs); |
279 | cfg80211_disconnected(ndev, reason_code, | 296 | cfg80211_disconnected(ndev, reason_code, |
280 | NULL, 0, | 297 | NULL, 0, |
281 | wil->locally_generated_disc, | 298 | vif->locally_generated_disc, |
282 | GFP_KERNEL); | 299 | GFP_KERNEL); |
283 | wil->locally_generated_disc = false; | 300 | vif->locally_generated_disc = false; |
284 | } else if (test_bit(wil_status_fwconnecting, wil->status)) { | 301 | } else if (test_bit(wil_vif_fwconnecting, vif->status)) { |
285 | cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, | 302 | cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, |
286 | WLAN_STATUS_UNSPECIFIED_FAILURE, | 303 | WLAN_STATUS_UNSPECIFIED_FAILURE, |
287 | GFP_KERNEL); | 304 | GFP_KERNEL); |
288 | wil->bss = NULL; | 305 | vif->bss = NULL; |
289 | } | 306 | } |
290 | clear_bit(wil_status_fwconnecting, wil->status); | 307 | clear_bit(wil_vif_fwconnecting, vif->status); |
291 | break; | 308 | break; |
292 | case NL80211_IFTYPE_AP: | 309 | case NL80211_IFTYPE_AP: |
293 | case NL80211_IFTYPE_P2P_GO: | 310 | case NL80211_IFTYPE_P2P_GO: |
294 | if (!wil_is_connected(wil)) { | 311 | if (!wil_vif_is_connected(wil, vif->mid)) { |
295 | wil_update_net_queues_bh(wil, NULL, true); | 312 | wil_update_net_queues_bh(wil, vif, NULL, true); |
296 | clear_bit(wil_status_fwconnected, wil->status); | 313 | if (test_and_clear_bit(wil_vif_fwconnected, |
314 | vif->status)) | ||
315 | atomic_dec(&wil->connected_vifs); | ||
297 | } else { | 316 | } else { |
298 | wil_update_net_queues_bh(wil, NULL, false); | 317 | wil_update_net_queues_bh(wil, vif, NULL, false); |
299 | } | 318 | } |
300 | break; | 319 | break; |
301 | default: | 320 | default: |
@@ -303,26 +322,27 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, | |||
303 | } | 322 | } |
304 | } | 323 | } |
305 | 324 | ||
306 | static void wil_disconnect_worker(struct work_struct *work) | 325 | void wil_disconnect_worker(struct work_struct *work) |
307 | { | 326 | { |
308 | struct wil6210_priv *wil = container_of(work, | 327 | struct wil6210_vif *vif = container_of(work, |
309 | struct wil6210_priv, disconnect_worker); | 328 | struct wil6210_vif, disconnect_worker); |
310 | struct net_device *ndev = wil_to_ndev(wil); | 329 | struct wil6210_priv *wil = vif_to_wil(vif); |
330 | struct net_device *ndev = vif_to_ndev(vif); | ||
311 | int rc; | 331 | int rc; |
312 | struct { | 332 | struct { |
313 | struct wmi_cmd_hdr wmi; | 333 | struct wmi_cmd_hdr wmi; |
314 | struct wmi_disconnect_event evt; | 334 | struct wmi_disconnect_event evt; |
315 | } __packed reply; | 335 | } __packed reply; |
316 | 336 | ||
317 | if (test_bit(wil_status_fwconnected, wil->status)) | 337 | if (test_bit(wil_vif_fwconnected, vif->status)) |
318 | /* connect succeeded after all */ | 338 | /* connect succeeded after all */ |
319 | return; | 339 | return; |
320 | 340 | ||
321 | if (!test_bit(wil_status_fwconnecting, wil->status)) | 341 | if (!test_bit(wil_vif_fwconnecting, vif->status)) |
322 | /* already disconnected */ | 342 | /* already disconnected */ |
323 | return; | 343 | return; |
324 | 344 | ||
325 | rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0, | 345 | rc = wmi_call(wil, WMI_DISCONNECT_CMDID, vif->mid, NULL, 0, |
326 | WMI_DISCONNECT_EVENTID, &reply, sizeof(reply), | 346 | WMI_DISCONNECT_EVENTID, &reply, sizeof(reply), |
327 | WIL6210_DISCONNECT_TO_MS); | 347 | WIL6210_DISCONNECT_TO_MS); |
328 | if (rc) { | 348 | if (rc) { |
@@ -330,35 +350,11 @@ static void wil_disconnect_worker(struct work_struct *work) | |||
330 | return; | 350 | return; |
331 | } | 351 | } |
332 | 352 | ||
333 | wil_update_net_queues_bh(wil, NULL, true); | 353 | wil_update_net_queues_bh(wil, vif, NULL, true); |
334 | netif_carrier_off(ndev); | 354 | netif_carrier_off(ndev); |
335 | cfg80211_connect_result(ndev, NULL, NULL, 0, NULL, 0, | 355 | cfg80211_connect_result(ndev, NULL, NULL, 0, NULL, 0, |
336 | WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); | 356 | WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); |
337 | clear_bit(wil_status_fwconnecting, wil->status); | 357 | clear_bit(wil_vif_fwconnecting, vif->status); |
338 | } | ||
339 | |||
340 | static void wil_connect_timer_fn(struct timer_list *t) | ||
341 | { | ||
342 | struct wil6210_priv *wil = from_timer(wil, t, connect_timer); | ||
343 | bool q; | ||
344 | |||
345 | wil_err(wil, "Connect timeout detected, disconnect station\n"); | ||
346 | |||
347 | /* reschedule to thread context - disconnect won't | ||
348 | * run from atomic context. | ||
349 | * queue on wmi_wq to prevent race with connect event. | ||
350 | */ | ||
351 | q = queue_work(wil->wmi_wq, &wil->disconnect_worker); | ||
352 | wil_dbg_wmi(wil, "queue_work of disconnect_worker -> %d\n", q); | ||
353 | } | ||
354 | |||
355 | static void wil_scan_timer_fn(struct timer_list *t) | ||
356 | { | ||
357 | struct wil6210_priv *wil = from_timer(wil, t, scan_timer); | ||
358 | |||
359 | clear_bit(wil_status_fwready, wil->status); | ||
360 | wil_err(wil, "Scan timeout detected, start fw error recovery\n"); | ||
361 | wil_fw_error_recovery(wil); | ||
362 | } | 358 | } |
363 | 359 | ||
364 | static int wil_wait_for_recovery(struct wil6210_priv *wil) | 360 | static int wil_wait_for_recovery(struct wil6210_priv *wil) |
@@ -394,12 +390,12 @@ static void wil_fw_error_worker(struct work_struct *work) | |||
394 | { | 390 | { |
395 | struct wil6210_priv *wil = container_of(work, struct wil6210_priv, | 391 | struct wil6210_priv *wil = container_of(work, struct wil6210_priv, |
396 | fw_error_worker); | 392 | fw_error_worker); |
397 | struct wireless_dev *wdev = wil->wdev; | 393 | struct net_device *ndev = wil->main_ndev; |
398 | struct net_device *ndev = wil_to_ndev(wil); | 394 | struct wireless_dev *wdev = ndev->ieee80211_ptr; |
399 | 395 | ||
400 | wil_dbg_misc(wil, "fw error worker\n"); | 396 | wil_dbg_misc(wil, "fw error worker\n"); |
401 | 397 | ||
402 | if (!(ndev->flags & IFF_UP)) { | 398 | if (!ndev || !(ndev->flags & IFF_UP)) { |
403 | wil_info(wil, "No recovery - interface is down\n"); | 399 | wil_info(wil, "No recovery - interface is down\n"); |
404 | return; | 400 | return; |
405 | } | 401 | } |
@@ -429,6 +425,10 @@ static void wil_fw_error_worker(struct work_struct *work) | |||
429 | return; | 425 | return; |
430 | 426 | ||
431 | mutex_lock(&wil->mutex); | 427 | mutex_lock(&wil->mutex); |
428 | /* Needs adaptation for multiple VIFs | ||
429 | * need to go over all VIFs and consider the appropriate | ||
430 | * recovery. | ||
431 | */ | ||
432 | switch (wdev->iftype) { | 432 | switch (wdev->iftype) { |
433 | case NL80211_IFTYPE_STATION: | 433 | case NL80211_IFTYPE_STATION: |
434 | case NL80211_IFTYPE_P2P_CLIENT: | 434 | case NL80211_IFTYPE_P2P_CLIENT: |
@@ -461,8 +461,9 @@ static int wil_find_free_vring(struct wil6210_priv *wil) | |||
461 | return -EINVAL; | 461 | return -EINVAL; |
462 | } | 462 | } |
463 | 463 | ||
464 | int wil_tx_init(struct wil6210_priv *wil, int cid) | 464 | int wil_tx_init(struct wil6210_vif *vif, int cid) |
465 | { | 465 | { |
466 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
466 | int rc = -EINVAL, ringid; | 467 | int rc = -EINVAL, ringid; |
467 | 468 | ||
468 | if (cid < 0) { | 469 | if (cid < 0) { |
@@ -475,21 +476,22 @@ int wil_tx_init(struct wil6210_priv *wil, int cid) | |||
475 | goto out; | 476 | goto out; |
476 | } | 477 | } |
477 | 478 | ||
478 | wil_dbg_wmi(wil, "Configure for connection CID %d vring %d\n", | 479 | wil_dbg_wmi(wil, "Configure for connection CID %d MID %d vring %d\n", |
479 | cid, ringid); | 480 | cid, vif->mid, ringid); |
480 | 481 | ||
481 | rc = wil_vring_init_tx(wil, ringid, 1 << tx_ring_order, cid, 0); | 482 | rc = wil_vring_init_tx(vif, ringid, 1 << tx_ring_order, cid, 0); |
482 | if (rc) | 483 | if (rc) |
483 | wil_err(wil, "wil_vring_init_tx for CID %d vring %d failed\n", | 484 | wil_err(wil, "init TX for CID %d MID %d vring %d failed\n", |
484 | cid, ringid); | 485 | cid, vif->mid, ringid); |
485 | 486 | ||
486 | out: | 487 | out: |
487 | return rc; | 488 | return rc; |
488 | } | 489 | } |
489 | 490 | ||
490 | int wil_bcast_init(struct wil6210_priv *wil) | 491 | int wil_bcast_init(struct wil6210_vif *vif) |
491 | { | 492 | { |
492 | int ri = wil->bcast_vring, rc; | 493 | struct wil6210_priv *wil = vif_to_wil(vif); |
494 | int ri = vif->bcast_vring, rc; | ||
493 | 495 | ||
494 | if ((ri >= 0) && wil->vring_tx[ri].va) | 496 | if ((ri >= 0) && wil->vring_tx[ri].va) |
495 | return 0; | 497 | return 0; |
@@ -498,25 +500,38 @@ int wil_bcast_init(struct wil6210_priv *wil) | |||
498 | if (ri < 0) | 500 | if (ri < 0) |
499 | return ri; | 501 | return ri; |
500 | 502 | ||
501 | wil->bcast_vring = ri; | 503 | vif->bcast_vring = ri; |
502 | rc = wil_vring_init_bcast(wil, ri, 1 << bcast_ring_order); | 504 | rc = wil_vring_init_bcast(vif, ri, 1 << bcast_ring_order); |
503 | if (rc) | 505 | if (rc) |
504 | wil->bcast_vring = -1; | 506 | vif->bcast_vring = -1; |
505 | 507 | ||
506 | return rc; | 508 | return rc; |
507 | } | 509 | } |
508 | 510 | ||
509 | void wil_bcast_fini(struct wil6210_priv *wil) | 511 | void wil_bcast_fini(struct wil6210_vif *vif) |
510 | { | 512 | { |
511 | int ri = wil->bcast_vring; | 513 | struct wil6210_priv *wil = vif_to_wil(vif); |
514 | int ri = vif->bcast_vring; | ||
512 | 515 | ||
513 | if (ri < 0) | 516 | if (ri < 0) |
514 | return; | 517 | return; |
515 | 518 | ||
516 | wil->bcast_vring = -1; | 519 | vif->bcast_vring = -1; |
517 | wil_vring_fini_tx(wil, ri); | 520 | wil_vring_fini_tx(wil, ri); |
518 | } | 521 | } |
519 | 522 | ||
523 | void wil_bcast_fini_all(struct wil6210_priv *wil) | ||
524 | { | ||
525 | int i; | ||
526 | struct wil6210_vif *vif; | ||
527 | |||
528 | for (i = 0; i < wil->max_vifs; i++) { | ||
529 | vif = wil->vifs[i]; | ||
530 | if (vif) | ||
531 | wil_bcast_fini(vif); | ||
532 | } | ||
533 | } | ||
534 | |||
520 | int wil_priv_init(struct wil6210_priv *wil) | 535 | int wil_priv_init(struct wil6210_priv *wil) |
521 | { | 536 | { |
522 | uint i; | 537 | uint i; |
@@ -524,38 +539,29 @@ int wil_priv_init(struct wil6210_priv *wil) | |||
524 | wil_dbg_misc(wil, "priv_init\n"); | 539 | wil_dbg_misc(wil, "priv_init\n"); |
525 | 540 | ||
526 | memset(wil->sta, 0, sizeof(wil->sta)); | 541 | memset(wil->sta, 0, sizeof(wil->sta)); |
527 | for (i = 0; i < WIL6210_MAX_CID; i++) | 542 | for (i = 0; i < WIL6210_MAX_CID; i++) { |
528 | spin_lock_init(&wil->sta[i].tid_rx_lock); | 543 | spin_lock_init(&wil->sta[i].tid_rx_lock); |
544 | wil->sta[i].mid = U8_MAX; | ||
545 | } | ||
529 | 546 | ||
530 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) | 547 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) |
531 | spin_lock_init(&wil->vring_tx_data[i].lock); | 548 | spin_lock_init(&wil->vring_tx_data[i].lock); |
532 | 549 | ||
533 | mutex_init(&wil->mutex); | 550 | mutex_init(&wil->mutex); |
551 | mutex_init(&wil->vif_mutex); | ||
534 | mutex_init(&wil->wmi_mutex); | 552 | mutex_init(&wil->wmi_mutex); |
535 | mutex_init(&wil->probe_client_mutex); | ||
536 | mutex_init(&wil->p2p_wdev_mutex); | ||
537 | mutex_init(&wil->halp.lock); | 553 | mutex_init(&wil->halp.lock); |
538 | 554 | ||
539 | init_completion(&wil->wmi_ready); | 555 | init_completion(&wil->wmi_ready); |
540 | init_completion(&wil->wmi_call); | 556 | init_completion(&wil->wmi_call); |
541 | init_completion(&wil->halp.comp); | 557 | init_completion(&wil->halp.comp); |
542 | 558 | ||
543 | wil->bcast_vring = -1; | ||
544 | timer_setup(&wil->connect_timer, wil_connect_timer_fn, 0); | ||
545 | timer_setup(&wil->scan_timer, wil_scan_timer_fn, 0); | ||
546 | timer_setup(&wil->p2p.discovery_timer, wil_p2p_discovery_timer_fn, 0); | ||
547 | |||
548 | INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); | ||
549 | INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); | 559 | INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); |
550 | INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker); | 560 | INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker); |
551 | INIT_WORK(&wil->probe_client_worker, wil_probe_client_worker); | ||
552 | INIT_WORK(&wil->p2p.delayed_listen_work, wil_p2p_delayed_listen_work); | ||
553 | 561 | ||
554 | INIT_LIST_HEAD(&wil->pending_wmi_ev); | 562 | INIT_LIST_HEAD(&wil->pending_wmi_ev); |
555 | INIT_LIST_HEAD(&wil->probe_client_pending); | ||
556 | spin_lock_init(&wil->wmi_ev_lock); | 563 | spin_lock_init(&wil->wmi_ev_lock); |
557 | spin_lock_init(&wil->net_queue_lock); | 564 | spin_lock_init(&wil->net_queue_lock); |
558 | wil->net_queue_stopped = 1; | ||
559 | init_waitqueue_head(&wil->wq); | 565 | init_waitqueue_head(&wil->wq); |
560 | 566 | ||
561 | wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi"); | 567 | wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi"); |
@@ -582,6 +588,9 @@ int wil_priv_init(struct wil6210_priv *wil) | |||
582 | memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats)); | 588 | memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats)); |
583 | wil->vring_idle_trsh = 16; | 589 | wil->vring_idle_trsh = 16; |
584 | 590 | ||
591 | wil->reply_mid = U8_MAX; | ||
592 | wil->max_vifs = 1; | ||
593 | |||
585 | return 0; | 594 | return 0; |
586 | 595 | ||
587 | out_wmi_wq: | 596 | out_wmi_wq: |
@@ -600,7 +609,7 @@ void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps) | |||
600 | 609 | ||
601 | /** | 610 | /** |
602 | * wil6210_disconnect - disconnect one connection | 611 | * wil6210_disconnect - disconnect one connection |
603 | * @wil: driver context | 612 | * @vif: virtual interface context |
604 | * @bssid: peer to disconnect, NULL to disconnect all | 613 | * @bssid: peer to disconnect, NULL to disconnect all |
605 | * @reason_code: Reason code for the Disassociation frame | 614 | * @reason_code: Reason code for the Disassociation frame |
606 | * @from_event: whether is invoked from FW event handler | 615 | * @from_event: whether is invoked from FW event handler |
@@ -608,13 +617,15 @@ void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps) | |||
608 | * Disconnect and release associated resources. If invoked not from the | 617 | * Disconnect and release associated resources. If invoked not from the |
609 | * FW event handler, issue WMI command(s) to trigger MAC disconnect. | 618 | * FW event handler, issue WMI command(s) to trigger MAC disconnect. |
610 | */ | 619 | */ |
611 | void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, | 620 | void wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid, |
612 | u16 reason_code, bool from_event) | 621 | u16 reason_code, bool from_event) |
613 | { | 622 | { |
623 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
624 | |||
614 | wil_dbg_misc(wil, "disconnect\n"); | 625 | wil_dbg_misc(wil, "disconnect\n"); |
615 | 626 | ||
616 | del_timer_sync(&wil->connect_timer); | 627 | del_timer_sync(&vif->connect_timer); |
617 | _wil6210_disconnect(wil, bssid, reason_code, from_event); | 628 | _wil6210_disconnect(vif, bssid, reason_code, from_event); |
618 | } | 629 | } |
619 | 630 | ||
620 | void wil_priv_deinit(struct wil6210_priv *wil) | 631 | void wil_priv_deinit(struct wil6210_priv *wil) |
@@ -622,18 +633,8 @@ void wil_priv_deinit(struct wil6210_priv *wil) | |||
622 | wil_dbg_misc(wil, "priv_deinit\n"); | 633 | wil_dbg_misc(wil, "priv_deinit\n"); |
623 | 634 | ||
624 | wil_set_recovery_state(wil, fw_recovery_idle); | 635 | wil_set_recovery_state(wil, fw_recovery_idle); |
625 | del_timer_sync(&wil->scan_timer); | ||
626 | del_timer_sync(&wil->p2p.discovery_timer); | ||
627 | cancel_work_sync(&wil->disconnect_worker); | ||
628 | cancel_work_sync(&wil->fw_error_worker); | 636 | cancel_work_sync(&wil->fw_error_worker); |
629 | cancel_work_sync(&wil->p2p.discovery_expired_work); | ||
630 | cancel_work_sync(&wil->p2p.delayed_listen_work); | ||
631 | mutex_lock(&wil->mutex); | ||
632 | wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); | ||
633 | mutex_unlock(&wil->mutex); | ||
634 | wmi_event_flush(wil); | 637 | wmi_event_flush(wil); |
635 | wil_probe_client_flush(wil); | ||
636 | cancel_work_sync(&wil->probe_client_worker); | ||
637 | destroy_workqueue(wil->wq_service); | 638 | destroy_workqueue(wil->wq_service); |
638 | destroy_workqueue(wil->wmi_wq); | 639 | destroy_workqueue(wil->wmi_wq); |
639 | } | 640 | } |
@@ -715,7 +716,7 @@ static void wil_bl_prepare_halt(struct wil6210_priv *wil) | |||
715 | offsetof(struct bl_dedicated_registers_v0, | 716 | offsetof(struct bl_dedicated_registers_v0, |
716 | boot_loader_struct_version)); | 717 | boot_loader_struct_version)); |
717 | if (!tmp) { | 718 | if (!tmp) { |
718 | wil_dbg_misc(wil, "old BL, skipping halt preperation\n"); | 719 | wil_dbg_misc(wil, "old BL, skipping halt preparation\n"); |
719 | return; | 720 | return; |
720 | } | 721 | } |
721 | 722 | ||
@@ -943,7 +944,7 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) | |||
943 | 944 | ||
944 | static int wil_get_bl_info(struct wil6210_priv *wil) | 945 | static int wil_get_bl_info(struct wil6210_priv *wil) |
945 | { | 946 | { |
946 | struct net_device *ndev = wil_to_ndev(wil); | 947 | struct net_device *ndev = wil->main_ndev; |
947 | struct wiphy *wiphy = wil_to_wiphy(wil); | 948 | struct wiphy *wiphy = wil_to_wiphy(wil); |
948 | union { | 949 | union { |
949 | struct bl_dedicated_registers_v0 bl0; | 950 | struct bl_dedicated_registers_v0 bl0; |
@@ -1035,7 +1036,7 @@ static void wil_bl_crash_info(struct wil6210_priv *wil, bool is_err) | |||
1035 | 1036 | ||
1036 | static int wil_get_otp_info(struct wil6210_priv *wil) | 1037 | static int wil_get_otp_info(struct wil6210_priv *wil) |
1037 | { | 1038 | { |
1038 | struct net_device *ndev = wil_to_ndev(wil); | 1039 | struct net_device *ndev = wil->main_ndev; |
1039 | struct wiphy *wiphy = wil_to_wiphy(wil); | 1040 | struct wiphy *wiphy = wil_to_wiphy(wil); |
1040 | u8 mac[8]; | 1041 | u8 mac[8]; |
1041 | 1042 | ||
@@ -1069,31 +1070,46 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil) | |||
1069 | return 0; | 1070 | return 0; |
1070 | } | 1071 | } |
1071 | 1072 | ||
1072 | void wil_abort_scan(struct wil6210_priv *wil, bool sync) | 1073 | void wil_abort_scan(struct wil6210_vif *vif, bool sync) |
1073 | { | 1074 | { |
1075 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1074 | int rc; | 1076 | int rc; |
1075 | struct cfg80211_scan_info info = { | 1077 | struct cfg80211_scan_info info = { |
1076 | .aborted = true, | 1078 | .aborted = true, |
1077 | }; | 1079 | }; |
1078 | 1080 | ||
1079 | lockdep_assert_held(&wil->p2p_wdev_mutex); | 1081 | lockdep_assert_held(&wil->vif_mutex); |
1080 | 1082 | ||
1081 | if (!wil->scan_request) | 1083 | if (!vif->scan_request) |
1082 | return; | 1084 | return; |
1083 | 1085 | ||
1084 | wil_dbg_misc(wil, "Abort scan_request 0x%p\n", wil->scan_request); | 1086 | wil_dbg_misc(wil, "Abort scan_request 0x%p\n", vif->scan_request); |
1085 | del_timer_sync(&wil->scan_timer); | 1087 | del_timer_sync(&vif->scan_timer); |
1086 | mutex_unlock(&wil->p2p_wdev_mutex); | 1088 | mutex_unlock(&wil->vif_mutex); |
1087 | rc = wmi_abort_scan(wil); | 1089 | rc = wmi_abort_scan(vif); |
1088 | if (!rc && sync) | 1090 | if (!rc && sync) |
1089 | wait_event_interruptible_timeout(wil->wq, !wil->scan_request, | 1091 | wait_event_interruptible_timeout(wil->wq, !vif->scan_request, |
1090 | msecs_to_jiffies( | 1092 | msecs_to_jiffies( |
1091 | WAIT_FOR_SCAN_ABORT_MS)); | 1093 | WAIT_FOR_SCAN_ABORT_MS)); |
1092 | 1094 | ||
1093 | mutex_lock(&wil->p2p_wdev_mutex); | 1095 | mutex_lock(&wil->vif_mutex); |
1094 | if (wil->scan_request) { | 1096 | if (vif->scan_request) { |
1095 | cfg80211_scan_done(wil->scan_request, &info); | 1097 | cfg80211_scan_done(vif->scan_request, &info); |
1096 | wil->scan_request = NULL; | 1098 | vif->scan_request = NULL; |
1099 | } | ||
1100 | } | ||
1101 | |||
1102 | void wil_abort_scan_all_vifs(struct wil6210_priv *wil, bool sync) | ||
1103 | { | ||
1104 | int i; | ||
1105 | |||
1106 | lockdep_assert_held(&wil->vif_mutex); | ||
1107 | |||
1108 | for (i = 0; i < wil->max_vifs; i++) { | ||
1109 | struct wil6210_vif *vif = wil->vifs[i]; | ||
1110 | |||
1111 | if (vif) | ||
1112 | wil_abort_scan(vif, sync); | ||
1097 | } | 1113 | } |
1098 | } | 1114 | } |
1099 | 1115 | ||
@@ -1138,6 +1154,34 @@ static void wil_pre_fw_config(struct wil6210_priv *wil) | |||
1138 | } | 1154 | } |
1139 | } | 1155 | } |
1140 | 1156 | ||
1157 | static int wil_restore_vifs(struct wil6210_priv *wil) | ||
1158 | { | ||
1159 | struct wil6210_vif *vif; | ||
1160 | struct net_device *ndev; | ||
1161 | struct wireless_dev *wdev; | ||
1162 | int i, rc; | ||
1163 | |||
1164 | for (i = 0; i < wil->max_vifs; i++) { | ||
1165 | vif = wil->vifs[i]; | ||
1166 | if (!vif) | ||
1167 | continue; | ||
1168 | vif->ap_isolate = 0; | ||
1169 | if (vif->mid) { | ||
1170 | ndev = vif_to_ndev(vif); | ||
1171 | wdev = vif_to_wdev(vif); | ||
1172 | rc = wmi_port_allocate(wil, vif->mid, ndev->dev_addr, | ||
1173 | wdev->iftype); | ||
1174 | if (rc) { | ||
1175 | wil_err(wil, "fail to restore VIF %d type %d, rc %d\n", | ||
1176 | i, wdev->iftype, rc); | ||
1177 | return rc; | ||
1178 | } | ||
1179 | } | ||
1180 | } | ||
1181 | |||
1182 | return 0; | ||
1183 | } | ||
1184 | |||
1141 | /* | 1185 | /* |
1142 | * We reset all the structures, and we reset the UMAC. | 1186 | * We reset all the structures, and we reset the UMAC. |
1143 | * After calling this routine, you're expected to reload | 1187 | * After calling this routine, you're expected to reload |
@@ -1145,9 +1189,10 @@ static void wil_pre_fw_config(struct wil6210_priv *wil) | |||
1145 | */ | 1189 | */ |
1146 | int wil_reset(struct wil6210_priv *wil, bool load_fw) | 1190 | int wil_reset(struct wil6210_priv *wil, bool load_fw) |
1147 | { | 1191 | { |
1148 | int rc; | 1192 | int rc, i; |
1149 | unsigned long status_flags = BIT(wil_status_resetting); | 1193 | unsigned long status_flags = BIT(wil_status_resetting); |
1150 | int no_flash; | 1194 | int no_flash; |
1195 | struct wil6210_vif *vif; | ||
1151 | 1196 | ||
1152 | wil_dbg_misc(wil, "reset\n"); | 1197 | wil_dbg_misc(wil, "reset\n"); |
1153 | 1198 | ||
@@ -1158,7 +1203,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) | |||
1158 | static const u8 mac[ETH_ALEN] = { | 1203 | static const u8 mac[ETH_ALEN] = { |
1159 | 0x00, 0xde, 0xad, 0x12, 0x34, 0x56, | 1204 | 0x00, 0xde, 0xad, 0x12, 0x34, 0x56, |
1160 | }; | 1205 | }; |
1161 | struct net_device *ndev = wil_to_ndev(wil); | 1206 | struct net_device *ndev = wil->main_ndev; |
1162 | 1207 | ||
1163 | ether_addr_copy(ndev->perm_addr, mac); | 1208 | ether_addr_copy(ndev->perm_addr, mac); |
1164 | ether_addr_copy(ndev->dev_addr, ndev->perm_addr); | 1209 | ether_addr_copy(ndev->dev_addr, ndev->perm_addr); |
@@ -1196,17 +1241,23 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) | |||
1196 | goto out; | 1241 | goto out; |
1197 | } | 1242 | } |
1198 | 1243 | ||
1199 | cancel_work_sync(&wil->disconnect_worker); | 1244 | mutex_lock(&wil->vif_mutex); |
1200 | wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); | 1245 | wil_abort_scan_all_vifs(wil, false); |
1201 | wil_bcast_fini(wil); | 1246 | mutex_unlock(&wil->vif_mutex); |
1247 | |||
1248 | for (i = 0; i < wil->max_vifs; i++) { | ||
1249 | vif = wil->vifs[i]; | ||
1250 | if (vif) { | ||
1251 | cancel_work_sync(&vif->disconnect_worker); | ||
1252 | wil6210_disconnect(vif, NULL, | ||
1253 | WLAN_REASON_DEAUTH_LEAVING, false); | ||
1254 | } | ||
1255 | } | ||
1256 | wil_bcast_fini_all(wil); | ||
1202 | 1257 | ||
1203 | /* Disable device led before reset*/ | 1258 | /* Disable device led before reset*/ |
1204 | wmi_led_cfg(wil, false); | 1259 | wmi_led_cfg(wil, false); |
1205 | 1260 | ||
1206 | mutex_lock(&wil->p2p_wdev_mutex); | ||
1207 | wil_abort_scan(wil, false); | ||
1208 | mutex_unlock(&wil->p2p_wdev_mutex); | ||
1209 | |||
1210 | /* prevent NAPI from being scheduled and prevent wmi commands */ | 1261 | /* prevent NAPI from being scheduled and prevent wmi commands */ |
1211 | mutex_lock(&wil->wmi_mutex); | 1262 | mutex_lock(&wil->wmi_mutex); |
1212 | if (test_bit(wil_status_suspending, wil->status)) | 1263 | if (test_bit(wil_status_suspending, wil->status)) |
@@ -1276,7 +1327,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) | |||
1276 | } | 1327 | } |
1277 | 1328 | ||
1278 | /* init after reset */ | 1329 | /* init after reset */ |
1279 | wil->ap_isolate = 0; | ||
1280 | reinit_completion(&wil->wmi_ready); | 1330 | reinit_completion(&wil->wmi_ready); |
1281 | reinit_completion(&wil->wmi_call); | 1331 | reinit_completion(&wil->wmi_call); |
1282 | reinit_completion(&wil->halp.comp); | 1332 | reinit_completion(&wil->halp.comp); |
@@ -1299,6 +1349,12 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) | |||
1299 | return rc; | 1349 | return rc; |
1300 | } | 1350 | } |
1301 | 1351 | ||
1352 | rc = wil_restore_vifs(wil); | ||
1353 | if (rc) { | ||
1354 | wil_err(wil, "failed to restore vifs, rc %d\n", rc); | ||
1355 | return rc; | ||
1356 | } | ||
1357 | |||
1302 | wil_collect_fw_info(wil); | 1358 | wil_collect_fw_info(wil); |
1303 | 1359 | ||
1304 | if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT) | 1360 | if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT) |
@@ -1337,8 +1393,8 @@ void wil_fw_error_recovery(struct wil6210_priv *wil) | |||
1337 | 1393 | ||
1338 | int __wil_up(struct wil6210_priv *wil) | 1394 | int __wil_up(struct wil6210_priv *wil) |
1339 | { | 1395 | { |
1340 | struct net_device *ndev = wil_to_ndev(wil); | 1396 | struct net_device *ndev = wil->main_ndev; |
1341 | struct wireless_dev *wdev = wil->wdev; | 1397 | struct wireless_dev *wdev = ndev->ieee80211_ptr; |
1342 | int rc; | 1398 | int rc; |
1343 | 1399 | ||
1344 | WARN_ON(!mutex_is_locked(&wil->mutex)); | 1400 | WARN_ON(!mutex_is_locked(&wil->mutex)); |
@@ -1420,10 +1476,10 @@ int __wil_down(struct wil6210_priv *wil) | |||
1420 | } | 1476 | } |
1421 | wil_enable_irq(wil); | 1477 | wil_enable_irq(wil); |
1422 | 1478 | ||
1423 | mutex_lock(&wil->p2p_wdev_mutex); | 1479 | mutex_lock(&wil->vif_mutex); |
1424 | wil_p2p_stop_radio_operations(wil); | 1480 | wil_p2p_stop_radio_operations(wil); |
1425 | wil_abort_scan(wil, false); | 1481 | wil_abort_scan_all_vifs(wil, false); |
1426 | mutex_unlock(&wil->p2p_wdev_mutex); | 1482 | mutex_unlock(&wil->vif_mutex); |
1427 | 1483 | ||
1428 | return wil_reset(wil, false); | 1484 | return wil_reset(wil, false); |
1429 | } | 1485 | } |
@@ -1442,13 +1498,14 @@ int wil_down(struct wil6210_priv *wil) | |||
1442 | return rc; | 1498 | return rc; |
1443 | } | 1499 | } |
1444 | 1500 | ||
1445 | int wil_find_cid(struct wil6210_priv *wil, const u8 *mac) | 1501 | int wil_find_cid(struct wil6210_priv *wil, u8 mid, const u8 *mac) |
1446 | { | 1502 | { |
1447 | int i; | 1503 | int i; |
1448 | int rc = -ENOENT; | 1504 | int rc = -ENOENT; |
1449 | 1505 | ||
1450 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { | 1506 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { |
1451 | if ((wil->sta[i].status != wil_sta_unused) && | 1507 | if (wil->sta[i].mid == mid && |
1508 | wil->sta[i].status != wil_sta_unused && | ||
1452 | ether_addr_equal(wil->sta[i].addr, mac)) { | 1509 | ether_addr_equal(wil->sta[i].addr, mac)) { |
1453 | rc = i; | 1510 | rc = i; |
1454 | break; | 1511 | break; |
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 7ba4e0af8f57..05e9408e7ea3 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -15,13 +16,41 @@ | |||
15 | */ | 16 | */ |
16 | 17 | ||
17 | #include <linux/etherdevice.h> | 18 | #include <linux/etherdevice.h> |
19 | #include <linux/rtnetlink.h> | ||
18 | #include "wil6210.h" | 20 | #include "wil6210.h" |
19 | #include "txrx.h" | 21 | #include "txrx.h" |
20 | 22 | ||
23 | bool wil_has_other_active_ifaces(struct wil6210_priv *wil, | ||
24 | struct net_device *ndev, bool up, bool ok) | ||
25 | { | ||
26 | int i; | ||
27 | struct wil6210_vif *vif; | ||
28 | struct net_device *ndev_i; | ||
29 | |||
30 | for (i = 0; i < wil->max_vifs; i++) { | ||
31 | vif = wil->vifs[i]; | ||
32 | if (vif) { | ||
33 | ndev_i = vif_to_ndev(vif); | ||
34 | if (ndev_i != ndev) | ||
35 | if ((up && (ndev_i->flags & IFF_UP)) || | ||
36 | (ok && netif_carrier_ok(ndev_i))) | ||
37 | return true; | ||
38 | } | ||
39 | } | ||
40 | |||
41 | return false; | ||
42 | } | ||
43 | |||
44 | bool wil_has_active_ifaces(struct wil6210_priv *wil, bool up, bool ok) | ||
45 | { | ||
46 | /* use NULL ndev argument to check all interfaces */ | ||
47 | return wil_has_other_active_ifaces(wil, NULL, up, ok); | ||
48 | } | ||
49 | |||
21 | static int wil_open(struct net_device *ndev) | 50 | static int wil_open(struct net_device *ndev) |
22 | { | 51 | { |
23 | struct wil6210_priv *wil = ndev_to_wil(ndev); | 52 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
24 | int rc; | 53 | int rc = 0; |
25 | 54 | ||
26 | wil_dbg_misc(wil, "open\n"); | 55 | wil_dbg_misc(wil, "open\n"); |
27 | 56 | ||
@@ -31,13 +60,16 @@ static int wil_open(struct net_device *ndev) | |||
31 | return -EINVAL; | 60 | return -EINVAL; |
32 | } | 61 | } |
33 | 62 | ||
34 | rc = wil_pm_runtime_get(wil); | 63 | if (!wil_has_other_active_ifaces(wil, ndev, true, false)) { |
35 | if (rc < 0) | 64 | wil_dbg_misc(wil, "open, first iface\n"); |
36 | return rc; | 65 | rc = wil_pm_runtime_get(wil); |
66 | if (rc < 0) | ||
67 | return rc; | ||
37 | 68 | ||
38 | rc = wil_up(wil); | 69 | rc = wil_up(wil); |
39 | if (rc) | 70 | if (rc) |
40 | wil_pm_runtime_put(wil); | 71 | wil_pm_runtime_put(wil); |
72 | } | ||
41 | 73 | ||
42 | return rc; | 74 | return rc; |
43 | } | 75 | } |
@@ -45,13 +77,16 @@ static int wil_open(struct net_device *ndev) | |||
45 | static int wil_stop(struct net_device *ndev) | 77 | static int wil_stop(struct net_device *ndev) |
46 | { | 78 | { |
47 | struct wil6210_priv *wil = ndev_to_wil(ndev); | 79 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
48 | int rc; | 80 | int rc = 0; |
49 | 81 | ||
50 | wil_dbg_misc(wil, "stop\n"); | 82 | wil_dbg_misc(wil, "stop\n"); |
51 | 83 | ||
52 | rc = wil_down(wil); | 84 | if (!wil_has_other_active_ifaces(wil, ndev, true, false)) { |
53 | if (!rc) | 85 | wil_dbg_misc(wil, "stop, last iface\n"); |
54 | wil_pm_runtime_put(wil); | 86 | rc = wil_down(wil); |
87 | if (!rc) | ||
88 | wil_pm_runtime_put(wil); | ||
89 | } | ||
55 | 90 | ||
56 | return rc; | 91 | return rc; |
57 | } | 92 | } |
@@ -96,11 +131,19 @@ static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget) | |||
96 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { | 131 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { |
97 | struct vring *vring = &wil->vring_tx[i]; | 132 | struct vring *vring = &wil->vring_tx[i]; |
98 | struct vring_tx_data *txdata = &wil->vring_tx_data[i]; | 133 | struct vring_tx_data *txdata = &wil->vring_tx_data[i]; |
134 | struct wil6210_vif *vif; | ||
99 | 135 | ||
100 | if (!vring->va || !txdata->enabled) | 136 | if (!vring->va || !txdata->enabled || |
137 | txdata->mid >= wil->max_vifs) | ||
101 | continue; | 138 | continue; |
102 | 139 | ||
103 | tx_done += wil_tx_complete(wil, i); | 140 | vif = wil->vifs[txdata->mid]; |
141 | if (unlikely(!vif)) { | ||
142 | wil_dbg_txrx(wil, "Invalid MID %d\n", txdata->mid); | ||
143 | continue; | ||
144 | } | ||
145 | |||
146 | tx_done += wil_tx_complete(vif, i); | ||
104 | } | 147 | } |
105 | 148 | ||
106 | if (tx_done < budget) { | 149 | if (tx_done < budget) { |
@@ -121,44 +164,137 @@ static void wil_dev_setup(struct net_device *dev) | |||
121 | dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT; | 164 | dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT; |
122 | } | 165 | } |
123 | 166 | ||
124 | void *wil_if_alloc(struct device *dev) | 167 | static void wil_vif_deinit(struct wil6210_vif *vif) |
125 | { | 168 | { |
126 | struct net_device *ndev; | 169 | del_timer_sync(&vif->scan_timer); |
127 | struct wireless_dev *wdev; | 170 | del_timer_sync(&vif->p2p.discovery_timer); |
128 | struct wil6210_priv *wil; | 171 | cancel_work_sync(&vif->disconnect_worker); |
129 | struct ieee80211_channel *ch; | 172 | cancel_work_sync(&vif->p2p.discovery_expired_work); |
130 | int rc = 0; | 173 | cancel_work_sync(&vif->p2p.delayed_listen_work); |
174 | wil_probe_client_flush(vif); | ||
175 | cancel_work_sync(&vif->probe_client_worker); | ||
176 | } | ||
131 | 177 | ||
132 | wdev = wil_cfg80211_init(dev); | 178 | void wil_vif_free(struct wil6210_vif *vif) |
133 | if (IS_ERR(wdev)) { | 179 | { |
134 | dev_err(dev, "wil_cfg80211_init failed\n"); | 180 | struct net_device *ndev = vif_to_ndev(vif); |
135 | return wdev; | ||
136 | } | ||
137 | 181 | ||
138 | wil = wdev_to_wil(wdev); | 182 | wil_vif_deinit(vif); |
139 | wil->wdev = wdev; | 183 | free_netdev(ndev); |
140 | wil->radio_wdev = wdev; | 184 | } |
141 | 185 | ||
142 | wil_dbg_misc(wil, "if_alloc\n"); | 186 | static void wil_ndev_destructor(struct net_device *ndev) |
187 | { | ||
188 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
143 | 189 | ||
144 | rc = wil_priv_init(wil); | 190 | wil_vif_deinit(vif); |
145 | if (rc) { | 191 | } |
146 | dev_err(dev, "wil_priv_init failed\n"); | 192 | |
147 | goto out_wdev; | 193 | static void wil_connect_timer_fn(struct timer_list *t) |
194 | { | ||
195 | struct wil6210_vif *vif = from_timer(vif, t, connect_timer); | ||
196 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
197 | bool q; | ||
198 | |||
199 | wil_err(wil, "Connect timeout detected, disconnect station\n"); | ||
200 | |||
201 | /* reschedule to thread context - disconnect won't | ||
202 | * run from atomic context. | ||
203 | * queue on wmi_wq to prevent race with connect event. | ||
204 | */ | ||
205 | q = queue_work(wil->wmi_wq, &vif->disconnect_worker); | ||
206 | wil_dbg_wmi(wil, "queue_work of disconnect_worker -> %d\n", q); | ||
207 | } | ||
208 | |||
209 | static void wil_scan_timer_fn(struct timer_list *t) | ||
210 | { | ||
211 | struct wil6210_vif *vif = from_timer(vif, t, scan_timer); | ||
212 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
213 | |||
214 | clear_bit(wil_status_fwready, wil->status); | ||
215 | wil_err(wil, "Scan timeout detected, start fw error recovery\n"); | ||
216 | wil_fw_error_recovery(wil); | ||
217 | } | ||
218 | |||
219 | static void wil_p2p_discovery_timer_fn(struct timer_list *t) | ||
220 | { | ||
221 | struct wil6210_vif *vif = from_timer(vif, t, p2p.discovery_timer); | ||
222 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
223 | |||
224 | wil_dbg_misc(wil, "p2p_discovery_timer_fn\n"); | ||
225 | |||
226 | schedule_work(&vif->p2p.discovery_expired_work); | ||
227 | } | ||
228 | |||
229 | static void wil_vif_init(struct wil6210_vif *vif) | ||
230 | { | ||
231 | vif->bcast_vring = -1; | ||
232 | |||
233 | mutex_init(&vif->probe_client_mutex); | ||
234 | |||
235 | timer_setup(&vif->connect_timer, wil_connect_timer_fn, 0); | ||
236 | timer_setup(&vif->scan_timer, wil_scan_timer_fn, 0); | ||
237 | timer_setup(&vif->p2p.discovery_timer, wil_p2p_discovery_timer_fn, 0); | ||
238 | |||
239 | INIT_WORK(&vif->probe_client_worker, wil_probe_client_worker); | ||
240 | INIT_WORK(&vif->disconnect_worker, wil_disconnect_worker); | ||
241 | INIT_WORK(&vif->p2p.delayed_listen_work, wil_p2p_delayed_listen_work); | ||
242 | |||
243 | INIT_LIST_HEAD(&vif->probe_client_pending); | ||
244 | |||
245 | vif->net_queue_stopped = 1; | ||
246 | } | ||
247 | |||
248 | static u8 wil_vif_find_free_mid(struct wil6210_priv *wil) | ||
249 | { | ||
250 | u8 i; | ||
251 | |||
252 | for (i = 0; i < wil->max_vifs; i++) { | ||
253 | if (!wil->vifs[i]) | ||
254 | return i; | ||
148 | } | 255 | } |
149 | 256 | ||
150 | wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */ | 257 | return U8_MAX; |
151 | /* default monitor channel */ | 258 | } |
152 | ch = wdev->wiphy->bands[NL80211_BAND_60GHZ]->channels; | 259 | |
153 | cfg80211_chandef_create(&wil->monitor_chandef, ch, NL80211_CHAN_NO_HT); | 260 | struct wil6210_vif * |
261 | wil_vif_alloc(struct wil6210_priv *wil, const char *name, | ||
262 | unsigned char name_assign_type, enum nl80211_iftype iftype) | ||
263 | { | ||
264 | struct net_device *ndev; | ||
265 | struct wireless_dev *wdev; | ||
266 | struct wil6210_vif *vif; | ||
267 | u8 mid; | ||
268 | |||
269 | mid = wil_vif_find_free_mid(wil); | ||
270 | if (mid == U8_MAX) { | ||
271 | wil_err(wil, "no available virtual interface\n"); | ||
272 | return ERR_PTR(-EINVAL); | ||
273 | } | ||
154 | 274 | ||
155 | ndev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, wil_dev_setup); | 275 | ndev = alloc_netdev(sizeof(*vif), name, name_assign_type, |
276 | wil_dev_setup); | ||
156 | if (!ndev) { | 277 | if (!ndev) { |
157 | dev_err(dev, "alloc_netdev_mqs failed\n"); | 278 | dev_err(wil_to_dev(wil), "alloc_netdev failed\n"); |
158 | rc = -ENOMEM; | 279 | return ERR_PTR(-ENOMEM); |
159 | goto out_priv; | 280 | } |
281 | if (mid == 0) { | ||
282 | wil->main_ndev = ndev; | ||
283 | } else { | ||
284 | ndev->priv_destructor = wil_ndev_destructor; | ||
285 | ndev->needs_free_netdev = true; | ||
160 | } | 286 | } |
161 | 287 | ||
288 | vif = ndev_to_vif(ndev); | ||
289 | vif->ndev = ndev; | ||
290 | vif->wil = wil; | ||
291 | vif->mid = mid; | ||
292 | wil_vif_init(vif); | ||
293 | |||
294 | wdev = &vif->wdev; | ||
295 | wdev->wiphy = wil->wiphy; | ||
296 | wdev->iftype = iftype; | ||
297 | |||
162 | ndev->netdev_ops = &wil_netdev_ops; | 298 | ndev->netdev_ops = &wil_netdev_ops; |
163 | wil_set_ethtoolops(ndev); | 299 | wil_set_ethtoolops(ndev); |
164 | ndev->ieee80211_ptr = wdev; | 300 | ndev->ieee80211_ptr = wdev; |
@@ -170,21 +306,53 @@ void *wil_if_alloc(struct device *dev) | |||
170 | ndev->features |= ndev->hw_features; | 306 | ndev->features |= ndev->hw_features; |
171 | SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); | 307 | SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); |
172 | wdev->netdev = ndev; | 308 | wdev->netdev = ndev; |
309 | return vif; | ||
310 | } | ||
311 | |||
312 | void *wil_if_alloc(struct device *dev) | ||
313 | { | ||
314 | struct wil6210_priv *wil; | ||
315 | struct wil6210_vif *vif; | ||
316 | int rc = 0; | ||
317 | |||
318 | wil = wil_cfg80211_init(dev); | ||
319 | if (IS_ERR(wil)) { | ||
320 | dev_err(dev, "wil_cfg80211_init failed\n"); | ||
321 | return wil; | ||
322 | } | ||
323 | |||
324 | rc = wil_priv_init(wil); | ||
325 | if (rc) { | ||
326 | dev_err(dev, "wil_priv_init failed\n"); | ||
327 | goto out_cfg; | ||
328 | } | ||
329 | |||
330 | wil_dbg_misc(wil, "if_alloc\n"); | ||
331 | |||
332 | vif = wil_vif_alloc(wil, "wlan%d", NET_NAME_UNKNOWN, | ||
333 | NL80211_IFTYPE_STATION); | ||
334 | if (IS_ERR(vif)) { | ||
335 | dev_err(dev, "wil_vif_alloc failed\n"); | ||
336 | rc = -ENOMEM; | ||
337 | goto out_priv; | ||
338 | } | ||
339 | |||
340 | wil->radio_wdev = vif_to_wdev(vif); | ||
173 | 341 | ||
174 | return wil; | 342 | return wil; |
175 | 343 | ||
176 | out_priv: | 344 | out_priv: |
177 | wil_priv_deinit(wil); | 345 | wil_priv_deinit(wil); |
178 | 346 | ||
179 | out_wdev: | 347 | out_cfg: |
180 | wil_wdev_free(wil); | 348 | wil_cfg80211_deinit(wil); |
181 | 349 | ||
182 | return ERR_PTR(rc); | 350 | return ERR_PTR(rc); |
183 | } | 351 | } |
184 | 352 | ||
185 | void wil_if_free(struct wil6210_priv *wil) | 353 | void wil_if_free(struct wil6210_priv *wil) |
186 | { | 354 | { |
187 | struct net_device *ndev = wil_to_ndev(wil); | 355 | struct net_device *ndev = wil->main_ndev; |
188 | 356 | ||
189 | wil_dbg_misc(wil, "if_free\n"); | 357 | wil_dbg_misc(wil, "if_free\n"); |
190 | 358 | ||
@@ -193,17 +361,50 @@ void wil_if_free(struct wil6210_priv *wil) | |||
193 | 361 | ||
194 | wil_priv_deinit(wil); | 362 | wil_priv_deinit(wil); |
195 | 363 | ||
196 | wil_to_ndev(wil) = NULL; | 364 | wil->main_ndev = NULL; |
365 | wil_ndev_destructor(ndev); | ||
197 | free_netdev(ndev); | 366 | free_netdev(ndev); |
198 | 367 | ||
199 | wil_wdev_free(wil); | 368 | wil_cfg80211_deinit(wil); |
369 | } | ||
370 | |||
371 | int wil_vif_add(struct wil6210_priv *wil, struct wil6210_vif *vif) | ||
372 | { | ||
373 | struct net_device *ndev = vif_to_ndev(vif); | ||
374 | struct wireless_dev *wdev = vif_to_wdev(vif); | ||
375 | bool any_active = wil_has_active_ifaces(wil, true, false); | ||
376 | int rc; | ||
377 | |||
378 | ASSERT_RTNL(); | ||
379 | |||
380 | if (wil->vifs[vif->mid]) { | ||
381 | dev_err(&ndev->dev, "VIF with mid %d already in use\n", | ||
382 | vif->mid); | ||
383 | return -EEXIST; | ||
384 | } | ||
385 | if (any_active && vif->mid != 0) { | ||
386 | rc = wmi_port_allocate(wil, vif->mid, ndev->dev_addr, | ||
387 | wdev->iftype); | ||
388 | if (rc) | ||
389 | return rc; | ||
390 | } | ||
391 | rc = register_netdevice(ndev); | ||
392 | if (rc < 0) { | ||
393 | dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc); | ||
394 | if (any_active && vif->mid != 0) | ||
395 | wmi_port_delete(wil, vif->mid); | ||
396 | return rc; | ||
397 | } | ||
398 | |||
399 | wil->vifs[vif->mid] = vif; | ||
400 | return 0; | ||
200 | } | 401 | } |
201 | 402 | ||
202 | int wil_if_add(struct wil6210_priv *wil) | 403 | int wil_if_add(struct wil6210_priv *wil) |
203 | { | 404 | { |
204 | struct wireless_dev *wdev = wil_to_wdev(wil); | 405 | struct wiphy *wiphy = wil->wiphy; |
205 | struct wiphy *wiphy = wdev->wiphy; | 406 | struct net_device *ndev = wil->main_ndev; |
206 | struct net_device *ndev = wil_to_ndev(wil); | 407 | struct wil6210_vif *vif = ndev_to_vif(ndev); |
207 | int rc; | 408 | int rc; |
208 | 409 | ||
209 | wil_dbg_misc(wil, "entered"); | 410 | wil_dbg_misc(wil, "entered"); |
@@ -216,33 +417,94 @@ int wil_if_add(struct wil6210_priv *wil) | |||
216 | return rc; | 417 | return rc; |
217 | } | 418 | } |
218 | 419 | ||
219 | netif_napi_add(ndev, &wil->napi_rx, wil6210_netdev_poll_rx, | 420 | init_dummy_netdev(&wil->napi_ndev); |
421 | netif_napi_add(&wil->napi_ndev, &wil->napi_rx, wil6210_netdev_poll_rx, | ||
220 | WIL6210_NAPI_BUDGET); | 422 | WIL6210_NAPI_BUDGET); |
221 | netif_tx_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx, | 423 | netif_tx_napi_add(&wil->napi_ndev, |
424 | &wil->napi_tx, wil6210_netdev_poll_tx, | ||
222 | WIL6210_NAPI_BUDGET); | 425 | WIL6210_NAPI_BUDGET); |
223 | 426 | ||
224 | wil_update_net_queues_bh(wil, NULL, true); | 427 | wil_update_net_queues_bh(wil, vif, NULL, true); |
225 | 428 | ||
226 | rc = register_netdev(ndev); | 429 | rtnl_lock(); |
227 | if (rc < 0) { | 430 | rc = wil_vif_add(wil, vif); |
228 | dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc); | 431 | rtnl_unlock(); |
432 | if (rc < 0) | ||
229 | goto out_wiphy; | 433 | goto out_wiphy; |
230 | } | ||
231 | 434 | ||
232 | return 0; | 435 | return 0; |
233 | 436 | ||
234 | out_wiphy: | 437 | out_wiphy: |
235 | wiphy_unregister(wdev->wiphy); | 438 | wiphy_unregister(wiphy); |
236 | return rc; | 439 | return rc; |
237 | } | 440 | } |
238 | 441 | ||
442 | void wil_vif_remove(struct wil6210_priv *wil, u8 mid) | ||
443 | { | ||
444 | struct wil6210_vif *vif; | ||
445 | struct net_device *ndev; | ||
446 | bool any_active = wil_has_active_ifaces(wil, true, false); | ||
447 | |||
448 | ASSERT_RTNL(); | ||
449 | if (mid >= wil->max_vifs) { | ||
450 | wil_err(wil, "invalid MID: %d\n", mid); | ||
451 | return; | ||
452 | } | ||
453 | |||
454 | vif = wil->vifs[mid]; | ||
455 | if (!vif) { | ||
456 | wil_err(wil, "MID %d not registered\n", mid); | ||
457 | return; | ||
458 | } | ||
459 | |||
460 | ndev = vif_to_ndev(vif); | ||
461 | /* during unregister_netdevice cfg80211_leave may perform operations | ||
462 | * such as stop AP, disconnect, so we only clear the VIF afterwards | ||
463 | */ | ||
464 | unregister_netdevice(ndev); | ||
465 | |||
466 | mutex_lock(&wil->mutex); | ||
467 | wil6210_disconnect(vif, NULL, WLAN_REASON_DEAUTH_LEAVING, false); | ||
468 | mutex_unlock(&wil->mutex); | ||
469 | |||
470 | if (any_active && vif->mid != 0) | ||
471 | wmi_port_delete(wil, vif->mid); | ||
472 | |||
473 | /* make sure no one is accessing the VIF before removing */ | ||
474 | mutex_lock(&wil->vif_mutex); | ||
475 | wil->vifs[mid] = NULL; | ||
476 | /* ensure NAPI code will see the NULL VIF */ | ||
477 | wmb(); | ||
478 | if (test_bit(wil_status_napi_en, wil->status)) { | ||
479 | napi_synchronize(&wil->napi_rx); | ||
480 | napi_synchronize(&wil->napi_tx); | ||
481 | } | ||
482 | mutex_unlock(&wil->vif_mutex); | ||
483 | |||
484 | flush_work(&wil->wmi_event_worker); | ||
485 | del_timer_sync(&vif->connect_timer); | ||
486 | cancel_work_sync(&vif->disconnect_worker); | ||
487 | wil_probe_client_flush(vif); | ||
488 | cancel_work_sync(&vif->probe_client_worker); | ||
489 | /* for VIFs, ndev will be freed by destructor after RTNL is unlocked. | ||
490 | * the main interface will be freed in wil_if_free, we need to keep it | ||
491 | * a bit longer so logging macros will work. | ||
492 | */ | ||
493 | } | ||
494 | |||
239 | void wil_if_remove(struct wil6210_priv *wil) | 495 | void wil_if_remove(struct wil6210_priv *wil) |
240 | { | 496 | { |
241 | struct net_device *ndev = wil_to_ndev(wil); | 497 | struct net_device *ndev = wil->main_ndev; |
242 | struct wireless_dev *wdev = wil_to_wdev(wil); | 498 | struct wireless_dev *wdev = ndev->ieee80211_ptr; |
243 | 499 | ||
244 | wil_dbg_misc(wil, "if_remove\n"); | 500 | wil_dbg_misc(wil, "if_remove\n"); |
245 | 501 | ||
246 | unregister_netdev(ndev); | 502 | rtnl_lock(); |
503 | wil_vif_remove(wil, 0); | ||
504 | rtnl_unlock(); | ||
505 | |||
506 | netif_napi_del(&wil->napi_tx); | ||
507 | netif_napi_del(&wil->napi_rx); | ||
508 | |||
247 | wiphy_unregister(wdev->wiphy); | 509 | wiphy_unregister(wdev->wiphy); |
248 | } | 510 | } |
diff --git a/drivers/net/wireless/ath/wil6210/p2p.c b/drivers/net/wireless/ath/wil6210/p2p.c index 7dbee2c3e482..db087ea58ddf 100644 --- a/drivers/net/wireless/ath/wil6210/p2p.c +++ b/drivers/net/wireless/ath/wil6210/p2p.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -22,27 +23,28 @@ | |||
22 | #define P2P_SEARCH_DURATION_MS 500 | 23 | #define P2P_SEARCH_DURATION_MS 500 |
23 | #define P2P_DEFAULT_BI 100 | 24 | #define P2P_DEFAULT_BI 100 |
24 | 25 | ||
25 | static int wil_p2p_start_listen(struct wil6210_priv *wil) | 26 | static int wil_p2p_start_listen(struct wil6210_vif *vif) |
26 | { | 27 | { |
27 | struct wil_p2p_info *p2p = &wil->p2p; | 28 | struct wil6210_priv *wil = vif_to_wil(vif); |
29 | struct wil_p2p_info *p2p = &vif->p2p; | ||
28 | u8 channel = p2p->listen_chan.hw_value; | 30 | u8 channel = p2p->listen_chan.hw_value; |
29 | int rc; | 31 | int rc; |
30 | 32 | ||
31 | lockdep_assert_held(&wil->mutex); | 33 | lockdep_assert_held(&wil->mutex); |
32 | 34 | ||
33 | rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI); | 35 | rc = wmi_p2p_cfg(vif, channel, P2P_DEFAULT_BI); |
34 | if (rc) { | 36 | if (rc) { |
35 | wil_err(wil, "wmi_p2p_cfg failed\n"); | 37 | wil_err(wil, "wmi_p2p_cfg failed\n"); |
36 | goto out; | 38 | goto out; |
37 | } | 39 | } |
38 | 40 | ||
39 | rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID); | 41 | rc = wmi_set_ssid(vif, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID); |
40 | if (rc) { | 42 | if (rc) { |
41 | wil_err(wil, "wmi_set_ssid failed\n"); | 43 | wil_err(wil, "wmi_set_ssid failed\n"); |
42 | goto out_stop; | 44 | goto out_stop; |
43 | } | 45 | } |
44 | 46 | ||
45 | rc = wmi_start_listen(wil); | 47 | rc = wmi_start_listen(vif); |
46 | if (rc) { | 48 | if (rc) { |
47 | wil_err(wil, "wmi_start_listen failed\n"); | 49 | wil_err(wil, "wmi_start_listen failed\n"); |
48 | goto out_stop; | 50 | goto out_stop; |
@@ -53,7 +55,7 @@ static int wil_p2p_start_listen(struct wil6210_priv *wil) | |||
53 | jiffies + msecs_to_jiffies(p2p->listen_duration)); | 55 | jiffies + msecs_to_jiffies(p2p->listen_duration)); |
54 | out_stop: | 56 | out_stop: |
55 | if (rc) | 57 | if (rc) |
56 | wmi_stop_discovery(wil); | 58 | wmi_stop_discovery(vif); |
57 | 59 | ||
58 | out: | 60 | out: |
59 | return rc; | 61 | return rc; |
@@ -65,20 +67,12 @@ bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request) | |||
65 | (request->channels[0]->hw_value == P2P_DMG_SOCIAL_CHANNEL); | 67 | (request->channels[0]->hw_value == P2P_DMG_SOCIAL_CHANNEL); |
66 | } | 68 | } |
67 | 69 | ||
68 | void wil_p2p_discovery_timer_fn(struct timer_list *t) | 70 | int wil_p2p_search(struct wil6210_vif *vif, |
69 | { | ||
70 | struct wil6210_priv *wil = from_timer(wil, t, p2p.discovery_timer); | ||
71 | |||
72 | wil_dbg_misc(wil, "p2p_discovery_timer_fn\n"); | ||
73 | |||
74 | schedule_work(&wil->p2p.discovery_expired_work); | ||
75 | } | ||
76 | |||
77 | int wil_p2p_search(struct wil6210_priv *wil, | ||
78 | struct cfg80211_scan_request *request) | 71 | struct cfg80211_scan_request *request) |
79 | { | 72 | { |
73 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
80 | int rc; | 74 | int rc; |
81 | struct wil_p2p_info *p2p = &wil->p2p; | 75 | struct wil_p2p_info *p2p = &vif->p2p; |
82 | 76 | ||
83 | wil_dbg_misc(wil, "p2p_search: channel %d\n", P2P_DMG_SOCIAL_CHANNEL); | 77 | wil_dbg_misc(wil, "p2p_search: channel %d\n", P2P_DMG_SOCIAL_CHANNEL); |
84 | 78 | ||
@@ -90,20 +84,20 @@ int wil_p2p_search(struct wil6210_priv *wil, | |||
90 | goto out; | 84 | goto out; |
91 | } | 85 | } |
92 | 86 | ||
93 | rc = wmi_p2p_cfg(wil, P2P_DMG_SOCIAL_CHANNEL, P2P_DEFAULT_BI); | 87 | rc = wmi_p2p_cfg(vif, P2P_DMG_SOCIAL_CHANNEL, P2P_DEFAULT_BI); |
94 | if (rc) { | 88 | if (rc) { |
95 | wil_err(wil, "wmi_p2p_cfg failed\n"); | 89 | wil_err(wil, "wmi_p2p_cfg failed\n"); |
96 | goto out; | 90 | goto out; |
97 | } | 91 | } |
98 | 92 | ||
99 | rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID); | 93 | rc = wmi_set_ssid(vif, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID); |
100 | if (rc) { | 94 | if (rc) { |
101 | wil_err(wil, "wmi_set_ssid failed\n"); | 95 | wil_err(wil, "wmi_set_ssid failed\n"); |
102 | goto out_stop; | 96 | goto out_stop; |
103 | } | 97 | } |
104 | 98 | ||
105 | /* Set application IE to probe request and probe response */ | 99 | /* Set application IE to probe request and probe response */ |
106 | rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, | 100 | rc = wmi_set_ie(vif, WMI_FRAME_PROBE_REQ, |
107 | request->ie_len, request->ie); | 101 | request->ie_len, request->ie); |
108 | if (rc) { | 102 | if (rc) { |
109 | wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n"); | 103 | wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n"); |
@@ -113,14 +107,14 @@ int wil_p2p_search(struct wil6210_priv *wil, | |||
113 | /* supplicant doesn't provide Probe Response IEs. As a workaround - | 107 | /* supplicant doesn't provide Probe Response IEs. As a workaround - |
114 | * re-use Probe Request IEs | 108 | * re-use Probe Request IEs |
115 | */ | 109 | */ |
116 | rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, | 110 | rc = wmi_set_ie(vif, WMI_FRAME_PROBE_RESP, |
117 | request->ie_len, request->ie); | 111 | request->ie_len, request->ie); |
118 | if (rc) { | 112 | if (rc) { |
119 | wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n"); | 113 | wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n"); |
120 | goto out_stop; | 114 | goto out_stop; |
121 | } | 115 | } |
122 | 116 | ||
123 | rc = wmi_start_search(wil); | 117 | rc = wmi_start_search(vif); |
124 | if (rc) { | 118 | if (rc) { |
125 | wil_err(wil, "wmi_start_search failed\n"); | 119 | wil_err(wil, "wmi_start_search failed\n"); |
126 | goto out_stop; | 120 | goto out_stop; |
@@ -133,7 +127,7 @@ int wil_p2p_search(struct wil6210_priv *wil, | |||
133 | 127 | ||
134 | out_stop: | 128 | out_stop: |
135 | if (rc) | 129 | if (rc) |
136 | wmi_stop_discovery(wil); | 130 | wmi_stop_discovery(vif); |
137 | 131 | ||
138 | out: | 132 | out: |
139 | return rc; | 133 | return rc; |
@@ -143,7 +137,8 @@ int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev, | |||
143 | unsigned int duration, struct ieee80211_channel *chan, | 137 | unsigned int duration, struct ieee80211_channel *chan, |
144 | u64 *cookie) | 138 | u64 *cookie) |
145 | { | 139 | { |
146 | struct wil_p2p_info *p2p = &wil->p2p; | 140 | struct wil6210_vif *vif = wdev_to_vif(wil, wdev); |
141 | struct wil_p2p_info *p2p = &vif->p2p; | ||
147 | int rc; | 142 | int rc; |
148 | 143 | ||
149 | if (!chan) | 144 | if (!chan) |
@@ -163,23 +158,24 @@ int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev, | |||
163 | *cookie = ++p2p->cookie; | 158 | *cookie = ++p2p->cookie; |
164 | p2p->listen_duration = duration; | 159 | p2p->listen_duration = duration; |
165 | 160 | ||
166 | mutex_lock(&wil->p2p_wdev_mutex); | 161 | mutex_lock(&wil->vif_mutex); |
167 | if (wil->scan_request) { | 162 | if (vif->scan_request) { |
168 | wil_dbg_misc(wil, "Delaying p2p listen until scan done\n"); | 163 | wil_dbg_misc(wil, "Delaying p2p listen until scan done\n"); |
169 | p2p->pending_listen_wdev = wdev; | 164 | p2p->pending_listen_wdev = wdev; |
170 | p2p->discovery_started = 1; | 165 | p2p->discovery_started = 1; |
171 | rc = 0; | 166 | rc = 0; |
172 | mutex_unlock(&wil->p2p_wdev_mutex); | 167 | mutex_unlock(&wil->vif_mutex); |
173 | goto out; | 168 | goto out; |
174 | } | 169 | } |
175 | mutex_unlock(&wil->p2p_wdev_mutex); | 170 | mutex_unlock(&wil->vif_mutex); |
176 | 171 | ||
177 | rc = wil_p2p_start_listen(wil); | 172 | rc = wil_p2p_start_listen(vif); |
178 | if (rc) | 173 | if (rc) |
179 | goto out; | 174 | goto out; |
180 | 175 | ||
181 | p2p->discovery_started = 1; | 176 | p2p->discovery_started = 1; |
182 | wil->radio_wdev = wdev; | 177 | if (vif->mid == 0) |
178 | wil->radio_wdev = wdev; | ||
183 | 179 | ||
184 | cfg80211_ready_on_channel(wdev, *cookie, chan, duration, | 180 | cfg80211_ready_on_channel(wdev, *cookie, chan, duration, |
185 | GFP_KERNEL); | 181 | GFP_KERNEL); |
@@ -189,9 +185,9 @@ out: | |||
189 | return rc; | 185 | return rc; |
190 | } | 186 | } |
191 | 187 | ||
192 | u8 wil_p2p_stop_discovery(struct wil6210_priv *wil) | 188 | u8 wil_p2p_stop_discovery(struct wil6210_vif *vif) |
193 | { | 189 | { |
194 | struct wil_p2p_info *p2p = &wil->p2p; | 190 | struct wil_p2p_info *p2p = &vif->p2p; |
195 | u8 started = p2p->discovery_started; | 191 | u8 started = p2p->discovery_started; |
196 | 192 | ||
197 | if (p2p->discovery_started) { | 193 | if (p2p->discovery_started) { |
@@ -200,7 +196,7 @@ u8 wil_p2p_stop_discovery(struct wil6210_priv *wil) | |||
200 | p2p->pending_listen_wdev = NULL; | 196 | p2p->pending_listen_wdev = NULL; |
201 | } else { | 197 | } else { |
202 | del_timer_sync(&p2p->discovery_timer); | 198 | del_timer_sync(&p2p->discovery_timer); |
203 | wmi_stop_discovery(wil); | 199 | wmi_stop_discovery(vif); |
204 | } | 200 | } |
205 | p2p->discovery_started = 0; | 201 | p2p->discovery_started = 0; |
206 | } | 202 | } |
@@ -208,9 +204,10 @@ u8 wil_p2p_stop_discovery(struct wil6210_priv *wil) | |||
208 | return started; | 204 | return started; |
209 | } | 205 | } |
210 | 206 | ||
211 | int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie) | 207 | int wil_p2p_cancel_listen(struct wil6210_vif *vif, u64 cookie) |
212 | { | 208 | { |
213 | struct wil_p2p_info *p2p = &wil->p2p; | 209 | struct wil6210_priv *wil = vif_to_wil(vif); |
210 | struct wil_p2p_info *p2p = &vif->p2p; | ||
214 | u8 started; | 211 | u8 started; |
215 | 212 | ||
216 | mutex_lock(&wil->mutex); | 213 | mutex_lock(&wil->mutex); |
@@ -222,7 +219,7 @@ int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie) | |||
222 | return -ENOENT; | 219 | return -ENOENT; |
223 | } | 220 | } |
224 | 221 | ||
225 | started = wil_p2p_stop_discovery(wil); | 222 | started = wil_p2p_stop_discovery(vif); |
226 | 223 | ||
227 | mutex_unlock(&wil->mutex); | 224 | mutex_unlock(&wil->mutex); |
228 | 225 | ||
@@ -231,13 +228,14 @@ int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie) | |||
231 | return -ENOENT; | 228 | return -ENOENT; |
232 | } | 229 | } |
233 | 230 | ||
234 | mutex_lock(&wil->p2p_wdev_mutex); | 231 | mutex_lock(&wil->vif_mutex); |
235 | cfg80211_remain_on_channel_expired(wil->radio_wdev, | 232 | cfg80211_remain_on_channel_expired(vif_to_radio_wdev(wil, vif), |
236 | p2p->cookie, | 233 | p2p->cookie, |
237 | &p2p->listen_chan, | 234 | &p2p->listen_chan, |
238 | GFP_KERNEL); | 235 | GFP_KERNEL); |
239 | wil->radio_wdev = wil->wdev; | 236 | if (vif->mid == 0) |
240 | mutex_unlock(&wil->p2p_wdev_mutex); | 237 | wil->radio_wdev = wil->main_ndev->ieee80211_ptr; |
238 | mutex_unlock(&wil->vif_mutex); | ||
241 | return 0; | 239 | return 0; |
242 | } | 240 | } |
243 | 241 | ||
@@ -245,40 +243,43 @@ void wil_p2p_listen_expired(struct work_struct *work) | |||
245 | { | 243 | { |
246 | struct wil_p2p_info *p2p = container_of(work, | 244 | struct wil_p2p_info *p2p = container_of(work, |
247 | struct wil_p2p_info, discovery_expired_work); | 245 | struct wil_p2p_info, discovery_expired_work); |
248 | struct wil6210_priv *wil = container_of(p2p, | 246 | struct wil6210_vif *vif = container_of(p2p, |
249 | struct wil6210_priv, p2p); | 247 | struct wil6210_vif, p2p); |
248 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
250 | u8 started; | 249 | u8 started; |
251 | 250 | ||
252 | wil_dbg_misc(wil, "p2p_listen_expired\n"); | 251 | wil_dbg_misc(wil, "p2p_listen_expired\n"); |
253 | 252 | ||
254 | mutex_lock(&wil->mutex); | 253 | mutex_lock(&wil->mutex); |
255 | started = wil_p2p_stop_discovery(wil); | 254 | started = wil_p2p_stop_discovery(vif); |
256 | mutex_unlock(&wil->mutex); | 255 | mutex_unlock(&wil->mutex); |
257 | 256 | ||
258 | if (started) { | 257 | if (!started) |
259 | mutex_lock(&wil->p2p_wdev_mutex); | 258 | return; |
260 | cfg80211_remain_on_channel_expired(wil->radio_wdev, | ||
261 | p2p->cookie, | ||
262 | &p2p->listen_chan, | ||
263 | GFP_KERNEL); | ||
264 | wil->radio_wdev = wil->wdev; | ||
265 | mutex_unlock(&wil->p2p_wdev_mutex); | ||
266 | } | ||
267 | 259 | ||
260 | mutex_lock(&wil->vif_mutex); | ||
261 | cfg80211_remain_on_channel_expired(vif_to_radio_wdev(wil, vif), | ||
262 | p2p->cookie, | ||
263 | &p2p->listen_chan, | ||
264 | GFP_KERNEL); | ||
265 | if (vif->mid == 0) | ||
266 | wil->radio_wdev = wil->main_ndev->ieee80211_ptr; | ||
267 | mutex_unlock(&wil->vif_mutex); | ||
268 | } | 268 | } |
269 | 269 | ||
270 | void wil_p2p_search_expired(struct work_struct *work) | 270 | void wil_p2p_search_expired(struct work_struct *work) |
271 | { | 271 | { |
272 | struct wil_p2p_info *p2p = container_of(work, | 272 | struct wil_p2p_info *p2p = container_of(work, |
273 | struct wil_p2p_info, discovery_expired_work); | 273 | struct wil_p2p_info, discovery_expired_work); |
274 | struct wil6210_priv *wil = container_of(p2p, | 274 | struct wil6210_vif *vif = container_of(p2p, |
275 | struct wil6210_priv, p2p); | 275 | struct wil6210_vif, p2p); |
276 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
276 | u8 started; | 277 | u8 started; |
277 | 278 | ||
278 | wil_dbg_misc(wil, "p2p_search_expired\n"); | 279 | wil_dbg_misc(wil, "p2p_search_expired\n"); |
279 | 280 | ||
280 | mutex_lock(&wil->mutex); | 281 | mutex_lock(&wil->mutex); |
281 | started = wil_p2p_stop_discovery(wil); | 282 | started = wil_p2p_stop_discovery(vif); |
282 | mutex_unlock(&wil->mutex); | 283 | mutex_unlock(&wil->mutex); |
283 | 284 | ||
284 | if (started) { | 285 | if (started) { |
@@ -286,13 +287,15 @@ void wil_p2p_search_expired(struct work_struct *work) | |||
286 | .aborted = false, | 287 | .aborted = false, |
287 | }; | 288 | }; |
288 | 289 | ||
289 | mutex_lock(&wil->p2p_wdev_mutex); | 290 | mutex_lock(&wil->vif_mutex); |
290 | if (wil->scan_request) { | 291 | if (vif->scan_request) { |
291 | cfg80211_scan_done(wil->scan_request, &info); | 292 | cfg80211_scan_done(vif->scan_request, &info); |
292 | wil->scan_request = NULL; | 293 | vif->scan_request = NULL; |
293 | wil->radio_wdev = wil->wdev; | 294 | if (vif->mid == 0) |
295 | wil->radio_wdev = | ||
296 | wil->main_ndev->ieee80211_ptr; | ||
294 | } | 297 | } |
295 | mutex_unlock(&wil->p2p_wdev_mutex); | 298 | mutex_unlock(&wil->vif_mutex); |
296 | } | 299 | } |
297 | } | 300 | } |
298 | 301 | ||
@@ -300,8 +303,9 @@ void wil_p2p_delayed_listen_work(struct work_struct *work) | |||
300 | { | 303 | { |
301 | struct wil_p2p_info *p2p = container_of(work, | 304 | struct wil_p2p_info *p2p = container_of(work, |
302 | struct wil_p2p_info, delayed_listen_work); | 305 | struct wil_p2p_info, delayed_listen_work); |
303 | struct wil6210_priv *wil = container_of(p2p, | 306 | struct wil6210_vif *vif = container_of(p2p, |
304 | struct wil6210_priv, p2p); | 307 | struct wil6210_vif, p2p); |
308 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
305 | int rc; | 309 | int rc; |
306 | 310 | ||
307 | mutex_lock(&wil->mutex); | 311 | mutex_lock(&wil->mutex); |
@@ -310,31 +314,33 @@ void wil_p2p_delayed_listen_work(struct work_struct *work) | |||
310 | if (!p2p->discovery_started || !p2p->pending_listen_wdev) | 314 | if (!p2p->discovery_started || !p2p->pending_listen_wdev) |
311 | goto out; | 315 | goto out; |
312 | 316 | ||
313 | mutex_lock(&wil->p2p_wdev_mutex); | 317 | mutex_lock(&wil->vif_mutex); |
314 | if (wil->scan_request) { | 318 | if (vif->scan_request) { |
315 | /* another scan started, wait again... */ | 319 | /* another scan started, wait again... */ |
316 | mutex_unlock(&wil->p2p_wdev_mutex); | 320 | mutex_unlock(&wil->vif_mutex); |
317 | goto out; | 321 | goto out; |
318 | } | 322 | } |
319 | mutex_unlock(&wil->p2p_wdev_mutex); | 323 | mutex_unlock(&wil->vif_mutex); |
320 | 324 | ||
321 | rc = wil_p2p_start_listen(wil); | 325 | rc = wil_p2p_start_listen(vif); |
322 | 326 | ||
323 | mutex_lock(&wil->p2p_wdev_mutex); | 327 | mutex_lock(&wil->vif_mutex); |
324 | if (rc) { | 328 | if (rc) { |
325 | cfg80211_remain_on_channel_expired(p2p->pending_listen_wdev, | 329 | cfg80211_remain_on_channel_expired(p2p->pending_listen_wdev, |
326 | p2p->cookie, | 330 | p2p->cookie, |
327 | &p2p->listen_chan, | 331 | &p2p->listen_chan, |
328 | GFP_KERNEL); | 332 | GFP_KERNEL); |
329 | wil->radio_wdev = wil->wdev; | 333 | if (vif->mid == 0) |
334 | wil->radio_wdev = wil->main_ndev->ieee80211_ptr; | ||
330 | } else { | 335 | } else { |
331 | cfg80211_ready_on_channel(p2p->pending_listen_wdev, p2p->cookie, | 336 | cfg80211_ready_on_channel(p2p->pending_listen_wdev, p2p->cookie, |
332 | &p2p->listen_chan, | 337 | &p2p->listen_chan, |
333 | p2p->listen_duration, GFP_KERNEL); | 338 | p2p->listen_duration, GFP_KERNEL); |
334 | wil->radio_wdev = p2p->pending_listen_wdev; | 339 | if (vif->mid == 0) |
340 | wil->radio_wdev = p2p->pending_listen_wdev; | ||
335 | } | 341 | } |
336 | p2p->pending_listen_wdev = NULL; | 342 | p2p->pending_listen_wdev = NULL; |
337 | mutex_unlock(&wil->p2p_wdev_mutex); | 343 | mutex_unlock(&wil->vif_mutex); |
338 | 344 | ||
339 | out: | 345 | out: |
340 | mutex_unlock(&wil->mutex); | 346 | mutex_unlock(&wil->mutex); |
@@ -342,34 +348,35 @@ out: | |||
342 | 348 | ||
343 | void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) | 349 | void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) |
344 | { | 350 | { |
345 | struct wil_p2p_info *p2p = &wil->p2p; | 351 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); |
352 | struct wil_p2p_info *p2p = &vif->p2p; | ||
346 | struct cfg80211_scan_info info = { | 353 | struct cfg80211_scan_info info = { |
347 | .aborted = true, | 354 | .aborted = true, |
348 | }; | 355 | }; |
349 | 356 | ||
350 | lockdep_assert_held(&wil->mutex); | 357 | lockdep_assert_held(&wil->mutex); |
351 | lockdep_assert_held(&wil->p2p_wdev_mutex); | 358 | lockdep_assert_held(&wil->vif_mutex); |
352 | 359 | ||
353 | if (wil->radio_wdev != wil->p2p_wdev) | 360 | if (wil->radio_wdev != wil->p2p_wdev) |
354 | goto out; | 361 | goto out; |
355 | 362 | ||
356 | if (!p2p->discovery_started) { | 363 | if (!p2p->discovery_started) { |
357 | /* Regular scan on the p2p device */ | 364 | /* Regular scan on the p2p device */ |
358 | if (wil->scan_request && | 365 | if (vif->scan_request && |
359 | wil->scan_request->wdev == wil->p2p_wdev) | 366 | vif->scan_request->wdev == wil->p2p_wdev) |
360 | wil_abort_scan(wil, true); | 367 | wil_abort_scan(vif, true); |
361 | goto out; | 368 | goto out; |
362 | } | 369 | } |
363 | 370 | ||
364 | /* Search or listen on p2p device */ | 371 | /* Search or listen on p2p device */ |
365 | mutex_unlock(&wil->p2p_wdev_mutex); | 372 | mutex_unlock(&wil->vif_mutex); |
366 | wil_p2p_stop_discovery(wil); | 373 | wil_p2p_stop_discovery(vif); |
367 | mutex_lock(&wil->p2p_wdev_mutex); | 374 | mutex_lock(&wil->vif_mutex); |
368 | 375 | ||
369 | if (wil->scan_request) { | 376 | if (vif->scan_request) { |
370 | /* search */ | 377 | /* search */ |
371 | cfg80211_scan_done(wil->scan_request, &info); | 378 | cfg80211_scan_done(vif->scan_request, &info); |
372 | wil->scan_request = NULL; | 379 | vif->scan_request = NULL; |
373 | } else { | 380 | } else { |
374 | /* listen */ | 381 | /* listen */ |
375 | cfg80211_remain_on_channel_expired(wil->radio_wdev, | 382 | cfg80211_remain_on_channel_expired(wil->radio_wdev, |
@@ -379,5 +386,5 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) | |||
379 | } | 386 | } |
380 | 387 | ||
381 | out: | 388 | out: |
382 | wil->radio_wdev = wil->wdev; | 389 | wil->radio_wdev = wil->main_ndev->ieee80211_ptr; |
383 | } | 390 | } |
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index 809092a49192..19cbc6add637 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c | |||
@@ -137,6 +137,20 @@ void wil_enable_irq(struct wil6210_priv *wil) | |||
137 | enable_irq(wil->pdev->irq); | 137 | enable_irq(wil->pdev->irq); |
138 | } | 138 | } |
139 | 139 | ||
140 | static void wil_remove_all_additional_vifs(struct wil6210_priv *wil) | ||
141 | { | ||
142 | struct wil6210_vif *vif; | ||
143 | int i; | ||
144 | |||
145 | for (i = 1; i < wil->max_vifs; i++) { | ||
146 | vif = wil->vifs[i]; | ||
147 | if (vif) { | ||
148 | wil_vif_prepare_stop(vif); | ||
149 | wil_vif_remove(wil, vif->mid); | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
140 | /* Bus ops */ | 154 | /* Bus ops */ |
141 | static int wil_if_pcie_enable(struct wil6210_priv *wil) | 155 | static int wil_if_pcie_enable(struct wil6210_priv *wil) |
142 | { | 156 | { |
@@ -148,10 +162,8 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil) | |||
148 | */ | 162 | */ |
149 | int msi_only = pdev->msi_enabled; | 163 | int msi_only = pdev->msi_enabled; |
150 | bool _use_msi = use_msi; | 164 | bool _use_msi = use_msi; |
151 | bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY, | ||
152 | wil->fw_capabilities); | ||
153 | 165 | ||
154 | wil_dbg_misc(wil, "if_pcie_enable, wmi_only %d\n", wmi_only); | 166 | wil_dbg_misc(wil, "if_pcie_enable\n"); |
155 | 167 | ||
156 | pci_set_master(pdev); | 168 | pci_set_master(pdev); |
157 | 169 | ||
@@ -172,11 +184,9 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil) | |||
172 | if (rc) | 184 | if (rc) |
173 | goto stop_master; | 185 | goto stop_master; |
174 | 186 | ||
175 | /* need reset here to obtain MAC or in case of WMI-only FW, full reset | 187 | /* need reset here to obtain MAC */ |
176 | * and fw loading takes place | ||
177 | */ | ||
178 | mutex_lock(&wil->mutex); | 188 | mutex_lock(&wil->mutex); |
179 | rc = wil_reset(wil, wmi_only); | 189 | rc = wil_reset(wil, false); |
180 | mutex_unlock(&wil->mutex); | 190 | mutex_unlock(&wil->mutex); |
181 | if (rc) | 191 | if (rc) |
182 | goto release_irq; | 192 | goto release_irq; |
@@ -356,6 +366,18 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
356 | goto bus_disable; | 366 | goto bus_disable; |
357 | } | 367 | } |
358 | 368 | ||
369 | /* in case of WMI-only FW, perform full reset and FW loading */ | ||
370 | if (test_bit(WMI_FW_CAPABILITY_WMI_ONLY, wil->fw_capabilities)) { | ||
371 | wil_dbg_misc(wil, "Loading WMI only FW\n"); | ||
372 | mutex_lock(&wil->mutex); | ||
373 | rc = wil_reset(wil, true); | ||
374 | mutex_unlock(&wil->mutex); | ||
375 | if (rc) { | ||
376 | wil_err(wil, "failed to load WMI only FW\n"); | ||
377 | goto if_remove; | ||
378 | } | ||
379 | } | ||
380 | |||
359 | if (IS_ENABLED(CONFIG_PM)) | 381 | if (IS_ENABLED(CONFIG_PM)) |
360 | wil->pm_notify.notifier_call = wil6210_pm_notify; | 382 | wil->pm_notify.notifier_call = wil6210_pm_notify; |
361 | 383 | ||
@@ -372,6 +394,8 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
372 | 394 | ||
373 | return 0; | 395 | return 0; |
374 | 396 | ||
397 | if_remove: | ||
398 | wil_if_remove(wil); | ||
375 | bus_disable: | 399 | bus_disable: |
376 | wil_if_pcie_disable(wil); | 400 | wil_if_pcie_disable(wil); |
377 | err_iounmap: | 401 | err_iounmap: |
@@ -402,6 +426,7 @@ static void wil_pcie_remove(struct pci_dev *pdev) | |||
402 | wil6210_debugfs_remove(wil); | 426 | wil6210_debugfs_remove(wil); |
403 | rtnl_lock(); | 427 | rtnl_lock(); |
404 | wil_p2p_wdev_free(wil); | 428 | wil_p2p_wdev_free(wil); |
429 | wil_remove_all_additional_vifs(wil); | ||
405 | rtnl_unlock(); | 430 | rtnl_unlock(); |
406 | wil_if_remove(wil); | 431 | wil_if_remove(wil); |
407 | wil_if_pcie_disable(wil); | 432 | wil_if_pcie_disable(wil); |
@@ -425,12 +450,15 @@ static int wil6210_suspend(struct device *dev, bool is_runtime) | |||
425 | int rc = 0; | 450 | int rc = 0; |
426 | struct pci_dev *pdev = to_pci_dev(dev); | 451 | struct pci_dev *pdev = to_pci_dev(dev); |
427 | struct wil6210_priv *wil = pci_get_drvdata(pdev); | 452 | struct wil6210_priv *wil = pci_get_drvdata(pdev); |
428 | struct net_device *ndev = wil_to_ndev(wil); | 453 | bool keep_radio_on, active_ifaces; |
429 | bool keep_radio_on = ndev->flags & IFF_UP && | ||
430 | wil->keep_radio_on_during_sleep; | ||
431 | 454 | ||
432 | wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system"); | 455 | wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system"); |
433 | 456 | ||
457 | mutex_lock(&wil->vif_mutex); | ||
458 | active_ifaces = wil_has_active_ifaces(wil, true, false); | ||
459 | mutex_unlock(&wil->vif_mutex); | ||
460 | keep_radio_on = active_ifaces && wil->keep_radio_on_during_sleep; | ||
461 | |||
434 | rc = wil_can_suspend(wil, is_runtime); | 462 | rc = wil_can_suspend(wil, is_runtime); |
435 | if (rc) | 463 | if (rc) |
436 | goto out; | 464 | goto out; |
@@ -457,12 +485,15 @@ static int wil6210_resume(struct device *dev, bool is_runtime) | |||
457 | int rc = 0; | 485 | int rc = 0; |
458 | struct pci_dev *pdev = to_pci_dev(dev); | 486 | struct pci_dev *pdev = to_pci_dev(dev); |
459 | struct wil6210_priv *wil = pci_get_drvdata(pdev); | 487 | struct wil6210_priv *wil = pci_get_drvdata(pdev); |
460 | struct net_device *ndev = wil_to_ndev(wil); | 488 | bool keep_radio_on, active_ifaces; |
461 | bool keep_radio_on = ndev->flags & IFF_UP && | ||
462 | wil->keep_radio_on_during_sleep; | ||
463 | 489 | ||
464 | wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system"); | 490 | wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system"); |
465 | 491 | ||
492 | mutex_lock(&wil->vif_mutex); | ||
493 | active_ifaces = wil_has_active_ifaces(wil, true, false); | ||
494 | mutex_unlock(&wil->vif_mutex); | ||
495 | keep_radio_on = active_ifaces && wil->keep_radio_on_during_sleep; | ||
496 | |||
466 | /* In case radio stays on, platform device will control | 497 | /* In case radio stays on, platform device will control |
467 | * PCIe master | 498 | * PCIe master |
468 | */ | 499 | */ |
diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c index 0a96518a566f..ba81fb3ac96f 100644 --- a/drivers/net/wireless/ath/wil6210/pm.c +++ b/drivers/net/wireless/ath/wil6210/pm.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2014,2017 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2014,2017 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -20,13 +21,72 @@ | |||
20 | 21 | ||
21 | #define WIL6210_AUTOSUSPEND_DELAY_MS (1000) | 22 | #define WIL6210_AUTOSUSPEND_DELAY_MS (1000) |
22 | 23 | ||
24 | static void wil_pm_wake_connected_net_queues(struct wil6210_priv *wil) | ||
25 | { | ||
26 | int i; | ||
27 | |||
28 | mutex_lock(&wil->vif_mutex); | ||
29 | for (i = 0; i < wil->max_vifs; i++) { | ||
30 | struct wil6210_vif *vif = wil->vifs[i]; | ||
31 | |||
32 | if (vif && test_bit(wil_vif_fwconnected, vif->status)) | ||
33 | wil_update_net_queues_bh(wil, vif, NULL, false); | ||
34 | } | ||
35 | mutex_unlock(&wil->vif_mutex); | ||
36 | } | ||
37 | |||
38 | static void wil_pm_stop_all_net_queues(struct wil6210_priv *wil) | ||
39 | { | ||
40 | int i; | ||
41 | |||
42 | mutex_lock(&wil->vif_mutex); | ||
43 | for (i = 0; i < wil->max_vifs; i++) { | ||
44 | struct wil6210_vif *vif = wil->vifs[i]; | ||
45 | |||
46 | if (vif) | ||
47 | wil_update_net_queues_bh(wil, vif, NULL, true); | ||
48 | } | ||
49 | mutex_unlock(&wil->vif_mutex); | ||
50 | } | ||
51 | |||
52 | static bool | ||
53 | wil_can_suspend_vif(struct wil6210_priv *wil, struct wil6210_vif *vif, | ||
54 | bool is_runtime) | ||
55 | { | ||
56 | struct wireless_dev *wdev = vif_to_wdev(vif); | ||
57 | |||
58 | switch (wdev->iftype) { | ||
59 | case NL80211_IFTYPE_MONITOR: | ||
60 | wil_dbg_pm(wil, "Sniffer\n"); | ||
61 | return false; | ||
62 | |||
63 | /* for STA-like interface, don't runtime suspend */ | ||
64 | case NL80211_IFTYPE_STATION: | ||
65 | case NL80211_IFTYPE_P2P_CLIENT: | ||
66 | if (test_bit(wil_vif_fwconnecting, vif->status)) { | ||
67 | wil_dbg_pm(wil, "Delay suspend when connecting\n"); | ||
68 | return false; | ||
69 | } | ||
70 | if (is_runtime) { | ||
71 | wil_dbg_pm(wil, "STA-like interface\n"); | ||
72 | return false; | ||
73 | } | ||
74 | break; | ||
75 | /* AP-like interface - can't suspend */ | ||
76 | default: | ||
77 | wil_dbg_pm(wil, "AP-like interface\n"); | ||
78 | return false; | ||
79 | } | ||
80 | |||
81 | return true; | ||
82 | } | ||
83 | |||
23 | int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) | 84 | int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) |
24 | { | 85 | { |
25 | int rc = 0; | 86 | int rc = 0, i; |
26 | struct wireless_dev *wdev = wil->wdev; | ||
27 | struct net_device *ndev = wil_to_ndev(wil); | ||
28 | bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY, | 87 | bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY, |
29 | wil->fw_capabilities); | 88 | wil->fw_capabilities); |
89 | bool active_ifaces; | ||
30 | 90 | ||
31 | wil_dbg_pm(wil, "can_suspend: %s\n", is_runtime ? "runtime" : "system"); | 91 | wil_dbg_pm(wil, "can_suspend: %s\n", is_runtime ? "runtime" : "system"); |
32 | 92 | ||
@@ -40,7 +100,12 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) | |||
40 | rc = -EBUSY; | 100 | rc = -EBUSY; |
41 | goto out; | 101 | goto out; |
42 | } | 102 | } |
43 | if (!(ndev->flags & IFF_UP)) { | 103 | |
104 | mutex_lock(&wil->vif_mutex); | ||
105 | active_ifaces = wil_has_active_ifaces(wil, true, false); | ||
106 | mutex_unlock(&wil->vif_mutex); | ||
107 | |||
108 | if (!active_ifaces) { | ||
44 | /* can always sleep when down */ | 109 | /* can always sleep when down */ |
45 | wil_dbg_pm(wil, "Interface is down\n"); | 110 | wil_dbg_pm(wil, "Interface is down\n"); |
46 | goto out; | 111 | goto out; |
@@ -57,32 +122,19 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) | |||
57 | } | 122 | } |
58 | 123 | ||
59 | /* interface is running */ | 124 | /* interface is running */ |
60 | switch (wdev->iftype) { | 125 | mutex_lock(&wil->vif_mutex); |
61 | case NL80211_IFTYPE_MONITOR: | 126 | for (i = 0; i < wil->max_vifs; i++) { |
62 | wil_dbg_pm(wil, "Sniffer\n"); | 127 | struct wil6210_vif *vif = wil->vifs[i]; |
63 | rc = -EBUSY; | 128 | |
64 | goto out; | 129 | if (!vif) |
65 | /* for STA-like interface, don't runtime suspend */ | 130 | continue; |
66 | case NL80211_IFTYPE_STATION: | 131 | if (!wil_can_suspend_vif(wil, vif, is_runtime)) { |
67 | case NL80211_IFTYPE_P2P_CLIENT: | ||
68 | if (test_bit(wil_status_fwconnecting, wil->status)) { | ||
69 | wil_dbg_pm(wil, "Delay suspend when connecting\n"); | ||
70 | rc = -EBUSY; | ||
71 | goto out; | ||
72 | } | ||
73 | /* Runtime pm not supported in case the interface is up */ | ||
74 | if (is_runtime) { | ||
75 | wil_dbg_pm(wil, "STA-like interface\n"); | ||
76 | rc = -EBUSY; | 132 | rc = -EBUSY; |
133 | mutex_unlock(&wil->vif_mutex); | ||
77 | goto out; | 134 | goto out; |
78 | } | 135 | } |
79 | break; | ||
80 | /* AP-like interface - can't suspend */ | ||
81 | default: | ||
82 | wil_dbg_pm(wil, "AP-like interface\n"); | ||
83 | rc = -EBUSY; | ||
84 | break; | ||
85 | } | 136 | } |
137 | mutex_unlock(&wil->vif_mutex); | ||
86 | 138 | ||
87 | out: | 139 | out: |
88 | wil_dbg_pm(wil, "can_suspend: %s => %s (%d)\n", | 140 | wil_dbg_pm(wil, "can_suspend: %s => %s (%d)\n", |
@@ -127,8 +179,7 @@ static int wil_resume_keep_radio_on(struct wil6210_priv *wil) | |||
127 | } | 179 | } |
128 | 180 | ||
129 | /* Wake all queues */ | 181 | /* Wake all queues */ |
130 | if (test_bit(wil_status_fwconnected, wil->status)) | 182 | wil_pm_wake_connected_net_queues(wil); |
131 | wil_update_net_queues_bh(wil, NULL, false); | ||
132 | 183 | ||
133 | out: | 184 | out: |
134 | if (rc) | 185 | if (rc) |
@@ -152,7 +203,7 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil) | |||
152 | wil->suspend_stats.rejected_by_host++; | 203 | wil->suspend_stats.rejected_by_host++; |
153 | return -EBUSY; | 204 | return -EBUSY; |
154 | } | 205 | } |
155 | wil_update_net_queues_bh(wil, NULL, true); | 206 | wil_pm_stop_all_net_queues(wil); |
156 | 207 | ||
157 | if (!wil_is_tx_idle(wil)) { | 208 | if (!wil_is_tx_idle(wil)) { |
158 | wil_dbg_pm(wil, "Pending TX data, reject suspend\n"); | 209 | wil_dbg_pm(wil, "Pending TX data, reject suspend\n"); |
@@ -243,22 +294,20 @@ resume_after_fail: | |||
243 | /* if resume succeeded, reject the suspend */ | 294 | /* if resume succeeded, reject the suspend */ |
244 | if (!rc) { | 295 | if (!rc) { |
245 | rc = -EBUSY; | 296 | rc = -EBUSY; |
246 | if (test_bit(wil_status_fwconnected, wil->status)) | 297 | wil_pm_wake_connected_net_queues(wil); |
247 | wil_update_net_queues_bh(wil, NULL, false); | ||
248 | } | 298 | } |
249 | return rc; | 299 | return rc; |
250 | 300 | ||
251 | reject_suspend: | 301 | reject_suspend: |
252 | clear_bit(wil_status_suspending, wil->status); | 302 | clear_bit(wil_status_suspending, wil->status); |
253 | if (test_bit(wil_status_fwconnected, wil->status)) | 303 | wil_pm_wake_connected_net_queues(wil); |
254 | wil_update_net_queues_bh(wil, NULL, false); | ||
255 | return -EBUSY; | 304 | return -EBUSY; |
256 | } | 305 | } |
257 | 306 | ||
258 | static int wil_suspend_radio_off(struct wil6210_priv *wil) | 307 | static int wil_suspend_radio_off(struct wil6210_priv *wil) |
259 | { | 308 | { |
260 | int rc = 0; | 309 | int rc = 0; |
261 | struct net_device *ndev = wil_to_ndev(wil); | 310 | bool active_ifaces; |
262 | 311 | ||
263 | wil_dbg_pm(wil, "suspend radio off\n"); | 312 | wil_dbg_pm(wil, "suspend radio off\n"); |
264 | 313 | ||
@@ -272,7 +321,11 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil) | |||
272 | } | 321 | } |
273 | 322 | ||
274 | /* if netif up, hardware is alive, shut it down */ | 323 | /* if netif up, hardware is alive, shut it down */ |
275 | if (ndev->flags & IFF_UP) { | 324 | mutex_lock(&wil->vif_mutex); |
325 | active_ifaces = wil_has_active_ifaces(wil, true, false); | ||
326 | mutex_unlock(&wil->vif_mutex); | ||
327 | |||
328 | if (active_ifaces) { | ||
276 | rc = wil_down(wil); | 329 | rc = wil_down(wil); |
277 | if (rc) { | 330 | if (rc) { |
278 | wil_err(wil, "wil_down : %d\n", rc); | 331 | wil_err(wil, "wil_down : %d\n", rc); |
@@ -306,16 +359,19 @@ out: | |||
306 | static int wil_resume_radio_off(struct wil6210_priv *wil) | 359 | static int wil_resume_radio_off(struct wil6210_priv *wil) |
307 | { | 360 | { |
308 | int rc = 0; | 361 | int rc = 0; |
309 | struct net_device *ndev = wil_to_ndev(wil); | 362 | bool active_ifaces; |
310 | 363 | ||
311 | wil_dbg_pm(wil, "Enabling PCIe IRQ\n"); | 364 | wil_dbg_pm(wil, "Enabling PCIe IRQ\n"); |
312 | wil_enable_irq(wil); | 365 | wil_enable_irq(wil); |
313 | /* if netif up, bring hardware up | 366 | /* if any netif up, bring hardware up |
314 | * During open(), IFF_UP set after actual device method | 367 | * During open(), IFF_UP set after actual device method |
315 | * invocation. This prevent recursive call to wil_up() | 368 | * invocation. This prevent recursive call to wil_up() |
316 | * wil_status_suspended will be cleared in wil_reset | 369 | * wil_status_suspended will be cleared in wil_reset |
317 | */ | 370 | */ |
318 | if (ndev->flags & IFF_UP) | 371 | mutex_lock(&wil->vif_mutex); |
372 | active_ifaces = wil_has_active_ifaces(wil, true, false); | ||
373 | mutex_unlock(&wil->vif_mutex); | ||
374 | if (active_ifaces) | ||
319 | rc = wil_up(wil); | 375 | rc = wil_up(wil); |
320 | else | 376 | else |
321 | clear_bit(wil_status_suspended, wil->status); | 377 | clear_bit(wil_status_suspended, wil->status); |
diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c index 4ea27b0bd278..c49f7988369e 100644 --- a/drivers/net/wireless/ath/wil6210/pmc.c +++ b/drivers/net/wireless/ath/wil6210/pmc.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012-2015,2017 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2015,2017 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -53,6 +54,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil, | |||
53 | u32 i; | 54 | u32 i; |
54 | struct pmc_ctx *pmc = &wil->pmc; | 55 | struct pmc_ctx *pmc = &wil->pmc; |
55 | struct device *dev = wil_to_dev(wil); | 56 | struct device *dev = wil_to_dev(wil); |
57 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
56 | struct wmi_pmc_cmd pmc_cmd = {0}; | 58 | struct wmi_pmc_cmd pmc_cmd = {0}; |
57 | int last_cmd_err = -ENOMEM; | 59 | int last_cmd_err = -ENOMEM; |
58 | 60 | ||
@@ -186,6 +188,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil, | |||
186 | wil_dbg_misc(wil, "pmc_alloc: send WMI_PMC_CMD with ALLOCATE op\n"); | 188 | wil_dbg_misc(wil, "pmc_alloc: send WMI_PMC_CMD with ALLOCATE op\n"); |
187 | pmc->last_cmd_status = wmi_send(wil, | 189 | pmc->last_cmd_status = wmi_send(wil, |
188 | WMI_PMC_CMDID, | 190 | WMI_PMC_CMDID, |
191 | vif->mid, | ||
189 | &pmc_cmd, | 192 | &pmc_cmd, |
190 | sizeof(pmc_cmd)); | 193 | sizeof(pmc_cmd)); |
191 | if (pmc->last_cmd_status) { | 194 | if (pmc->last_cmd_status) { |
@@ -236,6 +239,7 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd) | |||
236 | { | 239 | { |
237 | struct pmc_ctx *pmc = &wil->pmc; | 240 | struct pmc_ctx *pmc = &wil->pmc; |
238 | struct device *dev = wil_to_dev(wil); | 241 | struct device *dev = wil_to_dev(wil); |
242 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
239 | struct wmi_pmc_cmd pmc_cmd = {0}; | 243 | struct wmi_pmc_cmd pmc_cmd = {0}; |
240 | 244 | ||
241 | mutex_lock(&pmc->lock); | 245 | mutex_lock(&pmc->lock); |
@@ -254,8 +258,8 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd) | |||
254 | wil_dbg_misc(wil, "send WMI_PMC_CMD with RELEASE op\n"); | 258 | wil_dbg_misc(wil, "send WMI_PMC_CMD with RELEASE op\n"); |
255 | pmc_cmd.op = WMI_PMC_RELEASE; | 259 | pmc_cmd.op = WMI_PMC_RELEASE; |
256 | pmc->last_cmd_status = | 260 | pmc->last_cmd_status = |
257 | wmi_send(wil, WMI_PMC_CMDID, &pmc_cmd, | 261 | wmi_send(wil, WMI_PMC_CMDID, vif->mid, |
258 | sizeof(pmc_cmd)); | 262 | &pmc_cmd, sizeof(pmc_cmd)); |
259 | if (pmc->last_cmd_status) { | 263 | if (pmc->last_cmd_status) { |
260 | wil_err(wil, | 264 | wil_err(wil, |
261 | "WMI_PMC_CMD with RELEASE op failed, status %d", | 265 | "WMI_PMC_CMD with RELEASE op failed, status %d", |
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c index a43cffcf1bbf..14dcb0698dee 100644 --- a/drivers/net/wireless/ath/wil6210/rx_reorder.c +++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -40,11 +41,10 @@ static inline int reorder_index(struct wil_tid_ampdu_rx *r, u16 seq) | |||
40 | return seq_sub(seq, r->ssn) % r->buf_size; | 41 | return seq_sub(seq, r->ssn) % r->buf_size; |
41 | } | 42 | } |
42 | 43 | ||
43 | static void wil_release_reorder_frame(struct wil6210_priv *wil, | 44 | static void wil_release_reorder_frame(struct net_device *ndev, |
44 | struct wil_tid_ampdu_rx *r, | 45 | struct wil_tid_ampdu_rx *r, |
45 | int index) | 46 | int index) |
46 | { | 47 | { |
47 | struct net_device *ndev = wil_to_ndev(wil); | ||
48 | struct sk_buff *skb = r->reorder_buf[index]; | 48 | struct sk_buff *skb = r->reorder_buf[index]; |
49 | 49 | ||
50 | if (!skb) | 50 | if (!skb) |
@@ -59,7 +59,7 @@ no_frame: | |||
59 | r->head_seq_num = seq_inc(r->head_seq_num); | 59 | r->head_seq_num = seq_inc(r->head_seq_num); |
60 | } | 60 | } |
61 | 61 | ||
62 | static void wil_release_reorder_frames(struct wil6210_priv *wil, | 62 | static void wil_release_reorder_frames(struct net_device *ndev, |
63 | struct wil_tid_ampdu_rx *r, | 63 | struct wil_tid_ampdu_rx *r, |
64 | u16 hseq) | 64 | u16 hseq) |
65 | { | 65 | { |
@@ -73,18 +73,18 @@ static void wil_release_reorder_frames(struct wil6210_priv *wil, | |||
73 | */ | 73 | */ |
74 | while (seq_less(r->head_seq_num, hseq) && r->stored_mpdu_num) { | 74 | while (seq_less(r->head_seq_num, hseq) && r->stored_mpdu_num) { |
75 | index = reorder_index(r, r->head_seq_num); | 75 | index = reorder_index(r, r->head_seq_num); |
76 | wil_release_reorder_frame(wil, r, index); | 76 | wil_release_reorder_frame(ndev, r, index); |
77 | } | 77 | } |
78 | r->head_seq_num = hseq; | 78 | r->head_seq_num = hseq; |
79 | } | 79 | } |
80 | 80 | ||
81 | static void wil_reorder_release(struct wil6210_priv *wil, | 81 | static void wil_reorder_release(struct net_device *ndev, |
82 | struct wil_tid_ampdu_rx *r) | 82 | struct wil_tid_ampdu_rx *r) |
83 | { | 83 | { |
84 | int index = reorder_index(r, r->head_seq_num); | 84 | int index = reorder_index(r, r->head_seq_num); |
85 | 85 | ||
86 | while (r->reorder_buf[index]) { | 86 | while (r->reorder_buf[index]) { |
87 | wil_release_reorder_frame(wil, r, index); | 87 | wil_release_reorder_frame(ndev, r, index); |
88 | index = reorder_index(r, r->head_seq_num); | 88 | index = reorder_index(r, r->head_seq_num); |
89 | } | 89 | } |
90 | } | 90 | } |
@@ -93,7 +93,8 @@ static void wil_reorder_release(struct wil6210_priv *wil, | |||
93 | void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb) | 93 | void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb) |
94 | __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | 94 | __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) |
95 | { | 95 | { |
96 | struct net_device *ndev = wil_to_ndev(wil); | 96 | struct wil6210_vif *vif; |
97 | struct net_device *ndev; | ||
97 | struct vring_rx_desc *d = wil_skb_rxdesc(skb); | 98 | struct vring_rx_desc *d = wil_skb_rxdesc(skb); |
98 | int tid = wil_rxdesc_tid(d); | 99 | int tid = wil_rxdesc_tid(d); |
99 | int cid = wil_rxdesc_cid(d); | 100 | int cid = wil_rxdesc_cid(d); |
@@ -108,6 +109,14 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | |||
108 | wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x mcast %01x\n", | 109 | wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x mcast %01x\n", |
109 | mid, cid, tid, seq, mcast); | 110 | mid, cid, tid, seq, mcast); |
110 | 111 | ||
112 | vif = wil->vifs[mid]; | ||
113 | if (unlikely(!vif)) { | ||
114 | wil_dbg_txrx(wil, "invalid VIF, mid %d\n", mid); | ||
115 | dev_kfree_skb(skb); | ||
116 | return; | ||
117 | } | ||
118 | ndev = vif_to_ndev(vif); | ||
119 | |||
111 | if (unlikely(mcast)) { | 120 | if (unlikely(mcast)) { |
112 | wil_netif_rx_any(skb, ndev); | 121 | wil_netif_rx_any(skb, ndev); |
113 | return; | 122 | return; |
@@ -168,7 +177,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | |||
168 | if (!seq_less(seq, r->head_seq_num + r->buf_size)) { | 177 | if (!seq_less(seq, r->head_seq_num + r->buf_size)) { |
169 | hseq = seq_inc(seq_sub(seq, r->buf_size)); | 178 | hseq = seq_inc(seq_sub(seq, r->buf_size)); |
170 | /* release stored frames up to new head to stack */ | 179 | /* release stored frames up to new head to stack */ |
171 | wil_release_reorder_frames(wil, r, hseq); | 180 | wil_release_reorder_frames(ndev, r, hseq); |
172 | } | 181 | } |
173 | 182 | ||
174 | /* Now the new frame is always in the range of the reordering buffer */ | 183 | /* Now the new frame is always in the range of the reordering buffer */ |
@@ -199,16 +208,18 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | |||
199 | r->reorder_buf[index] = skb; | 208 | r->reorder_buf[index] = skb; |
200 | r->reorder_time[index] = jiffies; | 209 | r->reorder_time[index] = jiffies; |
201 | r->stored_mpdu_num++; | 210 | r->stored_mpdu_num++; |
202 | wil_reorder_release(wil, r); | 211 | wil_reorder_release(ndev, r); |
203 | 212 | ||
204 | out: | 213 | out: |
205 | spin_unlock(&sta->tid_rx_lock); | 214 | spin_unlock(&sta->tid_rx_lock); |
206 | } | 215 | } |
207 | 216 | ||
208 | /* process BAR frame, called in NAPI context */ | 217 | /* process BAR frame, called in NAPI context */ |
209 | void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq) | 218 | void wil_rx_bar(struct wil6210_priv *wil, struct wil6210_vif *vif, |
219 | u8 cid, u8 tid, u16 seq) | ||
210 | { | 220 | { |
211 | struct wil_sta_info *sta = &wil->sta[cid]; | 221 | struct wil_sta_info *sta = &wil->sta[cid]; |
222 | struct net_device *ndev = vif_to_ndev(vif); | ||
212 | struct wil_tid_ampdu_rx *r; | 223 | struct wil_tid_ampdu_rx *r; |
213 | 224 | ||
214 | spin_lock(&sta->tid_rx_lock); | 225 | spin_lock(&sta->tid_rx_lock); |
@@ -223,9 +234,9 @@ void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq) | |||
223 | seq, r->head_seq_num); | 234 | seq, r->head_seq_num); |
224 | goto out; | 235 | goto out; |
225 | } | 236 | } |
226 | wil_dbg_txrx(wil, "BAR: CID %d TID %d Seq 0x%03x head 0x%03x\n", | 237 | wil_dbg_txrx(wil, "BAR: CID %d MID %d TID %d Seq 0x%03x head 0x%03x\n", |
227 | cid, tid, seq, r->head_seq_num); | 238 | cid, vif->mid, tid, seq, r->head_seq_num); |
228 | wil_release_reorder_frames(wil, r, seq); | 239 | wil_release_reorder_frames(ndev, r, seq); |
229 | 240 | ||
230 | out: | 241 | out: |
231 | spin_unlock(&sta->tid_rx_lock); | 242 | spin_unlock(&sta->tid_rx_lock); |
@@ -292,8 +303,8 @@ static u16 wil_agg_size(struct wil6210_priv *wil, u16 req_agg_wsize) | |||
292 | } | 303 | } |
293 | 304 | ||
294 | /* Block Ack - Rx side (recipient) */ | 305 | /* Block Ack - Rx side (recipient) */ |
295 | int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid, | 306 | int wil_addba_rx_request(struct wil6210_priv *wil, u8 mid, |
296 | u8 dialog_token, __le16 ba_param_set, | 307 | u8 cidxtid, u8 dialog_token, __le16 ba_param_set, |
297 | __le16 ba_timeout, __le16 ba_seq_ctrl) | 308 | __le16 ba_timeout, __le16 ba_seq_ctrl) |
298 | __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | 309 | __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) |
299 | { | 310 | { |
@@ -354,7 +365,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | |||
354 | } | 365 | } |
355 | } | 366 | } |
356 | 367 | ||
357 | rc = wmi_addba_rx_resp(wil, cid, tid, dialog_token, status, | 368 | rc = wmi_addba_rx_resp(wil, mid, cid, tid, dialog_token, status, |
358 | agg_amsdu, agg_wsize, agg_timeout); | 369 | agg_amsdu, agg_wsize, agg_timeout); |
359 | if (rc || (status != WLAN_STATUS_SUCCESS)) { | 370 | if (rc || (status != WLAN_STATUS_SUCCESS)) { |
360 | wil_err(wil, "do not apply ba, rc(%d), status(%d)\n", rc, | 371 | wil_err(wil, "do not apply ba, rc(%d), status(%d)\n", rc, |
@@ -393,7 +404,7 @@ int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize) | |||
393 | goto out; | 404 | goto out; |
394 | } | 405 | } |
395 | txdata->addba_in_progress = true; | 406 | txdata->addba_in_progress = true; |
396 | rc = wmi_addba(wil, ringid, agg_wsize, agg_timeout); | 407 | rc = wmi_addba(wil, txdata->mid, ringid, agg_wsize, agg_timeout); |
397 | if (rc) { | 408 | if (rc) { |
398 | wil_err(wil, "wmi_addba failed, rc (%d)", rc); | 409 | wil_err(wil, "wmi_addba failed, rc (%d)", rc); |
399 | txdata->addba_in_progress = false; | 410 | txdata->addba_in_progress = false; |
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 16b8a4e5201f..b60b9fcaaebd 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -474,7 +475,8 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
474 | struct vring *vring) | 475 | struct vring *vring) |
475 | { | 476 | { |
476 | struct device *dev = wil_to_dev(wil); | 477 | struct device *dev = wil_to_dev(wil); |
477 | struct net_device *ndev = wil_to_ndev(wil); | 478 | struct wil6210_vif *vif; |
479 | struct net_device *ndev; | ||
478 | volatile struct vring_rx_desc *_d; | 480 | volatile struct vring_rx_desc *_d; |
479 | struct vring_rx_desc *d; | 481 | struct vring_rx_desc *d; |
480 | struct sk_buff *skb; | 482 | struct sk_buff *skb; |
@@ -483,7 +485,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
483 | unsigned int sz = wil->rx_buf_len + ETH_HLEN + snaplen; | 485 | unsigned int sz = wil->rx_buf_len + ETH_HLEN + snaplen; |
484 | u16 dmalen; | 486 | u16 dmalen; |
485 | u8 ftype; | 487 | u8 ftype; |
486 | int cid; | 488 | int cid, mid; |
487 | int i; | 489 | int i; |
488 | struct wil_net_stats *stats; | 490 | struct wil_net_stats *stats; |
489 | 491 | ||
@@ -520,6 +522,16 @@ again: | |||
520 | (const void *)d, sizeof(*d), false); | 522 | (const void *)d, sizeof(*d), false); |
521 | 523 | ||
522 | cid = wil_rxdesc_cid(d); | 524 | cid = wil_rxdesc_cid(d); |
525 | mid = wil_rxdesc_mid(d); | ||
526 | vif = wil->vifs[mid]; | ||
527 | |||
528 | if (unlikely(!vif)) { | ||
529 | wil_dbg_txrx(wil, "skipped RX descriptor with invalid mid %d", | ||
530 | mid); | ||
531 | kfree_skb(skb); | ||
532 | goto again; | ||
533 | } | ||
534 | ndev = vif_to_ndev(vif); | ||
523 | stats = &wil->sta[cid].stats; | 535 | stats = &wil->sta[cid].stats; |
524 | 536 | ||
525 | if (unlikely(dmalen > sz)) { | 537 | if (unlikely(dmalen > sz)) { |
@@ -553,7 +565,6 @@ again: | |||
553 | ftype = wil_rxdesc_ftype(d) << 2; | 565 | ftype = wil_rxdesc_ftype(d) << 2; |
554 | if (unlikely(ftype != IEEE80211_FTYPE_DATA)) { | 566 | if (unlikely(ftype != IEEE80211_FTYPE_DATA)) { |
555 | u8 fc1 = wil_rxdesc_fc1(d); | 567 | u8 fc1 = wil_rxdesc_fc1(d); |
556 | int mid = wil_rxdesc_mid(d); | ||
557 | int tid = wil_rxdesc_tid(d); | 568 | int tid = wil_rxdesc_tid(d); |
558 | u16 seq = wil_rxdesc_seq(d); | 569 | u16 seq = wil_rxdesc_seq(d); |
559 | 570 | ||
@@ -565,7 +576,7 @@ again: | |||
565 | wil_dbg_txrx(wil, | 576 | wil_dbg_txrx(wil, |
566 | "BAR: MID %d CID %d TID %d Seq 0x%03x\n", | 577 | "BAR: MID %d CID %d TID %d Seq 0x%03x\n", |
567 | mid, cid, tid, seq); | 578 | mid, cid, tid, seq); |
568 | wil_rx_bar(wil, cid, tid, seq); | 579 | wil_rx_bar(wil, vif, cid, tid, seq); |
569 | } else { | 580 | } else { |
570 | /* print again all info. One can enable only this | 581 | /* print again all info. One can enable only this |
571 | * without overhead for printing every Rx frame | 582 | * without overhead for printing every Rx frame |
@@ -621,10 +632,15 @@ again: | |||
621 | /** | 632 | /** |
622 | * allocate and fill up to @count buffers in rx ring | 633 | * allocate and fill up to @count buffers in rx ring |
623 | * buffers posted at @swtail | 634 | * buffers posted at @swtail |
635 | * Note: we have a single RX queue for servicing all VIFs, but we | ||
636 | * allocate skbs with headroom according to main interface only. This | ||
637 | * means it will not work with monitor interface together with other VIFs. | ||
638 | * Currently we only support monitor interface on its own without other VIFs, | ||
639 | * and we will need to fix this code once we add support. | ||
624 | */ | 640 | */ |
625 | static int wil_rx_refill(struct wil6210_priv *wil, int count) | 641 | static int wil_rx_refill(struct wil6210_priv *wil, int count) |
626 | { | 642 | { |
627 | struct net_device *ndev = wil_to_ndev(wil); | 643 | struct net_device *ndev = wil->main_ndev; |
628 | struct vring *v = &wil->vring_rx; | 644 | struct vring *v = &wil->vring_rx; |
629 | u32 next_tail; | 645 | u32 next_tail; |
630 | int rc = 0; | 646 | int rc = 0; |
@@ -713,8 +729,9 @@ static int wil_rx_crypto_check(struct wil6210_priv *wil, struct sk_buff *skb) | |||
713 | void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) | 729 | void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) |
714 | { | 730 | { |
715 | gro_result_t rc = GRO_NORMAL; | 731 | gro_result_t rc = GRO_NORMAL; |
732 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
716 | struct wil6210_priv *wil = ndev_to_wil(ndev); | 733 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
717 | struct wireless_dev *wdev = wil_to_wdev(wil); | 734 | struct wireless_dev *wdev = vif_to_wdev(vif); |
718 | unsigned int len = skb->len; | 735 | unsigned int len = skb->len; |
719 | struct vring_rx_desc *d = wil_skb_rxdesc(skb); | 736 | struct vring_rx_desc *d = wil_skb_rxdesc(skb); |
720 | int cid = wil_rxdesc_cid(d); /* always 0..7, no need to check */ | 737 | int cid = wil_rxdesc_cid(d); /* always 0..7, no need to check */ |
@@ -751,14 +768,15 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) | |||
751 | goto stats; | 768 | goto stats; |
752 | } | 769 | } |
753 | 770 | ||
754 | if (wdev->iftype == NL80211_IFTYPE_AP && !wil->ap_isolate) { | 771 | if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) { |
755 | if (mcast) { | 772 | if (mcast) { |
756 | /* send multicast frames both to higher layers in | 773 | /* send multicast frames both to higher layers in |
757 | * local net stack and back to the wireless medium | 774 | * local net stack and back to the wireless medium |
758 | */ | 775 | */ |
759 | xmit_skb = skb_copy(skb, GFP_ATOMIC); | 776 | xmit_skb = skb_copy(skb, GFP_ATOMIC); |
760 | } else { | 777 | } else { |
761 | int xmit_cid = wil_find_cid(wil, eth->h_dest); | 778 | int xmit_cid = wil_find_cid(wil, vif->mid, |
779 | eth->h_dest); | ||
762 | 780 | ||
763 | if (xmit_cid >= 0) { | 781 | if (xmit_cid >= 0) { |
764 | /* The destination station is associated to | 782 | /* The destination station is associated to |
@@ -786,8 +804,8 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) | |||
786 | } | 804 | } |
787 | 805 | ||
788 | if (skb) { /* deliver to local stack */ | 806 | if (skb) { /* deliver to local stack */ |
789 | |||
790 | skb->protocol = eth_type_trans(skb, ndev); | 807 | skb->protocol = eth_type_trans(skb, ndev); |
808 | skb->dev = ndev; | ||
791 | rc = napi_gro_receive(&wil->napi_rx, skb); | 809 | rc = napi_gro_receive(&wil->napi_rx, skb); |
792 | wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n", | 810 | wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n", |
793 | len, gro_res_str[rc]); | 811 | len, gro_res_str[rc]); |
@@ -815,7 +833,8 @@ stats: | |||
815 | */ | 833 | */ |
816 | void wil_rx_handle(struct wil6210_priv *wil, int *quota) | 834 | void wil_rx_handle(struct wil6210_priv *wil, int *quota) |
817 | { | 835 | { |
818 | struct net_device *ndev = wil_to_ndev(wil); | 836 | struct net_device *ndev = wil->main_ndev; |
837 | struct wireless_dev *wdev = ndev->ieee80211_ptr; | ||
819 | struct vring *v = &wil->vring_rx; | 838 | struct vring *v = &wil->vring_rx; |
820 | struct sk_buff *skb; | 839 | struct sk_buff *skb; |
821 | 840 | ||
@@ -827,7 +846,8 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota) | |||
827 | while ((*quota > 0) && (NULL != (skb = wil_vring_reap_rx(wil, v)))) { | 846 | while ((*quota > 0) && (NULL != (skb = wil_vring_reap_rx(wil, v)))) { |
828 | (*quota)--; | 847 | (*quota)--; |
829 | 848 | ||
830 | if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { | 849 | /* monitor is currently supported on main interface only */ |
850 | if (wdev->iftype == NL80211_IFTYPE_MONITOR) { | ||
831 | skb->dev = ndev; | 851 | skb->dev = ndev; |
832 | skb_reset_mac_header(skb); | 852 | skb_reset_mac_header(skb); |
833 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 853 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -911,12 +931,14 @@ static inline void wil_tx_data_init(struct vring_tx_data *txdata) | |||
911 | txdata->agg_timeout = 0; | 931 | txdata->agg_timeout = 0; |
912 | txdata->agg_amsdu = 0; | 932 | txdata->agg_amsdu = 0; |
913 | txdata->addba_in_progress = false; | 933 | txdata->addba_in_progress = false; |
934 | txdata->mid = U8_MAX; | ||
914 | spin_unlock_bh(&txdata->lock); | 935 | spin_unlock_bh(&txdata->lock); |
915 | } | 936 | } |
916 | 937 | ||
917 | int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | 938 | int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size, |
918 | int cid, int tid) | 939 | int cid, int tid) |
919 | { | 940 | { |
941 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
920 | int rc; | 942 | int rc; |
921 | struct wmi_vring_cfg_cmd cmd = { | 943 | struct wmi_vring_cfg_cmd cmd = { |
922 | .action = cpu_to_le32(WMI_VRING_CMD_ADD), | 944 | .action = cpu_to_le32(WMI_VRING_CMD_ADD), |
@@ -966,9 +988,9 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | |||
966 | 988 | ||
967 | cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); | 989 | cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); |
968 | 990 | ||
969 | if (!wil->privacy) | 991 | if (!vif->privacy) |
970 | txdata->dot1x_open = true; | 992 | txdata->dot1x_open = true; |
971 | rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd), | 993 | rc = wmi_call(wil, WMI_VRING_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), |
972 | WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); | 994 | WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); |
973 | if (rc) | 995 | if (rc) |
974 | goto out_free; | 996 | goto out_free; |
@@ -982,6 +1004,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | |||
982 | 1004 | ||
983 | spin_lock_bh(&txdata->lock); | 1005 | spin_lock_bh(&txdata->lock); |
984 | vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); | 1006 | vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); |
1007 | txdata->mid = vif->mid; | ||
985 | txdata->enabled = 1; | 1008 | txdata->enabled = 1; |
986 | spin_unlock_bh(&txdata->lock); | 1009 | spin_unlock_bh(&txdata->lock); |
987 | 1010 | ||
@@ -1003,8 +1026,9 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | |||
1003 | return rc; | 1026 | return rc; |
1004 | } | 1027 | } |
1005 | 1028 | ||
1006 | int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size) | 1029 | int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size) |
1007 | { | 1030 | { |
1031 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1008 | int rc; | 1032 | int rc; |
1009 | struct wmi_bcast_vring_cfg_cmd cmd = { | 1033 | struct wmi_bcast_vring_cfg_cmd cmd = { |
1010 | .action = cpu_to_le32(WMI_VRING_CMD_ADD), | 1034 | .action = cpu_to_le32(WMI_VRING_CMD_ADD), |
@@ -1046,9 +1070,10 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size) | |||
1046 | 1070 | ||
1047 | cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); | 1071 | cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); |
1048 | 1072 | ||
1049 | if (!wil->privacy) | 1073 | if (!vif->privacy) |
1050 | txdata->dot1x_open = true; | 1074 | txdata->dot1x_open = true; |
1051 | rc = wmi_call(wil, WMI_BCAST_VRING_CFG_CMDID, &cmd, sizeof(cmd), | 1075 | rc = wmi_call(wil, WMI_BCAST_VRING_CFG_CMDID, vif->mid, |
1076 | &cmd, sizeof(cmd), | ||
1052 | WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); | 1077 | WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); |
1053 | if (rc) | 1078 | if (rc) |
1054 | goto out_free; | 1079 | goto out_free; |
@@ -1062,6 +1087,7 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size) | |||
1062 | 1087 | ||
1063 | spin_lock_bh(&txdata->lock); | 1088 | spin_lock_bh(&txdata->lock); |
1064 | vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); | 1089 | vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); |
1090 | txdata->mid = vif->mid; | ||
1065 | txdata->enabled = 1; | 1091 | txdata->enabled = 1; |
1066 | spin_unlock_bh(&txdata->lock); | 1092 | spin_unlock_bh(&txdata->lock); |
1067 | 1093 | ||
@@ -1091,6 +1117,7 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id) | |||
1091 | 1117 | ||
1092 | spin_lock_bh(&txdata->lock); | 1118 | spin_lock_bh(&txdata->lock); |
1093 | txdata->dot1x_open = false; | 1119 | txdata->dot1x_open = false; |
1120 | txdata->mid = U8_MAX; | ||
1094 | txdata->enabled = 0; /* no Tx can be in progress or start anew */ | 1121 | txdata->enabled = 0; /* no Tx can be in progress or start anew */ |
1095 | spin_unlock_bh(&txdata->lock); | 1122 | spin_unlock_bh(&txdata->lock); |
1096 | /* napi_synchronize waits for completion of the current NAPI but will | 1123 | /* napi_synchronize waits for completion of the current NAPI but will |
@@ -1108,11 +1135,12 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id) | |||
1108 | } | 1135 | } |
1109 | 1136 | ||
1110 | static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil, | 1137 | static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil, |
1138 | struct wil6210_vif *vif, | ||
1111 | struct sk_buff *skb) | 1139 | struct sk_buff *skb) |
1112 | { | 1140 | { |
1113 | int i; | 1141 | int i; |
1114 | struct ethhdr *eth = (void *)skb->data; | 1142 | struct ethhdr *eth = (void *)skb->data; |
1115 | int cid = wil_find_cid(wil, eth->h_dest); | 1143 | int cid = wil_find_cid(wil, vif->mid, eth->h_dest); |
1116 | 1144 | ||
1117 | if (cid < 0) | 1145 | if (cid < 0) |
1118 | return NULL; | 1146 | return NULL; |
@@ -1142,10 +1170,11 @@ static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil, | |||
1142 | return NULL; | 1170 | return NULL; |
1143 | } | 1171 | } |
1144 | 1172 | ||
1145 | static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | 1173 | static int wil_tx_vring(struct wil6210_priv *wil, struct wil6210_vif *vif, |
1146 | struct sk_buff *skb); | 1174 | struct vring *vring, struct sk_buff *skb); |
1147 | 1175 | ||
1148 | static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil, | 1176 | static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil, |
1177 | struct wil6210_vif *vif, | ||
1149 | struct sk_buff *skb) | 1178 | struct sk_buff *skb) |
1150 | { | 1179 | { |
1151 | struct vring *v; | 1180 | struct vring *v; |
@@ -1160,7 +1189,7 @@ static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil, | |||
1160 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { | 1189 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { |
1161 | v = &wil->vring_tx[i]; | 1190 | v = &wil->vring_tx[i]; |
1162 | txdata = &wil->vring_tx_data[i]; | 1191 | txdata = &wil->vring_tx_data[i]; |
1163 | if (!v->va || !txdata->enabled) | 1192 | if (!v->va || !txdata->enabled || txdata->mid != vif->mid) |
1164 | continue; | 1193 | continue; |
1165 | 1194 | ||
1166 | cid = wil->vring2cid_tid[i][0]; | 1195 | cid = wil->vring2cid_tid[i][0]; |
@@ -1193,11 +1222,12 @@ static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil, | |||
1193 | * - for PBSS | 1222 | * - for PBSS |
1194 | */ | 1223 | */ |
1195 | static struct vring *wil_find_tx_bcast_1(struct wil6210_priv *wil, | 1224 | static struct vring *wil_find_tx_bcast_1(struct wil6210_priv *wil, |
1225 | struct wil6210_vif *vif, | ||
1196 | struct sk_buff *skb) | 1226 | struct sk_buff *skb) |
1197 | { | 1227 | { |
1198 | struct vring *v; | 1228 | struct vring *v; |
1199 | struct vring_tx_data *txdata; | 1229 | struct vring_tx_data *txdata; |
1200 | int i = wil->bcast_vring; | 1230 | int i = vif->bcast_vring; |
1201 | 1231 | ||
1202 | if (i < 0) | 1232 | if (i < 0) |
1203 | return NULL; | 1233 | return NULL; |
@@ -1222,6 +1252,7 @@ static void wil_set_da_for_vring(struct wil6210_priv *wil, | |||
1222 | } | 1252 | } |
1223 | 1253 | ||
1224 | static struct vring *wil_find_tx_bcast_2(struct wil6210_priv *wil, | 1254 | static struct vring *wil_find_tx_bcast_2(struct wil6210_priv *wil, |
1255 | struct wil6210_vif *vif, | ||
1225 | struct sk_buff *skb) | 1256 | struct sk_buff *skb) |
1226 | { | 1257 | { |
1227 | struct vring *v, *v2; | 1258 | struct vring *v, *v2; |
@@ -1230,13 +1261,13 @@ static struct vring *wil_find_tx_bcast_2(struct wil6210_priv *wil, | |||
1230 | u8 cid; | 1261 | u8 cid; |
1231 | struct ethhdr *eth = (void *)skb->data; | 1262 | struct ethhdr *eth = (void *)skb->data; |
1232 | char *src = eth->h_source; | 1263 | char *src = eth->h_source; |
1233 | struct vring_tx_data *txdata; | 1264 | struct vring_tx_data *txdata, *txdata2; |
1234 | 1265 | ||
1235 | /* find 1-st vring eligible for data */ | 1266 | /* find 1-st vring eligible for data */ |
1236 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { | 1267 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { |
1237 | v = &wil->vring_tx[i]; | 1268 | v = &wil->vring_tx[i]; |
1238 | txdata = &wil->vring_tx_data[i]; | 1269 | txdata = &wil->vring_tx_data[i]; |
1239 | if (!v->va || !txdata->enabled) | 1270 | if (!v->va || !txdata->enabled || txdata->mid != vif->mid) |
1240 | continue; | 1271 | continue; |
1241 | 1272 | ||
1242 | cid = wil->vring2cid_tid[i][0]; | 1273 | cid = wil->vring2cid_tid[i][0]; |
@@ -1264,7 +1295,8 @@ found: | |||
1264 | /* find other active vrings and duplicate skb for each */ | 1295 | /* find other active vrings and duplicate skb for each */ |
1265 | for (i++; i < WIL6210_MAX_TX_RINGS; i++) { | 1296 | for (i++; i < WIL6210_MAX_TX_RINGS; i++) { |
1266 | v2 = &wil->vring_tx[i]; | 1297 | v2 = &wil->vring_tx[i]; |
1267 | if (!v2->va) | 1298 | txdata2 = &wil->vring_tx_data[i]; |
1299 | if (!v2->va || txdata2->mid != vif->mid) | ||
1268 | continue; | 1300 | continue; |
1269 | cid = wil->vring2cid_tid[i][0]; | 1301 | cid = wil->vring2cid_tid[i][0]; |
1270 | if (cid >= WIL6210_MAX_CID) /* skip BCAST */ | 1302 | if (cid >= WIL6210_MAX_CID) /* skip BCAST */ |
@@ -1280,7 +1312,7 @@ found: | |||
1280 | if (skb2) { | 1312 | if (skb2) { |
1281 | wil_dbg_txrx(wil, "BCAST DUP -> ring %d\n", i); | 1313 | wil_dbg_txrx(wil, "BCAST DUP -> ring %d\n", i); |
1282 | wil_set_da_for_vring(wil, skb2, i); | 1314 | wil_set_da_for_vring(wil, skb2, i); |
1283 | wil_tx_vring(wil, v2, skb2); | 1315 | wil_tx_vring(wil, vif, v2, skb2); |
1284 | } else { | 1316 | } else { |
1285 | wil_err(wil, "skb_copy failed\n"); | 1317 | wil_err(wil, "skb_copy failed\n"); |
1286 | } | 1318 | } |
@@ -1417,8 +1449,8 @@ static inline void wil_set_tx_desc_last_tso(volatile struct vring_tx_desc *d) | |||
1417 | DMA_CFG_DESC_TX_0_SEGMENT_BUF_DETAILS_POS; | 1449 | DMA_CFG_DESC_TX_0_SEGMENT_BUF_DETAILS_POS; |
1418 | } | 1450 | } |
1419 | 1451 | ||
1420 | static int __wil_tx_vring_tso(struct wil6210_priv *wil, struct vring *vring, | 1452 | static int __wil_tx_vring_tso(struct wil6210_priv *wil, struct wil6210_vif *vif, |
1421 | struct sk_buff *skb) | 1453 | struct vring *vring, struct sk_buff *skb) |
1422 | { | 1454 | { |
1423 | struct device *dev = wil_to_dev(wil); | 1455 | struct device *dev = wil_to_dev(wil); |
1424 | 1456 | ||
@@ -1710,8 +1742,8 @@ err_exit: | |||
1710 | return rc; | 1742 | return rc; |
1711 | } | 1743 | } |
1712 | 1744 | ||
1713 | static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | 1745 | static int __wil_tx_vring(struct wil6210_priv *wil, struct wil6210_vif *vif, |
1714 | struct sk_buff *skb) | 1746 | struct vring *vring, struct sk_buff *skb) |
1715 | { | 1747 | { |
1716 | struct device *dev = wil_to_dev(wil); | 1748 | struct device *dev = wil_to_dev(wil); |
1717 | struct vring_tx_desc dd, *d = ⅆ | 1749 | struct vring_tx_desc dd, *d = ⅆ |
@@ -1725,7 +1757,7 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
1725 | uint i = swhead; | 1757 | uint i = swhead; |
1726 | dma_addr_t pa; | 1758 | dma_addr_t pa; |
1727 | int used; | 1759 | int used; |
1728 | bool mcast = (vring_index == wil->bcast_vring); | 1760 | bool mcast = (vring_index == vif->bcast_vring); |
1729 | uint len = skb_headlen(skb); | 1761 | uint len = skb_headlen(skb); |
1730 | 1762 | ||
1731 | wil_dbg_txrx(wil, "tx_vring: %d bytes to vring %d\n", skb->len, | 1763 | wil_dbg_txrx(wil, "tx_vring: %d bytes to vring %d\n", skb->len, |
@@ -1860,8 +1892,8 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
1860 | return -EINVAL; | 1892 | return -EINVAL; |
1861 | } | 1893 | } |
1862 | 1894 | ||
1863 | static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | 1895 | static int wil_tx_vring(struct wil6210_priv *wil, struct wil6210_vif *vif, |
1864 | struct sk_buff *skb) | 1896 | struct vring *vring, struct sk_buff *skb) |
1865 | { | 1897 | { |
1866 | int vring_index = vring - wil->vring_tx; | 1898 | int vring_index = vring - wil->vring_tx; |
1867 | struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index]; | 1899 | struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index]; |
@@ -1879,7 +1911,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
1879 | } | 1911 | } |
1880 | 1912 | ||
1881 | rc = (skb_is_gso(skb) ? __wil_tx_vring_tso : __wil_tx_vring) | 1913 | rc = (skb_is_gso(skb) ? __wil_tx_vring_tso : __wil_tx_vring) |
1882 | (wil, vring, skb); | 1914 | (wil, vif, vring, skb); |
1883 | 1915 | ||
1884 | spin_unlock(&txdata->lock); | 1916 | spin_unlock(&txdata->lock); |
1885 | 1917 | ||
@@ -1888,6 +1920,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
1888 | 1920 | ||
1889 | /** | 1921 | /** |
1890 | * Check status of tx vrings and stop/wake net queues if needed | 1922 | * Check status of tx vrings and stop/wake net queues if needed |
1923 | * It will start/stop net queues of a specific VIF net_device. | ||
1891 | * | 1924 | * |
1892 | * This function does one of two checks: | 1925 | * This function does one of two checks: |
1893 | * In case check_stop is true, will check if net queues need to be stopped. If | 1926 | * In case check_stop is true, will check if net queues need to be stopped. If |
@@ -1903,28 +1936,32 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
1903 | * availability and modified vring has high descriptor availability. | 1936 | * availability and modified vring has high descriptor availability. |
1904 | */ | 1937 | */ |
1905 | static inline void __wil_update_net_queues(struct wil6210_priv *wil, | 1938 | static inline void __wil_update_net_queues(struct wil6210_priv *wil, |
1939 | struct wil6210_vif *vif, | ||
1906 | struct vring *vring, | 1940 | struct vring *vring, |
1907 | bool check_stop) | 1941 | bool check_stop) |
1908 | { | 1942 | { |
1909 | int i; | 1943 | int i; |
1910 | 1944 | ||
1945 | if (unlikely(!vif)) | ||
1946 | return; | ||
1947 | |||
1911 | if (vring) | 1948 | if (vring) |
1912 | wil_dbg_txrx(wil, "vring %d, check_stop=%d, stopped=%d", | 1949 | wil_dbg_txrx(wil, "vring %d, mid %d, check_stop=%d, stopped=%d", |
1913 | (int)(vring - wil->vring_tx), check_stop, | 1950 | (int)(vring - wil->vring_tx), vif->mid, check_stop, |
1914 | wil->net_queue_stopped); | 1951 | vif->net_queue_stopped); |
1915 | else | 1952 | else |
1916 | wil_dbg_txrx(wil, "check_stop=%d, stopped=%d", | 1953 | wil_dbg_txrx(wil, "check_stop=%d, mid=%d, stopped=%d", |
1917 | check_stop, wil->net_queue_stopped); | 1954 | check_stop, vif->mid, vif->net_queue_stopped); |
1918 | 1955 | ||
1919 | if (check_stop == wil->net_queue_stopped) | 1956 | if (check_stop == vif->net_queue_stopped) |
1920 | /* net queues already in desired state */ | 1957 | /* net queues already in desired state */ |
1921 | return; | 1958 | return; |
1922 | 1959 | ||
1923 | if (check_stop) { | 1960 | if (check_stop) { |
1924 | if (!vring || unlikely(wil_vring_avail_low(vring))) { | 1961 | if (!vring || unlikely(wil_vring_avail_low(vring))) { |
1925 | /* not enough room in the vring */ | 1962 | /* not enough room in the vring */ |
1926 | netif_tx_stop_all_queues(wil_to_ndev(wil)); | 1963 | netif_tx_stop_all_queues(vif_to_ndev(vif)); |
1927 | wil->net_queue_stopped = true; | 1964 | vif->net_queue_stopped = true; |
1928 | wil_dbg_txrx(wil, "netif_tx_stop called\n"); | 1965 | wil_dbg_txrx(wil, "netif_tx_stop called\n"); |
1929 | } | 1966 | } |
1930 | return; | 1967 | return; |
@@ -1940,7 +1977,8 @@ static inline void __wil_update_net_queues(struct wil6210_priv *wil, | |||
1940 | struct vring *cur_vring = &wil->vring_tx[i]; | 1977 | struct vring *cur_vring = &wil->vring_tx[i]; |
1941 | struct vring_tx_data *txdata = &wil->vring_tx_data[i]; | 1978 | struct vring_tx_data *txdata = &wil->vring_tx_data[i]; |
1942 | 1979 | ||
1943 | if (!cur_vring->va || !txdata->enabled || cur_vring == vring) | 1980 | if (txdata->mid != vif->mid || !cur_vring->va || |
1981 | !txdata->enabled || cur_vring == vring) | ||
1944 | continue; | 1982 | continue; |
1945 | 1983 | ||
1946 | if (wil_vring_avail_low(cur_vring)) { | 1984 | if (wil_vring_avail_low(cur_vring)) { |
@@ -1953,30 +1991,31 @@ static inline void __wil_update_net_queues(struct wil6210_priv *wil, | |||
1953 | if (!vring || wil_vring_avail_high(vring)) { | 1991 | if (!vring || wil_vring_avail_high(vring)) { |
1954 | /* enough room in the vring */ | 1992 | /* enough room in the vring */ |
1955 | wil_dbg_txrx(wil, "calling netif_tx_wake\n"); | 1993 | wil_dbg_txrx(wil, "calling netif_tx_wake\n"); |
1956 | netif_tx_wake_all_queues(wil_to_ndev(wil)); | 1994 | netif_tx_wake_all_queues(vif_to_ndev(vif)); |
1957 | wil->net_queue_stopped = false; | 1995 | vif->net_queue_stopped = false; |
1958 | } | 1996 | } |
1959 | } | 1997 | } |
1960 | 1998 | ||
1961 | void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring, | 1999 | void wil_update_net_queues(struct wil6210_priv *wil, struct wil6210_vif *vif, |
1962 | bool check_stop) | 2000 | struct vring *vring, bool check_stop) |
1963 | { | 2001 | { |
1964 | spin_lock(&wil->net_queue_lock); | 2002 | spin_lock(&wil->net_queue_lock); |
1965 | __wil_update_net_queues(wil, vring, check_stop); | 2003 | __wil_update_net_queues(wil, vif, vring, check_stop); |
1966 | spin_unlock(&wil->net_queue_lock); | 2004 | spin_unlock(&wil->net_queue_lock); |
1967 | } | 2005 | } |
1968 | 2006 | ||
1969 | void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring, | 2007 | void wil_update_net_queues_bh(struct wil6210_priv *wil, struct wil6210_vif *vif, |
1970 | bool check_stop) | 2008 | struct vring *vring, bool check_stop) |
1971 | { | 2009 | { |
1972 | spin_lock_bh(&wil->net_queue_lock); | 2010 | spin_lock_bh(&wil->net_queue_lock); |
1973 | __wil_update_net_queues(wil, vring, check_stop); | 2011 | __wil_update_net_queues(wil, vif, vring, check_stop); |
1974 | spin_unlock_bh(&wil->net_queue_lock); | 2012 | spin_unlock_bh(&wil->net_queue_lock); |
1975 | } | 2013 | } |
1976 | 2014 | ||
1977 | netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 2015 | netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
1978 | { | 2016 | { |
1979 | struct wil6210_priv *wil = ndev_to_wil(ndev); | 2017 | struct wil6210_vif *vif = ndev_to_vif(ndev); |
2018 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1980 | struct ethhdr *eth = (void *)skb->data; | 2019 | struct ethhdr *eth = (void *)skb->data; |
1981 | bool bcast = is_multicast_ether_addr(eth->h_dest); | 2020 | bool bcast = is_multicast_ether_addr(eth->h_dest); |
1982 | struct vring *vring; | 2021 | struct vring *vring; |
@@ -1991,49 +2030,50 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
1991 | } | 2030 | } |
1992 | goto drop; | 2031 | goto drop; |
1993 | } | 2032 | } |
1994 | if (unlikely(!test_bit(wil_status_fwconnected, wil->status))) { | 2033 | if (unlikely(!test_bit(wil_vif_fwconnected, vif->status))) { |
1995 | wil_dbg_ratelimited(wil, "FW not connected, packet dropped\n"); | 2034 | wil_dbg_ratelimited(wil, |
2035 | "VIF not connected, packet dropped\n"); | ||
1996 | goto drop; | 2036 | goto drop; |
1997 | } | 2037 | } |
1998 | if (unlikely(wil->wdev->iftype == NL80211_IFTYPE_MONITOR)) { | 2038 | if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_MONITOR)) { |
1999 | wil_err(wil, "Xmit in monitor mode not supported\n"); | 2039 | wil_err(wil, "Xmit in monitor mode not supported\n"); |
2000 | goto drop; | 2040 | goto drop; |
2001 | } | 2041 | } |
2002 | pr_once_fw = false; | 2042 | pr_once_fw = false; |
2003 | 2043 | ||
2004 | /* find vring */ | 2044 | /* find vring */ |
2005 | if (wil->wdev->iftype == NL80211_IFTYPE_STATION && !wil->pbss) { | 2045 | if (vif->wdev.iftype == NL80211_IFTYPE_STATION && !vif->pbss) { |
2006 | /* in STA mode (ESS), all to same VRING (to AP) */ | 2046 | /* in STA mode (ESS), all to same VRING (to AP) */ |
2007 | vring = wil_find_tx_vring_sta(wil, skb); | 2047 | vring = wil_find_tx_vring_sta(wil, vif, skb); |
2008 | } else if (bcast) { | 2048 | } else if (bcast) { |
2009 | if (wil->pbss) | 2049 | if (vif->pbss) |
2010 | /* in pbss, no bcast VRING - duplicate skb in | 2050 | /* in pbss, no bcast VRING - duplicate skb in |
2011 | * all stations VRINGs | 2051 | * all stations VRINGs |
2012 | */ | 2052 | */ |
2013 | vring = wil_find_tx_bcast_2(wil, skb); | 2053 | vring = wil_find_tx_bcast_2(wil, vif, skb); |
2014 | else if (wil->wdev->iftype == NL80211_IFTYPE_AP) | 2054 | else if (vif->wdev.iftype == NL80211_IFTYPE_AP) |
2015 | /* AP has a dedicated bcast VRING */ | 2055 | /* AP has a dedicated bcast VRING */ |
2016 | vring = wil_find_tx_bcast_1(wil, skb); | 2056 | vring = wil_find_tx_bcast_1(wil, vif, skb); |
2017 | else | 2057 | else |
2018 | /* unexpected combination, fallback to duplicating | 2058 | /* unexpected combination, fallback to duplicating |
2019 | * the skb in all stations VRINGs | 2059 | * the skb in all stations VRINGs |
2020 | */ | 2060 | */ |
2021 | vring = wil_find_tx_bcast_2(wil, skb); | 2061 | vring = wil_find_tx_bcast_2(wil, vif, skb); |
2022 | } else { | 2062 | } else { |
2023 | /* unicast, find specific VRING by dest. address */ | 2063 | /* unicast, find specific VRING by dest. address */ |
2024 | vring = wil_find_tx_ucast(wil, skb); | 2064 | vring = wil_find_tx_ucast(wil, vif, skb); |
2025 | } | 2065 | } |
2026 | if (unlikely(!vring)) { | 2066 | if (unlikely(!vring)) { |
2027 | wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); | 2067 | wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); |
2028 | goto drop; | 2068 | goto drop; |
2029 | } | 2069 | } |
2030 | /* set up vring entry */ | 2070 | /* set up vring entry */ |
2031 | rc = wil_tx_vring(wil, vring, skb); | 2071 | rc = wil_tx_vring(wil, vif, vring, skb); |
2032 | 2072 | ||
2033 | switch (rc) { | 2073 | switch (rc) { |
2034 | case 0: | 2074 | case 0: |
2035 | /* shall we stop net queues? */ | 2075 | /* shall we stop net queues? */ |
2036 | wil_update_net_queues_bh(wil, vring, true); | 2076 | wil_update_net_queues_bh(wil, vif, vring, true); |
2037 | /* statistics will be updated on the tx_complete */ | 2077 | /* statistics will be updated on the tx_complete */ |
2038 | dev_kfree_skb_any(skb); | 2078 | dev_kfree_skb_any(skb); |
2039 | return NETDEV_TX_OK; | 2079 | return NETDEV_TX_OK; |
@@ -2072,9 +2112,10 @@ static inline void wil_consume_skb(struct sk_buff *skb, bool acked) | |||
2072 | * | 2112 | * |
2073 | * Safe to call from IRQ | 2113 | * Safe to call from IRQ |
2074 | */ | 2114 | */ |
2075 | int wil_tx_complete(struct wil6210_priv *wil, int ringid) | 2115 | int wil_tx_complete(struct wil6210_vif *vif, int ringid) |
2076 | { | 2116 | { |
2077 | struct net_device *ndev = wil_to_ndev(wil); | 2117 | struct wil6210_priv *wil = vif_to_wil(vif); |
2118 | struct net_device *ndev = vif_to_ndev(vif); | ||
2078 | struct device *dev = wil_to_dev(wil); | 2119 | struct device *dev = wil_to_dev(wil); |
2079 | struct vring *vring = &wil->vring_tx[ringid]; | 2120 | struct vring *vring = &wil->vring_tx[ringid]; |
2080 | struct vring_tx_data *txdata = &wil->vring_tx_data[ringid]; | 2121 | struct vring_tx_data *txdata = &wil->vring_tx_data[ringid]; |
@@ -2184,7 +2225,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid) | |||
2184 | 2225 | ||
2185 | /* shall we wake net queues? */ | 2226 | /* shall we wake net queues? */ |
2186 | if (done) | 2227 | if (done) |
2187 | wil_update_net_queues(wil, vring, false); | 2228 | wil_update_net_queues(wil, vif, vring, false); |
2188 | 2229 | ||
2189 | return done; | 2230 | return done; |
2190 | } | 2231 | } |
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index fcdffaa8251b..5f07717acc2c 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012-2016 Qualcomm Atheros, Inc. | 2 | * Copyright (c) 2012-2016 Qualcomm Atheros, Inc. |
3 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -63,7 +64,9 @@ static inline void wil_desc_addr_set(struct vring_dma_addr *addr, | |||
63 | * [dword 1] | 64 | * [dword 1] |
64 | * bit 0.. 3 : pkt_mode:4 | 65 | * bit 0.. 3 : pkt_mode:4 |
65 | * bit 4 : pkt_mode_en:1 | 66 | * bit 4 : pkt_mode_en:1 |
66 | * bit 5..14 : reserved0:10 | 67 | * bit 5 : mac_id_en:1 |
68 | * bit 6..7 : mac_id:2 | ||
69 | * bit 8..14 : reserved0:7 | ||
67 | * bit 15 : ack_policy_en:1 | 70 | * bit 15 : ack_policy_en:1 |
68 | * bit 16..19 : dst_index:4 | 71 | * bit 16..19 : dst_index:4 |
69 | * bit 20 : dst_index_en:1 | 72 | * bit 20 : dst_index_en:1 |
@@ -132,6 +135,14 @@ struct vring_tx_mac { | |||
132 | #define MAC_CFG_DESC_TX_1_PKT_MODE_EN_LEN 1 | 135 | #define MAC_CFG_DESC_TX_1_PKT_MODE_EN_LEN 1 |
133 | #define MAC_CFG_DESC_TX_1_PKT_MODE_EN_MSK 0x10 | 136 | #define MAC_CFG_DESC_TX_1_PKT_MODE_EN_MSK 0x10 |
134 | 137 | ||
138 | #define MAC_CFG_DESC_TX_1_MAC_ID_EN_POS 5 | ||
139 | #define MAC_CFG_DESC_TX_1_MAC_ID_EN_LEN 1 | ||
140 | #define MAC_CFG_DESC_TX_1_MAC_ID_EN_MSK 0x20 | ||
141 | |||
142 | #define MAC_CFG_DESC_TX_1_MAC_ID_POS 6 | ||
143 | #define MAC_CFG_DESC_TX_1_MAC_ID_LEN 2 | ||
144 | #define MAC_CFG_DESC_TX_1_MAC_ID_MSK 0xc0 | ||
145 | |||
135 | #define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_POS 15 | 146 | #define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_POS 15 |
136 | #define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_LEN 1 | 147 | #define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_LEN 1 |
137 | #define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_MSK 0x8000 | 148 | #define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_MSK 0x8000 |
@@ -304,7 +315,7 @@ enum { | |||
304 | * bit 0.. 3 : tid:4 The QoS (b3-0) TID Field | 315 | * bit 0.. 3 : tid:4 The QoS (b3-0) TID Field |
305 | * bit 4.. 6 : cid:3 The Source index that was found during parsing the TA. | 316 | * bit 4.. 6 : cid:3 The Source index that was found during parsing the TA. |
306 | * This field is used to define the source of the packet | 317 | * This field is used to define the source of the packet |
307 | * bit 7 : reserved:1 | 318 | * bit 7 : MAC_id_valid:1, 1 if MAC virtual number is valid. |
308 | * bit 8.. 9 : mid:2 The MAC virtual number | 319 | * bit 8.. 9 : mid:2 The MAC virtual number |
309 | * bit 10..11 : frame_type:2 : The FC (b3-2) - MPDU Type | 320 | * bit 10..11 : frame_type:2 : The FC (b3-2) - MPDU Type |
310 | * (management, data, control and extension) | 321 | * (management, data, control and extension) |
@@ -395,6 +406,7 @@ struct vring_rx_mac { | |||
395 | #define RX_DMA_D0_CMD_DMA_EOP BIT(8) | 406 | #define RX_DMA_D0_CMD_DMA_EOP BIT(8) |
396 | #define RX_DMA_D0_CMD_DMA_RT BIT(9) /* always 1 */ | 407 | #define RX_DMA_D0_CMD_DMA_RT BIT(9) /* always 1 */ |
397 | #define RX_DMA_D0_CMD_DMA_IT BIT(10) /* interrupt */ | 408 | #define RX_DMA_D0_CMD_DMA_IT BIT(10) /* interrupt */ |
409 | #define RX_MAC_D0_MAC_ID_VALID BIT(7) | ||
398 | 410 | ||
399 | /* Error field */ | 411 | /* Error field */ |
400 | #define RX_DMA_ERROR_FCS BIT(0) | 412 | #define RX_DMA_ERROR_FCS BIT(0) |
@@ -451,7 +463,8 @@ static inline int wil_rxdesc_cid(struct vring_rx_desc *d) | |||
451 | 463 | ||
452 | static inline int wil_rxdesc_mid(struct vring_rx_desc *d) | 464 | static inline int wil_rxdesc_mid(struct vring_rx_desc *d) |
453 | { | 465 | { |
454 | return WIL_GET_BITS(d->mac.d0, 8, 9); | 466 | return (d->mac.d0 & RX_MAC_D0_MAC_ID_VALID) ? |
467 | WIL_GET_BITS(d->mac.d0, 8, 9) : 0; | ||
455 | } | 468 | } |
456 | 469 | ||
457 | static inline int wil_rxdesc_ftype(struct vring_rx_desc *d) | 470 | static inline int wil_rxdesc_ftype(struct vring_rx_desc *d) |
@@ -517,7 +530,8 @@ static inline struct vring_rx_desc *wil_skb_rxdesc(struct sk_buff *skb) | |||
517 | 530 | ||
518 | void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev); | 531 | void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev); |
519 | void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb); | 532 | void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb); |
520 | void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq); | 533 | void wil_rx_bar(struct wil6210_priv *wil, struct wil6210_vif *vif, |
534 | u8 cid, u8 tid, u16 seq); | ||
521 | struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, | 535 | struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, |
522 | int size, u16 ssn); | 536 | int size, u16 ssn); |
523 | void wil_tid_ampdu_rx_free(struct wil6210_priv *wil, | 537 | void wil_tid_ampdu_rx_free(struct wil6210_priv *wil, |
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 0df2aada6659..f9c5155025bc 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include "wmi.h" | 27 | #include "wmi.h" |
28 | #include "wil_platform.h" | 28 | #include "wil_platform.h" |
29 | #include "fw.h" | ||
29 | 30 | ||
30 | extern bool no_fw_recovery; | 31 | extern bool no_fw_recovery; |
31 | extern unsigned int mtu_max; | 32 | extern unsigned int mtu_max; |
@@ -49,6 +50,11 @@ extern bool disable_ap_sme; | |||
49 | #define WIL_DEFAULT_BUS_REQUEST_KBPS 128000 /* ~1Gbps */ | 50 | #define WIL_DEFAULT_BUS_REQUEST_KBPS 128000 /* ~1Gbps */ |
50 | #define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */ | 51 | #define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */ |
51 | 52 | ||
53 | /* maximum number of virtual interfaces the driver supports | ||
54 | * (including the main interface) | ||
55 | */ | ||
56 | #define WIL_MAX_VIFS 4 | ||
57 | |||
52 | /** | 58 | /** |
53 | * extract bits [@b0:@b1] (inclusive) from the value @x | 59 | * extract bits [@b0:@b1] (inclusive) from the value @x |
54 | * it should be @b0 <= @b1, or result is incorrect | 60 | * it should be @b0 <= @b1, or result is incorrect |
@@ -463,13 +469,12 @@ struct vring_tx_data { | |||
463 | u16 agg_timeout; | 469 | u16 agg_timeout; |
464 | u8 agg_amsdu; | 470 | u8 agg_amsdu; |
465 | bool addba_in_progress; /* if set, agg_xxx is for request in progress */ | 471 | bool addba_in_progress; /* if set, agg_xxx is for request in progress */ |
472 | u8 mid; | ||
466 | spinlock_t lock; | 473 | spinlock_t lock; |
467 | }; | 474 | }; |
468 | 475 | ||
469 | enum { /* for wil6210_priv.status */ | 476 | enum { /* for wil6210_priv.status */ |
470 | wil_status_fwready = 0, /* FW operational */ | 477 | wil_status_fwready = 0, /* FW operational */ |
471 | wil_status_fwconnecting, | ||
472 | wil_status_fwconnected, | ||
473 | wil_status_dontscan, | 478 | wil_status_dontscan, |
474 | wil_status_mbox_ready, /* MBOX structures ready */ | 479 | wil_status_mbox_ready, /* MBOX structures ready */ |
475 | wil_status_irqen, /* interrupts enabled - for debug */ | 480 | wil_status_irqen, /* interrupts enabled - for debug */ |
@@ -541,7 +546,6 @@ struct wil_tid_crypto_rx { | |||
541 | struct wil_p2p_info { | 546 | struct wil_p2p_info { |
542 | struct ieee80211_channel listen_chan; | 547 | struct ieee80211_channel listen_chan; |
543 | u8 discovery_started; | 548 | u8 discovery_started; |
544 | u8 p2p_dev_started; | ||
545 | u64 cookie; | 549 | u64 cookie; |
546 | struct wireless_dev *pending_listen_wdev; | 550 | struct wireless_dev *pending_listen_wdev; |
547 | unsigned int listen_duration; | 551 | unsigned int listen_duration; |
@@ -584,6 +588,7 @@ struct wil_net_stats { | |||
584 | */ | 588 | */ |
585 | struct wil_sta_info { | 589 | struct wil_sta_info { |
586 | u8 addr[ETH_ALEN]; | 590 | u8 addr[ETH_ALEN]; |
591 | u8 mid; | ||
587 | enum wil_sta_status status; | 592 | enum wil_sta_status status; |
588 | struct wil_net_stats stats; | 593 | struct wil_net_stats stats; |
589 | /* Rx BACK */ | 594 | /* Rx BACK */ |
@@ -669,10 +674,44 @@ extern struct blink_on_off_time led_blink_time[WIL_LED_TIME_LAST]; | |||
669 | extern u8 led_id; | 674 | extern u8 led_id; |
670 | extern u8 led_polarity; | 675 | extern u8 led_polarity; |
671 | 676 | ||
677 | enum wil6210_vif_status { | ||
678 | wil_vif_fwconnecting, | ||
679 | wil_vif_fwconnected, | ||
680 | wil_vif_status_last /* keep last */ | ||
681 | }; | ||
682 | |||
683 | struct wil6210_vif { | ||
684 | struct wireless_dev wdev; | ||
685 | struct net_device *ndev; | ||
686 | struct wil6210_priv *wil; | ||
687 | u8 mid; | ||
688 | DECLARE_BITMAP(status, wil_vif_status_last); | ||
689 | u32 privacy; /* secure connection? */ | ||
690 | u16 channel; /* relevant in AP mode */ | ||
691 | u8 hidden_ssid; /* relevant in AP mode */ | ||
692 | u32 ap_isolate; /* no intra-BSS communication */ | ||
693 | bool pbss; | ||
694 | int bcast_vring; | ||
695 | struct cfg80211_bss *bss; /* connected bss, relevant in STA mode */ | ||
696 | int locally_generated_disc; /* relevant in STA mode */ | ||
697 | struct timer_list connect_timer; | ||
698 | struct work_struct disconnect_worker; | ||
699 | /* scan */ | ||
700 | struct cfg80211_scan_request *scan_request; | ||
701 | struct timer_list scan_timer; /* detect scan timeout */ | ||
702 | struct wil_p2p_info p2p; | ||
703 | /* keep alive */ | ||
704 | struct list_head probe_client_pending; | ||
705 | struct mutex probe_client_mutex; /* protect @probe_client_pending */ | ||
706 | struct work_struct probe_client_worker; | ||
707 | int net_queue_stopped; /* netif_tx_stop_all_queues invoked */ | ||
708 | }; | ||
709 | |||
672 | struct wil6210_priv { | 710 | struct wil6210_priv { |
673 | struct pci_dev *pdev; | 711 | struct pci_dev *pdev; |
674 | u32 bar_size; | 712 | u32 bar_size; |
675 | struct wireless_dev *wdev; | 713 | struct wiphy *wiphy; |
714 | struct net_device *main_ndev; | ||
676 | void __iomem *csr; | 715 | void __iomem *csr; |
677 | DECLARE_BITMAP(status, wil_status_last); | 716 | DECLARE_BITMAP(status, wil_status_last); |
678 | u8 fw_version[ETHTOOL_FWVERS_LEN]; | 717 | u8 fw_version[ETHTOOL_FWVERS_LEN]; |
@@ -686,21 +725,18 @@ struct wil6210_priv { | |||
686 | DECLARE_BITMAP(hw_capa, hw_capa_last); | 725 | DECLARE_BITMAP(hw_capa, hw_capa_last); |
687 | DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX); | 726 | DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX); |
688 | DECLARE_BITMAP(platform_capa, WIL_PLATFORM_CAPA_MAX); | 727 | DECLARE_BITMAP(platform_capa, WIL_PLATFORM_CAPA_MAX); |
689 | u8 n_mids; /* number of additional MIDs as reported by FW */ | ||
690 | u32 recovery_count; /* num of FW recovery attempts in a short time */ | 728 | u32 recovery_count; /* num of FW recovery attempts in a short time */ |
691 | u32 recovery_state; /* FW recovery state machine */ | 729 | u32 recovery_state; /* FW recovery state machine */ |
692 | unsigned long last_fw_recovery; /* jiffies of last fw recovery */ | 730 | unsigned long last_fw_recovery; /* jiffies of last fw recovery */ |
693 | wait_queue_head_t wq; /* for all wait_event() use */ | 731 | wait_queue_head_t wq; /* for all wait_event() use */ |
732 | u8 max_vifs; /* maximum number of interfaces, including main */ | ||
733 | struct wil6210_vif *vifs[WIL_MAX_VIFS]; | ||
734 | struct mutex vif_mutex; /* protects access to VIF entries */ | ||
735 | atomic_t connected_vifs; | ||
694 | /* profile */ | 736 | /* profile */ |
695 | struct cfg80211_chan_def monitor_chandef; | 737 | struct cfg80211_chan_def monitor_chandef; |
696 | u32 monitor_flags; | 738 | u32 monitor_flags; |
697 | u32 privacy; /* secure connection? */ | ||
698 | u8 hidden_ssid; /* relevant in AP mode */ | ||
699 | u16 channel; /* relevant in AP mode */ | ||
700 | int sinfo_gen; | 739 | int sinfo_gen; |
701 | u32 ap_isolate; /* no intra-BSS communication */ | ||
702 | struct cfg80211_bss *bss; /* connected bss, relevant in STA mode */ | ||
703 | int locally_generated_disc; /* relevant in STA mode */ | ||
704 | /* interrupt moderation */ | 740 | /* interrupt moderation */ |
705 | u32 tx_max_burst_duration; | 741 | u32 tx_max_burst_duration; |
706 | u32 tx_interframe_timeout; | 742 | u32 tx_interframe_timeout; |
@@ -715,15 +751,13 @@ struct wil6210_priv { | |||
715 | struct completion wmi_call; | 751 | struct completion wmi_call; |
716 | u16 wmi_seq; | 752 | u16 wmi_seq; |
717 | u16 reply_id; /**< wait for this WMI event */ | 753 | u16 reply_id; /**< wait for this WMI event */ |
754 | u8 reply_mid; | ||
718 | void *reply_buf; | 755 | void *reply_buf; |
719 | u16 reply_size; | 756 | u16 reply_size; |
720 | struct workqueue_struct *wmi_wq; /* for deferred calls */ | 757 | struct workqueue_struct *wmi_wq; /* for deferred calls */ |
721 | struct work_struct wmi_event_worker; | 758 | struct work_struct wmi_event_worker; |
722 | struct workqueue_struct *wq_service; | 759 | struct workqueue_struct *wq_service; |
723 | struct work_struct disconnect_worker; | ||
724 | struct work_struct fw_error_worker; /* for FW error recovery */ | 760 | struct work_struct fw_error_worker; /* for FW error recovery */ |
725 | struct timer_list connect_timer; | ||
726 | struct timer_list scan_timer; /* detect scan timeout */ | ||
727 | struct list_head pending_wmi_ev; | 761 | struct list_head pending_wmi_ev; |
728 | /* | 762 | /* |
729 | * protect pending_wmi_ev | 763 | * protect pending_wmi_ev |
@@ -732,13 +766,10 @@ struct wil6210_priv { | |||
732 | */ | 766 | */ |
733 | spinlock_t wmi_ev_lock; | 767 | spinlock_t wmi_ev_lock; |
734 | spinlock_t net_queue_lock; /* guarding stop/wake netif queue */ | 768 | spinlock_t net_queue_lock; /* guarding stop/wake netif queue */ |
735 | int net_queue_stopped; /* netif_tx_stop_all_queues invoked */ | ||
736 | struct napi_struct napi_rx; | 769 | struct napi_struct napi_rx; |
737 | struct napi_struct napi_tx; | 770 | struct napi_struct napi_tx; |
738 | /* keep alive */ | 771 | struct net_device napi_ndev; /* dummy net_device serving all VIFs */ |
739 | struct list_head probe_client_pending; | 772 | |
740 | struct mutex probe_client_mutex; /* protect @probe_client_pending */ | ||
741 | struct work_struct probe_client_worker; | ||
742 | /* DMA related */ | 773 | /* DMA related */ |
743 | struct vring vring_rx; | 774 | struct vring vring_rx; |
744 | unsigned int rx_buf_len; | 775 | unsigned int rx_buf_len; |
@@ -746,11 +777,8 @@ struct wil6210_priv { | |||
746 | struct vring_tx_data vring_tx_data[WIL6210_MAX_TX_RINGS]; | 777 | struct vring_tx_data vring_tx_data[WIL6210_MAX_TX_RINGS]; |
747 | u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */ | 778 | u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */ |
748 | struct wil_sta_info sta[WIL6210_MAX_CID]; | 779 | struct wil_sta_info sta[WIL6210_MAX_CID]; |
749 | int bcast_vring; | ||
750 | u32 vring_idle_trsh; /* HW fetches up to 16 descriptors at once */ | 780 | u32 vring_idle_trsh; /* HW fetches up to 16 descriptors at once */ |
751 | u32 dma_addr_size; /* indicates dma addr size */ | 781 | u32 dma_addr_size; /* indicates dma addr size */ |
752 | /* scan */ | ||
753 | struct cfg80211_scan_request *scan_request; | ||
754 | 782 | ||
755 | struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */ | 783 | struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */ |
756 | /* statistics */ | 784 | /* statistics */ |
@@ -770,13 +798,10 @@ struct wil6210_priv { | |||
770 | 798 | ||
771 | struct pmc_ctx pmc; | 799 | struct pmc_ctx pmc; |
772 | 800 | ||
773 | bool pbss; | 801 | u8 p2p_dev_started; |
774 | |||
775 | struct wil_p2p_info p2p; | ||
776 | 802 | ||
777 | /* P2P_DEVICE vif */ | 803 | /* P2P_DEVICE vif */ |
778 | struct wireless_dev *p2p_wdev; | 804 | struct wireless_dev *p2p_wdev; |
779 | struct mutex p2p_wdev_mutex; /* protect @p2p_wdev and @scan_request */ | ||
780 | struct wireless_dev *radio_wdev; | 805 | struct wireless_dev *radio_wdev; |
781 | 806 | ||
782 | /* High Access Latency Policy voting */ | 807 | /* High Access Latency Policy voting */ |
@@ -798,13 +823,35 @@ struct wil6210_priv { | |||
798 | u32 iccm_base; | 823 | u32 iccm_base; |
799 | }; | 824 | }; |
800 | 825 | ||
801 | #define wil_to_wiphy(i) (i->wdev->wiphy) | 826 | #define wil_to_wiphy(i) (i->wiphy) |
802 | #define wil_to_dev(i) (wiphy_dev(wil_to_wiphy(i))) | 827 | #define wil_to_dev(i) (wiphy_dev(wil_to_wiphy(i))) |
803 | #define wiphy_to_wil(w) (struct wil6210_priv *)(wiphy_priv(w)) | 828 | #define wiphy_to_wil(w) (struct wil6210_priv *)(wiphy_priv(w)) |
804 | #define wil_to_wdev(i) (i->wdev) | ||
805 | #define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w)) | 829 | #define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w)) |
806 | #define wil_to_ndev(i) (wil_to_wdev(i)->netdev) | ||
807 | #define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr)) | 830 | #define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr)) |
831 | #define ndev_to_vif(n) (struct wil6210_vif *)(netdev_priv(n)) | ||
832 | #define vif_to_wil(v) (v->wil) | ||
833 | #define vif_to_ndev(v) (v->ndev) | ||
834 | #define vif_to_wdev(v) (&v->wdev) | ||
835 | |||
836 | static inline struct wil6210_vif *wdev_to_vif(struct wil6210_priv *wil, | ||
837 | struct wireless_dev *wdev) | ||
838 | { | ||
839 | /* main interface is shared with P2P device */ | ||
840 | if (wdev == wil->p2p_wdev) | ||
841 | return ndev_to_vif(wil->main_ndev); | ||
842 | else | ||
843 | return container_of(wdev, struct wil6210_vif, wdev); | ||
844 | } | ||
845 | |||
846 | static inline struct wireless_dev * | ||
847 | vif_to_radio_wdev(struct wil6210_priv *wil, struct wil6210_vif *vif) | ||
848 | { | ||
849 | /* main interface is shared with P2P device */ | ||
850 | if (vif->mid) | ||
851 | return vif_to_wdev(vif); | ||
852 | else | ||
853 | return wil->radio_wdev; | ||
854 | } | ||
808 | 855 | ||
809 | __printf(2, 3) | 856 | __printf(2, 3) |
810 | void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...); | 857 | void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...); |
@@ -817,7 +864,7 @@ void __wil_info(struct wil6210_priv *wil, const char *fmt, ...); | |||
817 | __printf(2, 3) | 864 | __printf(2, 3) |
818 | void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...); | 865 | void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...); |
819 | #define wil_dbg(wil, fmt, arg...) do { \ | 866 | #define wil_dbg(wil, fmt, arg...) do { \ |
820 | netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \ | 867 | netdev_dbg(wil->main_ndev, fmt, ##arg); \ |
821 | wil_dbg_trace(wil, fmt, ##arg); \ | 868 | wil_dbg_trace(wil, fmt, ##arg); \ |
822 | } while (0) | 869 | } while (0) |
823 | 870 | ||
@@ -900,9 +947,18 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, | |||
900 | void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, | 947 | void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, |
901 | size_t count); | 948 | size_t count); |
902 | 949 | ||
950 | struct wil6210_vif * | ||
951 | wil_vif_alloc(struct wil6210_priv *wil, const char *name, | ||
952 | unsigned char name_assign_type, enum nl80211_iftype iftype); | ||
953 | void wil_vif_free(struct wil6210_vif *vif); | ||
903 | void *wil_if_alloc(struct device *dev); | 954 | void *wil_if_alloc(struct device *dev); |
955 | bool wil_has_other_active_ifaces(struct wil6210_priv *wil, | ||
956 | struct net_device *ndev, bool up, bool ok); | ||
957 | bool wil_has_active_ifaces(struct wil6210_priv *wil, bool up, bool ok); | ||
904 | void wil_if_free(struct wil6210_priv *wil); | 958 | void wil_if_free(struct wil6210_priv *wil); |
959 | int wil_vif_add(struct wil6210_priv *wil, struct wil6210_vif *vif); | ||
905 | int wil_if_add(struct wil6210_priv *wil); | 960 | int wil_if_add(struct wil6210_priv *wil); |
961 | void wil_vif_remove(struct wil6210_priv *wil, u8 mid); | ||
906 | void wil_if_remove(struct wil6210_priv *wil); | 962 | void wil_if_remove(struct wil6210_priv *wil); |
907 | int wil_priv_init(struct wil6210_priv *wil); | 963 | int wil_priv_init(struct wil6210_priv *wil); |
908 | void wil_priv_deinit(struct wil6210_priv *wil); | 964 | void wil_priv_deinit(struct wil6210_priv *wil); |
@@ -918,7 +974,7 @@ int wil_down(struct wil6210_priv *wil); | |||
918 | int __wil_down(struct wil6210_priv *wil); | 974 | int __wil_down(struct wil6210_priv *wil); |
919 | void wil_refresh_fw_capabilities(struct wil6210_priv *wil); | 975 | void wil_refresh_fw_capabilities(struct wil6210_priv *wil); |
920 | void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); | 976 | void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); |
921 | int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); | 977 | int wil_find_cid(struct wil6210_priv *wil, u8 mid, const u8 *mac); |
922 | void wil_set_ethtoolops(struct net_device *ndev); | 978 | void wil_set_ethtoolops(struct net_device *ndev); |
923 | 979 | ||
924 | struct fw_map *wil_find_fw_mapping(const char *section); | 980 | struct fw_map *wil_find_fw_mapping(const char *section); |
@@ -927,40 +983,45 @@ void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr); | |||
927 | void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); | 983 | void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); |
928 | int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, | 984 | int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, |
929 | struct wil6210_mbox_hdr *hdr); | 985 | struct wil6210_mbox_hdr *hdr); |
930 | int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len); | 986 | int wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len); |
931 | void wmi_recv_cmd(struct wil6210_priv *wil); | 987 | void wmi_recv_cmd(struct wil6210_priv *wil); |
932 | int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, | 988 | int wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len, |
933 | u16 reply_id, void *reply, u8 reply_size, int to_msec); | 989 | u16 reply_id, void *reply, u8 reply_size, int to_msec); |
934 | void wmi_event_worker(struct work_struct *work); | 990 | void wmi_event_worker(struct work_struct *work); |
935 | void wmi_event_flush(struct wil6210_priv *wil); | 991 | void wmi_event_flush(struct wil6210_priv *wil); |
936 | int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid); | 992 | int wmi_set_ssid(struct wil6210_vif *vif, u8 ssid_len, const void *ssid); |
937 | int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid); | 993 | int wmi_get_ssid(struct wil6210_vif *vif, u8 *ssid_len, void *ssid); |
938 | int wmi_set_channel(struct wil6210_priv *wil, int channel); | 994 | int wmi_set_channel(struct wil6210_priv *wil, int channel); |
939 | int wmi_get_channel(struct wil6210_priv *wil, int *channel); | 995 | int wmi_get_channel(struct wil6210_priv *wil, int *channel); |
940 | int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, | 996 | int wmi_del_cipher_key(struct wil6210_vif *vif, u8 key_index, |
941 | const void *mac_addr, int key_usage); | 997 | const void *mac_addr, int key_usage); |
942 | int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, | 998 | int wmi_add_cipher_key(struct wil6210_vif *vif, u8 key_index, |
943 | const void *mac_addr, int key_len, const void *key, | 999 | const void *mac_addr, int key_len, const void *key, |
944 | int key_usage); | 1000 | int key_usage); |
945 | int wmi_echo(struct wil6210_priv *wil); | 1001 | int wmi_echo(struct wil6210_priv *wil); |
946 | int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie); | 1002 | int wmi_set_ie(struct wil6210_vif *vif, u8 type, u16 ie_len, const void *ie); |
947 | int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring); | 1003 | int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring); |
948 | int wmi_rxon(struct wil6210_priv *wil, bool on); | 1004 | int wmi_rxon(struct wil6210_priv *wil, bool on); |
949 | int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); | 1005 | int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); |
950 | int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, | 1006 | int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac, |
951 | u16 reason, bool full_disconnect, bool del_sta); | 1007 | u16 reason, bool full_disconnect, bool del_sta); |
952 | int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout); | 1008 | int wmi_addba(struct wil6210_priv *wil, u8 mid, |
953 | int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason); | 1009 | u8 ringid, u8 size, u16 timeout); |
954 | int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason); | 1010 | int wmi_delba_tx(struct wil6210_priv *wil, u8 mid, u8 ringid, u16 reason); |
955 | int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, | 1011 | int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cidxtid, u16 reason); |
1012 | int wmi_addba_rx_resp(struct wil6210_priv *wil, | ||
1013 | u8 mid, u8 cid, u8 tid, u8 token, | ||
956 | u16 status, bool amsdu, u16 agg_wsize, u16 timeout); | 1014 | u16 status, bool amsdu, u16 agg_wsize, u16 timeout); |
957 | int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, | 1015 | int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, |
958 | enum wmi_ps_profile_type ps_profile); | 1016 | enum wmi_ps_profile_type ps_profile); |
959 | int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short); | 1017 | int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short); |
960 | int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short); | 1018 | int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short); |
961 | int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid); | 1019 | int wmi_new_sta(struct wil6210_vif *vif, const u8 *mac, u8 aid); |
962 | int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid, | 1020 | int wmi_port_allocate(struct wil6210_priv *wil, u8 mid, |
963 | u8 dialog_token, __le16 ba_param_set, | 1021 | const u8 *mac, enum nl80211_iftype iftype); |
1022 | int wmi_port_delete(struct wil6210_priv *wil, u8 mid); | ||
1023 | int wil_addba_rx_request(struct wil6210_priv *wil, u8 mid, | ||
1024 | u8 cidxtid, u8 dialog_token, __le16 ba_param_set, | ||
964 | __le16 ba_timeout, __le16 ba_seq_ctrl); | 1025 | __le16 ba_timeout, __le16 ba_seq_ctrl); |
965 | int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize); | 1026 | int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize); |
966 | 1027 | ||
@@ -976,28 +1037,31 @@ void wil6210_mask_halp(struct wil6210_priv *wil); | |||
976 | 1037 | ||
977 | /* P2P */ | 1038 | /* P2P */ |
978 | bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request); | 1039 | bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request); |
979 | void wil_p2p_discovery_timer_fn(struct timer_list *t); | 1040 | int wil_p2p_search(struct wil6210_vif *vif, |
980 | int wil_p2p_search(struct wil6210_priv *wil, | ||
981 | struct cfg80211_scan_request *request); | 1041 | struct cfg80211_scan_request *request); |
982 | int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev, | 1042 | int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev, |
983 | unsigned int duration, struct ieee80211_channel *chan, | 1043 | unsigned int duration, struct ieee80211_channel *chan, |
984 | u64 *cookie); | 1044 | u64 *cookie); |
985 | u8 wil_p2p_stop_discovery(struct wil6210_priv *wil); | 1045 | u8 wil_p2p_stop_discovery(struct wil6210_vif *vif); |
986 | int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie); | 1046 | int wil_p2p_cancel_listen(struct wil6210_vif *vif, u64 cookie); |
987 | void wil_p2p_listen_expired(struct work_struct *work); | 1047 | void wil_p2p_listen_expired(struct work_struct *work); |
988 | void wil_p2p_search_expired(struct work_struct *work); | 1048 | void wil_p2p_search_expired(struct work_struct *work); |
989 | void wil_p2p_stop_radio_operations(struct wil6210_priv *wil); | 1049 | void wil_p2p_stop_radio_operations(struct wil6210_priv *wil); |
990 | void wil_p2p_delayed_listen_work(struct work_struct *work); | 1050 | void wil_p2p_delayed_listen_work(struct work_struct *work); |
991 | 1051 | ||
992 | /* WMI for P2P */ | 1052 | /* WMI for P2P */ |
993 | int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi); | 1053 | int wmi_p2p_cfg(struct wil6210_vif *vif, int channel, int bi); |
994 | int wmi_start_listen(struct wil6210_priv *wil); | 1054 | int wmi_start_listen(struct wil6210_vif *vif); |
995 | int wmi_start_search(struct wil6210_priv *wil); | 1055 | int wmi_start_search(struct wil6210_vif *vif); |
996 | int wmi_stop_discovery(struct wil6210_priv *wil); | 1056 | int wmi_stop_discovery(struct wil6210_vif *vif); |
997 | 1057 | ||
998 | int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | 1058 | int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, |
999 | struct cfg80211_mgmt_tx_params *params, | 1059 | struct cfg80211_mgmt_tx_params *params, |
1000 | u64 *cookie); | 1060 | u64 *cookie); |
1061 | int wil_cfg80211_iface_combinations_from_fw( | ||
1062 | struct wil6210_priv *wil, | ||
1063 | const struct wil_fw_record_concurrency *conc); | ||
1064 | int wil_vif_prepare_stop(struct wil6210_vif *vif); | ||
1001 | 1065 | ||
1002 | #if defined(CONFIG_WIL6210_DEBUGFS) | 1066 | #if defined(CONFIG_WIL6210_DEBUGFS) |
1003 | int wil6210_debugfs_init(struct wil6210_priv *wil); | 1067 | int wil6210_debugfs_init(struct wil6210_priv *wil); |
@@ -1007,44 +1071,47 @@ static inline int wil6210_debugfs_init(struct wil6210_priv *wil) { return 0; } | |||
1007 | static inline void wil6210_debugfs_remove(struct wil6210_priv *wil) {} | 1071 | static inline void wil6210_debugfs_remove(struct wil6210_priv *wil) {} |
1008 | #endif | 1072 | #endif |
1009 | 1073 | ||
1010 | int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, | 1074 | int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid, |
1011 | struct station_info *sinfo); | 1075 | struct station_info *sinfo); |
1012 | 1076 | ||
1013 | struct wireless_dev *wil_cfg80211_init(struct device *dev); | 1077 | struct wil6210_priv *wil_cfg80211_init(struct device *dev); |
1014 | void wil_wdev_free(struct wil6210_priv *wil); | 1078 | void wil_cfg80211_deinit(struct wil6210_priv *wil); |
1015 | void wil_p2p_wdev_free(struct wil6210_priv *wil); | 1079 | void wil_p2p_wdev_free(struct wil6210_priv *wil); |
1016 | 1080 | ||
1017 | int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); | 1081 | int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); |
1018 | int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, | 1082 | int wmi_pcp_start(struct wil6210_vif *vif, int bi, u8 wmi_nettype, u8 chan, |
1019 | u8 chan, u8 hidden_ssid, u8 is_go); | 1083 | u8 hidden_ssid, u8 is_go); |
1020 | int wmi_pcp_stop(struct wil6210_priv *wil); | 1084 | int wmi_pcp_stop(struct wil6210_vif *vif); |
1021 | int wmi_led_cfg(struct wil6210_priv *wil, bool enable); | 1085 | int wmi_led_cfg(struct wil6210_priv *wil, bool enable); |
1022 | int wmi_abort_scan(struct wil6210_priv *wil); | 1086 | int wmi_abort_scan(struct wil6210_vif *vif); |
1023 | void wil_abort_scan(struct wil6210_priv *wil, bool sync); | 1087 | void wil_abort_scan(struct wil6210_vif *vif, bool sync); |
1088 | void wil_abort_scan_all_vifs(struct wil6210_priv *wil, bool sync); | ||
1024 | void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps); | 1089 | void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps); |
1025 | void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, | 1090 | void wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid, |
1026 | u16 reason_code, bool from_event); | 1091 | u16 reason_code, bool from_event); |
1027 | void wil_probe_client_flush(struct wil6210_priv *wil); | 1092 | void wil_probe_client_flush(struct wil6210_vif *vif); |
1028 | void wil_probe_client_worker(struct work_struct *work); | 1093 | void wil_probe_client_worker(struct work_struct *work); |
1094 | void wil_disconnect_worker(struct work_struct *work); | ||
1029 | 1095 | ||
1030 | int wil_rx_init(struct wil6210_priv *wil, u16 size); | 1096 | int wil_rx_init(struct wil6210_priv *wil, u16 size); |
1031 | void wil_rx_fini(struct wil6210_priv *wil); | 1097 | void wil_rx_fini(struct wil6210_priv *wil); |
1032 | 1098 | ||
1033 | /* TX API */ | 1099 | /* TX API */ |
1034 | int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | 1100 | int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size, |
1035 | int cid, int tid); | 1101 | int cid, int tid); |
1036 | void wil_vring_fini_tx(struct wil6210_priv *wil, int id); | 1102 | void wil_vring_fini_tx(struct wil6210_priv *wil, int id); |
1037 | int wil_tx_init(struct wil6210_priv *wil, int cid); | 1103 | int wil_tx_init(struct wil6210_vif *vif, int cid); |
1038 | int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size); | 1104 | int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size); |
1039 | int wil_bcast_init(struct wil6210_priv *wil); | 1105 | int wil_bcast_init(struct wil6210_vif *vif); |
1040 | void wil_bcast_fini(struct wil6210_priv *wil); | 1106 | void wil_bcast_fini(struct wil6210_vif *vif); |
1041 | 1107 | void wil_bcast_fini_all(struct wil6210_priv *wil); | |
1042 | void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring, | 1108 | |
1043 | bool should_stop); | 1109 | void wil_update_net_queues(struct wil6210_priv *wil, struct wil6210_vif *vif, |
1044 | void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring, | 1110 | struct vring *vring, bool should_stop); |
1045 | bool check_stop); | 1111 | void wil_update_net_queues_bh(struct wil6210_priv *wil, struct wil6210_vif *vif, |
1112 | struct vring *vring, bool check_stop); | ||
1046 | netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); | 1113 | netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); |
1047 | int wil_tx_complete(struct wil6210_priv *wil, int ringid); | 1114 | int wil_tx_complete(struct wil6210_vif *vif, int ringid); |
1048 | void wil6210_unmask_irq_tx(struct wil6210_priv *wil); | 1115 | void wil6210_unmask_irq_tx(struct wil6210_priv *wil); |
1049 | 1116 | ||
1050 | /* RX API */ | 1117 | /* RX API */ |
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index b31e2514f8c2..a3dda9a97c1f 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c | |||
@@ -341,6 +341,10 @@ static const char *cmdid2name(u16 cmdid) | |||
341 | return "WMI_GET_PCP_CHANNEL_CMD"; | 341 | return "WMI_GET_PCP_CHANNEL_CMD"; |
342 | case WMI_P2P_CFG_CMDID: | 342 | case WMI_P2P_CFG_CMDID: |
343 | return "WMI_P2P_CFG_CMD"; | 343 | return "WMI_P2P_CFG_CMD"; |
344 | case WMI_PORT_ALLOCATE_CMDID: | ||
345 | return "WMI_PORT_ALLOCATE_CMD"; | ||
346 | case WMI_PORT_DELETE_CMDID: | ||
347 | return "WMI_PORT_DELETE_CMD"; | ||
344 | case WMI_START_LISTEN_CMDID: | 348 | case WMI_START_LISTEN_CMDID: |
345 | return "WMI_START_LISTEN_CMD"; | 349 | return "WMI_START_LISTEN_CMD"; |
346 | case WMI_START_SEARCH_CMDID: | 350 | case WMI_START_SEARCH_CMDID: |
@@ -479,6 +483,10 @@ static const char *eventid2name(u16 eventid) | |||
479 | return "WMI_GET_PCP_CHANNEL_EVENT"; | 483 | return "WMI_GET_PCP_CHANNEL_EVENT"; |
480 | case WMI_P2P_CFG_DONE_EVENTID: | 484 | case WMI_P2P_CFG_DONE_EVENTID: |
481 | return "WMI_P2P_CFG_DONE_EVENT"; | 485 | return "WMI_P2P_CFG_DONE_EVENT"; |
486 | case WMI_PORT_ALLOCATED_EVENTID: | ||
487 | return "WMI_PORT_ALLOCATED_EVENT"; | ||
488 | case WMI_PORT_DELETED_EVENTID: | ||
489 | return "WMI_PORT_DELETED_EVENT"; | ||
482 | case WMI_LISTEN_STARTED_EVENTID: | 490 | case WMI_LISTEN_STARTED_EVENTID: |
483 | return "WMI_LISTEN_STARTED_EVENT"; | 491 | return "WMI_LISTEN_STARTED_EVENT"; |
484 | case WMI_SEARCH_STARTED_EVENTID: | 492 | case WMI_SEARCH_STARTED_EVENTID: |
@@ -516,7 +524,8 @@ static const char *eventid2name(u16 eventid) | |||
516 | } | 524 | } |
517 | } | 525 | } |
518 | 526 | ||
519 | static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) | 527 | static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, |
528 | void *buf, u16 len) | ||
520 | { | 529 | { |
521 | struct { | 530 | struct { |
522 | struct wil6210_mbox_hdr hdr; | 531 | struct wil6210_mbox_hdr hdr; |
@@ -528,7 +537,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) | |||
528 | .len = cpu_to_le16(sizeof(cmd.wmi) + len), | 537 | .len = cpu_to_le16(sizeof(cmd.wmi) + len), |
529 | }, | 538 | }, |
530 | .wmi = { | 539 | .wmi = { |
531 | .mid = 0, | 540 | .mid = mid, |
532 | .command_id = cpu_to_le16(cmdid), | 541 | .command_id = cpu_to_le16(cmdid), |
533 | }, | 542 | }, |
534 | }; | 543 | }; |
@@ -612,8 +621,8 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) | |||
612 | } | 621 | } |
613 | cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq); | 622 | cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq); |
614 | /* set command */ | 623 | /* set command */ |
615 | wil_dbg_wmi(wil, "sending %s (0x%04x) [%d]\n", | 624 | wil_dbg_wmi(wil, "sending %s (0x%04x) [%d] mid %d\n", |
616 | cmdid2name(cmdid), cmdid, len); | 625 | cmdid2name(cmdid), cmdid, len, mid); |
617 | wil_hex_dump_wmi("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd, | 626 | wil_hex_dump_wmi("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd, |
618 | sizeof(cmd), true); | 627 | sizeof(cmd), true); |
619 | wil_hex_dump_wmi("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf, | 628 | wil_hex_dump_wmi("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf, |
@@ -637,31 +646,34 @@ out: | |||
637 | return rc; | 646 | return rc; |
638 | } | 647 | } |
639 | 648 | ||
640 | int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) | 649 | int wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len) |
641 | { | 650 | { |
642 | int rc; | 651 | int rc; |
643 | 652 | ||
644 | mutex_lock(&wil->wmi_mutex); | 653 | mutex_lock(&wil->wmi_mutex); |
645 | rc = __wmi_send(wil, cmdid, buf, len); | 654 | rc = __wmi_send(wil, cmdid, mid, buf, len); |
646 | mutex_unlock(&wil->wmi_mutex); | 655 | mutex_unlock(&wil->wmi_mutex); |
647 | 656 | ||
648 | return rc; | 657 | return rc; |
649 | } | 658 | } |
650 | 659 | ||
651 | /*=== Event handlers ===*/ | 660 | /*=== Event handlers ===*/ |
652 | static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) | 661 | static void wmi_evt_ready(struct wil6210_vif *vif, int id, void *d, int len) |
653 | { | 662 | { |
654 | struct wireless_dev *wdev = wil->wdev; | 663 | struct wil6210_priv *wil = vif_to_wil(vif); |
664 | struct wiphy *wiphy = wil_to_wiphy(wil); | ||
655 | struct wmi_ready_event *evt = d; | 665 | struct wmi_ready_event *evt = d; |
656 | 666 | ||
657 | wil->n_mids = evt->numof_additional_mids; | ||
658 | |||
659 | wil_info(wil, "FW ver. %s(SW %d); MAC %pM; %d MID's\n", | 667 | wil_info(wil, "FW ver. %s(SW %d); MAC %pM; %d MID's\n", |
660 | wil->fw_version, le32_to_cpu(evt->sw_version), | 668 | wil->fw_version, le32_to_cpu(evt->sw_version), |
661 | evt->mac, wil->n_mids); | 669 | evt->mac, evt->numof_additional_mids); |
670 | if (evt->numof_additional_mids + 1 < wil->max_vifs) { | ||
671 | wil_err(wil, "FW does not support enough MIDs (need %d)", | ||
672 | wil->max_vifs - 1); | ||
673 | return; /* FW load will fail after timeout */ | ||
674 | } | ||
662 | /* ignore MAC address, we already have it from the boot loader */ | 675 | /* ignore MAC address, we already have it from the boot loader */ |
663 | strlcpy(wdev->wiphy->fw_version, wil->fw_version, | 676 | strlcpy(wiphy->fw_version, wil->fw_version, sizeof(wiphy->fw_version)); |
664 | sizeof(wdev->wiphy->fw_version)); | ||
665 | 677 | ||
666 | if (len > offsetof(struct wmi_ready_event, rfc_read_calib_result)) { | 678 | if (len > offsetof(struct wmi_ready_event, rfc_read_calib_result)) { |
667 | wil_dbg_wmi(wil, "rfc calibration result %d\n", | 679 | wil_dbg_wmi(wil, "rfc calibration result %d\n", |
@@ -674,8 +686,9 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) | |||
674 | complete(&wil->wmi_ready); | 686 | complete(&wil->wmi_ready); |
675 | } | 687 | } |
676 | 688 | ||
677 | static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) | 689 | static void wmi_evt_rx_mgmt(struct wil6210_vif *vif, int id, void *d, int len) |
678 | { | 690 | { |
691 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
679 | struct wmi_rx_mgmt_packet_event *data = d; | 692 | struct wmi_rx_mgmt_packet_event *data = d; |
680 | struct wiphy *wiphy = wil_to_wiphy(wil); | 693 | struct wiphy *wiphy = wil_to_wiphy(wil); |
681 | struct ieee80211_mgmt *rx_mgmt_frame = | 694 | struct ieee80211_mgmt *rx_mgmt_frame = |
@@ -753,14 +766,14 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) | |||
753 | wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); | 766 | wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); |
754 | } | 767 | } |
755 | } else { | 768 | } else { |
756 | mutex_lock(&wil->p2p_wdev_mutex); | 769 | mutex_lock(&wil->vif_mutex); |
757 | cfg80211_rx_mgmt(wil->radio_wdev, freq, signal, | 770 | cfg80211_rx_mgmt(vif_to_radio_wdev(wil, vif), freq, signal, |
758 | (void *)rx_mgmt_frame, d_len, 0); | 771 | (void *)rx_mgmt_frame, d_len, 0); |
759 | mutex_unlock(&wil->p2p_wdev_mutex); | 772 | mutex_unlock(&wil->vif_mutex); |
760 | } | 773 | } |
761 | } | 774 | } |
762 | 775 | ||
763 | static void wmi_evt_tx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) | 776 | static void wmi_evt_tx_mgmt(struct wil6210_vif *vif, int id, void *d, int len) |
764 | { | 777 | { |
765 | struct wmi_tx_mgmt_packet_event *data = d; | 778 | struct wmi_tx_mgmt_packet_event *data = d; |
766 | struct ieee80211_mgmt *mgmt_frame = | 779 | struct ieee80211_mgmt *mgmt_frame = |
@@ -771,11 +784,13 @@ static void wmi_evt_tx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) | |||
771 | flen, true); | 784 | flen, true); |
772 | } | 785 | } |
773 | 786 | ||
774 | static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, | 787 | static void wmi_evt_scan_complete(struct wil6210_vif *vif, int id, |
775 | void *d, int len) | 788 | void *d, int len) |
776 | { | 789 | { |
777 | mutex_lock(&wil->p2p_wdev_mutex); | 790 | struct wil6210_priv *wil = vif_to_wil(vif); |
778 | if (wil->scan_request) { | 791 | |
792 | mutex_lock(&wil->vif_mutex); | ||
793 | if (vif->scan_request) { | ||
779 | struct wmi_scan_complete_event *data = d; | 794 | struct wmi_scan_complete_event *data = d; |
780 | int status = le32_to_cpu(data->status); | 795 | int status = le32_to_cpu(data->status); |
781 | struct cfg80211_scan_info info = { | 796 | struct cfg80211_scan_info info = { |
@@ -785,26 +800,28 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, | |||
785 | 800 | ||
786 | wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status); | 801 | wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status); |
787 | wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n", | 802 | wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n", |
788 | wil->scan_request, info.aborted); | 803 | vif->scan_request, info.aborted); |
789 | del_timer_sync(&wil->scan_timer); | 804 | del_timer_sync(&vif->scan_timer); |
790 | cfg80211_scan_done(wil->scan_request, &info); | 805 | cfg80211_scan_done(vif->scan_request, &info); |
791 | wil->radio_wdev = wil->wdev; | 806 | if (vif->mid == 0) |
792 | wil->scan_request = NULL; | 807 | wil->radio_wdev = wil->main_ndev->ieee80211_ptr; |
808 | vif->scan_request = NULL; | ||
793 | wake_up_interruptible(&wil->wq); | 809 | wake_up_interruptible(&wil->wq); |
794 | if (wil->p2p.pending_listen_wdev) { | 810 | if (vif->p2p.pending_listen_wdev) { |
795 | wil_dbg_misc(wil, "Scheduling delayed listen\n"); | 811 | wil_dbg_misc(wil, "Scheduling delayed listen\n"); |
796 | schedule_work(&wil->p2p.delayed_listen_work); | 812 | schedule_work(&vif->p2p.delayed_listen_work); |
797 | } | 813 | } |
798 | } else { | 814 | } else { |
799 | wil_err(wil, "SCAN_COMPLETE while not scanning\n"); | 815 | wil_err(wil, "SCAN_COMPLETE while not scanning\n"); |
800 | } | 816 | } |
801 | mutex_unlock(&wil->p2p_wdev_mutex); | 817 | mutex_unlock(&wil->vif_mutex); |
802 | } | 818 | } |
803 | 819 | ||
804 | static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) | 820 | static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len) |
805 | { | 821 | { |
806 | struct net_device *ndev = wil_to_ndev(wil); | 822 | struct wil6210_priv *wil = vif_to_wil(vif); |
807 | struct wireless_dev *wdev = wil->wdev; | 823 | struct net_device *ndev = vif_to_ndev(vif); |
824 | struct wireless_dev *wdev = vif_to_wdev(vif); | ||
808 | struct wmi_connect_event *evt = d; | 825 | struct wmi_connect_event *evt = d; |
809 | int ch; /* channel number */ | 826 | int ch; /* channel number */ |
810 | struct station_info sinfo; | 827 | struct station_info sinfo; |
@@ -869,12 +886,12 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) | |||
869 | 886 | ||
870 | if ((wdev->iftype == NL80211_IFTYPE_STATION) || | 887 | if ((wdev->iftype == NL80211_IFTYPE_STATION) || |
871 | (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { | 888 | (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { |
872 | if (!test_bit(wil_status_fwconnecting, wil->status)) { | 889 | if (!test_bit(wil_vif_fwconnecting, vif->status)) { |
873 | wil_err(wil, "Not in connecting state\n"); | 890 | wil_err(wil, "Not in connecting state\n"); |
874 | mutex_unlock(&wil->mutex); | 891 | mutex_unlock(&wil->mutex); |
875 | return; | 892 | return; |
876 | } | 893 | } |
877 | del_timer_sync(&wil->connect_timer); | 894 | del_timer_sync(&vif->connect_timer); |
878 | } else if ((wdev->iftype == NL80211_IFTYPE_AP) || | 895 | } else if ((wdev->iftype == NL80211_IFTYPE_AP) || |
879 | (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { | 896 | (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { |
880 | if (wil->sta[evt->cid].status != wil_sta_unused) { | 897 | if (wil->sta[evt->cid].status != wil_sta_unused) { |
@@ -886,13 +903,14 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) | |||
886 | } | 903 | } |
887 | 904 | ||
888 | ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid); | 905 | ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid); |
906 | wil->sta[evt->cid].mid = vif->mid; | ||
889 | wil->sta[evt->cid].status = wil_sta_conn_pending; | 907 | wil->sta[evt->cid].status = wil_sta_conn_pending; |
890 | 908 | ||
891 | rc = wil_tx_init(wil, evt->cid); | 909 | rc = wil_tx_init(vif, evt->cid); |
892 | if (rc) { | 910 | if (rc) { |
893 | wil_err(wil, "config tx vring failed for CID %d, rc (%d)\n", | 911 | wil_err(wil, "config tx vring failed for CID %d, rc (%d)\n", |
894 | evt->cid, rc); | 912 | evt->cid, rc); |
895 | wmi_disconnect_sta(wil, wil->sta[evt->cid].addr, | 913 | wmi_disconnect_sta(vif, wil->sta[evt->cid].addr, |
896 | WLAN_REASON_UNSPECIFIED, false, false); | 914 | WLAN_REASON_UNSPECIFIED, false, false); |
897 | } else { | 915 | } else { |
898 | wil_info(wil, "successful connection to CID %d\n", evt->cid); | 916 | wil_info(wil, "successful connection to CID %d\n", evt->cid); |
@@ -912,14 +930,14 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) | |||
912 | } else { | 930 | } else { |
913 | struct wiphy *wiphy = wil_to_wiphy(wil); | 931 | struct wiphy *wiphy = wil_to_wiphy(wil); |
914 | 932 | ||
915 | cfg80211_ref_bss(wiphy, wil->bss); | 933 | cfg80211_ref_bss(wiphy, vif->bss); |
916 | cfg80211_connect_bss(ndev, evt->bssid, wil->bss, | 934 | cfg80211_connect_bss(ndev, evt->bssid, vif->bss, |
917 | assoc_req_ie, assoc_req_ielen, | 935 | assoc_req_ie, assoc_req_ielen, |
918 | assoc_resp_ie, assoc_resp_ielen, | 936 | assoc_resp_ie, assoc_resp_ielen, |
919 | WLAN_STATUS_SUCCESS, GFP_KERNEL, | 937 | WLAN_STATUS_SUCCESS, GFP_KERNEL, |
920 | NL80211_TIMEOUT_UNSPECIFIED); | 938 | NL80211_TIMEOUT_UNSPECIFIED); |
921 | } | 939 | } |
922 | wil->bss = NULL; | 940 | vif->bss = NULL; |
923 | } else if ((wdev->iftype == NL80211_IFTYPE_AP) || | 941 | } else if ((wdev->iftype == NL80211_IFTYPE_AP) || |
924 | (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { | 942 | (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { |
925 | if (rc) { | 943 | if (rc) { |
@@ -947,19 +965,23 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) | |||
947 | 965 | ||
948 | wil->sta[evt->cid].status = wil_sta_connected; | 966 | wil->sta[evt->cid].status = wil_sta_connected; |
949 | wil->sta[evt->cid].aid = evt->aid; | 967 | wil->sta[evt->cid].aid = evt->aid; |
950 | set_bit(wil_status_fwconnected, wil->status); | 968 | if (!test_and_set_bit(wil_vif_fwconnected, vif->status)) |
951 | wil_update_net_queues_bh(wil, NULL, false); | 969 | atomic_inc(&wil->connected_vifs); |
970 | wil_update_net_queues_bh(wil, vif, NULL, false); | ||
952 | 971 | ||
953 | out: | 972 | out: |
954 | if (rc) | 973 | if (rc) { |
955 | wil->sta[evt->cid].status = wil_sta_unused; | 974 | wil->sta[evt->cid].status = wil_sta_unused; |
956 | clear_bit(wil_status_fwconnecting, wil->status); | 975 | wil->sta[evt->cid].mid = U8_MAX; |
976 | } | ||
977 | clear_bit(wil_vif_fwconnecting, vif->status); | ||
957 | mutex_unlock(&wil->mutex); | 978 | mutex_unlock(&wil->mutex); |
958 | } | 979 | } |
959 | 980 | ||
960 | static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, | 981 | static void wmi_evt_disconnect(struct wil6210_vif *vif, int id, |
961 | void *d, int len) | 982 | void *d, int len) |
962 | { | 983 | { |
984 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
963 | struct wmi_disconnect_event *evt = d; | 985 | struct wmi_disconnect_event *evt = d; |
964 | u16 reason_code = le16_to_cpu(evt->protocol_reason_status); | 986 | u16 reason_code = le16_to_cpu(evt->protocol_reason_status); |
965 | 987 | ||
@@ -976,7 +998,7 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, | |||
976 | } | 998 | } |
977 | 999 | ||
978 | mutex_lock(&wil->mutex); | 1000 | mutex_lock(&wil->mutex); |
979 | wil6210_disconnect(wil, evt->bssid, reason_code, true); | 1001 | wil6210_disconnect(vif, evt->bssid, reason_code, true); |
980 | mutex_unlock(&wil->mutex); | 1002 | mutex_unlock(&wil->mutex); |
981 | } | 1003 | } |
982 | 1004 | ||
@@ -984,10 +1006,10 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, | |||
984 | * Firmware reports EAPOL frame using WME event. | 1006 | * Firmware reports EAPOL frame using WME event. |
985 | * Reconstruct Ethernet frame and deliver it via normal Rx | 1007 | * Reconstruct Ethernet frame and deliver it via normal Rx |
986 | */ | 1008 | */ |
987 | static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id, | 1009 | static void wmi_evt_eapol_rx(struct wil6210_vif *vif, int id, void *d, int len) |
988 | void *d, int len) | ||
989 | { | 1010 | { |
990 | struct net_device *ndev = wil_to_ndev(wil); | 1011 | struct wil6210_priv *wil = vif_to_wil(vif); |
1012 | struct net_device *ndev = vif_to_ndev(vif); | ||
991 | struct wmi_eapol_rx_event *evt = d; | 1013 | struct wmi_eapol_rx_event *evt = d; |
992 | u16 eapol_len = le16_to_cpu(evt->eapol_len); | 1014 | u16 eapol_len = le16_to_cpu(evt->eapol_len); |
993 | int sz = eapol_len + ETH_HLEN; | 1015 | int sz = eapol_len + ETH_HLEN; |
@@ -996,10 +1018,10 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id, | |||
996 | int cid; | 1018 | int cid; |
997 | struct wil_net_stats *stats = NULL; | 1019 | struct wil_net_stats *stats = NULL; |
998 | 1020 | ||
999 | wil_dbg_wmi(wil, "EAPOL len %d from %pM\n", eapol_len, | 1021 | wil_dbg_wmi(wil, "EAPOL len %d from %pM MID %d\n", eapol_len, |
1000 | evt->src_mac); | 1022 | evt->src_mac, vif->mid); |
1001 | 1023 | ||
1002 | cid = wil_find_cid(wil, evt->src_mac); | 1024 | cid = wil_find_cid(wil, vif->mid, evt->src_mac); |
1003 | if (cid >= 0) | 1025 | if (cid >= 0) |
1004 | stats = &wil->sta[cid].stats; | 1026 | stats = &wil->sta[cid].stats; |
1005 | 1027 | ||
@@ -1034,13 +1056,14 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id, | |||
1034 | } | 1056 | } |
1035 | } | 1057 | } |
1036 | 1058 | ||
1037 | static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len) | 1059 | static void wmi_evt_vring_en(struct wil6210_vif *vif, int id, void *d, int len) |
1038 | { | 1060 | { |
1061 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1039 | struct wmi_vring_en_event *evt = d; | 1062 | struct wmi_vring_en_event *evt = d; |
1040 | u8 vri = evt->vring_index; | 1063 | u8 vri = evt->vring_index; |
1041 | struct wireless_dev *wdev = wil_to_wdev(wil); | 1064 | struct wireless_dev *wdev = vif_to_wdev(vif); |
1042 | 1065 | ||
1043 | wil_dbg_wmi(wil, "Enable vring %d\n", vri); | 1066 | wil_dbg_wmi(wil, "Enable vring %d MID %d\n", vri, vif->mid); |
1044 | 1067 | ||
1045 | if (vri >= ARRAY_SIZE(wil->vring_tx)) { | 1068 | if (vri >= ARRAY_SIZE(wil->vring_tx)) { |
1046 | wil_err(wil, "Enable for invalid vring %d\n", vri); | 1069 | wil_err(wil, "Enable for invalid vring %d\n", vri); |
@@ -1052,15 +1075,16 @@ static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len) | |||
1052 | * wil_cfg80211_change_station() | 1075 | * wil_cfg80211_change_station() |
1053 | */ | 1076 | */ |
1054 | wil->vring_tx_data[vri].dot1x_open = true; | 1077 | wil->vring_tx_data[vri].dot1x_open = true; |
1055 | if (vri == wil->bcast_vring) /* no BA for bcast */ | 1078 | if (vri == vif->bcast_vring) /* no BA for bcast */ |
1056 | return; | 1079 | return; |
1057 | if (agg_wsize >= 0) | 1080 | if (agg_wsize >= 0) |
1058 | wil_addba_tx_request(wil, vri, agg_wsize); | 1081 | wil_addba_tx_request(wil, vri, agg_wsize); |
1059 | } | 1082 | } |
1060 | 1083 | ||
1061 | static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d, | 1084 | static void wmi_evt_ba_status(struct wil6210_vif *vif, int id, |
1062 | int len) | 1085 | void *d, int len) |
1063 | { | 1086 | { |
1087 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1064 | struct wmi_ba_status_event *evt = d; | 1088 | struct wmi_ba_status_event *evt = d; |
1065 | struct vring_tx_data *txdata; | 1089 | struct vring_tx_data *txdata; |
1066 | 1090 | ||
@@ -1089,19 +1113,21 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d, | |||
1089 | txdata->addba_in_progress = false; | 1113 | txdata->addba_in_progress = false; |
1090 | } | 1114 | } |
1091 | 1115 | ||
1092 | static void wmi_evt_addba_rx_req(struct wil6210_priv *wil, int id, void *d, | 1116 | static void wmi_evt_addba_rx_req(struct wil6210_vif *vif, int id, |
1093 | int len) | 1117 | void *d, int len) |
1094 | { | 1118 | { |
1119 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1095 | struct wmi_rcp_addba_req_event *evt = d; | 1120 | struct wmi_rcp_addba_req_event *evt = d; |
1096 | 1121 | ||
1097 | wil_addba_rx_request(wil, evt->cidxtid, evt->dialog_token, | 1122 | wil_addba_rx_request(wil, vif->mid, evt->cidxtid, evt->dialog_token, |
1098 | evt->ba_param_set, evt->ba_timeout, | 1123 | evt->ba_param_set, evt->ba_timeout, |
1099 | evt->ba_seq_ctrl); | 1124 | evt->ba_seq_ctrl); |
1100 | } | 1125 | } |
1101 | 1126 | ||
1102 | static void wmi_evt_delba(struct wil6210_priv *wil, int id, void *d, int len) | 1127 | static void wmi_evt_delba(struct wil6210_vif *vif, int id, void *d, int len) |
1103 | __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | 1128 | __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) |
1104 | { | 1129 | { |
1130 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1105 | struct wmi_delba_event *evt = d; | 1131 | struct wmi_delba_event *evt = d; |
1106 | u8 cid, tid; | 1132 | u8 cid, tid; |
1107 | u16 reason = __le16_to_cpu(evt->reason); | 1133 | u16 reason = __le16_to_cpu(evt->reason); |
@@ -1110,8 +1136,8 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | |||
1110 | 1136 | ||
1111 | might_sleep(); | 1137 | might_sleep(); |
1112 | parse_cidxtid(evt->cidxtid, &cid, &tid); | 1138 | parse_cidxtid(evt->cidxtid, &cid, &tid); |
1113 | wil_dbg_wmi(wil, "DELBA CID %d TID %d from %s reason %d\n", | 1139 | wil_dbg_wmi(wil, "DELBA MID %d CID %d TID %d from %s reason %d\n", |
1114 | cid, tid, | 1140 | vif->mid, cid, tid, |
1115 | evt->from_initiator ? "originator" : "recipient", | 1141 | evt->from_initiator ? "originator" : "recipient", |
1116 | reason); | 1142 | reason); |
1117 | if (!evt->from_initiator) { | 1143 | if (!evt->from_initiator) { |
@@ -1148,8 +1174,9 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) | |||
1148 | } | 1174 | } |
1149 | 1175 | ||
1150 | static void | 1176 | static void |
1151 | wmi_evt_sched_scan_result(struct wil6210_priv *wil, int id, void *d, int len) | 1177 | wmi_evt_sched_scan_result(struct wil6210_vif *vif, int id, void *d, int len) |
1152 | { | 1178 | { |
1179 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1153 | struct wmi_sched_scan_result_event *data = d; | 1180 | struct wmi_sched_scan_result_event *data = d; |
1154 | struct wiphy *wiphy = wil_to_wiphy(wil); | 1181 | struct wiphy *wiphy = wil_to_wiphy(wil); |
1155 | struct ieee80211_mgmt *rx_mgmt_frame = | 1182 | struct ieee80211_mgmt *rx_mgmt_frame = |
@@ -1220,15 +1247,17 @@ wmi_evt_sched_scan_result(struct wil6210_priv *wil, int id, void *d, int len) | |||
1220 | * Some events are ignored for purpose; and need not be interpreted as | 1247 | * Some events are ignored for purpose; and need not be interpreted as |
1221 | * "unhandled events" | 1248 | * "unhandled events" |
1222 | */ | 1249 | */ |
1223 | static void wmi_evt_ignore(struct wil6210_priv *wil, int id, void *d, int len) | 1250 | static void wmi_evt_ignore(struct wil6210_vif *vif, int id, void *d, int len) |
1224 | { | 1251 | { |
1252 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1253 | |||
1225 | wil_dbg_wmi(wil, "Ignore event 0x%04x len %d\n", id, len); | 1254 | wil_dbg_wmi(wil, "Ignore event 0x%04x len %d\n", id, len); |
1226 | } | 1255 | } |
1227 | 1256 | ||
1228 | static const struct { | 1257 | static const struct { |
1229 | int eventid; | 1258 | int eventid; |
1230 | void (*handler)(struct wil6210_priv *wil, int eventid, | 1259 | void (*handler)(struct wil6210_vif *vif, |
1231 | void *data, int data_len); | 1260 | int eventid, void *data, int data_len); |
1232 | } wmi_evt_handlers[] = { | 1261 | } wmi_evt_handlers[] = { |
1233 | {WMI_READY_EVENTID, wmi_evt_ready}, | 1262 | {WMI_READY_EVENTID, wmi_evt_ready}, |
1234 | {WMI_FW_READY_EVENTID, wmi_evt_ignore}, | 1263 | {WMI_FW_READY_EVENTID, wmi_evt_ignore}, |
@@ -1325,6 +1354,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil) | |||
1325 | (len >= sizeof(struct wmi_cmd_hdr))) { | 1354 | (len >= sizeof(struct wmi_cmd_hdr))) { |
1326 | struct wmi_cmd_hdr *wmi = &evt->event.wmi; | 1355 | struct wmi_cmd_hdr *wmi = &evt->event.wmi; |
1327 | u16 id = le16_to_cpu(wmi->command_id); | 1356 | u16 id = le16_to_cpu(wmi->command_id); |
1357 | u8 mid = wmi->mid; | ||
1328 | u32 tstamp = le32_to_cpu(wmi->fw_timestamp); | 1358 | u32 tstamp = le32_to_cpu(wmi->fw_timestamp); |
1329 | if (test_bit(wil_status_resuming, wil->status)) { | 1359 | if (test_bit(wil_status_resuming, wil->status)) { |
1330 | if (id == WMI_TRAFFIC_RESUME_EVENTID) | 1360 | if (id == WMI_TRAFFIC_RESUME_EVENTID) |
@@ -1336,7 +1366,8 @@ void wmi_recv_cmd(struct wil6210_priv *wil) | |||
1336 | id); | 1366 | id); |
1337 | } | 1367 | } |
1338 | spin_lock_irqsave(&wil->wmi_ev_lock, flags); | 1368 | spin_lock_irqsave(&wil->wmi_ev_lock, flags); |
1339 | if (wil->reply_id && wil->reply_id == id) { | 1369 | if (wil->reply_id && wil->reply_id == id && |
1370 | wil->reply_mid == mid) { | ||
1340 | if (wil->reply_buf) { | 1371 | if (wil->reply_buf) { |
1341 | memcpy(wil->reply_buf, wmi, | 1372 | memcpy(wil->reply_buf, wmi, |
1342 | min(len, wil->reply_size)); | 1373 | min(len, wil->reply_size)); |
@@ -1384,7 +1415,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil) | |||
1384 | n - num_immed_reply, num_immed_reply); | 1415 | n - num_immed_reply, num_immed_reply); |
1385 | } | 1416 | } |
1386 | 1417 | ||
1387 | int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, | 1418 | int wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len, |
1388 | u16 reply_id, void *reply, u8 reply_size, int to_msec) | 1419 | u16 reply_id, void *reply, u8 reply_size, int to_msec) |
1389 | { | 1420 | { |
1390 | int rc; | 1421 | int rc; |
@@ -1394,12 +1425,13 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, | |||
1394 | 1425 | ||
1395 | spin_lock(&wil->wmi_ev_lock); | 1426 | spin_lock(&wil->wmi_ev_lock); |
1396 | wil->reply_id = reply_id; | 1427 | wil->reply_id = reply_id; |
1428 | wil->reply_mid = mid; | ||
1397 | wil->reply_buf = reply; | 1429 | wil->reply_buf = reply; |
1398 | wil->reply_size = reply_size; | 1430 | wil->reply_size = reply_size; |
1399 | reinit_completion(&wil->wmi_call); | 1431 | reinit_completion(&wil->wmi_call); |
1400 | spin_unlock(&wil->wmi_ev_lock); | 1432 | spin_unlock(&wil->wmi_ev_lock); |
1401 | 1433 | ||
1402 | rc = __wmi_send(wil, cmdid, buf, len); | 1434 | rc = __wmi_send(wil, cmdid, mid, buf, len); |
1403 | if (rc) | 1435 | if (rc) |
1404 | goto out; | 1436 | goto out; |
1405 | 1437 | ||
@@ -1419,6 +1451,7 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, | |||
1419 | out: | 1451 | out: |
1420 | spin_lock(&wil->wmi_ev_lock); | 1452 | spin_lock(&wil->wmi_ev_lock); |
1421 | wil->reply_id = 0; | 1453 | wil->reply_id = 0; |
1454 | wil->reply_mid = U8_MAX; | ||
1422 | wil->reply_buf = NULL; | 1455 | wil->reply_buf = NULL; |
1423 | wil->reply_size = 0; | 1456 | wil->reply_size = 0; |
1424 | spin_unlock(&wil->wmi_ev_lock); | 1457 | spin_unlock(&wil->wmi_ev_lock); |
@@ -1430,27 +1463,31 @@ out: | |||
1430 | 1463 | ||
1431 | int wmi_echo(struct wil6210_priv *wil) | 1464 | int wmi_echo(struct wil6210_priv *wil) |
1432 | { | 1465 | { |
1466 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
1433 | struct wmi_echo_cmd cmd = { | 1467 | struct wmi_echo_cmd cmd = { |
1434 | .value = cpu_to_le32(0x12345678), | 1468 | .value = cpu_to_le32(0x12345678), |
1435 | }; | 1469 | }; |
1436 | 1470 | ||
1437 | return wmi_call(wil, WMI_ECHO_CMDID, &cmd, sizeof(cmd), | 1471 | return wmi_call(wil, WMI_ECHO_CMDID, vif->mid, &cmd, sizeof(cmd), |
1438 | WMI_ECHO_RSP_EVENTID, NULL, 0, 50); | 1472 | WMI_ECHO_RSP_EVENTID, NULL, 0, 50); |
1439 | } | 1473 | } |
1440 | 1474 | ||
1441 | int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) | 1475 | int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) |
1442 | { | 1476 | { |
1477 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
1443 | struct wmi_set_mac_address_cmd cmd; | 1478 | struct wmi_set_mac_address_cmd cmd; |
1444 | 1479 | ||
1445 | ether_addr_copy(cmd.mac, addr); | 1480 | ether_addr_copy(cmd.mac, addr); |
1446 | 1481 | ||
1447 | wil_dbg_wmi(wil, "Set MAC %pM\n", addr); | 1482 | wil_dbg_wmi(wil, "Set MAC %pM\n", addr); |
1448 | 1483 | ||
1449 | return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd)); | 1484 | return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, vif->mid, |
1485 | &cmd, sizeof(cmd)); | ||
1450 | } | 1486 | } |
1451 | 1487 | ||
1452 | int wmi_led_cfg(struct wil6210_priv *wil, bool enable) | 1488 | int wmi_led_cfg(struct wil6210_priv *wil, bool enable) |
1453 | { | 1489 | { |
1490 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
1454 | int rc = 0; | 1491 | int rc = 0; |
1455 | struct wmi_led_cfg_cmd cmd = { | 1492 | struct wmi_led_cfg_cmd cmd = { |
1456 | .led_mode = enable, | 1493 | .led_mode = enable, |
@@ -1487,7 +1524,7 @@ int wmi_led_cfg(struct wil6210_priv *wil, bool enable) | |||
1487 | "%s led %d\n", | 1524 | "%s led %d\n", |
1488 | enable ? "enabling" : "disabling", led_id); | 1525 | enable ? "enabling" : "disabling", led_id); |
1489 | 1526 | ||
1490 | rc = wmi_call(wil, WMI_LED_CFG_CMDID, &cmd, sizeof(cmd), | 1527 | rc = wmi_call(wil, WMI_LED_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), |
1491 | WMI_LED_CFG_DONE_EVENTID, &reply, sizeof(reply), | 1528 | WMI_LED_CFG_DONE_EVENTID, &reply, sizeof(reply), |
1492 | 100); | 1529 | 100); |
1493 | if (rc) | 1530 | if (rc) |
@@ -1503,9 +1540,10 @@ out: | |||
1503 | return rc; | 1540 | return rc; |
1504 | } | 1541 | } |
1505 | 1542 | ||
1506 | int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, | 1543 | int wmi_pcp_start(struct wil6210_vif *vif, |
1507 | u8 chan, u8 hidden_ssid, u8 is_go) | 1544 | int bi, u8 wmi_nettype, u8 chan, u8 hidden_ssid, u8 is_go) |
1508 | { | 1545 | { |
1546 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1509 | int rc; | 1547 | int rc; |
1510 | 1548 | ||
1511 | struct wmi_pcp_start_cmd cmd = { | 1549 | struct wmi_pcp_start_cmd cmd = { |
@@ -1524,7 +1562,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, | |||
1524 | struct wmi_pcp_started_event evt; | 1562 | struct wmi_pcp_started_event evt; |
1525 | } __packed reply; | 1563 | } __packed reply; |
1526 | 1564 | ||
1527 | if (!wil->privacy) | 1565 | if (!vif->privacy) |
1528 | cmd.disable_sec = 1; | 1566 | cmd.disable_sec = 1; |
1529 | 1567 | ||
1530 | if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) || | 1568 | if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) || |
@@ -1546,7 +1584,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, | |||
1546 | * Processing time may be huge, in case of secure AP it takes about | 1584 | * Processing time may be huge, in case of secure AP it takes about |
1547 | * 3500ms for FW to start AP | 1585 | * 3500ms for FW to start AP |
1548 | */ | 1586 | */ |
1549 | rc = wmi_call(wil, WMI_PCP_START_CMDID, &cmd, sizeof(cmd), | 1587 | rc = wmi_call(wil, WMI_PCP_START_CMDID, vif->mid, &cmd, sizeof(cmd), |
1550 | WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 5000); | 1588 | WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 5000); |
1551 | if (rc) | 1589 | if (rc) |
1552 | return rc; | 1590 | return rc; |
@@ -1561,20 +1599,22 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, | |||
1561 | return rc; | 1599 | return rc; |
1562 | } | 1600 | } |
1563 | 1601 | ||
1564 | int wmi_pcp_stop(struct wil6210_priv *wil) | 1602 | int wmi_pcp_stop(struct wil6210_vif *vif) |
1565 | { | 1603 | { |
1604 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1566 | int rc; | 1605 | int rc; |
1567 | 1606 | ||
1568 | rc = wmi_led_cfg(wil, false); | 1607 | rc = wmi_led_cfg(wil, false); |
1569 | if (rc) | 1608 | if (rc) |
1570 | return rc; | 1609 | return rc; |
1571 | 1610 | ||
1572 | return wmi_call(wil, WMI_PCP_STOP_CMDID, NULL, 0, | 1611 | return wmi_call(wil, WMI_PCP_STOP_CMDID, vif->mid, NULL, 0, |
1573 | WMI_PCP_STOPPED_EVENTID, NULL, 0, 20); | 1612 | WMI_PCP_STOPPED_EVENTID, NULL, 0, 20); |
1574 | } | 1613 | } |
1575 | 1614 | ||
1576 | int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid) | 1615 | int wmi_set_ssid(struct wil6210_vif *vif, u8 ssid_len, const void *ssid) |
1577 | { | 1616 | { |
1617 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1578 | struct wmi_set_ssid_cmd cmd = { | 1618 | struct wmi_set_ssid_cmd cmd = { |
1579 | .ssid_len = cpu_to_le32(ssid_len), | 1619 | .ssid_len = cpu_to_le32(ssid_len), |
1580 | }; | 1620 | }; |
@@ -1584,11 +1624,12 @@ int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid) | |||
1584 | 1624 | ||
1585 | memcpy(cmd.ssid, ssid, ssid_len); | 1625 | memcpy(cmd.ssid, ssid, ssid_len); |
1586 | 1626 | ||
1587 | return wmi_send(wil, WMI_SET_SSID_CMDID, &cmd, sizeof(cmd)); | 1627 | return wmi_send(wil, WMI_SET_SSID_CMDID, vif->mid, &cmd, sizeof(cmd)); |
1588 | } | 1628 | } |
1589 | 1629 | ||
1590 | int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid) | 1630 | int wmi_get_ssid(struct wil6210_vif *vif, u8 *ssid_len, void *ssid) |
1591 | { | 1631 | { |
1632 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1592 | int rc; | 1633 | int rc; |
1593 | struct { | 1634 | struct { |
1594 | struct wmi_cmd_hdr wmi; | 1635 | struct wmi_cmd_hdr wmi; |
@@ -1596,8 +1637,8 @@ int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid) | |||
1596 | } __packed reply; | 1637 | } __packed reply; |
1597 | int len; /* reply.cmd.ssid_len in CPU order */ | 1638 | int len; /* reply.cmd.ssid_len in CPU order */ |
1598 | 1639 | ||
1599 | rc = wmi_call(wil, WMI_GET_SSID_CMDID, NULL, 0, WMI_GET_SSID_EVENTID, | 1640 | rc = wmi_call(wil, WMI_GET_SSID_CMDID, vif->mid, NULL, 0, |
1600 | &reply, sizeof(reply), 20); | 1641 | WMI_GET_SSID_EVENTID, &reply, sizeof(reply), 20); |
1601 | if (rc) | 1642 | if (rc) |
1602 | return rc; | 1643 | return rc; |
1603 | 1644 | ||
@@ -1613,22 +1654,25 @@ int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid) | |||
1613 | 1654 | ||
1614 | int wmi_set_channel(struct wil6210_priv *wil, int channel) | 1655 | int wmi_set_channel(struct wil6210_priv *wil, int channel) |
1615 | { | 1656 | { |
1657 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
1616 | struct wmi_set_pcp_channel_cmd cmd = { | 1658 | struct wmi_set_pcp_channel_cmd cmd = { |
1617 | .channel = channel - 1, | 1659 | .channel = channel - 1, |
1618 | }; | 1660 | }; |
1619 | 1661 | ||
1620 | return wmi_send(wil, WMI_SET_PCP_CHANNEL_CMDID, &cmd, sizeof(cmd)); | 1662 | return wmi_send(wil, WMI_SET_PCP_CHANNEL_CMDID, vif->mid, |
1663 | &cmd, sizeof(cmd)); | ||
1621 | } | 1664 | } |
1622 | 1665 | ||
1623 | int wmi_get_channel(struct wil6210_priv *wil, int *channel) | 1666 | int wmi_get_channel(struct wil6210_priv *wil, int *channel) |
1624 | { | 1667 | { |
1668 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
1625 | int rc; | 1669 | int rc; |
1626 | struct { | 1670 | struct { |
1627 | struct wmi_cmd_hdr wmi; | 1671 | struct wmi_cmd_hdr wmi; |
1628 | struct wmi_set_pcp_channel_cmd cmd; | 1672 | struct wmi_set_pcp_channel_cmd cmd; |
1629 | } __packed reply; | 1673 | } __packed reply; |
1630 | 1674 | ||
1631 | rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, NULL, 0, | 1675 | rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, vif->mid, NULL, 0, |
1632 | WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 20); | 1676 | WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 20); |
1633 | if (rc) | 1677 | if (rc) |
1634 | return rc; | 1678 | return rc; |
@@ -1641,8 +1685,9 @@ int wmi_get_channel(struct wil6210_priv *wil, int *channel) | |||
1641 | return 0; | 1685 | return 0; |
1642 | } | 1686 | } |
1643 | 1687 | ||
1644 | int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi) | 1688 | int wmi_p2p_cfg(struct wil6210_vif *vif, int channel, int bi) |
1645 | { | 1689 | { |
1690 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1646 | int rc; | 1691 | int rc; |
1647 | struct wmi_p2p_cfg_cmd cmd = { | 1692 | struct wmi_p2p_cfg_cmd cmd = { |
1648 | .discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER, | 1693 | .discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER, |
@@ -1656,7 +1701,7 @@ int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi) | |||
1656 | 1701 | ||
1657 | wil_dbg_wmi(wil, "sending WMI_P2P_CFG_CMDID\n"); | 1702 | wil_dbg_wmi(wil, "sending WMI_P2P_CFG_CMDID\n"); |
1658 | 1703 | ||
1659 | rc = wmi_call(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd), | 1704 | rc = wmi_call(wil, WMI_P2P_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), |
1660 | WMI_P2P_CFG_DONE_EVENTID, &reply, sizeof(reply), 300); | 1705 | WMI_P2P_CFG_DONE_EVENTID, &reply, sizeof(reply), 300); |
1661 | if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { | 1706 | if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { |
1662 | wil_err(wil, "P2P_CFG failed. status %d\n", reply.evt.status); | 1707 | wil_err(wil, "P2P_CFG failed. status %d\n", reply.evt.status); |
@@ -1666,8 +1711,9 @@ int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi) | |||
1666 | return rc; | 1711 | return rc; |
1667 | } | 1712 | } |
1668 | 1713 | ||
1669 | int wmi_start_listen(struct wil6210_priv *wil) | 1714 | int wmi_start_listen(struct wil6210_vif *vif) |
1670 | { | 1715 | { |
1716 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1671 | int rc; | 1717 | int rc; |
1672 | struct { | 1718 | struct { |
1673 | struct wmi_cmd_hdr wmi; | 1719 | struct wmi_cmd_hdr wmi; |
@@ -1676,7 +1722,7 @@ int wmi_start_listen(struct wil6210_priv *wil) | |||
1676 | 1722 | ||
1677 | wil_dbg_wmi(wil, "sending WMI_START_LISTEN_CMDID\n"); | 1723 | wil_dbg_wmi(wil, "sending WMI_START_LISTEN_CMDID\n"); |
1678 | 1724 | ||
1679 | rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0, | 1725 | rc = wmi_call(wil, WMI_START_LISTEN_CMDID, vif->mid, NULL, 0, |
1680 | WMI_LISTEN_STARTED_EVENTID, &reply, sizeof(reply), 300); | 1726 | WMI_LISTEN_STARTED_EVENTID, &reply, sizeof(reply), 300); |
1681 | if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { | 1727 | if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { |
1682 | wil_err(wil, "device failed to start listen. status %d\n", | 1728 | wil_err(wil, "device failed to start listen. status %d\n", |
@@ -1687,8 +1733,9 @@ int wmi_start_listen(struct wil6210_priv *wil) | |||
1687 | return rc; | 1733 | return rc; |
1688 | } | 1734 | } |
1689 | 1735 | ||
1690 | int wmi_start_search(struct wil6210_priv *wil) | 1736 | int wmi_start_search(struct wil6210_vif *vif) |
1691 | { | 1737 | { |
1738 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1692 | int rc; | 1739 | int rc; |
1693 | struct { | 1740 | struct { |
1694 | struct wmi_cmd_hdr wmi; | 1741 | struct wmi_cmd_hdr wmi; |
@@ -1697,7 +1744,7 @@ int wmi_start_search(struct wil6210_priv *wil) | |||
1697 | 1744 | ||
1698 | wil_dbg_wmi(wil, "sending WMI_START_SEARCH_CMDID\n"); | 1745 | wil_dbg_wmi(wil, "sending WMI_START_SEARCH_CMDID\n"); |
1699 | 1746 | ||
1700 | rc = wmi_call(wil, WMI_START_SEARCH_CMDID, NULL, 0, | 1747 | rc = wmi_call(wil, WMI_START_SEARCH_CMDID, vif->mid, NULL, 0, |
1701 | WMI_SEARCH_STARTED_EVENTID, &reply, sizeof(reply), 300); | 1748 | WMI_SEARCH_STARTED_EVENTID, &reply, sizeof(reply), 300); |
1702 | if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { | 1749 | if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { |
1703 | wil_err(wil, "device failed to start search. status %d\n", | 1750 | wil_err(wil, "device failed to start search. status %d\n", |
@@ -1708,13 +1755,14 @@ int wmi_start_search(struct wil6210_priv *wil) | |||
1708 | return rc; | 1755 | return rc; |
1709 | } | 1756 | } |
1710 | 1757 | ||
1711 | int wmi_stop_discovery(struct wil6210_priv *wil) | 1758 | int wmi_stop_discovery(struct wil6210_vif *vif) |
1712 | { | 1759 | { |
1760 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1713 | int rc; | 1761 | int rc; |
1714 | 1762 | ||
1715 | wil_dbg_wmi(wil, "sending WMI_DISCOVERY_STOP_CMDID\n"); | 1763 | wil_dbg_wmi(wil, "sending WMI_DISCOVERY_STOP_CMDID\n"); |
1716 | 1764 | ||
1717 | rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, NULL, 0, | 1765 | rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, vif->mid, NULL, 0, |
1718 | WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 100); | 1766 | WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 100); |
1719 | 1767 | ||
1720 | if (rc) | 1768 | if (rc) |
@@ -1723,9 +1771,10 @@ int wmi_stop_discovery(struct wil6210_priv *wil) | |||
1723 | return rc; | 1771 | return rc; |
1724 | } | 1772 | } |
1725 | 1773 | ||
1726 | int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, | 1774 | int wmi_del_cipher_key(struct wil6210_vif *vif, u8 key_index, |
1727 | const void *mac_addr, int key_usage) | 1775 | const void *mac_addr, int key_usage) |
1728 | { | 1776 | { |
1777 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1729 | struct wmi_delete_cipher_key_cmd cmd = { | 1778 | struct wmi_delete_cipher_key_cmd cmd = { |
1730 | .key_index = key_index, | 1779 | .key_index = key_index, |
1731 | }; | 1780 | }; |
@@ -1733,13 +1782,15 @@ int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, | |||
1733 | if (mac_addr) | 1782 | if (mac_addr) |
1734 | memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); | 1783 | memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); |
1735 | 1784 | ||
1736 | return wmi_send(wil, WMI_DELETE_CIPHER_KEY_CMDID, &cmd, sizeof(cmd)); | 1785 | return wmi_send(wil, WMI_DELETE_CIPHER_KEY_CMDID, vif->mid, |
1786 | &cmd, sizeof(cmd)); | ||
1737 | } | 1787 | } |
1738 | 1788 | ||
1739 | int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, | 1789 | int wmi_add_cipher_key(struct wil6210_vif *vif, u8 key_index, |
1740 | const void *mac_addr, int key_len, const void *key, | 1790 | const void *mac_addr, int key_len, const void *key, |
1741 | int key_usage) | 1791 | int key_usage) |
1742 | { | 1792 | { |
1793 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1743 | struct wmi_add_cipher_key_cmd cmd = { | 1794 | struct wmi_add_cipher_key_cmd cmd = { |
1744 | .key_index = key_index, | 1795 | .key_index = key_index, |
1745 | .key_usage = key_usage, | 1796 | .key_usage = key_usage, |
@@ -1753,11 +1804,13 @@ int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, | |||
1753 | if (mac_addr) | 1804 | if (mac_addr) |
1754 | memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); | 1805 | memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); |
1755 | 1806 | ||
1756 | return wmi_send(wil, WMI_ADD_CIPHER_KEY_CMDID, &cmd, sizeof(cmd)); | 1807 | return wmi_send(wil, WMI_ADD_CIPHER_KEY_CMDID, vif->mid, |
1808 | &cmd, sizeof(cmd)); | ||
1757 | } | 1809 | } |
1758 | 1810 | ||
1759 | int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) | 1811 | int wmi_set_ie(struct wil6210_vif *vif, u8 type, u16 ie_len, const void *ie) |
1760 | { | 1812 | { |
1813 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1761 | static const char *const names[] = { | 1814 | static const char *const names[] = { |
1762 | [WMI_FRAME_BEACON] = "BEACON", | 1815 | [WMI_FRAME_BEACON] = "BEACON", |
1763 | [WMI_FRAME_PROBE_REQ] = "PROBE_REQ", | 1816 | [WMI_FRAME_PROBE_REQ] = "PROBE_REQ", |
@@ -1786,7 +1839,7 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) | |||
1786 | /* BUG: FW API define ieLen as u8. Will fix FW */ | 1839 | /* BUG: FW API define ieLen as u8. Will fix FW */ |
1787 | cmd->ie_len = cpu_to_le16(ie_len); | 1840 | cmd->ie_len = cpu_to_le16(ie_len); |
1788 | memcpy(cmd->ie_info, ie, ie_len); | 1841 | memcpy(cmd->ie_info, ie, ie_len); |
1789 | rc = wmi_send(wil, WMI_SET_APPIE_CMDID, cmd, len); | 1842 | rc = wmi_send(wil, WMI_SET_APPIE_CMDID, vif->mid, cmd, len); |
1790 | kfree(cmd); | 1843 | kfree(cmd); |
1791 | out: | 1844 | out: |
1792 | if (rc) { | 1845 | if (rc) { |
@@ -1808,6 +1861,7 @@ out: | |||
1808 | */ | 1861 | */ |
1809 | int wmi_rxon(struct wil6210_priv *wil, bool on) | 1862 | int wmi_rxon(struct wil6210_priv *wil, bool on) |
1810 | { | 1863 | { |
1864 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
1811 | int rc; | 1865 | int rc; |
1812 | struct { | 1866 | struct { |
1813 | struct wmi_cmd_hdr wmi; | 1867 | struct wmi_cmd_hdr wmi; |
@@ -1817,13 +1871,13 @@ int wmi_rxon(struct wil6210_priv *wil, bool on) | |||
1817 | wil_info(wil, "(%s)\n", on ? "on" : "off"); | 1871 | wil_info(wil, "(%s)\n", on ? "on" : "off"); |
1818 | 1872 | ||
1819 | if (on) { | 1873 | if (on) { |
1820 | rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0, | 1874 | rc = wmi_call(wil, WMI_START_LISTEN_CMDID, vif->mid, NULL, 0, |
1821 | WMI_LISTEN_STARTED_EVENTID, | 1875 | WMI_LISTEN_STARTED_EVENTID, |
1822 | &reply, sizeof(reply), 100); | 1876 | &reply, sizeof(reply), 100); |
1823 | if ((rc == 0) && (reply.evt.status != WMI_FW_STATUS_SUCCESS)) | 1877 | if ((rc == 0) && (reply.evt.status != WMI_FW_STATUS_SUCCESS)) |
1824 | rc = -EINVAL; | 1878 | rc = -EINVAL; |
1825 | } else { | 1879 | } else { |
1826 | rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, NULL, 0, | 1880 | rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, vif->mid, NULL, 0, |
1827 | WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 20); | 1881 | WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 20); |
1828 | } | 1882 | } |
1829 | 1883 | ||
@@ -1832,8 +1886,9 @@ int wmi_rxon(struct wil6210_priv *wil, bool on) | |||
1832 | 1886 | ||
1833 | int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring) | 1887 | int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring) |
1834 | { | 1888 | { |
1835 | struct wireless_dev *wdev = wil->wdev; | 1889 | struct net_device *ndev = wil->main_ndev; |
1836 | struct net_device *ndev = wil_to_ndev(wil); | 1890 | struct wireless_dev *wdev = ndev->ieee80211_ptr; |
1891 | struct wil6210_vif *vif = ndev_to_vif(ndev); | ||
1837 | struct wmi_cfg_rx_chain_cmd cmd = { | 1892 | struct wmi_cfg_rx_chain_cmd cmd = { |
1838 | .action = WMI_RX_CHAIN_ADD, | 1893 | .action = WMI_RX_CHAIN_ADD, |
1839 | .rx_sw_ring = { | 1894 | .rx_sw_ring = { |
@@ -1877,7 +1932,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring) | |||
1877 | L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_MSK; | 1932 | L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_MSK; |
1878 | 1933 | ||
1879 | /* typical time for secure PCP is 840ms */ | 1934 | /* typical time for secure PCP is 840ms */ |
1880 | rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd), | 1935 | rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, vif->mid, &cmd, sizeof(cmd), |
1881 | WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000); | 1936 | WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000); |
1882 | if (rc) | 1937 | if (rc) |
1883 | return rc; | 1938 | return rc; |
@@ -1895,6 +1950,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring) | |||
1895 | 1950 | ||
1896 | int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf) | 1951 | int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf) |
1897 | { | 1952 | { |
1953 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
1898 | int rc; | 1954 | int rc; |
1899 | struct wmi_temp_sense_cmd cmd = { | 1955 | struct wmi_temp_sense_cmd cmd = { |
1900 | .measure_baseband_en = cpu_to_le32(!!t_bb), | 1956 | .measure_baseband_en = cpu_to_le32(!!t_bb), |
@@ -1906,7 +1962,7 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf) | |||
1906 | struct wmi_temp_sense_done_event evt; | 1962 | struct wmi_temp_sense_done_event evt; |
1907 | } __packed reply; | 1963 | } __packed reply; |
1908 | 1964 | ||
1909 | rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, &cmd, sizeof(cmd), | 1965 | rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, vif->mid, &cmd, sizeof(cmd), |
1910 | WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100); | 1966 | WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100); |
1911 | if (rc) | 1967 | if (rc) |
1912 | return rc; | 1968 | return rc; |
@@ -1919,9 +1975,10 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf) | |||
1919 | return 0; | 1975 | return 0; |
1920 | } | 1976 | } |
1921 | 1977 | ||
1922 | int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, | 1978 | int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac, |
1923 | u16 reason, bool full_disconnect, bool del_sta) | 1979 | u16 reason, bool full_disconnect, bool del_sta) |
1924 | { | 1980 | { |
1981 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
1925 | int rc; | 1982 | int rc; |
1926 | u16 reason_code; | 1983 | u16 reason_code; |
1927 | struct wmi_disconnect_sta_cmd disc_sta_cmd = { | 1984 | struct wmi_disconnect_sta_cmd disc_sta_cmd = { |
@@ -1937,16 +1994,17 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, | |||
1937 | 1994 | ||
1938 | wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason); | 1995 | wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason); |
1939 | 1996 | ||
1940 | wil->locally_generated_disc = true; | 1997 | vif->locally_generated_disc = true; |
1941 | if (del_sta) { | 1998 | if (del_sta) { |
1942 | ether_addr_copy(del_sta_cmd.dst_mac, mac); | 1999 | ether_addr_copy(del_sta_cmd.dst_mac, mac); |
1943 | rc = wmi_call(wil, WMI_DEL_STA_CMDID, &del_sta_cmd, | 2000 | rc = wmi_call(wil, WMI_DEL_STA_CMDID, vif->mid, &del_sta_cmd, |
1944 | sizeof(del_sta_cmd), WMI_DISCONNECT_EVENTID, | 2001 | sizeof(del_sta_cmd), WMI_DISCONNECT_EVENTID, |
1945 | &reply, sizeof(reply), 1000); | 2002 | &reply, sizeof(reply), 1000); |
1946 | } else { | 2003 | } else { |
1947 | ether_addr_copy(disc_sta_cmd.dst_mac, mac); | 2004 | ether_addr_copy(disc_sta_cmd.dst_mac, mac); |
1948 | rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, &disc_sta_cmd, | 2005 | rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, vif->mid, |
1949 | sizeof(disc_sta_cmd), WMI_DISCONNECT_EVENTID, | 2006 | &disc_sta_cmd, sizeof(disc_sta_cmd), |
2007 | WMI_DISCONNECT_EVENTID, | ||
1950 | &reply, sizeof(reply), 1000); | 2008 | &reply, sizeof(reply), 1000); |
1951 | } | 2009 | } |
1952 | /* failure to disconnect in reasonable time treated as FW error */ | 2010 | /* failure to disconnect in reasonable time treated as FW error */ |
@@ -1967,12 +2025,13 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, | |||
1967 | reply.evt.disconnect_reason); | 2025 | reply.evt.disconnect_reason); |
1968 | 2026 | ||
1969 | wil->sinfo_gen++; | 2027 | wil->sinfo_gen++; |
1970 | wil6210_disconnect(wil, reply.evt.bssid, reason_code, true); | 2028 | wil6210_disconnect(vif, reply.evt.bssid, reason_code, true); |
1971 | } | 2029 | } |
1972 | return 0; | 2030 | return 0; |
1973 | } | 2031 | } |
1974 | 2032 | ||
1975 | int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout) | 2033 | int wmi_addba(struct wil6210_priv *wil, u8 mid, |
2034 | u8 ringid, u8 size, u16 timeout) | ||
1976 | { | 2035 | { |
1977 | struct wmi_vring_ba_en_cmd cmd = { | 2036 | struct wmi_vring_ba_en_cmd cmd = { |
1978 | .ringid = ringid, | 2037 | .ringid = ringid, |
@@ -1984,10 +2043,10 @@ int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout) | |||
1984 | wil_dbg_wmi(wil, "addba: (ring %d size %d timeout %d)\n", ringid, size, | 2043 | wil_dbg_wmi(wil, "addba: (ring %d size %d timeout %d)\n", ringid, size, |
1985 | timeout); | 2044 | timeout); |
1986 | 2045 | ||
1987 | return wmi_send(wil, WMI_VRING_BA_EN_CMDID, &cmd, sizeof(cmd)); | 2046 | return wmi_send(wil, WMI_VRING_BA_EN_CMDID, mid, &cmd, sizeof(cmd)); |
1988 | } | 2047 | } |
1989 | 2048 | ||
1990 | int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason) | 2049 | int wmi_delba_tx(struct wil6210_priv *wil, u8 mid, u8 ringid, u16 reason) |
1991 | { | 2050 | { |
1992 | struct wmi_vring_ba_dis_cmd cmd = { | 2051 | struct wmi_vring_ba_dis_cmd cmd = { |
1993 | .ringid = ringid, | 2052 | .ringid = ringid, |
@@ -1996,10 +2055,10 @@ int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason) | |||
1996 | 2055 | ||
1997 | wil_dbg_wmi(wil, "delba_tx: (ring %d reason %d)\n", ringid, reason); | 2056 | wil_dbg_wmi(wil, "delba_tx: (ring %d reason %d)\n", ringid, reason); |
1998 | 2057 | ||
1999 | return wmi_send(wil, WMI_VRING_BA_DIS_CMDID, &cmd, sizeof(cmd)); | 2058 | return wmi_send(wil, WMI_VRING_BA_DIS_CMDID, mid, &cmd, sizeof(cmd)); |
2000 | } | 2059 | } |
2001 | 2060 | ||
2002 | int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason) | 2061 | int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cidxtid, u16 reason) |
2003 | { | 2062 | { |
2004 | struct wmi_rcp_delba_cmd cmd = { | 2063 | struct wmi_rcp_delba_cmd cmd = { |
2005 | .cidxtid = cidxtid, | 2064 | .cidxtid = cidxtid, |
@@ -2009,10 +2068,11 @@ int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason) | |||
2009 | wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cidxtid & 0xf, | 2068 | wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cidxtid & 0xf, |
2010 | (cidxtid >> 4) & 0xf, reason); | 2069 | (cidxtid >> 4) & 0xf, reason); |
2011 | 2070 | ||
2012 | return wmi_send(wil, WMI_RCP_DELBA_CMDID, &cmd, sizeof(cmd)); | 2071 | return wmi_send(wil, WMI_RCP_DELBA_CMDID, mid, &cmd, sizeof(cmd)); |
2013 | } | 2072 | } |
2014 | 2073 | ||
2015 | int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, | 2074 | int wmi_addba_rx_resp(struct wil6210_priv *wil, |
2075 | u8 mid, u8 cid, u8 tid, u8 token, | ||
2016 | u16 status, bool amsdu, u16 agg_wsize, u16 timeout) | 2076 | u16 status, bool amsdu, u16 agg_wsize, u16 timeout) |
2017 | { | 2077 | { |
2018 | int rc; | 2078 | int rc; |
@@ -2035,10 +2095,11 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, | |||
2035 | } __packed reply; | 2095 | } __packed reply; |
2036 | 2096 | ||
2037 | wil_dbg_wmi(wil, | 2097 | wil_dbg_wmi(wil, |
2038 | "ADDBA response for CID %d TID %d size %d timeout %d status %d AMSDU%s\n", | 2098 | "ADDBA response for MID %d CID %d TID %d size %d timeout %d status %d AMSDU%s\n", |
2039 | cid, tid, agg_wsize, timeout, status, amsdu ? "+" : "-"); | 2099 | mid, cid, tid, agg_wsize, |
2100 | timeout, status, amsdu ? "+" : "-"); | ||
2040 | 2101 | ||
2041 | rc = wmi_call(wil, WMI_RCP_ADDBA_RESP_CMDID, &cmd, sizeof(cmd), | 2102 | rc = wmi_call(wil, WMI_RCP_ADDBA_RESP_CMDID, mid, &cmd, sizeof(cmd), |
2042 | WMI_RCP_ADDBA_RESP_SENT_EVENTID, &reply, sizeof(reply), | 2103 | WMI_RCP_ADDBA_RESP_SENT_EVENTID, &reply, sizeof(reply), |
2043 | 100); | 2104 | 100); |
2044 | if (rc) | 2105 | if (rc) |
@@ -2056,6 +2117,7 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, | |||
2056 | int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, | 2117 | int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, |
2057 | enum wmi_ps_profile_type ps_profile) | 2118 | enum wmi_ps_profile_type ps_profile) |
2058 | { | 2119 | { |
2120 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
2059 | int rc; | 2121 | int rc; |
2060 | struct wmi_ps_dev_profile_cfg_cmd cmd = { | 2122 | struct wmi_ps_dev_profile_cfg_cmd cmd = { |
2061 | .ps_profile = ps_profile, | 2123 | .ps_profile = ps_profile, |
@@ -2070,7 +2132,8 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, | |||
2070 | 2132 | ||
2071 | reply.evt.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR); | 2133 | reply.evt.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR); |
2072 | 2134 | ||
2073 | rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, &cmd, sizeof(cmd), | 2135 | rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, vif->mid, |
2136 | &cmd, sizeof(cmd), | ||
2074 | WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply), | 2137 | WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply), |
2075 | 100); | 2138 | 100); |
2076 | if (rc) | 2139 | if (rc) |
@@ -2089,6 +2152,7 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, | |||
2089 | 2152 | ||
2090 | int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short) | 2153 | int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short) |
2091 | { | 2154 | { |
2155 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
2092 | int rc; | 2156 | int rc; |
2093 | struct wmi_set_mgmt_retry_limit_cmd cmd = { | 2157 | struct wmi_set_mgmt_retry_limit_cmd cmd = { |
2094 | .mgmt_retry_limit = retry_short, | 2158 | .mgmt_retry_limit = retry_short, |
@@ -2105,7 +2169,8 @@ int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short) | |||
2105 | 2169 | ||
2106 | reply.evt.status = WMI_FW_STATUS_FAILURE; | 2170 | reply.evt.status = WMI_FW_STATUS_FAILURE; |
2107 | 2171 | ||
2108 | rc = wmi_call(wil, WMI_SET_MGMT_RETRY_LIMIT_CMDID, &cmd, sizeof(cmd), | 2172 | rc = wmi_call(wil, WMI_SET_MGMT_RETRY_LIMIT_CMDID, vif->mid, |
2173 | &cmd, sizeof(cmd), | ||
2109 | WMI_SET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), | 2174 | WMI_SET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), |
2110 | 100); | 2175 | 100); |
2111 | if (rc) | 2176 | if (rc) |
@@ -2122,6 +2187,7 @@ int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short) | |||
2122 | 2187 | ||
2123 | int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short) | 2188 | int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short) |
2124 | { | 2189 | { |
2190 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
2125 | int rc; | 2191 | int rc; |
2126 | struct { | 2192 | struct { |
2127 | struct wmi_cmd_hdr wmi; | 2193 | struct wmi_cmd_hdr wmi; |
@@ -2134,7 +2200,7 @@ int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short) | |||
2134 | return -ENOTSUPP; | 2200 | return -ENOTSUPP; |
2135 | 2201 | ||
2136 | reply.evt.mgmt_retry_limit = 0; | 2202 | reply.evt.mgmt_retry_limit = 0; |
2137 | rc = wmi_call(wil, WMI_GET_MGMT_RETRY_LIMIT_CMDID, NULL, 0, | 2203 | rc = wmi_call(wil, WMI_GET_MGMT_RETRY_LIMIT_CMDID, vif->mid, NULL, 0, |
2138 | WMI_GET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), | 2204 | WMI_GET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), |
2139 | 100); | 2205 | 100); |
2140 | if (rc) | 2206 | if (rc) |
@@ -2146,21 +2212,23 @@ int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short) | |||
2146 | return 0; | 2212 | return 0; |
2147 | } | 2213 | } |
2148 | 2214 | ||
2149 | int wmi_abort_scan(struct wil6210_priv *wil) | 2215 | int wmi_abort_scan(struct wil6210_vif *vif) |
2150 | { | 2216 | { |
2217 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
2151 | int rc; | 2218 | int rc; |
2152 | 2219 | ||
2153 | wil_dbg_wmi(wil, "sending WMI_ABORT_SCAN_CMDID\n"); | 2220 | wil_dbg_wmi(wil, "sending WMI_ABORT_SCAN_CMDID\n"); |
2154 | 2221 | ||
2155 | rc = wmi_send(wil, WMI_ABORT_SCAN_CMDID, NULL, 0); | 2222 | rc = wmi_send(wil, WMI_ABORT_SCAN_CMDID, vif->mid, NULL, 0); |
2156 | if (rc) | 2223 | if (rc) |
2157 | wil_err(wil, "Failed to abort scan (%d)\n", rc); | 2224 | wil_err(wil, "Failed to abort scan (%d)\n", rc); |
2158 | 2225 | ||
2159 | return rc; | 2226 | return rc; |
2160 | } | 2227 | } |
2161 | 2228 | ||
2162 | int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid) | 2229 | int wmi_new_sta(struct wil6210_vif *vif, const u8 *mac, u8 aid) |
2163 | { | 2230 | { |
2231 | struct wil6210_priv *wil = vif_to_wil(vif); | ||
2164 | int rc; | 2232 | int rc; |
2165 | struct wmi_new_sta_cmd cmd = { | 2233 | struct wmi_new_sta_cmd cmd = { |
2166 | .aid = aid, | 2234 | .aid = aid, |
@@ -2170,7 +2238,7 @@ int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid) | |||
2170 | 2238 | ||
2171 | ether_addr_copy(cmd.dst_mac, mac); | 2239 | ether_addr_copy(cmd.dst_mac, mac); |
2172 | 2240 | ||
2173 | rc = wmi_send(wil, WMI_NEW_STA_CMDID, &cmd, sizeof(cmd)); | 2241 | rc = wmi_send(wil, WMI_NEW_STA_CMDID, vif->mid, &cmd, sizeof(cmd)); |
2174 | if (rc) | 2242 | if (rc) |
2175 | wil_err(wil, "Failed to send new sta (%d)\n", rc); | 2243 | wil_err(wil, "Failed to send new sta (%d)\n", rc); |
2176 | 2244 | ||
@@ -2206,6 +2274,7 @@ static const char *suspend_status2name(u8 status) | |||
2206 | 2274 | ||
2207 | int wmi_suspend(struct wil6210_priv *wil) | 2275 | int wmi_suspend(struct wil6210_priv *wil) |
2208 | { | 2276 | { |
2277 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
2209 | int rc; | 2278 | int rc; |
2210 | struct wmi_traffic_suspend_cmd cmd = { | 2279 | struct wmi_traffic_suspend_cmd cmd = { |
2211 | .wakeup_trigger = wil->wakeup_trigger, | 2280 | .wakeup_trigger = wil->wakeup_trigger, |
@@ -2221,7 +2290,8 @@ int wmi_suspend(struct wil6210_priv *wil) | |||
2221 | 2290 | ||
2222 | reply.evt.status = WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE; | 2291 | reply.evt.status = WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE; |
2223 | 2292 | ||
2224 | rc = wmi_call(wil, WMI_TRAFFIC_SUSPEND_CMDID, &cmd, sizeof(cmd), | 2293 | rc = wmi_call(wil, WMI_TRAFFIC_SUSPEND_CMDID, vif->mid, |
2294 | &cmd, sizeof(cmd), | ||
2225 | WMI_TRAFFIC_SUSPEND_EVENTID, &reply, sizeof(reply), | 2295 | WMI_TRAFFIC_SUSPEND_EVENTID, &reply, sizeof(reply), |
2226 | suspend_to); | 2296 | suspend_to); |
2227 | if (rc) { | 2297 | if (rc) { |
@@ -2289,6 +2359,7 @@ static void resume_triggers2string(u32 triggers, char *string, int str_size) | |||
2289 | 2359 | ||
2290 | int wmi_resume(struct wil6210_priv *wil) | 2360 | int wmi_resume(struct wil6210_priv *wil) |
2291 | { | 2361 | { |
2362 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
2292 | int rc; | 2363 | int rc; |
2293 | char string[100]; | 2364 | char string[100]; |
2294 | struct { | 2365 | struct { |
@@ -2299,7 +2370,7 @@ int wmi_resume(struct wil6210_priv *wil) | |||
2299 | reply.evt.status = WMI_TRAFFIC_RESUME_FAILED; | 2370 | reply.evt.status = WMI_TRAFFIC_RESUME_FAILED; |
2300 | reply.evt.resume_triggers = WMI_RESUME_TRIGGER_UNKNOWN; | 2371 | reply.evt.resume_triggers = WMI_RESUME_TRIGGER_UNKNOWN; |
2301 | 2372 | ||
2302 | rc = wmi_call(wil, WMI_TRAFFIC_RESUME_CMDID, NULL, 0, | 2373 | rc = wmi_call(wil, WMI_TRAFFIC_RESUME_CMDID, vif->mid, NULL, 0, |
2303 | WMI_TRAFFIC_RESUME_EVENTID, &reply, sizeof(reply), | 2374 | WMI_TRAFFIC_RESUME_EVENTID, &reply, sizeof(reply), |
2304 | WIL_WAIT_FOR_SUSPEND_RESUME_COMP); | 2375 | WIL_WAIT_FOR_SUSPEND_RESUME_COMP); |
2305 | if (rc) | 2376 | if (rc) |
@@ -2313,14 +2384,100 @@ int wmi_resume(struct wil6210_priv *wil) | |||
2313 | return reply.evt.status; | 2384 | return reply.evt.status; |
2314 | } | 2385 | } |
2315 | 2386 | ||
2316 | static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id, | 2387 | int wmi_port_allocate(struct wil6210_priv *wil, u8 mid, |
2388 | const u8 *mac, enum nl80211_iftype iftype) | ||
2389 | { | ||
2390 | int rc; | ||
2391 | struct wmi_port_allocate_cmd cmd = { | ||
2392 | .mid = mid, | ||
2393 | }; | ||
2394 | struct { | ||
2395 | struct wmi_cmd_hdr wmi; | ||
2396 | struct wmi_port_allocated_event evt; | ||
2397 | } __packed reply; | ||
2398 | |||
2399 | wil_dbg_misc(wil, "port allocate, mid %d iftype %d, mac %pM\n", | ||
2400 | mid, iftype, mac); | ||
2401 | |||
2402 | ether_addr_copy(cmd.mac, mac); | ||
2403 | switch (iftype) { | ||
2404 | case NL80211_IFTYPE_STATION: | ||
2405 | cmd.port_role = WMI_PORT_STA; | ||
2406 | break; | ||
2407 | case NL80211_IFTYPE_AP: | ||
2408 | cmd.port_role = WMI_PORT_AP; | ||
2409 | break; | ||
2410 | case NL80211_IFTYPE_P2P_CLIENT: | ||
2411 | cmd.port_role = WMI_PORT_P2P_CLIENT; | ||
2412 | break; | ||
2413 | case NL80211_IFTYPE_P2P_GO: | ||
2414 | cmd.port_role = WMI_PORT_P2P_GO; | ||
2415 | break; | ||
2416 | /* what about monitor??? */ | ||
2417 | default: | ||
2418 | wil_err(wil, "unsupported iftype: %d\n", iftype); | ||
2419 | return -EINVAL; | ||
2420 | } | ||
2421 | |||
2422 | reply.evt.status = WMI_FW_STATUS_FAILURE; | ||
2423 | |||
2424 | rc = wmi_call(wil, WMI_PORT_ALLOCATE_CMDID, mid, | ||
2425 | &cmd, sizeof(cmd), | ||
2426 | WMI_PORT_ALLOCATED_EVENTID, &reply, | ||
2427 | sizeof(reply), 300); | ||
2428 | if (rc) { | ||
2429 | wil_err(wil, "failed to allocate port, status %d\n", rc); | ||
2430 | return rc; | ||
2431 | } | ||
2432 | if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { | ||
2433 | wil_err(wil, "WMI_PORT_ALLOCATE returned status %d\n", | ||
2434 | reply.evt.status); | ||
2435 | return -EINVAL; | ||
2436 | } | ||
2437 | |||
2438 | return 0; | ||
2439 | } | ||
2440 | |||
2441 | int wmi_port_delete(struct wil6210_priv *wil, u8 mid) | ||
2442 | { | ||
2443 | int rc; | ||
2444 | struct wmi_port_delete_cmd cmd = { | ||
2445 | .mid = mid, | ||
2446 | }; | ||
2447 | struct { | ||
2448 | struct wmi_cmd_hdr wmi; | ||
2449 | struct wmi_port_deleted_event evt; | ||
2450 | } __packed reply; | ||
2451 | |||
2452 | wil_dbg_misc(wil, "port delete, mid %d\n", mid); | ||
2453 | |||
2454 | reply.evt.status = WMI_FW_STATUS_FAILURE; | ||
2455 | |||
2456 | rc = wmi_call(wil, WMI_PORT_DELETE_CMDID, mid, | ||
2457 | &cmd, sizeof(cmd), | ||
2458 | WMI_PORT_DELETED_EVENTID, &reply, | ||
2459 | sizeof(reply), 2000); | ||
2460 | if (rc) { | ||
2461 | wil_err(wil, "failed to delete port, status %d\n", rc); | ||
2462 | return rc; | ||
2463 | } | ||
2464 | if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { | ||
2465 | wil_err(wil, "WMI_PORT_DELETE returned status %d\n", | ||
2466 | reply.evt.status); | ||
2467 | return -EINVAL; | ||
2468 | } | ||
2469 | |||
2470 | return 0; | ||
2471 | } | ||
2472 | |||
2473 | static bool wmi_evt_call_handler(struct wil6210_vif *vif, int id, | ||
2317 | void *d, int len) | 2474 | void *d, int len) |
2318 | { | 2475 | { |
2319 | uint i; | 2476 | uint i; |
2320 | 2477 | ||
2321 | for (i = 0; i < ARRAY_SIZE(wmi_evt_handlers); i++) { | 2478 | for (i = 0; i < ARRAY_SIZE(wmi_evt_handlers); i++) { |
2322 | if (wmi_evt_handlers[i].eventid == id) { | 2479 | if (wmi_evt_handlers[i].eventid == id) { |
2323 | wmi_evt_handlers[i].handler(wil, id, d, len); | 2480 | wmi_evt_handlers[i].handler(vif, id, d, len); |
2324 | return true; | 2481 | return true; |
2325 | } | 2482 | } |
2326 | } | 2483 | } |
@@ -2332,19 +2489,39 @@ static void wmi_event_handle(struct wil6210_priv *wil, | |||
2332 | struct wil6210_mbox_hdr *hdr) | 2489 | struct wil6210_mbox_hdr *hdr) |
2333 | { | 2490 | { |
2334 | u16 len = le16_to_cpu(hdr->len); | 2491 | u16 len = le16_to_cpu(hdr->len); |
2492 | struct wil6210_vif *vif; | ||
2335 | 2493 | ||
2336 | if ((hdr->type == WIL_MBOX_HDR_TYPE_WMI) && | 2494 | if ((hdr->type == WIL_MBOX_HDR_TYPE_WMI) && |
2337 | (len >= sizeof(struct wmi_cmd_hdr))) { | 2495 | (len >= sizeof(struct wmi_cmd_hdr))) { |
2338 | struct wmi_cmd_hdr *wmi = (void *)(&hdr[1]); | 2496 | struct wmi_cmd_hdr *wmi = (void *)(&hdr[1]); |
2339 | void *evt_data = (void *)(&wmi[1]); | 2497 | void *evt_data = (void *)(&wmi[1]); |
2340 | u16 id = le16_to_cpu(wmi->command_id); | 2498 | u16 id = le16_to_cpu(wmi->command_id); |
2499 | u8 mid = wmi->mid; | ||
2500 | |||
2501 | wil_dbg_wmi(wil, "Handle %s (0x%04x) (reply_id 0x%04x,%d)\n", | ||
2502 | eventid2name(id), id, wil->reply_id, | ||
2503 | wil->reply_mid); | ||
2504 | |||
2505 | if (mid == MID_BROADCAST) | ||
2506 | mid = 0; | ||
2507 | if (mid >= wil->max_vifs) { | ||
2508 | wil_dbg_wmi(wil, "invalid mid %d, event skipped\n", | ||
2509 | mid); | ||
2510 | return; | ||
2511 | } | ||
2512 | vif = wil->vifs[mid]; | ||
2513 | if (!vif) { | ||
2514 | wil_dbg_wmi(wil, "event for empty VIF(%d), skipped\n", | ||
2515 | mid); | ||
2516 | return; | ||
2517 | } | ||
2341 | 2518 | ||
2342 | wil_dbg_wmi(wil, "Handle %s (0x%04x) (reply_id 0x%04x)\n", | ||
2343 | eventid2name(id), id, wil->reply_id); | ||
2344 | /* check if someone waits for this event */ | 2519 | /* check if someone waits for this event */ |
2345 | if (wil->reply_id && wil->reply_id == id) { | 2520 | if (wil->reply_id && wil->reply_id == id && |
2521 | wil->reply_mid == mid) { | ||
2346 | WARN_ON(wil->reply_buf); | 2522 | WARN_ON(wil->reply_buf); |
2347 | wmi_evt_call_handler(wil, id, evt_data, | 2523 | |
2524 | wmi_evt_call_handler(vif, id, evt_data, | ||
2348 | len - sizeof(*wmi)); | 2525 | len - sizeof(*wmi)); |
2349 | wil_dbg_wmi(wil, "event_handle: Complete WMI 0x%04x\n", | 2526 | wil_dbg_wmi(wil, "event_handle: Complete WMI 0x%04x\n", |
2350 | id); | 2527 | id); |
@@ -2353,7 +2530,7 @@ static void wmi_event_handle(struct wil6210_priv *wil, | |||
2353 | } | 2530 | } |
2354 | /* unsolicited event */ | 2531 | /* unsolicited event */ |
2355 | /* search for handler */ | 2532 | /* search for handler */ |
2356 | if (!wmi_evt_call_handler(wil, id, evt_data, | 2533 | if (!wmi_evt_call_handler(vif, id, evt_data, |
2357 | len - sizeof(*wmi))) { | 2534 | len - sizeof(*wmi))) { |
2358 | wil_info(wil, "Unhandled event 0x%04x\n", id); | 2535 | wil_info(wil, "Unhandled event 0x%04x\n", id); |
2359 | } | 2536 | } |
@@ -2523,6 +2700,7 @@ wmi_sched_scan_set_plans(struct wil6210_priv *wil, | |||
2523 | int wmi_start_sched_scan(struct wil6210_priv *wil, | 2700 | int wmi_start_sched_scan(struct wil6210_priv *wil, |
2524 | struct cfg80211_sched_scan_request *request) | 2701 | struct cfg80211_sched_scan_request *request) |
2525 | { | 2702 | { |
2703 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
2526 | int rc; | 2704 | int rc; |
2527 | struct wmi_start_sched_scan_cmd cmd = { | 2705 | struct wmi_start_sched_scan_cmd cmd = { |
2528 | .min_rssi_threshold = S8_MIN, | 2706 | .min_rssi_threshold = S8_MIN, |
@@ -2549,7 +2727,8 @@ int wmi_start_sched_scan(struct wil6210_priv *wil, | |||
2549 | 2727 | ||
2550 | reply.evt.result = WMI_PNO_REJECT; | 2728 | reply.evt.result = WMI_PNO_REJECT; |
2551 | 2729 | ||
2552 | rc = wmi_call(wil, WMI_START_SCHED_SCAN_CMDID, &cmd, sizeof(cmd), | 2730 | rc = wmi_call(wil, WMI_START_SCHED_SCAN_CMDID, vif->mid, |
2731 | &cmd, sizeof(cmd), | ||
2553 | WMI_START_SCHED_SCAN_EVENTID, &reply, sizeof(reply), | 2732 | WMI_START_SCHED_SCAN_EVENTID, &reply, sizeof(reply), |
2554 | WIL_WMI_CALL_GENERAL_TO_MS); | 2733 | WIL_WMI_CALL_GENERAL_TO_MS); |
2555 | if (rc) | 2734 | if (rc) |
@@ -2566,6 +2745,7 @@ int wmi_start_sched_scan(struct wil6210_priv *wil, | |||
2566 | 2745 | ||
2567 | int wmi_stop_sched_scan(struct wil6210_priv *wil) | 2746 | int wmi_stop_sched_scan(struct wil6210_priv *wil) |
2568 | { | 2747 | { |
2748 | struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); | ||
2569 | int rc; | 2749 | int rc; |
2570 | struct { | 2750 | struct { |
2571 | struct wmi_cmd_hdr wmi; | 2751 | struct wmi_cmd_hdr wmi; |
@@ -2577,7 +2757,7 @@ int wmi_stop_sched_scan(struct wil6210_priv *wil) | |||
2577 | 2757 | ||
2578 | reply.evt.result = WMI_PNO_REJECT; | 2758 | reply.evt.result = WMI_PNO_REJECT; |
2579 | 2759 | ||
2580 | rc = wmi_call(wil, WMI_STOP_SCHED_SCAN_CMDID, NULL, 0, | 2760 | rc = wmi_call(wil, WMI_STOP_SCHED_SCAN_CMDID, vif->mid, NULL, 0, |
2581 | WMI_STOP_SCHED_SCAN_EVENTID, &reply, sizeof(reply), | 2761 | WMI_STOP_SCHED_SCAN_EVENTID, &reply, sizeof(reply), |
2582 | WIL_WMI_CALL_GENERAL_TO_MS); | 2762 | WIL_WMI_CALL_GENERAL_TO_MS); |
2583 | if (rc) | 2763 | if (rc) |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c index 2d3a5dd07a3f..1068a2a4494c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | |||
@@ -445,6 +445,11 @@ brcmf_proto_bcdc_init_done(struct brcmf_pub *drvr) | |||
445 | return 0; | 445 | return 0; |
446 | } | 446 | } |
447 | 447 | ||
448 | static void brcmf_proto_bcdc_debugfs_create(struct brcmf_pub *drvr) | ||
449 | { | ||
450 | brcmf_fws_debugfs_create(drvr); | ||
451 | } | ||
452 | |||
448 | int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) | 453 | int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) |
449 | { | 454 | { |
450 | struct brcmf_bcdc *bcdc; | 455 | struct brcmf_bcdc *bcdc; |
@@ -472,6 +477,7 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) | |||
472 | drvr->proto->del_if = brcmf_proto_bcdc_del_if; | 477 | drvr->proto->del_if = brcmf_proto_bcdc_del_if; |
473 | drvr->proto->reset_if = brcmf_proto_bcdc_reset_if; | 478 | drvr->proto->reset_if = brcmf_proto_bcdc_reset_if; |
474 | drvr->proto->init_done = brcmf_proto_bcdc_init_done; | 479 | drvr->proto->init_done = brcmf_proto_bcdc_init_done; |
480 | drvr->proto->debugfs_create = brcmf_proto_bcdc_debugfs_create; | ||
475 | drvr->proto->pd = bcdc; | 481 | drvr->proto->pd = bcdc; |
476 | 482 | ||
477 | drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; | 483 | drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c index 03aae6bc1838..372363a6e752 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c | |||
@@ -462,7 +462,7 @@ static void brcmf_btcoex_dhcp_end(struct brcmf_btcoex_info *btci) | |||
462 | int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif, | 462 | int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif, |
463 | enum brcmf_btcoex_mode mode, u16 duration) | 463 | enum brcmf_btcoex_mode mode, u16 duration) |
464 | { | 464 | { |
465 | struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy); | 465 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); |
466 | struct brcmf_btcoex_info *btci = cfg->btcoex; | 466 | struct brcmf_btcoex_info *btci = cfg->btcoex; |
467 | struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); | 467 | struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); |
468 | 468 | ||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h index 0b90a63bdeb1..27e693e93f21 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | |||
@@ -88,7 +88,7 @@ struct brcmf_bus_ops { | |||
88 | void (*wowl_config)(struct device *dev, bool enabled); | 88 | void (*wowl_config)(struct device *dev, bool enabled); |
89 | size_t (*get_ramsize)(struct device *dev); | 89 | size_t (*get_ramsize)(struct device *dev); |
90 | int (*get_memdump)(struct device *dev, void *data, size_t len); | 90 | int (*get_memdump)(struct device *dev, void *data, size_t len); |
91 | int (*get_fwname)(struct device *dev, uint chip, uint chiprev, | 91 | int (*get_fwname)(struct device *dev, const char *ext, |
92 | unsigned char *fw_name); | 92 | unsigned char *fw_name); |
93 | }; | 93 | }; |
94 | 94 | ||
@@ -140,6 +140,7 @@ struct brcmf_bus_stats { | |||
140 | * @always_use_fws_queue: bus wants use queue also when fwsignal is inactive. | 140 | * @always_use_fws_queue: bus wants use queue also when fwsignal is inactive. |
141 | * @wowl_supported: is wowl supported by bus driver. | 141 | * @wowl_supported: is wowl supported by bus driver. |
142 | * @chiprev: revision of the dongle chip. | 142 | * @chiprev: revision of the dongle chip. |
143 | * @msgbuf: msgbuf protocol parameters provided by bus layer. | ||
143 | */ | 144 | */ |
144 | struct brcmf_bus { | 145 | struct brcmf_bus { |
145 | union { | 146 | union { |
@@ -228,10 +229,10 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len) | |||
228 | } | 229 | } |
229 | 230 | ||
230 | static inline | 231 | static inline |
231 | int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev, | 232 | int brcmf_bus_get_fwname(struct brcmf_bus *bus, const char *ext, |
232 | unsigned char *fw_name) | 233 | unsigned char *fw_name) |
233 | { | 234 | { |
234 | return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name); | 235 | return bus->ops->get_fwname(bus->dev, ext, fw_name); |
235 | } | 236 | } |
236 | 237 | ||
237 | /* | 238 | /* |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 74a83020c073..89b86251910e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | |||
@@ -753,7 +753,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, | |||
753 | static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy, | 753 | static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy, |
754 | struct wireless_dev *wdev) | 754 | struct wireless_dev *wdev) |
755 | { | 755 | { |
756 | struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); | 756 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
757 | struct net_device *ndev = wdev->netdev; | 757 | struct net_device *ndev = wdev->netdev; |
758 | struct brcmf_if *ifp = netdev_priv(ndev); | 758 | struct brcmf_if *ifp = netdev_priv(ndev); |
759 | int ret; | 759 | int ret; |
@@ -786,7 +786,7 @@ err_unarm: | |||
786 | static | 786 | static |
787 | int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) | 787 | int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) |
788 | { | 788 | { |
789 | struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); | 789 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
790 | struct net_device *ndev = wdev->netdev; | 790 | struct net_device *ndev = wdev->netdev; |
791 | 791 | ||
792 | if (ndev && ndev == cfg_to_ndev(cfg)) | 792 | if (ndev && ndev == cfg_to_ndev(cfg)) |
@@ -831,7 +831,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, | |||
831 | enum nl80211_iftype type, | 831 | enum nl80211_iftype type, |
832 | struct vif_params *params) | 832 | struct vif_params *params) |
833 | { | 833 | { |
834 | struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); | 834 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
835 | struct brcmf_if *ifp = netdev_priv(ndev); | 835 | struct brcmf_if *ifp = netdev_priv(ndev); |
836 | struct brcmf_cfg80211_vif *vif = ifp->vif; | 836 | struct brcmf_cfg80211_vif *vif = ifp->vif; |
837 | s32 infra = 0; | 837 | s32 infra = 0; |
@@ -2127,17 +2127,15 @@ static s32 | |||
2127 | brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, | 2127 | brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, |
2128 | s32 *dbm) | 2128 | s32 *dbm) |
2129 | { | 2129 | { |
2130 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 2130 | struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev); |
2131 | struct net_device *ndev = cfg_to_ndev(cfg); | ||
2132 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
2133 | s32 qdbm = 0; | 2131 | s32 qdbm = 0; |
2134 | s32 err; | 2132 | s32 err; |
2135 | 2133 | ||
2136 | brcmf_dbg(TRACE, "Enter\n"); | 2134 | brcmf_dbg(TRACE, "Enter\n"); |
2137 | if (!check_vif_up(ifp->vif)) | 2135 | if (!check_vif_up(vif)) |
2138 | return -EIO; | 2136 | return -EIO; |
2139 | 2137 | ||
2140 | err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm); | 2138 | err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm); |
2141 | if (err) { | 2139 | if (err) { |
2142 | brcmf_err("error (%d)\n", err); | 2140 | brcmf_err("error (%d)\n", err); |
2143 | goto done; | 2141 | goto done; |
@@ -3358,7 +3356,7 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, | |||
3358 | struct cfg80211_sched_scan_request *req) | 3356 | struct cfg80211_sched_scan_request *req) |
3359 | { | 3357 | { |
3360 | struct brcmf_if *ifp = netdev_priv(ndev); | 3358 | struct brcmf_if *ifp = netdev_priv(ndev); |
3361 | struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); | 3359 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
3362 | 3360 | ||
3363 | brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n", | 3361 | brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n", |
3364 | req->n_match_sets, req->n_ssids); | 3362 | req->n_match_sets, req->n_ssids); |
@@ -5190,6 +5188,12 @@ static struct cfg80211_ops brcmf_cfg80211_ops = { | |||
5190 | .del_pmk = brcmf_cfg80211_del_pmk, | 5188 | .del_pmk = brcmf_cfg80211_del_pmk, |
5191 | }; | 5189 | }; |
5192 | 5190 | ||
5191 | struct cfg80211_ops *brcmf_cfg80211_get_ops(void) | ||
5192 | { | ||
5193 | return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops), | ||
5194 | GFP_KERNEL); | ||
5195 | } | ||
5196 | |||
5193 | struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | 5197 | struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, |
5194 | enum nl80211_iftype type) | 5198 | enum nl80211_iftype type) |
5195 | { | 5199 | { |
@@ -5897,7 +5901,7 @@ static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel, | |||
5897 | static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, | 5901 | static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, |
5898 | u32 bw_cap[]) | 5902 | u32 bw_cap[]) |
5899 | { | 5903 | { |
5900 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | 5904 | struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); |
5901 | struct ieee80211_supported_band *band; | 5905 | struct ieee80211_supported_band *band; |
5902 | struct ieee80211_channel *channel; | 5906 | struct ieee80211_channel *channel; |
5903 | struct wiphy *wiphy; | 5907 | struct wiphy *wiphy; |
@@ -6012,7 +6016,7 @@ fail_pbuf: | |||
6012 | 6016 | ||
6013 | static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) | 6017 | static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) |
6014 | { | 6018 | { |
6015 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | 6019 | struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); |
6016 | struct ieee80211_supported_band *band; | 6020 | struct ieee80211_supported_band *band; |
6017 | struct brcmf_fil_bwcap_le band_bwcap; | 6021 | struct brcmf_fil_bwcap_le band_bwcap; |
6018 | struct brcmf_chanspec_list *list; | 6022 | struct brcmf_chanspec_list *list; |
@@ -6197,10 +6201,10 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band, | |||
6197 | } | 6201 | } |
6198 | } | 6202 | } |
6199 | 6203 | ||
6200 | static int brcmf_setup_wiphybands(struct wiphy *wiphy) | 6204 | static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) |
6201 | { | 6205 | { |
6202 | struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); | 6206 | struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); |
6203 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | 6207 | struct wiphy *wiphy; |
6204 | u32 nmode = 0; | 6208 | u32 nmode = 0; |
6205 | u32 vhtmode = 0; | 6209 | u32 vhtmode = 0; |
6206 | u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT }; | 6210 | u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT }; |
@@ -6794,8 +6798,8 @@ static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2], | |||
6794 | static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, | 6798 | static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, |
6795 | struct regulatory_request *req) | 6799 | struct regulatory_request *req) |
6796 | { | 6800 | { |
6797 | struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); | 6801 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
6798 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | 6802 | struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); |
6799 | struct brcmf_fil_country_le ccreq; | 6803 | struct brcmf_fil_country_le ccreq; |
6800 | s32 err; | 6804 | s32 err; |
6801 | int i; | 6805 | int i; |
@@ -6805,7 +6809,7 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, | |||
6805 | return; | 6809 | return; |
6806 | 6810 | ||
6807 | /* ignore non-ISO3166 country codes */ | 6811 | /* ignore non-ISO3166 country codes */ |
6808 | for (i = 0; i < sizeof(req->alpha2); i++) | 6812 | for (i = 0; i < 2; i++) |
6809 | if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { | 6813 | if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { |
6810 | brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n", | 6814 | brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n", |
6811 | req->alpha2[0], req->alpha2[1]); | 6815 | req->alpha2[0], req->alpha2[1]); |
@@ -6830,7 +6834,7 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, | |||
6830 | brcmf_err("Firmware rejected country setting\n"); | 6834 | brcmf_err("Firmware rejected country setting\n"); |
6831 | return; | 6835 | return; |
6832 | } | 6836 | } |
6833 | brcmf_setup_wiphybands(wiphy); | 6837 | brcmf_setup_wiphybands(cfg); |
6834 | } | 6838 | } |
6835 | 6839 | ||
6836 | static void brcmf_free_wiphy(struct wiphy *wiphy) | 6840 | static void brcmf_free_wiphy(struct wiphy *wiphy) |
@@ -6857,17 +6861,15 @@ static void brcmf_free_wiphy(struct wiphy *wiphy) | |||
6857 | if (wiphy->wowlan != &brcmf_wowlan_support) | 6861 | if (wiphy->wowlan != &brcmf_wowlan_support) |
6858 | kfree(wiphy->wowlan); | 6862 | kfree(wiphy->wowlan); |
6859 | #endif | 6863 | #endif |
6860 | wiphy_free(wiphy); | ||
6861 | } | 6864 | } |
6862 | 6865 | ||
6863 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | 6866 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, |
6864 | struct device *busdev, | 6867 | struct cfg80211_ops *ops, |
6865 | bool p2pdev_forced) | 6868 | bool p2pdev_forced) |
6866 | { | 6869 | { |
6870 | struct wiphy *wiphy = drvr->wiphy; | ||
6867 | struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev; | 6871 | struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev; |
6868 | struct brcmf_cfg80211_info *cfg; | 6872 | struct brcmf_cfg80211_info *cfg; |
6869 | struct wiphy *wiphy; | ||
6870 | struct cfg80211_ops *ops; | ||
6871 | struct brcmf_cfg80211_vif *vif; | 6873 | struct brcmf_cfg80211_vif *vif; |
6872 | struct brcmf_if *ifp; | 6874 | struct brcmf_if *ifp; |
6873 | s32 err = 0; | 6875 | s32 err = 0; |
@@ -6879,26 +6881,13 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | |||
6879 | return NULL; | 6881 | return NULL; |
6880 | } | 6882 | } |
6881 | 6883 | ||
6882 | ops = kmemdup(&brcmf_cfg80211_ops, sizeof(*ops), GFP_KERNEL); | 6884 | cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); |
6883 | if (!ops) | 6885 | if (!cfg) { |
6884 | return NULL; | ||
6885 | |||
6886 | ifp = netdev_priv(ndev); | ||
6887 | #ifdef CONFIG_PM | ||
6888 | if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) | ||
6889 | ops->set_rekey_data = brcmf_cfg80211_set_rekey_data; | ||
6890 | #endif | ||
6891 | wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info)); | ||
6892 | if (!wiphy) { | ||
6893 | brcmf_err("Could not allocate wiphy device\n"); | 6886 | brcmf_err("Could not allocate wiphy device\n"); |
6894 | goto ops_out; | 6887 | return NULL; |
6895 | } | 6888 | } |
6896 | memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN); | ||
6897 | set_wiphy_dev(wiphy, busdev); | ||
6898 | 6889 | ||
6899 | cfg = wiphy_priv(wiphy); | ||
6900 | cfg->wiphy = wiphy; | 6890 | cfg->wiphy = wiphy; |
6901 | cfg->ops = ops; | ||
6902 | cfg->pub = drvr; | 6891 | cfg->pub = drvr; |
6903 | init_vif_event(&cfg->vif_event); | 6892 | init_vif_event(&cfg->vif_event); |
6904 | INIT_LIST_HEAD(&cfg->vif_list); | 6893 | INIT_LIST_HEAD(&cfg->vif_list); |
@@ -6907,6 +6896,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | |||
6907 | if (IS_ERR(vif)) | 6896 | if (IS_ERR(vif)) |
6908 | goto wiphy_out; | 6897 | goto wiphy_out; |
6909 | 6898 | ||
6899 | ifp = netdev_priv(ndev); | ||
6910 | vif->ifp = ifp; | 6900 | vif->ifp = ifp; |
6911 | vif->wdev.netdev = ndev; | 6901 | vif->wdev.netdev = ndev; |
6912 | ndev->ieee80211_ptr = &vif->wdev; | 6902 | ndev->ieee80211_ptr = &vif->wdev; |
@@ -6933,6 +6923,11 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | |||
6933 | if (err < 0) | 6923 | if (err < 0) |
6934 | goto priv_out; | 6924 | goto priv_out; |
6935 | 6925 | ||
6926 | /* regulatory notifer below needs access to cfg so | ||
6927 | * assign it now. | ||
6928 | */ | ||
6929 | drvr->config = cfg; | ||
6930 | |||
6936 | brcmf_dbg(INFO, "Registering custom regulatory\n"); | 6931 | brcmf_dbg(INFO, "Registering custom regulatory\n"); |
6937 | wiphy->reg_notifier = brcmf_cfg80211_reg_notifier; | 6932 | wiphy->reg_notifier = brcmf_cfg80211_reg_notifier; |
6938 | wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; | 6933 | wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; |
@@ -6946,13 +6941,17 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | |||
6946 | cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap; | 6941 | cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap; |
6947 | *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 6942 | *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
6948 | } | 6943 | } |
6944 | #ifdef CONFIG_PM | ||
6945 | if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) | ||
6946 | ops->set_rekey_data = brcmf_cfg80211_set_rekey_data; | ||
6947 | #endif | ||
6949 | err = wiphy_register(wiphy); | 6948 | err = wiphy_register(wiphy); |
6950 | if (err < 0) { | 6949 | if (err < 0) { |
6951 | brcmf_err("Could not register wiphy device (%d)\n", err); | 6950 | brcmf_err("Could not register wiphy device (%d)\n", err); |
6952 | goto priv_out; | 6951 | goto priv_out; |
6953 | } | 6952 | } |
6954 | 6953 | ||
6955 | err = brcmf_setup_wiphybands(wiphy); | 6954 | err = brcmf_setup_wiphybands(cfg); |
6956 | if (err) { | 6955 | if (err) { |
6957 | brcmf_err("Setting wiphy bands failed (%d)\n", err); | 6956 | brcmf_err("Setting wiphy bands failed (%d)\n", err); |
6958 | goto wiphy_unreg_out; | 6957 | goto wiphy_unreg_out; |
@@ -6969,12 +6968,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | |||
6969 | else | 6968 | else |
6970 | *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 6969 | *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
6971 | } | 6970 | } |
6972 | /* p2p might require that "if-events" get processed by fweh. So | 6971 | |
6973 | * activate the already registered event handlers now and activate | ||
6974 | * the rest when initialization has completed. drvr->config needs to | ||
6975 | * be assigned before activating events. | ||
6976 | */ | ||
6977 | drvr->config = cfg; | ||
6978 | err = brcmf_fweh_activate_events(ifp); | 6972 | err = brcmf_fweh_activate_events(ifp); |
6979 | if (err) { | 6973 | if (err) { |
6980 | brcmf_err("FWEH activation failed (%d)\n", err); | 6974 | brcmf_err("FWEH activation failed (%d)\n", err); |
@@ -7042,8 +7036,7 @@ priv_out: | |||
7042 | ifp->vif = NULL; | 7036 | ifp->vif = NULL; |
7043 | wiphy_out: | 7037 | wiphy_out: |
7044 | brcmf_free_wiphy(wiphy); | 7038 | brcmf_free_wiphy(wiphy); |
7045 | ops_out: | 7039 | kfree(cfg); |
7046 | kfree(ops); | ||
7047 | return NULL; | 7040 | return NULL; |
7048 | } | 7041 | } |
7049 | 7042 | ||
@@ -7058,4 +7051,5 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) | |||
7058 | kfree(cfg->ops); | 7051 | kfree(cfg->ops); |
7059 | wl_deinit_priv(cfg); | 7052 | wl_deinit_priv(cfg); |
7060 | brcmf_free_wiphy(cfg->wiphy); | 7053 | brcmf_free_wiphy(cfg->wiphy); |
7054 | kfree(cfg); | ||
7061 | } | 7055 | } |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h index b5b5f0f10b63..a4aec0004e4f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | |||
@@ -355,20 +355,24 @@ static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *cfg) | |||
355 | 355 | ||
356 | static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w) | 356 | static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w) |
357 | { | 357 | { |
358 | return (struct brcmf_cfg80211_info *)(wiphy_priv(w)); | 358 | struct brcmf_pub *drvr = wiphy_priv(w); |
359 | return drvr->config; | ||
359 | } | 360 | } |
360 | 361 | ||
361 | static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd) | 362 | static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd) |
362 | { | 363 | { |
363 | return (struct brcmf_cfg80211_info *)(wdev_priv(wd)); | 364 | return wiphy_to_cfg(wd->wiphy); |
365 | } | ||
366 | |||
367 | static inline struct brcmf_cfg80211_vif *wdev_to_vif(struct wireless_dev *wdev) | ||
368 | { | ||
369 | return container_of(wdev, struct brcmf_cfg80211_vif, wdev); | ||
364 | } | 370 | } |
365 | 371 | ||
366 | static inline | 372 | static inline |
367 | struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg) | 373 | struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg) |
368 | { | 374 | { |
369 | struct brcmf_cfg80211_vif *vif; | 375 | return brcmf_get_ifp(cfg->pub, 0)->ndev; |
370 | vif = list_first_entry(&cfg->vif_list, struct brcmf_cfg80211_vif, list); | ||
371 | return vif->wdev.netdev; | ||
372 | } | 376 | } |
373 | 377 | ||
374 | static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev) | 378 | static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev) |
@@ -395,11 +399,12 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) | |||
395 | } | 399 | } |
396 | 400 | ||
397 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | 401 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, |
398 | struct device *busdev, | 402 | struct cfg80211_ops *ops, |
399 | bool p2pdev_forced); | 403 | bool p2pdev_forced); |
400 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); | 404 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); |
401 | s32 brcmf_cfg80211_up(struct net_device *ndev); | 405 | s32 brcmf_cfg80211_up(struct net_device *ndev); |
402 | s32 brcmf_cfg80211_down(struct net_device *ndev); | 406 | s32 brcmf_cfg80211_down(struct net_device *ndev); |
407 | struct cfg80211_ops *brcmf_cfg80211_get_ops(void); | ||
403 | enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); | 408 | enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); |
404 | 409 | ||
405 | struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | 410 | struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c index f7b30ce2300d..3b829fed8631 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | |||
@@ -464,12 +464,12 @@ static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset, | |||
464 | ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL); | 464 | ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL); |
465 | } | 465 | } |
466 | 466 | ||
467 | static char *brcmf_chip_name(uint chipid, char *buf, uint len) | 467 | char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len) |
468 | { | 468 | { |
469 | const char *fmt; | 469 | const char *fmt; |
470 | 470 | ||
471 | fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; | 471 | fmt = ((id > 0xa000) || (id < 0x4000)) ? "BCM%d/%u" : "BCM%x/%u"; |
472 | snprintf(buf, len, fmt, chipid); | 472 | snprintf(buf, len, fmt, id, rev); |
473 | return buf; | 473 | return buf; |
474 | } | 474 | } |
475 | 475 | ||
@@ -924,10 +924,10 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci) | |||
924 | ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; | 924 | ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; |
925 | socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; | 925 | socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; |
926 | 926 | ||
927 | brcmf_chip_name(ci->pub.chip, ci->pub.name, sizeof(ci->pub.name)); | 927 | brcmf_chip_name(ci->pub.chip, ci->pub.chiprev, |
928 | brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n", | 928 | ci->pub.name, sizeof(ci->pub.name)); |
929 | socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name, | 929 | brcmf_dbg(INFO, "found %s chip: %s\n", |
930 | ci->pub.chiprev); | 930 | socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name); |
931 | 931 | ||
932 | if (socitype == SOCI_SB) { | 932 | if (socitype == SOCI_SB) { |
933 | if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) { | 933 | if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) { |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h index dd0ec3eba6a9..0ae3b33bab62 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h | |||
@@ -45,7 +45,7 @@ struct brcmf_chip { | |||
45 | u32 rambase; | 45 | u32 rambase; |
46 | u32 ramsize; | 46 | u32 ramsize; |
47 | u32 srsize; | 47 | u32 srsize; |
48 | char name[8]; | 48 | char name[12]; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | /** | 51 | /** |
@@ -93,5 +93,6 @@ void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset, | |||
93 | void brcmf_chip_set_passive(struct brcmf_chip *ci); | 93 | void brcmf_chip_set_passive(struct brcmf_chip *ci); |
94 | bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec); | 94 | bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec); |
95 | bool brcmf_chip_sr_capable(struct brcmf_chip *pub); | 95 | bool brcmf_chip_sr_capable(struct brcmf_chip *pub); |
96 | char *brcmf_chip_name(u32 chipid, u32 chiprev, char *buf, uint len); | ||
96 | 97 | ||
97 | #endif /* BRCMF_AXIDMP_H */ | 98 | #endif /* BRCMF_AXIDMP_H */ |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 70ef9835b647..105b8774fca9 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "common.h" | 30 | #include "common.h" |
31 | #include "of.h" | 31 | #include "of.h" |
32 | #include "firmware.h" | 32 | #include "firmware.h" |
33 | #include "chip.h" | ||
33 | 34 | ||
34 | MODULE_AUTHOR("Broadcom Corporation"); | 35 | MODULE_AUTHOR("Broadcom Corporation"); |
35 | MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); | 36 | MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); |
@@ -51,7 +52,7 @@ MODULE_PARM_DESC(txglomsz, "Maximum tx packet chain size [SDIO]"); | |||
51 | 52 | ||
52 | /* Debug level configuration. See debug.h for bits, sysfs modifiable */ | 53 | /* Debug level configuration. See debug.h for bits, sysfs modifiable */ |
53 | int brcmf_msg_level; | 54 | int brcmf_msg_level; |
54 | module_param_named(debug, brcmf_msg_level, int, S_IRUSR | S_IWUSR); | 55 | module_param_named(debug, brcmf_msg_level, int, 0600); |
55 | MODULE_PARM_DESC(debug, "Level of debug output"); | 56 | MODULE_PARM_DESC(debug, "Level of debug output"); |
56 | 57 | ||
57 | static int brcmf_p2p_enable; | 58 | static int brcmf_p2p_enable; |
@@ -64,7 +65,7 @@ MODULE_PARM_DESC(feature_disable, "Disable features"); | |||
64 | 65 | ||
65 | static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN]; | 66 | static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN]; |
66 | module_param_string(alternative_fw_path, brcmf_firmware_path, | 67 | module_param_string(alternative_fw_path, brcmf_firmware_path, |
67 | BRCMF_FW_ALTPATH_LEN, S_IRUSR); | 68 | BRCMF_FW_ALTPATH_LEN, 0400); |
68 | MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path"); | 69 | MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path"); |
69 | 70 | ||
70 | static int brcmf_fcmode; | 71 | static int brcmf_fcmode; |
@@ -72,9 +73,13 @@ module_param_named(fcmode, brcmf_fcmode, int, 0); | |||
72 | MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control"); | 73 | MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control"); |
73 | 74 | ||
74 | static int brcmf_roamoff; | 75 | static int brcmf_roamoff; |
75 | module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR); | 76 | module_param_named(roamoff, brcmf_roamoff, int, 0400); |
76 | MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); | 77 | MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); |
77 | 78 | ||
79 | static int brcmf_iapp_enable; | ||
80 | module_param_named(iapp, brcmf_iapp_enable, int, 0); | ||
81 | MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol"); | ||
82 | |||
78 | #ifdef DEBUG | 83 | #ifdef DEBUG |
79 | /* always succeed brcmf_bus_started() */ | 84 | /* always succeed brcmf_bus_started() */ |
80 | static int brcmf_ignore_probe_fail; | 85 | static int brcmf_ignore_probe_fail; |
@@ -124,43 +129,9 @@ static int brcmf_c_download(struct brcmf_if *ifp, u16 flag, | |||
124 | return err; | 129 | return err; |
125 | } | 130 | } |
126 | 131 | ||
127 | static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name) | ||
128 | { | ||
129 | struct brcmf_bus *bus = ifp->drvr->bus_if; | ||
130 | struct brcmf_rev_info *ri = &ifp->drvr->revinfo; | ||
131 | u8 fw_name[BRCMF_FW_NAME_LEN]; | ||
132 | u8 *ptr; | ||
133 | size_t len; | ||
134 | s32 err; | ||
135 | |||
136 | memset(fw_name, 0, BRCMF_FW_NAME_LEN); | ||
137 | err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name); | ||
138 | if (err) { | ||
139 | brcmf_err("get firmware name failed (%d)\n", err); | ||
140 | goto done; | ||
141 | } | ||
142 | |||
143 | /* generate CLM blob file name */ | ||
144 | ptr = strrchr(fw_name, '.'); | ||
145 | if (!ptr) { | ||
146 | err = -ENOENT; | ||
147 | goto done; | ||
148 | } | ||
149 | |||
150 | len = ptr - fw_name + 1; | ||
151 | if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) { | ||
152 | err = -E2BIG; | ||
153 | } else { | ||
154 | strlcpy(clm_name, fw_name, len); | ||
155 | strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN); | ||
156 | } | ||
157 | done: | ||
158 | return err; | ||
159 | } | ||
160 | |||
161 | static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) | 132 | static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) |
162 | { | 133 | { |
163 | struct device *dev = ifp->drvr->bus_if->dev; | 134 | struct brcmf_bus *bus = ifp->drvr->bus_if; |
164 | struct brcmf_dload_data_le *chunk_buf; | 135 | struct brcmf_dload_data_le *chunk_buf; |
165 | const struct firmware *clm = NULL; | 136 | const struct firmware *clm = NULL; |
166 | u8 clm_name[BRCMF_FW_NAME_LEN]; | 137 | u8 clm_name[BRCMF_FW_NAME_LEN]; |
@@ -173,16 +144,16 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) | |||
173 | 144 | ||
174 | brcmf_dbg(TRACE, "Enter\n"); | 145 | brcmf_dbg(TRACE, "Enter\n"); |
175 | 146 | ||
176 | memset(clm_name, 0, BRCMF_FW_NAME_LEN); | 147 | memset(clm_name, 0, sizeof(clm_name)); |
177 | err = brcmf_c_get_clm_name(ifp, clm_name); | 148 | err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name); |
178 | if (err) { | 149 | if (err) { |
179 | brcmf_err("get CLM blob file name failed (%d)\n", err); | 150 | brcmf_err("get CLM blob file name failed (%d)\n", err); |
180 | return err; | 151 | return err; |
181 | } | 152 | } |
182 | 153 | ||
183 | err = request_firmware(&clm, clm_name, dev); | 154 | err = request_firmware(&clm, clm_name, bus->dev); |
184 | if (err) { | 155 | if (err) { |
185 | brcmf_info("no clm_blob available(err=%d), device may have limited channels available\n", | 156 | brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n", |
186 | err); | 157 | err); |
187 | return 0; | 158 | return 0; |
188 | } | 159 | } |
@@ -234,6 +205,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) | |||
234 | { | 205 | { |
235 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; | 206 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; |
236 | u8 buf[BRCMF_DCMD_SMLEN]; | 207 | u8 buf[BRCMF_DCMD_SMLEN]; |
208 | struct brcmf_bus *bus; | ||
237 | struct brcmf_rev_info_le revinfo; | 209 | struct brcmf_rev_info_le revinfo; |
238 | struct brcmf_rev_info *ri; | 210 | struct brcmf_rev_info *ri; |
239 | char *clmver; | 211 | char *clmver; |
@@ -247,18 +219,21 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) | |||
247 | brcmf_err("Retreiving cur_etheraddr failed, %d\n", err); | 219 | brcmf_err("Retreiving cur_etheraddr failed, %d\n", err); |
248 | goto done; | 220 | goto done; |
249 | } | 221 | } |
222 | memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); | ||
250 | memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); | 223 | memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); |
251 | 224 | ||
225 | bus = ifp->drvr->bus_if; | ||
226 | ri = &ifp->drvr->revinfo; | ||
227 | |||
252 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO, | 228 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO, |
253 | &revinfo, sizeof(revinfo)); | 229 | &revinfo, sizeof(revinfo)); |
254 | ri = &ifp->drvr->revinfo; | ||
255 | if (err < 0) { | 230 | if (err < 0) { |
256 | brcmf_err("retrieving revision info failed, %d\n", err); | 231 | brcmf_err("retrieving revision info failed, %d\n", err); |
232 | strlcpy(ri->chipname, "UNKNOWN", sizeof(ri->chipname)); | ||
257 | } else { | 233 | } else { |
258 | ri->vendorid = le32_to_cpu(revinfo.vendorid); | 234 | ri->vendorid = le32_to_cpu(revinfo.vendorid); |
259 | ri->deviceid = le32_to_cpu(revinfo.deviceid); | 235 | ri->deviceid = le32_to_cpu(revinfo.deviceid); |
260 | ri->radiorev = le32_to_cpu(revinfo.radiorev); | 236 | ri->radiorev = le32_to_cpu(revinfo.radiorev); |
261 | ri->chiprev = le32_to_cpu(revinfo.chiprev); | ||
262 | ri->corerev = le32_to_cpu(revinfo.corerev); | 237 | ri->corerev = le32_to_cpu(revinfo.corerev); |
263 | ri->boardid = le32_to_cpu(revinfo.boardid); | 238 | ri->boardid = le32_to_cpu(revinfo.boardid); |
264 | ri->boardvendor = le32_to_cpu(revinfo.boardvendor); | 239 | ri->boardvendor = le32_to_cpu(revinfo.boardvendor); |
@@ -266,15 +241,24 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) | |||
266 | ri->driverrev = le32_to_cpu(revinfo.driverrev); | 241 | ri->driverrev = le32_to_cpu(revinfo.driverrev); |
267 | ri->ucoderev = le32_to_cpu(revinfo.ucoderev); | 242 | ri->ucoderev = le32_to_cpu(revinfo.ucoderev); |
268 | ri->bus = le32_to_cpu(revinfo.bus); | 243 | ri->bus = le32_to_cpu(revinfo.bus); |
269 | ri->chipnum = le32_to_cpu(revinfo.chipnum); | ||
270 | ri->phytype = le32_to_cpu(revinfo.phytype); | 244 | ri->phytype = le32_to_cpu(revinfo.phytype); |
271 | ri->phyrev = le32_to_cpu(revinfo.phyrev); | 245 | ri->phyrev = le32_to_cpu(revinfo.phyrev); |
272 | ri->anarev = le32_to_cpu(revinfo.anarev); | 246 | ri->anarev = le32_to_cpu(revinfo.anarev); |
273 | ri->chippkg = le32_to_cpu(revinfo.chippkg); | 247 | ri->chippkg = le32_to_cpu(revinfo.chippkg); |
274 | ri->nvramrev = le32_to_cpu(revinfo.nvramrev); | 248 | ri->nvramrev = le32_to_cpu(revinfo.nvramrev); |
249 | |||
250 | /* use revinfo if not known yet */ | ||
251 | if (!bus->chip) { | ||
252 | bus->chip = le32_to_cpu(revinfo.chipnum); | ||
253 | bus->chiprev = le32_to_cpu(revinfo.chiprev); | ||
254 | } | ||
275 | } | 255 | } |
276 | ri->result = err; | 256 | ri->result = err; |
277 | 257 | ||
258 | if (bus->chip) | ||
259 | brcmf_chip_name(bus->chip, bus->chiprev, | ||
260 | ri->chipname, sizeof(ri->chipname)); | ||
261 | |||
278 | /* Do any CLM downloading */ | 262 | /* Do any CLM downloading */ |
279 | err = brcmf_c_process_clm_blob(ifp); | 263 | err = brcmf_c_process_clm_blob(ifp); |
280 | if (err < 0) { | 264 | if (err < 0) { |
@@ -295,7 +279,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) | |||
295 | strsep(&ptr, "\n"); | 279 | strsep(&ptr, "\n"); |
296 | 280 | ||
297 | /* Print fw version info */ | 281 | /* Print fw version info */ |
298 | brcmf_info("Firmware version = %s\n", buf); | 282 | brcmf_info("Firmware: %s %s\n", ri->chipname, buf); |
299 | 283 | ||
300 | /* locate firmware version number for ethtool */ | 284 | /* locate firmware version number for ethtool */ |
301 | ptr = strrchr(buf, ' ') + 1; | 285 | ptr = strrchr(buf, ' ') + 1; |
@@ -438,6 +422,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, | |||
438 | settings->feature_disable = brcmf_feature_disable; | 422 | settings->feature_disable = brcmf_feature_disable; |
439 | settings->fcmode = brcmf_fcmode; | 423 | settings->fcmode = brcmf_fcmode; |
440 | settings->roamoff = !!brcmf_roamoff; | 424 | settings->roamoff = !!brcmf_roamoff; |
425 | settings->iapp = !!brcmf_iapp_enable; | ||
441 | #ifdef DEBUG | 426 | #ifdef DEBUG |
442 | settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; | 427 | settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; |
443 | #endif | 428 | #endif |
@@ -511,9 +496,6 @@ static int __init brcmfmac_module_init(void) | |||
511 | { | 496 | { |
512 | int err; | 497 | int err; |
513 | 498 | ||
514 | /* Initialize debug system first */ | ||
515 | brcmf_debugfs_init(); | ||
516 | |||
517 | /* Get the platform data (if available) for our devices */ | 499 | /* Get the platform data (if available) for our devices */ |
518 | err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe); | 500 | err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe); |
519 | if (err == -ENODEV) | 501 | if (err == -ENODEV) |
@@ -525,7 +507,6 @@ static int __init brcmfmac_module_init(void) | |||
525 | /* Continue the initialization by registering the different busses */ | 507 | /* Continue the initialization by registering the different busses */ |
526 | err = brcmf_core_init(); | 508 | err = brcmf_core_init(); |
527 | if (err) { | 509 | if (err) { |
528 | brcmf_debugfs_exit(); | ||
529 | if (brcmfmac_pdata) | 510 | if (brcmfmac_pdata) |
530 | platform_driver_unregister(&brcmf_pd); | 511 | platform_driver_unregister(&brcmf_pd); |
531 | } | 512 | } |
@@ -538,7 +519,6 @@ static void __exit brcmfmac_module_exit(void) | |||
538 | brcmf_core_exit(); | 519 | brcmf_core_exit(); |
539 | if (brcmfmac_pdata) | 520 | if (brcmfmac_pdata) |
540 | platform_driver_unregister(&brcmf_pd); | 521 | platform_driver_unregister(&brcmf_pd); |
541 | brcmf_debugfs_exit(); | ||
542 | } | 522 | } |
543 | 523 | ||
544 | module_init(brcmfmac_module_init); | 524 | module_init(brcmfmac_module_init); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h index a62f8e70b320..ef914619e8e1 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h | |||
@@ -58,6 +58,7 @@ struct brcmf_mp_device { | |||
58 | unsigned int feature_disable; | 58 | unsigned int feature_disable; |
59 | int fcmode; | 59 | int fcmode; |
60 | bool roamoff; | 60 | bool roamoff; |
61 | bool iapp; | ||
61 | bool ignore_probe_fail; | 62 | bool ignore_probe_fail; |
62 | struct brcmfmac_pd_cc *country_codes; | 63 | struct brcmfmac_pd_cc *country_codes; |
63 | union { | 64 | union { |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 19048526b4af..8d4511eaa9b9 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | |||
@@ -230,6 +230,37 @@ static void brcmf_netdev_set_multicast_list(struct net_device *ndev) | |||
230 | schedule_work(&ifp->multicast_work); | 230 | schedule_work(&ifp->multicast_work); |
231 | } | 231 | } |
232 | 232 | ||
233 | /** | ||
234 | * brcmf_skb_is_iapp - checks if skb is an IAPP packet | ||
235 | * | ||
236 | * @skb: skb to check | ||
237 | */ | ||
238 | static bool brcmf_skb_is_iapp(struct sk_buff *skb) | ||
239 | { | ||
240 | static const u8 iapp_l2_update_packet[6] __aligned(2) = { | ||
241 | 0x00, 0x01, 0xaf, 0x81, 0x01, 0x00, | ||
242 | }; | ||
243 | unsigned char *eth_data; | ||
244 | #if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | ||
245 | const u16 *a, *b; | ||
246 | #endif | ||
247 | |||
248 | if (skb->len - skb->mac_len != 6 || | ||
249 | !is_multicast_ether_addr(eth_hdr(skb)->h_dest)) | ||
250 | return false; | ||
251 | |||
252 | eth_data = skb_mac_header(skb) + ETH_HLEN; | ||
253 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | ||
254 | return !(((*(const u32 *)eth_data) ^ (*(const u32 *)iapp_l2_update_packet)) | | ||
255 | ((*(const u16 *)(eth_data + 4)) ^ (*(const u16 *)(iapp_l2_update_packet + 4)))); | ||
256 | #else | ||
257 | a = (const u16 *)eth_data; | ||
258 | b = (const u16 *)iapp_l2_update_packet; | ||
259 | |||
260 | return !((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])); | ||
261 | #endif | ||
262 | } | ||
263 | |||
233 | static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, | 264 | static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, |
234 | struct net_device *ndev) | 265 | struct net_device *ndev) |
235 | { | 266 | { |
@@ -250,6 +281,23 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, | |||
250 | goto done; | 281 | goto done; |
251 | } | 282 | } |
252 | 283 | ||
284 | /* Some recent Broadcom's firmwares disassociate STA when they receive | ||
285 | * an 802.11f ADD frame. This behavior can lead to a local DoS security | ||
286 | * issue. Attacker may trigger disassociation of any STA by sending a | ||
287 | * proper Ethernet frame to the wireless interface. | ||
288 | * | ||
289 | * Moreover this feature may break AP interfaces in some specific | ||
290 | * setups. This applies e.g. to the bridge with hairpin mode enabled and | ||
291 | * IFLA_BRPORT_MCAST_TO_UCAST set. IAPP packet generated by a firmware | ||
292 | * will get passed back to the wireless interface and cause immediate | ||
293 | * disassociation of a just-connected STA. | ||
294 | */ | ||
295 | if (!drvr->settings->iapp && brcmf_skb_is_iapp(skb)) { | ||
296 | dev_kfree_skb(skb); | ||
297 | ret = -EINVAL; | ||
298 | goto done; | ||
299 | } | ||
300 | |||
253 | /* Make sure there's enough writeable headroom */ | 301 | /* Make sure there's enough writeable headroom */ |
254 | if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) { | 302 | if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) { |
255 | head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0); | 303 | head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0); |
@@ -325,6 +373,15 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp, | |||
325 | 373 | ||
326 | void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) | 374 | void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) |
327 | { | 375 | { |
376 | /* Most of Broadcom's firmwares send 802.11f ADD frame every time a new | ||
377 | * STA connects to the AP interface. This is an obsoleted standard most | ||
378 | * users don't use, so don't pass these frames up unless requested. | ||
379 | */ | ||
380 | if (!ifp->drvr->settings->iapp && brcmf_skb_is_iapp(skb)) { | ||
381 | brcmu_pkt_buf_free_skb(skb); | ||
382 | return; | ||
383 | } | ||
384 | |||
328 | if (skb->pkt_type == PACKET_MULTICAST) | 385 | if (skb->pkt_type == PACKET_MULTICAST) |
329 | ifp->ndev->stats.multicast++; | 386 | ifp->ndev->stats.multicast++; |
330 | 387 | ||
@@ -924,8 +981,7 @@ static int brcmf_revinfo_read(struct seq_file *s, void *data) | |||
924 | seq_printf(s, "vendorid: 0x%04x\n", ri->vendorid); | 981 | seq_printf(s, "vendorid: 0x%04x\n", ri->vendorid); |
925 | seq_printf(s, "deviceid: 0x%04x\n", ri->deviceid); | 982 | seq_printf(s, "deviceid: 0x%04x\n", ri->deviceid); |
926 | seq_printf(s, "radiorev: %s\n", brcmu_dotrev_str(ri->radiorev, drev)); | 983 | seq_printf(s, "radiorev: %s\n", brcmu_dotrev_str(ri->radiorev, drev)); |
927 | seq_printf(s, "chipnum: %u (%x)\n", ri->chipnum, ri->chipnum); | 984 | seq_printf(s, "chip: %s\n", ri->chipname); |
928 | seq_printf(s, "chiprev: %u\n", ri->chiprev); | ||
929 | seq_printf(s, "chippkg: %u\n", ri->chippkg); | 985 | seq_printf(s, "chippkg: %u\n", ri->chippkg); |
930 | seq_printf(s, "corerev: %u\n", ri->corerev); | 986 | seq_printf(s, "corerev: %u\n", ri->corerev); |
931 | seq_printf(s, "boardid: 0x%04x\n", ri->boardid); | 987 | seq_printf(s, "boardid: 0x%04x\n", ri->boardid); |
@@ -944,7 +1000,7 @@ static int brcmf_revinfo_read(struct seq_file *s, void *data) | |||
944 | return 0; | 1000 | return 0; |
945 | } | 1001 | } |
946 | 1002 | ||
947 | static int brcmf_bus_started(struct brcmf_pub *drvr) | 1003 | static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops) |
948 | { | 1004 | { |
949 | int ret = -1; | 1005 | int ret = -1; |
950 | struct brcmf_bus *bus_if = drvr->bus_if; | 1006 | struct brcmf_bus *bus_if = drvr->bus_if; |
@@ -973,15 +1029,6 @@ static int brcmf_bus_started(struct brcmf_pub *drvr) | |||
973 | if (ret < 0) | 1029 | if (ret < 0) |
974 | goto fail; | 1030 | goto fail; |
975 | 1031 | ||
976 | brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); | ||
977 | |||
978 | /* assure we have chipid before feature attach */ | ||
979 | if (!bus_if->chip) { | ||
980 | bus_if->chip = drvr->revinfo.chipnum; | ||
981 | bus_if->chiprev = drvr->revinfo.chiprev; | ||
982 | brcmf_dbg(INFO, "firmware revinfo: chip %x (%d) rev %d\n", | ||
983 | bus_if->chip, bus_if->chip, bus_if->chiprev); | ||
984 | } | ||
985 | brcmf_feat_attach(drvr); | 1032 | brcmf_feat_attach(drvr); |
986 | 1033 | ||
987 | ret = brcmf_proto_init_done(drvr); | 1034 | ret = brcmf_proto_init_done(drvr); |
@@ -990,7 +1037,7 @@ static int brcmf_bus_started(struct brcmf_pub *drvr) | |||
990 | 1037 | ||
991 | brcmf_proto_add_if(drvr, ifp); | 1038 | brcmf_proto_add_if(drvr, ifp); |
992 | 1039 | ||
993 | drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev, | 1040 | drvr->config = brcmf_cfg80211_attach(drvr, ops, |
994 | drvr->settings->p2p_enable); | 1041 | drvr->settings->p2p_enable); |
995 | if (drvr->config == NULL) { | 1042 | if (drvr->config == NULL) { |
996 | ret = -ENOMEM; | 1043 | ret = -ENOMEM; |
@@ -1024,6 +1071,11 @@ static int brcmf_bus_started(struct brcmf_pub *drvr) | |||
1024 | #endif | 1071 | #endif |
1025 | #endif /* CONFIG_INET */ | 1072 | #endif /* CONFIG_INET */ |
1026 | 1073 | ||
1074 | /* populate debugfs */ | ||
1075 | brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); | ||
1076 | brcmf_feat_debugfs_create(drvr); | ||
1077 | brcmf_proto_debugfs_create(drvr); | ||
1078 | |||
1027 | return 0; | 1079 | return 0; |
1028 | 1080 | ||
1029 | fail: | 1081 | fail: |
@@ -1045,17 +1097,26 @@ fail: | |||
1045 | 1097 | ||
1046 | int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) | 1098 | int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) |
1047 | { | 1099 | { |
1100 | struct wiphy *wiphy; | ||
1101 | struct cfg80211_ops *ops; | ||
1048 | struct brcmf_pub *drvr = NULL; | 1102 | struct brcmf_pub *drvr = NULL; |
1049 | int ret = 0; | 1103 | int ret = 0; |
1050 | int i; | 1104 | int i; |
1051 | 1105 | ||
1052 | brcmf_dbg(TRACE, "Enter\n"); | 1106 | brcmf_dbg(TRACE, "Enter\n"); |
1053 | 1107 | ||
1054 | /* Allocate primary brcmf_info */ | 1108 | ops = brcmf_cfg80211_get_ops(); |
1055 | drvr = kzalloc(sizeof(*drvr), GFP_ATOMIC); | 1109 | if (!ops) |
1056 | if (!drvr) | 1110 | return -ENOMEM; |
1111 | |||
1112 | wiphy = wiphy_new(ops, sizeof(*drvr)); | ||
1113 | if (!wiphy) | ||
1057 | return -ENOMEM; | 1114 | return -ENOMEM; |
1058 | 1115 | ||
1116 | set_wiphy_dev(wiphy, dev); | ||
1117 | drvr = wiphy_priv(wiphy); | ||
1118 | drvr->wiphy = wiphy; | ||
1119 | |||
1059 | for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) | 1120 | for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) |
1060 | drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; | 1121 | drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; |
1061 | 1122 | ||
@@ -1067,9 +1128,6 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) | |||
1067 | drvr->bus_if->drvr = drvr; | 1128 | drvr->bus_if->drvr = drvr; |
1068 | drvr->settings = settings; | 1129 | drvr->settings = settings; |
1069 | 1130 | ||
1070 | /* attach debug facilities */ | ||
1071 | brcmf_debug_attach(drvr); | ||
1072 | |||
1073 | /* Attach and link in the protocol */ | 1131 | /* Attach and link in the protocol */ |
1074 | ret = brcmf_proto_attach(drvr); | 1132 | ret = brcmf_proto_attach(drvr); |
1075 | if (ret != 0) { | 1133 | if (ret != 0) { |
@@ -1084,15 +1142,18 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) | |||
1084 | /* attach firmware event handler */ | 1142 | /* attach firmware event handler */ |
1085 | brcmf_fweh_attach(drvr); | 1143 | brcmf_fweh_attach(drvr); |
1086 | 1144 | ||
1087 | ret = brcmf_bus_started(drvr); | 1145 | ret = brcmf_bus_started(drvr, ops); |
1088 | if (ret != 0) { | 1146 | if (ret != 0) { |
1089 | brcmf_err("dongle is not responding: err=%d\n", ret); | 1147 | brcmf_err("dongle is not responding: err=%d\n", ret); |
1090 | goto fail; | 1148 | goto fail; |
1091 | } | 1149 | } |
1150 | |||
1151 | drvr->config->ops = ops; | ||
1092 | return 0; | 1152 | return 0; |
1093 | 1153 | ||
1094 | fail: | 1154 | fail: |
1095 | brcmf_detach(dev); | 1155 | brcmf_detach(dev); |
1156 | kfree(ops); | ||
1096 | 1157 | ||
1097 | return ret; | 1158 | return ret; |
1098 | } | 1159 | } |
@@ -1150,14 +1211,14 @@ void brcmf_detach(struct device *dev) | |||
1150 | brcmf_remove_interface(drvr->iflist[i], false); | 1211 | brcmf_remove_interface(drvr->iflist[i], false); |
1151 | 1212 | ||
1152 | brcmf_cfg80211_detach(drvr->config); | 1213 | brcmf_cfg80211_detach(drvr->config); |
1214 | drvr->config = NULL; | ||
1153 | 1215 | ||
1154 | brcmf_bus_stop(drvr->bus_if); | 1216 | brcmf_bus_stop(drvr->bus_if); |
1155 | 1217 | ||
1156 | brcmf_proto_detach(drvr); | 1218 | brcmf_proto_detach(drvr); |
1157 | 1219 | ||
1158 | brcmf_debug_detach(drvr); | ||
1159 | bus_if->drvr = NULL; | 1220 | bus_if->drvr = NULL; |
1160 | kfree(drvr); | 1221 | wiphy_free(drvr->wiphy); |
1161 | } | 1222 | } |
1162 | 1223 | ||
1163 | s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len) | 1224 | s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len) |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index 232dcbb83311..401f50458686 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | |||
@@ -87,7 +87,6 @@ struct brcmf_rev_info { | |||
87 | u32 vendorid; | 87 | u32 vendorid; |
88 | u32 deviceid; | 88 | u32 deviceid; |
89 | u32 radiorev; | 89 | u32 radiorev; |
90 | u32 chiprev; | ||
91 | u32 corerev; | 90 | u32 corerev; |
92 | u32 boardid; | 91 | u32 boardid; |
93 | u32 boardvendor; | 92 | u32 boardvendor; |
@@ -95,7 +94,7 @@ struct brcmf_rev_info { | |||
95 | u32 driverrev; | 94 | u32 driverrev; |
96 | u32 ucoderev; | 95 | u32 ucoderev; |
97 | u32 bus; | 96 | u32 bus; |
98 | u32 chipnum; | 97 | char chipname[12]; |
99 | u32 phytype; | 98 | u32 phytype; |
100 | u32 phyrev; | 99 | u32 phyrev; |
101 | u32 anarev; | 100 | u32 anarev; |
@@ -108,6 +107,7 @@ struct brcmf_pub { | |||
108 | /* Linkage ponters */ | 107 | /* Linkage ponters */ |
109 | struct brcmf_bus *bus_if; | 108 | struct brcmf_bus *bus_if; |
110 | struct brcmf_proto *proto; | 109 | struct brcmf_proto *proto; |
110 | struct wiphy *wiphy; | ||
111 | struct brcmf_cfg80211_info *config; | 111 | struct brcmf_cfg80211_info *config; |
112 | 112 | ||
113 | /* Internal brcmf items */ | 113 | /* Internal brcmf items */ |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c index 2d3e5e263a32..504832084eca 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include "fweh.h" | 25 | #include "fweh.h" |
26 | #include "debug.h" | 26 | #include "debug.h" |
27 | 27 | ||
28 | static struct dentry *root_folder; | ||
29 | |||
30 | int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, | 28 | int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, |
31 | size_t len) | 29 | size_t len) |
32 | { | 30 | { |
@@ -54,44 +52,9 @@ int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, | |||
54 | return 0; | 52 | return 0; |
55 | } | 53 | } |
56 | 54 | ||
57 | void brcmf_debugfs_init(void) | ||
58 | { | ||
59 | root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
60 | if (IS_ERR(root_folder)) | ||
61 | root_folder = NULL; | ||
62 | } | ||
63 | |||
64 | void brcmf_debugfs_exit(void) | ||
65 | { | ||
66 | if (!root_folder) | ||
67 | return; | ||
68 | |||
69 | debugfs_remove_recursive(root_folder); | ||
70 | root_folder = NULL; | ||
71 | } | ||
72 | |||
73 | int brcmf_debug_attach(struct brcmf_pub *drvr) | ||
74 | { | ||
75 | struct device *dev = drvr->bus_if->dev; | ||
76 | |||
77 | if (!root_folder) | ||
78 | return -ENODEV; | ||
79 | |||
80 | drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); | ||
81 | return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); | ||
82 | } | ||
83 | |||
84 | void brcmf_debug_detach(struct brcmf_pub *drvr) | ||
85 | { | ||
86 | brcmf_fweh_unregister(drvr, BRCMF_E_PSM_WATCHDOG); | ||
87 | |||
88 | if (!IS_ERR_OR_NULL(drvr->dbgfs_dir)) | ||
89 | debugfs_remove_recursive(drvr->dbgfs_dir); | ||
90 | } | ||
91 | |||
92 | struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) | 55 | struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) |
93 | { | 56 | { |
94 | return drvr->dbgfs_dir; | 57 | return drvr->wiphy->debugfsdir; |
95 | } | 58 | } |
96 | 59 | ||
97 | int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, | 60 | int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, |
@@ -99,7 +62,8 @@ int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, | |||
99 | { | 62 | { |
100 | struct dentry *e; | 63 | struct dentry *e; |
101 | 64 | ||
65 | WARN(!drvr->wiphy->debugfsdir, "wiphy not (yet) registered\n"); | ||
102 | e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn, | 66 | e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn, |
103 | drvr->dbgfs_dir, read_fn); | 67 | drvr->wiphy->debugfsdir, read_fn); |
104 | return PTR_ERR_OR_ZERO(e); | 68 | return PTR_ERR_OR_ZERO(e); |
105 | } | 69 | } |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h index 35919d9e8e13..cfed0626bf5a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | |||
@@ -113,29 +113,12 @@ extern int brcmf_msg_level; | |||
113 | struct brcmf_bus; | 113 | struct brcmf_bus; |
114 | struct brcmf_pub; | 114 | struct brcmf_pub; |
115 | #ifdef DEBUG | 115 | #ifdef DEBUG |
116 | void brcmf_debugfs_init(void); | ||
117 | void brcmf_debugfs_exit(void); | ||
118 | int brcmf_debug_attach(struct brcmf_pub *drvr); | ||
119 | void brcmf_debug_detach(struct brcmf_pub *drvr); | ||
120 | struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); | 116 | struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); |
121 | int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, | 117 | int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, |
122 | int (*read_fn)(struct seq_file *seq, void *data)); | 118 | int (*read_fn)(struct seq_file *seq, void *data)); |
123 | int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, | 119 | int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, |
124 | size_t len); | 120 | size_t len); |
125 | #else | 121 | #else |
126 | static inline void brcmf_debugfs_init(void) | ||
127 | { | ||
128 | } | ||
129 | static inline void brcmf_debugfs_exit(void) | ||
130 | { | ||
131 | } | ||
132 | static inline int brcmf_debug_attach(struct brcmf_pub *drvr) | ||
133 | { | ||
134 | return 0; | ||
135 | } | ||
136 | static inline void brcmf_debug_detach(struct brcmf_pub *drvr) | ||
137 | { | ||
138 | } | ||
139 | static inline | 122 | static inline |
140 | int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, | 123 | int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, |
141 | int (*read_fn)(struct seq_file *seq, void *data)) | 124 | int (*read_fn)(struct seq_file *seq, void *data)) |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c index bede7b7fd996..876731c57bf5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | |||
@@ -228,7 +228,10 @@ void brcmf_feat_attach(struct brcmf_pub *drvr) | |||
228 | /* no quirks */ | 228 | /* no quirks */ |
229 | break; | 229 | break; |
230 | } | 230 | } |
231 | } | ||
231 | 232 | ||
233 | void brcmf_feat_debugfs_create(struct brcmf_pub *drvr) | ||
234 | { | ||
232 | brcmf_debugfs_add_entry(drvr, "features", brcmf_feat_debugfs_read); | 235 | brcmf_debugfs_add_entry(drvr, "features", brcmf_feat_debugfs_read); |
233 | } | 236 | } |
234 | 237 | ||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h index 1ab4f1617112..d1193825e559 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h | |||
@@ -90,6 +90,13 @@ enum brcmf_feat_quirk { | |||
90 | void brcmf_feat_attach(struct brcmf_pub *drvr); | 90 | void brcmf_feat_attach(struct brcmf_pub *drvr); |
91 | 91 | ||
92 | /** | 92 | /** |
93 | * brcmf_feat_debugfs_create() - create debugfs entries. | ||
94 | * | ||
95 | * @drvr: driver instance. | ||
96 | */ | ||
97 | void brcmf_feat_debugfs_create(struct brcmf_pub *drvr); | ||
98 | |||
99 | /** | ||
93 | * brcmf_feat_is_enabled() - query feature. | 100 | * brcmf_feat_is_enabled() - query feature. |
94 | * | 101 | * |
95 | * @ifp: interface instance. | 102 | * @ifp: interface instance. |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c index 091b52979e03..9277f4c2bfeb 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "firmware.h" | 25 | #include "firmware.h" |
26 | #include "core.h" | 26 | #include "core.h" |
27 | #include "common.h" | 27 | #include "common.h" |
28 | #include "chip.h" | ||
28 | 29 | ||
29 | #define BRCMF_FW_MAX_NVRAM_SIZE 64000 | 30 | #define BRCMF_FW_MAX_NVRAM_SIZE 64000 |
30 | #define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ | 31 | #define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ |
@@ -437,18 +438,31 @@ void brcmf_fw_nvram_free(void *nvram) | |||
437 | 438 | ||
438 | struct brcmf_fw { | 439 | struct brcmf_fw { |
439 | struct device *dev; | 440 | struct device *dev; |
440 | u16 flags; | 441 | struct brcmf_fw_request *req; |
441 | const struct firmware *code; | 442 | u32 curpos; |
442 | const char *nvram_name; | 443 | void (*done)(struct device *dev, int err, struct brcmf_fw_request *req); |
443 | u16 domain_nr; | ||
444 | u16 bus_nr; | ||
445 | void (*done)(struct device *dev, int err, const struct firmware *fw, | ||
446 | void *nvram_image, u32 nvram_len); | ||
447 | }; | 444 | }; |
448 | 445 | ||
446 | static void brcmf_fw_request_done(const struct firmware *fw, void *ctx); | ||
447 | |||
448 | static void brcmf_fw_free_request(struct brcmf_fw_request *req) | ||
449 | { | ||
450 | struct brcmf_fw_item *item; | ||
451 | int i; | ||
452 | |||
453 | for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) { | ||
454 | if (item->type == BRCMF_FW_TYPE_BINARY) | ||
455 | release_firmware(item->binary); | ||
456 | else if (item->type == BRCMF_FW_TYPE_NVRAM) | ||
457 | brcmf_fw_nvram_free(item->nv_data.data); | ||
458 | } | ||
459 | kfree(req); | ||
460 | } | ||
461 | |||
449 | static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) | 462 | static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) |
450 | { | 463 | { |
451 | struct brcmf_fw *fwctx = ctx; | 464 | struct brcmf_fw *fwctx = ctx; |
465 | struct brcmf_fw_item *cur; | ||
452 | u32 nvram_length = 0; | 466 | u32 nvram_length = 0; |
453 | void *nvram = NULL; | 467 | void *nvram = NULL; |
454 | u8 *data = NULL; | 468 | u8 *data = NULL; |
@@ -456,83 +470,150 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) | |||
456 | bool raw_nvram; | 470 | bool raw_nvram; |
457 | 471 | ||
458 | brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); | 472 | brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); |
473 | |||
474 | cur = &fwctx->req->items[fwctx->curpos]; | ||
475 | |||
459 | if (fw && fw->data) { | 476 | if (fw && fw->data) { |
460 | data = (u8 *)fw->data; | 477 | data = (u8 *)fw->data; |
461 | data_len = fw->size; | 478 | data_len = fw->size; |
462 | raw_nvram = false; | 479 | raw_nvram = false; |
463 | } else { | 480 | } else { |
464 | data = bcm47xx_nvram_get_contents(&data_len); | 481 | data = bcm47xx_nvram_get_contents(&data_len); |
465 | if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) | 482 | if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) |
466 | goto fail; | 483 | goto fail; |
467 | raw_nvram = true; | 484 | raw_nvram = true; |
468 | } | 485 | } |
469 | 486 | ||
470 | if (data) | 487 | if (data) |
471 | nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length, | 488 | nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length, |
472 | fwctx->domain_nr, fwctx->bus_nr); | 489 | fwctx->req->domain_nr, |
490 | fwctx->req->bus_nr); | ||
473 | 491 | ||
474 | if (raw_nvram) | 492 | if (raw_nvram) |
475 | bcm47xx_nvram_release_contents(data); | 493 | bcm47xx_nvram_release_contents(data); |
476 | release_firmware(fw); | 494 | release_firmware(fw); |
477 | if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) | 495 | if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) |
478 | goto fail; | 496 | goto fail; |
479 | 497 | ||
480 | fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length); | 498 | brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length); |
481 | kfree(fwctx); | 499 | cur->nv_data.data = nvram; |
500 | cur->nv_data.len = nvram_length; | ||
482 | return; | 501 | return; |
483 | 502 | ||
484 | fail: | 503 | fail: |
485 | brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); | 504 | brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); |
486 | release_firmware(fwctx->code); | 505 | fwctx->done(fwctx->dev, -ENOENT, NULL); |
487 | fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0); | 506 | brcmf_fw_free_request(fwctx->req); |
488 | kfree(fwctx); | 507 | kfree(fwctx); |
489 | } | 508 | } |
490 | 509 | ||
491 | static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx) | 510 | static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async) |
511 | { | ||
512 | struct brcmf_fw_item *cur; | ||
513 | const struct firmware *fw = NULL; | ||
514 | int ret; | ||
515 | |||
516 | cur = &fwctx->req->items[fwctx->curpos]; | ||
517 | |||
518 | brcmf_dbg(TRACE, "%srequest for %s\n", async ? "async " : "", | ||
519 | cur->path); | ||
520 | |||
521 | if (async) | ||
522 | ret = request_firmware_nowait(THIS_MODULE, true, cur->path, | ||
523 | fwctx->dev, GFP_KERNEL, fwctx, | ||
524 | brcmf_fw_request_done); | ||
525 | else | ||
526 | ret = request_firmware(&fw, cur->path, fwctx->dev); | ||
527 | |||
528 | if (ret < 0) { | ||
529 | brcmf_fw_request_done(NULL, fwctx); | ||
530 | } else if (!async && fw) { | ||
531 | brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path, | ||
532 | fw ? "" : "not "); | ||
533 | if (cur->type == BRCMF_FW_TYPE_BINARY) | ||
534 | cur->binary = fw; | ||
535 | else if (cur->type == BRCMF_FW_TYPE_NVRAM) | ||
536 | brcmf_fw_request_nvram_done(fw, fwctx); | ||
537 | else | ||
538 | release_firmware(fw); | ||
539 | |||
540 | return -EAGAIN; | ||
541 | } | ||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static void brcmf_fw_request_done(const struct firmware *fw, void *ctx) | ||
492 | { | 546 | { |
493 | struct brcmf_fw *fwctx = ctx; | 547 | struct brcmf_fw *fwctx = ctx; |
548 | struct brcmf_fw_item *cur; | ||
494 | int ret = 0; | 549 | int ret = 0; |
495 | 550 | ||
496 | brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); | 551 | cur = &fwctx->req->items[fwctx->curpos]; |
497 | if (!fw) { | 552 | |
553 | brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path, | ||
554 | fw ? "" : "not "); | ||
555 | |||
556 | if (fw) { | ||
557 | if (cur->type == BRCMF_FW_TYPE_BINARY) | ||
558 | cur->binary = fw; | ||
559 | else if (cur->type == BRCMF_FW_TYPE_NVRAM) | ||
560 | brcmf_fw_request_nvram_done(fw, fwctx); | ||
561 | else | ||
562 | release_firmware(fw); | ||
563 | } else if (cur->type == BRCMF_FW_TYPE_NVRAM) { | ||
564 | brcmf_fw_request_nvram_done(NULL, fwctx); | ||
565 | } else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) { | ||
498 | ret = -ENOENT; | 566 | ret = -ENOENT; |
499 | goto fail; | 567 | goto fail; |
500 | } | 568 | } |
501 | /* only requested code so done here */ | ||
502 | if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) | ||
503 | goto done; | ||
504 | 569 | ||
505 | fwctx->code = fw; | 570 | do { |
506 | ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name, | 571 | if (++fwctx->curpos == fwctx->req->n_items) { |
507 | fwctx->dev, GFP_KERNEL, fwctx, | 572 | ret = 0; |
508 | brcmf_fw_request_nvram_done); | 573 | goto done; |
574 | } | ||
575 | |||
576 | ret = brcmf_fw_request_next_item(fwctx, false); | ||
577 | } while (ret == -EAGAIN); | ||
509 | 578 | ||
510 | /* pass NULL to nvram callback for bcm47xx fallback */ | ||
511 | if (ret) | ||
512 | brcmf_fw_request_nvram_done(NULL, fwctx); | ||
513 | return; | 579 | return; |
514 | 580 | ||
515 | fail: | 581 | fail: |
516 | brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); | 582 | brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret, |
583 | dev_name(fwctx->dev), cur->path); | ||
584 | brcmf_fw_free_request(fwctx->req); | ||
585 | fwctx->req = NULL; | ||
517 | done: | 586 | done: |
518 | fwctx->done(fwctx->dev, ret, fw, NULL, 0); | 587 | fwctx->done(fwctx->dev, ret, fwctx->req); |
519 | kfree(fwctx); | 588 | kfree(fwctx); |
520 | } | 589 | } |
521 | 590 | ||
522 | int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, | 591 | static bool brcmf_fw_request_is_valid(struct brcmf_fw_request *req) |
523 | const char *code, const char *nvram, | 592 | { |
524 | void (*fw_cb)(struct device *dev, int err, | 593 | struct brcmf_fw_item *item; |
525 | const struct firmware *fw, | 594 | int i; |
526 | void *nvram_image, u32 nvram_len), | 595 | |
527 | u16 domain_nr, u16 bus_nr) | 596 | if (!req->n_items) |
597 | return false; | ||
598 | |||
599 | for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) { | ||
600 | if (!item->path) | ||
601 | return false; | ||
602 | } | ||
603 | return true; | ||
604 | } | ||
605 | |||
606 | int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req, | ||
607 | void (*fw_cb)(struct device *dev, int err, | ||
608 | struct brcmf_fw_request *req)) | ||
528 | { | 609 | { |
529 | struct brcmf_fw *fwctx; | 610 | struct brcmf_fw *fwctx; |
530 | 611 | ||
531 | brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); | 612 | brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); |
532 | if (!fw_cb || !code) | 613 | if (!fw_cb) |
533 | return -EINVAL; | 614 | return -EINVAL; |
534 | 615 | ||
535 | if ((flags & BRCMF_FW_REQUEST_NVRAM) && !nvram) | 616 | if (!brcmf_fw_request_is_valid(req)) |
536 | return -EINVAL; | 617 | return -EINVAL; |
537 | 618 | ||
538 | fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL); | 619 | fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL); |
@@ -540,35 +621,25 @@ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, | |||
540 | return -ENOMEM; | 621 | return -ENOMEM; |
541 | 622 | ||
542 | fwctx->dev = dev; | 623 | fwctx->dev = dev; |
543 | fwctx->flags = flags; | 624 | fwctx->req = req; |
544 | fwctx->done = fw_cb; | 625 | fwctx->done = fw_cb; |
545 | if (flags & BRCMF_FW_REQUEST_NVRAM) | ||
546 | fwctx->nvram_name = nvram; | ||
547 | fwctx->domain_nr = domain_nr; | ||
548 | fwctx->bus_nr = bus_nr; | ||
549 | |||
550 | return request_firmware_nowait(THIS_MODULE, true, code, dev, | ||
551 | GFP_KERNEL, fwctx, | ||
552 | brcmf_fw_request_code_done); | ||
553 | } | ||
554 | 626 | ||
555 | int brcmf_fw_get_firmwares(struct device *dev, u16 flags, | 627 | brcmf_fw_request_next_item(fwctx, true); |
556 | const char *code, const char *nvram, | 628 | return 0; |
557 | void (*fw_cb)(struct device *dev, int err, | ||
558 | const struct firmware *fw, | ||
559 | void *nvram_image, u32 nvram_len)) | ||
560 | { | ||
561 | return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0, | ||
562 | 0); | ||
563 | } | 629 | } |
564 | 630 | ||
565 | int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, | 631 | struct brcmf_fw_request * |
566 | struct brcmf_firmware_mapping mapping_table[], | 632 | brcmf_fw_alloc_request(u32 chip, u32 chiprev, |
567 | u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], | 633 | struct brcmf_firmware_mapping mapping_table[], |
568 | char nvram_name[BRCMF_FW_NAME_LEN]) | 634 | u32 table_size, struct brcmf_fw_name *fwnames, |
635 | u32 n_fwnames) | ||
569 | { | 636 | { |
570 | u32 i; | 637 | struct brcmf_fw_request *fwreq; |
638 | char chipname[12]; | ||
639 | const char *mp_path; | ||
640 | u32 i, j; | ||
571 | char end; | 641 | char end; |
642 | size_t reqsz; | ||
572 | 643 | ||
573 | for (i = 0; i < table_size; i++) { | 644 | for (i = 0; i < table_size; i++) { |
574 | if (mapping_table[i].chipid == chip && | 645 | if (mapping_table[i].chipid == chip && |
@@ -578,32 +649,41 @@ int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, | |||
578 | 649 | ||
579 | if (i == table_size) { | 650 | if (i == table_size) { |
580 | brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev); | 651 | brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev); |
581 | return -ENODEV; | 652 | return NULL; |
582 | } | 653 | } |
583 | 654 | ||
584 | /* check if firmware path is provided by module parameter */ | 655 | reqsz = sizeof(*fwreq) + n_fwnames * sizeof(struct brcmf_fw_item); |
585 | if (brcmf_mp_global.firmware_path[0] != '\0') { | 656 | fwreq = kzalloc(reqsz, GFP_KERNEL); |
586 | strlcpy(fw_name, brcmf_mp_global.firmware_path, | 657 | if (!fwreq) |
587 | BRCMF_FW_NAME_LEN); | 658 | return NULL; |
588 | if ((nvram_name) && (mapping_table[i].nvram)) | 659 | |
589 | strlcpy(nvram_name, brcmf_mp_global.firmware_path, | 660 | brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname)); |
661 | |||
662 | brcmf_info("using %s for chip %s\n", | ||
663 | mapping_table[i].fw_base, chipname); | ||
664 | |||
665 | mp_path = brcmf_mp_global.firmware_path; | ||
666 | end = mp_path[strlen(mp_path) - 1]; | ||
667 | fwreq->n_items = n_fwnames; | ||
668 | |||
669 | for (j = 0; j < n_fwnames; j++) { | ||
670 | fwreq->items[j].path = fwnames[j].path; | ||
671 | /* check if firmware path is provided by module parameter */ | ||
672 | if (brcmf_mp_global.firmware_path[0] != '\0') { | ||
673 | strlcpy(fwnames[j].path, mp_path, | ||
590 | BRCMF_FW_NAME_LEN); | 674 | BRCMF_FW_NAME_LEN); |
591 | 675 | ||
592 | end = brcmf_mp_global.firmware_path[ | 676 | if (end != '/') { |
593 | strlen(brcmf_mp_global.firmware_path) - 1]; | 677 | strlcat(fwnames[j].path, "/", |
594 | if (end != '/') { | 678 | BRCMF_FW_NAME_LEN); |
595 | strlcat(fw_name, "/", BRCMF_FW_NAME_LEN); | 679 | } |
596 | if ((nvram_name) && (mapping_table[i].nvram)) | ||
597 | strlcat(nvram_name, "/", BRCMF_FW_NAME_LEN); | ||
598 | } | 680 | } |
681 | strlcat(fwnames[j].path, mapping_table[i].fw_base, | ||
682 | BRCMF_FW_NAME_LEN); | ||
683 | strlcat(fwnames[j].path, fwnames[j].extension, | ||
684 | BRCMF_FW_NAME_LEN); | ||
685 | fwreq->items[j].path = fwnames[j].path; | ||
599 | } | 686 | } |
600 | strlcat(fw_name, mapping_table[i].fw, BRCMF_FW_NAME_LEN); | ||
601 | if ((nvram_name) && (mapping_table[i].nvram)) | ||
602 | strlcat(nvram_name, mapping_table[i].nvram, BRCMF_FW_NAME_LEN); | ||
603 | 687 | ||
604 | brcmf_info("using %s for chip %#08x(%d) rev %#08x\n", | 688 | return fwreq; |
605 | fw_name, chip, chip, chiprev); | ||
606 | |||
607 | return 0; | ||
608 | } | 689 | } |
609 | |||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h index 8fa4b7e1ab3d..79a21095c349 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h | |||
@@ -16,10 +16,7 @@ | |||
16 | #ifndef BRCMFMAC_FIRMWARE_H | 16 | #ifndef BRCMFMAC_FIRMWARE_H |
17 | #define BRCMFMAC_FIRMWARE_H | 17 | #define BRCMFMAC_FIRMWARE_H |
18 | 18 | ||
19 | #define BRCMF_FW_REQUEST 0x000F | 19 | #define BRCMF_FW_REQF_OPTIONAL 0x0001 |
20 | #define BRCMF_FW_REQUEST_NVRAM 0x0001 | ||
21 | #define BRCMF_FW_REQ_FLAGS 0x00F0 | ||
22 | #define BRCMF_FW_REQ_NV_OPTIONAL 0x0010 | ||
23 | 20 | ||
24 | #define BRCMF_FW_NAME_LEN 320 | 21 | #define BRCMF_FW_NAME_LEN 320 |
25 | 22 | ||
@@ -38,49 +35,62 @@ | |||
38 | struct brcmf_firmware_mapping { | 35 | struct brcmf_firmware_mapping { |
39 | u32 chipid; | 36 | u32 chipid; |
40 | u32 revmask; | 37 | u32 revmask; |
41 | const char *fw; | 38 | const char *fw_base; |
42 | const char *nvram; | ||
43 | }; | 39 | }; |
44 | 40 | ||
45 | #define BRCMF_FW_NVRAM_DEF(fw_nvram_name, fw, nvram) \ | 41 | #define BRCMF_FW_DEF(fw_name, fw_base) \ |
46 | static const char BRCM_ ## fw_nvram_name ## _FIRMWARE_NAME[] = \ | 42 | static const char BRCM_ ## fw_name ## _FIRMWARE_BASENAME[] = \ |
47 | BRCMF_FW_DEFAULT_PATH fw; \ | 43 | BRCMF_FW_DEFAULT_PATH fw_base; \ |
48 | static const char BRCM_ ## fw_nvram_name ## _NVRAM_NAME[] = \ | 44 | MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw_base ".bin") |
49 | BRCMF_FW_DEFAULT_PATH nvram; \ | ||
50 | MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw); | ||
51 | |||
52 | #define BRCMF_FW_DEF(fw_name, fw) \ | ||
53 | static const char BRCM_ ## fw_name ## _FIRMWARE_NAME[] = \ | ||
54 | BRCMF_FW_DEFAULT_PATH fw; \ | ||
55 | MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw) \ | ||
56 | |||
57 | #define BRCMF_FW_NVRAM_ENTRY(chipid, mask, name) \ | ||
58 | { chipid, mask, \ | ||
59 | BRCM_ ## name ## _FIRMWARE_NAME, BRCM_ ## name ## _NVRAM_NAME } | ||
60 | 45 | ||
61 | #define BRCMF_FW_ENTRY(chipid, mask, name) \ | 46 | #define BRCMF_FW_ENTRY(chipid, mask, name) \ |
62 | { chipid, mask, BRCM_ ## name ## _FIRMWARE_NAME, NULL } | 47 | { chipid, mask, BRCM_ ## name ## _FIRMWARE_BASENAME } |
63 | 48 | ||
64 | int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, | ||
65 | struct brcmf_firmware_mapping mapping_table[], | ||
66 | u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], | ||
67 | char nvram_name[BRCMF_FW_NAME_LEN]); | ||
68 | void brcmf_fw_nvram_free(void *nvram); | 49 | void brcmf_fw_nvram_free(void *nvram); |
50 | |||
51 | enum brcmf_fw_type { | ||
52 | BRCMF_FW_TYPE_BINARY, | ||
53 | BRCMF_FW_TYPE_NVRAM | ||
54 | }; | ||
55 | |||
56 | struct brcmf_fw_item { | ||
57 | const char *path; | ||
58 | enum brcmf_fw_type type; | ||
59 | u16 flags; | ||
60 | union { | ||
61 | const struct firmware *binary; | ||
62 | struct { | ||
63 | void *data; | ||
64 | u32 len; | ||
65 | } nv_data; | ||
66 | }; | ||
67 | }; | ||
68 | |||
69 | struct brcmf_fw_request { | ||
70 | u16 domain_nr; | ||
71 | u16 bus_nr; | ||
72 | u32 n_items; | ||
73 | struct brcmf_fw_item items[0]; | ||
74 | }; | ||
75 | |||
76 | struct brcmf_fw_name { | ||
77 | const char *extension; | ||
78 | char *path; | ||
79 | }; | ||
80 | |||
81 | struct brcmf_fw_request * | ||
82 | brcmf_fw_alloc_request(u32 chip, u32 chiprev, | ||
83 | struct brcmf_firmware_mapping mapping_table[], | ||
84 | u32 table_size, struct brcmf_fw_name *fwnames, | ||
85 | u32 n_fwnames); | ||
86 | |||
69 | /* | 87 | /* |
70 | * Request firmware(s) asynchronously. When the asynchronous request | 88 | * Request firmware(s) asynchronously. When the asynchronous request |
71 | * fails it will not use the callback, but call device_release_driver() | 89 | * fails it will not use the callback, but call device_release_driver() |
72 | * instead which will call the driver .remove() callback. | 90 | * instead which will call the driver .remove() callback. |
73 | */ | 91 | */ |
74 | int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, | 92 | int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req, |
75 | const char *code, const char *nvram, | ||
76 | void (*fw_cb)(struct device *dev, int err, | ||
77 | const struct firmware *fw, | ||
78 | void *nvram_image, u32 nvram_len), | ||
79 | u16 domain_nr, u16 bus_nr); | ||
80 | int brcmf_fw_get_firmwares(struct device *dev, u16 flags, | ||
81 | const char *code, const char *nvram, | ||
82 | void (*fw_cb)(struct device *dev, int err, | 93 | void (*fw_cb)(struct device *dev, int err, |
83 | const struct firmware *fw, | 94 | struct brcmf_fw_request *req)); |
84 | void *nvram_image, u32 nvram_len)); | ||
85 | 95 | ||
86 | #endif /* BRCMFMAC_FIRMWARE_H */ | 96 | #endif /* BRCMFMAC_FIRMWARE_H */ |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c index fc5751116d99..802d7cb73b80 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | |||
@@ -124,8 +124,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) | |||
124 | data, len, &fwerr); | 124 | data, len, &fwerr); |
125 | 125 | ||
126 | if (err) { | 126 | if (err) { |
127 | brcmf_dbg(FIL, "Failed: %s (%d)\n", | 127 | brcmf_dbg(FIL, "Failed: error=%d\n", err); |
128 | brcmf_fil_get_errstr((u32)(-err)), err); | ||
129 | } else if (fwerr < 0) { | 128 | } else if (fwerr < 0) { |
130 | brcmf_dbg(FIL, "Firmware error: %s (%d)\n", | 129 | brcmf_dbg(FIL, "Firmware error: %s (%d)\n", |
131 | brcmf_fil_get_errstr((u32)(-fwerr)), fwerr); | 130 | brcmf_fil_get_errstr((u32)(-fwerr)), fwerr); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index f59642b2c935..f3cbf78c8899 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | |||
@@ -2399,10 +2399,6 @@ struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr) | |||
2399 | brcmu_pktq_init(&fws->desc.other.psq, BRCMF_FWS_PSQ_PREC_COUNT, | 2399 | brcmu_pktq_init(&fws->desc.other.psq, BRCMF_FWS_PSQ_PREC_COUNT, |
2400 | BRCMF_FWS_PSQ_LEN); | 2400 | BRCMF_FWS_PSQ_LEN); |
2401 | 2401 | ||
2402 | /* create debugfs file for statistics */ | ||
2403 | brcmf_debugfs_add_entry(drvr, "fws_stats", | ||
2404 | brcmf_debugfs_fws_stats_read); | ||
2405 | |||
2406 | brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n", | 2402 | brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n", |
2407 | fws->fw_signals ? "enabled" : "disabled", tlv); | 2403 | fws->fw_signals ? "enabled" : "disabled", tlv); |
2408 | return fws; | 2404 | return fws; |
@@ -2429,6 +2425,13 @@ void brcmf_fws_detach(struct brcmf_fws_info *fws) | |||
2429 | kfree(fws); | 2425 | kfree(fws); |
2430 | } | 2426 | } |
2431 | 2427 | ||
2428 | void brcmf_fws_debugfs_create(struct brcmf_pub *drvr) | ||
2429 | { | ||
2430 | /* create debugfs file for statistics */ | ||
2431 | brcmf_debugfs_add_entry(drvr, "fws_stats", | ||
2432 | brcmf_debugfs_fws_stats_read); | ||
2433 | } | ||
2434 | |||
2432 | bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws) | 2435 | bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws) |
2433 | { | 2436 | { |
2434 | return !fws->avoid_queueing; | 2437 | return !fws->avoid_queueing; |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h index ba07bd972002..4e6835766d5d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); | 21 | struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); |
22 | void brcmf_fws_detach(struct brcmf_fws_info *fws); | 22 | void brcmf_fws_detach(struct brcmf_fws_info *fws); |
23 | void brcmf_fws_debugfs_create(struct brcmf_pub *drvr); | ||
23 | bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); | 24 | bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); |
24 | bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); | 25 | bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); |
25 | void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb); | 26 | void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c index e212a791a072..49d37ad96958 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | |||
@@ -1418,6 +1418,11 @@ static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data) | |||
1418 | } | 1418 | } |
1419 | #endif | 1419 | #endif |
1420 | 1420 | ||
1421 | static void brcmf_msgbuf_debugfs_create(struct brcmf_pub *drvr) | ||
1422 | { | ||
1423 | brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read); | ||
1424 | } | ||
1425 | |||
1421 | int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) | 1426 | int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) |
1422 | { | 1427 | { |
1423 | struct brcmf_bus_msgbuf *if_msgbuf; | 1428 | struct brcmf_bus_msgbuf *if_msgbuf; |
@@ -1472,6 +1477,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) | |||
1472 | drvr->proto->delete_peer = brcmf_msgbuf_delete_peer; | 1477 | drvr->proto->delete_peer = brcmf_msgbuf_delete_peer; |
1473 | drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer; | 1478 | drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer; |
1474 | drvr->proto->rxreorder = brcmf_msgbuf_rxreorder; | 1479 | drvr->proto->rxreorder = brcmf_msgbuf_rxreorder; |
1480 | drvr->proto->debugfs_create = brcmf_msgbuf_debugfs_create; | ||
1475 | drvr->proto->pd = msgbuf; | 1481 | drvr->proto->pd = msgbuf; |
1476 | 1482 | ||
1477 | init_waitqueue_head(&msgbuf->ioctl_resp_wait); | 1483 | init_waitqueue_head(&msgbuf->ioctl_resp_wait); |
@@ -1525,8 +1531,6 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) | |||
1525 | spin_lock_init(&msgbuf->flowring_work_lock); | 1531 | spin_lock_init(&msgbuf->flowring_work_lock); |
1526 | INIT_LIST_HEAD(&msgbuf->work_queue); | 1532 | INIT_LIST_HEAD(&msgbuf->work_queue); |
1527 | 1533 | ||
1528 | brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read); | ||
1529 | |||
1530 | return 0; | 1534 | return 0; |
1531 | 1535 | ||
1532 | fail: | 1536 | fail: |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index 82064e909784..bcef208a81a5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | |||
@@ -2227,7 +2227,7 @@ fail: | |||
2227 | */ | 2227 | */ |
2228 | int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) | 2228 | int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) |
2229 | { | 2229 | { |
2230 | struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); | 2230 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
2231 | struct brcmf_p2p_info *p2p = &cfg->p2p; | 2231 | struct brcmf_p2p_info *p2p = &cfg->p2p; |
2232 | struct brcmf_cfg80211_vif *vif; | 2232 | struct brcmf_cfg80211_vif *vif; |
2233 | enum nl80211_iftype iftype; | 2233 | enum nl80211_iftype iftype; |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index a7d827ce1684..091c191ce259 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | |||
@@ -46,36 +46,36 @@ enum brcmf_pcie_state { | |||
46 | BRCMFMAC_PCIE_STATE_UP | 46 | BRCMFMAC_PCIE_STATE_UP |
47 | }; | 47 | }; |
48 | 48 | ||
49 | BRCMF_FW_NVRAM_DEF(43602, "brcmfmac43602-pcie.bin", "brcmfmac43602-pcie.txt"); | 49 | BRCMF_FW_DEF(43602, "brcmfmac43602-pcie"); |
50 | BRCMF_FW_NVRAM_DEF(4350, "brcmfmac4350-pcie.bin", "brcmfmac4350-pcie.txt"); | 50 | BRCMF_FW_DEF(4350, "brcmfmac4350-pcie"); |
51 | BRCMF_FW_NVRAM_DEF(4350C, "brcmfmac4350c2-pcie.bin", "brcmfmac4350c2-pcie.txt"); | 51 | BRCMF_FW_DEF(4350C, "brcmfmac4350c2-pcie"); |
52 | BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-pcie.bin", "brcmfmac4356-pcie.txt"); | 52 | BRCMF_FW_DEF(4356, "brcmfmac4356-pcie"); |
53 | BRCMF_FW_NVRAM_DEF(43570, "brcmfmac43570-pcie.bin", "brcmfmac43570-pcie.txt"); | 53 | BRCMF_FW_DEF(43570, "brcmfmac43570-pcie"); |
54 | BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-pcie.bin", "brcmfmac4358-pcie.txt"); | 54 | BRCMF_FW_DEF(4358, "brcmfmac4358-pcie"); |
55 | BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt"); | 55 | BRCMF_FW_DEF(4359, "brcmfmac4359-pcie"); |
56 | BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt"); | 56 | BRCMF_FW_DEF(4365B, "brcmfmac4365b-pcie"); |
57 | BRCMF_FW_NVRAM_DEF(4365C, "brcmfmac4365c-pcie.bin", "brcmfmac4365c-pcie.txt"); | 57 | BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie"); |
58 | BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt"); | 58 | BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); |
59 | BRCMF_FW_NVRAM_DEF(4366C, "brcmfmac4366c-pcie.bin", "brcmfmac4366c-pcie.txt"); | 59 | BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); |
60 | BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt"); | 60 | BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); |
61 | 61 | ||
62 | static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { | 62 | static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { |
63 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), | 63 | BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), |
64 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C), | 64 | BRCMF_FW_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C), |
65 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C), | 65 | BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C), |
66 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350), | 66 | BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350), |
67 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C), | 67 | BRCMF_FW_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C), |
68 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), | 68 | BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), |
69 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570), | 69 | BRCMF_FW_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570), |
70 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570), | 70 | BRCMF_FW_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570), |
71 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570), | 71 | BRCMF_FW_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570), |
72 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358), | 72 | BRCMF_FW_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358), |
73 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), | 73 | BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), |
74 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0x0000000F, 4365B), | 74 | BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0x0000000F, 4365B), |
75 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C), | 75 | BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C), |
76 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), | 76 | BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), |
77 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), | 77 | BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), |
78 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), | 78 | BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), |
79 | }; | 79 | }; |
80 | 80 | ||
81 | #define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */ | 81 | #define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */ |
@@ -1350,23 +1350,24 @@ static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len) | |||
1350 | return 0; | 1350 | return 0; |
1351 | } | 1351 | } |
1352 | 1352 | ||
1353 | static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev, | 1353 | static |
1354 | u8 *fw_name) | 1354 | int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name) |
1355 | { | 1355 | { |
1356 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 1356 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
1357 | struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie; | 1357 | struct brcmf_fw_request *fwreq; |
1358 | struct brcmf_pciedev_info *devinfo = buspub->devinfo; | 1358 | struct brcmf_fw_name fwnames[] = { |
1359 | int ret = 0; | 1359 | { ext, fw_name }, |
1360 | 1360 | }; | |
1361 | if (devinfo->fw_name[0] != '\0') | 1361 | |
1362 | strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); | 1362 | fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev, |
1363 | else | 1363 | brcmf_pcie_fwnames, |
1364 | ret = brcmf_fw_map_chip_to_name(chip, chiprev, | 1364 | ARRAY_SIZE(brcmf_pcie_fwnames), |
1365 | brcmf_pcie_fwnames, | 1365 | fwnames, ARRAY_SIZE(fwnames)); |
1366 | ARRAY_SIZE(brcmf_pcie_fwnames), | 1366 | if (!fwreq) |
1367 | fw_name, NULL); | 1367 | return -ENOMEM; |
1368 | 1368 | ||
1369 | return ret; | 1369 | kfree(fwreq); |
1370 | return 0; | ||
1370 | } | 1371 | } |
1371 | 1372 | ||
1372 | static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { | 1373 | static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { |
@@ -1651,15 +1652,19 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { | |||
1651 | .write32 = brcmf_pcie_buscore_write32, | 1652 | .write32 = brcmf_pcie_buscore_write32, |
1652 | }; | 1653 | }; |
1653 | 1654 | ||
1655 | #define BRCMF_PCIE_FW_CODE 0 | ||
1656 | #define BRCMF_PCIE_FW_NVRAM 1 | ||
1657 | |||
1654 | static void brcmf_pcie_setup(struct device *dev, int ret, | 1658 | static void brcmf_pcie_setup(struct device *dev, int ret, |
1655 | const struct firmware *fw, | 1659 | struct brcmf_fw_request *fwreq) |
1656 | void *nvram, u32 nvram_len) | ||
1657 | { | 1660 | { |
1661 | const struct firmware *fw; | ||
1662 | void *nvram; | ||
1658 | struct brcmf_bus *bus; | 1663 | struct brcmf_bus *bus; |
1659 | struct brcmf_pciedev *pcie_bus_dev; | 1664 | struct brcmf_pciedev *pcie_bus_dev; |
1660 | struct brcmf_pciedev_info *devinfo; | 1665 | struct brcmf_pciedev_info *devinfo; |
1661 | struct brcmf_commonring **flowrings; | 1666 | struct brcmf_commonring **flowrings; |
1662 | u32 i; | 1667 | u32 i, nvram_len; |
1663 | 1668 | ||
1664 | /* check firmware loading result */ | 1669 | /* check firmware loading result */ |
1665 | if (ret) | 1670 | if (ret) |
@@ -1670,6 +1675,11 @@ static void brcmf_pcie_setup(struct device *dev, int ret, | |||
1670 | devinfo = pcie_bus_dev->devinfo; | 1675 | devinfo = pcie_bus_dev->devinfo; |
1671 | brcmf_pcie_attach(devinfo); | 1676 | brcmf_pcie_attach(devinfo); |
1672 | 1677 | ||
1678 | fw = fwreq->items[BRCMF_PCIE_FW_CODE].binary; | ||
1679 | nvram = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.data; | ||
1680 | nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len; | ||
1681 | kfree(fwreq); | ||
1682 | |||
1673 | /* Some of the firmwares have the size of the memory of the device | 1683 | /* Some of the firmwares have the size of the memory of the device |
1674 | * defined inside the firmware. This is because part of the memory in | 1684 | * defined inside the firmware. This is because part of the memory in |
1675 | * the device is shared and the devision is determined by FW. Parse | 1685 | * the device is shared and the devision is determined by FW. Parse |
@@ -1726,20 +1736,41 @@ fail: | |||
1726 | device_release_driver(dev); | 1736 | device_release_driver(dev); |
1727 | } | 1737 | } |
1728 | 1738 | ||
1739 | static struct brcmf_fw_request * | ||
1740 | brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo) | ||
1741 | { | ||
1742 | struct brcmf_fw_request *fwreq; | ||
1743 | struct brcmf_fw_name fwnames[] = { | ||
1744 | { ".bin", devinfo->fw_name }, | ||
1745 | { ".txt", devinfo->nvram_name }, | ||
1746 | }; | ||
1747 | |||
1748 | fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev, | ||
1749 | brcmf_pcie_fwnames, | ||
1750 | ARRAY_SIZE(brcmf_pcie_fwnames), | ||
1751 | fwnames, ARRAY_SIZE(fwnames)); | ||
1752 | if (!fwreq) | ||
1753 | return NULL; | ||
1754 | |||
1755 | fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; | ||
1756 | fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; | ||
1757 | fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; | ||
1758 | fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus); | ||
1759 | fwreq->bus_nr = devinfo->pdev->bus->number; | ||
1760 | |||
1761 | return fwreq; | ||
1762 | } | ||
1763 | |||
1729 | static int | 1764 | static int |
1730 | brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 1765 | brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
1731 | { | 1766 | { |
1732 | int ret; | 1767 | int ret; |
1768 | struct brcmf_fw_request *fwreq; | ||
1733 | struct brcmf_pciedev_info *devinfo; | 1769 | struct brcmf_pciedev_info *devinfo; |
1734 | struct brcmf_pciedev *pcie_bus_dev; | 1770 | struct brcmf_pciedev *pcie_bus_dev; |
1735 | struct brcmf_bus *bus; | 1771 | struct brcmf_bus *bus; |
1736 | u16 domain_nr; | ||
1737 | u16 bus_nr; | ||
1738 | 1772 | ||
1739 | domain_nr = pci_domain_nr(pdev->bus) + 1; | 1773 | brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device); |
1740 | bus_nr = pdev->bus->number; | ||
1741 | brcmf_dbg(PCIE, "Enter %x:%x (%d/%d)\n", pdev->vendor, pdev->device, | ||
1742 | domain_nr, bus_nr); | ||
1743 | 1774 | ||
1744 | ret = -ENOMEM; | 1775 | ret = -ENOMEM; |
1745 | devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); | 1776 | devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); |
@@ -1793,19 +1824,19 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1793 | bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot); | 1824 | bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot); |
1794 | dev_set_drvdata(&pdev->dev, bus); | 1825 | dev_set_drvdata(&pdev->dev, bus); |
1795 | 1826 | ||
1796 | ret = brcmf_fw_map_chip_to_name(devinfo->ci->chip, devinfo->ci->chiprev, | 1827 | fwreq = brcmf_pcie_prepare_fw_request(devinfo); |
1797 | brcmf_pcie_fwnames, | 1828 | if (!fwreq) { |
1798 | ARRAY_SIZE(brcmf_pcie_fwnames), | 1829 | ret = -ENOMEM; |
1799 | devinfo->fw_name, devinfo->nvram_name); | ||
1800 | if (ret) | ||
1801 | goto fail_bus; | 1830 | goto fail_bus; |
1831 | } | ||
1832 | |||
1833 | ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup); | ||
1834 | if (ret < 0) { | ||
1835 | kfree(fwreq); | ||
1836 | goto fail_bus; | ||
1837 | } | ||
1838 | return 0; | ||
1802 | 1839 | ||
1803 | ret = brcmf_fw_get_firmwares_pcie(bus->dev, BRCMF_FW_REQUEST_NVRAM | | ||
1804 | BRCMF_FW_REQ_NV_OPTIONAL, | ||
1805 | devinfo->fw_name, devinfo->nvram_name, | ||
1806 | brcmf_pcie_setup, domain_nr, bus_nr); | ||
1807 | if (ret == 0) | ||
1808 | return 0; | ||
1809 | fail_bus: | 1840 | fail_bus: |
1810 | kfree(bus->msgbuf); | 1841 | kfree(bus->msgbuf); |
1811 | kfree(bus); | 1842 | kfree(bus); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c index d26ff219ef66..c5ff551ec659 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c | |||
@@ -54,7 +54,8 @@ int brcmf_proto_attach(struct brcmf_pub *drvr) | |||
54 | if (!proto->tx_queue_data || (proto->hdrpull == NULL) || | 54 | if (!proto->tx_queue_data || (proto->hdrpull == NULL) || |
55 | (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) || | 55 | (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) || |
56 | (proto->configure_addr_mode == NULL) || | 56 | (proto->configure_addr_mode == NULL) || |
57 | (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL)) { | 57 | (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL) || |
58 | (proto->debugfs_create == NULL)) { | ||
58 | brcmf_err("Not all proto handlers have been installed\n"); | 59 | brcmf_err("Not all proto handlers have been installed\n"); |
59 | goto fail; | 60 | goto fail; |
60 | } | 61 | } |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h index 8a8e08f09ea0..d3c3b9a815ad 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | |||
@@ -48,6 +48,7 @@ struct brcmf_proto { | |||
48 | void (*del_if)(struct brcmf_if *ifp); | 48 | void (*del_if)(struct brcmf_if *ifp); |
49 | void (*reset_if)(struct brcmf_if *ifp); | 49 | void (*reset_if)(struct brcmf_if *ifp); |
50 | int (*init_done)(struct brcmf_pub *drvr); | 50 | int (*init_done)(struct brcmf_pub *drvr); |
51 | void (*debugfs_create)(struct brcmf_pub *drvr); | ||
51 | void *pd; | 52 | void *pd; |
52 | }; | 53 | }; |
53 | 54 | ||
@@ -156,4 +157,10 @@ brcmf_proto_init_done(struct brcmf_pub *drvr) | |||
156 | return drvr->proto->init_done(drvr); | 157 | return drvr->proto->init_done(drvr); |
157 | } | 158 | } |
158 | 159 | ||
160 | static inline void | ||
161 | brcmf_proto_debugfs_create(struct brcmf_pub *drvr) | ||
162 | { | ||
163 | drvr->proto->debugfs_create(drvr); | ||
164 | } | ||
165 | |||
159 | #endif /* BRCMFMAC_PROTO_H */ | 166 | #endif /* BRCMFMAC_PROTO_H */ |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 4a6459a429ec..1037df7297bb 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | |||
@@ -600,47 +600,44 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { | |||
600 | {4, 0x1} | 600 | {4, 0x1} |
601 | }; | 601 | }; |
602 | 602 | ||
603 | BRCMF_FW_NVRAM_DEF(43143, "brcmfmac43143-sdio.bin", "brcmfmac43143-sdio.txt"); | 603 | BRCMF_FW_DEF(43143, "brcmfmac43143-sdio"); |
604 | BRCMF_FW_NVRAM_DEF(43241B0, "brcmfmac43241b0-sdio.bin", | 604 | BRCMF_FW_DEF(43241B0, "brcmfmac43241b0-sdio"); |
605 | "brcmfmac43241b0-sdio.txt"); | 605 | BRCMF_FW_DEF(43241B4, "brcmfmac43241b4-sdio"); |
606 | BRCMF_FW_NVRAM_DEF(43241B4, "brcmfmac43241b4-sdio.bin", | 606 | BRCMF_FW_DEF(43241B5, "brcmfmac43241b5-sdio"); |
607 | "brcmfmac43241b4-sdio.txt"); | 607 | BRCMF_FW_DEF(4329, "brcmfmac4329-sdio"); |
608 | BRCMF_FW_NVRAM_DEF(43241B5, "brcmfmac43241b5-sdio.bin", | 608 | BRCMF_FW_DEF(4330, "brcmfmac4330-sdio"); |
609 | "brcmfmac43241b5-sdio.txt"); | 609 | BRCMF_FW_DEF(4334, "brcmfmac4334-sdio"); |
610 | BRCMF_FW_NVRAM_DEF(4329, "brcmfmac4329-sdio.bin", "brcmfmac4329-sdio.txt"); | 610 | BRCMF_FW_DEF(43340, "brcmfmac43340-sdio"); |
611 | BRCMF_FW_NVRAM_DEF(4330, "brcmfmac4330-sdio.bin", "brcmfmac4330-sdio.txt"); | 611 | BRCMF_FW_DEF(4335, "brcmfmac4335-sdio"); |
612 | BRCMF_FW_NVRAM_DEF(4334, "brcmfmac4334-sdio.bin", "brcmfmac4334-sdio.txt"); | 612 | BRCMF_FW_DEF(43362, "brcmfmac43362-sdio"); |
613 | BRCMF_FW_NVRAM_DEF(43340, "brcmfmac43340-sdio.bin", "brcmfmac43340-sdio.txt"); | 613 | BRCMF_FW_DEF(4339, "brcmfmac4339-sdio"); |
614 | BRCMF_FW_NVRAM_DEF(4335, "brcmfmac4335-sdio.bin", "brcmfmac4335-sdio.txt"); | 614 | BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio"); |
615 | BRCMF_FW_NVRAM_DEF(43362, "brcmfmac43362-sdio.bin", "brcmfmac43362-sdio.txt"); | ||
616 | BRCMF_FW_NVRAM_DEF(4339, "brcmfmac4339-sdio.bin", "brcmfmac4339-sdio.txt"); | ||
617 | BRCMF_FW_NVRAM_DEF(43430A0, "brcmfmac43430a0-sdio.bin", "brcmfmac43430a0-sdio.txt"); | ||
618 | /* Note the names are not postfixed with a1 for backward compatibility */ | 615 | /* Note the names are not postfixed with a1 for backward compatibility */ |
619 | BRCMF_FW_NVRAM_DEF(43430A1, "brcmfmac43430-sdio.bin", "brcmfmac43430-sdio.txt"); | 616 | BRCMF_FW_DEF(43430A1, "brcmfmac43430-sdio"); |
620 | BRCMF_FW_NVRAM_DEF(43455, "brcmfmac43455-sdio.bin", "brcmfmac43455-sdio.txt"); | 617 | BRCMF_FW_DEF(43455, "brcmfmac43455-sdio"); |
621 | BRCMF_FW_NVRAM_DEF(4354, "brcmfmac4354-sdio.bin", "brcmfmac4354-sdio.txt"); | 618 | BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); |
622 | BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-sdio.bin", "brcmfmac4356-sdio.txt"); | 619 | BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); |
623 | BRCMF_FW_NVRAM_DEF(4373, "brcmfmac4373-sdio.bin", "brcmfmac4373-sdio.txt"); | 620 | BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); |
624 | 621 | ||
625 | static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { | 622 | static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { |
626 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), | 623 | BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), |
627 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), | 624 | BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), |
628 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), | 625 | BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), |
629 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0xFFFFFFC0, 43241B5), | 626 | BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0xFFFFFFC0, 43241B5), |
630 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, 4329), | 627 | BRCMF_FW_ENTRY(BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, 4329), |
631 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), | 628 | BRCMF_FW_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), |
632 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), | 629 | BRCMF_FW_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), |
633 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), | 630 | BRCMF_FW_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), |
634 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340), | 631 | BRCMF_FW_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340), |
635 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), | 632 | BRCMF_FW_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), |
636 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), | 633 | BRCMF_FW_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), |
637 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), | 634 | BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), |
638 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0), | 635 | BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0), |
639 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFE, 43430A1), | 636 | BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFE, 43430A1), |
640 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455), | 637 | BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455), |
641 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354), | 638 | BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354), |
642 | BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), | 639 | BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), |
643 | BRCMF_FW_NVRAM_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373) | 640 | BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373) |
644 | }; | 641 | }; |
645 | 642 | ||
646 | static void pkt_align(struct sk_buff *p, int len, int align) | 643 | static void pkt_align(struct sk_buff *p, int len, int align) |
@@ -4003,22 +4000,24 @@ brcmf_sdio_watchdog(struct timer_list *t) | |||
4003 | } | 4000 | } |
4004 | } | 4001 | } |
4005 | 4002 | ||
4006 | static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev, | 4003 | static |
4007 | u8 *fw_name) | 4004 | int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name) |
4008 | { | 4005 | { |
4009 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 4006 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
4010 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | 4007 | struct brcmf_fw_request *fwreq; |
4011 | int ret = 0; | 4008 | struct brcmf_fw_name fwnames[] = { |
4012 | 4009 | { ext, fw_name }, | |
4013 | if (sdiodev->fw_name[0] != '\0') | 4010 | }; |
4014 | strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN); | 4011 | |
4015 | else | 4012 | fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev, |
4016 | ret = brcmf_fw_map_chip_to_name(chip, chiprev, | 4013 | brcmf_sdio_fwnames, |
4017 | brcmf_sdio_fwnames, | 4014 | ARRAY_SIZE(brcmf_sdio_fwnames), |
4018 | ARRAY_SIZE(brcmf_sdio_fwnames), | 4015 | fwnames, ARRAY_SIZE(fwnames)); |
4019 | fw_name, NULL); | 4016 | if (!fwreq) |
4017 | return -ENOMEM; | ||
4020 | 4018 | ||
4021 | return ret; | 4019 | kfree(fwreq); |
4020 | return 0; | ||
4022 | } | 4021 | } |
4023 | 4022 | ||
4024 | static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { | 4023 | static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { |
@@ -4034,14 +4033,19 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { | |||
4034 | .get_fwname = brcmf_sdio_get_fwname, | 4033 | .get_fwname = brcmf_sdio_get_fwname, |
4035 | }; | 4034 | }; |
4036 | 4035 | ||
4036 | #define BRCMF_SDIO_FW_CODE 0 | ||
4037 | #define BRCMF_SDIO_FW_NVRAM 1 | ||
4038 | |||
4037 | static void brcmf_sdio_firmware_callback(struct device *dev, int err, | 4039 | static void brcmf_sdio_firmware_callback(struct device *dev, int err, |
4038 | const struct firmware *code, | 4040 | struct brcmf_fw_request *fwreq) |
4039 | void *nvram, u32 nvram_len) | ||
4040 | { | 4041 | { |
4041 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 4042 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
4042 | struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio; | 4043 | struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio; |
4043 | struct brcmf_sdio *bus = sdiod->bus; | 4044 | struct brcmf_sdio *bus = sdiod->bus; |
4044 | struct brcmf_core *core = bus->sdio_core; | 4045 | struct brcmf_core *core = bus->sdio_core; |
4046 | const struct firmware *code; | ||
4047 | void *nvram; | ||
4048 | u32 nvram_len; | ||
4045 | u8 saveclk; | 4049 | u8 saveclk; |
4046 | 4050 | ||
4047 | brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); | 4051 | brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); |
@@ -4049,6 +4053,11 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, | |||
4049 | if (err) | 4053 | if (err) |
4050 | goto fail; | 4054 | goto fail; |
4051 | 4055 | ||
4056 | code = fwreq->items[BRCMF_SDIO_FW_CODE].binary; | ||
4057 | nvram = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.data; | ||
4058 | nvram_len = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.len; | ||
4059 | kfree(fwreq); | ||
4060 | |||
4052 | /* try to download image and nvram to the dongle */ | 4061 | /* try to download image and nvram to the dongle */ |
4053 | bus->alp_only = true; | 4062 | bus->alp_only = true; |
4054 | err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); | 4063 | err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); |
@@ -4148,11 +4157,34 @@ fail: | |||
4148 | device_release_driver(dev); | 4157 | device_release_driver(dev); |
4149 | } | 4158 | } |
4150 | 4159 | ||
4160 | static struct brcmf_fw_request * | ||
4161 | brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus) | ||
4162 | { | ||
4163 | struct brcmf_fw_request *fwreq; | ||
4164 | struct brcmf_fw_name fwnames[] = { | ||
4165 | { ".bin", bus->sdiodev->fw_name }, | ||
4166 | { ".txt", bus->sdiodev->nvram_name }, | ||
4167 | }; | ||
4168 | |||
4169 | fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev, | ||
4170 | brcmf_sdio_fwnames, | ||
4171 | ARRAY_SIZE(brcmf_sdio_fwnames), | ||
4172 | fwnames, ARRAY_SIZE(fwnames)); | ||
4173 | if (!fwreq) | ||
4174 | return NULL; | ||
4175 | |||
4176 | fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; | ||
4177 | fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; | ||
4178 | |||
4179 | return fwreq; | ||
4180 | } | ||
4181 | |||
4151 | struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) | 4182 | struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) |
4152 | { | 4183 | { |
4153 | int ret; | 4184 | int ret; |
4154 | struct brcmf_sdio *bus; | 4185 | struct brcmf_sdio *bus; |
4155 | struct workqueue_struct *wq; | 4186 | struct workqueue_struct *wq; |
4187 | struct brcmf_fw_request *fwreq; | ||
4156 | 4188 | ||
4157 | brcmf_dbg(TRACE, "Enter\n"); | 4189 | brcmf_dbg(TRACE, "Enter\n"); |
4158 | 4190 | ||
@@ -4235,18 +4267,17 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) | |||
4235 | 4267 | ||
4236 | brcmf_dbg(INFO, "completed!!\n"); | 4268 | brcmf_dbg(INFO, "completed!!\n"); |
4237 | 4269 | ||
4238 | ret = brcmf_fw_map_chip_to_name(bus->ci->chip, bus->ci->chiprev, | 4270 | fwreq = brcmf_sdio_prepare_fw_request(bus); |
4239 | brcmf_sdio_fwnames, | 4271 | if (!fwreq) { |
4240 | ARRAY_SIZE(brcmf_sdio_fwnames), | 4272 | ret = -ENOMEM; |
4241 | sdiodev->fw_name, sdiodev->nvram_name); | ||
4242 | if (ret) | ||
4243 | goto fail; | 4273 | goto fail; |
4274 | } | ||
4244 | 4275 | ||
4245 | ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM, | 4276 | ret = brcmf_fw_get_firmwares(sdiodev->dev, fwreq, |
4246 | sdiodev->fw_name, sdiodev->nvram_name, | ||
4247 | brcmf_sdio_firmware_callback); | 4277 | brcmf_sdio_firmware_callback); |
4248 | if (ret != 0) { | 4278 | if (ret != 0) { |
4249 | brcmf_err("async firmware request failed: %d\n", ret); | 4279 | brcmf_err("async firmware request failed: %d\n", ret); |
4280 | kfree(fwreq); | ||
4250 | goto fail; | 4281 | goto fail; |
4251 | } | 4282 | } |
4252 | 4283 | ||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 41642dda40fd..a0873adcc01c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | |||
@@ -46,11 +46,11 @@ | |||
46 | #define BRCMF_USB_CBCTL_READ 1 | 46 | #define BRCMF_USB_CBCTL_READ 1 |
47 | #define BRCMF_USB_MAX_PKT_SIZE 1600 | 47 | #define BRCMF_USB_MAX_PKT_SIZE 1600 |
48 | 48 | ||
49 | BRCMF_FW_DEF(43143, "brcmfmac43143.bin"); | 49 | BRCMF_FW_DEF(43143, "brcmfmac43143"); |
50 | BRCMF_FW_DEF(43236B, "brcmfmac43236b.bin"); | 50 | BRCMF_FW_DEF(43236B, "brcmfmac43236b"); |
51 | BRCMF_FW_DEF(43242A, "brcmfmac43242a.bin"); | 51 | BRCMF_FW_DEF(43242A, "brcmfmac43242a"); |
52 | BRCMF_FW_DEF(43569, "brcmfmac43569.bin"); | 52 | BRCMF_FW_DEF(43569, "brcmfmac43569"); |
53 | BRCMF_FW_DEF(4373, "brcmfmac4373.bin"); | 53 | BRCMF_FW_DEF(4373, "brcmfmac4373"); |
54 | 54 | ||
55 | static struct brcmf_firmware_mapping brcmf_usb_fwnames[] = { | 55 | static struct brcmf_firmware_mapping brcmf_usb_fwnames[] = { |
56 | BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), | 56 | BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), |
@@ -1128,21 +1128,24 @@ static void brcmf_usb_wowl_config(struct device *dev, bool enabled) | |||
1128 | device_set_wakeup_enable(devinfo->dev, false); | 1128 | device_set_wakeup_enable(devinfo->dev, false); |
1129 | } | 1129 | } |
1130 | 1130 | ||
1131 | static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev, | 1131 | static |
1132 | u8 *fw_name) | 1132 | int brcmf_usb_get_fwname(struct device *dev, const char *ext, u8 *fw_name) |
1133 | { | 1133 | { |
1134 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 1134 | struct brcmf_bus *bus = dev_get_drvdata(dev); |
1135 | int ret = 0; | 1135 | struct brcmf_fw_request *fwreq; |
1136 | 1136 | struct brcmf_fw_name fwnames[] = { | |
1137 | if (devinfo->fw_name[0] != '\0') | 1137 | { ext, fw_name }, |
1138 | strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); | 1138 | }; |
1139 | else | 1139 | |
1140 | ret = brcmf_fw_map_chip_to_name(chip, chiprev, | 1140 | fwreq = brcmf_fw_alloc_request(bus->chip, bus->chiprev, |
1141 | brcmf_usb_fwnames, | 1141 | brcmf_usb_fwnames, |
1142 | ARRAY_SIZE(brcmf_usb_fwnames), | 1142 | ARRAY_SIZE(brcmf_usb_fwnames), |
1143 | fw_name, NULL); | 1143 | fwnames, ARRAY_SIZE(fwnames)); |
1144 | if (!fwreq) | ||
1145 | return -ENOMEM; | ||
1144 | 1146 | ||
1145 | return ret; | 1147 | kfree(fwreq); |
1148 | return 0; | ||
1146 | } | 1149 | } |
1147 | 1150 | ||
1148 | static const struct brcmf_bus_ops brcmf_usb_bus_ops = { | 1151 | static const struct brcmf_bus_ops brcmf_usb_bus_ops = { |
@@ -1155,18 +1158,23 @@ static const struct brcmf_bus_ops brcmf_usb_bus_ops = { | |||
1155 | .get_fwname = brcmf_usb_get_fwname, | 1158 | .get_fwname = brcmf_usb_get_fwname, |
1156 | }; | 1159 | }; |
1157 | 1160 | ||
1161 | #define BRCMF_USB_FW_CODE 0 | ||
1162 | |||
1158 | static void brcmf_usb_probe_phase2(struct device *dev, int ret, | 1163 | static void brcmf_usb_probe_phase2(struct device *dev, int ret, |
1159 | const struct firmware *fw, | 1164 | struct brcmf_fw_request *fwreq) |
1160 | void *nvram, u32 nvlen) | ||
1161 | { | 1165 | { |
1162 | struct brcmf_bus *bus = dev_get_drvdata(dev); | 1166 | struct brcmf_bus *bus = dev_get_drvdata(dev); |
1163 | struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo; | 1167 | struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo; |
1168 | const struct firmware *fw; | ||
1164 | 1169 | ||
1165 | if (ret) | 1170 | if (ret) |
1166 | goto error; | 1171 | goto error; |
1167 | 1172 | ||
1168 | brcmf_dbg(USB, "Start fw downloading\n"); | 1173 | brcmf_dbg(USB, "Start fw downloading\n"); |
1169 | 1174 | ||
1175 | fw = fwreq->items[BRCMF_USB_FW_CODE].binary; | ||
1176 | kfree(fwreq); | ||
1177 | |||
1170 | ret = check_file(fw->data); | 1178 | ret = check_file(fw->data); |
1171 | if (ret < 0) { | 1179 | if (ret < 0) { |
1172 | brcmf_err("invalid firmware\n"); | 1180 | brcmf_err("invalid firmware\n"); |
@@ -1195,11 +1203,33 @@ error: | |||
1195 | device_release_driver(dev); | 1203 | device_release_driver(dev); |
1196 | } | 1204 | } |
1197 | 1205 | ||
1206 | static struct brcmf_fw_request * | ||
1207 | brcmf_usb_prepare_fw_request(struct brcmf_usbdev_info *devinfo) | ||
1208 | { | ||
1209 | struct brcmf_fw_request *fwreq; | ||
1210 | struct brcmf_fw_name fwnames[] = { | ||
1211 | { ".bin", devinfo->fw_name }, | ||
1212 | }; | ||
1213 | |||
1214 | fwreq = brcmf_fw_alloc_request(devinfo->bus_pub.devid, | ||
1215 | devinfo->bus_pub.chiprev, | ||
1216 | brcmf_usb_fwnames, | ||
1217 | ARRAY_SIZE(brcmf_usb_fwnames), | ||
1218 | fwnames, ARRAY_SIZE(fwnames)); | ||
1219 | if (!fwreq) | ||
1220 | return NULL; | ||
1221 | |||
1222 | fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; | ||
1223 | |||
1224 | return fwreq; | ||
1225 | } | ||
1226 | |||
1198 | static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) | 1227 | static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) |
1199 | { | 1228 | { |
1200 | struct brcmf_bus *bus = NULL; | 1229 | struct brcmf_bus *bus = NULL; |
1201 | struct brcmf_usbdev *bus_pub = NULL; | 1230 | struct brcmf_usbdev *bus_pub = NULL; |
1202 | struct device *dev = devinfo->dev; | 1231 | struct device *dev = devinfo->dev; |
1232 | struct brcmf_fw_request *fwreq; | ||
1203 | int ret; | 1233 | int ret; |
1204 | 1234 | ||
1205 | brcmf_dbg(USB, "Enter\n"); | 1235 | brcmf_dbg(USB, "Enter\n"); |
@@ -1243,18 +1273,17 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) | |||
1243 | bus->chip = bus_pub->devid; | 1273 | bus->chip = bus_pub->devid; |
1244 | bus->chiprev = bus_pub->chiprev; | 1274 | bus->chiprev = bus_pub->chiprev; |
1245 | 1275 | ||
1246 | ret = brcmf_fw_map_chip_to_name(bus_pub->devid, bus_pub->chiprev, | 1276 | fwreq = brcmf_usb_prepare_fw_request(devinfo); |
1247 | brcmf_usb_fwnames, | 1277 | if (!fwreq) { |
1248 | ARRAY_SIZE(brcmf_usb_fwnames), | 1278 | ret = -ENOMEM; |
1249 | devinfo->fw_name, NULL); | ||
1250 | if (ret) | ||
1251 | goto fail; | 1279 | goto fail; |
1280 | } | ||
1252 | 1281 | ||
1253 | /* request firmware here */ | 1282 | /* request firmware here */ |
1254 | ret = brcmf_fw_get_firmwares(dev, 0, devinfo->fw_name, NULL, | 1283 | ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2); |
1255 | brcmf_usb_probe_phase2); | ||
1256 | if (ret) { | 1284 | if (ret) { |
1257 | brcmf_err("firmware request failed: %d\n", ret); | 1285 | brcmf_err("firmware request failed: %d\n", ret); |
1286 | kfree(fwreq); | ||
1258 | goto fail; | 1287 | goto fail; |
1259 | } | 1288 | } |
1260 | 1289 | ||
@@ -1447,11 +1476,20 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf) | |||
1447 | { | 1476 | { |
1448 | struct usb_device *usb = interface_to_usbdev(intf); | 1477 | struct usb_device *usb = interface_to_usbdev(intf); |
1449 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); | 1478 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); |
1479 | struct brcmf_fw_request *fwreq; | ||
1480 | int ret; | ||
1450 | 1481 | ||
1451 | brcmf_dbg(USB, "Enter\n"); | 1482 | brcmf_dbg(USB, "Enter\n"); |
1452 | 1483 | ||
1453 | return brcmf_fw_get_firmwares(&usb->dev, 0, devinfo->fw_name, NULL, | 1484 | fwreq = brcmf_usb_prepare_fw_request(devinfo); |
1454 | brcmf_usb_probe_phase2); | 1485 | if (!fwreq) |
1486 | return -ENOMEM; | ||
1487 | |||
1488 | ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2); | ||
1489 | if (ret < 0) | ||
1490 | kfree(fwreq); | ||
1491 | |||
1492 | return ret; | ||
1455 | } | 1493 | } |
1456 | 1494 | ||
1457 | #define BRCMF_USB_DEVICE(dev_id) \ | 1495 | #define BRCMF_USB_DEVICE(dev_id) \ |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c index 7a1fbb2e3a71..2fe1f6863278 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c | |||
@@ -214,7 +214,7 @@ brcms_debugfs_add_entry(struct brcms_pub *drvr, const char *fn, | |||
214 | entry->read = read_fn; | 214 | entry->read = read_fn; |
215 | entry->drvr = drvr; | 215 | entry->drvr = drvr; |
216 | 216 | ||
217 | dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry, | 217 | dentry = debugfs_create_file(fn, 0444, dentry, entry, |
218 | &brcms_debugfs_def_ops); | 218 | &brcms_debugfs_def_ops); |
219 | 219 | ||
220 | return PTR_ERR_OR_ZERO(dentry); | 220 | return PTR_ERR_OR_ZERO(dentry); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c index ddfdfe177e24..ecc89e718b9c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -108,7 +108,7 @@ MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); | |||
108 | * flags are specified by the BRCM_DL_* macros in | 108 | * flags are specified by the BRCM_DL_* macros in |
109 | * drivers/net/wireless/brcm80211/include/defs.h. | 109 | * drivers/net/wireless/brcm80211/include/defs.h. |
110 | */ | 110 | */ |
111 | module_param_named(debug, brcm_msg_level, uint, S_IRUGO | S_IWUSR); | 111 | module_param_named(debug, brcm_msg_level, uint, 0644); |
112 | #endif | 112 | #endif |
113 | 113 | ||
114 | static struct ieee80211_channel brcms_2ghz_chantable[] = { | 114 | static struct ieee80211_channel brcms_2ghz_chantable[] = { |
@@ -1563,7 +1563,7 @@ void brcms_free_timer(struct brcms_timer *t) | |||
1563 | } | 1563 | } |
1564 | 1564 | ||
1565 | /* | 1565 | /* |
1566 | * precondition: perimeter lock has been acquired | 1566 | * precondition: no locking required |
1567 | */ | 1567 | */ |
1568 | int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) | 1568 | int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) |
1569 | { | 1569 | { |
@@ -1578,7 +1578,7 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) | |||
1578 | if (le32_to_cpu(hdr->idx) == idx) { | 1578 | if (le32_to_cpu(hdr->idx) == idx) { |
1579 | pdata = wl->fw.fw_bin[i]->data + | 1579 | pdata = wl->fw.fw_bin[i]->data + |
1580 | le32_to_cpu(hdr->offset); | 1580 | le32_to_cpu(hdr->offset); |
1581 | *pbuf = kmemdup(pdata, len, GFP_ATOMIC); | 1581 | *pbuf = kmemdup(pdata, len, GFP_KERNEL); |
1582 | if (*pbuf == NULL) | 1582 | if (*pbuf == NULL) |
1583 | goto fail; | 1583 | goto fail; |
1584 | 1584 | ||
diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c index 54201c02fdb8..ce0fbf83285f 100644 --- a/drivers/net/wireless/cisco/airo.c +++ b/drivers/net/wireless/cisco/airo.c | |||
@@ -4519,21 +4519,21 @@ static int setup_proc_entry( struct net_device *dev, | |||
4519 | proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid); | 4519 | proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid); |
4520 | 4520 | ||
4521 | /* Setup the StatsDelta */ | 4521 | /* Setup the StatsDelta */ |
4522 | entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm, | 4522 | entry = proc_create_data("StatsDelta", 0444 & proc_perm, |
4523 | apriv->proc_entry, &proc_statsdelta_ops, dev); | 4523 | apriv->proc_entry, &proc_statsdelta_ops, dev); |
4524 | if (!entry) | 4524 | if (!entry) |
4525 | goto fail; | 4525 | goto fail; |
4526 | proc_set_user(entry, proc_kuid, proc_kgid); | 4526 | proc_set_user(entry, proc_kuid, proc_kgid); |
4527 | 4527 | ||
4528 | /* Setup the Stats */ | 4528 | /* Setup the Stats */ |
4529 | entry = proc_create_data("Stats", S_IRUGO & proc_perm, | 4529 | entry = proc_create_data("Stats", 0444 & proc_perm, |
4530 | apriv->proc_entry, &proc_stats_ops, dev); | 4530 | apriv->proc_entry, &proc_stats_ops, dev); |
4531 | if (!entry) | 4531 | if (!entry) |
4532 | goto fail; | 4532 | goto fail; |
4533 | proc_set_user(entry, proc_kuid, proc_kgid); | 4533 | proc_set_user(entry, proc_kuid, proc_kgid); |
4534 | 4534 | ||
4535 | /* Setup the Status */ | 4535 | /* Setup the Status */ |
4536 | entry = proc_create_data("Status", S_IRUGO & proc_perm, | 4536 | entry = proc_create_data("Status", 0444 & proc_perm, |
4537 | apriv->proc_entry, &proc_status_ops, dev); | 4537 | apriv->proc_entry, &proc_status_ops, dev); |
4538 | if (!entry) | 4538 | if (!entry) |
4539 | goto fail; | 4539 | goto fail; |
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index 19c442cb93e4..236b52423506 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c | |||
@@ -3538,7 +3538,7 @@ static ssize_t show_pci(struct device *d, struct device_attribute *attr, | |||
3538 | return out - buf; | 3538 | return out - buf; |
3539 | } | 3539 | } |
3540 | 3540 | ||
3541 | static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL); | 3541 | static DEVICE_ATTR(pci, 0444, show_pci, NULL); |
3542 | 3542 | ||
3543 | static ssize_t show_cfg(struct device *d, struct device_attribute *attr, | 3543 | static ssize_t show_cfg(struct device *d, struct device_attribute *attr, |
3544 | char *buf) | 3544 | char *buf) |
@@ -3547,7 +3547,7 @@ static ssize_t show_cfg(struct device *d, struct device_attribute *attr, | |||
3547 | return sprintf(buf, "0x%08x\n", (int)p->config); | 3547 | return sprintf(buf, "0x%08x\n", (int)p->config); |
3548 | } | 3548 | } |
3549 | 3549 | ||
3550 | static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); | 3550 | static DEVICE_ATTR(cfg, 0444, show_cfg, NULL); |
3551 | 3551 | ||
3552 | static ssize_t show_status(struct device *d, struct device_attribute *attr, | 3552 | static ssize_t show_status(struct device *d, struct device_attribute *attr, |
3553 | char *buf) | 3553 | char *buf) |
@@ -3556,7 +3556,7 @@ static ssize_t show_status(struct device *d, struct device_attribute *attr, | |||
3556 | return sprintf(buf, "0x%08x\n", (int)p->status); | 3556 | return sprintf(buf, "0x%08x\n", (int)p->status); |
3557 | } | 3557 | } |
3558 | 3558 | ||
3559 | static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); | 3559 | static DEVICE_ATTR(status, 0444, show_status, NULL); |
3560 | 3560 | ||
3561 | static ssize_t show_capability(struct device *d, struct device_attribute *attr, | 3561 | static ssize_t show_capability(struct device *d, struct device_attribute *attr, |
3562 | char *buf) | 3562 | char *buf) |
@@ -3565,7 +3565,7 @@ static ssize_t show_capability(struct device *d, struct device_attribute *attr, | |||
3565 | return sprintf(buf, "0x%08x\n", (int)p->capability); | 3565 | return sprintf(buf, "0x%08x\n", (int)p->capability); |
3566 | } | 3566 | } |
3567 | 3567 | ||
3568 | static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL); | 3568 | static DEVICE_ATTR(capability, 0444, show_capability, NULL); |
3569 | 3569 | ||
3570 | #define IPW2100_REG(x) { IPW_ ##x, #x } | 3570 | #define IPW2100_REG(x) { IPW_ ##x, #x } |
3571 | static const struct { | 3571 | static const struct { |
@@ -3822,7 +3822,7 @@ static ssize_t show_registers(struct device *d, struct device_attribute *attr, | |||
3822 | return out - buf; | 3822 | return out - buf; |
3823 | } | 3823 | } |
3824 | 3824 | ||
3825 | static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL); | 3825 | static DEVICE_ATTR(registers, 0444, show_registers, NULL); |
3826 | 3826 | ||
3827 | static ssize_t show_hardware(struct device *d, struct device_attribute *attr, | 3827 | static ssize_t show_hardware(struct device *d, struct device_attribute *attr, |
3828 | char *buf) | 3828 | char *buf) |
@@ -3863,7 +3863,7 @@ static ssize_t show_hardware(struct device *d, struct device_attribute *attr, | |||
3863 | return out - buf; | 3863 | return out - buf; |
3864 | } | 3864 | } |
3865 | 3865 | ||
3866 | static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL); | 3866 | static DEVICE_ATTR(hardware, 0444, show_hardware, NULL); |
3867 | 3867 | ||
3868 | static ssize_t show_memory(struct device *d, struct device_attribute *attr, | 3868 | static ssize_t show_memory(struct device *d, struct device_attribute *attr, |
3869 | char *buf) | 3869 | char *buf) |
@@ -3957,7 +3957,7 @@ static ssize_t store_memory(struct device *d, struct device_attribute *attr, | |||
3957 | return count; | 3957 | return count; |
3958 | } | 3958 | } |
3959 | 3959 | ||
3960 | static DEVICE_ATTR(memory, S_IWUSR | S_IRUGO, show_memory, store_memory); | 3960 | static DEVICE_ATTR(memory, 0644, show_memory, store_memory); |
3961 | 3961 | ||
3962 | static ssize_t show_ordinals(struct device *d, struct device_attribute *attr, | 3962 | static ssize_t show_ordinals(struct device *d, struct device_attribute *attr, |
3963 | char *buf) | 3963 | char *buf) |
@@ -3993,7 +3993,7 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr, | |||
3993 | return len; | 3993 | return len; |
3994 | } | 3994 | } |
3995 | 3995 | ||
3996 | static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL); | 3996 | static DEVICE_ATTR(ordinals, 0444, show_ordinals, NULL); |
3997 | 3997 | ||
3998 | static ssize_t show_stats(struct device *d, struct device_attribute *attr, | 3998 | static ssize_t show_stats(struct device *d, struct device_attribute *attr, |
3999 | char *buf) | 3999 | char *buf) |
@@ -4014,7 +4014,7 @@ static ssize_t show_stats(struct device *d, struct device_attribute *attr, | |||
4014 | return out - buf; | 4014 | return out - buf; |
4015 | } | 4015 | } |
4016 | 4016 | ||
4017 | static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL); | 4017 | static DEVICE_ATTR(stats, 0444, show_stats, NULL); |
4018 | 4018 | ||
4019 | static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) | 4019 | static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) |
4020 | { | 4020 | { |
@@ -4112,7 +4112,7 @@ static ssize_t show_internals(struct device *d, struct device_attribute *attr, | |||
4112 | return len; | 4112 | return len; |
4113 | } | 4113 | } |
4114 | 4114 | ||
4115 | static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL); | 4115 | static DEVICE_ATTR(internals, 0444, show_internals, NULL); |
4116 | 4116 | ||
4117 | static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, | 4117 | static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, |
4118 | char *buf) | 4118 | char *buf) |
@@ -4157,7 +4157,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, | |||
4157 | return out - buf; | 4157 | return out - buf; |
4158 | } | 4158 | } |
4159 | 4159 | ||
4160 | static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL); | 4160 | static DEVICE_ATTR(bssinfo, 0444, show_bssinfo, NULL); |
4161 | 4161 | ||
4162 | #ifdef CONFIG_IPW2100_DEBUG | 4162 | #ifdef CONFIG_IPW2100_DEBUG |
4163 | static ssize_t debug_level_show(struct device_driver *d, char *buf) | 4163 | static ssize_t debug_level_show(struct device_driver *d, char *buf) |
@@ -4216,8 +4216,7 @@ static ssize_t store_fatal_error(struct device *d, | |||
4216 | return count; | 4216 | return count; |
4217 | } | 4217 | } |
4218 | 4218 | ||
4219 | static DEVICE_ATTR(fatal_error, S_IWUSR | S_IRUGO, show_fatal_error, | 4219 | static DEVICE_ATTR(fatal_error, 0644, show_fatal_error, store_fatal_error); |
4220 | store_fatal_error); | ||
4221 | 4220 | ||
4222 | static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, | 4221 | static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, |
4223 | char *buf) | 4222 | char *buf) |
@@ -4250,7 +4249,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, | |||
4250 | return strnlen(buf, count); | 4249 | return strnlen(buf, count); |
4251 | } | 4250 | } |
4252 | 4251 | ||
4253 | static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age); | 4252 | static DEVICE_ATTR(scan_age, 0644, show_scan_age, store_scan_age); |
4254 | 4253 | ||
4255 | static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, | 4254 | static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, |
4256 | char *buf) | 4255 | char *buf) |
@@ -4304,7 +4303,7 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, | |||
4304 | return count; | 4303 | return count; |
4305 | } | 4304 | } |
4306 | 4305 | ||
4307 | static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); | 4306 | static DEVICE_ATTR(rf_kill, 0644, show_rf_kill, store_rf_kill); |
4308 | 4307 | ||
4309 | static struct attribute *ipw2100_sysfs_entries[] = { | 4308 | static struct attribute *ipw2100_sysfs_entries[] = { |
4310 | &dev_attr_hardware.attr, | 4309 | &dev_attr_hardware.attr, |
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index 8da87496cb58..87a5e414c2f7 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c | |||
@@ -1303,7 +1303,7 @@ static ssize_t show_event_log(struct device *d, | |||
1303 | return len; | 1303 | return len; |
1304 | } | 1304 | } |
1305 | 1305 | ||
1306 | static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL); | 1306 | static DEVICE_ATTR(event_log, 0444, show_event_log, NULL); |
1307 | 1307 | ||
1308 | static ssize_t show_error(struct device *d, | 1308 | static ssize_t show_error(struct device *d, |
1309 | struct device_attribute *attr, char *buf) | 1309 | struct device_attribute *attr, char *buf) |
@@ -1351,7 +1351,7 @@ static ssize_t clear_error(struct device *d, | |||
1351 | return count; | 1351 | return count; |
1352 | } | 1352 | } |
1353 | 1353 | ||
1354 | static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error); | 1354 | static DEVICE_ATTR(error, 0644, show_error, clear_error); |
1355 | 1355 | ||
1356 | static ssize_t show_cmd_log(struct device *d, | 1356 | static ssize_t show_cmd_log(struct device *d, |
1357 | struct device_attribute *attr, char *buf) | 1357 | struct device_attribute *attr, char *buf) |
@@ -1378,7 +1378,7 @@ static ssize_t show_cmd_log(struct device *d, | |||
1378 | return len; | 1378 | return len; |
1379 | } | 1379 | } |
1380 | 1380 | ||
1381 | static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL); | 1381 | static DEVICE_ATTR(cmd_log, 0444, show_cmd_log, NULL); |
1382 | 1382 | ||
1383 | #ifdef CONFIG_IPW2200_PROMISCUOUS | 1383 | #ifdef CONFIG_IPW2200_PROMISCUOUS |
1384 | static void ipw_prom_free(struct ipw_priv *priv); | 1384 | static void ipw_prom_free(struct ipw_priv *priv); |
@@ -1443,8 +1443,7 @@ static ssize_t show_rtap_iface(struct device *d, | |||
1443 | } | 1443 | } |
1444 | } | 1444 | } |
1445 | 1445 | ||
1446 | static DEVICE_ATTR(rtap_iface, S_IWUSR | S_IRUSR, show_rtap_iface, | 1446 | static DEVICE_ATTR(rtap_iface, 0600, show_rtap_iface, store_rtap_iface); |
1447 | store_rtap_iface); | ||
1448 | 1447 | ||
1449 | static ssize_t store_rtap_filter(struct device *d, | 1448 | static ssize_t store_rtap_filter(struct device *d, |
1450 | struct device_attribute *attr, | 1449 | struct device_attribute *attr, |
@@ -1475,8 +1474,7 @@ static ssize_t show_rtap_filter(struct device *d, | |||
1475 | priv->prom_priv ? priv->prom_priv->filter : 0); | 1474 | priv->prom_priv ? priv->prom_priv->filter : 0); |
1476 | } | 1475 | } |
1477 | 1476 | ||
1478 | static DEVICE_ATTR(rtap_filter, S_IWUSR | S_IRUSR, show_rtap_filter, | 1477 | static DEVICE_ATTR(rtap_filter, 0600, show_rtap_filter, store_rtap_filter); |
1479 | store_rtap_filter); | ||
1480 | #endif | 1478 | #endif |
1481 | 1479 | ||
1482 | static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, | 1480 | static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, |
@@ -1520,7 +1518,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, | |||
1520 | return len; | 1518 | return len; |
1521 | } | 1519 | } |
1522 | 1520 | ||
1523 | static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age); | 1521 | static DEVICE_ATTR(scan_age, 0644, show_scan_age, store_scan_age); |
1524 | 1522 | ||
1525 | static ssize_t show_led(struct device *d, struct device_attribute *attr, | 1523 | static ssize_t show_led(struct device *d, struct device_attribute *attr, |
1526 | char *buf) | 1524 | char *buf) |
@@ -1553,7 +1551,7 @@ static ssize_t store_led(struct device *d, struct device_attribute *attr, | |||
1553 | return count; | 1551 | return count; |
1554 | } | 1552 | } |
1555 | 1553 | ||
1556 | static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led); | 1554 | static DEVICE_ATTR(led, 0644, show_led, store_led); |
1557 | 1555 | ||
1558 | static ssize_t show_status(struct device *d, | 1556 | static ssize_t show_status(struct device *d, |
1559 | struct device_attribute *attr, char *buf) | 1557 | struct device_attribute *attr, char *buf) |
@@ -1562,7 +1560,7 @@ static ssize_t show_status(struct device *d, | |||
1562 | return sprintf(buf, "0x%08x\n", (int)p->status); | 1560 | return sprintf(buf, "0x%08x\n", (int)p->status); |
1563 | } | 1561 | } |
1564 | 1562 | ||
1565 | static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); | 1563 | static DEVICE_ATTR(status, 0444, show_status, NULL); |
1566 | 1564 | ||
1567 | static ssize_t show_cfg(struct device *d, struct device_attribute *attr, | 1565 | static ssize_t show_cfg(struct device *d, struct device_attribute *attr, |
1568 | char *buf) | 1566 | char *buf) |
@@ -1571,7 +1569,7 @@ static ssize_t show_cfg(struct device *d, struct device_attribute *attr, | |||
1571 | return sprintf(buf, "0x%08x\n", (int)p->config); | 1569 | return sprintf(buf, "0x%08x\n", (int)p->config); |
1572 | } | 1570 | } |
1573 | 1571 | ||
1574 | static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); | 1572 | static DEVICE_ATTR(cfg, 0444, show_cfg, NULL); |
1575 | 1573 | ||
1576 | static ssize_t show_nic_type(struct device *d, | 1574 | static ssize_t show_nic_type(struct device *d, |
1577 | struct device_attribute *attr, char *buf) | 1575 | struct device_attribute *attr, char *buf) |
@@ -1580,7 +1578,7 @@ static ssize_t show_nic_type(struct device *d, | |||
1580 | return sprintf(buf, "TYPE: %d\n", priv->nic_type); | 1578 | return sprintf(buf, "TYPE: %d\n", priv->nic_type); |
1581 | } | 1579 | } |
1582 | 1580 | ||
1583 | static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); | 1581 | static DEVICE_ATTR(nic_type, 0444, show_nic_type, NULL); |
1584 | 1582 | ||
1585 | static ssize_t show_ucode_version(struct device *d, | 1583 | static ssize_t show_ucode_version(struct device *d, |
1586 | struct device_attribute *attr, char *buf) | 1584 | struct device_attribute *attr, char *buf) |
@@ -1594,7 +1592,7 @@ static ssize_t show_ucode_version(struct device *d, | |||
1594 | return sprintf(buf, "0x%08x\n", tmp); | 1592 | return sprintf(buf, "0x%08x\n", tmp); |
1595 | } | 1593 | } |
1596 | 1594 | ||
1597 | static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL); | 1595 | static DEVICE_ATTR(ucode_version, 0644, show_ucode_version, NULL); |
1598 | 1596 | ||
1599 | static ssize_t show_rtc(struct device *d, struct device_attribute *attr, | 1597 | static ssize_t show_rtc(struct device *d, struct device_attribute *attr, |
1600 | char *buf) | 1598 | char *buf) |
@@ -1608,7 +1606,7 @@ static ssize_t show_rtc(struct device *d, struct device_attribute *attr, | |||
1608 | return sprintf(buf, "0x%08x\n", tmp); | 1606 | return sprintf(buf, "0x%08x\n", tmp); |
1609 | } | 1607 | } |
1610 | 1608 | ||
1611 | static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL); | 1609 | static DEVICE_ATTR(rtc, 0644, show_rtc, NULL); |
1612 | 1610 | ||
1613 | /* | 1611 | /* |
1614 | * Add a device attribute to view/control the delay between eeprom | 1612 | * Add a device attribute to view/control the delay between eeprom |
@@ -1630,8 +1628,7 @@ static ssize_t store_eeprom_delay(struct device *d, | |||
1630 | return strnlen(buf, count); | 1628 | return strnlen(buf, count); |
1631 | } | 1629 | } |
1632 | 1630 | ||
1633 | static DEVICE_ATTR(eeprom_delay, S_IWUSR | S_IRUGO, | 1631 | static DEVICE_ATTR(eeprom_delay, 0644, show_eeprom_delay, store_eeprom_delay); |
1634 | show_eeprom_delay, store_eeprom_delay); | ||
1635 | 1632 | ||
1636 | static ssize_t show_command_event_reg(struct device *d, | 1633 | static ssize_t show_command_event_reg(struct device *d, |
1637 | struct device_attribute *attr, char *buf) | 1634 | struct device_attribute *attr, char *buf) |
@@ -1654,7 +1651,7 @@ static ssize_t store_command_event_reg(struct device *d, | |||
1654 | return strnlen(buf, count); | 1651 | return strnlen(buf, count); |
1655 | } | 1652 | } |
1656 | 1653 | ||
1657 | static DEVICE_ATTR(command_event_reg, S_IWUSR | S_IRUGO, | 1654 | static DEVICE_ATTR(command_event_reg, 0644, |
1658 | show_command_event_reg, store_command_event_reg); | 1655 | show_command_event_reg, store_command_event_reg); |
1659 | 1656 | ||
1660 | static ssize_t show_mem_gpio_reg(struct device *d, | 1657 | static ssize_t show_mem_gpio_reg(struct device *d, |
@@ -1678,8 +1675,7 @@ static ssize_t store_mem_gpio_reg(struct device *d, | |||
1678 | return strnlen(buf, count); | 1675 | return strnlen(buf, count); |
1679 | } | 1676 | } |
1680 | 1677 | ||
1681 | static DEVICE_ATTR(mem_gpio_reg, S_IWUSR | S_IRUGO, | 1678 | static DEVICE_ATTR(mem_gpio_reg, 0644, show_mem_gpio_reg, store_mem_gpio_reg); |
1682 | show_mem_gpio_reg, store_mem_gpio_reg); | ||
1683 | 1679 | ||
1684 | static ssize_t show_indirect_dword(struct device *d, | 1680 | static ssize_t show_indirect_dword(struct device *d, |
1685 | struct device_attribute *attr, char *buf) | 1681 | struct device_attribute *attr, char *buf) |
@@ -1705,7 +1701,7 @@ static ssize_t store_indirect_dword(struct device *d, | |||
1705 | return strnlen(buf, count); | 1701 | return strnlen(buf, count); |
1706 | } | 1702 | } |
1707 | 1703 | ||
1708 | static DEVICE_ATTR(indirect_dword, S_IWUSR | S_IRUGO, | 1704 | static DEVICE_ATTR(indirect_dword, 0644, |
1709 | show_indirect_dword, store_indirect_dword); | 1705 | show_indirect_dword, store_indirect_dword); |
1710 | 1706 | ||
1711 | static ssize_t show_indirect_byte(struct device *d, | 1707 | static ssize_t show_indirect_byte(struct device *d, |
@@ -1732,7 +1728,7 @@ static ssize_t store_indirect_byte(struct device *d, | |||
1732 | return strnlen(buf, count); | 1728 | return strnlen(buf, count); |
1733 | } | 1729 | } |
1734 | 1730 | ||
1735 | static DEVICE_ATTR(indirect_byte, S_IWUSR | S_IRUGO, | 1731 | static DEVICE_ATTR(indirect_byte, 0644, |
1736 | show_indirect_byte, store_indirect_byte); | 1732 | show_indirect_byte, store_indirect_byte); |
1737 | 1733 | ||
1738 | static ssize_t show_direct_dword(struct device *d, | 1734 | static ssize_t show_direct_dword(struct device *d, |
@@ -1759,8 +1755,7 @@ static ssize_t store_direct_dword(struct device *d, | |||
1759 | return strnlen(buf, count); | 1755 | return strnlen(buf, count); |
1760 | } | 1756 | } |
1761 | 1757 | ||
1762 | static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO, | 1758 | static DEVICE_ATTR(direct_dword, 0644, show_direct_dword, store_direct_dword); |
1763 | show_direct_dword, store_direct_dword); | ||
1764 | 1759 | ||
1765 | static int rf_kill_active(struct ipw_priv *priv) | 1760 | static int rf_kill_active(struct ipw_priv *priv) |
1766 | { | 1761 | { |
@@ -1831,7 +1826,7 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, | |||
1831 | return count; | 1826 | return count; |
1832 | } | 1827 | } |
1833 | 1828 | ||
1834 | static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); | 1829 | static DEVICE_ATTR(rf_kill, 0644, show_rf_kill, store_rf_kill); |
1835 | 1830 | ||
1836 | static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr, | 1831 | static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr, |
1837 | char *buf) | 1832 | char *buf) |
@@ -1884,8 +1879,7 @@ static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr, | |||
1884 | return count; | 1879 | return count; |
1885 | } | 1880 | } |
1886 | 1881 | ||
1887 | static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan, | 1882 | static DEVICE_ATTR(speed_scan, 0644, show_speed_scan, store_speed_scan); |
1888 | store_speed_scan); | ||
1889 | 1883 | ||
1890 | static ssize_t show_net_stats(struct device *d, struct device_attribute *attr, | 1884 | static ssize_t show_net_stats(struct device *d, struct device_attribute *attr, |
1891 | char *buf) | 1885 | char *buf) |
@@ -1906,8 +1900,7 @@ static ssize_t store_net_stats(struct device *d, struct device_attribute *attr, | |||
1906 | return count; | 1900 | return count; |
1907 | } | 1901 | } |
1908 | 1902 | ||
1909 | static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO, | 1903 | static DEVICE_ATTR(net_stats, 0644, show_net_stats, store_net_stats); |
1910 | show_net_stats, store_net_stats); | ||
1911 | 1904 | ||
1912 | static ssize_t show_channels(struct device *d, | 1905 | static ssize_t show_channels(struct device *d, |
1913 | struct device_attribute *attr, | 1906 | struct device_attribute *attr, |
@@ -1953,7 +1946,7 @@ static ssize_t show_channels(struct device *d, | |||
1953 | return len; | 1946 | return len; |
1954 | } | 1947 | } |
1955 | 1948 | ||
1956 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | 1949 | static DEVICE_ATTR(channels, 0400, show_channels, NULL); |
1957 | 1950 | ||
1958 | static void notify_wx_assoc_event(struct ipw_priv *priv) | 1951 | static void notify_wx_assoc_event(struct ipw_priv *priv) |
1959 | { | 1952 | { |
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_module.c b/drivers/net/wireless/intel/ipw2x00/libipw_module.c index c58c5b2dcce5..f00d45f54c76 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_module.c | |||
@@ -276,7 +276,7 @@ static int __init libipw_init(void) | |||
276 | " proc directory\n"); | 276 | " proc directory\n"); |
277 | return -EIO; | 277 | return -EIO; |
278 | } | 278 | } |
279 | e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc, | 279 | e = proc_create("debug_level", 0644, libipw_proc, |
280 | &debug_level_proc_fops); | 280 | &debug_level_proc_fops); |
281 | if (!e) { | 281 | if (!e) { |
282 | remove_proc_entry(DRV_PROCNAME, init_net.proc_net); | 282 | remove_proc_entry(DRV_PROCNAME, init_net.proc_net); |
diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c index 4b53ebf00c7f..62a9794f952b 100644 --- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c | |||
@@ -3122,7 +3122,7 @@ il3945_store_debug_level(struct device *d, struct device_attribute *attr, | |||
3122 | return strnlen(buf, count); | 3122 | return strnlen(buf, count); |
3123 | } | 3123 | } |
3124 | 3124 | ||
3125 | static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, il3945_show_debug_level, | 3125 | static DEVICE_ATTR(debug_level, 0644, il3945_show_debug_level, |
3126 | il3945_store_debug_level); | 3126 | il3945_store_debug_level); |
3127 | 3127 | ||
3128 | #endif /* CONFIG_IWLEGACY_DEBUG */ | 3128 | #endif /* CONFIG_IWLEGACY_DEBUG */ |
@@ -3139,7 +3139,7 @@ il3945_show_temperature(struct device *d, struct device_attribute *attr, | |||
3139 | return sprintf(buf, "%d\n", il3945_hw_get_temperature(il)); | 3139 | return sprintf(buf, "%d\n", il3945_hw_get_temperature(il)); |
3140 | } | 3140 | } |
3141 | 3141 | ||
3142 | static DEVICE_ATTR(temperature, S_IRUGO, il3945_show_temperature, NULL); | 3142 | static DEVICE_ATTR(temperature, 0444, il3945_show_temperature, NULL); |
3143 | 3143 | ||
3144 | static ssize_t | 3144 | static ssize_t |
3145 | il3945_show_tx_power(struct device *d, struct device_attribute *attr, char *buf) | 3145 | il3945_show_tx_power(struct device *d, struct device_attribute *attr, char *buf) |
@@ -3165,8 +3165,7 @@ il3945_store_tx_power(struct device *d, struct device_attribute *attr, | |||
3165 | return count; | 3165 | return count; |
3166 | } | 3166 | } |
3167 | 3167 | ||
3168 | static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, il3945_show_tx_power, | 3168 | static DEVICE_ATTR(tx_power, 0644, il3945_show_tx_power, il3945_store_tx_power); |
3169 | il3945_store_tx_power); | ||
3170 | 3169 | ||
3171 | static ssize_t | 3170 | static ssize_t |
3172 | il3945_show_flags(struct device *d, struct device_attribute *attr, char *buf) | 3171 | il3945_show_flags(struct device *d, struct device_attribute *attr, char *buf) |
@@ -3199,8 +3198,7 @@ il3945_store_flags(struct device *d, struct device_attribute *attr, | |||
3199 | return count; | 3198 | return count; |
3200 | } | 3199 | } |
3201 | 3200 | ||
3202 | static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, il3945_show_flags, | 3201 | static DEVICE_ATTR(flags, 0644, il3945_show_flags, il3945_store_flags); |
3203 | il3945_store_flags); | ||
3204 | 3202 | ||
3205 | static ssize_t | 3203 | static ssize_t |
3206 | il3945_show_filter_flags(struct device *d, struct device_attribute *attr, | 3204 | il3945_show_filter_flags(struct device *d, struct device_attribute *attr, |
@@ -3235,7 +3233,7 @@ il3945_store_filter_flags(struct device *d, struct device_attribute *attr, | |||
3235 | return count; | 3233 | return count; |
3236 | } | 3234 | } |
3237 | 3235 | ||
3238 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, il3945_show_filter_flags, | 3236 | static DEVICE_ATTR(filter_flags, 0644, il3945_show_filter_flags, |
3239 | il3945_store_filter_flags); | 3237 | il3945_store_filter_flags); |
3240 | 3238 | ||
3241 | static ssize_t | 3239 | static ssize_t |
@@ -3306,7 +3304,7 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr, | |||
3306 | return count; | 3304 | return count; |
3307 | } | 3305 | } |
3308 | 3306 | ||
3309 | static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, il3945_show_measurement, | 3307 | static DEVICE_ATTR(measurement, 0600, il3945_show_measurement, |
3310 | il3945_store_measurement); | 3308 | il3945_store_measurement); |
3311 | 3309 | ||
3312 | static ssize_t | 3310 | static ssize_t |
@@ -3330,7 +3328,7 @@ il3945_show_retry_rate(struct device *d, struct device_attribute *attr, | |||
3330 | return sprintf(buf, "%d", il->retry_rate); | 3328 | return sprintf(buf, "%d", il->retry_rate); |
3331 | } | 3329 | } |
3332 | 3330 | ||
3333 | static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, il3945_show_retry_rate, | 3331 | static DEVICE_ATTR(retry_rate, 0600, il3945_show_retry_rate, |
3334 | il3945_store_retry_rate); | 3332 | il3945_store_retry_rate); |
3335 | 3333 | ||
3336 | static ssize_t | 3334 | static ssize_t |
@@ -3340,7 +3338,7 @@ il3945_show_channels(struct device *d, struct device_attribute *attr, char *buf) | |||
3340 | return 0; | 3338 | return 0; |
3341 | } | 3339 | } |
3342 | 3340 | ||
3343 | static DEVICE_ATTR(channels, S_IRUSR, il3945_show_channels, NULL); | 3341 | static DEVICE_ATTR(channels, 0400, il3945_show_channels, NULL); |
3344 | 3342 | ||
3345 | static ssize_t | 3343 | static ssize_t |
3346 | il3945_show_antenna(struct device *d, struct device_attribute *attr, char *buf) | 3344 | il3945_show_antenna(struct device *d, struct device_attribute *attr, char *buf) |
@@ -3377,8 +3375,7 @@ il3945_store_antenna(struct device *d, struct device_attribute *attr, | |||
3377 | return count; | 3375 | return count; |
3378 | } | 3376 | } |
3379 | 3377 | ||
3380 | static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, il3945_show_antenna, | 3378 | static DEVICE_ATTR(antenna, 0644, il3945_show_antenna, il3945_store_antenna); |
3381 | il3945_store_antenna); | ||
3382 | 3379 | ||
3383 | static ssize_t | 3380 | static ssize_t |
3384 | il3945_show_status(struct device *d, struct device_attribute *attr, char *buf) | 3381 | il3945_show_status(struct device *d, struct device_attribute *attr, char *buf) |
@@ -3389,7 +3386,7 @@ il3945_show_status(struct device *d, struct device_attribute *attr, char *buf) | |||
3389 | return sprintf(buf, "0x%08x\n", (int)il->status); | 3386 | return sprintf(buf, "0x%08x\n", (int)il->status); |
3390 | } | 3387 | } |
3391 | 3388 | ||
3392 | static DEVICE_ATTR(status, S_IRUGO, il3945_show_status, NULL); | 3389 | static DEVICE_ATTR(status, 0444, il3945_show_status, NULL); |
3393 | 3390 | ||
3394 | static ssize_t | 3391 | static ssize_t |
3395 | il3945_dump_error_log(struct device *d, struct device_attribute *attr, | 3392 | il3945_dump_error_log(struct device *d, struct device_attribute *attr, |
@@ -3404,7 +3401,7 @@ il3945_dump_error_log(struct device *d, struct device_attribute *attr, | |||
3404 | return strnlen(buf, count); | 3401 | return strnlen(buf, count); |
3405 | } | 3402 | } |
3406 | 3403 | ||
3407 | static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, il3945_dump_error_log); | 3404 | static DEVICE_ATTR(dump_errors, 0200, NULL, il3945_dump_error_log); |
3408 | 3405 | ||
3409 | /***************************************************************************** | 3406 | /***************************************************************************** |
3410 | * | 3407 | * |
@@ -3943,18 +3940,18 @@ il3945_exit(void) | |||
3943 | 3940 | ||
3944 | MODULE_FIRMWARE(IL3945_MODULE_FIRMWARE(IL3945_UCODE_API_MAX)); | 3941 | MODULE_FIRMWARE(IL3945_MODULE_FIRMWARE(IL3945_UCODE_API_MAX)); |
3945 | 3942 | ||
3946 | module_param_named(antenna, il3945_mod_params.antenna, int, S_IRUGO); | 3943 | module_param_named(antenna, il3945_mod_params.antenna, int, 0444); |
3947 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); | 3944 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); |
3948 | module_param_named(swcrypto, il3945_mod_params.sw_crypto, int, S_IRUGO); | 3945 | module_param_named(swcrypto, il3945_mod_params.sw_crypto, int, 0444); |
3949 | MODULE_PARM_DESC(swcrypto, "using software crypto (default 1 [software])"); | 3946 | MODULE_PARM_DESC(swcrypto, "using software crypto (default 1 [software])"); |
3950 | module_param_named(disable_hw_scan, il3945_mod_params.disable_hw_scan, int, | 3947 | module_param_named(disable_hw_scan, il3945_mod_params.disable_hw_scan, int, |
3951 | S_IRUGO); | 3948 | 0444); |
3952 | MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 1)"); | 3949 | MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 1)"); |
3953 | #ifdef CONFIG_IWLEGACY_DEBUG | 3950 | #ifdef CONFIG_IWLEGACY_DEBUG |
3954 | module_param_named(debug, il_debug_level, uint, S_IRUGO | S_IWUSR); | 3951 | module_param_named(debug, il_debug_level, uint, 0644); |
3955 | MODULE_PARM_DESC(debug, "debug output mask"); | 3952 | MODULE_PARM_DESC(debug, "debug output mask"); |
3956 | #endif | 3953 | #endif |
3957 | module_param_named(fw_restart, il3945_mod_params.restart_fw, int, S_IRUGO); | 3954 | module_param_named(fw_restart, il3945_mod_params.restart_fw, int, 0444); |
3958 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); | 3955 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); |
3959 | 3956 | ||
3960 | module_exit(il3945_exit); | 3957 | module_exit(il3945_exit); |
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c index de63f2518f23..562e94870a9c 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c | |||
@@ -4591,7 +4591,7 @@ il4965_store_debug_level(struct device *d, struct device_attribute *attr, | |||
4591 | return strnlen(buf, count); | 4591 | return strnlen(buf, count); |
4592 | } | 4592 | } |
4593 | 4593 | ||
4594 | static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, il4965_show_debug_level, | 4594 | static DEVICE_ATTR(debug_level, 0644, il4965_show_debug_level, |
4595 | il4965_store_debug_level); | 4595 | il4965_store_debug_level); |
4596 | 4596 | ||
4597 | #endif /* CONFIG_IWLEGACY_DEBUG */ | 4597 | #endif /* CONFIG_IWLEGACY_DEBUG */ |
@@ -4608,7 +4608,7 @@ il4965_show_temperature(struct device *d, struct device_attribute *attr, | |||
4608 | return sprintf(buf, "%d\n", il->temperature); | 4608 | return sprintf(buf, "%d\n", il->temperature); |
4609 | } | 4609 | } |
4610 | 4610 | ||
4611 | static DEVICE_ATTR(temperature, S_IRUGO, il4965_show_temperature, NULL); | 4611 | static DEVICE_ATTR(temperature, 0444, il4965_show_temperature, NULL); |
4612 | 4612 | ||
4613 | static ssize_t | 4613 | static ssize_t |
4614 | il4965_show_tx_power(struct device *d, struct device_attribute *attr, char *buf) | 4614 | il4965_show_tx_power(struct device *d, struct device_attribute *attr, char *buf) |
@@ -4642,7 +4642,7 @@ il4965_store_tx_power(struct device *d, struct device_attribute *attr, | |||
4642 | return ret; | 4642 | return ret; |
4643 | } | 4643 | } |
4644 | 4644 | ||
4645 | static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, il4965_show_tx_power, | 4645 | static DEVICE_ATTR(tx_power, 0644, il4965_show_tx_power, |
4646 | il4965_store_tx_power); | 4646 | il4965_store_tx_power); |
4647 | 4647 | ||
4648 | static struct attribute *il_sysfs_entries[] = { | 4648 | static struct attribute *il_sysfs_entries[] = { |
@@ -6859,18 +6859,17 @@ module_exit(il4965_exit); | |||
6859 | module_init(il4965_init); | 6859 | module_init(il4965_init); |
6860 | 6860 | ||
6861 | #ifdef CONFIG_IWLEGACY_DEBUG | 6861 | #ifdef CONFIG_IWLEGACY_DEBUG |
6862 | module_param_named(debug, il_debug_level, uint, S_IRUGO | S_IWUSR); | 6862 | module_param_named(debug, il_debug_level, uint, 0644); |
6863 | MODULE_PARM_DESC(debug, "debug output mask"); | 6863 | MODULE_PARM_DESC(debug, "debug output mask"); |
6864 | #endif | 6864 | #endif |
6865 | 6865 | ||
6866 | module_param_named(swcrypto, il4965_mod_params.sw_crypto, int, S_IRUGO); | 6866 | module_param_named(swcrypto, il4965_mod_params.sw_crypto, int, 0444); |
6867 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 6867 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); |
6868 | module_param_named(queues_num, il4965_mod_params.num_of_queues, int, S_IRUGO); | 6868 | module_param_named(queues_num, il4965_mod_params.num_of_queues, int, 0444); |
6869 | MODULE_PARM_DESC(queues_num, "number of hw queues."); | 6869 | MODULE_PARM_DESC(queues_num, "number of hw queues."); |
6870 | module_param_named(11n_disable, il4965_mod_params.disable_11n, int, S_IRUGO); | 6870 | module_param_named(11n_disable, il4965_mod_params.disable_11n, int, 0444); |
6871 | MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); | 6871 | MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); |
6872 | module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K, int, | 6872 | module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K, int, 0444); |
6873 | S_IRUGO); | ||
6874 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0 [disabled])"); | 6873 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0 [disabled])"); |
6875 | module_param_named(fw_restart, il4965_mod_params.restart_fw, int, S_IRUGO); | 6874 | module_param_named(fw_restart, il4965_mod_params.restart_fw, int, 0444); |
6876 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); | 6875 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); |
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-rs.c b/drivers/net/wireless/intel/iwlegacy/4965-rs.c index 365a4187fc37..54ff83829afb 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c | |||
@@ -2768,16 +2768,16 @@ il4965_rs_add_debugfs(void *il, void *il_sta, struct dentry *dir) | |||
2768 | { | 2768 | { |
2769 | struct il_lq_sta *lq_sta = il_sta; | 2769 | struct il_lq_sta *lq_sta = il_sta; |
2770 | lq_sta->rs_sta_dbgfs_scale_table_file = | 2770 | lq_sta->rs_sta_dbgfs_scale_table_file = |
2771 | debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, | 2771 | debugfs_create_file("rate_scale_table", 0600, dir, |
2772 | lq_sta, &rs_sta_dbgfs_scale_table_ops); | 2772 | lq_sta, &rs_sta_dbgfs_scale_table_ops); |
2773 | lq_sta->rs_sta_dbgfs_stats_table_file = | 2773 | lq_sta->rs_sta_dbgfs_stats_table_file = |
2774 | debugfs_create_file("rate_stats_table", S_IRUSR, dir, lq_sta, | 2774 | debugfs_create_file("rate_stats_table", 0400, dir, lq_sta, |
2775 | &rs_sta_dbgfs_stats_table_ops); | 2775 | &rs_sta_dbgfs_stats_table_ops); |
2776 | lq_sta->rs_sta_dbgfs_rate_scale_data_file = | 2776 | lq_sta->rs_sta_dbgfs_rate_scale_data_file = |
2777 | debugfs_create_file("rate_scale_data", S_IRUSR, dir, lq_sta, | 2777 | debugfs_create_file("rate_scale_data", 0400, dir, lq_sta, |
2778 | &rs_sta_dbgfs_rate_scale_data_ops); | 2778 | &rs_sta_dbgfs_rate_scale_data_ops); |
2779 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | 2779 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = |
2780 | debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir, | 2780 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, |
2781 | &lq_sta->tx_agg_tid_en); | 2781 | &lq_sta->tx_agg_tid_en); |
2782 | 2782 | ||
2783 | } | 2783 | } |
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c index 558bb16bfd46..063e19ced7c8 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.c +++ b/drivers/net/wireless/intel/iwlegacy/common.c | |||
@@ -435,7 +435,7 @@ EXPORT_SYMBOL(il_send_cmd_pdu_async); | |||
435 | 435 | ||
436 | /* default: IL_LED_BLINK(0) using blinking idx table */ | 436 | /* default: IL_LED_BLINK(0) using blinking idx table */ |
437 | static int led_mode; | 437 | static int led_mode; |
438 | module_param(led_mode, int, S_IRUGO); | 438 | module_param(led_mode, int, 0444); |
439 | MODULE_PARM_DESC(led_mode, | 439 | MODULE_PARM_DESC(led_mode, |
440 | "0=system default, " "1=On(RF On)/Off(RF Off), 2=blinking"); | 440 | "0=system default, " "1=On(RF On)/Off(RF Off), 2=blinking"); |
441 | 441 | ||
@@ -3372,7 +3372,7 @@ MODULE_LICENSE("GPL"); | |||
3372 | * default: bt_coex_active = true (BT_COEX_ENABLE) | 3372 | * default: bt_coex_active = true (BT_COEX_ENABLE) |
3373 | */ | 3373 | */ |
3374 | static bool bt_coex_active = true; | 3374 | static bool bt_coex_active = true; |
3375 | module_param(bt_coex_active, bool, S_IRUGO); | 3375 | module_param(bt_coex_active, bool, 0444); |
3376 | MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); | 3376 | MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); |
3377 | 3377 | ||
3378 | u32 il_debug_level; | 3378 | u32 il_debug_level; |
diff --git a/drivers/net/wireless/intel/iwlegacy/debug.c b/drivers/net/wireless/intel/iwlegacy/debug.c index 6fc6b7ff9849..d76073def677 100644 --- a/drivers/net/wireless/intel/iwlegacy/debug.c +++ b/drivers/net/wireless/intel/iwlegacy/debug.c | |||
@@ -135,16 +135,14 @@ EXPORT_SYMBOL(il_update_stats); | |||
135 | 135 | ||
136 | #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ | 136 | #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ |
137 | struct dentry *__tmp; \ | 137 | struct dentry *__tmp; \ |
138 | __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ | 138 | __tmp = debugfs_create_bool(#name, 0600, parent, ptr); \ |
139 | parent, ptr); \ | ||
140 | if (IS_ERR(__tmp) || !__tmp) \ | 139 | if (IS_ERR(__tmp) || !__tmp) \ |
141 | goto err; \ | 140 | goto err; \ |
142 | } while (0) | 141 | } while (0) |
143 | 142 | ||
144 | #define DEBUGFS_ADD_X32(name, parent, ptr) do { \ | 143 | #define DEBUGFS_ADD_X32(name, parent, ptr) do { \ |
145 | struct dentry *__tmp; \ | 144 | struct dentry *__tmp; \ |
146 | __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \ | 145 | __tmp = debugfs_create_x32(#name, 0600, parent, ptr); \ |
147 | parent, ptr); \ | ||
148 | if (IS_ERR(__tmp) || !__tmp) \ | 146 | if (IS_ERR(__tmp) || !__tmp) \ |
149 | goto err; \ | 147 | goto err; \ |
150 | } while (0) | 148 | } while (0) |
@@ -1365,35 +1363,35 @@ il_dbgfs_register(struct il_priv *il, const char *name) | |||
1365 | if (!dir_debug) | 1363 | if (!dir_debug) |
1366 | goto err; | 1364 | goto err; |
1367 | 1365 | ||
1368 | DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); | 1366 | DEBUGFS_ADD_FILE(nvm, dir_data, 0400); |
1369 | DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); | 1367 | DEBUGFS_ADD_FILE(sram, dir_data, 0600); |
1370 | DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); | 1368 | DEBUGFS_ADD_FILE(stations, dir_data, 0400); |
1371 | DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); | 1369 | DEBUGFS_ADD_FILE(channels, dir_data, 0400); |
1372 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); | 1370 | DEBUGFS_ADD_FILE(status, dir_data, 0400); |
1373 | DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); | 1371 | DEBUGFS_ADD_FILE(interrupt, dir_data, 0600); |
1374 | DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); | 1372 | DEBUGFS_ADD_FILE(qos, dir_data, 0400); |
1375 | DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); | 1373 | DEBUGFS_ADD_FILE(disable_ht40, dir_data, 0600); |
1376 | DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR); | 1374 | DEBUGFS_ADD_FILE(rx_stats, dir_debug, 0400); |
1377 | DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR); | 1375 | DEBUGFS_ADD_FILE(tx_stats, dir_debug, 0400); |
1378 | DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR); | 1376 | DEBUGFS_ADD_FILE(rx_queue, dir_debug, 0400); |
1379 | DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR); | 1377 | DEBUGFS_ADD_FILE(tx_queue, dir_debug, 0400); |
1380 | DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); | 1378 | DEBUGFS_ADD_FILE(power_save_status, dir_debug, 0400); |
1381 | DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, S_IWUSR); | 1379 | DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, 0200); |
1382 | DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, S_IWUSR); | 1380 | DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, 0200); |
1383 | DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); | 1381 | DEBUGFS_ADD_FILE(fh_reg, dir_debug, 0400); |
1384 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); | 1382 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, 0200); |
1385 | DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); | 1383 | DEBUGFS_ADD_FILE(force_reset, dir_debug, 0600); |
1386 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); | 1384 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, 0400); |
1387 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); | 1385 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, 0400); |
1388 | DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); | 1386 | DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, 0400); |
1389 | 1387 | ||
1390 | if (il->cfg->sensitivity_calib_by_driver) | 1388 | if (il->cfg->sensitivity_calib_by_driver) |
1391 | DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); | 1389 | DEBUGFS_ADD_FILE(sensitivity, dir_debug, 0400); |
1392 | if (il->cfg->chain_noise_calib_by_driver) | 1390 | if (il->cfg->chain_noise_calib_by_driver) |
1393 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); | 1391 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, 0400); |
1394 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); | 1392 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, 0200); |
1395 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); | 1393 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, 0200); |
1396 | DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); | 1394 | DEBUGFS_ADD_FILE(wd_timeout, dir_debug, 0200); |
1397 | if (il->cfg->sensitivity_calib_by_driver) | 1395 | if (il->cfg->sensitivity_calib_by_driver) |
1398 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, | 1396 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, |
1399 | &il->disable_sens_cal); | 1397 | &il->disable_sens_cal); |
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 48f6f80eb24b..dffd9df782b0 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2015-2017 Intel Deutschland GmbH | 8 | * Copyright(c) 2015-2017 Intel Deutschland GmbH |
9 | * Copyright (C) 2018 Intel Corporation | ||
9 | * | 10 | * |
10 | * 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 |
11 | * 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 |
@@ -19,6 +20,7 @@ | |||
19 | * BSD LICENSE | 20 | * BSD LICENSE |
20 | * | 21 | * |
21 | * Copyright(c) 2015-2017 Intel Deutschland GmbH | 22 | * Copyright(c) 2015-2017 Intel Deutschland GmbH |
23 | * Copyright (C) 2018 Intel Corporation | ||
22 | * All rights reserved. | 24 | * All rights reserved. |
23 | * | 25 | * |
24 | * Redistribution and use in source and binary forms, with or without | 26 | * Redistribution and use in source and binary forms, with or without |
@@ -55,7 +57,7 @@ | |||
55 | #include "iwl-agn-hw.h" | 57 | #include "iwl-agn-hw.h" |
56 | 58 | ||
57 | /* Highest firmware API version supported */ | 59 | /* Highest firmware API version supported */ |
58 | #define IWL_22000_UCODE_API_MAX 36 | 60 | #define IWL_22000_UCODE_API_MAX 38 |
59 | 61 | ||
60 | /* Lowest firmware API version supported */ | 62 | /* Lowest firmware API version supported */ |
61 | #define IWL_22000_UCODE_API_MIN 24 | 63 | #define IWL_22000_UCODE_API_MIN 24 |
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index 90a1d14cf7d2..e1c869a1f8cc 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2015-2017 Intel Deutschland GmbH | 8 | * Copyright(c) 2015-2017 Intel Deutschland GmbH |
9 | * Copyright (C) 2018 Intel Corporation | ||
9 | * | 10 | * |
10 | * 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 |
11 | * 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 |
@@ -19,6 +20,7 @@ | |||
19 | * BSD LICENSE | 20 | * BSD LICENSE |
20 | * | 21 | * |
21 | * Copyright(c) 2015-2017 Intel Deutschland GmbH | 22 | * Copyright(c) 2015-2017 Intel Deutschland GmbH |
23 | * Copyright (C) 2018 Intel Corporation | ||
22 | * All rights reserved. | 24 | * All rights reserved. |
23 | * | 25 | * |
24 | * Redistribution and use in source and binary forms, with or without | 26 | * Redistribution and use in source and binary forms, with or without |
@@ -53,9 +55,10 @@ | |||
53 | #include <linux/stringify.h> | 55 | #include <linux/stringify.h> |
54 | #include "iwl-config.h" | 56 | #include "iwl-config.h" |
55 | #include "iwl-agn-hw.h" | 57 | #include "iwl-agn-hw.h" |
58 | #include "fw/file.h" | ||
56 | 59 | ||
57 | /* Highest firmware API version supported */ | 60 | /* Highest firmware API version supported */ |
58 | #define IWL9000_UCODE_API_MAX 36 | 61 | #define IWL9000_UCODE_API_MAX 38 |
59 | 62 | ||
60 | /* Lowest firmware API version supported */ | 63 | /* Lowest firmware API version supported */ |
61 | #define IWL9000_UCODE_API_MIN 30 | 64 | #define IWL9000_UCODE_API_MIN 30 |
@@ -265,6 +268,67 @@ const struct iwl_cfg iwl9560_2ac_cfg_soc = { | |||
265 | .integrated = true, | 268 | .integrated = true, |
266 | .soc_latency = 5000, | 269 | .soc_latency = 5000, |
267 | }; | 270 | }; |
271 | |||
272 | const struct iwl_cfg iwl9460_2ac_cfg_shared_clk = { | ||
273 | .name = "Intel(R) Dual Band Wireless AC 9460", | ||
274 | .fw_name_pre = IWL9000A_FW_PRE, | ||
275 | .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE, | ||
276 | .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE, | ||
277 | IWL_DEVICE_9000, | ||
278 | .ht_params = &iwl9000_ht_params, | ||
279 | .nvm_ver = IWL9000_NVM_VERSION, | ||
280 | .nvm_calib_ver = IWL9000_TX_POWER_VERSION, | ||
281 | .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, | ||
282 | .integrated = true, | ||
283 | .soc_latency = 5000, | ||
284 | .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK | ||
285 | }; | ||
286 | |||
287 | const struct iwl_cfg iwl9461_2ac_cfg_shared_clk = { | ||
288 | .name = "Intel(R) Dual Band Wireless AC 9461", | ||
289 | .fw_name_pre = IWL9000A_FW_PRE, | ||
290 | .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE, | ||
291 | .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE, | ||
292 | IWL_DEVICE_9000, | ||
293 | .ht_params = &iwl9000_ht_params, | ||
294 | .nvm_ver = IWL9000_NVM_VERSION, | ||
295 | .nvm_calib_ver = IWL9000_TX_POWER_VERSION, | ||
296 | .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, | ||
297 | .integrated = true, | ||
298 | .soc_latency = 5000, | ||
299 | .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK | ||
300 | }; | ||
301 | |||
302 | const struct iwl_cfg iwl9462_2ac_cfg_shared_clk = { | ||
303 | .name = "Intel(R) Dual Band Wireless AC 9462", | ||
304 | .fw_name_pre = IWL9000A_FW_PRE, | ||
305 | .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE, | ||
306 | .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE, | ||
307 | IWL_DEVICE_9000, | ||
308 | .ht_params = &iwl9000_ht_params, | ||
309 | .nvm_ver = IWL9000_NVM_VERSION, | ||
310 | .nvm_calib_ver = IWL9000_TX_POWER_VERSION, | ||
311 | .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, | ||
312 | .integrated = true, | ||
313 | .soc_latency = 5000, | ||
314 | .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK | ||
315 | }; | ||
316 | |||
317 | const struct iwl_cfg iwl9560_2ac_cfg_shared_clk = { | ||
318 | .name = "Intel(R) Dual Band Wireless AC 9560", | ||
319 | .fw_name_pre = IWL9000A_FW_PRE, | ||
320 | .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE, | ||
321 | .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE, | ||
322 | IWL_DEVICE_9000, | ||
323 | .ht_params = &iwl9000_ht_params, | ||
324 | .nvm_ver = IWL9000_NVM_VERSION, | ||
325 | .nvm_calib_ver = IWL9000_TX_POWER_VERSION, | ||
326 | .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, | ||
327 | .integrated = true, | ||
328 | .soc_latency = 5000, | ||
329 | .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK | ||
330 | }; | ||
331 | |||
268 | MODULE_FIRMWARE(IWL9000A_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); | 332 | MODULE_FIRMWARE(IWL9000A_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); |
269 | MODULE_FIRMWARE(IWL9000B_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); | 333 | MODULE_FIRMWARE(IWL9000B_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); |
270 | MODULE_FIRMWARE(IWL9000RFB_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); | 334 | MODULE_FIRMWARE(IWL9000RFB_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); |
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c index 482ac8fdc67b..096a07c5a33f 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c | |||
@@ -48,16 +48,14 @@ | |||
48 | 48 | ||
49 | #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ | 49 | #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ |
50 | struct dentry *__tmp; \ | 50 | struct dentry *__tmp; \ |
51 | __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ | 51 | __tmp = debugfs_create_bool(#name, 0600, parent, ptr); \ |
52 | parent, ptr); \ | ||
53 | if (IS_ERR(__tmp) || !__tmp) \ | 52 | if (IS_ERR(__tmp) || !__tmp) \ |
54 | goto err; \ | 53 | goto err; \ |
55 | } while (0) | 54 | } while (0) |
56 | 55 | ||
57 | #define DEBUGFS_ADD_X32(name, parent, ptr) do { \ | 56 | #define DEBUGFS_ADD_X32(name, parent, ptr) do { \ |
58 | struct dentry *__tmp; \ | 57 | struct dentry *__tmp; \ |
59 | __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \ | 58 | __tmp = debugfs_create_x32(#name, 0600, parent, ptr); \ |
60 | parent, ptr); \ | ||
61 | if (IS_ERR(__tmp) || !__tmp) \ | 59 | if (IS_ERR(__tmp) || !__tmp) \ |
62 | goto err; \ | 60 | goto err; \ |
63 | } while (0) | 61 | } while (0) |
@@ -2370,48 +2368,48 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) | |||
2370 | if (!dir_debug) | 2368 | if (!dir_debug) |
2371 | goto err; | 2369 | goto err; |
2372 | 2370 | ||
2373 | DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); | 2371 | DEBUGFS_ADD_FILE(nvm, dir_data, 0400); |
2374 | DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); | 2372 | DEBUGFS_ADD_FILE(sram, dir_data, 0600); |
2375 | DEBUGFS_ADD_FILE(wowlan_sram, dir_data, S_IRUSR); | 2373 | DEBUGFS_ADD_FILE(wowlan_sram, dir_data, 0400); |
2376 | DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); | 2374 | DEBUGFS_ADD_FILE(stations, dir_data, 0400); |
2377 | DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); | 2375 | DEBUGFS_ADD_FILE(channels, dir_data, 0400); |
2378 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); | 2376 | DEBUGFS_ADD_FILE(status, dir_data, 0400); |
2379 | DEBUGFS_ADD_FILE(rx_handlers, dir_data, S_IWUSR | S_IRUSR); | 2377 | DEBUGFS_ADD_FILE(rx_handlers, dir_data, 0600); |
2380 | DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); | 2378 | DEBUGFS_ADD_FILE(qos, dir_data, 0400); |
2381 | DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); | 2379 | DEBUGFS_ADD_FILE(sleep_level_override, dir_data, 0600); |
2382 | DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); | 2380 | DEBUGFS_ADD_FILE(current_sleep_command, dir_data, 0400); |
2383 | DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); | 2381 | DEBUGFS_ADD_FILE(thermal_throttling, dir_data, 0400); |
2384 | DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); | 2382 | DEBUGFS_ADD_FILE(disable_ht40, dir_data, 0600); |
2385 | DEBUGFS_ADD_FILE(temperature, dir_data, S_IRUSR); | 2383 | DEBUGFS_ADD_FILE(temperature, dir_data, 0400); |
2386 | 2384 | ||
2387 | DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); | 2385 | DEBUGFS_ADD_FILE(power_save_status, dir_debug, 0400); |
2388 | DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); | 2386 | DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, 0200); |
2389 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); | 2387 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, 0200); |
2390 | DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); | 2388 | DEBUGFS_ADD_FILE(plcp_delta, dir_debug, 0600); |
2391 | DEBUGFS_ADD_FILE(rf_reset, dir_debug, S_IWUSR | S_IRUSR); | 2389 | DEBUGFS_ADD_FILE(rf_reset, dir_debug, 0600); |
2392 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); | 2390 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, 0400); |
2393 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); | 2391 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, 0400); |
2394 | DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); | 2392 | DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, 0400); |
2395 | DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); | 2393 | DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, 0200); |
2396 | DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); | 2394 | DEBUGFS_ADD_FILE(protection_mode, dir_debug, 0600); |
2397 | DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); | 2395 | DEBUGFS_ADD_FILE(sensitivity, dir_debug, 0400); |
2398 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); | 2396 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, 0400); |
2399 | DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); | 2397 | DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, 0600); |
2400 | DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); | 2398 | DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, 0400); |
2401 | DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); | 2399 | DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, 0400); |
2402 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); | 2400 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, 0200); |
2403 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); | 2401 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, 0200); |
2404 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); | 2402 | DEBUGFS_ADD_FILE(echo_test, dir_debug, 0200); |
2405 | DEBUGFS_ADD_FILE(fw_restart, dir_debug, S_IWUSR); | 2403 | DEBUGFS_ADD_FILE(fw_restart, dir_debug, 0200); |
2406 | #ifdef CONFIG_IWLWIFI_DEBUG | 2404 | #ifdef CONFIG_IWLWIFI_DEBUG |
2407 | DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); | 2405 | DEBUGFS_ADD_FILE(log_event, dir_debug, 0600); |
2408 | #endif | 2406 | #endif |
2409 | 2407 | ||
2410 | if (iwl_advanced_bt_coexist(priv)) | 2408 | if (iwl_advanced_bt_coexist(priv)) |
2411 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); | 2409 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, 0400); |
2412 | 2410 | ||
2413 | /* Calibrations disabled/enabled status*/ | 2411 | /* Calibrations disabled/enabled status*/ |
2414 | DEBUGFS_ADD_FILE(calib_disabled, dir_rf, S_IWUSR | S_IRUSR); | 2412 | DEBUGFS_ADD_FILE(calib_disabled, dir_rf, 0600); |
2415 | 2413 | ||
2416 | /* | 2414 | /* |
2417 | * Create a symlink with mac80211. This is not very robust, as it does | 2415 | * Create a symlink with mac80211. This is not very robust, as it does |
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c index ddcd8c2d66cd..98050d7be411 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c | |||
@@ -3276,17 +3276,17 @@ static void rs_add_debugfs(void *priv, void *priv_sta, | |||
3276 | { | 3276 | { |
3277 | struct iwl_lq_sta *lq_sta = priv_sta; | 3277 | struct iwl_lq_sta *lq_sta = priv_sta; |
3278 | lq_sta->rs_sta_dbgfs_scale_table_file = | 3278 | lq_sta->rs_sta_dbgfs_scale_table_file = |
3279 | debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, | 3279 | debugfs_create_file("rate_scale_table", 0600, dir, |
3280 | lq_sta, &rs_sta_dbgfs_scale_table_ops); | 3280 | lq_sta, &rs_sta_dbgfs_scale_table_ops); |
3281 | lq_sta->rs_sta_dbgfs_stats_table_file = | 3281 | lq_sta->rs_sta_dbgfs_stats_table_file = |
3282 | debugfs_create_file("rate_stats_table", S_IRUSR, dir, | 3282 | debugfs_create_file("rate_stats_table", 0400, dir, |
3283 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 3283 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
3284 | lq_sta->rs_sta_dbgfs_rate_scale_data_file = | 3284 | lq_sta->rs_sta_dbgfs_rate_scale_data_file = |
3285 | debugfs_create_file("rate_scale_data", S_IRUSR, dir, | 3285 | debugfs_create_file("rate_scale_data", 0400, dir, |
3286 | lq_sta, &rs_sta_dbgfs_rate_scale_data_ops); | 3286 | lq_sta, &rs_sta_dbgfs_rate_scale_data_ops); |
3287 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | 3287 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = |
3288 | debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir, | 3288 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, |
3289 | &lq_sta->tx_agg_tid_en); | 3289 | &lq_sta->tx_agg_tid_en); |
3290 | 3290 | ||
3291 | } | 3291 | } |
3292 | 3292 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h index 3fd07bc80f54..37c57bcbfb4a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h | |||
@@ -8,6 +8,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 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
11 | * Copyright (C) 2018 Intel Corporation | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,6 +31,7 @@ | |||
30 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 31 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
31 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 32 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
32 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 33 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
34 | * Copyright (C) 2018 Intel Corporation | ||
33 | * All rights reserved. | 35 | * All rights reserved. |
34 | * | 36 | * |
35 | * Redistribution and use in source and binary forms, with or without | 37 | * Redistribution and use in source and binary forms, with or without |
@@ -311,6 +313,17 @@ struct iwl_mcc_update_resp_v1 { | |||
311 | } __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_1 */ | 313 | } __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_1 */ |
312 | 314 | ||
313 | /** | 315 | /** |
316 | * enum iwl_geo_information - geographic information. | ||
317 | * @GEO_NO_INFO: no special info for this geo profile. | ||
318 | * @GEO_WMM_ETSI_5GHZ_INFO: this geo profile limits the WMM params | ||
319 | * for the 5 GHz band. | ||
320 | */ | ||
321 | enum iwl_geo_information { | ||
322 | GEO_NO_INFO = 0, | ||
323 | GEO_WMM_ETSI_5GHZ_INFO = BIT(0), | ||
324 | }; | ||
325 | |||
326 | /** | ||
314 | * struct iwl_mcc_update_resp - response to MCC_UPDATE_CMD. | 327 | * struct iwl_mcc_update_resp - response to MCC_UPDATE_CMD. |
315 | * Contains the new channel control profile map, if changed, and the new MCC | 328 | * Contains the new channel control profile map, if changed, and the new MCC |
316 | * (mobile country code). | 329 | * (mobile country code). |
@@ -320,7 +333,8 @@ struct iwl_mcc_update_resp_v1 { | |||
320 | * @cap: capabilities for all channels which matches the MCC | 333 | * @cap: capabilities for all channels which matches the MCC |
321 | * @source_id: the MCC source, see iwl_mcc_source | 334 | * @source_id: the MCC source, see iwl_mcc_source |
322 | * @time: time elapsed from the MCC test start (in 30 seconds TU) | 335 | * @time: time elapsed from the MCC test start (in 30 seconds TU) |
323 | * @reserved: reserved. | 336 | * @geo_info: geographic specific profile information |
337 | * see &enum iwl_geo_information. | ||
324 | * @n_channels: number of channels in @channels_data (may be 14, 39, 50 or 51 | 338 | * @n_channels: number of channels in @channels_data (may be 14, 39, 50 or 51 |
325 | * channels, depending on platform) | 339 | * channels, depending on platform) |
326 | * @channels: channel control data map, DWORD for each channel. Only the first | 340 | * @channels: channel control data map, DWORD for each channel. Only the first |
@@ -332,10 +346,10 @@ struct iwl_mcc_update_resp { | |||
332 | u8 cap; | 346 | u8 cap; |
333 | u8 source_id; | 347 | u8 source_id; |
334 | __le16 time; | 348 | __le16 time; |
335 | __le16 reserved; | 349 | __le16 geo_info; |
336 | __le32 n_channels; | 350 | __le32 n_channels; |
337 | __le32 channels[0]; | 351 | __le32 channels[0]; |
338 | } __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_2 */ | 352 | } __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_3 */ |
339 | 353 | ||
340 | /** | 354 | /** |
341 | * struct iwl_mcc_chub_notif - chub notifies of mcc change | 355 | * struct iwl_mcc_chub_notif - chub notifies of mcc change |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index 3bfc657f6b42..7af3a0f51b77 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h | |||
@@ -30,6 +30,7 @@ | |||
30 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 30 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
31 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 31 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
32 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 32 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
33 | * Copyright(c) 2018 Intel Corporation | ||
33 | * All rights reserved. | 34 | * All rights reserved. |
34 | * | 35 | * |
35 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -579,8 +580,23 @@ enum iwl_umac_scan_general_flags { | |||
579 | IWL_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED = BIT(8), | 580 | IWL_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED = BIT(8), |
580 | IWL_UMAC_SCAN_GEN_FLAGS_MATCH = BIT(9), | 581 | IWL_UMAC_SCAN_GEN_FLAGS_MATCH = BIT(9), |
581 | IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL = BIT(10), | 582 | IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL = BIT(10), |
583 | /* Extended dwell is obselete when adaptive dwell is used, making this | ||
584 | * bit reusable. Hence, probe request defer is used only when adaptive | ||
585 | * dwell is supported. */ | ||
586 | IWL_UMAC_SCAN_GEN_FLAGS_PROB_REQ_DEFER_SUPP = BIT(10), | ||
582 | IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED = BIT(11), | 587 | IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED = BIT(11), |
583 | IWL_UMAC_SCAN_GEN_FLAGS_ADAPTIVE_DWELL = BIT(13), | 588 | IWL_UMAC_SCAN_GEN_FLAGS_ADAPTIVE_DWELL = BIT(13), |
589 | IWL_UMAC_SCAN_GEN_FLAGS_MAX_CHNL_TIME = BIT(14), | ||
590 | IWL_UMAC_SCAN_GEN_FLAGS_PROB_REQ_HIGH_TX_RATE = BIT(15), | ||
591 | }; | ||
592 | |||
593 | /** | ||
594 | * enum iwl_umac_scan_general_flags2 - UMAC scan general flags #2 | ||
595 | * @IWL_UMAC_SCAN_GEN_FLAGS2_NOTIF_PER_CHNL: Whether to send a complete | ||
596 | * notification per channel or not. | ||
597 | */ | ||
598 | enum iwl_umac_scan_general_flags2 { | ||
599 | IWL_UMAC_SCAN_GEN_FLAGS2_NOTIF_PER_CHNL = BIT(0), | ||
584 | }; | 600 | }; |
585 | 601 | ||
586 | /** | 602 | /** |
@@ -629,6 +645,18 @@ struct iwl_scan_req_umac_tail { | |||
629 | } __packed; | 645 | } __packed; |
630 | 646 | ||
631 | /** | 647 | /** |
648 | * struct iwl_scan_umac_chan_param | ||
649 | * @flags: channel flags &enum iwl_scan_channel_flags | ||
650 | * @count: num of channels in scan request | ||
651 | * @reserved: for future use and alignment | ||
652 | */ | ||
653 | struct iwl_scan_umac_chan_param { | ||
654 | u8 flags; | ||
655 | u8 count; | ||
656 | __le16 reserved; | ||
657 | } __packed; /*SCAN_CHANNEL_PARAMS_API_S_VER_1 */ | ||
658 | |||
659 | /** | ||
632 | * struct iwl_scan_req_umac | 660 | * struct iwl_scan_req_umac |
633 | * @flags: &enum iwl_umac_scan_flags | 661 | * @flags: &enum iwl_umac_scan_flags |
634 | * @uid: scan id, &enum iwl_umac_scan_uid_offsets | 662 | * @uid: scan id, &enum iwl_umac_scan_uid_offsets |
@@ -636,23 +664,24 @@ struct iwl_scan_req_umac_tail { | |||
636 | * @general_flags: &enum iwl_umac_scan_general_flags | 664 | * @general_flags: &enum iwl_umac_scan_general_flags |
637 | * @scan_start_mac_id: report the scan start TSF time according to this mac TSF | 665 | * @scan_start_mac_id: report the scan start TSF time according to this mac TSF |
638 | * @extended_dwell: dwell time for channels 1, 6 and 11 | 666 | * @extended_dwell: dwell time for channels 1, 6 and 11 |
639 | * @active_dwell: dwell time for active scan | 667 | * @active_dwell: dwell time for active scan per LMAC |
640 | * @passive_dwell: dwell time for passive scan | 668 | * @passive_dwell: dwell time for passive scan per LMAC |
641 | * @fragmented_dwell: dwell time for fragmented passive scan | 669 | * @fragmented_dwell: dwell time for fragmented passive scan |
642 | * @adwell_default_n_aps: for adaptive dwell the default number of APs | 670 | * @adwell_default_n_aps: for adaptive dwell the default number of APs |
643 | * per channel | 671 | * per channel |
644 | * @adwell_default_n_aps_social: for adaptive dwell the default | 672 | * @adwell_default_n_aps_social: for adaptive dwell the default |
645 | * number of APs per social (1,6,11) channel | 673 | * number of APs per social (1,6,11) channel |
674 | * @general_flags2: &enum iwl_umac_scan_general_flags2 | ||
646 | * @adwell_max_budget: for adaptive dwell the maximal budget of TU to be added | 675 | * @adwell_max_budget: for adaptive dwell the maximal budget of TU to be added |
647 | * to total scan time | 676 | * to total scan time |
648 | * @max_out_time: max out of serving channel time, per LMAC - for CDB there | 677 | * @max_out_time: max out of serving channel time, per LMAC - for CDB there |
649 | * are 2 LMACs | 678 | * are 2 LMACs |
650 | * @suspend_time: max suspend time, per LMAC - for CDB there are 2 LMACs | 679 | * @suspend_time: max suspend time, per LMAC - for CDB there are 2 LMACs |
651 | * @scan_priority: scan internal prioritization &enum iwl_scan_priority | 680 | * @scan_priority: scan internal prioritization &enum iwl_scan_priority |
652 | * @channel_flags: &enum iwl_scan_channel_flags | 681 | * @num_of_fragments: Number of fragments needed for full coverage per band. |
653 | * @n_channels: num of channels in scan request | 682 | * Relevant only for fragmented scan. |
683 | * @channel: &struct iwl_scan_umac_chan_param | ||
654 | * @reserved: for future use and alignment | 684 | * @reserved: for future use and alignment |
655 | * @reserved2: for future use and alignment | ||
656 | * @reserved3: for future use and alignment | 685 | * @reserved3: for future use and alignment |
657 | * @data: &struct iwl_scan_channel_cfg_umac and | 686 | * @data: &struct iwl_scan_channel_cfg_umac and |
658 | * &struct iwl_scan_req_umac_tail | 687 | * &struct iwl_scan_req_umac_tail |
@@ -673,10 +702,7 @@ struct iwl_scan_req_umac { | |||
673 | __le32 max_out_time; | 702 | __le32 max_out_time; |
674 | __le32 suspend_time; | 703 | __le32 suspend_time; |
675 | __le32 scan_priority; | 704 | __le32 scan_priority; |
676 | /* SCAN_CHANNEL_PARAMS_API_S_VER_1 */ | 705 | struct iwl_scan_umac_chan_param channel; |
677 | u8 channel_flags; | ||
678 | u8 n_channels; | ||
679 | __le16 reserved2; | ||
680 | u8 data[]; | 706 | u8 data[]; |
681 | } v1; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_1 */ | 707 | } v1; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_1 */ |
682 | struct { | 708 | struct { |
@@ -687,10 +713,7 @@ struct iwl_scan_req_umac { | |||
687 | __le32 max_out_time[SCAN_TWO_LMACS]; | 713 | __le32 max_out_time[SCAN_TWO_LMACS]; |
688 | __le32 suspend_time[SCAN_TWO_LMACS]; | 714 | __le32 suspend_time[SCAN_TWO_LMACS]; |
689 | __le32 scan_priority; | 715 | __le32 scan_priority; |
690 | /* SCAN_CHANNEL_PARAMS_API_S_VER_1 */ | 716 | struct iwl_scan_umac_chan_param channel; |
691 | u8 channel_flags; | ||
692 | u8 n_channels; | ||
693 | __le16 reserved2; | ||
694 | u8 data[]; | 717 | u8 data[]; |
695 | } v6; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_6 */ | 718 | } v6; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_6 */ |
696 | struct { | 719 | struct { |
@@ -704,16 +727,30 @@ struct iwl_scan_req_umac { | |||
704 | __le32 max_out_time[SCAN_TWO_LMACS]; | 727 | __le32 max_out_time[SCAN_TWO_LMACS]; |
705 | __le32 suspend_time[SCAN_TWO_LMACS]; | 728 | __le32 suspend_time[SCAN_TWO_LMACS]; |
706 | __le32 scan_priority; | 729 | __le32 scan_priority; |
707 | /* SCAN_CHANNEL_PARAMS_API_S_VER_1 */ | 730 | struct iwl_scan_umac_chan_param channel; |
708 | u8 channel_flags; | ||
709 | u8 n_channels; | ||
710 | __le16 reserved2; | ||
711 | u8 data[]; | 731 | u8 data[]; |
712 | } v7; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_7 */ | 732 | } v7; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_7 */ |
733 | struct { | ||
734 | u8 active_dwell[SCAN_TWO_LMACS]; | ||
735 | u8 reserved2; | ||
736 | u8 adwell_default_n_aps; | ||
737 | u8 adwell_default_n_aps_social; | ||
738 | u8 general_flags2; | ||
739 | __le16 adwell_max_budget; | ||
740 | __le32 max_out_time[SCAN_TWO_LMACS]; | ||
741 | __le32 suspend_time[SCAN_TWO_LMACS]; | ||
742 | __le32 scan_priority; | ||
743 | u8 passive_dwell[SCAN_TWO_LMACS]; | ||
744 | u8 num_of_fragments[SCAN_TWO_LMACS]; | ||
745 | struct iwl_scan_umac_chan_param channel; | ||
746 | u8 data[]; | ||
747 | } v8; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_8 */ | ||
713 | }; | 748 | }; |
714 | } __packed; | 749 | } __packed; |
715 | 750 | ||
716 | #define IWL_SCAN_REQ_UMAC_SIZE_V7 sizeof(struct iwl_scan_req_umac) | 751 | #define IWL_SCAN_REQ_UMAC_SIZE_V8 sizeof(struct iwl_scan_req_umac) |
752 | #define IWL_SCAN_REQ_UMAC_SIZE_V7 (sizeof(struct iwl_scan_req_umac) - \ | ||
753 | 4 * sizeof(u8)) | ||
717 | #define IWL_SCAN_REQ_UMAC_SIZE_V6 (sizeof(struct iwl_scan_req_umac) - \ | 754 | #define IWL_SCAN_REQ_UMAC_SIZE_V6 (sizeof(struct iwl_scan_req_umac) - \ |
718 | 2 * sizeof(u8) - sizeof(__le16)) | 755 | 2 * sizeof(u8) - sizeof(__le16)) |
719 | #define IWL_SCAN_REQ_UMAC_SIZE_V1 (sizeof(struct iwl_scan_req_umac) - \ | 756 | #define IWL_SCAN_REQ_UMAC_SIZE_V1 (sizeof(struct iwl_scan_req_umac) - \ |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 7bd704a3e640..fa283285fcbe 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c | |||
@@ -68,6 +68,7 @@ | |||
68 | #include "iwl-drv.h" | 68 | #include "iwl-drv.h" |
69 | #include "runtime.h" | 69 | #include "runtime.h" |
70 | #include "dbg.h" | 70 | #include "dbg.h" |
71 | #include "debugfs.h" | ||
71 | #include "iwl-io.h" | 72 | #include "iwl-io.h" |
72 | #include "iwl-prph.h" | 73 | #include "iwl-prph.h" |
73 | #include "iwl-csr.h" | 74 | #include "iwl-csr.h" |
@@ -1007,6 +1008,12 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt, | |||
1007 | { | 1008 | { |
1008 | struct iwl_fw_dump_desc *desc; | 1009 | struct iwl_fw_dump_desc *desc; |
1009 | 1010 | ||
1011 | if (trigger && trigger->flags & IWL_FW_DBG_FORCE_RESTART) { | ||
1012 | IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", trig); | ||
1013 | iwl_force_nmi(fwrt->trans); | ||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
1010 | desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC); | 1017 | desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC); |
1011 | if (!desc) | 1018 | if (!desc) |
1012 | return -ENOMEM; | 1019 | return -ENOMEM; |
@@ -1080,6 +1087,9 @@ int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, u8 conf_id) | |||
1080 | IWL_WARN(fwrt, "FW already configured (%d) - re-configuring\n", | 1087 | IWL_WARN(fwrt, "FW already configured (%d) - re-configuring\n", |
1081 | fwrt->dump.conf); | 1088 | fwrt->dump.conf); |
1082 | 1089 | ||
1090 | /* start default config marker cmd for syncing logs */ | ||
1091 | iwl_fw_trigger_timestamp(fwrt, 1); | ||
1092 | |||
1083 | /* Send all HCMDs for configuring the FW debug */ | 1093 | /* Send all HCMDs for configuring the FW debug */ |
1084 | ptr = (void *)&fwrt->fw->dbg_conf_tlv[conf_id]->hcmd; | 1094 | ptr = (void *)&fwrt->fw->dbg_conf_tlv[conf_id]->hcmd; |
1085 | for (i = 0; i < fwrt->fw->dbg_conf_tlv[conf_id]->num_of_hcmds; i++) { | 1095 | for (i = 0; i < fwrt->fw->dbg_conf_tlv[conf_id]->num_of_hcmds; i++) { |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c index e2ded29a145d..8f005cd69559 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c | |||
@@ -157,6 +157,20 @@ static void iwl_fw_timestamp_marker_wk(struct work_struct *work) | |||
157 | ret, jiffies_to_msecs(delay) / 1000); | 157 | ret, jiffies_to_msecs(delay) / 1000); |
158 | } | 158 | } |
159 | 159 | ||
160 | void iwl_fw_trigger_timestamp(struct iwl_fw_runtime *fwrt, u32 delay) | ||
161 | { | ||
162 | IWL_INFO(fwrt, | ||
163 | "starting timestamp_marker trigger with delay: %us\n", | ||
164 | delay); | ||
165 | |||
166 | iwl_fw_cancel_timestamp(fwrt); | ||
167 | |||
168 | fwrt->timestamp.delay = msecs_to_jiffies(delay * 1000); | ||
169 | |||
170 | schedule_delayed_work(&fwrt->timestamp.wk, | ||
171 | round_jiffies_relative(fwrt->timestamp.delay)); | ||
172 | } | ||
173 | |||
160 | static ssize_t iwl_dbgfs_timestamp_marker_write(struct iwl_fw_runtime *fwrt, | 174 | static ssize_t iwl_dbgfs_timestamp_marker_write(struct iwl_fw_runtime *fwrt, |
161 | char *buf, size_t count, | 175 | char *buf, size_t count, |
162 | loff_t *ppos) | 176 | loff_t *ppos) |
@@ -168,16 +182,8 @@ static ssize_t iwl_dbgfs_timestamp_marker_write(struct iwl_fw_runtime *fwrt, | |||
168 | if (ret < 0) | 182 | if (ret < 0) |
169 | return ret; | 183 | return ret; |
170 | 184 | ||
171 | IWL_INFO(fwrt, | 185 | iwl_fw_trigger_timestamp(fwrt, delay); |
172 | "starting timestamp_marker trigger with delay: %us\n", | ||
173 | delay); | ||
174 | 186 | ||
175 | iwl_fw_cancel_timestamp(fwrt); | ||
176 | |||
177 | fwrt->timestamp.delay = msecs_to_jiffies(delay * 1000); | ||
178 | |||
179 | schedule_delayed_work(&fwrt->timestamp.wk, | ||
180 | round_jiffies_relative(fwrt->timestamp.delay)); | ||
181 | return count; | 187 | return count; |
182 | } | 188 | } |
183 | 189 | ||
@@ -187,7 +193,7 @@ int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, | |||
187 | struct dentry *dbgfs_dir) | 193 | struct dentry *dbgfs_dir) |
188 | { | 194 | { |
189 | INIT_DELAYED_WORK(&fwrt->timestamp.wk, iwl_fw_timestamp_marker_wk); | 195 | INIT_DELAYED_WORK(&fwrt->timestamp.wk, iwl_fw_timestamp_marker_wk); |
190 | FWRT_DEBUGFS_ADD_FILE(timestamp_marker, dbgfs_dir, S_IWUSR); | 196 | FWRT_DEBUGFS_ADD_FILE(timestamp_marker, dbgfs_dir, 0200); |
191 | return 0; | 197 | return 0; |
192 | err: | 198 | err: |
193 | IWL_ERR(fwrt, "Can't create the fwrt debugfs directory\n"); | 199 | IWL_ERR(fwrt, "Can't create the fwrt debugfs directory\n"); |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h index 3da468d2cc92..d93f6a4bb22d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h | |||
@@ -89,6 +89,8 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) | |||
89 | round_jiffies_relative(fwrt->timestamp.delay)); | 89 | round_jiffies_relative(fwrt->timestamp.delay)); |
90 | } | 90 | } |
91 | 91 | ||
92 | void iwl_fw_trigger_timestamp(struct iwl_fw_runtime *fwrt, u32 delay); | ||
93 | |||
92 | #else | 94 | #else |
93 | static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, | 95 | static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, |
94 | struct dentry *dbgfs_dir) | 96 | struct dentry *dbgfs_dir) |
@@ -102,4 +104,7 @@ static inline void iwl_fw_suspend_timestamp(struct iwl_fw_runtime *fwrt) {} | |||
102 | 104 | ||
103 | static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {} | 105 | static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {} |
104 | 106 | ||
107 | static inline void iwl_fw_trigger_timestamp(struct iwl_fw_runtime *fwrt, | ||
108 | u32 delay) {} | ||
109 | |||
105 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 110 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 1a05d506ac9a..9b2805e1e3b1 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h | |||
@@ -250,6 +250,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t; | |||
250 | * indicating low latency direction. | 250 | * indicating low latency direction. |
251 | * @IWL_UCODE_TLV_API_DEPRECATE_TTAK: RX status flag TTAK ok (bit 7) is | 251 | * @IWL_UCODE_TLV_API_DEPRECATE_TTAK: RX status flag TTAK ok (bit 7) is |
252 | * deprecated. | 252 | * deprecated. |
253 | * @IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2: This ucode supports version 8 | ||
254 | * of scan request: SCAN_REQUEST_CMD_UMAC_API_S_VER_8 | ||
253 | * | 255 | * |
254 | * @NUM_IWL_UCODE_TLV_API: number of bits used | 256 | * @NUM_IWL_UCODE_TLV_API: number of bits used |
255 | */ | 257 | */ |
@@ -265,10 +267,12 @@ enum iwl_ucode_tlv_api { | |||
265 | IWL_UCODE_TLV_API_NAN2_VER2 = (__force iwl_ucode_tlv_api_t)31, | 267 | IWL_UCODE_TLV_API_NAN2_VER2 = (__force iwl_ucode_tlv_api_t)31, |
266 | /* API Set 1 */ | 268 | /* API Set 1 */ |
267 | IWL_UCODE_TLV_API_ADAPTIVE_DWELL = (__force iwl_ucode_tlv_api_t)32, | 269 | IWL_UCODE_TLV_API_ADAPTIVE_DWELL = (__force iwl_ucode_tlv_api_t)32, |
270 | IWL_UCODE_TLV_API_OCE = (__force iwl_ucode_tlv_api_t)33, | ||
268 | IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE = (__force iwl_ucode_tlv_api_t)34, | 271 | IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE = (__force iwl_ucode_tlv_api_t)34, |
269 | IWL_UCODE_TLV_API_NEW_RX_STATS = (__force iwl_ucode_tlv_api_t)35, | 272 | IWL_UCODE_TLV_API_NEW_RX_STATS = (__force iwl_ucode_tlv_api_t)35, |
270 | IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY = (__force iwl_ucode_tlv_api_t)38, | 273 | IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY = (__force iwl_ucode_tlv_api_t)38, |
271 | IWL_UCODE_TLV_API_DEPRECATE_TTAK = (__force iwl_ucode_tlv_api_t)41, | 274 | IWL_UCODE_TLV_API_DEPRECATE_TTAK = (__force iwl_ucode_tlv_api_t)41, |
275 | IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2 = (__force iwl_ucode_tlv_api_t)42, | ||
272 | 276 | ||
273 | NUM_IWL_UCODE_TLV_API | 277 | NUM_IWL_UCODE_TLV_API |
274 | #ifdef __CHECKER__ | 278 | #ifdef __CHECKER__ |
@@ -441,6 +445,7 @@ enum iwl_fw_phy_cfg { | |||
441 | FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS, | 445 | FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS, |
442 | FW_PHY_CFG_RX_CHAIN_POS = 20, | 446 | FW_PHY_CFG_RX_CHAIN_POS = 20, |
443 | FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS, | 447 | FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS, |
448 | FW_PHY_CFG_SHARED_CLK = BIT(31), | ||
444 | }; | 449 | }; |
445 | 450 | ||
446 | #define IWL_UCODE_MAX_CS 1 | 451 | #define IWL_UCODE_MAX_CS 1 |
@@ -616,6 +621,14 @@ enum iwl_fw_dbg_trigger_mode { | |||
616 | }; | 621 | }; |
617 | 622 | ||
618 | /** | 623 | /** |
624 | * enum iwl_fw_dbg_trigger_flags - the flags supported by wrt triggers | ||
625 | * @IWL_FW_DBG_FORCE_RESTART: force a firmware restart | ||
626 | */ | ||
627 | enum iwl_fw_dbg_trigger_flags { | ||
628 | IWL_FW_DBG_FORCE_RESTART = BIT(0), | ||
629 | }; | ||
630 | |||
631 | /** | ||
619 | * enum iwl_fw_dbg_trigger_vif_type - define the VIF type for a trigger | 632 | * enum iwl_fw_dbg_trigger_vif_type - define the VIF type for a trigger |
620 | * @IWL_FW_DBG_CONF_VIF_ANY: any vif type | 633 | * @IWL_FW_DBG_CONF_VIF_ANY: any vif type |
621 | * @IWL_FW_DBG_CONF_VIF_IBSS: IBSS mode | 634 | * @IWL_FW_DBG_CONF_VIF_IBSS: IBSS mode |
@@ -651,6 +664,7 @@ enum iwl_fw_dbg_trigger_vif_type { | |||
651 | * @occurrences: number of occurrences. 0 means the trigger will never fire. | 664 | * @occurrences: number of occurrences. 0 means the trigger will never fire. |
652 | * @trig_dis_ms: the time, in milliseconds, after an occurrence of this | 665 | * @trig_dis_ms: the time, in milliseconds, after an occurrence of this |
653 | * trigger in which another occurrence should be ignored. | 666 | * trigger in which another occurrence should be ignored. |
667 | * @flags: &enum iwl_fw_dbg_trigger_flags | ||
654 | */ | 668 | */ |
655 | struct iwl_fw_dbg_trigger_tlv { | 669 | struct iwl_fw_dbg_trigger_tlv { |
656 | __le32 id; | 670 | __le32 id; |
@@ -661,7 +675,8 @@ struct iwl_fw_dbg_trigger_tlv { | |||
661 | u8 start_conf_id; | 675 | u8 start_conf_id; |
662 | __le16 occurrences; | 676 | __le16 occurrences; |
663 | __le16 trig_dis_ms; | 677 | __le16 trig_dis_ms; |
664 | __le16 reserved[3]; | 678 | u8 flags; |
679 | u8 reserved[5]; | ||
665 | 680 | ||
666 | u8 data[0]; | 681 | u8 data[0]; |
667 | } __packed; | 682 | } __packed; |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 258d439bb0a9..f0f5636dd3ea 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h | |||
@@ -398,6 +398,7 @@ struct iwl_cfg { | |||
398 | u8 ucode_api_max; | 398 | u8 ucode_api_max; |
399 | u8 ucode_api_min; | 399 | u8 ucode_api_min; |
400 | u32 min_umac_error_event_table; | 400 | u32 min_umac_error_event_table; |
401 | u32 extra_phy_cfg_flags; | ||
401 | }; | 402 | }; |
402 | 403 | ||
403 | /* | 404 | /* |
@@ -477,6 +478,10 @@ extern const struct iwl_cfg iwl9460_2ac_cfg_soc; | |||
477 | extern const struct iwl_cfg iwl9461_2ac_cfg_soc; | 478 | extern const struct iwl_cfg iwl9461_2ac_cfg_soc; |
478 | extern const struct iwl_cfg iwl9462_2ac_cfg_soc; | 479 | extern const struct iwl_cfg iwl9462_2ac_cfg_soc; |
479 | extern const struct iwl_cfg iwl9560_2ac_cfg_soc; | 480 | extern const struct iwl_cfg iwl9560_2ac_cfg_soc; |
481 | extern const struct iwl_cfg iwl9460_2ac_cfg_shared_clk; | ||
482 | extern const struct iwl_cfg iwl9461_2ac_cfg_shared_clk; | ||
483 | extern const struct iwl_cfg iwl9462_2ac_cfg_shared_clk; | ||
484 | extern const struct iwl_cfg iwl9560_2ac_cfg_shared_clk; | ||
480 | extern const struct iwl_cfg iwl22000_2ac_cfg_hr; | 485 | extern const struct iwl_cfg iwl22000_2ac_cfg_hr; |
481 | extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; | 486 | extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; |
482 | extern const struct iwl_cfg iwl22000_2ac_cfg_jf; | 487 | extern const struct iwl_cfg iwl22000_2ac_cfg_jf; |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 9c4a7f648a44..aa2d5c14e202 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c | |||
@@ -1768,41 +1768,36 @@ static void __exit iwl_drv_exit(void) | |||
1768 | module_exit(iwl_drv_exit); | 1768 | module_exit(iwl_drv_exit); |
1769 | 1769 | ||
1770 | #ifdef CONFIG_IWLWIFI_DEBUG | 1770 | #ifdef CONFIG_IWLWIFI_DEBUG |
1771 | module_param_named(debug, iwlwifi_mod_params.debug_level, uint, | 1771 | module_param_named(debug, iwlwifi_mod_params.debug_level, uint, 0644); |
1772 | S_IRUGO | S_IWUSR); | ||
1773 | MODULE_PARM_DESC(debug, "debug output mask"); | 1772 | MODULE_PARM_DESC(debug, "debug output mask"); |
1774 | #endif | 1773 | #endif |
1775 | 1774 | ||
1776 | module_param_named(swcrypto, iwlwifi_mod_params.swcrypto, int, S_IRUGO); | 1775 | module_param_named(swcrypto, iwlwifi_mod_params.swcrypto, int, 0444); |
1777 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 1776 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); |
1778 | module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); | 1777 | module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, 0444); |
1779 | MODULE_PARM_DESC(11n_disable, | 1778 | MODULE_PARM_DESC(11n_disable, |
1780 | "disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX"); | 1779 | "disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX"); |
1781 | module_param_named(amsdu_size, iwlwifi_mod_params.amsdu_size, | 1780 | module_param_named(amsdu_size, iwlwifi_mod_params.amsdu_size, int, 0444); |
1782 | int, S_IRUGO); | ||
1783 | MODULE_PARM_DESC(amsdu_size, | 1781 | MODULE_PARM_DESC(amsdu_size, |
1784 | "amsdu size 0: 12K for multi Rx queue devices, 4K for other devices 1:4K 2:8K 3:12K (default 0)"); | 1782 | "amsdu size 0: 12K for multi Rx queue devices, 4K for other devices 1:4K 2:8K 3:12K (default 0)"); |
1785 | module_param_named(fw_restart, iwlwifi_mod_params.fw_restart, bool, S_IRUGO); | 1783 | module_param_named(fw_restart, iwlwifi_mod_params.fw_restart, bool, 0444); |
1786 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)"); | 1784 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)"); |
1787 | 1785 | ||
1788 | module_param_named(antenna_coupling, iwlwifi_mod_params.antenna_coupling, | 1786 | module_param_named(antenna_coupling, iwlwifi_mod_params.antenna_coupling, |
1789 | int, S_IRUGO); | 1787 | int, 0444); |
1790 | MODULE_PARM_DESC(antenna_coupling, | 1788 | MODULE_PARM_DESC(antenna_coupling, |
1791 | "specify antenna coupling in dB (default: 0 dB)"); | 1789 | "specify antenna coupling in dB (default: 0 dB)"); |
1792 | 1790 | ||
1793 | module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO); | 1791 | module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, 0444); |
1794 | MODULE_PARM_DESC(nvm_file, "NVM file name"); | 1792 | MODULE_PARM_DESC(nvm_file, "NVM file name"); |
1795 | 1793 | ||
1796 | module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable, | 1794 | module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable, bool, 0444); |
1797 | bool, S_IRUGO); | ||
1798 | MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)"); | 1795 | MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)"); |
1799 | 1796 | ||
1800 | module_param_named(lar_disable, iwlwifi_mod_params.lar_disable, | 1797 | module_param_named(lar_disable, iwlwifi_mod_params.lar_disable, bool, 0444); |
1801 | bool, S_IRUGO); | ||
1802 | MODULE_PARM_DESC(lar_disable, "disable LAR functionality (default: N)"); | 1798 | MODULE_PARM_DESC(lar_disable, "disable LAR functionality (default: N)"); |
1803 | 1799 | ||
1804 | module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, | 1800 | module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, uint, 0644); |
1805 | uint, S_IRUGO | S_IWUSR); | ||
1806 | MODULE_PARM_DESC(uapsd_disable, | 1801 | MODULE_PARM_DESC(uapsd_disable, |
1807 | "disable U-APSD functionality bitmap 1: BSS 2: P2P Client (default: 3)"); | 1802 | "disable U-APSD functionality bitmap 1: BSS 2: P2P Client (default: 3)"); |
1808 | 1803 | ||
@@ -1823,31 +1818,27 @@ MODULE_PARM_DESC(uapsd_disable, | |||
1823 | * default: bt_coex_active = true (BT_COEX_ENABLE) | 1818 | * default: bt_coex_active = true (BT_COEX_ENABLE) |
1824 | */ | 1819 | */ |
1825 | module_param_named(bt_coex_active, iwlwifi_mod_params.bt_coex_active, | 1820 | module_param_named(bt_coex_active, iwlwifi_mod_params.bt_coex_active, |
1826 | bool, S_IRUGO); | 1821 | bool, 0444); |
1827 | MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)"); | 1822 | MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)"); |
1828 | 1823 | ||
1829 | module_param_named(led_mode, iwlwifi_mod_params.led_mode, int, S_IRUGO); | 1824 | module_param_named(led_mode, iwlwifi_mod_params.led_mode, int, 0444); |
1830 | MODULE_PARM_DESC(led_mode, "0=system default, " | 1825 | MODULE_PARM_DESC(led_mode, "0=system default, " |
1831 | "1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)"); | 1826 | "1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)"); |
1832 | 1827 | ||
1833 | module_param_named(power_save, iwlwifi_mod_params.power_save, | 1828 | module_param_named(power_save, iwlwifi_mod_params.power_save, bool, 0444); |
1834 | bool, S_IRUGO); | ||
1835 | MODULE_PARM_DESC(power_save, | 1829 | MODULE_PARM_DESC(power_save, |
1836 | "enable WiFi power management (default: disable)"); | 1830 | "enable WiFi power management (default: disable)"); |
1837 | 1831 | ||
1838 | module_param_named(power_level, iwlwifi_mod_params.power_level, | 1832 | module_param_named(power_level, iwlwifi_mod_params.power_level, int, 0444); |
1839 | int, S_IRUGO); | ||
1840 | MODULE_PARM_DESC(power_level, | 1833 | MODULE_PARM_DESC(power_level, |
1841 | "default power save level (range from 1 - 5, default: 1)"); | 1834 | "default power save level (range from 1 - 5, default: 1)"); |
1842 | 1835 | ||
1843 | module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, S_IRUGO); | 1836 | module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, 0444); |
1844 | MODULE_PARM_DESC(fw_monitor, | 1837 | MODULE_PARM_DESC(fw_monitor, |
1845 | "firmware monitor - to debug FW (default: false - needs lots of memory)"); | 1838 | "firmware monitor - to debug FW (default: false - needs lots of memory)"); |
1846 | 1839 | ||
1847 | module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_timeout, | 1840 | module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_timeout, uint, 0444); |
1848 | uint, S_IRUGO); | ||
1849 | MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)"); | 1841 | MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)"); |
1850 | 1842 | ||
1851 | module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool, | 1843 | module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool, 0444); |
1852 | S_IRUGO); | ||
1853 | MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities (default: false)"); | 1844 | MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities (default: false)"); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h index 976640fed334..96b52a275ee3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h | |||
@@ -110,6 +110,8 @@ | |||
110 | #define IWL_MVM_SW_TX_CSUM_OFFLOAD 0 | 110 | #define IWL_MVM_SW_TX_CSUM_OFFLOAD 0 |
111 | #define IWL_MVM_HW_CSUM_DISABLE 0 | 111 | #define IWL_MVM_HW_CSUM_DISABLE 0 |
112 | #define IWL_MVM_PARSE_NVM 0 | 112 | #define IWL_MVM_PARSE_NVM 0 |
113 | #define IWL_MVM_ADWELL_ENABLE 1 | ||
114 | #define IWL_MVM_ADWELL_MAX_BUDGET 0 | ||
113 | #define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1 | 115 | #define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1 |
114 | #define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2 | 116 | #define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2 |
115 | #define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1 | 117 | #define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1 |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c index 4228fac77f41..f7fcf700196b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | |||
@@ -1276,7 +1276,6 @@ static ssize_t iwl_dbgfs_low_latency_write(struct ieee80211_vif *vif, char *buf, | |||
1276 | { | 1276 | { |
1277 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 1277 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
1278 | struct iwl_mvm *mvm = mvmvif->mvm; | 1278 | struct iwl_mvm *mvm = mvmvif->mvm; |
1279 | bool prev; | ||
1280 | u8 value; | 1279 | u8 value; |
1281 | int ret; | 1280 | int ret; |
1282 | 1281 | ||
@@ -1287,9 +1286,7 @@ static ssize_t iwl_dbgfs_low_latency_write(struct ieee80211_vif *vif, char *buf, | |||
1287 | return -EINVAL; | 1286 | return -EINVAL; |
1288 | 1287 | ||
1289 | mutex_lock(&mvm->mutex); | 1288 | mutex_lock(&mvm->mutex); |
1290 | prev = iwl_mvm_vif_low_latency(mvmvif); | 1289 | iwl_mvm_update_low_latency(mvm, vif, value, LOW_LATENCY_DEBUGFS); |
1291 | mvmvif->low_latency_dbgfs = value; | ||
1292 | iwl_mvm_update_low_latency(mvm, vif, prev); | ||
1293 | mutex_unlock(&mvm->mutex); | 1290 | mutex_unlock(&mvm->mutex); |
1294 | 1291 | ||
1295 | return count; | 1292 | return count; |
@@ -1306,9 +1303,9 @@ static ssize_t iwl_dbgfs_low_latency_read(struct file *file, | |||
1306 | 1303 | ||
1307 | len = scnprintf(buf, sizeof(buf) - 1, | 1304 | len = scnprintf(buf, sizeof(buf) - 1, |
1308 | "traffic=%d\ndbgfs=%d\nvcmd=%d\n", | 1305 | "traffic=%d\ndbgfs=%d\nvcmd=%d\n", |
1309 | mvmvif->low_latency_traffic, | 1306 | !!(mvmvif->low_latency & LOW_LATENCY_TRAFFIC), |
1310 | mvmvif->low_latency_dbgfs, | 1307 | !!(mvmvif->low_latency & LOW_LATENCY_DEBUGFS), |
1311 | mvmvif->low_latency_vcmd); | 1308 | !!(mvmvif->low_latency & LOW_LATENCY_VCMD)); |
1312 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | 1309 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); |
1313 | } | 1310 | } |
1314 | 1311 | ||
@@ -1506,44 +1503,36 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
1506 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM && | 1503 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM && |
1507 | ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) || | 1504 | ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) || |
1508 | (vif->type == NL80211_IFTYPE_STATION && vif->p2p))) | 1505 | (vif->type == NL80211_IFTYPE_STATION && vif->p2p))) |
1509 | MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR | | 1506 | MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, 0600); |
1510 | S_IRUSR); | 1507 | |
1511 | 1508 | MVM_DEBUGFS_ADD_FILE_VIF(tx_pwr_lmt, mvmvif->dbgfs_dir, 0400); | |
1512 | MVM_DEBUGFS_ADD_FILE_VIF(tx_pwr_lmt, mvmvif->dbgfs_dir, S_IRUSR); | 1509 | MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, 0400); |
1513 | MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, S_IRUSR); | 1510 | MVM_DEBUGFS_ADD_FILE_VIF(low_latency, mvmvif->dbgfs_dir, 0600); |
1514 | MVM_DEBUGFS_ADD_FILE_VIF(low_latency, mvmvif->dbgfs_dir, | 1511 | MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir, 0600); |
1515 | S_IRUSR | S_IWUSR); | 1512 | MVM_DEBUGFS_ADD_FILE_VIF(rx_phyinfo, mvmvif->dbgfs_dir, 0600); |
1516 | MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir, | 1513 | MVM_DEBUGFS_ADD_FILE_VIF(quota_min, mvmvif->dbgfs_dir, 0600); |
1517 | S_IRUSR | S_IWUSR); | 1514 | MVM_DEBUGFS_ADD_FILE_VIF(os_device_timediff, mvmvif->dbgfs_dir, 0400); |
1518 | MVM_DEBUGFS_ADD_FILE_VIF(rx_phyinfo, mvmvif->dbgfs_dir, | ||
1519 | S_IRUSR | S_IWUSR); | ||
1520 | MVM_DEBUGFS_ADD_FILE_VIF(quota_min, mvmvif->dbgfs_dir, | ||
1521 | S_IRUSR | S_IWUSR); | ||
1522 | MVM_DEBUGFS_ADD_FILE_VIF(os_device_timediff, | ||
1523 | mvmvif->dbgfs_dir, S_IRUSR); | ||
1524 | 1515 | ||
1525 | if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p && | 1516 | if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p && |
1526 | mvmvif == mvm->bf_allowed_vif) | 1517 | mvmvif == mvm->bf_allowed_vif) |
1527 | MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir, | 1518 | MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir, 0600); |
1528 | S_IRUSR | S_IWUSR); | ||
1529 | 1519 | ||
1530 | if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TOF_SUPPORT) && | 1520 | if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TOF_SUPPORT) && |
1531 | !vif->p2p && (vif->type != NL80211_IFTYPE_P2P_DEVICE)) { | 1521 | !vif->p2p && (vif->type != NL80211_IFTYPE_P2P_DEVICE)) { |
1532 | if (IWL_MVM_TOF_IS_RESPONDER && vif->type == NL80211_IFTYPE_AP) | 1522 | if (IWL_MVM_TOF_IS_RESPONDER && vif->type == NL80211_IFTYPE_AP) |
1533 | MVM_DEBUGFS_ADD_FILE_VIF(tof_responder_params, | 1523 | MVM_DEBUGFS_ADD_FILE_VIF(tof_responder_params, |
1534 | mvmvif->dbgfs_dir, | 1524 | mvmvif->dbgfs_dir, 0600); |
1535 | S_IRUSR | S_IWUSR); | ||
1536 | 1525 | ||
1537 | MVM_DEBUGFS_ADD_FILE_VIF(tof_range_request, mvmvif->dbgfs_dir, | 1526 | MVM_DEBUGFS_ADD_FILE_VIF(tof_range_request, mvmvif->dbgfs_dir, |
1538 | S_IRUSR | S_IWUSR); | 1527 | 0600); |
1539 | MVM_DEBUGFS_ADD_FILE_VIF(tof_range_req_ext, mvmvif->dbgfs_dir, | 1528 | MVM_DEBUGFS_ADD_FILE_VIF(tof_range_req_ext, mvmvif->dbgfs_dir, |
1540 | S_IRUSR | S_IWUSR); | 1529 | 0600); |
1541 | MVM_DEBUGFS_ADD_FILE_VIF(tof_enable, mvmvif->dbgfs_dir, | 1530 | MVM_DEBUGFS_ADD_FILE_VIF(tof_enable, mvmvif->dbgfs_dir, |
1542 | S_IRUSR | S_IWUSR); | 1531 | 0600); |
1543 | MVM_DEBUGFS_ADD_FILE_VIF(tof_range_abort, mvmvif->dbgfs_dir, | 1532 | MVM_DEBUGFS_ADD_FILE_VIF(tof_range_abort, mvmvif->dbgfs_dir, |
1544 | S_IRUSR | S_IWUSR); | 1533 | 0600); |
1545 | MVM_DEBUGFS_ADD_FILE_VIF(tof_range_response, mvmvif->dbgfs_dir, | 1534 | MVM_DEBUGFS_ADD_FILE_VIF(tof_range_response, mvmvif->dbgfs_dir, |
1546 | S_IRUSR); | 1535 | 0400); |
1547 | } | 1536 | } |
1548 | 1537 | ||
1549 | /* | 1538 | /* |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 9c436d8d001d..0e6401cd7ccc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | |||
@@ -1914,7 +1914,7 @@ void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw, | |||
1914 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | 1914 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); |
1915 | 1915 | ||
1916 | if (iwl_mvm_has_tlc_offload(mvm)) | 1916 | if (iwl_mvm_has_tlc_offload(mvm)) |
1917 | MVM_DEBUGFS_ADD_STA_FILE(rs_data, dir, S_IRUSR); | 1917 | MVM_DEBUGFS_ADD_STA_FILE(rs_data, dir, 0400); |
1918 | 1918 | ||
1919 | return; | 1919 | return; |
1920 | err: | 1920 | err: |
@@ -1930,48 +1930,45 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | |||
1930 | 1930 | ||
1931 | mvm->debugfs_dir = dbgfs_dir; | 1931 | mvm->debugfs_dir = dbgfs_dir; |
1932 | 1932 | ||
1933 | MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR); | 1933 | MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, 0200); |
1934 | MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); | 1934 | MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, 0200); |
1935 | MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); | 1935 | MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, 0600); |
1936 | MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, | 1936 | MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, 0600); |
1937 | S_IWUSR | S_IRUSR); | 1937 | MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, 0400); |
1938 | MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, S_IRUSR); | 1938 | MVM_DEBUGFS_ADD_FILE(ctdp_budget, dbgfs_dir, 0400); |
1939 | MVM_DEBUGFS_ADD_FILE(ctdp_budget, dbgfs_dir, S_IRUSR); | 1939 | MVM_DEBUGFS_ADD_FILE(stop_ctdp, dbgfs_dir, 0200); |
1940 | MVM_DEBUGFS_ADD_FILE(stop_ctdp, dbgfs_dir, S_IWUSR); | 1940 | MVM_DEBUGFS_ADD_FILE(force_ctkill, dbgfs_dir, 0200); |
1941 | MVM_DEBUGFS_ADD_FILE(force_ctkill, dbgfs_dir, S_IWUSR); | 1941 | MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, 0400); |
1942 | MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); | 1942 | MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, 0400); |
1943 | MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); | 1943 | MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, 0400); |
1944 | MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR); | 1944 | MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, 0600); |
1945 | MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, | 1945 | MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, 0400); |
1946 | S_IRUSR | S_IWUSR); | 1946 | MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, 0400); |
1947 | MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, S_IRUSR); | 1947 | MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, 0400); |
1948 | MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR); | 1948 | MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, 0200); |
1949 | MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, S_IRUSR); | 1949 | MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, 0200); |
1950 | MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); | 1950 | MVM_DEBUGFS_ADD_FILE(bt_tx_prio, mvm->debugfs_dir, 0200); |
1951 | MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR); | 1951 | MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, 0200); |
1952 | MVM_DEBUGFS_ADD_FILE(bt_tx_prio, mvm->debugfs_dir, S_IWUSR); | 1952 | MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600); |
1953 | MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, S_IWUSR); | 1953 | MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600); |
1954 | MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, | 1954 | MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, 0600); |
1955 | S_IWUSR | S_IRUSR); | 1955 | MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600); |
1956 | MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR); | 1956 | MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200); |
1957 | MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR); | 1957 | MVM_DEBUGFS_ADD_FILE(max_amsdu_len, mvm->debugfs_dir, 0200); |
1958 | MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR); | 1958 | MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200); |
1959 | MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR); | 1959 | MVM_DEBUGFS_ADD_FILE(cont_recording, mvm->debugfs_dir, 0200); |
1960 | MVM_DEBUGFS_ADD_FILE(max_amsdu_len, mvm->debugfs_dir, S_IWUSR); | 1960 | MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200); |
1961 | MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, S_IWUSR); | 1961 | MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200); |
1962 | MVM_DEBUGFS_ADD_FILE(cont_recording, mvm->debugfs_dir, S_IWUSR); | ||
1963 | MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, S_IWUSR); | ||
1964 | MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, S_IWUSR); | ||
1965 | #ifdef CONFIG_ACPI | 1962 | #ifdef CONFIG_ACPI |
1966 | MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, S_IRUSR); | 1963 | MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400); |
1967 | #endif | 1964 | #endif |
1968 | 1965 | ||
1969 | if (!debugfs_create_bool("enable_scan_iteration_notif", | 1966 | if (!debugfs_create_bool("enable_scan_iteration_notif", |
1970 | S_IRUSR | S_IWUSR, | 1967 | 0600, |
1971 | mvm->debugfs_dir, | 1968 | mvm->debugfs_dir, |
1972 | &mvm->scan_iter_notif_enabled)) | 1969 | &mvm->scan_iter_notif_enabled)) |
1973 | goto err; | 1970 | goto err; |
1974 | if (!debugfs_create_bool("drop_bcn_ap_mode", S_IRUSR | S_IWUSR, | 1971 | if (!debugfs_create_bool("drop_bcn_ap_mode", 0600, |
1975 | mvm->debugfs_dir, &mvm->drop_bcn_ap_mode)) | 1972 | mvm->debugfs_dir, &mvm->drop_bcn_ap_mode)) |
1976 | goto err; | 1973 | goto err; |
1977 | 1974 | ||
@@ -1982,50 +1979,49 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | |||
1982 | if (!bcast_dir) | 1979 | if (!bcast_dir) |
1983 | goto err; | 1980 | goto err; |
1984 | 1981 | ||
1985 | if (!debugfs_create_bool("override", S_IRUSR | S_IWUSR, | 1982 | if (!debugfs_create_bool("override", 0600, |
1986 | bcast_dir, | 1983 | bcast_dir, |
1987 | &mvm->dbgfs_bcast_filtering.override)) | 1984 | &mvm->dbgfs_bcast_filtering.override)) |
1988 | goto err; | 1985 | goto err; |
1989 | 1986 | ||
1990 | MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters, | 1987 | MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters, |
1991 | bcast_dir, S_IWUSR | S_IRUSR); | 1988 | bcast_dir, 0600); |
1992 | MVM_DEBUGFS_ADD_FILE_ALIAS("macs", bcast_filters_macs, | 1989 | MVM_DEBUGFS_ADD_FILE_ALIAS("macs", bcast_filters_macs, |
1993 | bcast_dir, S_IWUSR | S_IRUSR); | 1990 | bcast_dir, 0600); |
1994 | } | 1991 | } |
1995 | #endif | 1992 | #endif |
1996 | 1993 | ||
1997 | #ifdef CONFIG_PM_SLEEP | 1994 | #ifdef CONFIG_PM_SLEEP |
1998 | MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR); | 1995 | MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, 0600); |
1999 | MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR); | 1996 | MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400); |
2000 | if (!debugfs_create_bool("d3_wake_sysassert", S_IRUSR | S_IWUSR, | 1997 | if (!debugfs_create_bool("d3_wake_sysassert", 0600, |
2001 | mvm->debugfs_dir, &mvm->d3_wake_sysassert)) | 1998 | mvm->debugfs_dir, &mvm->d3_wake_sysassert)) |
2002 | goto err; | 1999 | goto err; |
2003 | if (!debugfs_create_u32("last_netdetect_scans", S_IRUSR, | 2000 | if (!debugfs_create_u32("last_netdetect_scans", 0400, |
2004 | mvm->debugfs_dir, &mvm->last_netdetect_scans)) | 2001 | mvm->debugfs_dir, &mvm->last_netdetect_scans)) |
2005 | goto err; | 2002 | goto err; |
2006 | #endif | 2003 | #endif |
2007 | 2004 | ||
2008 | if (!debugfs_create_u8("ps_disabled", S_IRUSR, | 2005 | if (!debugfs_create_u8("ps_disabled", 0400, |
2009 | mvm->debugfs_dir, &mvm->ps_disabled)) | 2006 | mvm->debugfs_dir, &mvm->ps_disabled)) |
2010 | goto err; | 2007 | goto err; |
2011 | if (!debugfs_create_blob("nvm_hw", S_IRUSR, | 2008 | if (!debugfs_create_blob("nvm_hw", 0400, |
2012 | mvm->debugfs_dir, &mvm->nvm_hw_blob)) | 2009 | mvm->debugfs_dir, &mvm->nvm_hw_blob)) |
2013 | goto err; | 2010 | goto err; |
2014 | if (!debugfs_create_blob("nvm_sw", S_IRUSR, | 2011 | if (!debugfs_create_blob("nvm_sw", 0400, |
2015 | mvm->debugfs_dir, &mvm->nvm_sw_blob)) | 2012 | mvm->debugfs_dir, &mvm->nvm_sw_blob)) |
2016 | goto err; | 2013 | goto err; |
2017 | if (!debugfs_create_blob("nvm_calib", S_IRUSR, | 2014 | if (!debugfs_create_blob("nvm_calib", 0400, |
2018 | mvm->debugfs_dir, &mvm->nvm_calib_blob)) | 2015 | mvm->debugfs_dir, &mvm->nvm_calib_blob)) |
2019 | goto err; | 2016 | goto err; |
2020 | if (!debugfs_create_blob("nvm_prod", S_IRUSR, | 2017 | if (!debugfs_create_blob("nvm_prod", 0400, |
2021 | mvm->debugfs_dir, &mvm->nvm_prod_blob)) | 2018 | mvm->debugfs_dir, &mvm->nvm_prod_blob)) |
2022 | goto err; | 2019 | goto err; |
2023 | if (!debugfs_create_blob("nvm_phy_sku", S_IRUSR, | 2020 | if (!debugfs_create_blob("nvm_phy_sku", 0400, |
2024 | mvm->debugfs_dir, &mvm->nvm_phy_sku_blob)) | 2021 | mvm->debugfs_dir, &mvm->nvm_phy_sku_blob)) |
2025 | goto err; | 2022 | goto err; |
2026 | 2023 | ||
2027 | debugfs_create_file("mem", S_IRUSR | S_IWUSR, dbgfs_dir, mvm, | 2024 | debugfs_create_file("mem", 0600, dbgfs_dir, mvm, &iwl_dbgfs_mem_ops); |
2028 | &iwl_dbgfs_mem_ops); | ||
2029 | 2025 | ||
2030 | /* | 2026 | /* |
2031 | * Create a symlink with mac80211. It will be removed when mac80211 | 2027 | * Create a symlink with mac80211. It will be removed when mac80211 |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 0920be637b57..3c59109bea20 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c | |||
@@ -433,6 +433,10 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) | |||
433 | 433 | ||
434 | /* Set parameters */ | 434 | /* Set parameters */ |
435 | phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_get_phy_config(mvm)); | 435 | phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_get_phy_config(mvm)); |
436 | |||
437 | /* set flags extra PHY configuration flags from the device's cfg */ | ||
438 | phy_cfg_cmd.phy_cfg |= cpu_to_le32(mvm->cfg->extra_phy_cfg_flags); | ||
439 | |||
436 | phy_cfg_cmd.calib_control.event_trigger = | 440 | phy_cfg_cmd.calib_control.event_trigger = |
437 | mvm->fw->default_calib[ucode_type].event_trigger; | 441 | mvm->fw->default_calib[ucode_type].event_trigger; |
438 | phy_cfg_cmd.calib_control.flow_trigger = | 442 | phy_cfg_cmd.calib_control.flow_trigger = |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index ebf511150f4d..51b30424575b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | |||
@@ -421,6 +421,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
421 | ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); | 421 | ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); |
422 | ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); | 422 | ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); |
423 | ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR); | 423 | ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR); |
424 | ieee80211_hw_set(hw, DEAUTH_NEED_MGD_TX_PREP); | ||
424 | 425 | ||
425 | if (iwl_mvm_has_tlc_offload(mvm)) { | 426 | if (iwl_mvm_has_tlc_offload(mvm)) { |
426 | ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW); | 427 | ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW); |
@@ -661,6 +662,17 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
661 | NL80211_EXT_FEATURE_SET_SCAN_DWELL); | 662 | NL80211_EXT_FEATURE_SET_SCAN_DWELL); |
662 | } | 663 | } |
663 | 664 | ||
665 | if (iwl_mvm_is_oce_supported(mvm)) { | ||
666 | wiphy_ext_feature_set(hw->wiphy, | ||
667 | NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP); | ||
668 | wiphy_ext_feature_set(hw->wiphy, | ||
669 | NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME); | ||
670 | wiphy_ext_feature_set(hw->wiphy, | ||
671 | NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION); | ||
672 | wiphy_ext_feature_set(hw->wiphy, | ||
673 | NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE); | ||
674 | } | ||
675 | |||
664 | mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 676 | mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
665 | 677 | ||
666 | #ifdef CONFIG_PM_SLEEP | 678 | #ifdef CONFIG_PM_SLEEP |
@@ -2132,10 +2144,10 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
2132 | * Send the bcast station. At this stage the TBTT and DTIM time | 2144 | * Send the bcast station. At this stage the TBTT and DTIM time |
2133 | * events are added and applied to the scheduler | 2145 | * events are added and applied to the scheduler |
2134 | */ | 2146 | */ |
2135 | iwl_mvm_send_add_bcast_sta(mvm, vif); | 2147 | ret = iwl_mvm_send_add_bcast_sta(mvm, vif); |
2136 | if (ret) | 2148 | if (ret) |
2137 | goto out_unbind; | 2149 | goto out_unbind; |
2138 | iwl_mvm_add_mcast_sta(mvm, vif); | 2150 | ret = iwl_mvm_add_mcast_sta(mvm, vif); |
2139 | if (ret) { | 2151 | if (ret) { |
2140 | iwl_mvm_send_rm_bcast_sta(mvm, vif); | 2152 | iwl_mvm_send_rm_bcast_sta(mvm, vif); |
2141 | goto out_unbind; | 2153 | goto out_unbind; |
@@ -2804,9 +2816,6 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, | |||
2804 | u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS; | 2816 | u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS; |
2805 | u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS; | 2817 | u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS; |
2806 | 2818 | ||
2807 | if (WARN_ON_ONCE(vif->bss_conf.assoc)) | ||
2808 | return; | ||
2809 | |||
2810 | /* | 2819 | /* |
2811 | * iwl_mvm_protect_session() reads directly from the device | 2820 | * iwl_mvm_protect_session() reads directly from the device |
2812 | * (the system time), so make sure it is available. | 2821 | * (the system time), so make sure it is available. |
@@ -3494,6 +3503,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, | |||
3494 | ret = 0; | 3503 | ret = 0; |
3495 | goto out; | 3504 | goto out; |
3496 | case NL80211_IFTYPE_STATION: | 3505 | case NL80211_IFTYPE_STATION: |
3506 | mvmvif->csa_bcn_pending = false; | ||
3497 | break; | 3507 | break; |
3498 | case NL80211_IFTYPE_MONITOR: | 3508 | case NL80211_IFTYPE_MONITOR: |
3499 | /* always disable PS when a monitor interface is active */ | 3509 | /* always disable PS when a monitor interface is active */ |
@@ -3537,7 +3547,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, | |||
3537 | } | 3547 | } |
3538 | 3548 | ||
3539 | if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) { | 3549 | if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) { |
3540 | u32 duration = 2 * vif->bss_conf.beacon_int; | 3550 | u32 duration = 3 * vif->bss_conf.beacon_int; |
3541 | 3551 | ||
3542 | /* iwl_mvm_protect_session() reads directly from the | 3552 | /* iwl_mvm_protect_session() reads directly from the |
3543 | * device (the system time), so make sure it is | 3553 | * device (the system time), so make sure it is |
@@ -3550,6 +3560,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, | |||
3550 | /* Protect the session to make sure we hear the first | 3560 | /* Protect the session to make sure we hear the first |
3551 | * beacon on the new channel. | 3561 | * beacon on the new channel. |
3552 | */ | 3562 | */ |
3563 | mvmvif->csa_bcn_pending = true; | ||
3553 | iwl_mvm_protect_session(mvm, vif, duration, duration, | 3564 | iwl_mvm_protect_session(mvm, vif, duration, duration, |
3554 | vif->bss_conf.beacon_int / 2, | 3565 | vif->bss_conf.beacon_int / 2, |
3555 | true); | 3566 | true); |
@@ -3988,6 +3999,7 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, | |||
3988 | if (vif->type == NL80211_IFTYPE_STATION) { | 3999 | if (vif->type == NL80211_IFTYPE_STATION) { |
3989 | struct iwl_mvm_sta *mvmsta; | 4000 | struct iwl_mvm_sta *mvmsta; |
3990 | 4001 | ||
4002 | mvmvif->csa_bcn_pending = false; | ||
3991 | mvmsta = iwl_mvm_sta_from_staid_protected(mvm, | 4003 | mvmsta = iwl_mvm_sta_from_staid_protected(mvm, |
3992 | mvmvif->ap_sta_id); | 4004 | mvmvif->ap_sta_id); |
3993 | 4005 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 89ff02d7c876..d2cf751db68d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | |||
@@ -300,6 +300,18 @@ enum iwl_bt_force_ant_mode { | |||
300 | }; | 300 | }; |
301 | 301 | ||
302 | /** | 302 | /** |
303 | * struct iwl_mvm_low_latency_cause - low latency set causes | ||
304 | * @LOW_LATENCY_TRAFFIC: indicates low latency traffic was detected | ||
305 | * @LOW_LATENCY_DEBUGFS: low latency mode set from debugfs | ||
306 | * @LOW_LATENCY_VCMD: low latency mode set from vendor command | ||
307 | */ | ||
308 | enum iwl_mvm_low_latency_cause { | ||
309 | LOW_LATENCY_TRAFFIC = BIT(0), | ||
310 | LOW_LATENCY_DEBUGFS = BIT(1), | ||
311 | LOW_LATENCY_VCMD = BIT(2), | ||
312 | }; | ||
313 | |||
314 | /** | ||
303 | * struct iwl_mvm_vif_bf_data - beacon filtering related data | 315 | * struct iwl_mvm_vif_bf_data - beacon filtering related data |
304 | * @bf_enabled: indicates if beacon filtering is enabled | 316 | * @bf_enabled: indicates if beacon filtering is enabled |
305 | * @ba_enabled: indicated if beacon abort is enabled | 317 | * @ba_enabled: indicated if beacon abort is enabled |
@@ -335,9 +347,8 @@ struct iwl_mvm_vif_bf_data { | |||
335 | * @pm_enabled - Indicate if MAC power management is allowed | 347 | * @pm_enabled - Indicate if MAC power management is allowed |
336 | * @monitor_active: indicates that monitor context is configured, and that the | 348 | * @monitor_active: indicates that monitor context is configured, and that the |
337 | * interface should get quota etc. | 349 | * interface should get quota etc. |
338 | * @low_latency_traffic: indicates low latency traffic was detected | 350 | * @low_latency: indicates low latency is set, see |
339 | * @low_latency_dbgfs: low latency mode set from debugfs | 351 | * enum &iwl_mvm_low_latency_cause for causes. |
340 | * @low_latency_vcmd: low latency mode set from vendor command | ||
341 | * @ps_disabled: indicates that this interface requires PS to be disabled | 352 | * @ps_disabled: indicates that this interface requires PS to be disabled |
342 | * @queue_params: QoS params for this MAC | 353 | * @queue_params: QoS params for this MAC |
343 | * @bcast_sta: station used for broadcast packets. Used by the following | 354 | * @bcast_sta: station used for broadcast packets. Used by the following |
@@ -367,7 +378,7 @@ struct iwl_mvm_vif { | |||
367 | bool ap_ibss_active; | 378 | bool ap_ibss_active; |
368 | bool pm_enabled; | 379 | bool pm_enabled; |
369 | bool monitor_active; | 380 | bool monitor_active; |
370 | bool low_latency_traffic, low_latency_dbgfs, low_latency_vcmd; | 381 | u8 low_latency; |
371 | bool ps_disabled; | 382 | bool ps_disabled; |
372 | struct iwl_mvm_vif_bf_data bf_data; | 383 | struct iwl_mvm_vif_bf_data bf_data; |
373 | 384 | ||
@@ -438,6 +449,9 @@ struct iwl_mvm_vif { | |||
438 | bool csa_failed; | 449 | bool csa_failed; |
439 | u16 csa_target_freq; | 450 | u16 csa_target_freq; |
440 | 451 | ||
452 | /* Indicates that we are waiting for a beacon on a new channel */ | ||
453 | bool csa_bcn_pending; | ||
454 | |||
441 | /* TCP Checksum Offload */ | 455 | /* TCP Checksum Offload */ |
442 | netdev_features_t features; | 456 | netdev_features_t features; |
443 | }; | 457 | }; |
@@ -1152,6 +1166,18 @@ static inline bool iwl_mvm_is_adaptive_dwell_supported(struct iwl_mvm *mvm) | |||
1152 | IWL_UCODE_TLV_API_ADAPTIVE_DWELL); | 1166 | IWL_UCODE_TLV_API_ADAPTIVE_DWELL); |
1153 | } | 1167 | } |
1154 | 1168 | ||
1169 | static inline bool iwl_mvm_is_adaptive_dwell_v2_supported(struct iwl_mvm *mvm) | ||
1170 | { | ||
1171 | return fw_has_api(&mvm->fw->ucode_capa, | ||
1172 | IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2); | ||
1173 | } | ||
1174 | |||
1175 | static inline bool iwl_mvm_is_oce_supported(struct iwl_mvm *mvm) | ||
1176 | { | ||
1177 | /* OCE should never be enabled for LMAC scan FWs */ | ||
1178 | return fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_OCE); | ||
1179 | } | ||
1180 | |||
1155 | static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm) | 1181 | static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm) |
1156 | { | 1182 | { |
1157 | /* For now we only use this mode to differentiate between | 1183 | /* For now we only use this mode to differentiate between |
@@ -1741,7 +1767,8 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm); | |||
1741 | 1767 | ||
1742 | /* Low latency */ | 1768 | /* Low latency */ |
1743 | int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1769 | int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
1744 | bool value); | 1770 | bool low_latency, |
1771 | enum iwl_mvm_low_latency_cause cause); | ||
1745 | /* get SystemLowLatencyMode - only needed for beacon threshold? */ | 1772 | /* get SystemLowLatencyMode - only needed for beacon threshold? */ |
1746 | bool iwl_mvm_low_latency(struct iwl_mvm *mvm); | 1773 | bool iwl_mvm_low_latency(struct iwl_mvm *mvm); |
1747 | /* get VMACLowLatencyMode */ | 1774 | /* get VMACLowLatencyMode */ |
@@ -1757,9 +1784,17 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif) | |||
1757 | * binding, so this has no real impact. For now, just return | 1784 | * binding, so this has no real impact. For now, just return |
1758 | * the current desired low-latency state. | 1785 | * the current desired low-latency state. |
1759 | */ | 1786 | */ |
1760 | return mvmvif->low_latency_dbgfs || | 1787 | return mvmvif->low_latency; |
1761 | mvmvif->low_latency_traffic || | 1788 | } |
1762 | mvmvif->low_latency_vcmd; | 1789 | |
1790 | static inline | ||
1791 | void iwl_mvm_vif_set_low_latency(struct iwl_mvm_vif *mvmvif, bool set, | ||
1792 | enum iwl_mvm_low_latency_cause cause) | ||
1793 | { | ||
1794 | if (set) | ||
1795 | mvmvif->low_latency |= cause; | ||
1796 | else | ||
1797 | mvmvif->low_latency &= ~cause; | ||
1763 | } | 1798 | } |
1764 | 1799 | ||
1765 | /* hw scheduler queue config */ | 1800 | /* hw scheduler queue config */ |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index ab7fb5aad984..224bfa1bcf53 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |||
@@ -104,14 +104,14 @@ struct iwl_mvm_mod_params iwlmvm_mod_params = { | |||
104 | /* rest of fields are 0 by default */ | 104 | /* rest of fields are 0 by default */ |
105 | }; | 105 | }; |
106 | 106 | ||
107 | module_param_named(init_dbg, iwlmvm_mod_params.init_dbg, bool, S_IRUGO); | 107 | module_param_named(init_dbg, iwlmvm_mod_params.init_dbg, bool, 0444); |
108 | MODULE_PARM_DESC(init_dbg, | 108 | MODULE_PARM_DESC(init_dbg, |
109 | "set to true to debug an ASSERT in INIT fw (default: false"); | 109 | "set to true to debug an ASSERT in INIT fw (default: false"); |
110 | module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO); | 110 | module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, 0444); |
111 | MODULE_PARM_DESC(power_scheme, | 111 | MODULE_PARM_DESC(power_scheme, |
112 | "power management scheme: 1-active, 2-balanced, 3-low power, default: 2"); | 112 | "power management scheme: 1-active, 2-balanced, 3-low power, default: 2"); |
113 | module_param_named(tfd_q_hang_detect, iwlmvm_mod_params.tfd_q_hang_detect, | 113 | module_param_named(tfd_q_hang_detect, iwlmvm_mod_params.tfd_q_hang_detect, |
114 | bool, S_IRUGO); | 114 | bool, 0444); |
115 | MODULE_PARM_DESC(tfd_q_hang_detect, | 115 | MODULE_PARM_DESC(tfd_q_hang_detect, |
116 | "TFD queues hang detection (default: true"); | 116 | "TFD queues hang detection (default: true"); |
117 | 117 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c index 305cd56bf746..7f5434b34d0d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | |||
@@ -8,6 +8,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 - 2014 Intel Mobile Communications GmbH |
10 | * Copyright(c) 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2017 Intel Deutschland GmbH |
11 | * Copyright(c) 2018 Intel Corporation | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
@@ -18,11 +19,6 @@ | |||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
19 | * General Public License for more details. | 20 | * General Public License for more details. |
20 | * | 21 | * |
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
24 | * USA | ||
25 | * | ||
26 | * The full GNU General Public License is included in this distribution | 22 | * The full GNU General Public License is included in this distribution |
27 | * in the file called COPYING. | 23 | * in the file called COPYING. |
28 | * | 24 | * |
@@ -34,6 +30,7 @@ | |||
34 | * | 30 | * |
35 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 31 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
36 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 32 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH |
33 | * Copyright(c) 2018 Intel Corporation | ||
37 | * All rights reserved. | 34 | * All rights reserved. |
38 | * | 35 | * |
39 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -286,6 +283,20 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt) | |||
286 | return; | 283 | return; |
287 | 284 | ||
288 | ctxt->ref--; | 285 | ctxt->ref--; |
286 | |||
287 | /* | ||
288 | * Move unused phy's to a default channel. When the phy is moved the, | ||
289 | * fw will cleanup immediate quiet bit if it was previously set, | ||
290 | * otherwise we might not be able to reuse this phy. | ||
291 | */ | ||
292 | if (ctxt->ref == 0) { | ||
293 | struct ieee80211_channel *chan; | ||
294 | struct cfg80211_chan_def chandef; | ||
295 | |||
296 | chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0]; | ||
297 | cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT); | ||
298 | iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1); | ||
299 | } | ||
289 | } | 300 | } |
290 | 301 | ||
291 | static void iwl_mvm_binding_iterator(void *_data, u8 *mac, | 302 | static void iwl_mvm_binding_iterator(void *_data, u8 *mac, |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index 55d1274c6092..fb5745660509 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c | |||
@@ -234,13 +234,15 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) | |||
234 | struct iwl_mvm_sta *mvmsta; | 234 | struct iwl_mvm_sta *mvmsta; |
235 | struct iwl_lq_sta_rs_fw *lq_sta; | 235 | struct iwl_lq_sta_rs_fw *lq_sta; |
236 | 236 | ||
237 | rcu_read_lock(); | ||
238 | |||
237 | notif = (void *)pkt->data; | 239 | notif = (void *)pkt->data; |
238 | mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, notif->sta_id); | 240 | mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, notif->sta_id); |
239 | 241 | ||
240 | if (!mvmsta) { | 242 | if (!mvmsta) { |
241 | IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n", | 243 | IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n", |
242 | notif->sta_id); | 244 | notif->sta_id); |
243 | return; | 245 | goto out; |
244 | } | 246 | } |
245 | 247 | ||
246 | lq_sta = &mvmsta->lq_sta.rs_fw; | 248 | lq_sta = &mvmsta->lq_sta.rs_fw; |
@@ -251,6 +253,8 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) | |||
251 | IWL_DEBUG_RATE(mvm, "new rate_n_flags: 0x%X\n", | 253 | IWL_DEBUG_RATE(mvm, "new rate_n_flags: 0x%X\n", |
252 | lq_sta->last_rate_n_flags); | 254 | lq_sta->last_rate_n_flags); |
253 | } | 255 | } |
256 | out: | ||
257 | rcu_read_unlock(); | ||
254 | } | 258 | } |
255 | 259 | ||
256 | void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | 260 | void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 47f4c7a1d80d..5d776ec1840f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c | |||
@@ -4010,18 +4010,18 @@ static void rs_drv_add_sta_debugfs(void *mvm, void *priv_sta, | |||
4010 | if (!mvmsta->vif) | 4010 | if (!mvmsta->vif) |
4011 | return; | 4011 | return; |
4012 | 4012 | ||
4013 | debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, | 4013 | debugfs_create_file("rate_scale_table", 0600, dir, |
4014 | lq_sta, &rs_sta_dbgfs_scale_table_ops); | 4014 | lq_sta, &rs_sta_dbgfs_scale_table_ops); |
4015 | debugfs_create_file("rate_stats_table", S_IRUSR, dir, | 4015 | debugfs_create_file("rate_stats_table", 0400, dir, |
4016 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 4016 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
4017 | debugfs_create_file("drv_tx_stats", S_IRUSR | S_IWUSR, dir, | 4017 | debugfs_create_file("drv_tx_stats", 0600, dir, |
4018 | lq_sta, &rs_sta_dbgfs_drv_tx_stats_ops); | 4018 | lq_sta, &rs_sta_dbgfs_drv_tx_stats_ops); |
4019 | debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir, | 4019 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, |
4020 | &lq_sta->tx_agg_tid_en); | 4020 | &lq_sta->tx_agg_tid_en); |
4021 | debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir, | 4021 | debugfs_create_u8("reduced_tpc", 0600, dir, |
4022 | &lq_sta->pers.dbg_fixed_txp_reduction); | 4022 | &lq_sta->pers.dbg_fixed_txp_reduction); |
4023 | 4023 | ||
4024 | MVM_DEBUGFS_ADD_FILE_RS(ss_force, dir, S_IRUSR | S_IWUSR); | 4024 | MVM_DEBUGFS_ADD_FILE_RS(ss_force, dir, 0600); |
4025 | return; | 4025 | return; |
4026 | err: | 4026 | err: |
4027 | IWL_ERR((struct iwl_mvm *)mvm, "Can't create debugfs entity\n"); | 4027 | IWL_ERR((struct iwl_mvm *)mvm, "Can't create debugfs entity\n"); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 580de5851fc7..4a4ccfd11e5b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | |||
@@ -831,6 +831,16 @@ out: | |||
831 | rcu_read_unlock(); | 831 | rcu_read_unlock(); |
832 | } | 832 | } |
833 | 833 | ||
834 | static void iwl_mvm_flip_address(u8 *addr) | ||
835 | { | ||
836 | int i; | ||
837 | u8 mac_addr[ETH_ALEN]; | ||
838 | |||
839 | for (i = 0; i < ETH_ALEN; i++) | ||
840 | mac_addr[i] = addr[ETH_ALEN - i - 1]; | ||
841 | ether_addr_copy(addr, mac_addr); | ||
842 | } | ||
843 | |||
834 | void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, | 844 | void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, |
835 | struct iwl_rx_cmd_buffer *rxb, int queue) | 845 | struct iwl_rx_cmd_buffer *rxb, int queue) |
836 | { | 846 | { |
@@ -985,21 +995,16 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, | |||
985 | */ | 995 | */ |
986 | if ((desc->mac_flags2 & IWL_RX_MPDU_MFLG2_AMSDU) && | 996 | if ((desc->mac_flags2 & IWL_RX_MPDU_MFLG2_AMSDU) && |
987 | !WARN_ON(!ieee80211_is_data_qos(hdr->frame_control))) { | 997 | !WARN_ON(!ieee80211_is_data_qos(hdr->frame_control))) { |
988 | int i; | ||
989 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 998 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
990 | u8 mac_addr[ETH_ALEN]; | ||
991 | 999 | ||
992 | *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; | 1000 | *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; |
993 | 1001 | ||
994 | for (i = 0; i < ETH_ALEN; i++) | 1002 | if (mvm->trans->cfg->device_family == |
995 | mac_addr[i] = hdr->addr3[ETH_ALEN - i - 1]; | 1003 | IWL_DEVICE_FAMILY_9000) { |
996 | ether_addr_copy(hdr->addr3, mac_addr); | 1004 | iwl_mvm_flip_address(hdr->addr3); |
997 | 1005 | ||
998 | if (ieee80211_has_a4(hdr->frame_control)) { | 1006 | if (ieee80211_has_a4(hdr->frame_control)) |
999 | for (i = 0; i < ETH_ALEN; i++) | 1007 | iwl_mvm_flip_address(hdr->addr4); |
1000 | mac_addr[i] = | ||
1001 | hdr->addr4[ETH_ALEN - i - 1]; | ||
1002 | ether_addr_copy(hdr->addr4, mac_addr); | ||
1003 | } | 1008 | } |
1004 | } | 1009 | } |
1005 | if (baid != IWL_RX_REORDER_DATA_INVALID_BAID) { | 1010 | if (baid != IWL_RX_REORDER_DATA_INVALID_BAID) { |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 356b16f40e78..b31f0ffbbbf0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c | |||
@@ -35,6 +35,7 @@ | |||
35 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 35 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
36 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 36 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
37 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 37 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
38 | * Copyright(c) 2018 Intel Corporation | ||
38 | * All rights reserved. | 39 | * All rights reserved. |
39 | * | 40 | * |
40 | * Redistribution and use in source and binary forms, with or without | 41 | * Redistribution and use in source and binary forms, with or without |
@@ -85,6 +86,17 @@ enum iwl_mvm_traffic_load { | |||
85 | #define IWL_SCAN_DWELL_PASSIVE 110 | 86 | #define IWL_SCAN_DWELL_PASSIVE 110 |
86 | #define IWL_SCAN_DWELL_FRAGMENTED 44 | 87 | #define IWL_SCAN_DWELL_FRAGMENTED 44 |
87 | #define IWL_SCAN_DWELL_EXTENDED 90 | 88 | #define IWL_SCAN_DWELL_EXTENDED 90 |
89 | #define IWL_SCAN_NUM_OF_FRAGS 3 | ||
90 | |||
91 | |||
92 | /* adaptive dwell max budget time [TU] for full scan */ | ||
93 | #define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300 | ||
94 | /* adaptive dwell max budget time [TU] for directed scan */ | ||
95 | #define IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN 100 | ||
96 | /* adaptive dwell default APs number */ | ||
97 | #define IWL_SCAN_ADWELL_DEFAULT_N_APS 2 | ||
98 | /* adaptive dwell default APs number in social channels (1, 6, 11) */ | ||
99 | #define IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10 | ||
88 | 100 | ||
89 | struct iwl_mvm_scan_timing_params { | 101 | struct iwl_mvm_scan_timing_params { |
90 | u32 suspend_time; | 102 | u32 suspend_time; |
@@ -134,6 +146,9 @@ static inline void *iwl_mvm_get_scan_req_umac_data(struct iwl_mvm *mvm) | |||
134 | { | 146 | { |
135 | struct iwl_scan_req_umac *cmd = mvm->scan_cmd; | 147 | struct iwl_scan_req_umac *cmd = mvm->scan_cmd; |
136 | 148 | ||
149 | if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) | ||
150 | return (void *)&cmd->v8.data; | ||
151 | |||
137 | if (iwl_mvm_is_adaptive_dwell_supported(mvm)) | 152 | if (iwl_mvm_is_adaptive_dwell_supported(mvm)) |
138 | return (void *)&cmd->v7.data; | 153 | return (void *)&cmd->v7.data; |
139 | 154 | ||
@@ -143,6 +158,23 @@ static inline void *iwl_mvm_get_scan_req_umac_data(struct iwl_mvm *mvm) | |||
143 | return (void *)&cmd->v1.data; | 158 | return (void *)&cmd->v1.data; |
144 | } | 159 | } |
145 | 160 | ||
161 | static inline struct iwl_scan_umac_chan_param * | ||
162 | iwl_mvm_get_scan_req_umac_channel(struct iwl_mvm *mvm) | ||
163 | { | ||
164 | struct iwl_scan_req_umac *cmd = mvm->scan_cmd; | ||
165 | |||
166 | if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) | ||
167 | return &cmd->v8.channel; | ||
168 | |||
169 | if (iwl_mvm_is_adaptive_dwell_supported(mvm)) | ||
170 | return &cmd->v7.channel; | ||
171 | |||
172 | if (iwl_mvm_has_new_tx_api(mvm)) | ||
173 | return &cmd->v6.channel; | ||
174 | |||
175 | return &cmd->v1.channel; | ||
176 | } | ||
177 | |||
146 | static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm) | 178 | static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm) |
147 | { | 179 | { |
148 | if (mvm->scan_rx_ant != ANT_NONE) | 180 | if (mvm->scan_rx_ant != ANT_NONE) |
@@ -1113,66 +1145,92 @@ static void iwl_mvm_scan_umac_dwell(struct iwl_mvm *mvm, | |||
1113 | struct iwl_scan_req_umac *cmd, | 1145 | struct iwl_scan_req_umac *cmd, |
1114 | struct iwl_mvm_scan_params *params) | 1146 | struct iwl_mvm_scan_params *params) |
1115 | { | 1147 | { |
1116 | struct iwl_mvm_scan_timing_params *timing = &scan_timing[params->type]; | 1148 | struct iwl_mvm_scan_timing_params *timing, *hb_timing; |
1149 | u8 active_dwell, passive_dwell; | ||
1117 | 1150 | ||
1118 | if (iwl_mvm_is_regular_scan(params)) | 1151 | timing = &scan_timing[params->type]; |
1119 | cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6); | 1152 | active_dwell = params->measurement_dwell ? |
1120 | else | 1153 | params->measurement_dwell : IWL_SCAN_DWELL_ACTIVE; |
1121 | cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_2); | 1154 | passive_dwell = params->measurement_dwell ? |
1155 | params->measurement_dwell : IWL_SCAN_DWELL_PASSIVE; | ||
1122 | 1156 | ||
1123 | if (iwl_mvm_is_adaptive_dwell_supported(mvm)) { | 1157 | if (iwl_mvm_is_adaptive_dwell_supported(mvm)) { |
1124 | if (params->measurement_dwell) { | 1158 | cmd->v7.adwell_default_n_aps_social = |
1125 | cmd->v7.active_dwell = params->measurement_dwell; | 1159 | IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL; |
1126 | cmd->v7.passive_dwell = params->measurement_dwell; | 1160 | cmd->v7.adwell_default_n_aps = |
1127 | } else { | 1161 | IWL_SCAN_ADWELL_DEFAULT_N_APS; |
1128 | cmd->v7.active_dwell = IWL_SCAN_DWELL_ACTIVE; | 1162 | |
1129 | cmd->v7.passive_dwell = IWL_SCAN_DWELL_PASSIVE; | 1163 | /* if custom max budget was configured with debugfs */ |
1130 | } | 1164 | if (IWL_MVM_ADWELL_MAX_BUDGET) |
1131 | cmd->v7.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED; | 1165 | cmd->v7.adwell_max_budget = |
1166 | cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET); | ||
1167 | else if (params->ssids && params->ssids[0].ssid_len) | ||
1168 | cmd->v7.adwell_max_budget = | ||
1169 | cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN); | ||
1170 | else | ||
1171 | cmd->v7.adwell_max_budget = | ||
1172 | cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN); | ||
1132 | 1173 | ||
1133 | cmd->v7.scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6); | 1174 | cmd->v7.scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6); |
1134 | cmd->v7.max_out_time[SCAN_LB_LMAC_IDX] = | 1175 | cmd->v7.max_out_time[SCAN_LB_LMAC_IDX] = |
1135 | cpu_to_le32(timing->max_out_time); | 1176 | cpu_to_le32(timing->max_out_time); |
1136 | cmd->v7.suspend_time[SCAN_LB_LMAC_IDX] = | 1177 | cmd->v7.suspend_time[SCAN_LB_LMAC_IDX] = |
1137 | cpu_to_le32(timing->suspend_time); | 1178 | cpu_to_le32(timing->suspend_time); |
1179 | |||
1138 | if (iwl_mvm_is_cdb_supported(mvm)) { | 1180 | if (iwl_mvm_is_cdb_supported(mvm)) { |
1181 | hb_timing = &scan_timing[params->type]; | ||
1182 | |||
1139 | cmd->v7.max_out_time[SCAN_HB_LMAC_IDX] = | 1183 | cmd->v7.max_out_time[SCAN_HB_LMAC_IDX] = |
1140 | cpu_to_le32(timing->max_out_time); | 1184 | cpu_to_le32(hb_timing->max_out_time); |
1141 | cmd->v7.suspend_time[SCAN_HB_LMAC_IDX] = | 1185 | cmd->v7.suspend_time[SCAN_HB_LMAC_IDX] = |
1142 | cpu_to_le32(timing->suspend_time); | 1186 | cpu_to_le32(hb_timing->suspend_time); |
1143 | } | 1187 | } |
1144 | 1188 | ||
1145 | return; | 1189 | if (!iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) { |
1146 | } | 1190 | cmd->v7.active_dwell = active_dwell; |
1147 | 1191 | cmd->v7.passive_dwell = passive_dwell; | |
1148 | if (params->measurement_dwell) { | 1192 | cmd->v7.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED; |
1149 | cmd->v1.active_dwell = params->measurement_dwell; | 1193 | } else { |
1150 | cmd->v1.passive_dwell = params->measurement_dwell; | 1194 | cmd->v8.active_dwell[SCAN_LB_LMAC_IDX] = active_dwell; |
1151 | cmd->v1.extended_dwell = params->measurement_dwell; | 1195 | cmd->v8.passive_dwell[SCAN_LB_LMAC_IDX] = passive_dwell; |
1196 | if (iwl_mvm_is_cdb_supported(mvm)) { | ||
1197 | cmd->v8.active_dwell[SCAN_HB_LMAC_IDX] = | ||
1198 | active_dwell; | ||
1199 | cmd->v8.passive_dwell[SCAN_HB_LMAC_IDX] = | ||
1200 | passive_dwell; | ||
1201 | } | ||
1202 | } | ||
1152 | } else { | 1203 | } else { |
1153 | cmd->v1.active_dwell = IWL_SCAN_DWELL_ACTIVE; | 1204 | cmd->v1.extended_dwell = params->measurement_dwell ? |
1154 | cmd->v1.passive_dwell = IWL_SCAN_DWELL_PASSIVE; | 1205 | params->measurement_dwell : IWL_SCAN_DWELL_EXTENDED; |
1155 | cmd->v1.extended_dwell = IWL_SCAN_DWELL_EXTENDED; | 1206 | cmd->v1.active_dwell = active_dwell; |
1156 | } | 1207 | cmd->v1.passive_dwell = passive_dwell; |
1157 | cmd->v1.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED; | 1208 | cmd->v1.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED; |
1158 | 1209 | ||
1159 | if (iwl_mvm_has_new_tx_api(mvm)) { | ||
1160 | cmd->v6.scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6); | ||
1161 | cmd->v6.max_out_time[SCAN_LB_LMAC_IDX] = | ||
1162 | cpu_to_le32(timing->max_out_time); | ||
1163 | cmd->v6.suspend_time[SCAN_LB_LMAC_IDX] = | ||
1164 | cpu_to_le32(timing->suspend_time); | ||
1165 | if (iwl_mvm_is_cdb_supported(mvm)) { | 1210 | if (iwl_mvm_is_cdb_supported(mvm)) { |
1211 | hb_timing = &scan_timing[params->type]; | ||
1212 | |||
1166 | cmd->v6.max_out_time[SCAN_HB_LMAC_IDX] = | 1213 | cmd->v6.max_out_time[SCAN_HB_LMAC_IDX] = |
1167 | cpu_to_le32(timing->max_out_time); | 1214 | cpu_to_le32(hb_timing->max_out_time); |
1168 | cmd->v6.suspend_time[SCAN_HB_LMAC_IDX] = | 1215 | cmd->v6.suspend_time[SCAN_HB_LMAC_IDX] = |
1216 | cpu_to_le32(hb_timing->suspend_time); | ||
1217 | } | ||
1218 | |||
1219 | if (iwl_mvm_has_new_tx_api(mvm)) { | ||
1220 | cmd->v6.scan_priority = | ||
1221 | cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6); | ||
1222 | cmd->v6.max_out_time[SCAN_LB_LMAC_IDX] = | ||
1223 | cpu_to_le32(timing->max_out_time); | ||
1224 | cmd->v6.suspend_time[SCAN_LB_LMAC_IDX] = | ||
1225 | cpu_to_le32(timing->suspend_time); | ||
1226 | } else { | ||
1227 | cmd->v1.scan_priority = | ||
1228 | cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6); | ||
1229 | cmd->v1.max_out_time = | ||
1230 | cpu_to_le32(timing->max_out_time); | ||
1231 | cmd->v1.suspend_time = | ||
1169 | cpu_to_le32(timing->suspend_time); | 1232 | cpu_to_le32(timing->suspend_time); |
1170 | } | 1233 | } |
1171 | } else { | ||
1172 | cmd->v1.max_out_time = cpu_to_le32(timing->max_out_time); | ||
1173 | cmd->v1.suspend_time = cpu_to_le32(timing->suspend_time); | ||
1174 | cmd->v1.scan_priority = | ||
1175 | cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6); | ||
1176 | } | 1234 | } |
1177 | } | 1235 | } |
1178 | 1236 | ||
@@ -1234,11 +1292,39 @@ static u16 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm, | |||
1234 | if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED) | 1292 | if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED) |
1235 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE; | 1293 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE; |
1236 | 1294 | ||
1295 | if (iwl_mvm_is_adaptive_dwell_supported(mvm) && IWL_MVM_ADWELL_ENABLE && | ||
1296 | vif->type != NL80211_IFTYPE_P2P_DEVICE) | ||
1297 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_ADAPTIVE_DWELL; | ||
1298 | |||
1299 | /* | ||
1300 | * Extended dwell is relevant only for low band to start with, as it is | ||
1301 | * being used for social channles only (1, 6, 11), so we can check | ||
1302 | * only scan type on low band also for CDB. | ||
1303 | */ | ||
1237 | if (iwl_mvm_is_regular_scan(params) && | 1304 | if (iwl_mvm_is_regular_scan(params) && |
1238 | vif->type != NL80211_IFTYPE_P2P_DEVICE && | 1305 | vif->type != NL80211_IFTYPE_P2P_DEVICE && |
1239 | params->type != IWL_SCAN_TYPE_FRAGMENTED) | 1306 | params->type != IWL_SCAN_TYPE_FRAGMENTED && |
1307 | !iwl_mvm_is_adaptive_dwell_supported(mvm) && | ||
1308 | !iwl_mvm_is_oce_supported(mvm)) | ||
1240 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL; | 1309 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL; |
1241 | 1310 | ||
1311 | if (iwl_mvm_is_oce_supported(mvm)) { | ||
1312 | if ((params->flags & | ||
1313 | NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE)) | ||
1314 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_PROB_REQ_HIGH_TX_RATE; | ||
1315 | /* Since IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL and | ||
1316 | * NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION shares | ||
1317 | * the same bit, we need to make sure that we use this bit here | ||
1318 | * only when IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL cannot be | ||
1319 | * used. */ | ||
1320 | if ((params->flags & | ||
1321 | NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) && | ||
1322 | !WARN_ON_ONCE(!iwl_mvm_is_adaptive_dwell_supported(mvm))) | ||
1323 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_PROB_REQ_DEFER_SUPP; | ||
1324 | if ((params->flags & NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME)) | ||
1325 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_MAX_CHNL_TIME; | ||
1326 | } | ||
1327 | |||
1242 | return flags; | 1328 | return flags; |
1243 | } | 1329 | } |
1244 | 1330 | ||
@@ -1247,6 +1333,7 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
1247 | int type) | 1333 | int type) |
1248 | { | 1334 | { |
1249 | struct iwl_scan_req_umac *cmd = mvm->scan_cmd; | 1335 | struct iwl_scan_req_umac *cmd = mvm->scan_cmd; |
1336 | struct iwl_scan_umac_chan_param *chan_param; | ||
1250 | void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm); | 1337 | void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm); |
1251 | struct iwl_scan_req_umac_tail *sec_part = cmd_data + | 1338 | struct iwl_scan_req_umac_tail *sec_part = cmd_data + |
1252 | sizeof(struct iwl_scan_channel_cfg_umac) * | 1339 | sizeof(struct iwl_scan_channel_cfg_umac) * |
@@ -1254,8 +1341,11 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
1254 | int uid, i; | 1341 | int uid, i; |
1255 | u32 ssid_bitmap = 0; | 1342 | u32 ssid_bitmap = 0; |
1256 | u8 channel_flags = 0; | 1343 | u8 channel_flags = 0; |
1344 | u16 gen_flags; | ||
1257 | struct iwl_mvm_vif *scan_vif = iwl_mvm_vif_from_mac80211(vif); | 1345 | struct iwl_mvm_vif *scan_vif = iwl_mvm_vif_from_mac80211(vif); |
1258 | 1346 | ||
1347 | chan_param = iwl_mvm_get_scan_req_umac_channel(mvm); | ||
1348 | |||
1259 | lockdep_assert_held(&mvm->mutex); | 1349 | lockdep_assert_held(&mvm->mutex); |
1260 | 1350 | ||
1261 | if (WARN_ON(params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS)) | 1351 | if (WARN_ON(params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS)) |
@@ -1272,8 +1362,17 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
1272 | mvm->scan_uid_status[uid] = type; | 1362 | mvm->scan_uid_status[uid] = type; |
1273 | 1363 | ||
1274 | cmd->uid = cpu_to_le32(uid); | 1364 | cmd->uid = cpu_to_le32(uid); |
1275 | cmd->general_flags = cpu_to_le16(iwl_mvm_scan_umac_flags(mvm, params, | 1365 | gen_flags = iwl_mvm_scan_umac_flags(mvm, params, vif); |
1276 | vif)); | 1366 | cmd->general_flags = cpu_to_le16(gen_flags); |
1367 | if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) { | ||
1368 | if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED) | ||
1369 | cmd->v8.num_of_fragments[SCAN_LB_LMAC_IDX] = | ||
1370 | IWL_SCAN_NUM_OF_FRAGS; | ||
1371 | if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED) | ||
1372 | cmd->v8.num_of_fragments[SCAN_HB_LMAC_IDX] = | ||
1373 | IWL_SCAN_NUM_OF_FRAGS; | ||
1374 | } | ||
1375 | |||
1277 | cmd->scan_start_mac_id = scan_vif->id; | 1376 | cmd->scan_start_mac_id = scan_vif->id; |
1278 | 1377 | ||
1279 | if (type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT) | 1378 | if (type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT) |
@@ -1284,16 +1383,8 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
1284 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | 1383 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | |
1285 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD; | 1384 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD; |
1286 | 1385 | ||
1287 | if (iwl_mvm_is_adaptive_dwell_supported(mvm)) { | 1386 | chan_param->flags = channel_flags; |
1288 | cmd->v7.channel_flags = channel_flags; | 1387 | chan_param->count = params->n_channels; |
1289 | cmd->v7.n_channels = params->n_channels; | ||
1290 | } else if (iwl_mvm_has_new_tx_api(mvm)) { | ||
1291 | cmd->v6.channel_flags = channel_flags; | ||
1292 | cmd->v6.n_channels = params->n_channels; | ||
1293 | } else { | ||
1294 | cmd->v1.channel_flags = channel_flags; | ||
1295 | cmd->v1.n_channels = params->n_channels; | ||
1296 | } | ||
1297 | 1388 | ||
1298 | iwl_scan_build_ssids(params, sec_part->direct_scan, &ssid_bitmap); | 1389 | iwl_scan_build_ssids(params, sec_part->direct_scan, &ssid_bitmap); |
1299 | 1390 | ||
@@ -1732,7 +1823,9 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm) | |||
1732 | { | 1823 | { |
1733 | int base_size = IWL_SCAN_REQ_UMAC_SIZE_V1; | 1824 | int base_size = IWL_SCAN_REQ_UMAC_SIZE_V1; |
1734 | 1825 | ||
1735 | if (iwl_mvm_is_adaptive_dwell_supported(mvm)) | 1826 | if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) |
1827 | base_size = IWL_SCAN_REQ_UMAC_SIZE_V8; | ||
1828 | else if (iwl_mvm_is_adaptive_dwell_supported(mvm)) | ||
1736 | base_size = IWL_SCAN_REQ_UMAC_SIZE_V7; | 1829 | base_size = IWL_SCAN_REQ_UMAC_SIZE_V7; |
1737 | else if (iwl_mvm_has_new_tx_api(mvm)) | 1830 | else if (iwl_mvm_has_new_tx_api(mvm)) |
1738 | base_size = IWL_SCAN_REQ_UMAC_SIZE_V6; | 1831 | base_size = IWL_SCAN_REQ_UMAC_SIZE_V6; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 630e23cb0ffb..80067eb9ea05 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c | |||
@@ -1695,7 +1695,8 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, | |||
1695 | u32 qmask, enum nl80211_iftype iftype, | 1695 | u32 qmask, enum nl80211_iftype iftype, |
1696 | enum iwl_sta_type type) | 1696 | enum iwl_sta_type type) |
1697 | { | 1697 | { |
1698 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { | 1698 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) || |
1699 | sta->sta_id == IWL_MVM_INVALID_STA) { | ||
1699 | sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype); | 1700 | sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype); |
1700 | if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_INVALID_STA)) | 1701 | if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_INVALID_STA)) |
1701 | return -ENOSPC; | 1702 | return -ENOSPC; |
@@ -2478,28 +2479,12 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
2478 | 2479 | ||
2479 | /* | 2480 | /* |
2480 | * Note the possible cases: | 2481 | * Note the possible cases: |
2481 | * 1. In DQA mode with an enabled TXQ - TXQ needs to become agg'ed | 2482 | * 1. An enabled TXQ - TXQ needs to become agg'ed |
2482 | * 2. Non-DQA mode: the TXQ hasn't yet been enabled, so find a free | 2483 | * 2. The TXQ hasn't yet been enabled, so find a free one and mark |
2483 | * one and mark it as reserved | 2484 | * it as reserved |
2484 | * 3. In DQA mode, but no traffic yet on this TID: same treatment as in | ||
2485 | * non-DQA mode, since the TXQ hasn't yet been allocated | ||
2486 | * Don't support case 3 for new TX path as it is not expected to happen | ||
2487 | * and aggregation will be offloaded soon anyway | ||
2488 | */ | 2485 | */ |
2489 | txq_id = mvmsta->tid_data[tid].txq_id; | 2486 | txq_id = mvmsta->tid_data[tid].txq_id; |
2490 | if (iwl_mvm_has_new_tx_api(mvm)) { | 2487 | if (txq_id == IWL_MVM_INVALID_QUEUE) { |
2491 | if (txq_id == IWL_MVM_INVALID_QUEUE) { | ||
2492 | ret = -ENXIO; | ||
2493 | goto release_locks; | ||
2494 | } | ||
2495 | } else if (unlikely(mvm->queue_info[txq_id].status == | ||
2496 | IWL_MVM_QUEUE_SHARED)) { | ||
2497 | ret = -ENXIO; | ||
2498 | IWL_DEBUG_TX_QUEUES(mvm, | ||
2499 | "Can't start tid %d agg on shared queue!\n", | ||
2500 | tid); | ||
2501 | goto release_locks; | ||
2502 | } else if (mvm->queue_info[txq_id].status != IWL_MVM_QUEUE_READY) { | ||
2503 | txq_id = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id, | 2488 | txq_id = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id, |
2504 | IWL_MVM_DQA_MIN_DATA_QUEUE, | 2489 | IWL_MVM_DQA_MIN_DATA_QUEUE, |
2505 | IWL_MVM_DQA_MAX_DATA_QUEUE); | 2490 | IWL_MVM_DQA_MAX_DATA_QUEUE); |
@@ -2508,16 +2493,16 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
2508 | IWL_ERR(mvm, "Failed to allocate agg queue\n"); | 2493 | IWL_ERR(mvm, "Failed to allocate agg queue\n"); |
2509 | goto release_locks; | 2494 | goto release_locks; |
2510 | } | 2495 | } |
2511 | /* | ||
2512 | * TXQ shouldn't be in inactive mode for non-DQA, so getting | ||
2513 | * an inactive queue from iwl_mvm_find_free_queue() is | ||
2514 | * certainly a bug | ||
2515 | */ | ||
2516 | WARN_ON(mvm->queue_info[txq_id].status == | ||
2517 | IWL_MVM_QUEUE_INACTIVE); | ||
2518 | 2496 | ||
2519 | /* TXQ hasn't yet been enabled, so mark it only as reserved */ | 2497 | /* TXQ hasn't yet been enabled, so mark it only as reserved */ |
2520 | mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED; | 2498 | mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED; |
2499 | } else if (unlikely(mvm->queue_info[txq_id].status == | ||
2500 | IWL_MVM_QUEUE_SHARED)) { | ||
2501 | ret = -ENXIO; | ||
2502 | IWL_DEBUG_TX_QUEUES(mvm, | ||
2503 | "Can't start tid %d agg on shared queue!\n", | ||
2504 | tid); | ||
2505 | goto release_locks; | ||
2521 | } | 2506 | } |
2522 | 2507 | ||
2523 | spin_unlock(&mvm->queue_info_lock); | 2508 | spin_unlock(&mvm->queue_info_lock); |
@@ -2696,8 +2681,10 @@ out: | |||
2696 | 2681 | ||
2697 | static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm, | 2682 | static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm, |
2698 | struct iwl_mvm_sta *mvmsta, | 2683 | struct iwl_mvm_sta *mvmsta, |
2699 | u16 txq_id) | 2684 | struct iwl_mvm_tid_data *tid_data) |
2700 | { | 2685 | { |
2686 | u16 txq_id = tid_data->txq_id; | ||
2687 | |||
2701 | if (iwl_mvm_has_new_tx_api(mvm)) | 2688 | if (iwl_mvm_has_new_tx_api(mvm)) |
2702 | return; | 2689 | return; |
2703 | 2690 | ||
@@ -2709,8 +2696,10 @@ static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm, | |||
2709 | * allocated through iwl_mvm_enable_txq, so we can just mark it back as | 2696 | * allocated through iwl_mvm_enable_txq, so we can just mark it back as |
2710 | * free. | 2697 | * free. |
2711 | */ | 2698 | */ |
2712 | if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED) | 2699 | if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED) { |
2713 | mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_FREE; | 2700 | mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_FREE; |
2701 | tid_data->txq_id = IWL_MVM_INVALID_QUEUE; | ||
2702 | } | ||
2714 | 2703 | ||
2715 | spin_unlock_bh(&mvm->queue_info_lock); | 2704 | spin_unlock_bh(&mvm->queue_info_lock); |
2716 | } | 2705 | } |
@@ -2741,7 +2730,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
2741 | 2730 | ||
2742 | mvmsta->agg_tids &= ~BIT(tid); | 2731 | mvmsta->agg_tids &= ~BIT(tid); |
2743 | 2732 | ||
2744 | iwl_mvm_unreserve_agg_queue(mvm, mvmsta, txq_id); | 2733 | iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data); |
2745 | 2734 | ||
2746 | switch (tid_data->state) { | 2735 | switch (tid_data->state) { |
2747 | case IWL_AGG_ON: | 2736 | case IWL_AGG_ON: |
@@ -2808,7 +2797,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
2808 | mvmsta->agg_tids &= ~BIT(tid); | 2797 | mvmsta->agg_tids &= ~BIT(tid); |
2809 | spin_unlock_bh(&mvmsta->lock); | 2798 | spin_unlock_bh(&mvmsta->lock); |
2810 | 2799 | ||
2811 | iwl_mvm_unreserve_agg_queue(mvm, mvmsta, txq_id); | 2800 | iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data); |
2812 | 2801 | ||
2813 | if (old_state >= IWL_AGG_ON) { | 2802 | if (old_state >= IWL_AGG_ON) { |
2814 | iwl_mvm_drain_sta(mvm, mvmsta, true); | 2803 | iwl_mvm_drain_sta(mvm, mvmsta, true); |
@@ -3233,17 +3222,9 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
3233 | } | 3222 | } |
3234 | sta_id = mvm_sta->sta_id; | 3223 | sta_id = mvm_sta->sta_id; |
3235 | 3224 | ||
3236 | if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC || | ||
3237 | keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || | ||
3238 | keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256) { | ||
3239 | ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, | ||
3240 | false); | ||
3241 | goto end; | ||
3242 | } | ||
3243 | |||
3244 | /* | 3225 | /* |
3245 | * It is possible that the 'sta' parameter is NULL, and thus | 3226 | * It is possible that the 'sta' parameter is NULL, and thus |
3246 | * there is a need to retrieve the sta from the local station | 3227 | * there is a need to retrieve the sta from the local station |
3247 | * table. | 3228 | * table. |
3248 | */ | 3229 | */ |
3249 | if (!sta) { | 3230 | if (!sta) { |
@@ -3258,6 +3239,17 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
3258 | 3239 | ||
3259 | if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif)) | 3240 | if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif)) |
3260 | return -EINVAL; | 3241 | return -EINVAL; |
3242 | } else { | ||
3243 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
3244 | |||
3245 | sta_id = mvmvif->mcast_sta.sta_id; | ||
3246 | } | ||
3247 | |||
3248 | if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC || | ||
3249 | keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || | ||
3250 | keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256) { | ||
3251 | ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, false); | ||
3252 | goto end; | ||
3261 | } | 3253 | } |
3262 | 3254 | ||
3263 | /* If the key_offset is not pre-assigned, we need to find a | 3255 | /* If the key_offset is not pre-assigned, we need to find a |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index acb217e666db..cd91bc44259c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c | |||
@@ -8,6 +8,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 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
10 | * Copyright(c) 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2017 Intel Deutschland GmbH |
11 | * Copyright(c) 2018 Intel Corporation | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
@@ -18,11 +19,6 @@ | |||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
19 | * General Public License for more details. | 20 | * General Public License for more details. |
20 | * | 21 | * |
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
24 | * USA | ||
25 | * | ||
26 | * The full GNU General Public License is included in this distribution | 22 | * The full GNU General Public License is included in this distribution |
27 | * in the file called COPYING. | 23 | * in the file called COPYING. |
28 | * | 24 | * |
@@ -35,6 +31,7 @@ | |||
35 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 31 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
36 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 32 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
37 | * Copyright(c) 2017 Intel Deutschland GmbH | 33 | * Copyright(c) 2017 Intel Deutschland GmbH |
34 | * Copyright(c) 2018 Intel Corporation | ||
38 | * All rights reserved. | 35 | * All rights reserved. |
39 | * | 36 | * |
40 | * Redistribution and use in source and binary forms, with or without | 37 | * Redistribution and use in source and binary forms, with or without |
@@ -198,9 +195,13 @@ static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm, | |||
198 | struct ieee80211_vif *vif, | 195 | struct ieee80211_vif *vif, |
199 | const char *errmsg) | 196 | const char *errmsg) |
200 | { | 197 | { |
198 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
199 | |||
201 | if (vif->type != NL80211_IFTYPE_STATION) | 200 | if (vif->type != NL80211_IFTYPE_STATION) |
202 | return false; | 201 | return false; |
203 | if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) | 202 | |
203 | if (!mvmvif->csa_bcn_pending && vif->bss_conf.assoc && | ||
204 | vif->bss_conf.dtim_period) | ||
204 | return false; | 205 | return false; |
205 | if (errmsg) | 206 | if (errmsg) |
206 | IWL_ERR(mvm, "%s\n", errmsg); | 207 | IWL_ERR(mvm, "%s\n", errmsg); |
@@ -344,7 +345,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
344 | * and know the dtim period. | 345 | * and know the dtim period. |
345 | */ | 346 | */ |
346 | iwl_mvm_te_check_disconnect(mvm, te_data->vif, | 347 | iwl_mvm_te_check_disconnect(mvm, te_data->vif, |
347 | "No association and the time event is over already..."); | 348 | "No beacon heard and the time event is over already..."); |
348 | break; | 349 | break; |
349 | default: | 350 | default: |
350 | break; | 351 | break; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index af6dfceab6b8..795065974d78 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c | |||
@@ -687,6 +687,74 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) | |||
687 | } | 687 | } |
688 | 688 | ||
689 | #ifdef CONFIG_INET | 689 | #ifdef CONFIG_INET |
690 | |||
691 | static int | ||
692 | iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes, | ||
693 | netdev_features_t netdev_flags, | ||
694 | struct sk_buff_head *mpdus_skb) | ||
695 | { | ||
696 | struct sk_buff *tmp, *next; | ||
697 | struct ieee80211_hdr *hdr = (void *)skb->data; | ||
698 | char cb[sizeof(skb->cb)]; | ||
699 | u16 i = 0; | ||
700 | unsigned int tcp_payload_len; | ||
701 | unsigned int mss = skb_shinfo(skb)->gso_size; | ||
702 | bool ipv4 = (skb->protocol == htons(ETH_P_IP)); | ||
703 | u16 ip_base_id = ipv4 ? ntohs(ip_hdr(skb)->id) : 0; | ||
704 | |||
705 | skb_shinfo(skb)->gso_size = num_subframes * mss; | ||
706 | memcpy(cb, skb->cb, sizeof(cb)); | ||
707 | |||
708 | next = skb_gso_segment(skb, netdev_flags); | ||
709 | skb_shinfo(skb)->gso_size = mss; | ||
710 | if (WARN_ON_ONCE(IS_ERR(next))) | ||
711 | return -EINVAL; | ||
712 | else if (next) | ||
713 | consume_skb(skb); | ||
714 | |||
715 | while (next) { | ||
716 | tmp = next; | ||
717 | next = tmp->next; | ||
718 | |||
719 | memcpy(tmp->cb, cb, sizeof(tmp->cb)); | ||
720 | /* | ||
721 | * Compute the length of all the data added for the A-MSDU. | ||
722 | * This will be used to compute the length to write in the TX | ||
723 | * command. We have: SNAP + IP + TCP for n -1 subframes and | ||
724 | * ETH header for n subframes. | ||
725 | */ | ||
726 | tcp_payload_len = skb_tail_pointer(tmp) - | ||
727 | skb_transport_header(tmp) - | ||
728 | tcp_hdrlen(tmp) + tmp->data_len; | ||
729 | |||
730 | if (ipv4) | ||
731 | ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes); | ||
732 | |||
733 | if (tcp_payload_len > mss) { | ||
734 | skb_shinfo(tmp)->gso_size = mss; | ||
735 | } else { | ||
736 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
737 | u8 *qc; | ||
738 | |||
739 | if (ipv4) | ||
740 | ip_send_check(ip_hdr(tmp)); | ||
741 | |||
742 | qc = ieee80211_get_qos_ctl((void *)tmp->data); | ||
743 | *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; | ||
744 | } | ||
745 | skb_shinfo(tmp)->gso_size = 0; | ||
746 | } | ||
747 | |||
748 | tmp->prev = NULL; | ||
749 | tmp->next = NULL; | ||
750 | |||
751 | __skb_queue_tail(mpdus_skb, tmp); | ||
752 | i++; | ||
753 | } | ||
754 | |||
755 | return 0; | ||
756 | } | ||
757 | |||
690 | static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, | 758 | static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, |
691 | struct ieee80211_tx_info *info, | 759 | struct ieee80211_tx_info *info, |
692 | struct ieee80211_sta *sta, | 760 | struct ieee80211_sta *sta, |
@@ -695,14 +763,10 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
695 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); | 763 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); |
696 | struct ieee80211_hdr *hdr = (void *)skb->data; | 764 | struct ieee80211_hdr *hdr = (void *)skb->data; |
697 | unsigned int mss = skb_shinfo(skb)->gso_size; | 765 | unsigned int mss = skb_shinfo(skb)->gso_size; |
698 | struct sk_buff *tmp, *next; | ||
699 | char cb[sizeof(skb->cb)]; | ||
700 | unsigned int num_subframes, tcp_payload_len, subf_len, max_amsdu_len; | 766 | unsigned int num_subframes, tcp_payload_len, subf_len, max_amsdu_len; |
701 | bool ipv4 = (skb->protocol == htons(ETH_P_IP)); | 767 | u16 snap_ip_tcp, pad; |
702 | u16 ip_base_id = ipv4 ? ntohs(ip_hdr(skb)->id) : 0; | ||
703 | u16 snap_ip_tcp, pad, i = 0; | ||
704 | unsigned int dbg_max_amsdu_len; | 768 | unsigned int dbg_max_amsdu_len; |
705 | netdev_features_t netdev_features = NETIF_F_CSUM_MASK | NETIF_F_SG; | 769 | netdev_features_t netdev_flags = NETIF_F_CSUM_MASK | NETIF_F_SG; |
706 | u8 *qc, tid, txf; | 770 | u8 *qc, tid, txf; |
707 | 771 | ||
708 | snap_ip_tcp = 8 + skb_transport_header(skb) - skb_network_header(skb) + | 772 | snap_ip_tcp = 8 + skb_transport_header(skb) - skb_network_header(skb) + |
@@ -712,16 +776,8 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
712 | 776 | ||
713 | if (!sta->max_amsdu_len || | 777 | if (!sta->max_amsdu_len || |
714 | !ieee80211_is_data_qos(hdr->frame_control) || | 778 | !ieee80211_is_data_qos(hdr->frame_control) || |
715 | (!mvmsta->tlc_amsdu && !dbg_max_amsdu_len)) { | 779 | (!mvmsta->tlc_amsdu && !dbg_max_amsdu_len)) |
716 | num_subframes = 1; | 780 | return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb); |
717 | pad = 0; | ||
718 | goto segment; | ||
719 | } | ||
720 | |||
721 | qc = ieee80211_get_qos_ctl(hdr); | ||
722 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | ||
723 | if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) | ||
724 | return -EINVAL; | ||
725 | 781 | ||
726 | /* | 782 | /* |
727 | * Do not build AMSDU for IPv6 with extension headers. | 783 | * Do not build AMSDU for IPv6 with extension headers. |
@@ -730,22 +786,22 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
730 | if (skb->protocol == htons(ETH_P_IPV6) && | 786 | if (skb->protocol == htons(ETH_P_IPV6) && |
731 | ((struct ipv6hdr *)skb_network_header(skb))->nexthdr != | 787 | ((struct ipv6hdr *)skb_network_header(skb))->nexthdr != |
732 | IPPROTO_TCP) { | 788 | IPPROTO_TCP) { |
733 | num_subframes = 1; | 789 | netdev_flags &= ~NETIF_F_CSUM_MASK; |
734 | pad = 0; | 790 | return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb); |
735 | netdev_features &= ~NETIF_F_CSUM_MASK; | ||
736 | goto segment; | ||
737 | } | 791 | } |
738 | 792 | ||
793 | qc = ieee80211_get_qos_ctl(hdr); | ||
794 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | ||
795 | if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) | ||
796 | return -EINVAL; | ||
797 | |||
739 | /* | 798 | /* |
740 | * No need to lock amsdu_in_ampdu_allowed since it can't be modified | 799 | * No need to lock amsdu_in_ampdu_allowed since it can't be modified |
741 | * during an BA session. | 800 | * during an BA session. |
742 | */ | 801 | */ |
743 | if (info->flags & IEEE80211_TX_CTL_AMPDU && | 802 | if (info->flags & IEEE80211_TX_CTL_AMPDU && |
744 | !mvmsta->tid_data[tid].amsdu_in_ampdu_allowed) { | 803 | !mvmsta->tid_data[tid].amsdu_in_ampdu_allowed) |
745 | num_subframes = 1; | 804 | return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb); |
746 | pad = 0; | ||
747 | goto segment; | ||
748 | } | ||
749 | 805 | ||
750 | max_amsdu_len = sta->max_amsdu_len; | 806 | max_amsdu_len = sta->max_amsdu_len; |
751 | 807 | ||
@@ -811,56 +867,8 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
811 | * Trick the segmentation function to make it | 867 | * Trick the segmentation function to make it |
812 | * create SKBs that can fit into one A-MSDU. | 868 | * create SKBs that can fit into one A-MSDU. |
813 | */ | 869 | */ |
814 | segment: | 870 | return iwl_mvm_tx_tso_segment(skb, num_subframes, netdev_flags, |
815 | skb_shinfo(skb)->gso_size = num_subframes * mss; | 871 | mpdus_skb); |
816 | memcpy(cb, skb->cb, sizeof(cb)); | ||
817 | |||
818 | next = skb_gso_segment(skb, netdev_features); | ||
819 | skb_shinfo(skb)->gso_size = mss; | ||
820 | if (WARN_ON_ONCE(IS_ERR(next))) | ||
821 | return -EINVAL; | ||
822 | else if (next) | ||
823 | consume_skb(skb); | ||
824 | |||
825 | while (next) { | ||
826 | tmp = next; | ||
827 | next = tmp->next; | ||
828 | |||
829 | memcpy(tmp->cb, cb, sizeof(tmp->cb)); | ||
830 | /* | ||
831 | * Compute the length of all the data added for the A-MSDU. | ||
832 | * This will be used to compute the length to write in the TX | ||
833 | * command. We have: SNAP + IP + TCP for n -1 subframes and | ||
834 | * ETH header for n subframes. | ||
835 | */ | ||
836 | tcp_payload_len = skb_tail_pointer(tmp) - | ||
837 | skb_transport_header(tmp) - | ||
838 | tcp_hdrlen(tmp) + tmp->data_len; | ||
839 | |||
840 | if (ipv4) | ||
841 | ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes); | ||
842 | |||
843 | if (tcp_payload_len > mss) { | ||
844 | skb_shinfo(tmp)->gso_size = mss; | ||
845 | } else { | ||
846 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
847 | qc = ieee80211_get_qos_ctl((void *)tmp->data); | ||
848 | |||
849 | if (ipv4) | ||
850 | ip_send_check(ip_hdr(tmp)); | ||
851 | *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; | ||
852 | } | ||
853 | skb_shinfo(tmp)->gso_size = 0; | ||
854 | } | ||
855 | |||
856 | tmp->prev = NULL; | ||
857 | tmp->next = NULL; | ||
858 | |||
859 | __skb_queue_tail(mpdus_skb, tmp); | ||
860 | i++; | ||
861 | } | ||
862 | |||
863 | return 0; | ||
864 | } | 872 | } |
865 | #else /* CONFIG_INET */ | 873 | #else /* CONFIG_INET */ |
866 | static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, | 874 | static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, |
@@ -1894,14 +1902,12 @@ int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal, u32 flags) | |||
1894 | struct iwl_mvm_int_sta *int_sta = sta; | 1902 | struct iwl_mvm_int_sta *int_sta = sta; |
1895 | struct iwl_mvm_sta *mvm_sta = sta; | 1903 | struct iwl_mvm_sta *mvm_sta = sta; |
1896 | 1904 | ||
1897 | if (iwl_mvm_has_new_tx_api(mvm)) { | 1905 | BUILD_BUG_ON(offsetof(struct iwl_mvm_int_sta, sta_id) != |
1898 | if (internal) | 1906 | offsetof(struct iwl_mvm_sta, sta_id)); |
1899 | return iwl_mvm_flush_sta_tids(mvm, int_sta->sta_id, | ||
1900 | BIT(IWL_MGMT_TID), flags); | ||
1901 | 1907 | ||
1908 | if (iwl_mvm_has_new_tx_api(mvm)) | ||
1902 | return iwl_mvm_flush_sta_tids(mvm, mvm_sta->sta_id, | 1909 | return iwl_mvm_flush_sta_tids(mvm, mvm_sta->sta_id, |
1903 | 0xFF, flags); | 1910 | 0xff | BIT(IWL_MGMT_TID), flags); |
1904 | } | ||
1905 | 1911 | ||
1906 | if (internal) | 1912 | if (internal) |
1907 | return iwl_mvm_flush_tx_path(mvm, int_sta->tfd_queue_msk, | 1913 | return iwl_mvm_flush_tx_path(mvm, int_sta->tfd_queue_msk, |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index d65e1db7c097..bebcfb44c8c2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c | |||
@@ -800,12 +800,19 @@ int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, | |||
800 | .scd_queue = queue, | 800 | .scd_queue = queue, |
801 | .action = SCD_CFG_DISABLE_QUEUE, | 801 | .action = SCD_CFG_DISABLE_QUEUE, |
802 | }; | 802 | }; |
803 | bool remove_mac_queue = true; | 803 | bool remove_mac_queue = mac80211_queue != IEEE80211_INVAL_HW_QUEUE; |
804 | int ret; | 804 | int ret; |
805 | 805 | ||
806 | if (WARN_ON(remove_mac_queue && mac80211_queue >= IEEE80211_MAX_QUEUES)) | ||
807 | return -EINVAL; | ||
808 | |||
806 | if (iwl_mvm_has_new_tx_api(mvm)) { | 809 | if (iwl_mvm_has_new_tx_api(mvm)) { |
807 | spin_lock_bh(&mvm->queue_info_lock); | 810 | spin_lock_bh(&mvm->queue_info_lock); |
808 | mvm->hw_queue_to_mac80211[queue] &= ~BIT(mac80211_queue); | 811 | |
812 | if (remove_mac_queue) | ||
813 | mvm->hw_queue_to_mac80211[queue] &= | ||
814 | ~BIT(mac80211_queue); | ||
815 | |||
809 | spin_unlock_bh(&mvm->queue_info_lock); | 816 | spin_unlock_bh(&mvm->queue_info_lock); |
810 | 817 | ||
811 | iwl_trans_txq_free(mvm->trans, queue); | 818 | iwl_trans_txq_free(mvm->trans, queue); |
@@ -1027,14 +1034,18 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm) | |||
1027 | } | 1034 | } |
1028 | 1035 | ||
1029 | int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1036 | int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
1030 | bool prev) | 1037 | bool low_latency, |
1038 | enum iwl_mvm_low_latency_cause cause) | ||
1031 | { | 1039 | { |
1032 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 1040 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
1033 | int res; | 1041 | int res; |
1034 | bool low_latency; | 1042 | bool prev; |
1035 | 1043 | ||
1036 | lockdep_assert_held(&mvm->mutex); | 1044 | lockdep_assert_held(&mvm->mutex); |
1037 | 1045 | ||
1046 | prev = iwl_mvm_vif_low_latency(mvmvif); | ||
1047 | iwl_mvm_vif_set_low_latency(mvmvif, low_latency, cause); | ||
1048 | |||
1038 | low_latency = iwl_mvm_vif_low_latency(mvmvif); | 1049 | low_latency = iwl_mvm_vif_low_latency(mvmvif); |
1039 | 1050 | ||
1040 | if (low_latency == prev) | 1051 | if (low_latency == prev) |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 56fc28750a41..959de2f8bb28 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
10 | * Copyright(c) 2016-2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2016-2017 Intel Deutschland GmbH |
11 | * Copyright(c) 2018 Intel Corporation | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
@@ -36,6 +37,7 @@ | |||
36 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 37 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
37 | * All rights reserved. | 38 | * All rights reserved. |
38 | * Copyright(c) 2017 Intel Deutschland GmbH | 39 | * Copyright(c) 2017 Intel Deutschland GmbH |
40 | * Copyright(c) 2018 Intel Corporation | ||
39 | * | 41 | * |
40 | * Redistribution and use in source and binary forms, with or without | 42 | * Redistribution and use in source and binary forms, with or without |
41 | * modification, are permitted provided that the following conditions | 43 | * modification, are permitted provided that the following conditions |
@@ -517,9 +519,9 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
517 | {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)}, | 519 | {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)}, |
518 | 520 | ||
519 | /* 9000 Series */ | 521 | /* 9000 Series */ |
520 | {IWL_PCI_DEVICE(0x2526, 0x0000, iwl9260_2ac_cfg)}, | ||
521 | {IWL_PCI_DEVICE(0x2526, 0x0010, iwl9260_2ac_cfg)}, | 522 | {IWL_PCI_DEVICE(0x2526, 0x0010, iwl9260_2ac_cfg)}, |
522 | {IWL_PCI_DEVICE(0x2526, 0x0014, iwl9260_2ac_cfg)}, | 523 | {IWL_PCI_DEVICE(0x2526, 0x0014, iwl9260_2ac_cfg)}, |
524 | {IWL_PCI_DEVICE(0x2526, 0x0018, iwl9260_2ac_cfg)}, | ||
523 | {IWL_PCI_DEVICE(0x2526, 0x0030, iwl9560_2ac_cfg)}, | 525 | {IWL_PCI_DEVICE(0x2526, 0x0030, iwl9560_2ac_cfg)}, |
524 | {IWL_PCI_DEVICE(0x2526, 0x0034, iwl9560_2ac_cfg)}, | 526 | {IWL_PCI_DEVICE(0x2526, 0x0034, iwl9560_2ac_cfg)}, |
525 | {IWL_PCI_DEVICE(0x2526, 0x0038, iwl9560_2ac_cfg)}, | 527 | {IWL_PCI_DEVICE(0x2526, 0x0038, iwl9560_2ac_cfg)}, |
@@ -544,11 +546,15 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
544 | {IWL_PCI_DEVICE(0x2526, 0x1410, iwl9270_2ac_cfg)}, | 546 | {IWL_PCI_DEVICE(0x2526, 0x1410, iwl9270_2ac_cfg)}, |
545 | {IWL_PCI_DEVICE(0x2526, 0x1420, iwl9460_2ac_cfg_soc)}, | 547 | {IWL_PCI_DEVICE(0x2526, 0x1420, iwl9460_2ac_cfg_soc)}, |
546 | {IWL_PCI_DEVICE(0x2526, 0x1610, iwl9270_2ac_cfg)}, | 548 | {IWL_PCI_DEVICE(0x2526, 0x1610, iwl9270_2ac_cfg)}, |
549 | {IWL_PCI_DEVICE(0x2526, 0x2030, iwl9560_2ac_cfg_soc)}, | ||
550 | {IWL_PCI_DEVICE(0x2526, 0x2034, iwl9560_2ac_cfg_soc)}, | ||
547 | {IWL_PCI_DEVICE(0x2526, 0x4010, iwl9260_2ac_cfg)}, | 551 | {IWL_PCI_DEVICE(0x2526, 0x4010, iwl9260_2ac_cfg)}, |
548 | {IWL_PCI_DEVICE(0x2526, 0x4030, iwl9560_2ac_cfg)}, | 552 | {IWL_PCI_DEVICE(0x2526, 0x4030, iwl9560_2ac_cfg)}, |
553 | {IWL_PCI_DEVICE(0x2526, 0x4034, iwl9560_2ac_cfg_soc)}, | ||
549 | {IWL_PCI_DEVICE(0x2526, 0x40A4, iwl9460_2ac_cfg)}, | 554 | {IWL_PCI_DEVICE(0x2526, 0x40A4, iwl9460_2ac_cfg)}, |
550 | {IWL_PCI_DEVICE(0x2526, 0xA014, iwl9260_2ac_cfg)}, | 555 | {IWL_PCI_DEVICE(0x2526, 0x4234, iwl9560_2ac_cfg_soc)}, |
551 | {IWL_PCI_DEVICE(0x2526, 0x42A4, iwl9462_2ac_cfg_soc)}, | 556 | {IWL_PCI_DEVICE(0x2526, 0x42A4, iwl9462_2ac_cfg_soc)}, |
557 | {IWL_PCI_DEVICE(0x2526, 0xA014, iwl9260_2ac_cfg)}, | ||
552 | {IWL_PCI_DEVICE(0x271B, 0x0010, iwl9160_2ac_cfg)}, | 558 | {IWL_PCI_DEVICE(0x271B, 0x0010, iwl9160_2ac_cfg)}, |
553 | {IWL_PCI_DEVICE(0x271B, 0x0014, iwl9160_2ac_cfg)}, | 559 | {IWL_PCI_DEVICE(0x271B, 0x0014, iwl9160_2ac_cfg)}, |
554 | {IWL_PCI_DEVICE(0x271B, 0x0210, iwl9160_2ac_cfg)}, | 560 | {IWL_PCI_DEVICE(0x271B, 0x0210, iwl9160_2ac_cfg)}, |
@@ -569,38 +575,146 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
569 | {IWL_PCI_DEVICE(0x2720, 0x0264, iwl9461_2ac_cfg_soc)}, | 575 | {IWL_PCI_DEVICE(0x2720, 0x0264, iwl9461_2ac_cfg_soc)}, |
570 | {IWL_PCI_DEVICE(0x2720, 0x02A0, iwl9462_2ac_cfg_soc)}, | 576 | {IWL_PCI_DEVICE(0x2720, 0x02A0, iwl9462_2ac_cfg_soc)}, |
571 | {IWL_PCI_DEVICE(0x2720, 0x02A4, iwl9462_2ac_cfg_soc)}, | 577 | {IWL_PCI_DEVICE(0x2720, 0x02A4, iwl9462_2ac_cfg_soc)}, |
578 | {IWL_PCI_DEVICE(0x2720, 0x1010, iwl9260_2ac_cfg)}, | ||
579 | {IWL_PCI_DEVICE(0x2720, 0x1030, iwl9560_2ac_cfg_soc)}, | ||
580 | {IWL_PCI_DEVICE(0x2720, 0x1210, iwl9260_2ac_cfg)}, | ||
581 | {IWL_PCI_DEVICE(0x2720, 0x2030, iwl9560_2ac_cfg_soc)}, | ||
582 | {IWL_PCI_DEVICE(0x2720, 0x2034, iwl9560_2ac_cfg_soc)}, | ||
572 | {IWL_PCI_DEVICE(0x2720, 0x4030, iwl9560_2ac_cfg)}, | 583 | {IWL_PCI_DEVICE(0x2720, 0x4030, iwl9560_2ac_cfg)}, |
584 | {IWL_PCI_DEVICE(0x2720, 0x4034, iwl9560_2ac_cfg_soc)}, | ||
573 | {IWL_PCI_DEVICE(0x2720, 0x40A4, iwl9462_2ac_cfg_soc)}, | 585 | {IWL_PCI_DEVICE(0x2720, 0x40A4, iwl9462_2ac_cfg_soc)}, |
586 | {IWL_PCI_DEVICE(0x2720, 0x4234, iwl9560_2ac_cfg_soc)}, | ||
587 | {IWL_PCI_DEVICE(0x2720, 0x42A4, iwl9462_2ac_cfg_soc)}, | ||
588 | {IWL_PCI_DEVICE(0x30DC, 0x0030, iwl9560_2ac_cfg_soc)}, | ||
589 | {IWL_PCI_DEVICE(0x30DC, 0x0034, iwl9560_2ac_cfg_soc)}, | ||
590 | {IWL_PCI_DEVICE(0x30DC, 0x0038, iwl9560_2ac_cfg_soc)}, | ||
591 | {IWL_PCI_DEVICE(0x30DC, 0x003C, iwl9560_2ac_cfg_soc)}, | ||
574 | {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9460_2ac_cfg_soc)}, | 592 | {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9460_2ac_cfg_soc)}, |
575 | {IWL_PCI_DEVICE(0x30DC, 0x0064, iwl9461_2ac_cfg_soc)}, | 593 | {IWL_PCI_DEVICE(0x30DC, 0x0064, iwl9461_2ac_cfg_soc)}, |
576 | {IWL_PCI_DEVICE(0x30DC, 0x00A0, iwl9462_2ac_cfg_soc)}, | 594 | {IWL_PCI_DEVICE(0x30DC, 0x00A0, iwl9462_2ac_cfg_soc)}, |
577 | {IWL_PCI_DEVICE(0x30DC, 0x00A4, iwl9462_2ac_cfg_soc)}, | 595 | {IWL_PCI_DEVICE(0x30DC, 0x00A4, iwl9462_2ac_cfg_soc)}, |
596 | {IWL_PCI_DEVICE(0x30DC, 0x0230, iwl9560_2ac_cfg_soc)}, | ||
597 | {IWL_PCI_DEVICE(0x30DC, 0x0234, iwl9560_2ac_cfg_soc)}, | ||
598 | {IWL_PCI_DEVICE(0x30DC, 0x0238, iwl9560_2ac_cfg_soc)}, | ||
599 | {IWL_PCI_DEVICE(0x30DC, 0x023C, iwl9560_2ac_cfg_soc)}, | ||
578 | {IWL_PCI_DEVICE(0x30DC, 0x0260, iwl9461_2ac_cfg_soc)}, | 600 | {IWL_PCI_DEVICE(0x30DC, 0x0260, iwl9461_2ac_cfg_soc)}, |
579 | {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_soc)}, | 601 | {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_soc)}, |
580 | {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_soc)}, | 602 | {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_soc)}, |
581 | {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_soc)}, | 603 | {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_soc)}, |
582 | {IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_cfg_soc)}, | 604 | {IWL_PCI_DEVICE(0x30DC, 0x1010, iwl9260_2ac_cfg)}, |
583 | {IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg_soc)}, | 605 | {IWL_PCI_DEVICE(0x30DC, 0x1030, iwl9560_2ac_cfg_soc)}, |
584 | {IWL_PCI_DEVICE(0x31DC, 0x0038, iwl9560_2ac_cfg_soc)}, | 606 | {IWL_PCI_DEVICE(0x30DC, 0x1210, iwl9260_2ac_cfg)}, |
585 | {IWL_PCI_DEVICE(0x31DC, 0x003C, iwl9560_2ac_cfg_soc)}, | 607 | {IWL_PCI_DEVICE(0x30DC, 0x2030, iwl9560_2ac_cfg_soc)}, |
586 | {IWL_PCI_DEVICE(0x31DC, 0x0060, iwl9460_2ac_cfg_soc)}, | 608 | {IWL_PCI_DEVICE(0x30DC, 0x2034, iwl9560_2ac_cfg_soc)}, |
587 | {IWL_PCI_DEVICE(0x31DC, 0x0064, iwl9461_2ac_cfg_soc)}, | 609 | {IWL_PCI_DEVICE(0x30DC, 0x4030, iwl9560_2ac_cfg_soc)}, |
588 | {IWL_PCI_DEVICE(0x31DC, 0x00A0, iwl9462_2ac_cfg_soc)}, | 610 | {IWL_PCI_DEVICE(0x30DC, 0x4034, iwl9560_2ac_cfg_soc)}, |
589 | {IWL_PCI_DEVICE(0x31DC, 0x00A4, iwl9462_2ac_cfg_soc)}, | 611 | {IWL_PCI_DEVICE(0x30DC, 0x40A4, iwl9462_2ac_cfg_soc)}, |
590 | {IWL_PCI_DEVICE(0x31DC, 0x0230, iwl9560_2ac_cfg_soc)}, | 612 | {IWL_PCI_DEVICE(0x30DC, 0x4234, iwl9560_2ac_cfg_soc)}, |
591 | {IWL_PCI_DEVICE(0x31DC, 0x0234, iwl9560_2ac_cfg_soc)}, | 613 | {IWL_PCI_DEVICE(0x30DC, 0x42A4, iwl9462_2ac_cfg_soc)}, |
592 | {IWL_PCI_DEVICE(0x31DC, 0x0238, iwl9560_2ac_cfg_soc)}, | 614 | {IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_cfg_shared_clk)}, |
593 | {IWL_PCI_DEVICE(0x31DC, 0x023C, iwl9560_2ac_cfg_soc)}, | 615 | {IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg_shared_clk)}, |
594 | {IWL_PCI_DEVICE(0x31DC, 0x0260, iwl9461_2ac_cfg_soc)}, | 616 | {IWL_PCI_DEVICE(0x31DC, 0x0038, iwl9560_2ac_cfg_shared_clk)}, |
595 | {IWL_PCI_DEVICE(0x31DC, 0x0264, iwl9461_2ac_cfg_soc)}, | 617 | {IWL_PCI_DEVICE(0x31DC, 0x003C, iwl9560_2ac_cfg_shared_clk)}, |
596 | {IWL_PCI_DEVICE(0x31DC, 0x02A0, iwl9462_2ac_cfg_soc)}, | 618 | {IWL_PCI_DEVICE(0x31DC, 0x0060, iwl9460_2ac_cfg_shared_clk)}, |
597 | {IWL_PCI_DEVICE(0x31DC, 0x02A4, iwl9462_2ac_cfg_soc)}, | 619 | {IWL_PCI_DEVICE(0x31DC, 0x0064, iwl9461_2ac_cfg_shared_clk)}, |
598 | {IWL_PCI_DEVICE(0x31DC, 0x4030, iwl9560_2ac_cfg_soc)}, | 620 | {IWL_PCI_DEVICE(0x31DC, 0x00A0, iwl9462_2ac_cfg_shared_clk)}, |
599 | {IWL_PCI_DEVICE(0x31DC, 0x4034, iwl9560_2ac_cfg_soc)}, | 621 | {IWL_PCI_DEVICE(0x31DC, 0x00A4, iwl9462_2ac_cfg_shared_clk)}, |
600 | {IWL_PCI_DEVICE(0x31DC, 0x40A4, iwl9462_2ac_cfg_soc)}, | 622 | {IWL_PCI_DEVICE(0x31DC, 0x0230, iwl9560_2ac_cfg_shared_clk)}, |
623 | {IWL_PCI_DEVICE(0x31DC, 0x0234, iwl9560_2ac_cfg_shared_clk)}, | ||
624 | {IWL_PCI_DEVICE(0x31DC, 0x0238, iwl9560_2ac_cfg_shared_clk)}, | ||
625 | {IWL_PCI_DEVICE(0x31DC, 0x023C, iwl9560_2ac_cfg_shared_clk)}, | ||
626 | {IWL_PCI_DEVICE(0x31DC, 0x0260, iwl9461_2ac_cfg_shared_clk)}, | ||
627 | {IWL_PCI_DEVICE(0x31DC, 0x0264, iwl9461_2ac_cfg_shared_clk)}, | ||
628 | {IWL_PCI_DEVICE(0x31DC, 0x02A0, iwl9462_2ac_cfg_shared_clk)}, | ||
629 | {IWL_PCI_DEVICE(0x31DC, 0x02A4, iwl9462_2ac_cfg_shared_clk)}, | ||
630 | {IWL_PCI_DEVICE(0x31DC, 0x1010, iwl9260_2ac_cfg)}, | ||
631 | {IWL_PCI_DEVICE(0x31DC, 0x1030, iwl9560_2ac_cfg_shared_clk)}, | ||
632 | {IWL_PCI_DEVICE(0x31DC, 0x1210, iwl9260_2ac_cfg)}, | ||
633 | {IWL_PCI_DEVICE(0x31DC, 0x2030, iwl9560_2ac_cfg_shared_clk)}, | ||
634 | {IWL_PCI_DEVICE(0x31DC, 0x2034, iwl9560_2ac_cfg_shared_clk)}, | ||
635 | {IWL_PCI_DEVICE(0x31DC, 0x4030, iwl9560_2ac_cfg_shared_clk)}, | ||
636 | {IWL_PCI_DEVICE(0x31DC, 0x4034, iwl9560_2ac_cfg_shared_clk)}, | ||
637 | {IWL_PCI_DEVICE(0x31DC, 0x40A4, iwl9462_2ac_cfg_shared_clk)}, | ||
638 | {IWL_PCI_DEVICE(0x31DC, 0x4234, iwl9560_2ac_cfg_shared_clk)}, | ||
639 | {IWL_PCI_DEVICE(0x31DC, 0x42A4, iwl9462_2ac_cfg_shared_clk)}, | ||
601 | {IWL_PCI_DEVICE(0x34F0, 0x0030, iwl9560_2ac_cfg_soc)}, | 640 | {IWL_PCI_DEVICE(0x34F0, 0x0030, iwl9560_2ac_cfg_soc)}, |
602 | {IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_soc)}, | 641 | {IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_soc)}, |
642 | {IWL_PCI_DEVICE(0x34F0, 0x0038, iwl9560_2ac_cfg_soc)}, | ||
643 | {IWL_PCI_DEVICE(0x34F0, 0x003C, iwl9560_2ac_cfg_soc)}, | ||
644 | {IWL_PCI_DEVICE(0x34F0, 0x0060, iwl9461_2ac_cfg_soc)}, | ||
645 | {IWL_PCI_DEVICE(0x34F0, 0x0064, iwl9461_2ac_cfg_soc)}, | ||
646 | {IWL_PCI_DEVICE(0x34F0, 0x00A0, iwl9462_2ac_cfg_soc)}, | ||
647 | {IWL_PCI_DEVICE(0x34F0, 0x00A4, iwl9462_2ac_cfg_soc)}, | ||
648 | {IWL_PCI_DEVICE(0x34F0, 0x0230, iwl9560_2ac_cfg_soc)}, | ||
649 | {IWL_PCI_DEVICE(0x34F0, 0x0234, iwl9560_2ac_cfg_soc)}, | ||
650 | {IWL_PCI_DEVICE(0x34F0, 0x0238, iwl9560_2ac_cfg_soc)}, | ||
651 | {IWL_PCI_DEVICE(0x34F0, 0x023C, iwl9560_2ac_cfg_soc)}, | ||
652 | {IWL_PCI_DEVICE(0x34F0, 0x0260, iwl9461_2ac_cfg_soc)}, | ||
653 | {IWL_PCI_DEVICE(0x34F0, 0x0264, iwl9461_2ac_cfg_soc)}, | ||
654 | {IWL_PCI_DEVICE(0x34F0, 0x02A0, iwl9462_2ac_cfg_soc)}, | ||
603 | {IWL_PCI_DEVICE(0x34F0, 0x02A4, iwl9462_2ac_cfg_soc)}, | 655 | {IWL_PCI_DEVICE(0x34F0, 0x02A4, iwl9462_2ac_cfg_soc)}, |
656 | {IWL_PCI_DEVICE(0x34F0, 0x1010, iwl9260_2ac_cfg)}, | ||
657 | {IWL_PCI_DEVICE(0x34F0, 0x1030, iwl9560_2ac_cfg_soc)}, | ||
658 | {IWL_PCI_DEVICE(0x34F0, 0x1210, iwl9260_2ac_cfg)}, | ||
659 | {IWL_PCI_DEVICE(0x34F0, 0x2030, iwl9560_2ac_cfg_soc)}, | ||
660 | {IWL_PCI_DEVICE(0x34F0, 0x2034, iwl9560_2ac_cfg_soc)}, | ||
661 | {IWL_PCI_DEVICE(0x34F0, 0x4030, iwl9560_2ac_cfg_soc)}, | ||
662 | {IWL_PCI_DEVICE(0x34F0, 0x4034, iwl9560_2ac_cfg_soc)}, | ||
663 | {IWL_PCI_DEVICE(0x34F0, 0x40A4, iwl9462_2ac_cfg_soc)}, | ||
664 | {IWL_PCI_DEVICE(0x34F0, 0x4234, iwl9560_2ac_cfg_soc)}, | ||
665 | {IWL_PCI_DEVICE(0x34F0, 0x42A4, iwl9462_2ac_cfg_soc)}, | ||
666 | {IWL_PCI_DEVICE(0x3DF0, 0x0030, iwl9560_2ac_cfg_soc)}, | ||
667 | {IWL_PCI_DEVICE(0x3DF0, 0x0034, iwl9560_2ac_cfg_soc)}, | ||
668 | {IWL_PCI_DEVICE(0x3DF0, 0x0038, iwl9560_2ac_cfg_soc)}, | ||
669 | {IWL_PCI_DEVICE(0x3DF0, 0x003C, iwl9560_2ac_cfg_soc)}, | ||
670 | {IWL_PCI_DEVICE(0x3DF0, 0x0060, iwl9461_2ac_cfg_soc)}, | ||
671 | {IWL_PCI_DEVICE(0x3DF0, 0x0064, iwl9461_2ac_cfg_soc)}, | ||
672 | {IWL_PCI_DEVICE(0x3DF0, 0x00A0, iwl9462_2ac_cfg_soc)}, | ||
673 | {IWL_PCI_DEVICE(0x3DF0, 0x00A4, iwl9462_2ac_cfg_soc)}, | ||
674 | {IWL_PCI_DEVICE(0x3DF0, 0x0230, iwl9560_2ac_cfg_soc)}, | ||
675 | {IWL_PCI_DEVICE(0x3DF0, 0x0234, iwl9560_2ac_cfg_soc)}, | ||
676 | {IWL_PCI_DEVICE(0x3DF0, 0x0238, iwl9560_2ac_cfg_soc)}, | ||
677 | {IWL_PCI_DEVICE(0x3DF0, 0x023C, iwl9560_2ac_cfg_soc)}, | ||
678 | {IWL_PCI_DEVICE(0x3DF0, 0x0260, iwl9461_2ac_cfg_soc)}, | ||
679 | {IWL_PCI_DEVICE(0x3DF0, 0x0264, iwl9461_2ac_cfg_soc)}, | ||
680 | {IWL_PCI_DEVICE(0x3DF0, 0x02A0, iwl9462_2ac_cfg_soc)}, | ||
681 | {IWL_PCI_DEVICE(0x3DF0, 0x02A4, iwl9462_2ac_cfg_soc)}, | ||
682 | {IWL_PCI_DEVICE(0x3DF0, 0x1010, iwl9260_2ac_cfg)}, | ||
683 | {IWL_PCI_DEVICE(0x3DF0, 0x1030, iwl9560_2ac_cfg_soc)}, | ||
684 | {IWL_PCI_DEVICE(0x3DF0, 0x1210, iwl9260_2ac_cfg)}, | ||
685 | {IWL_PCI_DEVICE(0x3DF0, 0x2030, iwl9560_2ac_cfg_soc)}, | ||
686 | {IWL_PCI_DEVICE(0x3DF0, 0x2034, iwl9560_2ac_cfg_soc)}, | ||
687 | {IWL_PCI_DEVICE(0x3DF0, 0x4030, iwl9560_2ac_cfg_soc)}, | ||
688 | {IWL_PCI_DEVICE(0x3DF0, 0x4034, iwl9560_2ac_cfg_soc)}, | ||
689 | {IWL_PCI_DEVICE(0x3DF0, 0x40A4, iwl9462_2ac_cfg_soc)}, | ||
690 | {IWL_PCI_DEVICE(0x3DF0, 0x4234, iwl9560_2ac_cfg_soc)}, | ||
691 | {IWL_PCI_DEVICE(0x3DF0, 0x42A4, iwl9462_2ac_cfg_soc)}, | ||
692 | {IWL_PCI_DEVICE(0x43F0, 0x0030, iwl9560_2ac_cfg_soc)}, | ||
693 | {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_soc)}, | ||
694 | {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_cfg_soc)}, | ||
695 | {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_cfg_soc)}, | ||
696 | {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_soc)}, | ||
697 | {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_soc)}, | ||
698 | {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_soc)}, | ||
699 | {IWL_PCI_DEVICE(0x43F0, 0x00A4, iwl9462_2ac_cfg_soc)}, | ||
700 | {IWL_PCI_DEVICE(0x43F0, 0x0230, iwl9560_2ac_cfg_soc)}, | ||
701 | {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_soc)}, | ||
702 | {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_soc)}, | ||
703 | {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_soc)}, | ||
704 | {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_soc)}, | ||
705 | {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_soc)}, | ||
706 | {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_soc)}, | ||
707 | {IWL_PCI_DEVICE(0x43F0, 0x02A4, iwl9462_2ac_cfg_soc)}, | ||
708 | {IWL_PCI_DEVICE(0x43F0, 0x1010, iwl9260_2ac_cfg)}, | ||
709 | {IWL_PCI_DEVICE(0x43F0, 0x1030, iwl9560_2ac_cfg_soc)}, | ||
710 | {IWL_PCI_DEVICE(0x43F0, 0x1210, iwl9260_2ac_cfg)}, | ||
711 | {IWL_PCI_DEVICE(0x43F0, 0x2030, iwl9560_2ac_cfg_soc)}, | ||
712 | {IWL_PCI_DEVICE(0x43F0, 0x2034, iwl9560_2ac_cfg_soc)}, | ||
713 | {IWL_PCI_DEVICE(0x43F0, 0x4030, iwl9560_2ac_cfg_soc)}, | ||
714 | {IWL_PCI_DEVICE(0x43F0, 0x4034, iwl9560_2ac_cfg_soc)}, | ||
715 | {IWL_PCI_DEVICE(0x43F0, 0x40A4, iwl9462_2ac_cfg_soc)}, | ||
716 | {IWL_PCI_DEVICE(0x43F0, 0x4234, iwl9560_2ac_cfg_soc)}, | ||
717 | {IWL_PCI_DEVICE(0x43F0, 0x42A4, iwl9462_2ac_cfg_soc)}, | ||
604 | {IWL_PCI_DEVICE(0x9DF0, 0x0000, iwl9460_2ac_cfg_soc)}, | 718 | {IWL_PCI_DEVICE(0x9DF0, 0x0000, iwl9460_2ac_cfg_soc)}, |
605 | {IWL_PCI_DEVICE(0x9DF0, 0x0010, iwl9460_2ac_cfg_soc)}, | 719 | {IWL_PCI_DEVICE(0x9DF0, 0x0010, iwl9460_2ac_cfg_soc)}, |
606 | {IWL_PCI_DEVICE(0x9DF0, 0x0030, iwl9560_2ac_cfg_soc)}, | 720 | {IWL_PCI_DEVICE(0x9DF0, 0x0030, iwl9560_2ac_cfg_soc)}, |
@@ -626,11 +740,44 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
626 | {IWL_PCI_DEVICE(0x9DF0, 0x0610, iwl9460_2ac_cfg_soc)}, | 740 | {IWL_PCI_DEVICE(0x9DF0, 0x0610, iwl9460_2ac_cfg_soc)}, |
627 | {IWL_PCI_DEVICE(0x9DF0, 0x0710, iwl9460_2ac_cfg_soc)}, | 741 | {IWL_PCI_DEVICE(0x9DF0, 0x0710, iwl9460_2ac_cfg_soc)}, |
628 | {IWL_PCI_DEVICE(0x9DF0, 0x0A10, iwl9460_2ac_cfg_soc)}, | 742 | {IWL_PCI_DEVICE(0x9DF0, 0x0A10, iwl9460_2ac_cfg_soc)}, |
743 | {IWL_PCI_DEVICE(0x9DF0, 0x1010, iwl9260_2ac_cfg)}, | ||
744 | {IWL_PCI_DEVICE(0x9DF0, 0x1030, iwl9560_2ac_cfg_soc)}, | ||
745 | {IWL_PCI_DEVICE(0x9DF0, 0x1210, iwl9260_2ac_cfg)}, | ||
629 | {IWL_PCI_DEVICE(0x9DF0, 0x2010, iwl9460_2ac_cfg_soc)}, | 746 | {IWL_PCI_DEVICE(0x9DF0, 0x2010, iwl9460_2ac_cfg_soc)}, |
747 | {IWL_PCI_DEVICE(0x9DF0, 0x2030, iwl9560_2ac_cfg_soc)}, | ||
748 | {IWL_PCI_DEVICE(0x9DF0, 0x2034, iwl9560_2ac_cfg_soc)}, | ||
630 | {IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl9460_2ac_cfg_soc)}, | 749 | {IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl9460_2ac_cfg_soc)}, |
631 | {IWL_PCI_DEVICE(0x9DF0, 0x4030, iwl9560_2ac_cfg_soc)}, | 750 | {IWL_PCI_DEVICE(0x9DF0, 0x4030, iwl9560_2ac_cfg_soc)}, |
632 | {IWL_PCI_DEVICE(0x9DF0, 0x4034, iwl9560_2ac_cfg_soc)}, | 751 | {IWL_PCI_DEVICE(0x9DF0, 0x4034, iwl9560_2ac_cfg_soc)}, |
633 | {IWL_PCI_DEVICE(0x9DF0, 0x40A4, iwl9462_2ac_cfg_soc)}, | 752 | {IWL_PCI_DEVICE(0x9DF0, 0x40A4, iwl9462_2ac_cfg_soc)}, |
753 | {IWL_PCI_DEVICE(0x9DF0, 0x4234, iwl9560_2ac_cfg_soc)}, | ||
754 | {IWL_PCI_DEVICE(0x9DF0, 0x42A4, iwl9462_2ac_cfg_soc)}, | ||
755 | {IWL_PCI_DEVICE(0xA0F0, 0x0030, iwl9560_2ac_cfg_soc)}, | ||
756 | {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_soc)}, | ||
757 | {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_cfg_soc)}, | ||
758 | {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_cfg_soc)}, | ||
759 | {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_soc)}, | ||
760 | {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_soc)}, | ||
761 | {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_soc)}, | ||
762 | {IWL_PCI_DEVICE(0xA0F0, 0x00A4, iwl9462_2ac_cfg_soc)}, | ||
763 | {IWL_PCI_DEVICE(0xA0F0, 0x0230, iwl9560_2ac_cfg_soc)}, | ||
764 | {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_soc)}, | ||
765 | {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_soc)}, | ||
766 | {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_soc)}, | ||
767 | {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_soc)}, | ||
768 | {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_soc)}, | ||
769 | {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_soc)}, | ||
770 | {IWL_PCI_DEVICE(0xA0F0, 0x02A4, iwl9462_2ac_cfg_soc)}, | ||
771 | {IWL_PCI_DEVICE(0xA0F0, 0x1010, iwl9260_2ac_cfg)}, | ||
772 | {IWL_PCI_DEVICE(0xA0F0, 0x1030, iwl9560_2ac_cfg_soc)}, | ||
773 | {IWL_PCI_DEVICE(0xA0F0, 0x1210, iwl9260_2ac_cfg)}, | ||
774 | {IWL_PCI_DEVICE(0xA0F0, 0x2030, iwl9560_2ac_cfg_soc)}, | ||
775 | {IWL_PCI_DEVICE(0xA0F0, 0x2034, iwl9560_2ac_cfg_soc)}, | ||
776 | {IWL_PCI_DEVICE(0xA0F0, 0x4030, iwl9560_2ac_cfg_soc)}, | ||
777 | {IWL_PCI_DEVICE(0xA0F0, 0x4034, iwl9560_2ac_cfg_soc)}, | ||
778 | {IWL_PCI_DEVICE(0xA0F0, 0x40A4, iwl9462_2ac_cfg_soc)}, | ||
779 | {IWL_PCI_DEVICE(0xA0F0, 0x4234, iwl9560_2ac_cfg_soc)}, | ||
780 | {IWL_PCI_DEVICE(0xA0F0, 0x42A4, iwl9462_2ac_cfg_soc)}, | ||
634 | {IWL_PCI_DEVICE(0xA370, 0x0030, iwl9560_2ac_cfg_soc)}, | 781 | {IWL_PCI_DEVICE(0xA370, 0x0030, iwl9560_2ac_cfg_soc)}, |
635 | {IWL_PCI_DEVICE(0xA370, 0x0034, iwl9560_2ac_cfg_soc)}, | 782 | {IWL_PCI_DEVICE(0xA370, 0x0034, iwl9560_2ac_cfg_soc)}, |
636 | {IWL_PCI_DEVICE(0xA370, 0x0038, iwl9560_2ac_cfg_soc)}, | 783 | {IWL_PCI_DEVICE(0xA370, 0x0038, iwl9560_2ac_cfg_soc)}, |
@@ -647,10 +794,16 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
647 | {IWL_PCI_DEVICE(0xA370, 0x0264, iwl9461_2ac_cfg_soc)}, | 794 | {IWL_PCI_DEVICE(0xA370, 0x0264, iwl9461_2ac_cfg_soc)}, |
648 | {IWL_PCI_DEVICE(0xA370, 0x02A0, iwl9462_2ac_cfg_soc)}, | 795 | {IWL_PCI_DEVICE(0xA370, 0x02A0, iwl9462_2ac_cfg_soc)}, |
649 | {IWL_PCI_DEVICE(0xA370, 0x02A4, iwl9462_2ac_cfg_soc)}, | 796 | {IWL_PCI_DEVICE(0xA370, 0x02A4, iwl9462_2ac_cfg_soc)}, |
797 | {IWL_PCI_DEVICE(0xA370, 0x1010, iwl9260_2ac_cfg)}, | ||
650 | {IWL_PCI_DEVICE(0xA370, 0x1030, iwl9560_2ac_cfg_soc)}, | 798 | {IWL_PCI_DEVICE(0xA370, 0x1030, iwl9560_2ac_cfg_soc)}, |
799 | {IWL_PCI_DEVICE(0xA370, 0x1210, iwl9260_2ac_cfg)}, | ||
800 | {IWL_PCI_DEVICE(0xA370, 0x2030, iwl9560_2ac_cfg_soc)}, | ||
801 | {IWL_PCI_DEVICE(0xA370, 0x2034, iwl9560_2ac_cfg_soc)}, | ||
651 | {IWL_PCI_DEVICE(0xA370, 0x4030, iwl9560_2ac_cfg_soc)}, | 802 | {IWL_PCI_DEVICE(0xA370, 0x4030, iwl9560_2ac_cfg_soc)}, |
652 | {IWL_PCI_DEVICE(0xA370, 0x4034, iwl9560_2ac_cfg_soc)}, | 803 | {IWL_PCI_DEVICE(0xA370, 0x4034, iwl9560_2ac_cfg_soc)}, |
653 | {IWL_PCI_DEVICE(0xA370, 0x40A4, iwl9462_2ac_cfg_soc)}, | 804 | {IWL_PCI_DEVICE(0xA370, 0x40A4, iwl9462_2ac_cfg_soc)}, |
805 | {IWL_PCI_DEVICE(0xA370, 0x4234, iwl9560_2ac_cfg_soc)}, | ||
806 | {IWL_PCI_DEVICE(0xA370, 0x42A4, iwl9462_2ac_cfg_soc)}, | ||
654 | 807 | ||
655 | /* 22000 Series */ | 808 | /* 22000 Series */ |
656 | {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl22000_2ac_cfg_hr_cdb)}, | 809 | {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl22000_2ac_cfg_hr_cdb)}, |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index b406b536c850..f8a0234d332c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c | |||
@@ -2616,12 +2616,12 @@ int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans) | |||
2616 | { | 2616 | { |
2617 | struct dentry *dir = trans->dbgfs_dir; | 2617 | struct dentry *dir = trans->dbgfs_dir; |
2618 | 2618 | ||
2619 | DEBUGFS_ADD_FILE(rx_queue, dir, S_IRUSR); | 2619 | DEBUGFS_ADD_FILE(rx_queue, dir, 0400); |
2620 | DEBUGFS_ADD_FILE(tx_queue, dir, S_IRUSR); | 2620 | DEBUGFS_ADD_FILE(tx_queue, dir, 0400); |
2621 | DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); | 2621 | DEBUGFS_ADD_FILE(interrupt, dir, 0600); |
2622 | DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); | 2622 | DEBUGFS_ADD_FILE(csr, dir, 0200); |
2623 | DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); | 2623 | DEBUGFS_ADD_FILE(fh_reg, dir, 0400); |
2624 | DEBUGFS_ADD_FILE(rfkill, dir, S_IWUSR | S_IRUSR); | 2624 | DEBUGFS_ADD_FILE(rfkill, dir, 0600); |
2625 | return 0; | 2625 | return 0; |
2626 | 2626 | ||
2627 | err: | 2627 | err: |
diff --git a/drivers/net/wireless/intersil/p54/main.c b/drivers/net/wireless/intersil/p54/main.c index ab6d39e12069..1c6d428515a4 100644 --- a/drivers/net/wireless/intersil/p54/main.c +++ b/drivers/net/wireless/intersil/p54/main.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "lmac.h" | 27 | #include "lmac.h" |
28 | 28 | ||
29 | static bool modparam_nohwcrypt; | 29 | static bool modparam_nohwcrypt; |
30 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 30 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); |
31 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 31 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
32 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); | 32 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); |
33 | MODULE_DESCRIPTION("Softmac Prism54 common code"); | 33 | MODULE_DESCRIPTION("Softmac Prism54 common code"); |
diff --git a/drivers/net/wireless/marvell/mwifiex/11n.c b/drivers/net/wireless/marvell/mwifiex/11n.c index feebfdcf025a..5d75c971004b 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n.c +++ b/drivers/net/wireless/marvell/mwifiex/11n.c | |||
@@ -356,17 +356,19 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
356 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 356 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
357 | if (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) { | 357 | if (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) { |
358 | ht_cap->ht_cap.cap_info &= | 358 | ht_cap->ht_cap.cap_info &= |
359 | ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 359 | cpu_to_le16 |
360 | (~IEEE80211_HT_CAP_SUP_WIDTH_20_40); | ||
360 | ht_cap->ht_cap.cap_info &= | 361 | ht_cap->ht_cap.cap_info &= |
361 | ~IEEE80211_HT_CAP_SGI_40; | 362 | cpu_to_le16(~IEEE80211_HT_CAP_SGI_40); |
362 | } | 363 | } |
363 | break; | 364 | break; |
364 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | 365 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
365 | if (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) { | 366 | if (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) { |
366 | ht_cap->ht_cap.cap_info &= | 367 | ht_cap->ht_cap.cap_info &= |
367 | ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 368 | cpu_to_le16 |
369 | (~IEEE80211_HT_CAP_SUP_WIDTH_20_40); | ||
368 | ht_cap->ht_cap.cap_info &= | 370 | ht_cap->ht_cap.cap_info &= |
369 | ~IEEE80211_HT_CAP_SGI_40; | 371 | cpu_to_le16(~IEEE80211_HT_CAP_SGI_40); |
370 | } | 372 | } |
371 | break; | 373 | break; |
372 | } | 374 | } |
diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c index c121b502a462..a38d05dea599 100644 --- a/drivers/net/wireless/mediatek/mt76/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/debugfs.c | |||
@@ -64,13 +64,13 @@ struct dentry *mt76_register_debugfs(struct mt76_dev *dev) | |||
64 | if (!dir) | 64 | if (!dir) |
65 | return NULL; | 65 | return NULL; |
66 | 66 | ||
67 | debugfs_create_u8("led_pin", S_IRUSR | S_IWUSR, dir, &dev->led_pin); | 67 | debugfs_create_u8("led_pin", 0600, dir, &dev->led_pin); |
68 | debugfs_create_u32("regidx", S_IRUSR | S_IWUSR, dir, &dev->debugfs_reg); | 68 | debugfs_create_u32("regidx", 0600, dir, &dev->debugfs_reg); |
69 | debugfs_create_file_unsafe("regval", S_IRUSR | S_IWUSR, dir, dev, | 69 | debugfs_create_file_unsafe("regval", 0600, dir, dev, |
70 | &fops_regval); | 70 | &fops_regval); |
71 | debugfs_create_blob("eeprom", S_IRUSR, dir, &dev->eeprom); | 71 | debugfs_create_blob("eeprom", 0400, dir, &dev->eeprom); |
72 | if (dev->otp.data) | 72 | if (dev->otp.data) |
73 | debugfs_create_blob("otp", S_IRUSR, dir, &dev->otp); | 73 | debugfs_create_blob("otp", 0400, dir, &dev->otp); |
74 | debugfs_create_devm_seqfile(dev->dev, "queues", dir, mt76_queues_read); | 74 | debugfs_create_devm_seqfile(dev->dev, "queues", dir, mt76_queues_read); |
75 | 75 | ||
76 | return dir; | 76 | return dir; |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c b/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c index 612feb593d7d..955ea3e692dd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c | |||
@@ -123,11 +123,11 @@ void mt76x2_init_debugfs(struct mt76x2_dev *dev) | |||
123 | if (!dir) | 123 | if (!dir) |
124 | return; | 124 | return; |
125 | 125 | ||
126 | debugfs_create_u8("temperature", S_IRUSR, dir, &dev->cal.temp); | 126 | debugfs_create_u8("temperature", 0400, dir, &dev->cal.temp); |
127 | debugfs_create_bool("tpc", S_IRUSR | S_IWUSR, dir, &dev->enable_tpc); | 127 | debugfs_create_bool("tpc", 0600, dir, &dev->enable_tpc); |
128 | 128 | ||
129 | debugfs_create_file("ampdu_stat", S_IRUSR, dir, dev, &fops_ampdu_stat); | 129 | debugfs_create_file("ampdu_stat", 0400, dir, dev, &fops_ampdu_stat); |
130 | debugfs_create_file("dfs_stats", S_IRUSR, dir, dev, &fops_dfs_stat); | 130 | debugfs_create_file("dfs_stats", 0400, dir, dev, &fops_dfs_stat); |
131 | debugfs_create_devm_seqfile(dev->mt76.dev, "txpower", dir, | 131 | debugfs_create_devm_seqfile(dev->mt76.dev, "txpower", dir, |
132 | read_txpower); | 132 | read_txpower); |
133 | } | 133 | } |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 25f4cebef26d..73c127f92613 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c | |||
@@ -336,6 +336,17 @@ mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
336 | int idx = key->keyidx; | 336 | int idx = key->keyidx; |
337 | int ret; | 337 | int ret; |
338 | 338 | ||
339 | /* fall back to sw encryption for unsupported ciphers */ | ||
340 | switch (key->cipher) { | ||
341 | case WLAN_CIPHER_SUITE_WEP40: | ||
342 | case WLAN_CIPHER_SUITE_WEP104: | ||
343 | case WLAN_CIPHER_SUITE_TKIP: | ||
344 | case WLAN_CIPHER_SUITE_CCMP: | ||
345 | break; | ||
346 | default: | ||
347 | return -EOPNOTSUPP; | ||
348 | } | ||
349 | |||
339 | /* | 350 | /* |
340 | * The hardware does not support per-STA RX GTK, fall back | 351 | * The hardware does not support per-STA RX GTK, fall back |
341 | * to software mode for these. | 352 | * to software mode for these. |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index 15820b11f9db..dfd36d736b06 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c | |||
@@ -187,7 +187,7 @@ mt76pci_load_firmware(struct mt76x2_dev *dev) | |||
187 | { | 187 | { |
188 | const struct firmware *fw; | 188 | const struct firmware *fw; |
189 | const struct mt76x2_fw_header *hdr; | 189 | const struct mt76x2_fw_header *hdr; |
190 | int i, len, ret; | 190 | int len, ret; |
191 | __le32 *cur; | 191 | __le32 *cur; |
192 | u32 offset, val; | 192 | u32 offset, val; |
193 | 193 | ||
@@ -240,16 +240,7 @@ mt76pci_load_firmware(struct mt76x2_dev *dev) | |||
240 | 240 | ||
241 | /* trigger firmware */ | 241 | /* trigger firmware */ |
242 | mt76_wr(dev, MT_MCU_INT_LEVEL, 2); | 242 | mt76_wr(dev, MT_MCU_INT_LEVEL, 2); |
243 | for (i = 200; i > 0; i--) { | 243 | if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 200)) { |
244 | val = mt76_rr(dev, MT_MCU_COM_REG0); | ||
245 | |||
246 | if (val & 1) | ||
247 | break; | ||
248 | |||
249 | msleep(10); | ||
250 | } | ||
251 | |||
252 | if (!i) { | ||
253 | dev_err(dev->mt76.dev, "Firmware failed to start\n"); | 244 | dev_err(dev->mt76.dev, "Firmware failed to start\n"); |
254 | release_firmware(fw); | 245 | release_firmware(fw); |
255 | return -ETIMEDOUT; | 246 | return -ETIMEDOUT; |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c index 534e4bf9a34c..e46eafc4c436 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c | |||
@@ -36,9 +36,12 @@ void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, | |||
36 | 36 | ||
37 | msta = (struct mt76x2_sta *) control->sta->drv_priv; | 37 | msta = (struct mt76x2_sta *) control->sta->drv_priv; |
38 | wcid = &msta->wcid; | 38 | wcid = &msta->wcid; |
39 | /* sw encrypted frames */ | ||
40 | if (!info->control.hw_key && wcid->hw_key_idx != -1) | ||
41 | control->sta = NULL; | ||
39 | } | 42 | } |
40 | 43 | ||
41 | if (vif || (!info->control.hw_key && wcid->hw_key_idx != -1)) { | 44 | if (vif && !control->sta) { |
42 | struct mt76x2_vif *mvif; | 45 | struct mt76x2_vif *mvif; |
43 | 46 | ||
44 | mvif = (struct mt76x2_vif *) vif->drv_priv; | 47 | mvif = (struct mt76x2_vif *) vif->drv_priv; |
diff --git a/drivers/net/wireless/mediatek/mt7601u/debugfs.c b/drivers/net/wireless/mediatek/mt7601u/debugfs.c index fc008475a03b..991a6a729b1e 100644 --- a/drivers/net/wireless/mediatek/mt7601u/debugfs.c +++ b/drivers/net/wireless/mediatek/mt7601u/debugfs.c | |||
@@ -160,13 +160,11 @@ void mt7601u_init_debugfs(struct mt7601u_dev *dev) | |||
160 | if (!dir) | 160 | if (!dir) |
161 | return; | 161 | return; |
162 | 162 | ||
163 | debugfs_create_u8("temperature", S_IRUSR, dir, &dev->raw_temp); | 163 | debugfs_create_u8("temperature", 0400, dir, &dev->raw_temp); |
164 | debugfs_create_u32("temp_mode", S_IRUSR, dir, &dev->temp_mode); | 164 | debugfs_create_u32("temp_mode", 0400, dir, &dev->temp_mode); |
165 | 165 | ||
166 | debugfs_create_u32("regidx", S_IRUSR | S_IWUSR, dir, &dev->debugfs_reg); | 166 | debugfs_create_u32("regidx", 0600, dir, &dev->debugfs_reg); |
167 | debugfs_create_file("regval", S_IRUSR | S_IWUSR, dir, dev, | 167 | debugfs_create_file("regval", 0600, dir, dev, &fops_regval); |
168 | &fops_regval); | 168 | debugfs_create_file("ampdu_stat", 0400, dir, dev, &fops_ampdu_stat); |
169 | debugfs_create_file("ampdu_stat", S_IRUSR, dir, dev, &fops_ampdu_stat); | 169 | debugfs_create_file("eeprom_param", 0400, dir, dev, &fops_eeprom_param); |
170 | debugfs_create_file("eeprom_param", S_IRUSR, dir, dev, | ||
171 | &fops_eeprom_param); | ||
172 | } | 170 | } |
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c index f4b48b77c491..3df8c4b895e7 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c | |||
@@ -37,7 +37,7 @@ | |||
37 | * Allow hardware encryption to be disabled. | 37 | * Allow hardware encryption to be disabled. |
38 | */ | 38 | */ |
39 | static bool modparam_nohwcrypt; | 39 | static bool modparam_nohwcrypt; |
40 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 40 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); |
41 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 41 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
42 | 42 | ||
43 | /* | 43 | /* |
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c index 5cf655ff1430..1172eefd1c1a 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c | |||
@@ -49,7 +49,7 @@ | |||
49 | * Allow hardware encryption to be disabled. | 49 | * Allow hardware encryption to be disabled. |
50 | */ | 50 | */ |
51 | static bool modparam_nohwcrypt = false; | 51 | static bool modparam_nohwcrypt = false; |
52 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 52 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); |
53 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 53 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
54 | 54 | ||
55 | static bool rt2800pci_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) | 55 | static bool rt2800pci_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) |
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c index a985a5a7945e..6848ebc83534 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | /* Allow hardware encryption to be disabled. */ | 42 | /* Allow hardware encryption to be disabled. */ |
43 | static bool modparam_nohwcrypt; | 43 | static bool modparam_nohwcrypt; |
44 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 44 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); |
45 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 45 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
46 | 46 | ||
47 | static bool rt2800soc_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) | 47 | static bool rt2800soc_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) |
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c index 24fc6d2045ef..d901a41d36e4 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c | |||
@@ -43,7 +43,7 @@ | |||
43 | * Allow hardware encryption to be disabled. | 43 | * Allow hardware encryption to be disabled. |
44 | */ | 44 | */ |
45 | static bool modparam_nohwcrypt; | 45 | static bool modparam_nohwcrypt; |
46 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 46 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); |
47 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 47 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
48 | 48 | ||
49 | static bool rt2800usb_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) | 49 | static bool rt2800usb_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) |
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c index ac2572943ed0..0eee479583b8 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | |||
@@ -606,7 +606,7 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name, | |||
606 | data += sprintf(data, "version:\t%s\n", DRV_VERSION); | 606 | data += sprintf(data, "version:\t%s\n", DRV_VERSION); |
607 | blob->size = strlen(blob->data); | 607 | blob->size = strlen(blob->data); |
608 | 608 | ||
609 | return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob); | 609 | return debugfs_create_blob(name, 0400, intf->driver_folder, blob); |
610 | } | 610 | } |
611 | 611 | ||
612 | static struct dentry *rt2x00debug_create_file_chipset(const char *name, | 612 | static struct dentry *rt2x00debug_create_file_chipset(const char *name, |
@@ -647,7 +647,7 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name, | |||
647 | 647 | ||
648 | blob->size = strlen(blob->data); | 648 | blob->size = strlen(blob->data); |
649 | 649 | ||
650 | return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob); | 650 | return debugfs_create_blob(name, 0400, intf->driver_folder, blob); |
651 | } | 651 | } |
652 | 652 | ||
653 | void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | 653 | void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) |
@@ -682,13 +682,13 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
682 | if (IS_ERR(intf->chipset_entry) || !intf->chipset_entry) | 682 | if (IS_ERR(intf->chipset_entry) || !intf->chipset_entry) |
683 | goto exit; | 683 | goto exit; |
684 | 684 | ||
685 | intf->dev_flags = debugfs_create_file("dev_flags", S_IRUSR, | 685 | intf->dev_flags = debugfs_create_file("dev_flags", 0400, |
686 | intf->driver_folder, intf, | 686 | intf->driver_folder, intf, |
687 | &rt2x00debug_fop_dev_flags); | 687 | &rt2x00debug_fop_dev_flags); |
688 | if (IS_ERR(intf->dev_flags) || !intf->dev_flags) | 688 | if (IS_ERR(intf->dev_flags) || !intf->dev_flags) |
689 | goto exit; | 689 | goto exit; |
690 | 690 | ||
691 | intf->cap_flags = debugfs_create_file("cap_flags", S_IRUSR, | 691 | intf->cap_flags = debugfs_create_file("cap_flags", 0400, |
692 | intf->driver_folder, intf, | 692 | intf->driver_folder, intf, |
693 | &rt2x00debug_fop_cap_flags); | 693 | &rt2x00debug_fop_cap_flags); |
694 | if (IS_ERR(intf->cap_flags) || !intf->cap_flags) | 694 | if (IS_ERR(intf->cap_flags) || !intf->cap_flags) |
@@ -699,27 +699,28 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
699 | if (IS_ERR(intf->register_folder) || !intf->register_folder) | 699 | if (IS_ERR(intf->register_folder) || !intf->register_folder) |
700 | goto exit; | 700 | goto exit; |
701 | 701 | ||
702 | #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name) \ | 702 | #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name) \ |
703 | ({ \ | 703 | ({ \ |
704 | if (debug->__name.read) { \ | 704 | if (debug->__name.read) { \ |
705 | (__intf)->__name##_off_entry = \ | 705 | (__intf)->__name##_off_entry = \ |
706 | debugfs_create_u32(__stringify(__name) "_offset", \ | 706 | debugfs_create_u32(__stringify(__name) "_offset", \ |
707 | S_IRUSR | S_IWUSR, \ | 707 | 0600, \ |
708 | (__intf)->register_folder, \ | 708 | (__intf)->register_folder, \ |
709 | &(__intf)->offset_##__name); \ | 709 | &(__intf)->offset_##__name); \ |
710 | if (IS_ERR((__intf)->__name##_off_entry) \ | 710 | if (IS_ERR((__intf)->__name##_off_entry) || \ |
711 | || !(__intf)->__name##_off_entry) \ | 711 | !(__intf)->__name##_off_entry) \ |
712 | goto exit; \ | 712 | goto exit; \ |
713 | \ | 713 | \ |
714 | (__intf)->__name##_val_entry = \ | 714 | (__intf)->__name##_val_entry = \ |
715 | debugfs_create_file(__stringify(__name) "_value", \ | 715 | debugfs_create_file(__stringify(__name) "_value", \ |
716 | S_IRUSR | S_IWUSR, \ | 716 | 0600, \ |
717 | (__intf)->register_folder, \ | 717 | (__intf)->register_folder, \ |
718 | (__intf), &rt2x00debug_fop_##__name); \ | 718 | (__intf), \ |
719 | if (IS_ERR((__intf)->__name##_val_entry) \ | 719 | &rt2x00debug_fop_##__name); \ |
720 | || !(__intf)->__name##_val_entry) \ | 720 | if (IS_ERR((__intf)->__name##_val_entry) || \ |
721 | goto exit; \ | 721 | !(__intf)->__name##_val_entry) \ |
722 | } \ | 722 | goto exit; \ |
723 | } \ | ||
723 | }) | 724 | }) |
724 | 725 | ||
725 | RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr); | 726 | RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr); |
@@ -736,8 +737,8 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
736 | goto exit; | 737 | goto exit; |
737 | 738 | ||
738 | intf->queue_frame_dump_entry = | 739 | intf->queue_frame_dump_entry = |
739 | debugfs_create_file("dump", S_IRUSR, intf->queue_folder, | 740 | debugfs_create_file("dump", 0400, intf->queue_folder, |
740 | intf, &rt2x00debug_fop_queue_dump); | 741 | intf, &rt2x00debug_fop_queue_dump); |
741 | if (IS_ERR(intf->queue_frame_dump_entry) | 742 | if (IS_ERR(intf->queue_frame_dump_entry) |
742 | || !intf->queue_frame_dump_entry) | 743 | || !intf->queue_frame_dump_entry) |
743 | goto exit; | 744 | goto exit; |
@@ -746,14 +747,15 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
746 | init_waitqueue_head(&intf->frame_dump_waitqueue); | 747 | init_waitqueue_head(&intf->frame_dump_waitqueue); |
747 | 748 | ||
748 | intf->queue_stats_entry = | 749 | intf->queue_stats_entry = |
749 | debugfs_create_file("queue", S_IRUSR, intf->queue_folder, | 750 | debugfs_create_file("queue", 0400, intf->queue_folder, |
750 | intf, &rt2x00debug_fop_queue_stats); | 751 | intf, &rt2x00debug_fop_queue_stats); |
751 | 752 | ||
752 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 753 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
753 | if (rt2x00_has_cap_hw_crypto(rt2x00dev)) | 754 | if (rt2x00_has_cap_hw_crypto(rt2x00dev)) |
754 | intf->crypto_stats_entry = | 755 | intf->crypto_stats_entry = |
755 | debugfs_create_file("crypto", S_IRUGO, intf->queue_folder, | 756 | debugfs_create_file("crypto", 0444, intf->queue_folder, |
756 | intf, &rt2x00debug_fop_crypto_stats); | 757 | intf, |
758 | &rt2x00debug_fop_crypto_stats); | ||
757 | #endif | 759 | #endif |
758 | 760 | ||
759 | return; | 761 | return; |
diff --git a/drivers/net/wireless/ralink/rt2x00/rt61pci.c b/drivers/net/wireless/ralink/rt2x00/rt61pci.c index 234310200759..cb0e1196f2c2 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c +++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c | |||
@@ -40,7 +40,7 @@ | |||
40 | * Allow hardware encryption to be disabled. | 40 | * Allow hardware encryption to be disabled. |
41 | */ | 41 | */ |
42 | static bool modparam_nohwcrypt = false; | 42 | static bool modparam_nohwcrypt = false; |
43 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 43 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); |
44 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 44 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
45 | 45 | ||
46 | /* | 46 | /* |
diff --git a/drivers/net/wireless/ralink/rt2x00/rt73usb.c b/drivers/net/wireless/ralink/rt2x00/rt73usb.c index 9a212823f42c..319ec4f2d9d2 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c | |||
@@ -38,7 +38,7 @@ | |||
38 | * Allow hardware encryption to be disabled. | 38 | * Allow hardware encryption to be disabled. |
39 | */ | 39 | */ |
40 | static bool modparam_nohwcrypt; | 40 | static bool modparam_nohwcrypt; |
41 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 41 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); |
42 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 42 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
43 | 43 | ||
44 | /* | 44 | /* |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 0133fcd4601b..7f9b16b97ea3 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -2815,9 +2815,11 @@ static int __init init_ray_cs(void) | |||
2815 | proc_mkdir("driver/ray_cs", NULL); | 2815 | proc_mkdir("driver/ray_cs", NULL); |
2816 | 2816 | ||
2817 | proc_create("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_fops); | 2817 | proc_create("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_fops); |
2818 | proc_create("driver/ray_cs/essid", S_IWUSR, NULL, &ray_cs_essid_proc_fops); | 2818 | proc_create("driver/ray_cs/essid", 0200, NULL, &ray_cs_essid_proc_fops); |
2819 | proc_create_data("driver/ray_cs/net_type", S_IWUSR, NULL, &int_proc_fops, &net_type); | 2819 | proc_create_data("driver/ray_cs/net_type", 0200, NULL, &int_proc_fops, |
2820 | proc_create_data("driver/ray_cs/translate", S_IWUSR, NULL, &int_proc_fops, &translate); | 2820 | &net_type); |
2821 | proc_create_data("driver/ray_cs/translate", 0200, NULL, &int_proc_fops, | ||
2822 | &translate); | ||
2821 | #endif | 2823 | #endif |
2822 | if (translate != 0) | 2824 | if (translate != 0) |
2823 | translate = 1; | 2825 | translate = 1; |
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index 6db3389e2ced..762a29cdf7ad 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c | |||
@@ -1549,7 +1549,6 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx, | |||
1549 | /* EAPOL is seens as in-4way */ | 1549 | /* EAPOL is seens as in-4way */ |
1550 | rtlpriv->btcoexist.btc_info.in_4way = true; | 1550 | rtlpriv->btcoexist.btc_info.in_4way = true; |
1551 | rtlpriv->btcoexist.btc_info.in_4way_ts = jiffies; | 1551 | rtlpriv->btcoexist.btc_info.in_4way_ts = jiffies; |
1552 | rtlpriv->btcoexist.btc_info.in_4way_ts = jiffies; | ||
1553 | 1552 | ||
1554 | RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, | 1553 | RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, |
1555 | "802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"); | 1554 | "802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"); |
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c index 05beb16f0a0a..59553db020ef 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c | |||
@@ -1436,6 +1436,7 @@ static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist, | |||
1436 | coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; | 1436 | coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; |
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | static | ||
1439 | void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, | 1440 | void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, |
1440 | u8 wifi_status) | 1441 | u8 wifi_status) |
1441 | { | 1442 | { |
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c index 4907c2ffadfe..73ec31972944 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c | |||
@@ -833,9 +833,9 @@ static void btc8723b2ant_set_sw_fulltime_dac_swing(struct btc_coexist *btcoex, | |||
833 | btc8723b2ant_set_dac_swing_reg(btcoex, 0x18); | 833 | btc8723b2ant_set_dac_swing_reg(btcoex, 0x18); |
834 | } | 834 | } |
835 | 835 | ||
836 | void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist, | 836 | static void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist, |
837 | bool force_exec, bool dac_swing_on, | 837 | bool force_exec, bool dac_swing_on, |
838 | u32 dac_swing_lvl) | 838 | u32 dac_swing_lvl) |
839 | { | 839 | { |
840 | struct rtl_priv *rtlpriv = btcoexist->adapter; | 840 | struct rtl_priv *rtlpriv = btcoexist->adapter; |
841 | 841 | ||
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c index 0b26419881c0..202597cf8915 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c | |||
@@ -426,39 +426,6 @@ static void btc8821a1ant_query_bt_info(struct btc_coexist *btcoexist) | |||
426 | btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); | 426 | btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); |
427 | } | 427 | } |
428 | 428 | ||
429 | bool btc8821a1ant_is_wifi_status_changed(struct btc_coexist *btcoexist) | ||
430 | { | ||
431 | static bool pre_wifi_busy = true; | ||
432 | static bool pre_under_4way = true; | ||
433 | static bool pre_bt_hs_on = true; | ||
434 | bool wifi_busy = false, under_4way = false, bt_hs_on = false; | ||
435 | bool wifi_connected = false; | ||
436 | |||
437 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
438 | &wifi_connected); | ||
439 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
440 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
441 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, | ||
442 | &under_4way); | ||
443 | |||
444 | if (wifi_connected) { | ||
445 | if (wifi_busy != pre_wifi_busy) { | ||
446 | pre_wifi_busy = wifi_busy; | ||
447 | return true; | ||
448 | } | ||
449 | if (under_4way != pre_under_4way) { | ||
450 | pre_under_4way = under_4way; | ||
451 | return true; | ||
452 | } | ||
453 | if (bt_hs_on != pre_bt_hs_on) { | ||
454 | pre_bt_hs_on = bt_hs_on; | ||
455 | return true; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | return false; | ||
460 | } | ||
461 | |||
462 | static void btc8821a1ant_update_bt_link_info(struct btc_coexist *btcoexist) | 429 | static void btc8821a1ant_update_bt_link_info(struct btc_coexist *btcoexist) |
463 | { | 430 | { |
464 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | 431 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; |
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c index d5f282cb9d24..2202d5e18977 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c | |||
@@ -359,7 +359,7 @@ static void btc8821a2ant_query_bt_info(struct btc_coexist *btcoexist) | |||
359 | btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); | 359 | btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); |
360 | } | 360 | } |
361 | 361 | ||
362 | bool btc8821a2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) | 362 | static bool btc8821a2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) |
363 | { | 363 | { |
364 | static bool pre_wifi_busy = true; | 364 | static bool pre_wifi_busy = true; |
365 | static bool pre_under_4way = true; | 365 | static bool pre_under_4way = true; |
@@ -1517,7 +1517,7 @@ static void btc8821a2ant_action_bt_inquiry(struct btc_coexist *btcoexist) | |||
1517 | btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); | 1517 | btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | void btc8821a2ant_action_wifi_link_process(struct btc_coexist *btcoexist) | 1520 | static void btc8821a2ant_action_wifi_link_process(struct btc_coexist *btcoexist) |
1521 | { | 1521 | { |
1522 | struct rtl_priv *rtlpriv = btcoexist->adapter; | 1522 | struct rtl_priv *rtlpriv = btcoexist->adapter; |
1523 | u8 u8tmpa, u8tmpb; | 1523 | u8 u8tmpa, u8tmpb; |
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c index 823694cb4fdb..8b6b07a936f5 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c | |||
@@ -363,6 +363,22 @@ static void halbtc_normal_lps(struct btc_coexist *btcoexist) | |||
363 | } | 363 | } |
364 | } | 364 | } |
365 | 365 | ||
366 | static void halbtc_pre_normal_lps(struct btc_coexist *btcoexist) | ||
367 | { | ||
368 | struct rtl_priv *rtlpriv = btcoexist->adapter; | ||
369 | |||
370 | if (btcoexist->bt_info.bt_ctrl_lps) { | ||
371 | btcoexist->bt_info.bt_lps_on = false; | ||
372 | rtl_lps_leave(rtlpriv->mac80211.hw); | ||
373 | } | ||
374 | } | ||
375 | |||
376 | static void halbtc_post_normal_lps(struct btc_coexist *btcoexist) | ||
377 | { | ||
378 | if (btcoexist->bt_info.bt_ctrl_lps) | ||
379 | btcoexist->bt_info.bt_ctrl_lps = false; | ||
380 | } | ||
381 | |||
366 | static void halbtc_leave_low_power(struct btc_coexist *btcoexist) | 382 | static void halbtc_leave_low_power(struct btc_coexist *btcoexist) |
367 | { | 383 | { |
368 | } | 384 | } |
@@ -577,6 +593,9 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf) | |||
577 | tmp = true; | 593 | tmp = true; |
578 | *bool_tmp = tmp; | 594 | *bool_tmp = tmp; |
579 | break; | 595 | break; |
596 | case BTC_GET_BL_WIFI_DUAL_BAND_CONNECTED: | ||
597 | *u8_tmp = BTC_MULTIPORT_SCC; | ||
598 | break; | ||
580 | case BTC_GET_BL_WIFI_BUSY: | 599 | case BTC_GET_BL_WIFI_BUSY: |
581 | if (halbtc_is_wifi_busy(rtlpriv)) | 600 | if (halbtc_is_wifi_busy(rtlpriv)) |
582 | *bool_tmp = true; | 601 | *bool_tmp = true; |
@@ -637,6 +656,9 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf) | |||
637 | case BTC_GET_BL_IS_ASUS_8723B: | 656 | case BTC_GET_BL_IS_ASUS_8723B: |
638 | *bool_tmp = false; | 657 | *bool_tmp = false; |
639 | break; | 658 | break; |
659 | case BTC_GET_BL_RF4CE_CONNECTED: | ||
660 | *bool_tmp = false; | ||
661 | break; | ||
640 | case BTC_GET_S4_WIFI_RSSI: | 662 | case BTC_GET_S4_WIFI_RSSI: |
641 | *s32_tmp = halbtc_get_wifi_rssi(rtlpriv); | 663 | *s32_tmp = halbtc_get_wifi_rssi(rtlpriv); |
642 | break; | 664 | break; |
@@ -677,6 +699,21 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf) | |||
677 | case BTC_GET_U4_BT_FORBIDDEN_SLOT_VAL: | 699 | case BTC_GET_U4_BT_FORBIDDEN_SLOT_VAL: |
678 | *u32_tmp = halbtc_get_bt_forbidden_slot_val(btcoexist); | 700 | *u32_tmp = halbtc_get_bt_forbidden_slot_val(btcoexist); |
679 | break; | 701 | break; |
702 | case BTC_GET_U4_WIFI_IQK_TOTAL: | ||
703 | *u32_tmp = | ||
704 | btcoexist->btc_phydm_query_phy_counter(btcoexist, | ||
705 | DM_INFO_IQK_ALL); | ||
706 | break; | ||
707 | case BTC_GET_U4_WIFI_IQK_OK: | ||
708 | *u32_tmp = | ||
709 | btcoexist->btc_phydm_query_phy_counter(btcoexist, | ||
710 | DM_INFO_IQK_OK); | ||
711 | break; | ||
712 | case BTC_GET_U4_WIFI_IQK_FAIL: | ||
713 | *u32_tmp = | ||
714 | btcoexist->btc_phydm_query_phy_counter(btcoexist, | ||
715 | DM_INFO_IQK_NG); | ||
716 | break; | ||
680 | case BTC_GET_U1_WIFI_DOT11_CHNL: | 717 | case BTC_GET_U1_WIFI_DOT11_CHNL: |
681 | *u8_tmp = rtlphy->current_channel; | 718 | *u8_tmp = rtlphy->current_channel; |
682 | break; | 719 | break; |
@@ -788,6 +825,12 @@ static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf) | |||
788 | case BTC_SET_ACT_NORMAL_LPS: | 825 | case BTC_SET_ACT_NORMAL_LPS: |
789 | halbtc_normal_lps(btcoexist); | 826 | halbtc_normal_lps(btcoexist); |
790 | break; | 827 | break; |
828 | case BTC_SET_ACT_PRE_NORMAL_LPS: | ||
829 | halbtc_pre_normal_lps(btcoexist); | ||
830 | break; | ||
831 | case BTC_SET_ACT_POST_NORMAL_LPS: | ||
832 | halbtc_post_normal_lps(btcoexist); | ||
833 | break; | ||
791 | case BTC_SET_ACT_DISABLE_LOW_POWER: | 834 | case BTC_SET_ACT_DISABLE_LOW_POWER: |
792 | halbtc_disable_low_power(btcoexist, *bool_tmp); | 835 | halbtc_disable_low_power(btcoexist, *bool_tmp); |
793 | break; | 836 | break; |
@@ -1101,6 +1144,11 @@ static void halbtc_display_dbg_msg(void *bt_context, u8 disp_type, | |||
1101 | } | 1144 | } |
1102 | } | 1145 | } |
1103 | 1146 | ||
1147 | static u32 halbtc_get_bt_reg(void *btc_context, u8 reg_type, u32 offset) | ||
1148 | { | ||
1149 | return 0; | ||
1150 | } | ||
1151 | |||
1104 | static bool halbtc_under_ips(struct btc_coexist *btcoexist) | 1152 | static bool halbtc_under_ips(struct btc_coexist *btcoexist) |
1105 | { | 1153 | { |
1106 | struct rtl_priv *rtlpriv = btcoexist->adapter; | 1154 | struct rtl_priv *rtlpriv = btcoexist->adapter; |
@@ -1119,6 +1167,25 @@ static bool halbtc_under_ips(struct btc_coexist *btcoexist) | |||
1119 | return false; | 1167 | return false; |
1120 | } | 1168 | } |
1121 | 1169 | ||
1170 | static | ||
1171 | u32 halbtc_get_phydm_version(void *btc_context) | ||
1172 | { | ||
1173 | return 0; | ||
1174 | } | ||
1175 | |||
1176 | static | ||
1177 | void halbtc_phydm_modify_ra_pcr_threshold(void *btc_context, | ||
1178 | u8 ra_offset_direction, | ||
1179 | u8 ra_threshold_offset) | ||
1180 | { | ||
1181 | } | ||
1182 | |||
1183 | static | ||
1184 | u32 halbtc_phydm_query_phy_counter(void *btc_context, enum dm_info_query dm_id) | ||
1185 | { | ||
1186 | return 0; | ||
1187 | } | ||
1188 | |||
1122 | static u8 halbtc_get_ant_det_val_from_bt(void *btc_context) | 1189 | static u8 halbtc_get_ant_det_val_from_bt(void *btc_context) |
1123 | { | 1190 | { |
1124 | struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; | 1191 | struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; |
@@ -1232,6 +1299,7 @@ bool exhalbtc_initlize_variables(struct rtl_priv *rtlpriv) | |||
1232 | btcoexist->btc_get = halbtc_get; | 1299 | btcoexist->btc_get = halbtc_get; |
1233 | btcoexist->btc_set = halbtc_set; | 1300 | btcoexist->btc_set = halbtc_set; |
1234 | btcoexist->btc_set_bt_reg = halbtc_set_bt_reg; | 1301 | btcoexist->btc_set_bt_reg = halbtc_set_bt_reg; |
1302 | btcoexist->btc_get_bt_reg = halbtc_get_bt_reg; | ||
1235 | 1303 | ||
1236 | btcoexist->bt_info.bt_ctrl_buf_size = false; | 1304 | btcoexist->bt_info.bt_ctrl_buf_size = false; |
1237 | btcoexist->bt_info.agg_buf_size = 5; | 1305 | btcoexist->bt_info.agg_buf_size = 5; |
@@ -1242,6 +1310,10 @@ bool exhalbtc_initlize_variables(struct rtl_priv *rtlpriv) | |||
1242 | halbtc_get_bt_coex_supported_feature; | 1310 | halbtc_get_bt_coex_supported_feature; |
1243 | btcoexist->btc_get_bt_coex_supported_version = | 1311 | btcoexist->btc_get_bt_coex_supported_version = |
1244 | halbtc_get_bt_coex_supported_version; | 1312 | halbtc_get_bt_coex_supported_version; |
1313 | btcoexist->btc_get_bt_phydm_version = halbtc_get_phydm_version; | ||
1314 | btcoexist->btc_phydm_modify_ra_pcr_threshold = | ||
1315 | halbtc_phydm_modify_ra_pcr_threshold; | ||
1316 | btcoexist->btc_phydm_query_phy_counter = halbtc_phydm_query_phy_counter; | ||
1245 | btcoexist->btc_get_ant_det_val_from_bt = halbtc_get_ant_det_val_from_bt; | 1317 | btcoexist->btc_get_ant_det_val_from_bt = halbtc_get_ant_det_val_from_bt; |
1246 | btcoexist->btc_get_ble_scan_type_from_bt = | 1318 | btcoexist->btc_get_ble_scan_type_from_bt = |
1247 | halbtc_get_ble_scan_type_from_bt; | 1319 | halbtc_get_ble_scan_type_from_bt; |
@@ -1547,7 +1619,8 @@ void exhalbtc_scan_notify_wifi_only(struct wifi_only_cfg *wifionly_cfg, | |||
1547 | 1619 | ||
1548 | void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action) | 1620 | void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action) |
1549 | { | 1621 | { |
1550 | u8 asso_type; | 1622 | u8 asso_type, asso_type_v2; |
1623 | bool wifi_under_5g; | ||
1551 | 1624 | ||
1552 | if (!halbtc_is_bt_coexist_available(btcoexist)) | 1625 | if (!halbtc_is_bt_coexist_available(btcoexist)) |
1553 | return; | 1626 | return; |
@@ -1555,10 +1628,17 @@ void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action) | |||
1555 | if (btcoexist->manual_control) | 1628 | if (btcoexist->manual_control) |
1556 | return; | 1629 | return; |
1557 | 1630 | ||
1558 | if (action) | 1631 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); |
1632 | |||
1633 | if (action) { | ||
1559 | asso_type = BTC_ASSOCIATE_START; | 1634 | asso_type = BTC_ASSOCIATE_START; |
1560 | else | 1635 | asso_type_v2 = wifi_under_5g ? BTC_ASSOCIATE_5G_START : |
1636 | BTC_ASSOCIATE_START; | ||
1637 | } else { | ||
1561 | asso_type = BTC_ASSOCIATE_FINISH; | 1638 | asso_type = BTC_ASSOCIATE_FINISH; |
1639 | asso_type_v2 = wifi_under_5g ? BTC_ASSOCIATE_5G_FINISH : | ||
1640 | BTC_ASSOCIATE_FINISH; | ||
1641 | } | ||
1562 | 1642 | ||
1563 | halbtc_leave_low_power(btcoexist); | 1643 | halbtc_leave_low_power(btcoexist); |
1564 | 1644 | ||
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h index f5d8159a88eb..9eae87d19120 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h | |||
@@ -62,6 +62,8 @@ | |||
62 | #define BTC_ANT_PATH_WIFI 0 | 62 | #define BTC_ANT_PATH_WIFI 0 |
63 | #define BTC_ANT_PATH_BT 1 | 63 | #define BTC_ANT_PATH_BT 1 |
64 | #define BTC_ANT_PATH_PTA 2 | 64 | #define BTC_ANT_PATH_PTA 2 |
65 | #define BTC_ANT_PATH_WIFI5G 3 | ||
66 | #define BTC_ANT_PATH_AUTO 4 | ||
65 | /* dual Antenna definition */ | 67 | /* dual Antenna definition */ |
66 | #define BTC_ANT_WIFI_AT_MAIN 0 | 68 | #define BTC_ANT_WIFI_AT_MAIN 0 |
67 | #define BTC_ANT_WIFI_AT_AUX 1 | 69 | #define BTC_ANT_WIFI_AT_AUX 1 |
@@ -154,6 +156,7 @@ struct btc_board_info { | |||
154 | 156 | ||
155 | u8 rfe_type; | 157 | u8 rfe_type; |
156 | u8 ant_div_cfg; | 158 | u8 ant_div_cfg; |
159 | u8 customer_id; | ||
157 | }; | 160 | }; |
158 | 161 | ||
159 | enum btc_dbg_opcode { | 162 | enum btc_dbg_opcode { |
@@ -204,6 +207,7 @@ enum btc_wifi_traffic_dir { | |||
204 | enum btc_wifi_pnp { | 207 | enum btc_wifi_pnp { |
205 | BTC_WIFI_PNP_WAKE_UP = 0x0, | 208 | BTC_WIFI_PNP_WAKE_UP = 0x0, |
206 | BTC_WIFI_PNP_SLEEP = 0x1, | 209 | BTC_WIFI_PNP_SLEEP = 0x1, |
210 | BTC_WIFI_PNP_SLEEP_KEEP_ANT = 0x2, | ||
207 | BTC_WIFI_PNP_MAX | 211 | BTC_WIFI_PNP_MAX |
208 | }; | 212 | }; |
209 | 213 | ||
@@ -250,6 +254,7 @@ enum btc_get_type { | |||
250 | BTC_GET_BL_HS_OPERATION, | 254 | BTC_GET_BL_HS_OPERATION, |
251 | BTC_GET_BL_HS_CONNECTING, | 255 | BTC_GET_BL_HS_CONNECTING, |
252 | BTC_GET_BL_WIFI_CONNECTED, | 256 | BTC_GET_BL_WIFI_CONNECTED, |
257 | BTC_GET_BL_WIFI_DUAL_BAND_CONNECTED, | ||
253 | BTC_GET_BL_WIFI_BUSY, | 258 | BTC_GET_BL_WIFI_BUSY, |
254 | BTC_GET_BL_WIFI_SCAN, | 259 | BTC_GET_BL_WIFI_SCAN, |
255 | BTC_GET_BL_WIFI_LINK, | 260 | BTC_GET_BL_WIFI_LINK, |
@@ -333,6 +338,7 @@ enum btc_set_type { | |||
333 | BTC_SET_ACT_GET_BT_RSSI, | 338 | BTC_SET_ACT_GET_BT_RSSI, |
334 | BTC_SET_ACT_AGGREGATE_CTRL, | 339 | BTC_SET_ACT_AGGREGATE_CTRL, |
335 | BTC_SET_ACT_ANTPOSREGRISTRY_CTRL, | 340 | BTC_SET_ACT_ANTPOSREGRISTRY_CTRL, |
341 | BTC_SET_MIMO_PS_MODE, | ||
336 | 342 | ||
337 | /********* for 1Ant **********/ | 343 | /********* for 1Ant **********/ |
338 | /* type bool */ | 344 | /* type bool */ |
@@ -347,8 +353,11 @@ enum btc_set_type { | |||
347 | BTC_SET_ACT_LEAVE_LPS, | 353 | BTC_SET_ACT_LEAVE_LPS, |
348 | BTC_SET_ACT_ENTER_LPS, | 354 | BTC_SET_ACT_ENTER_LPS, |
349 | BTC_SET_ACT_NORMAL_LPS, | 355 | BTC_SET_ACT_NORMAL_LPS, |
356 | BTC_SET_ACT_PRE_NORMAL_LPS, | ||
357 | BTC_SET_ACT_POST_NORMAL_LPS, | ||
350 | BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT, | 358 | BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT, |
351 | BTC_SET_ACT_DISABLE_LOW_POWER, | 359 | BTC_SET_ACT_DISABLE_LOW_POWER, |
360 | BTC_SET_BL_BT_LNA_CONSTRAIN_LEVEL, | ||
352 | BTC_SET_ACT_UPDATE_RAMASK, | 361 | BTC_SET_ACT_UPDATE_RAMASK, |
353 | BTC_SET_ACT_SEND_MIMO_PS, | 362 | BTC_SET_ACT_SEND_MIMO_PS, |
354 | /* BT Coex related */ | 363 | /* BT Coex related */ |
@@ -383,6 +392,7 @@ enum btc_notify_type_lps { | |||
383 | enum btc_notify_type_scan { | 392 | enum btc_notify_type_scan { |
384 | BTC_SCAN_FINISH = 0x0, | 393 | BTC_SCAN_FINISH = 0x0, |
385 | BTC_SCAN_START = 0x1, | 394 | BTC_SCAN_START = 0x1, |
395 | BTC_SCAN_START_2G = 0x2, | ||
386 | BTC_SCAN_MAX | 396 | BTC_SCAN_MAX |
387 | }; | 397 | }; |
388 | 398 | ||
@@ -397,6 +407,8 @@ enum btc_notify_type_switchband { | |||
397 | enum btc_notify_type_associate { | 407 | enum btc_notify_type_associate { |
398 | BTC_ASSOCIATE_FINISH = 0x0, | 408 | BTC_ASSOCIATE_FINISH = 0x0, |
399 | BTC_ASSOCIATE_START = 0x1, | 409 | BTC_ASSOCIATE_START = 0x1, |
410 | BTC_ASSOCIATE_5G_FINISH = 0x2, | ||
411 | BTC_ASSOCIATE_5G_START = 0x3, | ||
400 | BTC_ASSOCIATE_MAX | 412 | BTC_ASSOCIATE_MAX |
401 | }; | 413 | }; |
402 | 414 | ||
@@ -435,6 +447,107 @@ enum btc_notify_type_stack_operation { | |||
435 | BTC_STACK_OP_MAX | 447 | BTC_STACK_OP_MAX |
436 | }; | 448 | }; |
437 | 449 | ||
450 | enum { | ||
451 | BTC_CCK_1, | ||
452 | BTC_CCK_2, | ||
453 | BTC_CCK_5_5, | ||
454 | BTC_CCK_11, | ||
455 | BTC_OFDM_6, | ||
456 | BTC_OFDM_9, | ||
457 | BTC_OFDM_12, | ||
458 | BTC_OFDM_18, | ||
459 | BTC_OFDM_24, | ||
460 | BTC_OFDM_36, | ||
461 | BTC_OFDM_48, | ||
462 | BTC_OFDM_54, | ||
463 | BTC_MCS_0, | ||
464 | BTC_MCS_1, | ||
465 | BTC_MCS_2, | ||
466 | BTC_MCS_3, | ||
467 | BTC_MCS_4, | ||
468 | BTC_MCS_5, | ||
469 | BTC_MCS_6, | ||
470 | BTC_MCS_7, | ||
471 | BTC_MCS_8, | ||
472 | BTC_MCS_9, | ||
473 | BTC_MCS_10, | ||
474 | BTC_MCS_11, | ||
475 | BTC_MCS_12, | ||
476 | BTC_MCS_13, | ||
477 | BTC_MCS_14, | ||
478 | BTC_MCS_15, | ||
479 | BTC_MCS_16, | ||
480 | BTC_MCS_17, | ||
481 | BTC_MCS_18, | ||
482 | BTC_MCS_19, | ||
483 | BTC_MCS_20, | ||
484 | BTC_MCS_21, | ||
485 | BTC_MCS_22, | ||
486 | BTC_MCS_23, | ||
487 | BTC_MCS_24, | ||
488 | BTC_MCS_25, | ||
489 | BTC_MCS_26, | ||
490 | BTC_MCS_27, | ||
491 | BTC_MCS_28, | ||
492 | BTC_MCS_29, | ||
493 | BTC_MCS_30, | ||
494 | BTC_MCS_31, | ||
495 | BTC_VHT_1SS_MCS_0, | ||
496 | BTC_VHT_1SS_MCS_1, | ||
497 | BTC_VHT_1SS_MCS_2, | ||
498 | BTC_VHT_1SS_MCS_3, | ||
499 | BTC_VHT_1SS_MCS_4, | ||
500 | BTC_VHT_1SS_MCS_5, | ||
501 | BTC_VHT_1SS_MCS_6, | ||
502 | BTC_VHT_1SS_MCS_7, | ||
503 | BTC_VHT_1SS_MCS_8, | ||
504 | BTC_VHT_1SS_MCS_9, | ||
505 | BTC_VHT_2SS_MCS_0, | ||
506 | BTC_VHT_2SS_MCS_1, | ||
507 | BTC_VHT_2SS_MCS_2, | ||
508 | BTC_VHT_2SS_MCS_3, | ||
509 | BTC_VHT_2SS_MCS_4, | ||
510 | BTC_VHT_2SS_MCS_5, | ||
511 | BTC_VHT_2SS_MCS_6, | ||
512 | BTC_VHT_2SS_MCS_7, | ||
513 | BTC_VHT_2SS_MCS_8, | ||
514 | BTC_VHT_2SS_MCS_9, | ||
515 | BTC_VHT_3SS_MCS_0, | ||
516 | BTC_VHT_3SS_MCS_1, | ||
517 | BTC_VHT_3SS_MCS_2, | ||
518 | BTC_VHT_3SS_MCS_3, | ||
519 | BTC_VHT_3SS_MCS_4, | ||
520 | BTC_VHT_3SS_MCS_5, | ||
521 | BTC_VHT_3SS_MCS_6, | ||
522 | BTC_VHT_3SS_MCS_7, | ||
523 | BTC_VHT_3SS_MCS_8, | ||
524 | BTC_VHT_3SS_MCS_9, | ||
525 | BTC_VHT_4SS_MCS_0, | ||
526 | BTC_VHT_4SS_MCS_1, | ||
527 | BTC_VHT_4SS_MCS_2, | ||
528 | BTC_VHT_4SS_MCS_3, | ||
529 | BTC_VHT_4SS_MCS_4, | ||
530 | BTC_VHT_4SS_MCS_5, | ||
531 | BTC_VHT_4SS_MCS_6, | ||
532 | BTC_VHT_4SS_MCS_7, | ||
533 | BTC_VHT_4SS_MCS_8, | ||
534 | BTC_VHT_4SS_MCS_9, | ||
535 | BTC_MCS_32, | ||
536 | BTC_UNKNOWN, | ||
537 | BTC_PKT_MGNT, | ||
538 | BTC_PKT_CTRL, | ||
539 | BTC_PKT_UNKNOWN, | ||
540 | BTC_PKT_NOT_FOR_ME, | ||
541 | BTC_RATE_MAX | ||
542 | }; | ||
543 | |||
544 | enum { | ||
545 | BTC_MULTIPORT_SCC, | ||
546 | BTC_MULTIPORT_MCC_2CHANNEL, | ||
547 | BTC_MULTIPORT_MCC_2BAND, | ||
548 | BTC_MULTIPORT_MAX | ||
549 | }; | ||
550 | |||
438 | struct btc_bt_info { | 551 | struct btc_bt_info { |
439 | bool bt_disabled; | 552 | bool bt_disabled; |
440 | u8 rssi_adjust_for_agc_table_on; | 553 | u8 rssi_adjust_for_agc_table_on; |
@@ -454,6 +567,7 @@ struct btc_bt_info { | |||
454 | u16 bt_hci_ver; | 567 | u16 bt_hci_ver; |
455 | u16 bt_real_fw_ver; | 568 | u16 bt_real_fw_ver; |
456 | u8 bt_fw_ver; | 569 | u8 bt_fw_ver; |
570 | u32 bt_get_fw_ver; | ||
457 | 571 | ||
458 | bool bt_disable_low_pwr; | 572 | bool bt_disable_low_pwr; |
459 | 573 | ||
@@ -525,6 +639,7 @@ struct btc_bt_link_info { | |||
525 | bool pan_exist; | 639 | bool pan_exist; |
526 | bool pan_only; | 640 | bool pan_only; |
527 | bool slave_role; | 641 | bool slave_role; |
642 | bool acl_busy; | ||
528 | }; | 643 | }; |
529 | 644 | ||
530 | enum btc_antenna_pos { | 645 | enum btc_antenna_pos { |
@@ -625,8 +740,15 @@ struct btc_coexist { | |||
625 | 740 | ||
626 | void (*btc_set_bt_reg)(void *btc_context, u8 reg_type, u32 offset, | 741 | void (*btc_set_bt_reg)(void *btc_context, u8 reg_type, u32 offset, |
627 | u32 value); | 742 | u32 value); |
743 | u32 (*btc_get_bt_reg)(void *btc_context, u8 reg_type, u32 offset); | ||
628 | u32 (*btc_get_bt_coex_supported_feature)(void *btcoexist); | 744 | u32 (*btc_get_bt_coex_supported_feature)(void *btcoexist); |
629 | u32 (*btc_get_bt_coex_supported_version)(void *btcoexist); | 745 | u32 (*btc_get_bt_coex_supported_version)(void *btcoexist); |
746 | u32 (*btc_get_bt_phydm_version)(void *btcoexist); | ||
747 | void (*btc_phydm_modify_ra_pcr_threshold)(void *btcoexist, | ||
748 | u8 ra_offset_direction, | ||
749 | u8 ra_threshold_offset); | ||
750 | u32 (*btc_phydm_query_phy_counter)(void *btcoexist, | ||
751 | enum dm_info_query dm_id); | ||
630 | u8 (*btc_get_ant_det_val_from_bt)(void *btcoexist); | 752 | u8 (*btc_get_ant_det_val_from_bt)(void *btcoexist); |
631 | u8 (*btc_get_ble_scan_type_from_bt)(void *btcoexist); | 753 | u8 (*btc_get_ble_scan_type_from_bt)(void *btcoexist); |
632 | u32 (*btc_get_ble_scan_para_from_bt)(void *btcoexist, u8 scan_type); | 754 | u32 (*btc_get_ble_scan_para_from_bt)(void *btcoexist, u8 scan_type); |
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h index f2d9c6116e5c..8379a3e5198c 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h | |||
@@ -142,7 +142,7 @@ | |||
142 | /*wait power state to suspend*/}, \ | 142 | /*wait power state to suspend*/}, \ |
143 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | 143 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ |
144 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(4), 0 \ | 144 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(4), 0 \ |
145 | /*0x04[12:11] = 2b'01enable WL suspend*/}, | 145 | /*0x04[12:11] = 2b'00 disable WL suspend*/}, |
146 | 146 | ||
147 | #define RTL8188EE_TRANS_CARDEMU_TO_CARDDIS \ | 147 | #define RTL8188EE_TRANS_CARDEMU_TO_CARDDIS \ |
148 | {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | 148 | {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ |
@@ -179,7 +179,7 @@ | |||
179 | /*wait power state to suspend*/}, \ | 179 | /*wait power state to suspend*/}, \ |
180 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | 180 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ |
181 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0 \ | 181 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0 \ |
182 | /*0x04[12:11] = 2b'01enable WL suspend*/}, | 182 | /*0x04[12:11] = 2b'00 disable WL suspend*/}, |
183 | 183 | ||
184 | #define RTL8188EE_TRANS_CARDEMU_TO_PDN \ | 184 | #define RTL8188EE_TRANS_CARDEMU_TO_PDN \ |
185 | {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | 185 | {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ |
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h index 781eeaa6af49..c570801508cc 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h | |||
@@ -134,7 +134,7 @@ | |||
134 | /*wait power state to suspend*/ \ | 134 | /*wait power state to suspend*/ \ |
135 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | 135 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ |
136 | PWR_BASEADDR_SDIO , PWR_CMD_POLLING, BIT(1), BIT(1)}, \ | 136 | PWR_BASEADDR_SDIO , PWR_CMD_POLLING, BIT(1), BIT(1)}, \ |
137 | /*0x04[12:11] = 2b'01enable WL suspend*/ \ | 137 | /*0x04[12:11] = 2b'00 disable WL suspend*/ \ |
138 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | 138 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ |
139 | PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, | 139 | PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, |
140 | 140 | ||
@@ -181,7 +181,7 @@ | |||
181 | /*Lock small LDO Register*/ \ | 181 | /*Lock small LDO Register*/ \ |
182 | {0x00CC, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | 182 | {0x00CC, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ |
183 | PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(2), 0}, \ | 183 | PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(2), 0}, \ |
184 | /*0x04[12:11] = 2b'01enable WL suspend*/ \ | 184 | /*0x04[12:11] = 2b'00 disable WL suspend*/ \ |
185 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | 185 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ |
186 | PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, | 186 | PWR_BASEADDR_MAC , PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, |
187 | 187 | ||
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h index 4ac7db526f15..e6c3aac3e9fd 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h | |||
@@ -135,7 +135,7 @@ | |||
135 | /*wait power state to suspend*/ \ | 135 | /*wait power state to suspend*/ \ |
136 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ | 136 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ |
137 | PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)},\ | 137 | PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)},\ |
138 | /*0x04[12:11] = 2b'01enable WL suspend*/ \ | 138 | /*0x04[12:11] = 2b'00 disable WL suspend*/ \ |
139 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ | 139 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ |
140 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, | 140 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, |
141 | 141 | ||
@@ -172,7 +172,7 @@ | |||
172 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ | 172 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ |
173 | PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO,\ | 173 | PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO,\ |
174 | PWR_CMD_POLLING, BIT(1), BIT(1)},\ | 174 | PWR_CMD_POLLING, BIT(1), BIT(1)},\ |
175 | /*0x04[12:11] = 2b'00enable WL suspend*/ \ | 175 | /*0x04[12:11] = 2b'00 disable WL suspend*/ \ |
176 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ | 176 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ |
177 | PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ | 177 | PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC,\ |
178 | PWR_CMD_WRITE, BIT(3)|BIT(4), 0},\ | 178 | PWR_CMD_WRITE, BIT(3)|BIT(4), 0},\ |
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h index 0fee5e0e55c2..3367cfbc9502 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h | |||
@@ -204,7 +204,7 @@ | |||
204 | /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ | 204 | /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ |
205 | {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | 205 | {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ |
206 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \ | 206 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \ |
207 | /*0x04[12:11] = 2b'01enable WL suspend*/ \ | 207 | /*0x04[12:11] = 2b'00 disable WL suspend*/ \ |
208 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | 208 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ |
209 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, | 209 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, |
210 | 210 | ||
@@ -251,7 +251,7 @@ | |||
251 | /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \ | 251 | /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \ |
252 | {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ | 252 | {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ |
253 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ | 253 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ |
254 | /*0x04[12:11] = 2b'01enable WL suspend*/ \ | 254 | /*0x04[12:11] = 2b'00 disable WL suspend*/ \ |
255 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | 255 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ |
256 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \ | 256 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \ |
257 | /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ | 257 | /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ |
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c index b11365a5ee1f..9111ba7ff0a1 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c | |||
@@ -1475,7 +1475,7 @@ void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, | |||
1475 | } | 1475 | } |
1476 | } else if (method == MIX_MODE) { | 1476 | } else if (method == MIX_MODE) { |
1477 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 1477 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
1478 | "pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Aboslute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", | 1478 | "pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", |
1479 | rtldm->default_ofdm_index, | 1479 | rtldm->default_ofdm_index, |
1480 | rtldm->absolute_ofdm_swing_idx[rf_path], | 1480 | rtldm->absolute_ofdm_swing_idx[rf_path], |
1481 | rf_path); | 1481 | rf_path); |
@@ -1750,7 +1750,7 @@ void rtl8812ae_dm_txpower_tracking_callback_thermalmeter( | |||
1750 | /*Record delta swing for mix mode power tracking*/ | 1750 | /*Record delta swing for mix mode power tracking*/ |
1751 | 1751 | ||
1752 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 1752 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
1753 | "******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", | 1753 | "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", |
1754 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); | 1754 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); |
1755 | 1755 | ||
1756 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 1756 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
@@ -1766,7 +1766,7 @@ void rtl8812ae_dm_txpower_tracking_callback_thermalmeter( | |||
1766 | /*Record delta swing for mix mode power tracking*/ | 1766 | /*Record delta swing for mix mode power tracking*/ |
1767 | 1767 | ||
1768 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 1768 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
1769 | "******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", | 1769 | "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", |
1770 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); | 1770 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); |
1771 | } else { | 1771 | } else { |
1772 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 1772 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
@@ -1782,7 +1782,7 @@ void rtl8812ae_dm_txpower_tracking_callback_thermalmeter( | |||
1782 | -1 * delta_swing_table_idx_tdown_a[delta]; | 1782 | -1 * delta_swing_table_idx_tdown_a[delta]; |
1783 | /* Record delta swing for mix mode power tracking*/ | 1783 | /* Record delta swing for mix mode power tracking*/ |
1784 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 1784 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
1785 | "******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", | 1785 | "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", |
1786 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); | 1786 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); |
1787 | 1787 | ||
1788 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 1788 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
@@ -1799,7 +1799,7 @@ void rtl8812ae_dm_txpower_tracking_callback_thermalmeter( | |||
1799 | /*Record delta swing for mix mode power tracking*/ | 1799 | /*Record delta swing for mix mode power tracking*/ |
1800 | 1800 | ||
1801 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 1801 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
1802 | "******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", | 1802 | "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", |
1803 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); | 1803 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); |
1804 | } | 1804 | } |
1805 | 1805 | ||
@@ -2115,7 +2115,7 @@ void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, | |||
2115 | } | 2115 | } |
2116 | } else if (method == MIX_MODE) { | 2116 | } else if (method == MIX_MODE) { |
2117 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 2117 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
2118 | "pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Aboslute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", | 2118 | "pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", |
2119 | rtldm->default_ofdm_index, | 2119 | rtldm->default_ofdm_index, |
2120 | rtldm->absolute_ofdm_swing_idx[rf_path], | 2120 | rtldm->absolute_ofdm_swing_idx[rf_path], |
2121 | rf_path); | 2121 | rf_path); |
@@ -2329,7 +2329,7 @@ void rtl8821ae_dm_txpower_tracking_callback_thermalmeter( | |||
2329 | /*Record delta swing for mix mode power tracking*/ | 2329 | /*Record delta swing for mix mode power tracking*/ |
2330 | 2330 | ||
2331 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 2331 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
2332 | "******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", | 2332 | "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", |
2333 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); | 2333 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); |
2334 | } else { | 2334 | } else { |
2335 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 2335 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
@@ -2345,7 +2345,7 @@ void rtl8821ae_dm_txpower_tracking_callback_thermalmeter( | |||
2345 | -1 * delta_swing_table_idx_tdown_a[delta]; | 2345 | -1 * delta_swing_table_idx_tdown_a[delta]; |
2346 | /* Record delta swing for mix mode power tracking*/ | 2346 | /* Record delta swing for mix mode power tracking*/ |
2347 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 2347 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
2348 | "******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", | 2348 | "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", |
2349 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); | 2349 | rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); |
2350 | } | 2350 | } |
2351 | 2351 | ||
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h index 36b3e91d996e..6dd575435c63 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h | |||
@@ -531,7 +531,7 @@ extern struct wlan_pwr_cfg rtl8812_leave_lps_flow | |||
531 | /*0x23[4] = 1b'0 12H LDO enter normal mode*/}, \ | 531 | /*0x23[4] = 1b'0 12H LDO enter normal mode*/}, \ |
532 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ | 532 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ |
533 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3|BIT4, 0 \ | 533 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3|BIT4, 0 \ |
534 | /*0x04[12:11] = 2b'01enable WL suspend*/}, | 534 | /*0x04[12:11] = 2b'00 disable WL suspend*/}, |
535 | 535 | ||
536 | #define RTL8821A_TRANS_CARDEMU_TO_CARDDIS \ | 536 | #define RTL8821A_TRANS_CARDEMU_TO_CARDDIS \ |
537 | {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ | 537 | {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ |
@@ -572,7 +572,7 @@ extern struct wlan_pwr_cfg rtl8812_leave_lps_flow | |||
572 | /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/}, \ | 572 | /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/}, \ |
573 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ | 573 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ |
574 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3|BIT4, 0 \ | 574 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT3|BIT4, 0 \ |
575 | /*0x04[12:11] = 2b'01enable WL suspend*/},\ | 575 | /*0x04[12:11] = 2b'00 disable WL suspend*/},\ |
576 | {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ | 576 | {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,\ |
577 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, 0 \ | 577 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, 0 \ |
578 | /*0x23[4] = 1b'0 12H LDO enter normal mode*/}, \ | 578 | /*0x23[4] = 1b'0 12H LDO enter normal mode*/}, \ |
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h index 4f48b934ec01..d27e33960e77 100644 --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h | |||
@@ -556,6 +556,7 @@ enum rt_oem_id { | |||
556 | RT_CID_NETGEAR = 36, | 556 | RT_CID_NETGEAR = 36, |
557 | RT_CID_PLANEX = 37, | 557 | RT_CID_PLANEX = 37, |
558 | RT_CID_CC_C = 38, | 558 | RT_CID_CC_C = 38, |
559 | RT_CID_LENOVO_CHINA = 40, | ||
559 | }; | 560 | }; |
560 | 561 | ||
561 | enum hw_descs { | 562 | enum hw_descs { |
@@ -977,6 +978,38 @@ enum rtl_spec_ver { | |||
977 | RTL_SPEC_EXT_C2H = BIT(2), /* extend FW C2H (e.g. TX REPORT) */ | 978 | RTL_SPEC_EXT_C2H = BIT(2), /* extend FW C2H (e.g. TX REPORT) */ |
978 | }; | 979 | }; |
979 | 980 | ||
981 | enum dm_info_query { | ||
982 | DM_INFO_FA_OFDM, | ||
983 | DM_INFO_FA_CCK, | ||
984 | DM_INFO_FA_TOTAL, | ||
985 | DM_INFO_CCA_OFDM, | ||
986 | DM_INFO_CCA_CCK, | ||
987 | DM_INFO_CCA_ALL, | ||
988 | DM_INFO_CRC32_OK_VHT, | ||
989 | DM_INFO_CRC32_OK_HT, | ||
990 | DM_INFO_CRC32_OK_LEGACY, | ||
991 | DM_INFO_CRC32_OK_CCK, | ||
992 | DM_INFO_CRC32_ERROR_VHT, | ||
993 | DM_INFO_CRC32_ERROR_HT, | ||
994 | DM_INFO_CRC32_ERROR_LEGACY, | ||
995 | DM_INFO_CRC32_ERROR_CCK, | ||
996 | DM_INFO_EDCCA_FLAG, | ||
997 | DM_INFO_OFDM_ENABLE, | ||
998 | DM_INFO_CCK_ENABLE, | ||
999 | DM_INFO_CRC32_OK_HT_AGG, | ||
1000 | DM_INFO_CRC32_ERROR_HT_AGG, | ||
1001 | DM_INFO_DBG_PORT_0, | ||
1002 | DM_INFO_CURR_IGI, | ||
1003 | DM_INFO_RSSI_MIN, | ||
1004 | DM_INFO_RSSI_MAX, | ||
1005 | DM_INFO_CLM_RATIO, | ||
1006 | DM_INFO_NHM_RATIO, | ||
1007 | DM_INFO_IQK_ALL, | ||
1008 | DM_INFO_IQK_OK, | ||
1009 | DM_INFO_IQK_NG, | ||
1010 | DM_INFO_SIZE, | ||
1011 | }; | ||
1012 | |||
980 | struct octet_string { | 1013 | struct octet_string { |
981 | u8 *octet; | 1014 | u8 *octet; |
982 | u16 length; | 1015 | u16 length; |
diff --git a/drivers/net/wireless/rsi/Kconfig b/drivers/net/wireless/rsi/Kconfig index f004be33fcfa..976c21866230 100644 --- a/drivers/net/wireless/rsi/Kconfig +++ b/drivers/net/wireless/rsi/Kconfig | |||
@@ -13,6 +13,7 @@ if WLAN_VENDOR_RSI | |||
13 | 13 | ||
14 | config RSI_91X | 14 | config RSI_91X |
15 | tristate "Redpine Signals Inc 91x WLAN driver support" | 15 | tristate "Redpine Signals Inc 91x WLAN driver support" |
16 | select BT_HCIRSI if RSI_COEX | ||
16 | depends on MAC80211 | 17 | depends on MAC80211 |
17 | ---help--- | 18 | ---help--- |
18 | This option enabes support for RSI 1x1 devices. | 19 | This option enabes support for RSI 1x1 devices. |
@@ -44,7 +45,8 @@ config RSI_USB | |||
44 | 45 | ||
45 | config RSI_COEX | 46 | config RSI_COEX |
46 | bool "Redpine Signals WLAN BT Coexistence support" | 47 | bool "Redpine Signals WLAN BT Coexistence support" |
47 | depends on BT_HCIRSI && RSI_91X | 48 | depends on BT && RSI_91X |
49 | depends on !(BT=m && RSI_91X=y) | ||
48 | default y | 50 | default y |
49 | ---help--- | 51 | ---help--- |
50 | This option enables the WLAN BT coex support in rsi drivers. | 52 | This option enables the WLAN BT coex support in rsi drivers. |
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index 98c7d1dae18e..d76e69c0beaa 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c | |||
@@ -576,7 +576,7 @@ static int rsi_sdio_load_data_master_write(struct rsi_hw *adapter, | |||
576 | { | 576 | { |
577 | u32 num_blocks, offset, i; | 577 | u32 num_blocks, offset, i; |
578 | u16 msb_address, lsb_address; | 578 | u16 msb_address, lsb_address; |
579 | u8 temp_buf[block_size]; | 579 | u8 *temp_buf; |
580 | int status; | 580 | int status; |
581 | 581 | ||
582 | num_blocks = instructions_sz / block_size; | 582 | num_blocks = instructions_sz / block_size; |
@@ -585,11 +585,15 @@ static int rsi_sdio_load_data_master_write(struct rsi_hw *adapter, | |||
585 | rsi_dbg(INFO_ZONE, "ins_size: %d, num_blocks: %d\n", | 585 | rsi_dbg(INFO_ZONE, "ins_size: %d, num_blocks: %d\n", |
586 | instructions_sz, num_blocks); | 586 | instructions_sz, num_blocks); |
587 | 587 | ||
588 | temp_buf = kmalloc(block_size, GFP_KERNEL); | ||
589 | if (!temp_buf) | ||
590 | return -ENOMEM; | ||
591 | |||
588 | /* Loading DM ms word in the sdio slave */ | 592 | /* Loading DM ms word in the sdio slave */ |
589 | status = rsi_sdio_master_access_msword(adapter, msb_address); | 593 | status = rsi_sdio_master_access_msword(adapter, msb_address); |
590 | if (status < 0) { | 594 | if (status < 0) { |
591 | rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__); | 595 | rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__); |
592 | return status; | 596 | goto out_free; |
593 | } | 597 | } |
594 | 598 | ||
595 | for (offset = 0, i = 0; i < num_blocks; i++, offset += block_size) { | 599 | for (offset = 0, i = 0; i < num_blocks; i++, offset += block_size) { |
@@ -601,7 +605,7 @@ static int rsi_sdio_load_data_master_write(struct rsi_hw *adapter, | |||
601 | temp_buf, block_size); | 605 | temp_buf, block_size); |
602 | if (status < 0) { | 606 | if (status < 0) { |
603 | rsi_dbg(ERR_ZONE, "%s: failed to write\n", __func__); | 607 | rsi_dbg(ERR_ZONE, "%s: failed to write\n", __func__); |
604 | return status; | 608 | goto out_free; |
605 | } | 609 | } |
606 | rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, i); | 610 | rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, i); |
607 | base_address += block_size; | 611 | base_address += block_size; |
@@ -616,7 +620,7 @@ static int rsi_sdio_load_data_master_write(struct rsi_hw *adapter, | |||
616 | rsi_dbg(ERR_ZONE, | 620 | rsi_dbg(ERR_ZONE, |
617 | "%s: Unable to set ms word reg\n", | 621 | "%s: Unable to set ms word reg\n", |
618 | __func__); | 622 | __func__); |
619 | return status; | 623 | goto out_free; |
620 | } | 624 | } |
621 | } | 625 | } |
622 | } | 626 | } |
@@ -632,12 +636,16 @@ static int rsi_sdio_load_data_master_write(struct rsi_hw *adapter, | |||
632 | temp_buf, | 636 | temp_buf, |
633 | instructions_sz % block_size); | 637 | instructions_sz % block_size); |
634 | if (status < 0) | 638 | if (status < 0) |
635 | return status; | 639 | goto out_free; |
636 | rsi_dbg(INFO_ZONE, | 640 | rsi_dbg(INFO_ZONE, |
637 | "Written Last Block in Address 0x%x Successfully\n", | 641 | "Written Last Block in Address 0x%x Successfully\n", |
638 | offset | RSI_SD_REQUEST_MASTER); | 642 | offset | RSI_SD_REQUEST_MASTER); |
639 | } | 643 | } |
640 | return 0; | 644 | |
645 | status = 0; | ||
646 | out_free: | ||
647 | kfree(temp_buf); | ||
648 | return status; | ||
641 | } | 649 | } |
642 | 650 | ||
643 | #define FLASH_SIZE_ADDR 0x04000016 | 651 | #define FLASH_SIZE_ADDR 0x04000016 |
@@ -645,11 +653,14 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr, | |||
645 | u32 *read_buf, u16 size) | 653 | u32 *read_buf, u16 size) |
646 | { | 654 | { |
647 | u32 addr_on_bus, *data; | 655 | u32 addr_on_bus, *data; |
648 | u32 align[2] = {}; | ||
649 | u16 ms_addr; | 656 | u16 ms_addr; |
650 | int status; | 657 | int status; |
651 | 658 | ||
652 | data = PTR_ALIGN(&align[0], 8); | 659 | data = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL); |
660 | if (!data) | ||
661 | return -ENOMEM; | ||
662 | |||
663 | data = PTR_ALIGN(data, 8); | ||
653 | 664 | ||
654 | ms_addr = (addr >> 16); | 665 | ms_addr = (addr >> 16); |
655 | status = rsi_sdio_master_access_msword(adapter, ms_addr); | 666 | status = rsi_sdio_master_access_msword(adapter, ms_addr); |
@@ -657,7 +668,7 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr, | |||
657 | rsi_dbg(ERR_ZONE, | 668 | rsi_dbg(ERR_ZONE, |
658 | "%s: Unable to set ms word to common reg\n", | 669 | "%s: Unable to set ms word to common reg\n", |
659 | __func__); | 670 | __func__); |
660 | return status; | 671 | goto err; |
661 | } | 672 | } |
662 | addr &= 0xFFFF; | 673 | addr &= 0xFFFF; |
663 | 674 | ||
@@ -675,7 +686,7 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr, | |||
675 | (u8 *)data, 4); | 686 | (u8 *)data, 4); |
676 | if (status < 0) { | 687 | if (status < 0) { |
677 | rsi_dbg(ERR_ZONE, "%s: AHB register read failed\n", __func__); | 688 | rsi_dbg(ERR_ZONE, "%s: AHB register read failed\n", __func__); |
678 | return status; | 689 | goto err; |
679 | } | 690 | } |
680 | if (size == 2) { | 691 | if (size == 2) { |
681 | if ((addr & 0x3) == 0) | 692 | if ((addr & 0x3) == 0) |
@@ -697,17 +708,23 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr, | |||
697 | *read_buf = *data; | 708 | *read_buf = *data; |
698 | } | 709 | } |
699 | 710 | ||
700 | return 0; | 711 | err: |
712 | kfree(data); | ||
713 | return status; | ||
701 | } | 714 | } |
702 | 715 | ||
703 | static int rsi_sdio_master_reg_write(struct rsi_hw *adapter, | 716 | static int rsi_sdio_master_reg_write(struct rsi_hw *adapter, |
704 | unsigned long addr, | 717 | unsigned long addr, |
705 | unsigned long data, u16 size) | 718 | unsigned long data, u16 size) |
706 | { | 719 | { |
707 | unsigned long data1[2], *data_aligned; | 720 | unsigned long *data_aligned; |
708 | int status; | 721 | int status; |
709 | 722 | ||
710 | data_aligned = PTR_ALIGN(&data1[0], 8); | 723 | data_aligned = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL); |
724 | if (!data_aligned) | ||
725 | return -ENOMEM; | ||
726 | |||
727 | data_aligned = PTR_ALIGN(data_aligned, 8); | ||
711 | 728 | ||
712 | if (size == 2) { | 729 | if (size == 2) { |
713 | *data_aligned = ((data << 16) | (data & 0xFFFF)); | 730 | *data_aligned = ((data << 16) | (data & 0xFFFF)); |
@@ -726,6 +743,7 @@ static int rsi_sdio_master_reg_write(struct rsi_hw *adapter, | |||
726 | rsi_dbg(ERR_ZONE, | 743 | rsi_dbg(ERR_ZONE, |
727 | "%s: Unable to set ms word to common reg\n", | 744 | "%s: Unable to set ms word to common reg\n", |
728 | __func__); | 745 | __func__); |
746 | kfree(data_aligned); | ||
729 | return -EIO; | 747 | return -EIO; |
730 | } | 748 | } |
731 | addr = addr & 0xFFFF; | 749 | addr = addr & 0xFFFF; |
@@ -735,12 +753,12 @@ static int rsi_sdio_master_reg_write(struct rsi_hw *adapter, | |||
735 | (adapter, | 753 | (adapter, |
736 | (addr | RSI_SD_REQUEST_MASTER), | 754 | (addr | RSI_SD_REQUEST_MASTER), |
737 | (u8 *)data_aligned, size); | 755 | (u8 *)data_aligned, size); |
738 | if (status < 0) { | 756 | if (status < 0) |
739 | rsi_dbg(ERR_ZONE, | 757 | rsi_dbg(ERR_ZONE, |
740 | "%s: Unable to do AHB reg write\n", __func__); | 758 | "%s: Unable to do AHB reg write\n", __func__); |
741 | return status; | 759 | |
742 | } | 760 | kfree(data_aligned); |
743 | return 0; | 761 | return status; |
744 | } | 762 | } |
745 | 763 | ||
746 | /** | 764 | /** |
@@ -959,7 +977,7 @@ static int rsi_probe(struct sdio_func *pfunction, | |||
959 | rsi_sdio_rx_thread, "SDIO-RX-Thread"); | 977 | rsi_sdio_rx_thread, "SDIO-RX-Thread"); |
960 | if (status) { | 978 | if (status) { |
961 | rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__); | 979 | rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__); |
962 | goto fail_free_adapter; | 980 | goto fail_kill_thread; |
963 | } | 981 | } |
964 | skb_queue_head_init(&sdev->rx_q.head); | 982 | skb_queue_head_init(&sdev->rx_q.head); |
965 | sdev->rx_q.num_rx_pkts = 0; | 983 | sdev->rx_q.num_rx_pkts = 0; |
@@ -969,7 +987,7 @@ static int rsi_probe(struct sdio_func *pfunction, | |||
969 | rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__); | 987 | rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__); |
970 | sdio_release_host(pfunction); | 988 | sdio_release_host(pfunction); |
971 | status = -EIO; | 989 | status = -EIO; |
972 | goto fail_kill_thread; | 990 | goto fail_claim_irq; |
973 | } | 991 | } |
974 | sdio_release_host(pfunction); | 992 | sdio_release_host(pfunction); |
975 | rsi_dbg(INIT_ZONE, "%s: Registered Interrupt handler\n", __func__); | 993 | rsi_dbg(INIT_ZONE, "%s: Registered Interrupt handler\n", __func__); |
@@ -977,7 +995,7 @@ static int rsi_probe(struct sdio_func *pfunction, | |||
977 | if (rsi_hal_device_init(adapter)) { | 995 | if (rsi_hal_device_init(adapter)) { |
978 | rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__); | 996 | rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__); |
979 | status = -EINVAL; | 997 | status = -EINVAL; |
980 | goto fail_kill_thread; | 998 | goto fail_dev_init; |
981 | } | 999 | } |
982 | rsi_dbg(INFO_ZONE, "===> RSI Device Init Done <===\n"); | 1000 | rsi_dbg(INFO_ZONE, "===> RSI Device Init Done <===\n"); |
983 | 1001 | ||
@@ -994,10 +1012,13 @@ static int rsi_probe(struct sdio_func *pfunction, | |||
994 | fail_dev_init: | 1012 | fail_dev_init: |
995 | sdio_claim_host(pfunction); | 1013 | sdio_claim_host(pfunction); |
996 | sdio_release_irq(pfunction); | 1014 | sdio_release_irq(pfunction); |
997 | sdio_disable_func(pfunction); | ||
998 | sdio_release_host(pfunction); | 1015 | sdio_release_host(pfunction); |
999 | fail_kill_thread: | 1016 | fail_claim_irq: |
1000 | rsi_kill_thread(&sdev->rx_thread); | 1017 | rsi_kill_thread(&sdev->rx_thread); |
1018 | fail_kill_thread: | ||
1019 | sdio_claim_host(pfunction); | ||
1020 | sdio_disable_func(pfunction); | ||
1021 | sdio_release_host(pfunction); | ||
1001 | fail_free_adapter: | 1022 | fail_free_adapter: |
1002 | rsi_91x_deinit(adapter); | 1023 | rsi_91x_deinit(adapter); |
1003 | rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__); | 1024 | rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__); |
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index be8236f404b5..7b8bae313aa9 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c | |||
@@ -140,7 +140,6 @@ static int rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface, | |||
140 | buffer_size = endpoint->wMaxPacketSize; | 140 | buffer_size = endpoint->wMaxPacketSize; |
141 | dev->bulkout_endpoint_addr[bout_found] = | 141 | dev->bulkout_endpoint_addr[bout_found] = |
142 | endpoint->bEndpointAddress; | 142 | endpoint->bEndpointAddress; |
143 | buffer_size = endpoint->wMaxPacketSize; | ||
144 | dev->bulkout_size[bout_found] = buffer_size; | 143 | dev->bulkout_size[bout_found] = buffer_size; |
145 | bout_found++; | 144 | bout_found++; |
146 | } | 145 | } |
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h index ba649be284af..ead8e7c4df3a 100644 --- a/drivers/net/wireless/rsi/rsi_sdio.h +++ b/drivers/net/wireless/rsi/rsi_sdio.h | |||
@@ -46,6 +46,8 @@ enum sdio_interrupt_type { | |||
46 | #define PKT_BUFF_AVAILABLE 1 | 46 | #define PKT_BUFF_AVAILABLE 1 |
47 | #define FW_ASSERT_IND 2 | 47 | #define FW_ASSERT_IND 2 |
48 | 48 | ||
49 | #define RSI_MASTER_REG_BUF_SIZE 12 | ||
50 | |||
49 | #define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3 | 51 | #define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3 |
50 | #define RSI_FN1_INT_REGISTER 0xf9 | 52 | #define RSI_FN1_INT_REGISTER 0xf9 |
51 | #define RSI_INT_ENABLE_REGISTER 0x04 | 53 | #define RSI_INT_ENABLE_REGISTER 0x04 |
diff --git a/drivers/net/wireless/st/cw1200/debug.c b/drivers/net/wireless/st/cw1200/debug.c index 34f97c31eecf..295cb1a29f25 100644 --- a/drivers/net/wireless/st/cw1200/debug.c +++ b/drivers/net/wireless/st/cw1200/debug.c | |||
@@ -398,15 +398,15 @@ int cw1200_debug_init(struct cw1200_common *priv) | |||
398 | if (!d->debugfs_phy) | 398 | if (!d->debugfs_phy) |
399 | goto err; | 399 | goto err; |
400 | 400 | ||
401 | if (!debugfs_create_file("status", S_IRUSR, d->debugfs_phy, | 401 | if (!debugfs_create_file("status", 0400, d->debugfs_phy, |
402 | priv, &fops_status)) | 402 | priv, &fops_status)) |
403 | goto err; | 403 | goto err; |
404 | 404 | ||
405 | if (!debugfs_create_file("counters", S_IRUSR, d->debugfs_phy, | 405 | if (!debugfs_create_file("counters", 0400, d->debugfs_phy, |
406 | priv, &fops_counters)) | 406 | priv, &fops_counters)) |
407 | goto err; | 407 | goto err; |
408 | 408 | ||
409 | if (!debugfs_create_file("wsm_dumps", S_IWUSR, d->debugfs_phy, | 409 | if (!debugfs_create_file("wsm_dumps", 0200, d->debugfs_phy, |
410 | priv, &fops_wsm_dumps)) | 410 | priv, &fops_wsm_dumps)) |
411 | goto err; | 411 | goto err; |
412 | 412 | ||
diff --git a/drivers/net/wireless/st/cw1200/main.c b/drivers/net/wireless/st/cw1200/main.c index a186d1df1f29..90dc979f260b 100644 --- a/drivers/net/wireless/st/cw1200/main.c +++ b/drivers/net/wireless/st/cw1200/main.c | |||
@@ -46,7 +46,7 @@ MODULE_ALIAS("cw1200_core"); | |||
46 | 46 | ||
47 | /* Accept MAC address of the form macaddr=0x00,0x80,0xE1,0x30,0x40,0x50 */ | 47 | /* Accept MAC address of the form macaddr=0x00,0x80,0xE1,0x30,0x40,0x50 */ |
48 | static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00}; | 48 | static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00}; |
49 | module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, S_IRUGO); | 49 | module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, 0444); |
50 | MODULE_PARM_DESC(macaddr, "Override platform_data MAC address"); | 50 | MODULE_PARM_DESC(macaddr, "Override platform_data MAC address"); |
51 | 51 | ||
52 | static char *cw1200_sdd_path; | 52 | static char *cw1200_sdd_path; |
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 0cf3b4013dd6..ca0f936fc119 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c | |||
@@ -2092,54 +2092,51 @@ static struct platform_driver wl18xx_driver = { | |||
2092 | }; | 2092 | }; |
2093 | 2093 | ||
2094 | module_platform_driver(wl18xx_driver); | 2094 | module_platform_driver(wl18xx_driver); |
2095 | module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); | 2095 | module_param_named(ht_mode, ht_mode_param, charp, 0400); |
2096 | MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20"); | 2096 | MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20"); |
2097 | 2097 | ||
2098 | module_param_named(board_type, board_type_param, charp, S_IRUSR); | 2098 | module_param_named(board_type, board_type_param, charp, 0400); |
2099 | MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or " | 2099 | MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or " |
2100 | "dvp"); | 2100 | "dvp"); |
2101 | 2101 | ||
2102 | module_param_named(checksum, checksum_param, bool, S_IRUSR); | 2102 | module_param_named(checksum, checksum_param, bool, 0400); |
2103 | MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)"); | 2103 | MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)"); |
2104 | 2104 | ||
2105 | module_param_named(dc2dc, dc2dc_param, int, S_IRUSR); | 2105 | module_param_named(dc2dc, dc2dc_param, int, 0400); |
2106 | MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)"); | 2106 | MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)"); |
2107 | 2107 | ||
2108 | module_param_named(n_antennas_2, n_antennas_2_param, int, S_IRUSR); | 2108 | module_param_named(n_antennas_2, n_antennas_2_param, int, 0400); |
2109 | MODULE_PARM_DESC(n_antennas_2, | 2109 | MODULE_PARM_DESC(n_antennas_2, |
2110 | "Number of installed 2.4GHz antennas: 1 (default) or 2"); | 2110 | "Number of installed 2.4GHz antennas: 1 (default) or 2"); |
2111 | 2111 | ||
2112 | module_param_named(n_antennas_5, n_antennas_5_param, int, S_IRUSR); | 2112 | module_param_named(n_antennas_5, n_antennas_5_param, int, 0400); |
2113 | MODULE_PARM_DESC(n_antennas_5, | 2113 | MODULE_PARM_DESC(n_antennas_5, |
2114 | "Number of installed 5GHz antennas: 1 (default) or 2"); | 2114 | "Number of installed 5GHz antennas: 1 (default) or 2"); |
2115 | 2115 | ||
2116 | module_param_named(low_band_component, low_band_component_param, int, | 2116 | module_param_named(low_band_component, low_band_component_param, int, 0400); |
2117 | S_IRUSR); | ||
2118 | MODULE_PARM_DESC(low_band_component, "Low band component: u8 " | 2117 | MODULE_PARM_DESC(low_band_component, "Low band component: u8 " |
2119 | "(default is 0x01)"); | 2118 | "(default is 0x01)"); |
2120 | 2119 | ||
2121 | module_param_named(low_band_component_type, low_band_component_type_param, | 2120 | module_param_named(low_band_component_type, low_band_component_type_param, |
2122 | int, S_IRUSR); | 2121 | int, 0400); |
2123 | MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 " | 2122 | MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 " |
2124 | "(default is 0x05 or 0x06 depending on the board_type)"); | 2123 | "(default is 0x05 or 0x06 depending on the board_type)"); |
2125 | 2124 | ||
2126 | module_param_named(high_band_component, high_band_component_param, int, | 2125 | module_param_named(high_band_component, high_band_component_param, int, 0400); |
2127 | S_IRUSR); | ||
2128 | MODULE_PARM_DESC(high_band_component, "High band component: u8, " | 2126 | MODULE_PARM_DESC(high_band_component, "High band component: u8, " |
2129 | "(default is 0x01)"); | 2127 | "(default is 0x01)"); |
2130 | 2128 | ||
2131 | module_param_named(high_band_component_type, high_band_component_type_param, | 2129 | module_param_named(high_band_component_type, high_band_component_type_param, |
2132 | int, S_IRUSR); | 2130 | int, 0400); |
2133 | MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 " | 2131 | MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 " |
2134 | "(default is 0x09)"); | 2132 | "(default is 0x09)"); |
2135 | 2133 | ||
2136 | module_param_named(pwr_limit_reference_11_abg, | 2134 | module_param_named(pwr_limit_reference_11_abg, |
2137 | pwr_limit_reference_11_abg_param, int, S_IRUSR); | 2135 | pwr_limit_reference_11_abg_param, int, 0400); |
2138 | MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 " | 2136 | MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 " |
2139 | "(default is 0xc8)"); | 2137 | "(default is 0xc8)"); |
2140 | 2138 | ||
2141 | module_param_named(num_rx_desc, | 2139 | module_param_named(num_rx_desc, num_rx_desc_param, int, 0400); |
2142 | num_rx_desc_param, int, S_IRUSR); | ||
2143 | MODULE_PARM_DESC(num_rx_desc_param, | 2140 | MODULE_PARM_DESC(num_rx_desc_param, |
2144 | "Number of Rx descriptors: u8 (default is 32)"); | 2141 | "Number of Rx descriptors: u8 (default is 32)"); |
2145 | 2142 | ||
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 09714034dbf1..3a51ab116e79 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -6630,20 +6630,20 @@ EXPORT_SYMBOL_GPL(wlcore_remove); | |||
6630 | 6630 | ||
6631 | u32 wl12xx_debug_level = DEBUG_NONE; | 6631 | u32 wl12xx_debug_level = DEBUG_NONE; |
6632 | EXPORT_SYMBOL_GPL(wl12xx_debug_level); | 6632 | EXPORT_SYMBOL_GPL(wl12xx_debug_level); |
6633 | module_param_named(debug_level, wl12xx_debug_level, uint, S_IRUSR | S_IWUSR); | 6633 | module_param_named(debug_level, wl12xx_debug_level, uint, 0600); |
6634 | MODULE_PARM_DESC(debug_level, "wl12xx debugging level"); | 6634 | MODULE_PARM_DESC(debug_level, "wl12xx debugging level"); |
6635 | 6635 | ||
6636 | module_param_named(fwlog, fwlog_param, charp, 0); | 6636 | module_param_named(fwlog, fwlog_param, charp, 0); |
6637 | MODULE_PARM_DESC(fwlog, | 6637 | MODULE_PARM_DESC(fwlog, |
6638 | "FW logger options: continuous, dbgpins or disable"); | 6638 | "FW logger options: continuous, dbgpins or disable"); |
6639 | 6639 | ||
6640 | module_param(fwlog_mem_blocks, int, S_IRUSR | S_IWUSR); | 6640 | module_param(fwlog_mem_blocks, int, 0600); |
6641 | MODULE_PARM_DESC(fwlog_mem_blocks, "fwlog mem_blocks"); | 6641 | MODULE_PARM_DESC(fwlog_mem_blocks, "fwlog mem_blocks"); |
6642 | 6642 | ||
6643 | module_param(bug_on_recovery, int, S_IRUSR | S_IWUSR); | 6643 | module_param(bug_on_recovery, int, 0600); |
6644 | MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); | 6644 | MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); |
6645 | 6645 | ||
6646 | module_param(no_recovery, int, S_IRUSR | S_IWUSR); | 6646 | module_param(no_recovery, int, 0600); |
6647 | MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck."); | 6647 | MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck."); |
6648 | 6648 | ||
6649 | MODULE_LICENSE("GPL"); | 6649 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index f8a1fea64e25..1f727babbea0 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c | |||
@@ -469,7 +469,7 @@ static void __exit wl1271_exit(void) | |||
469 | module_init(wl1271_init); | 469 | module_init(wl1271_init); |
470 | module_exit(wl1271_exit); | 470 | module_exit(wl1271_exit); |
471 | 471 | ||
472 | module_param(dump, bool, S_IRUSR | S_IWUSR); | 472 | module_param(dump, bool, 0600); |
473 | MODULE_PARM_DESC(dump, "Enable sdio read/write dumps."); | 473 | MODULE_PARM_DESC(dump, "Enable sdio read/write dumps."); |
474 | 474 | ||
475 | MODULE_LICENSE("GPL"); | 475 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/wireless/ti/wlcore/sysfs.c b/drivers/net/wireless/ti/wlcore/sysfs.c index b72e2101488b..d31eb775e023 100644 --- a/drivers/net/wireless/ti/wlcore/sysfs.c +++ b/drivers/net/wireless/ti/wlcore/sysfs.c | |||
@@ -80,7 +80,7 @@ static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev, | |||
80 | return count; | 80 | return count; |
81 | } | 81 | } |
82 | 82 | ||
83 | static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR, | 83 | static DEVICE_ATTR(bt_coex_state, 0644, |
84 | wl1271_sysfs_show_bt_coex_state, | 84 | wl1271_sysfs_show_bt_coex_state, |
85 | wl1271_sysfs_store_bt_coex_state); | 85 | wl1271_sysfs_store_bt_coex_state); |
86 | 86 | ||
@@ -103,8 +103,7 @@ static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev, | |||
103 | return len; | 103 | return len; |
104 | } | 104 | } |
105 | 105 | ||
106 | static DEVICE_ATTR(hw_pg_ver, S_IRUGO, | 106 | static DEVICE_ATTR(hw_pg_ver, 0444, wl1271_sysfs_show_hw_pg_ver, NULL); |
107 | wl1271_sysfs_show_hw_pg_ver, NULL); | ||
108 | 107 | ||
109 | static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj, | 108 | static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj, |
110 | struct bin_attribute *bin_attr, | 109 | struct bin_attribute *bin_attr, |
@@ -139,7 +138,7 @@ static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj, | |||
139 | } | 138 | } |
140 | 139 | ||
141 | static const struct bin_attribute fwlog_attr = { | 140 | static const struct bin_attribute fwlog_attr = { |
142 | .attr = {.name = "fwlog", .mode = S_IRUSR}, | 141 | .attr = { .name = "fwlog", .mode = 0400 }, |
143 | .read = wl1271_sysfs_read_fwlog, | 142 | .read = wl1271_sysfs_read_fwlog, |
144 | }; | 143 | }; |
145 | 144 | ||