aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-03-29 16:24:06 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-29 16:24:06 -0400
commit18845557fd6fc1998f2d0d8c30467f86db587529 (patch)
tree80e3f239192cb421b54f8e6d85c03270c5ac394d
parente15f20ea33b8e5074145abe464b4b48acea505d9 (diff)
parent14c99949a3398a655c47b262ca8e2e83edfae7fd (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>
-rw-r--r--drivers/bluetooth/Kconfig4
-rw-r--r--drivers/net/wireless/ath/ath.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c9
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h88
-rw-r--r--drivers/net/wireless/ath/ath10k/coredump.c90
-rw-r--r--drivers/net/wireless/ath/ath10k/coredump.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c154
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.h41
-rw-r--r--drivers/net/wireless/ath/ath10k/debugfs_sta.c286
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c113
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c54
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c101
-rw-r--r--drivers/net/wireless/ath/ath10k/trace.h12
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c12
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h56
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c116
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h18
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c462
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h94
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c37
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/sysfs.c8
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/common-debug.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/common-init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/common-spectral.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c40
-rw-r--r--drivers/net/wireless/ath/ath9k/debug_sta.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs_debug.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/tx99.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c4
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.c8
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c4
-rw-r--r--drivers/net/wireless/ath/dfs_pattern_detector.c2
-rw-r--r--drivers/net/wireless/ath/wcn36xx/debug.c5
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.c69
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.h221
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c14
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c115
-rw-r--r--drivers/net/wireless/ath/wcn36xx/txrx.c32
-rw-r--r--drivers/net/wireless/ath/wcn36xx/wcn36xx.h2
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c741
-rw-r--r--drivers/net/wireless/ath/wil6210/debug.c9
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c117
-rw-r--r--drivers/net/wireless/ath/wil6210/ethtool.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/fw.h38
-rw-r--r--drivers/net/wireless/ath/wil6210/fw_inc.c52
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c8
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c333
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c382
-rw-r--r--drivers/net/wireless/ath/wil6210/p2p.c175
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c57
-rw-r--r--drivers/net/wireless/ath/wil6210/pm.c132
-rw-r--r--drivers/net/wireless/ath/wil6210/pmc.c8
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c45
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c177
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h22
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h217
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c460
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c6
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h7
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c88
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h17
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c14
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c82
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h1
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c105
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h4
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c42
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h17
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h7
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c242
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h82
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c11
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h1
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c8
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c157
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h7
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c151
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c96
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c6
-rw-r--r--drivers/net/wireless/cisco/airo.c6
-rw-r--r--drivers/net/wireless/intel/ipw2x00/ipw2100.c29
-rw-r--r--drivers/net/wireless/intel/ipw2x00/ipw2200.c51
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_module.c2
-rw-r--r--drivers/net/wireless/intel/iwlegacy/3945-mac.c35
-rw-r--r--drivers/net/wireless/intel/iwlegacy/4965-mac.c19
-rw-r--r--drivers/net/wireless/intel/iwlegacy/4965-rs.c8
-rw-r--r--drivers/net/wireless/intel/iwlegacy/common.c4
-rw-r--r--drivers/net/wireless/intel/iwlegacy/debug.c58
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/22000.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/9000.c66
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c78
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/rs.c16
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h20
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/scan.h73
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.c10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/debugfs.c26
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/debugfs.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/file.h17
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-config.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-drv.c43
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/constants.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c51
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c110
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c24
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h51
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c21
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.c12
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c25
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c199
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c74
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/time-event.c15
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tx.c168
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/utils.c19
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/drv.c195
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c12
-rw-r--r--drivers/net/wireless/intersil/p54/main.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/11n.c10
-rw-r--r--drivers/net/wireless/mediatek/mt76/debugfs.c10
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c8
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2_main.c11
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c13
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2_tx.c5
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/debugfs.c16
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2500usb.c2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800pci.c2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800soc.c2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800usb.c2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00debug.c64
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt61pci.c2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt73usb.c2
-rw-r--r--drivers/net/wireless/ray_cs.c8
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/base.c1
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c1
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c6
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c33
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c86
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h122
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/pwrseq.h4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/pwrseq.h4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/pwrseq.h4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/pwrseq.h4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c16
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/pwrseq.h4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/wifi.h33
-rw-r--r--drivers/net/wireless/rsi/Kconfig4
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio.c65
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_usb.c1
-rw-r--r--drivers/net/wireless/rsi/rsi_sdio.h2
-rw-r--r--drivers/net/wireless/st/cw1200/debug.c6
-rw-r--r--drivers/net/wireless/st/cw1200/main.c2
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c27
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c8
-rw-r--r--drivers/net/wireless/ti/wlcore/sdio.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/sysfs.c7
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
395config BT_HCIRSI 395config 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
36static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
37
38struct ath_ani { 36struct 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
225struct 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
224struct ath10k_fw_stats_pdev { 246struct 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
349struct 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
355struct 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
327struct ath10k_dfs_stats { 370struct 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
400enum 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
408enum 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
419enum 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
428struct 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
357struct ath10k_sta { 439struct 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
704static 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
704static const struct ath10k_hw_mem_layout hw_mem_layouts[] = { 787static 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
763static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar) 853static 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
1483void
1484ath10k_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
1483static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats, 1496static 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
2159static 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
2171static 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
2193static 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
2201static 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
2224static 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
2256err_free:
2257 vfree(buf);
2258
2259err_unlock:
2260 mutex_unlock(&ar->conf_mutex);
2261 return ret;
2262}
2263
2264static 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
2272static 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
2282static 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
2146int ath10k_debug_create(struct ath10k *ar) 2290int 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);
101void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb); 102void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb);
102void ath10k_debug_tpc_stats_process(struct ath10k *ar, 103void ath10k_debug_tpc_stats_process(struct ath10k *ar,
103 struct ath10k_tpc_stats *tpc_stats); 104 struct ath10k_tpc_stats *tpc_stats);
105void
106ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
107 struct ath10k_tpc_stats_final *tpc_stats);
104void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); 108void 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
171static inline void
172ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
173 struct ath10k_tpc_stats_final *tpc_stats)
174{
175 kfree(tpc_stats);
176}
177
167static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, 178static 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);
192void ath10k_sta_update_rx_duration(struct ath10k *ar, 203void ath10k_sta_update_rx_duration(struct ath10k *ar,
193 struct ath10k_fw_stats *stats); 204 struct ath10k_fw_stats *stats);
205void 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);
212void 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
195static inline 217static inline
196void ath10k_sta_update_rx_duration(struct ath10k *ar, 218void 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
223static inline
224void 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
234static inline
235void 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
23static 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
39static 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
59void 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
84out:
85 spin_unlock_bh(&ar->data_lock);
86 rcu_read_unlock();
87}
88
89void 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
135exit:
136 rcu_read_unlock();
137}
138
21static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar, 139static 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
463static 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
481static 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
505static 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
546static 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
622static 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
345void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 629void 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
727static 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
726static void ath10k_htt_rx_h_rates(struct ath10k *ar, 749static 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)
1502static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, 1509static 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
1654static int ath10k_unchain_msdu(struct sk_buff_head *amsdu) 1677static 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
1697static void ath10k_htt_rx_h_unchain(struct ath10k *ar, 1725static 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
1723static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, 1754static 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
1744static void ath10k_htt_rx_h_filter(struct ath10k *ar, 1775static 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
1820static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, 1876static 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
2505static void ath10k_htt_fetch_peer_stats(struct ath10k *ar, 2562static 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
5917exit: 5939exit:
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
60static const struct pci_device_id ath10k_pci_id_table[] = { 64static 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 */
1592static 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 */
1611static 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 */
1625static 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
1587static void ath10k_pci_dump_memory(struct ath10k *ar, 1654static 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);
3718MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_BOARD_API2_FILE); 3778MODULE_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 */
3781MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" ATH10K_FW_API6_FILE);
3721MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" ATH10K_FW_API5_FILE); 3782MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" ATH10K_FW_API5_FILE);
3722MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" QCA9377_HW_1_0_BOARD_DATA_FILE); 3783MODULE_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
154TRACE_EVENT(ath10k_wmi_cmd, 154TRACE_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
202int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); 209int 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
374static inline int 381static inline int
382ath10k_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
403static inline int
375ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) 404ath10k_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
1451static inline int
1452ath10k_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
416static 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
429static 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
2486static struct sk_buff * 2549static struct sk_buff *
2487ath10k_wmi_tlv_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) 2550ath10k_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
2664static struct sk_buff * 2722static struct sk_buff *
2723ath10k_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
2741static struct sk_buff *
2665ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar) 2742ath10k_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
1343struct wmi_tlv_pdev_get_temp_cmd {
1344 __le32 pdev_id; /* not used */
1345} __packed;
1346
1347struct 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
1343struct wmi_tlv_pdev_set_param_cmd { 1354struct 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
1760struct 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
1749void ath10k_wmi_tlv_attach(struct ath10k *ar); 1767void ath10k_wmi_tlv_attach(struct ath10k *ar);
1750 1768
1751struct wmi_tlv_mgmt_tx_cmd { 1769struct 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
1485static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = { 1490static 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
2711static void
2712ath10k_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
2706static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar, 2733static 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
4316void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) 4369void 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
4466void 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
4523static u8
4524ath10k_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
4637out:
4638 return tpc;
4639}
4640
4641static void
4642ath10k_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
4706void 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
4460static void 4763static void
4461ath10k_wmi_handle_tdls_peer_event(struct ath10k *ar, struct sk_buff *skb) 4764ath10k_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
8055static void
8056ath10k_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
7748void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, 8121void 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
7992static struct sk_buff * 8364static struct sk_buff *
8365ath10k_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
8382static struct sk_buff *
7993ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar, 8383ath10k_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
344static inline char *wmi_service_name(int service_id) 351static 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
4001enum wmi_tpc_table_type { 4019enum 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
4060struct 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
4081struct wmi_pdev_get_tpc_table_cmd {
4082 __le32 param;
4083} __packed;
4084
4085enum 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
4095enum 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
4042struct wmi_pdev_chanlist_update_event { 4105struct 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
4355struct wlan_inst_rssi_args { 4419struct 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
4494struct wmi_vdev_stats { 4562struct wmi_vdev_stats {
4495 __le32 vdev_id; 4563 __le32 vdev_id;
4496} __packed; 4564} __packed;
4497 4565
4566struct 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
6734enum wmi_tdls_peer_state { 6823enum wmi_tdls_peer_state {
@@ -6979,5 +7068,8 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
6979int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar, 7068int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar,
6980 enum wmi_vdev_subtype subtype); 7069 enum wmi_vdev_subtype subtype);
6981int ath10k_wmi_barrier(struct ath10k *ar); 7070int ath10k_wmi_barrier(struct ath10k *ar);
7071void ath10k_wmi_tpc_config_get_rate_code(u8 *rate_code, u16 *pream_table,
7072 u32 num_tx_chain);
7073void 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
75bool ath5k_modparam_nohwcrypt; 75bool ath5k_modparam_nohwcrypt;
76module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO); 76module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, 0444);
77MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 77MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
78 78
79static bool modparam_fastchanswitch; 79static bool modparam_fastchanswitch;
80module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); 80module_param_named(fastchanswitch, modparam_fastchanswitch, bool, 0444);
81MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); 81MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
82 82
83static bool ath5k_modparam_no_hw_rfkill_switch; 83static bool ath5k_modparam_no_hw_rfkill_switch;
84module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch, 84module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch,
85 bool, S_IRUGO); 85 bool, 0444);
86MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state"); 86MODULE_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} \
34static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, \ 34static 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} \
46static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) 46static 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}
69static DEVICE_ATTR(noise_immunity_level_max, S_IRUGO, 69static 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
72static ssize_t ath5k_attr_show_firstep_level_max(struct device *dev, 72static 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}
78static DEVICE_ATTR(firstep_level_max, S_IRUGO, 78static DEVICE_ATTR(firstep_level_max, 0444,
79 ath5k_attr_show_firstep_level_max, NULL); 79 ath5k_attr_show_firstep_level_max, NULL);
80 80
81static struct attribute *ath5k_sysfs_entries_ani[] = { 81static 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 = {
47void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy, 47void 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}
53EXPORT_SYMBOL(ath9k_cmn_debug_modal_eeprom); 53EXPORT_SYMBOL(ath9k_cmn_debug_modal_eeprom);
@@ -82,7 +82,7 @@ static const struct file_operations fops_base_eeprom = {
82void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy, 82void 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}
88EXPORT_SYMBOL(ath9k_cmn_debug_base_eeprom); 88EXPORT_SYMBOL(ath9k_cmn_debug_base_eeprom);
@@ -178,8 +178,7 @@ static const struct file_operations fops_recv = {
178void ath9k_cmn_debug_recv(struct dentry *debugfs_phy, 178void 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}
184EXPORT_SYMBOL(ath9k_cmn_debug_recv); 183EXPORT_SYMBOL(ath9k_cmn_debug_recv);
185 184
@@ -255,7 +254,7 @@ static const struct file_operations fops_phy_err = {
255void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy, 254void 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}
261EXPORT_SYMBOL(ath9k_cmn_debug_phy_err); 260EXPORT_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
145void ath9k_dfs_init_debug(struct ath_softc *sc) 145void 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}
1138EXPORT_SYMBOL(ath9k_hw_init_global_settings); 1146EXPORT_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...) \
207static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar, \ 207static 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
50static bool modparam_nohwcrypt; 50static bool modparam_nohwcrypt;
51module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 51module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
52MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload."); 52MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload.");
53 53
54int modparam_noht; 54int modparam_noht;
55module_param_named(noht, modparam_noht, int, S_IRUGO); 55module_param_named(noht, modparam_noht, int, 0444);
56MODULE_PARM_DESC(noht, "Disable MPDU aggregation."); 56MODULE_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
169void wcn36xx_debugfs_exit(struct wcn36xx *wcn) 168void 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
30void *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
39static void wcn36xx_ccu_write_register(struct wcn36xx *wcn, int addr, int data) 30static 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
613int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, 640int 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
455struct wcn36xx_tx_bd;
269struct wcn36xx_vif; 456struct wcn36xx_vif;
270int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn); 457int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn);
271void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn); 458void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn);
@@ -277,8 +464,8 @@ void wcn36xx_dxe_deinit(struct wcn36xx *wcn);
277int wcn36xx_dxe_init_channels(struct wcn36xx *wcn); 464int wcn36xx_dxe_init_channels(struct wcn36xx *wcn);
278int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, 465int 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);
282void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status); 470void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status);
283void *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}
2459int wcn36xx_smd_open(struct wcn36xx *wcn) 2472int 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
261int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, 264int 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 */
351static int wil_find_cid_by_idx(struct wil6210_priv *wil, int idx) 357static 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
422static 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, &params);
439}
440
441static 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, &params);
465 }
466 return ret;
467}
468
413static struct wireless_dev * 469static struct wireless_dev *
414wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name, 470wil_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;
541out:
542 wil_vif_free(vif);
543 return ERR_PTR(rc);
544}
545
546int 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
449static int wil_cfg80211_del_iface(struct wiphy *wiphy, 571static 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);
605out:
606 return rc;
465} 607}
466 608
467static int wil_cfg80211_change_iface(struct wiphy *wiphy, 609static 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
632out_restore: 806out_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 }
638out: 813out:
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
666out: 842out:
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
965static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil, 1146static 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
995static struct wil_sta_info * 1176static struct wil_sta_info *
996wil_find_sta_by_key_usage(struct wil6210_priv *wil, 1177wil_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 */
1278static int _wil_cfg80211_set_ies(struct wiphy *wiphy, 1466static 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
1318out: 1506out:
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
1380err_bcast: 1572err_bcast:
1381 wmi_pcp_stop(wil); 1573 wmi_pcp_stop(vif);
1382err_pcp_start: 1574err_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);
1385out: 1578out:
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
1529static int wil_cfg80211_del_station(struct wiphy *wiphy, 1732static 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 */
1592static void wil_probe_client_handle(struct wil6210_priv *wil, 1798static 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
1606static struct list_head *next_probe_client(struct wil6210_priv *wil) 1813static 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
1622void wil_probe_client_worker(struct work_struct *work) 1829void 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
1637void wil_probe_client_flush(struct wil6210_priv *wil) 1845void 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
1653static int wil_cfg80211_probe_client(struct wiphy *wiphy, 1862static 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
1741out: 1953out:
@@ -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
1896struct wireless_dev *wil_cfg80211_init(struct device *dev) 2117int 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); 2189struct 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
1919out: 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
1925void wil_wdev_free(struct wil6210_priv *wil) 2218void 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
1938void wil_p2p_wdev_free(struct wil6210_priv *wil) 2234void 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
2282static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil, 2581static 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 = {
1155static int wil_freq_debugfs_show(struct seq_file *s, void *data) 1176static 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 = {
1229static int wil_info_debugfs_show(struct seq_file *s, void *data) 1260static 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
1498static 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
1522static 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
1527static 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
1464static ssize_t wil_read_file_led_cfg(struct file *file, char __user *user_buf, 1534static 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 */
1775static const struct dbg_off dbg_wil_off[] = { 1846static 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
83struct 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
88struct 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
97struct 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
175static int 174static int
175fw_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);
207out_short:
208 wil_err_fw(wil, "concurrency record truncated\n");
209 return 0;
210}
211
212static int
176fw_handle_comment(struct wil6210_priv *wil, const void *data, 213fw_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
128void wil6210_unmask_irq_rx(struct wil6210_priv *wil) 128void 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
189void wil_configure_interrupt_moderation(struct wil6210_priv *wil) 189void 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
341static void wil_notify_fw_error(struct wil6210_priv *wil) 343static 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
163static void wil_disconnect_cid(struct wil6210_priv *wil, int cid, 163static 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
219static bool wil_is_connected(struct wil6210_priv *wil) 230static 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
231static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, 243static 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
306static void wil_disconnect_worker(struct work_struct *work) 325void 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
340static 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
355static 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
364static int wil_wait_for_recovery(struct wil6210_priv *wil) 360static 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
464int wil_tx_init(struct wil6210_priv *wil, int cid) 464int 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
486out: 487out:
487 return rc; 488 return rc;
488} 489}
489 490
490int wil_bcast_init(struct wil6210_priv *wil) 491int 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
509void wil_bcast_fini(struct wil6210_priv *wil) 511void 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
523void 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
520int wil_priv_init(struct wil6210_priv *wil) 535int 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
587out_wmi_wq: 596out_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 */
611void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, 620void 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
620void wil_priv_deinit(struct wil6210_priv *wil) 631void 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
944static int wil_get_bl_info(struct wil6210_priv *wil) 945static 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
1036static int wil_get_otp_info(struct wil6210_priv *wil) 1037static 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
1072void wil_abort_scan(struct wil6210_priv *wil, bool sync) 1073void 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
1102void 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
1157static 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 */
1146int wil_reset(struct wil6210_priv *wil, bool load_fw) 1190int 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
1338int __wil_up(struct wil6210_priv *wil) 1394int __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
1445int wil_find_cid(struct wil6210_priv *wil, const u8 *mac) 1501int 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
23bool 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
44bool 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
21static int wil_open(struct net_device *ndev) 50static 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)
45static int wil_stop(struct net_device *ndev) 77static 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
124void *wil_if_alloc(struct device *dev) 167static 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); 178void 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"); 186static 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; 193static 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
209static 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
219static 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
229static 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
248static 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); 260struct wil6210_vif *
261wil_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
312void *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: 344out_priv:
177 wil_priv_deinit(wil); 345 wil_priv_deinit(wil);
178 346
179 out_wdev: 347out_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
185void wil_if_free(struct wil6210_priv *wil) 353void 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
371int 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
202int wil_if_add(struct wil6210_priv *wil) 403int 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
234out_wiphy: 437out_wiphy:
235 wiphy_unregister(wdev->wiphy); 438 wiphy_unregister(wiphy);
236 return rc; 439 return rc;
237} 440}
238 441
442void 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
239void wil_if_remove(struct wil6210_priv *wil) 495void 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
25static int wil_p2p_start_listen(struct wil6210_priv *wil) 26static 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));
54out_stop: 56out_stop:
55 if (rc) 57 if (rc)
56 wmi_stop_discovery(wil); 58 wmi_stop_discovery(vif);
57 59
58out: 60out:
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
68void wil_p2p_discovery_timer_fn(struct timer_list *t) 70int 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
77int 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
134out_stop: 128out_stop:
135 if (rc) 129 if (rc)
136 wmi_stop_discovery(wil); 130 wmi_stop_discovery(vif);
137 131
138out: 132out:
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
192u8 wil_p2p_stop_discovery(struct wil6210_priv *wil) 188u8 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
211int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie) 207int 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
270void wil_p2p_search_expired(struct work_struct *work) 270void 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
339out: 345out:
340 mutex_unlock(&wil->mutex); 346 mutex_unlock(&wil->mutex);
@@ -342,34 +348,35 @@ out:
342 348
343void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) 349void 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
381out: 388out:
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
140static 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 */
141static int wil_if_pcie_enable(struct wil6210_priv *wil) 155static 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
397if_remove:
398 wil_if_remove(wil);
375bus_disable: 399bus_disable:
376 wil_if_pcie_disable(wil); 400 wil_if_pcie_disable(wil);
377err_iounmap: 401err_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
24static 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
38static 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
52static bool
53wil_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
23int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) 84int 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
87out: 139out:
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
133out: 184out:
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
251reject_suspend: 301reject_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
258static int wil_suspend_radio_off(struct wil6210_priv *wil) 307static 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:
306static int wil_resume_radio_off(struct wil6210_priv *wil) 359static 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
43static void wil_release_reorder_frame(struct wil6210_priv *wil, 44static 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
62static void wil_release_reorder_frames(struct wil6210_priv *wil, 62static 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
81static void wil_reorder_release(struct wil6210_priv *wil, 81static 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,
93void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb) 93void 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
204out: 213out:
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 */
209void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq) 218void 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
230out: 241out:
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) */
295int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid, 306int 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 */
625static int wil_rx_refill(struct wil6210_priv *wil, int count) 641static 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)
713void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) 729void 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 */
816void wil_rx_handle(struct wil6210_priv *wil, int *quota) 834void 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
917int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, 938int 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
1006int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size) 1029int 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
1110static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil, 1137static 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
1145static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 1173static 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
1148static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil, 1176static 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 */
1195static struct vring *wil_find_tx_bcast_1(struct wil6210_priv *wil, 1224static 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
1224static struct vring *wil_find_tx_bcast_2(struct wil6210_priv *wil, 1254static 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
1420static int __wil_tx_vring_tso(struct wil6210_priv *wil, struct vring *vring, 1452static 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
1713static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 1745static 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 = &dd; 1749 struct vring_tx_desc dd, *d = &dd;
@@ -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
1863static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 1895static 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 */
1905static inline void __wil_update_net_queues(struct wil6210_priv *wil, 1938static 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
1961void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring, 1999void 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
1969void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring, 2007void 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
1977netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) 2015netdev_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 */
2075int wil_tx_complete(struct wil6210_priv *wil, int ringid) 2115int 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
452static inline int wil_rxdesc_mid(struct vring_rx_desc *d) 464static 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
457static inline int wil_rxdesc_ftype(struct vring_rx_desc *d) 470static 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
518void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev); 531void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev);
519void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb); 532void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb);
520void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq); 533void wil_rx_bar(struct wil6210_priv *wil, struct wil6210_vif *vif,
534 u8 cid, u8 tid, u16 seq);
521struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, 535struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
522 int size, u16 ssn); 536 int size, u16 ssn);
523void wil_tid_ampdu_rx_free(struct wil6210_priv *wil, 537void 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
30extern bool no_fw_recovery; 31extern bool no_fw_recovery;
31extern unsigned int mtu_max; 32extern 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
469enum { /* for wil6210_priv.status */ 476enum { /* 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 {
541struct wil_p2p_info { 546struct 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 */
585struct wil_sta_info { 589struct 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];
669extern u8 led_id; 674extern u8 led_id;
670extern u8 led_polarity; 675extern u8 led_polarity;
671 676
677enum wil6210_vif_status {
678 wil_vif_fwconnecting,
679 wil_vif_fwconnected,
680 wil_vif_status_last /* keep last */
681};
682
683struct 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
672struct wil6210_priv { 710struct 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
836static 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
846static inline struct wireless_dev *
847vif_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)
810void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...); 857void 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)
818void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...); 865void 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,
900void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, 947void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
901 size_t count); 948 size_t count);
902 949
950struct wil6210_vif *
951wil_vif_alloc(struct wil6210_priv *wil, const char *name,
952 unsigned char name_assign_type, enum nl80211_iftype iftype);
953void wil_vif_free(struct wil6210_vif *vif);
903void *wil_if_alloc(struct device *dev); 954void *wil_if_alloc(struct device *dev);
955bool wil_has_other_active_ifaces(struct wil6210_priv *wil,
956 struct net_device *ndev, bool up, bool ok);
957bool wil_has_active_ifaces(struct wil6210_priv *wil, bool up, bool ok);
904void wil_if_free(struct wil6210_priv *wil); 958void wil_if_free(struct wil6210_priv *wil);
959int wil_vif_add(struct wil6210_priv *wil, struct wil6210_vif *vif);
905int wil_if_add(struct wil6210_priv *wil); 960int wil_if_add(struct wil6210_priv *wil);
961void wil_vif_remove(struct wil6210_priv *wil, u8 mid);
906void wil_if_remove(struct wil6210_priv *wil); 962void wil_if_remove(struct wil6210_priv *wil);
907int wil_priv_init(struct wil6210_priv *wil); 963int wil_priv_init(struct wil6210_priv *wil);
908void wil_priv_deinit(struct wil6210_priv *wil); 964void wil_priv_deinit(struct wil6210_priv *wil);
@@ -918,7 +974,7 @@ int wil_down(struct wil6210_priv *wil);
918int __wil_down(struct wil6210_priv *wil); 974int __wil_down(struct wil6210_priv *wil);
919void wil_refresh_fw_capabilities(struct wil6210_priv *wil); 975void wil_refresh_fw_capabilities(struct wil6210_priv *wil);
920void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); 976void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r);
921int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); 977int wil_find_cid(struct wil6210_priv *wil, u8 mid, const u8 *mac);
922void wil_set_ethtoolops(struct net_device *ndev); 978void wil_set_ethtoolops(struct net_device *ndev);
923 979
924struct fw_map *wil_find_fw_mapping(const char *section); 980struct fw_map *wil_find_fw_mapping(const char *section);
@@ -927,40 +983,45 @@ void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr);
927void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); 983void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr);
928int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, 984int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,
929 struct wil6210_mbox_hdr *hdr); 985 struct wil6210_mbox_hdr *hdr);
930int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len); 986int wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len);
931void wmi_recv_cmd(struct wil6210_priv *wil); 987void wmi_recv_cmd(struct wil6210_priv *wil);
932int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, 988int 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);
934void wmi_event_worker(struct work_struct *work); 990void wmi_event_worker(struct work_struct *work);
935void wmi_event_flush(struct wil6210_priv *wil); 991void wmi_event_flush(struct wil6210_priv *wil);
936int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid); 992int wmi_set_ssid(struct wil6210_vif *vif, u8 ssid_len, const void *ssid);
937int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid); 993int wmi_get_ssid(struct wil6210_vif *vif, u8 *ssid_len, void *ssid);
938int wmi_set_channel(struct wil6210_priv *wil, int channel); 994int wmi_set_channel(struct wil6210_priv *wil, int channel);
939int wmi_get_channel(struct wil6210_priv *wil, int *channel); 995int wmi_get_channel(struct wil6210_priv *wil, int *channel);
940int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, 996int 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);
942int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, 998int 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);
945int wmi_echo(struct wil6210_priv *wil); 1001int wmi_echo(struct wil6210_priv *wil);
946int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie); 1002int wmi_set_ie(struct wil6210_vif *vif, u8 type, u16 ie_len, const void *ie);
947int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring); 1003int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
948int wmi_rxon(struct wil6210_priv *wil, bool on); 1004int wmi_rxon(struct wil6210_priv *wil, bool on);
949int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); 1005int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
950int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, 1006int 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);
952int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout); 1008int wmi_addba(struct wil6210_priv *wil, u8 mid,
953int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason); 1009 u8 ringid, u8 size, u16 timeout);
954int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason); 1010int wmi_delba_tx(struct wil6210_priv *wil, u8 mid, u8 ringid, u16 reason);
955int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, 1011int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cidxtid, u16 reason);
1012int 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);
957int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, 1015int 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);
959int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short); 1017int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short);
960int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short); 1018int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short);
961int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid); 1019int wmi_new_sta(struct wil6210_vif *vif, const u8 *mac, u8 aid);
962int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid, 1020int 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);
1022int wmi_port_delete(struct wil6210_priv *wil, u8 mid);
1023int 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);
965int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize); 1026int 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 */
978bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request); 1039bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request);
979void wil_p2p_discovery_timer_fn(struct timer_list *t); 1040int wil_p2p_search(struct wil6210_vif *vif,
980int wil_p2p_search(struct wil6210_priv *wil,
981 struct cfg80211_scan_request *request); 1041 struct cfg80211_scan_request *request);
982int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev, 1042int 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);
985u8 wil_p2p_stop_discovery(struct wil6210_priv *wil); 1045u8 wil_p2p_stop_discovery(struct wil6210_vif *vif);
986int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie); 1046int wil_p2p_cancel_listen(struct wil6210_vif *vif, u64 cookie);
987void wil_p2p_listen_expired(struct work_struct *work); 1047void wil_p2p_listen_expired(struct work_struct *work);
988void wil_p2p_search_expired(struct work_struct *work); 1048void wil_p2p_search_expired(struct work_struct *work);
989void wil_p2p_stop_radio_operations(struct wil6210_priv *wil); 1049void wil_p2p_stop_radio_operations(struct wil6210_priv *wil);
990void wil_p2p_delayed_listen_work(struct work_struct *work); 1050void wil_p2p_delayed_listen_work(struct work_struct *work);
991 1051
992/* WMI for P2P */ 1052/* WMI for P2P */
993int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi); 1053int wmi_p2p_cfg(struct wil6210_vif *vif, int channel, int bi);
994int wmi_start_listen(struct wil6210_priv *wil); 1054int wmi_start_listen(struct wil6210_vif *vif);
995int wmi_start_search(struct wil6210_priv *wil); 1055int wmi_start_search(struct wil6210_vif *vif);
996int wmi_stop_discovery(struct wil6210_priv *wil); 1056int wmi_stop_discovery(struct wil6210_vif *vif);
997 1057
998int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 1058int 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);
1061int wil_cfg80211_iface_combinations_from_fw(
1062 struct wil6210_priv *wil,
1063 const struct wil_fw_record_concurrency *conc);
1064int wil_vif_prepare_stop(struct wil6210_vif *vif);
1001 1065
1002#if defined(CONFIG_WIL6210_DEBUGFS) 1066#if defined(CONFIG_WIL6210_DEBUGFS)
1003int wil6210_debugfs_init(struct wil6210_priv *wil); 1067int wil6210_debugfs_init(struct wil6210_priv *wil);
@@ -1007,44 +1071,47 @@ static inline int wil6210_debugfs_init(struct wil6210_priv *wil) { return 0; }
1007static inline void wil6210_debugfs_remove(struct wil6210_priv *wil) {} 1071static inline void wil6210_debugfs_remove(struct wil6210_priv *wil) {}
1008#endif 1072#endif
1009 1073
1010int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, 1074int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
1011 struct station_info *sinfo); 1075 struct station_info *sinfo);
1012 1076
1013struct wireless_dev *wil_cfg80211_init(struct device *dev); 1077struct wil6210_priv *wil_cfg80211_init(struct device *dev);
1014void wil_wdev_free(struct wil6210_priv *wil); 1078void wil_cfg80211_deinit(struct wil6210_priv *wil);
1015void wil_p2p_wdev_free(struct wil6210_priv *wil); 1079void wil_p2p_wdev_free(struct wil6210_priv *wil);
1016 1080
1017int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); 1081int wmi_set_mac_address(struct wil6210_priv *wil, void *addr);
1018int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, 1082int 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);
1020int wmi_pcp_stop(struct wil6210_priv *wil); 1084int wmi_pcp_stop(struct wil6210_vif *vif);
1021int wmi_led_cfg(struct wil6210_priv *wil, bool enable); 1085int wmi_led_cfg(struct wil6210_priv *wil, bool enable);
1022int wmi_abort_scan(struct wil6210_priv *wil); 1086int wmi_abort_scan(struct wil6210_vif *vif);
1023void wil_abort_scan(struct wil6210_priv *wil, bool sync); 1087void wil_abort_scan(struct wil6210_vif *vif, bool sync);
1088void wil_abort_scan_all_vifs(struct wil6210_priv *wil, bool sync);
1024void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps); 1089void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps);
1025void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, 1090void wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
1026 u16 reason_code, bool from_event); 1091 u16 reason_code, bool from_event);
1027void wil_probe_client_flush(struct wil6210_priv *wil); 1092void wil_probe_client_flush(struct wil6210_vif *vif);
1028void wil_probe_client_worker(struct work_struct *work); 1093void wil_probe_client_worker(struct work_struct *work);
1094void wil_disconnect_worker(struct work_struct *work);
1029 1095
1030int wil_rx_init(struct wil6210_priv *wil, u16 size); 1096int wil_rx_init(struct wil6210_priv *wil, u16 size);
1031void wil_rx_fini(struct wil6210_priv *wil); 1097void wil_rx_fini(struct wil6210_priv *wil);
1032 1098
1033/* TX API */ 1099/* TX API */
1034int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, 1100int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size,
1035 int cid, int tid); 1101 int cid, int tid);
1036void wil_vring_fini_tx(struct wil6210_priv *wil, int id); 1102void wil_vring_fini_tx(struct wil6210_priv *wil, int id);
1037int wil_tx_init(struct wil6210_priv *wil, int cid); 1103int wil_tx_init(struct wil6210_vif *vif, int cid);
1038int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size); 1104int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size);
1039int wil_bcast_init(struct wil6210_priv *wil); 1105int wil_bcast_init(struct wil6210_vif *vif);
1040void wil_bcast_fini(struct wil6210_priv *wil); 1106void wil_bcast_fini(struct wil6210_vif *vif);
1041 1107void wil_bcast_fini_all(struct wil6210_priv *wil);
1042void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring, 1108
1043 bool should_stop); 1109void wil_update_net_queues(struct wil6210_priv *wil, struct wil6210_vif *vif,
1044void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring, 1110 struct vring *vring, bool should_stop);
1045 bool check_stop); 1111void wil_update_net_queues_bh(struct wil6210_priv *wil, struct wil6210_vif *vif,
1112 struct vring *vring, bool check_stop);
1046netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); 1113netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
1047int wil_tx_complete(struct wil6210_priv *wil, int ringid); 1114int wil_tx_complete(struct wil6210_vif *vif, int ringid);
1048void wil6210_unmask_irq_tx(struct wil6210_priv *wil); 1115void 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
519static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) 527static 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
640int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) 649int 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 ===*/
652static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) 661static 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
677static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) 689static 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
763static void wmi_evt_tx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) 776static 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
774static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, 787static 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
804static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) 820static 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
953out: 972out:
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
960static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, 981static 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 */
987static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id, 1009static 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
1037static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len) 1059static 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
1061static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d, 1084static 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
1092static void wmi_evt_addba_rx_req(struct wil6210_priv *wil, int id, void *d, 1116static 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
1102static void wmi_evt_delba(struct wil6210_priv *wil, int id, void *d, int len) 1127static 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
1150static void 1176static void
1151wmi_evt_sched_scan_result(struct wil6210_priv *wil, int id, void *d, int len) 1177wmi_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 */
1223static void wmi_evt_ignore(struct wil6210_priv *wil, int id, void *d, int len) 1250static 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
1228static const struct { 1257static 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
1387int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, 1418int 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,
1419out: 1451out:
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
1431int wmi_echo(struct wil6210_priv *wil) 1464int 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
1441int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) 1475int 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
1452int wmi_led_cfg(struct wil6210_priv *wil, bool enable) 1488int 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
1506int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, 1543int 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
1564int wmi_pcp_stop(struct wil6210_priv *wil) 1602int 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
1576int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid) 1615int 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
1590int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid) 1630int 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
1614int wmi_set_channel(struct wil6210_priv *wil, int channel) 1655int 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
1623int wmi_get_channel(struct wil6210_priv *wil, int *channel) 1666int 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
1644int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi) 1688int 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
1669int wmi_start_listen(struct wil6210_priv *wil) 1714int 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
1690int wmi_start_search(struct wil6210_priv *wil) 1736int 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
1711int wmi_stop_discovery(struct wil6210_priv *wil) 1758int 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
1726int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, 1774int 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
1739int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, 1789int 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
1759int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) 1811int 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);
1791out: 1844out:
1792 if (rc) { 1845 if (rc) {
@@ -1808,6 +1861,7 @@ out:
1808 */ 1861 */
1809int wmi_rxon(struct wil6210_priv *wil, bool on) 1862int 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
1833int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring) 1887int 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
1896int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf) 1951int 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
1922int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, 1978int 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
1975int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout) 2033int 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
1990int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason) 2049int 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
2002int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason) 2061int 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
2015int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, 2074int 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,
2056int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, 2117int 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
2090int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short) 2153int 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
2123int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short) 2188int 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
2149int wmi_abort_scan(struct wil6210_priv *wil) 2215int 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
2162int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid) 2229int 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
2207int wmi_suspend(struct wil6210_priv *wil) 2275int 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
2290int wmi_resume(struct wil6210_priv *wil) 2360int 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
2316static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id, 2387int 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
2441int 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
2473static 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,
2523int wmi_start_sched_scan(struct wil6210_priv *wil, 2700int 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
2567int wmi_stop_sched_scan(struct wil6210_priv *wil) 2746int 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
448static void brcmf_proto_bcdc_debugfs_create(struct brcmf_pub *drvr)
449{
450 brcmf_fws_debugfs_create(drvr);
451}
452
448int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) 453int 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)
462int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif, 462int 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 */
144struct brcmf_bus { 145struct 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
230static inline 231static inline
231int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev, 232int 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,
753static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy, 753static 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:
786static 786static
787int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) 787int 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
2127brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, 2127brcmf_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
5191struct cfg80211_ops *brcmf_cfg80211_get_ops(void)
5192{
5193 return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
5194 GFP_KERNEL);
5195}
5196
5193struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, 5197struct 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,
5897static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, 5901static 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
6013static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) 6017static 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
6200static int brcmf_setup_wiphybands(struct wiphy *wiphy) 6204static 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],
6794static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, 6798static 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
6836static void brcmf_free_wiphy(struct wiphy *wiphy) 6840static 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
6863struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, 6866struct 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;
7043wiphy_out: 7037wiphy_out:
7044 brcmf_free_wiphy(wiphy); 7038 brcmf_free_wiphy(wiphy);
7045ops_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
356static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w) 356static 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
361static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd) 362static 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
367static 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
366static inline 372static inline
367struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg) 373struct 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
374static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev) 378static 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
397struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, 401struct 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);
400void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); 404void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
401s32 brcmf_cfg80211_up(struct net_device *ndev); 405s32 brcmf_cfg80211_up(struct net_device *ndev);
402s32 brcmf_cfg80211_down(struct net_device *ndev); 406s32 brcmf_cfg80211_down(struct net_device *ndev);
407struct cfg80211_ops *brcmf_cfg80211_get_ops(void);
403enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); 408enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
404 409
405struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, 410struct 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
467static char *brcmf_chip_name(uint chipid, char *buf, uint len) 467char *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,
93void brcmf_chip_set_passive(struct brcmf_chip *ci); 93void brcmf_chip_set_passive(struct brcmf_chip *ci);
94bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec); 94bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec);
95bool brcmf_chip_sr_capable(struct brcmf_chip *pub); 95bool brcmf_chip_sr_capable(struct brcmf_chip *pub);
96char *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
34MODULE_AUTHOR("Broadcom Corporation"); 35MODULE_AUTHOR("Broadcom Corporation");
35MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); 36MODULE_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 */
53int brcmf_msg_level; 54int brcmf_msg_level;
54module_param_named(debug, brcmf_msg_level, int, S_IRUSR | S_IWUSR); 55module_param_named(debug, brcmf_msg_level, int, 0600);
55MODULE_PARM_DESC(debug, "Level of debug output"); 56MODULE_PARM_DESC(debug, "Level of debug output");
56 57
57static int brcmf_p2p_enable; 58static int brcmf_p2p_enable;
@@ -64,7 +65,7 @@ MODULE_PARM_DESC(feature_disable, "Disable features");
64 65
65static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN]; 66static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN];
66module_param_string(alternative_fw_path, brcmf_firmware_path, 67module_param_string(alternative_fw_path, brcmf_firmware_path,
67 BRCMF_FW_ALTPATH_LEN, S_IRUSR); 68 BRCMF_FW_ALTPATH_LEN, 0400);
68MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path"); 69MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path");
69 70
70static int brcmf_fcmode; 71static int brcmf_fcmode;
@@ -72,9 +73,13 @@ module_param_named(fcmode, brcmf_fcmode, int, 0);
72MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control"); 73MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
73 74
74static int brcmf_roamoff; 75static int brcmf_roamoff;
75module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR); 76module_param_named(roamoff, brcmf_roamoff, int, 0400);
76MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); 77MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
77 78
79static int brcmf_iapp_enable;
80module_param_named(iapp, brcmf_iapp_enable, int, 0);
81MODULE_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() */
80static int brcmf_ignore_probe_fail; 85static 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
127static 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 }
157done:
158 return err;
159}
160
161static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) 132static 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
544module_init(brcmfmac_module_init); 524module_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 */
238static 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
233static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, 264static 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
326void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) 374void 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
947static int brcmf_bus_started(struct brcmf_pub *drvr) 1003static 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
1029fail: 1081fail:
@@ -1045,17 +1097,26 @@ fail:
1045 1097
1046int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) 1098int 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
1094fail: 1154fail:
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
1163s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len) 1224s32 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
28static struct dentry *root_folder;
29
30int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, 28int 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
57void 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
64void brcmf_debugfs_exit(void)
65{
66 if (!root_folder)
67 return;
68
69 debugfs_remove_recursive(root_folder);
70 root_folder = NULL;
71}
72
73int 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
84void 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
92struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) 55struct 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
97int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, 60int 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;
113struct brcmf_bus; 113struct brcmf_bus;
114struct brcmf_pub; 114struct brcmf_pub;
115#ifdef DEBUG 115#ifdef DEBUG
116void brcmf_debugfs_init(void);
117void brcmf_debugfs_exit(void);
118int brcmf_debug_attach(struct brcmf_pub *drvr);
119void brcmf_debug_detach(struct brcmf_pub *drvr);
120struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); 116struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
121int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, 117int 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));
123int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, 119int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
124 size_t len); 120 size_t len);
125#else 121#else
126static inline void brcmf_debugfs_init(void)
127{
128}
129static inline void brcmf_debugfs_exit(void)
130{
131}
132static inline int brcmf_debug_attach(struct brcmf_pub *drvr)
133{
134 return 0;
135}
136static inline void brcmf_debug_detach(struct brcmf_pub *drvr)
137{
138}
139static inline 122static inline
140int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, 123int 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
233void 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 {
90void brcmf_feat_attach(struct brcmf_pub *drvr); 90void 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 */
97void 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
438struct brcmf_fw { 439struct 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
446static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
447
448static 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
449static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) 462static 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
484fail: 503fail:
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
491static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx) 510static 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
545static 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
515fail: 581fail:
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;
517done: 586done:
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
522int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, 591static 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
606int 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
555int 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
565int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, 631struct brcmf_fw_request *
566 struct brcmf_firmware_mapping mapping_table[], 632brcmf_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 @@
38struct brcmf_firmware_mapping { 35struct 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) \
46static const char BRCM_ ## fw_nvram_name ## _FIRMWARE_NAME[] = \ 42static const char BRCM_ ## fw_name ## _FIRMWARE_BASENAME[] = \
47 BRCMF_FW_DEFAULT_PATH fw; \ 43 BRCMF_FW_DEFAULT_PATH fw_base; \
48static const char BRCM_ ## fw_nvram_name ## _NVRAM_NAME[] = \ 44MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw_base ".bin")
49 BRCMF_FW_DEFAULT_PATH nvram; \
50MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw);
51
52#define BRCMF_FW_DEF(fw_name, fw) \
53static const char BRCM_ ## fw_name ## _FIRMWARE_NAME[] = \
54 BRCMF_FW_DEFAULT_PATH fw; \
55MODULE_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
64int 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]);
68void brcmf_fw_nvram_free(void *nvram); 49void brcmf_fw_nvram_free(void *nvram);
50
51enum brcmf_fw_type {
52 BRCMF_FW_TYPE_BINARY,
53 BRCMF_FW_TYPE_NVRAM
54};
55
56struct 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
69struct brcmf_fw_request {
70 u16 domain_nr;
71 u16 bus_nr;
72 u32 n_items;
73 struct brcmf_fw_item items[0];
74};
75
76struct brcmf_fw_name {
77 const char *extension;
78 char *path;
79};
80
81struct brcmf_fw_request *
82brcmf_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 */
74int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, 92int 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);
80int 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
2428void 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
2432bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws) 2435bool 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
21struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); 21struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr);
22void brcmf_fws_detach(struct brcmf_fws_info *fws); 22void brcmf_fws_detach(struct brcmf_fws_info *fws);
23void brcmf_fws_debugfs_create(struct brcmf_pub *drvr);
23bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); 24bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws);
24bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); 25bool brcmf_fws_fc_active(struct brcmf_fws_info *fws);
25void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb); 26void 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
1421static void brcmf_msgbuf_debugfs_create(struct brcmf_pub *drvr)
1422{
1423 brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read);
1424}
1425
1421int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) 1426int 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
1532fail: 1536fail:
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 */
2228int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) 2228int 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
49BRCMF_FW_NVRAM_DEF(43602, "brcmfmac43602-pcie.bin", "brcmfmac43602-pcie.txt"); 49BRCMF_FW_DEF(43602, "brcmfmac43602-pcie");
50BRCMF_FW_NVRAM_DEF(4350, "brcmfmac4350-pcie.bin", "brcmfmac4350-pcie.txt"); 50BRCMF_FW_DEF(4350, "brcmfmac4350-pcie");
51BRCMF_FW_NVRAM_DEF(4350C, "brcmfmac4350c2-pcie.bin", "brcmfmac4350c2-pcie.txt"); 51BRCMF_FW_DEF(4350C, "brcmfmac4350c2-pcie");
52BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-pcie.bin", "brcmfmac4356-pcie.txt"); 52BRCMF_FW_DEF(4356, "brcmfmac4356-pcie");
53BRCMF_FW_NVRAM_DEF(43570, "brcmfmac43570-pcie.bin", "brcmfmac43570-pcie.txt"); 53BRCMF_FW_DEF(43570, "brcmfmac43570-pcie");
54BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-pcie.bin", "brcmfmac4358-pcie.txt"); 54BRCMF_FW_DEF(4358, "brcmfmac4358-pcie");
55BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt"); 55BRCMF_FW_DEF(4359, "brcmfmac4359-pcie");
56BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt"); 56BRCMF_FW_DEF(4365B, "brcmfmac4365b-pcie");
57BRCMF_FW_NVRAM_DEF(4365C, "brcmfmac4365c-pcie.bin", "brcmfmac4365c-pcie.txt"); 57BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie");
58BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt"); 58BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie");
59BRCMF_FW_NVRAM_DEF(4366C, "brcmfmac4366c-pcie.bin", "brcmfmac4366c-pcie.txt"); 59BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
60BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt"); 60BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
61 61
62static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { 62static 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
1353static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev, 1353static
1354 u8 *fw_name) 1354int 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
1372static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { 1373static 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
1654static void brcmf_pcie_setup(struct device *dev, int ret, 1658static 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
1739static struct brcmf_fw_request *
1740brcmf_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
1729static int 1764static int
1730brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1765brcmf_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;
1809fail_bus: 1840fail_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
160static inline void
161brcmf_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
603BRCMF_FW_NVRAM_DEF(43143, "brcmfmac43143-sdio.bin", "brcmfmac43143-sdio.txt"); 603BRCMF_FW_DEF(43143, "brcmfmac43143-sdio");
604BRCMF_FW_NVRAM_DEF(43241B0, "brcmfmac43241b0-sdio.bin", 604BRCMF_FW_DEF(43241B0, "brcmfmac43241b0-sdio");
605 "brcmfmac43241b0-sdio.txt"); 605BRCMF_FW_DEF(43241B4, "brcmfmac43241b4-sdio");
606BRCMF_FW_NVRAM_DEF(43241B4, "brcmfmac43241b4-sdio.bin", 606BRCMF_FW_DEF(43241B5, "brcmfmac43241b5-sdio");
607 "brcmfmac43241b4-sdio.txt"); 607BRCMF_FW_DEF(4329, "brcmfmac4329-sdio");
608BRCMF_FW_NVRAM_DEF(43241B5, "brcmfmac43241b5-sdio.bin", 608BRCMF_FW_DEF(4330, "brcmfmac4330-sdio");
609 "brcmfmac43241b5-sdio.txt"); 609BRCMF_FW_DEF(4334, "brcmfmac4334-sdio");
610BRCMF_FW_NVRAM_DEF(4329, "brcmfmac4329-sdio.bin", "brcmfmac4329-sdio.txt"); 610BRCMF_FW_DEF(43340, "brcmfmac43340-sdio");
611BRCMF_FW_NVRAM_DEF(4330, "brcmfmac4330-sdio.bin", "brcmfmac4330-sdio.txt"); 611BRCMF_FW_DEF(4335, "brcmfmac4335-sdio");
612BRCMF_FW_NVRAM_DEF(4334, "brcmfmac4334-sdio.bin", "brcmfmac4334-sdio.txt"); 612BRCMF_FW_DEF(43362, "brcmfmac43362-sdio");
613BRCMF_FW_NVRAM_DEF(43340, "brcmfmac43340-sdio.bin", "brcmfmac43340-sdio.txt"); 613BRCMF_FW_DEF(4339, "brcmfmac4339-sdio");
614BRCMF_FW_NVRAM_DEF(4335, "brcmfmac4335-sdio.bin", "brcmfmac4335-sdio.txt"); 614BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio");
615BRCMF_FW_NVRAM_DEF(43362, "brcmfmac43362-sdio.bin", "brcmfmac43362-sdio.txt");
616BRCMF_FW_NVRAM_DEF(4339, "brcmfmac4339-sdio.bin", "brcmfmac4339-sdio.txt");
617BRCMF_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 */
619BRCMF_FW_NVRAM_DEF(43430A1, "brcmfmac43430-sdio.bin", "brcmfmac43430-sdio.txt"); 616BRCMF_FW_DEF(43430A1, "brcmfmac43430-sdio");
620BRCMF_FW_NVRAM_DEF(43455, "brcmfmac43455-sdio.bin", "brcmfmac43455-sdio.txt"); 617BRCMF_FW_DEF(43455, "brcmfmac43455-sdio");
621BRCMF_FW_NVRAM_DEF(4354, "brcmfmac4354-sdio.bin", "brcmfmac4354-sdio.txt"); 618BRCMF_FW_DEF(4354, "brcmfmac4354-sdio");
622BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-sdio.bin", "brcmfmac4356-sdio.txt"); 619BRCMF_FW_DEF(4356, "brcmfmac4356-sdio");
623BRCMF_FW_NVRAM_DEF(4373, "brcmfmac4373-sdio.bin", "brcmfmac4373-sdio.txt"); 620BRCMF_FW_DEF(4373, "brcmfmac4373-sdio");
624 621
625static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { 622static 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
646static void pkt_align(struct sk_buff *p, int len, int align) 643static 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
4006static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev, 4003static
4007 u8 *fw_name) 4004int 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
4024static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { 4023static 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
4037static void brcmf_sdio_firmware_callback(struct device *dev, int err, 4039static 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
4160static struct brcmf_fw_request *
4161brcmf_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
4151struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) 4182struct 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
49BRCMF_FW_DEF(43143, "brcmfmac43143.bin"); 49BRCMF_FW_DEF(43143, "brcmfmac43143");
50BRCMF_FW_DEF(43236B, "brcmfmac43236b.bin"); 50BRCMF_FW_DEF(43236B, "brcmfmac43236b");
51BRCMF_FW_DEF(43242A, "brcmfmac43242a.bin"); 51BRCMF_FW_DEF(43242A, "brcmfmac43242a");
52BRCMF_FW_DEF(43569, "brcmfmac43569.bin"); 52BRCMF_FW_DEF(43569, "brcmfmac43569");
53BRCMF_FW_DEF(4373, "brcmfmac4373.bin"); 53BRCMF_FW_DEF(4373, "brcmfmac4373");
54 54
55static struct brcmf_firmware_mapping brcmf_usb_fwnames[] = { 55static 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
1131static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev, 1131static
1132 u8 *fw_name) 1132int 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
1148static const struct brcmf_bus_ops brcmf_usb_bus_ops = { 1151static 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
1158static void brcmf_usb_probe_phase2(struct device *dev, int ret, 1163static 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
1206static struct brcmf_fw_request *
1207brcmf_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
1198static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) 1227static 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 */
111module_param_named(debug, brcm_msg_level, uint, S_IRUGO | S_IWUSR); 111module_param_named(debug, brcm_msg_level, uint, 0644);
112#endif 112#endif
113 113
114static struct ieee80211_channel brcms_2ghz_chantable[] = { 114static 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 */
1568int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) 1568int 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
3541static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL); 3541static DEVICE_ATTR(pci, 0444, show_pci, NULL);
3542 3542
3543static ssize_t show_cfg(struct device *d, struct device_attribute *attr, 3543static 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
3550static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); 3550static DEVICE_ATTR(cfg, 0444, show_cfg, NULL);
3551 3551
3552static ssize_t show_status(struct device *d, struct device_attribute *attr, 3552static 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
3559static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 3559static DEVICE_ATTR(status, 0444, show_status, NULL);
3560 3560
3561static ssize_t show_capability(struct device *d, struct device_attribute *attr, 3561static 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
3568static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL); 3568static 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 }
3571static const struct { 3571static 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
3825static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL); 3825static DEVICE_ATTR(registers, 0444, show_registers, NULL);
3826 3826
3827static ssize_t show_hardware(struct device *d, struct device_attribute *attr, 3827static 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
3866static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL); 3866static DEVICE_ATTR(hardware, 0444, show_hardware, NULL);
3867 3867
3868static ssize_t show_memory(struct device *d, struct device_attribute *attr, 3868static 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
3960static DEVICE_ATTR(memory, S_IWUSR | S_IRUGO, show_memory, store_memory); 3960static DEVICE_ATTR(memory, 0644, show_memory, store_memory);
3961 3961
3962static ssize_t show_ordinals(struct device *d, struct device_attribute *attr, 3962static 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
3996static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL); 3996static DEVICE_ATTR(ordinals, 0444, show_ordinals, NULL);
3997 3997
3998static ssize_t show_stats(struct device *d, struct device_attribute *attr, 3998static 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
4017static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL); 4017static DEVICE_ATTR(stats, 0444, show_stats, NULL);
4018 4018
4019static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) 4019static 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
4115static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL); 4115static DEVICE_ATTR(internals, 0444, show_internals, NULL);
4116 4116
4117static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, 4117static 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
4160static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL); 4160static DEVICE_ATTR(bssinfo, 0444, show_bssinfo, NULL);
4161 4161
4162#ifdef CONFIG_IPW2100_DEBUG 4162#ifdef CONFIG_IPW2100_DEBUG
4163static ssize_t debug_level_show(struct device_driver *d, char *buf) 4163static 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
4219static DEVICE_ATTR(fatal_error, S_IWUSR | S_IRUGO, show_fatal_error, 4219static DEVICE_ATTR(fatal_error, 0644, show_fatal_error, store_fatal_error);
4220 store_fatal_error);
4221 4220
4222static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, 4221static 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
4253static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age); 4252static DEVICE_ATTR(scan_age, 0644, show_scan_age, store_scan_age);
4254 4253
4255static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, 4254static 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
4307static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); 4306static DEVICE_ATTR(rf_kill, 0644, show_rf_kill, store_rf_kill);
4308 4307
4309static struct attribute *ipw2100_sysfs_entries[] = { 4308static 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
1306static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL); 1306static DEVICE_ATTR(event_log, 0444, show_event_log, NULL);
1307 1307
1308static ssize_t show_error(struct device *d, 1308static 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
1354static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error); 1354static DEVICE_ATTR(error, 0644, show_error, clear_error);
1355 1355
1356static ssize_t show_cmd_log(struct device *d, 1356static 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
1381static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL); 1381static DEVICE_ATTR(cmd_log, 0444, show_cmd_log, NULL);
1382 1382
1383#ifdef CONFIG_IPW2200_PROMISCUOUS 1383#ifdef CONFIG_IPW2200_PROMISCUOUS
1384static void ipw_prom_free(struct ipw_priv *priv); 1384static 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
1446static DEVICE_ATTR(rtap_iface, S_IWUSR | S_IRUSR, show_rtap_iface, 1446static DEVICE_ATTR(rtap_iface, 0600, show_rtap_iface, store_rtap_iface);
1447 store_rtap_iface);
1448 1447
1449static ssize_t store_rtap_filter(struct device *d, 1448static 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
1478static DEVICE_ATTR(rtap_filter, S_IWUSR | S_IRUSR, show_rtap_filter, 1477static DEVICE_ATTR(rtap_filter, 0600, show_rtap_filter, store_rtap_filter);
1479 store_rtap_filter);
1480#endif 1478#endif
1481 1479
1482static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, 1480static 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
1523static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age); 1521static DEVICE_ATTR(scan_age, 0644, show_scan_age, store_scan_age);
1524 1522
1525static ssize_t show_led(struct device *d, struct device_attribute *attr, 1523static 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
1556static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led); 1554static DEVICE_ATTR(led, 0644, show_led, store_led);
1557 1555
1558static ssize_t show_status(struct device *d, 1556static 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
1565static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 1563static DEVICE_ATTR(status, 0444, show_status, NULL);
1566 1564
1567static ssize_t show_cfg(struct device *d, struct device_attribute *attr, 1565static 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
1574static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); 1572static DEVICE_ATTR(cfg, 0444, show_cfg, NULL);
1575 1573
1576static ssize_t show_nic_type(struct device *d, 1574static 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
1583static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); 1581static DEVICE_ATTR(nic_type, 0444, show_nic_type, NULL);
1584 1582
1585static ssize_t show_ucode_version(struct device *d, 1583static 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
1597static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL); 1595static DEVICE_ATTR(ucode_version, 0644, show_ucode_version, NULL);
1598 1596
1599static ssize_t show_rtc(struct device *d, struct device_attribute *attr, 1597static 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
1611static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL); 1609static 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
1633static DEVICE_ATTR(eeprom_delay, S_IWUSR | S_IRUGO, 1631static DEVICE_ATTR(eeprom_delay, 0644, show_eeprom_delay, store_eeprom_delay);
1634 show_eeprom_delay, store_eeprom_delay);
1635 1632
1636static ssize_t show_command_event_reg(struct device *d, 1633static 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
1657static DEVICE_ATTR(command_event_reg, S_IWUSR | S_IRUGO, 1654static 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
1660static ssize_t show_mem_gpio_reg(struct device *d, 1657static 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
1681static DEVICE_ATTR(mem_gpio_reg, S_IWUSR | S_IRUGO, 1678static 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
1684static ssize_t show_indirect_dword(struct device *d, 1680static 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
1708static DEVICE_ATTR(indirect_dword, S_IWUSR | S_IRUGO, 1704static DEVICE_ATTR(indirect_dword, 0644,
1709 show_indirect_dword, store_indirect_dword); 1705 show_indirect_dword, store_indirect_dword);
1710 1706
1711static ssize_t show_indirect_byte(struct device *d, 1707static 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
1735static DEVICE_ATTR(indirect_byte, S_IWUSR | S_IRUGO, 1731static DEVICE_ATTR(indirect_byte, 0644,
1736 show_indirect_byte, store_indirect_byte); 1732 show_indirect_byte, store_indirect_byte);
1737 1733
1738static ssize_t show_direct_dword(struct device *d, 1734static 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
1762static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO, 1758static DEVICE_ATTR(direct_dword, 0644, show_direct_dword, store_direct_dword);
1763 show_direct_dword, store_direct_dword);
1764 1759
1765static int rf_kill_active(struct ipw_priv *priv) 1760static 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
1834static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); 1829static DEVICE_ATTR(rf_kill, 0644, show_rf_kill, store_rf_kill);
1835 1830
1836static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr, 1831static 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
1887static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan, 1882static DEVICE_ATTR(speed_scan, 0644, show_speed_scan, store_speed_scan);
1888 store_speed_scan);
1889 1883
1890static ssize_t show_net_stats(struct device *d, struct device_attribute *attr, 1884static 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
1909static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO, 1903static DEVICE_ATTR(net_stats, 0644, show_net_stats, store_net_stats);
1910 show_net_stats, store_net_stats);
1911 1904
1912static ssize_t show_channels(struct device *d, 1905static 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
1956static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); 1949static DEVICE_ATTR(channels, 0400, show_channels, NULL);
1957 1950
1958static void notify_wx_assoc_event(struct ipw_priv *priv) 1951static 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
3125static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, il3945_show_debug_level, 3125static 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
3142static DEVICE_ATTR(temperature, S_IRUGO, il3945_show_temperature, NULL); 3142static DEVICE_ATTR(temperature, 0444, il3945_show_temperature, NULL);
3143 3143
3144static ssize_t 3144static ssize_t
3145il3945_show_tx_power(struct device *d, struct device_attribute *attr, char *buf) 3145il3945_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
3168static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, il3945_show_tx_power, 3168static DEVICE_ATTR(tx_power, 0644, il3945_show_tx_power, il3945_store_tx_power);
3169 il3945_store_tx_power);
3170 3169
3171static ssize_t 3170static ssize_t
3172il3945_show_flags(struct device *d, struct device_attribute *attr, char *buf) 3171il3945_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
3202static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, il3945_show_flags, 3201static DEVICE_ATTR(flags, 0644, il3945_show_flags, il3945_store_flags);
3203 il3945_store_flags);
3204 3202
3205static ssize_t 3203static ssize_t
3206il3945_show_filter_flags(struct device *d, struct device_attribute *attr, 3204il3945_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
3238static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, il3945_show_filter_flags, 3236static DEVICE_ATTR(filter_flags, 0644, il3945_show_filter_flags,
3239 il3945_store_filter_flags); 3237 il3945_store_filter_flags);
3240 3238
3241static ssize_t 3239static 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
3309static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, il3945_show_measurement, 3307static DEVICE_ATTR(measurement, 0600, il3945_show_measurement,
3310 il3945_store_measurement); 3308 il3945_store_measurement);
3311 3309
3312static ssize_t 3310static 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
3333static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, il3945_show_retry_rate, 3331static DEVICE_ATTR(retry_rate, 0600, il3945_show_retry_rate,
3334 il3945_store_retry_rate); 3332 il3945_store_retry_rate);
3335 3333
3336static ssize_t 3334static 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
3343static DEVICE_ATTR(channels, S_IRUSR, il3945_show_channels, NULL); 3341static DEVICE_ATTR(channels, 0400, il3945_show_channels, NULL);
3344 3342
3345static ssize_t 3343static ssize_t
3346il3945_show_antenna(struct device *d, struct device_attribute *attr, char *buf) 3344il3945_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
3380static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, il3945_show_antenna, 3378static DEVICE_ATTR(antenna, 0644, il3945_show_antenna, il3945_store_antenna);
3381 il3945_store_antenna);
3382 3379
3383static ssize_t 3380static ssize_t
3384il3945_show_status(struct device *d, struct device_attribute *attr, char *buf) 3381il3945_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
3392static DEVICE_ATTR(status, S_IRUGO, il3945_show_status, NULL); 3389static DEVICE_ATTR(status, 0444, il3945_show_status, NULL);
3393 3390
3394static ssize_t 3391static ssize_t
3395il3945_dump_error_log(struct device *d, struct device_attribute *attr, 3392il3945_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
3407static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, il3945_dump_error_log); 3404static 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
3944MODULE_FIRMWARE(IL3945_MODULE_FIRMWARE(IL3945_UCODE_API_MAX)); 3941MODULE_FIRMWARE(IL3945_MODULE_FIRMWARE(IL3945_UCODE_API_MAX));
3945 3942
3946module_param_named(antenna, il3945_mod_params.antenna, int, S_IRUGO); 3943module_param_named(antenna, il3945_mod_params.antenna, int, 0444);
3947MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); 3944MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
3948module_param_named(swcrypto, il3945_mod_params.sw_crypto, int, S_IRUGO); 3945module_param_named(swcrypto, il3945_mod_params.sw_crypto, int, 0444);
3949MODULE_PARM_DESC(swcrypto, "using software crypto (default 1 [software])"); 3946MODULE_PARM_DESC(swcrypto, "using software crypto (default 1 [software])");
3950module_param_named(disable_hw_scan, il3945_mod_params.disable_hw_scan, int, 3947module_param_named(disable_hw_scan, il3945_mod_params.disable_hw_scan, int,
3951 S_IRUGO); 3948 0444);
3952MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 1)"); 3949MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 1)");
3953#ifdef CONFIG_IWLEGACY_DEBUG 3950#ifdef CONFIG_IWLEGACY_DEBUG
3954module_param_named(debug, il_debug_level, uint, S_IRUGO | S_IWUSR); 3951module_param_named(debug, il_debug_level, uint, 0644);
3955MODULE_PARM_DESC(debug, "debug output mask"); 3952MODULE_PARM_DESC(debug, "debug output mask");
3956#endif 3953#endif
3957module_param_named(fw_restart, il3945_mod_params.restart_fw, int, S_IRUGO); 3954module_param_named(fw_restart, il3945_mod_params.restart_fw, int, 0444);
3958MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); 3955MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
3959 3956
3960module_exit(il3945_exit); 3957module_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
4594static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, il4965_show_debug_level, 4594static 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
4611static DEVICE_ATTR(temperature, S_IRUGO, il4965_show_temperature, NULL); 4611static DEVICE_ATTR(temperature, 0444, il4965_show_temperature, NULL);
4612 4612
4613static ssize_t 4613static ssize_t
4614il4965_show_tx_power(struct device *d, struct device_attribute *attr, char *buf) 4614il4965_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
4645static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, il4965_show_tx_power, 4645static DEVICE_ATTR(tx_power, 0644, il4965_show_tx_power,
4646 il4965_store_tx_power); 4646 il4965_store_tx_power);
4647 4647
4648static struct attribute *il_sysfs_entries[] = { 4648static struct attribute *il_sysfs_entries[] = {
@@ -6859,18 +6859,17 @@ module_exit(il4965_exit);
6859module_init(il4965_init); 6859module_init(il4965_init);
6860 6860
6861#ifdef CONFIG_IWLEGACY_DEBUG 6861#ifdef CONFIG_IWLEGACY_DEBUG
6862module_param_named(debug, il_debug_level, uint, S_IRUGO | S_IWUSR); 6862module_param_named(debug, il_debug_level, uint, 0644);
6863MODULE_PARM_DESC(debug, "debug output mask"); 6863MODULE_PARM_DESC(debug, "debug output mask");
6864#endif 6864#endif
6865 6865
6866module_param_named(swcrypto, il4965_mod_params.sw_crypto, int, S_IRUGO); 6866module_param_named(swcrypto, il4965_mod_params.sw_crypto, int, 0444);
6867MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); 6867MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
6868module_param_named(queues_num, il4965_mod_params.num_of_queues, int, S_IRUGO); 6868module_param_named(queues_num, il4965_mod_params.num_of_queues, int, 0444);
6869MODULE_PARM_DESC(queues_num, "number of hw queues."); 6869MODULE_PARM_DESC(queues_num, "number of hw queues.");
6870module_param_named(11n_disable, il4965_mod_params.disable_11n, int, S_IRUGO); 6870module_param_named(11n_disable, il4965_mod_params.disable_11n, int, 0444);
6871MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); 6871MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
6872module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K, int, 6872module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K, int, 0444);
6873 S_IRUGO);
6874MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0 [disabled])"); 6873MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0 [disabled])");
6875module_param_named(fw_restart, il4965_mod_params.restart_fw, int, S_IRUGO); 6874module_param_named(fw_restart, il4965_mod_params.restart_fw, int, 0444);
6876MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); 6875MODULE_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 */
437static int led_mode; 437static int led_mode;
438module_param(led_mode, int, S_IRUGO); 438module_param(led_mode, int, 0444);
439MODULE_PARM_DESC(led_mode, 439MODULE_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 */
3374static bool bt_coex_active = true; 3374static bool bt_coex_active = true;
3375module_param(bt_coex_active, bool, S_IRUGO); 3375module_param(bt_coex_active, bool, 0444);
3376MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); 3376MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
3377 3377
3378u32 il_debug_level; 3378u32 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
272const 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
287const 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
302const 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
317const 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
268MODULE_FIRMWARE(IWL9000A_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); 332MODULE_FIRMWARE(IWL9000A_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
269MODULE_FIRMWARE(IWL9000B_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); 333MODULE_FIRMWARE(IWL9000B_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
270MODULE_FIRMWARE(IWL9000RFB_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); 334MODULE_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 */
321enum 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 */
598enum 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 */
653struct 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
160void 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
160static ssize_t iwl_dbgfs_timestamp_marker_write(struct iwl_fw_runtime *fwrt, 174static 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;
192err: 198err:
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
92void iwl_fw_trigger_timestamp(struct iwl_fw_runtime *fwrt, u32 delay);
93
92#else 94#else
93static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, 95static 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
103static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {} 105static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
104 106
107static 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 */
627enum 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 */
655struct iwl_fw_dbg_trigger_tlv { 669struct 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;
477extern const struct iwl_cfg iwl9461_2ac_cfg_soc; 478extern const struct iwl_cfg iwl9461_2ac_cfg_soc;
478extern const struct iwl_cfg iwl9462_2ac_cfg_soc; 479extern const struct iwl_cfg iwl9462_2ac_cfg_soc;
479extern const struct iwl_cfg iwl9560_2ac_cfg_soc; 480extern const struct iwl_cfg iwl9560_2ac_cfg_soc;
481extern const struct iwl_cfg iwl9460_2ac_cfg_shared_clk;
482extern const struct iwl_cfg iwl9461_2ac_cfg_shared_clk;
483extern const struct iwl_cfg iwl9462_2ac_cfg_shared_clk;
484extern const struct iwl_cfg iwl9560_2ac_cfg_shared_clk;
480extern const struct iwl_cfg iwl22000_2ac_cfg_hr; 485extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
481extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; 486extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
482extern const struct iwl_cfg iwl22000_2ac_cfg_jf; 487extern 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)
1768module_exit(iwl_drv_exit); 1768module_exit(iwl_drv_exit);
1769 1769
1770#ifdef CONFIG_IWLWIFI_DEBUG 1770#ifdef CONFIG_IWLWIFI_DEBUG
1771module_param_named(debug, iwlwifi_mod_params.debug_level, uint, 1771module_param_named(debug, iwlwifi_mod_params.debug_level, uint, 0644);
1772 S_IRUGO | S_IWUSR);
1773MODULE_PARM_DESC(debug, "debug output mask"); 1772MODULE_PARM_DESC(debug, "debug output mask");
1774#endif 1773#endif
1775 1774
1776module_param_named(swcrypto, iwlwifi_mod_params.swcrypto, int, S_IRUGO); 1775module_param_named(swcrypto, iwlwifi_mod_params.swcrypto, int, 0444);
1777MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); 1776MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
1778module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); 1777module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, 0444);
1779MODULE_PARM_DESC(11n_disable, 1778MODULE_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");
1781module_param_named(amsdu_size, iwlwifi_mod_params.amsdu_size, 1780module_param_named(amsdu_size, iwlwifi_mod_params.amsdu_size, int, 0444);
1782 int, S_IRUGO);
1783MODULE_PARM_DESC(amsdu_size, 1781MODULE_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)");
1785module_param_named(fw_restart, iwlwifi_mod_params.fw_restart, bool, S_IRUGO); 1783module_param_named(fw_restart, iwlwifi_mod_params.fw_restart, bool, 0444);
1786MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)"); 1784MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)");
1787 1785
1788module_param_named(antenna_coupling, iwlwifi_mod_params.antenna_coupling, 1786module_param_named(antenna_coupling, iwlwifi_mod_params.antenna_coupling,
1789 int, S_IRUGO); 1787 int, 0444);
1790MODULE_PARM_DESC(antenna_coupling, 1788MODULE_PARM_DESC(antenna_coupling,
1791 "specify antenna coupling in dB (default: 0 dB)"); 1789 "specify antenna coupling in dB (default: 0 dB)");
1792 1790
1793module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO); 1791module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, 0444);
1794MODULE_PARM_DESC(nvm_file, "NVM file name"); 1792MODULE_PARM_DESC(nvm_file, "NVM file name");
1795 1793
1796module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable, 1794module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable, bool, 0444);
1797 bool, S_IRUGO);
1798MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)"); 1795MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)");
1799 1796
1800module_param_named(lar_disable, iwlwifi_mod_params.lar_disable, 1797module_param_named(lar_disable, iwlwifi_mod_params.lar_disable, bool, 0444);
1801 bool, S_IRUGO);
1802MODULE_PARM_DESC(lar_disable, "disable LAR functionality (default: N)"); 1798MODULE_PARM_DESC(lar_disable, "disable LAR functionality (default: N)");
1803 1799
1804module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, 1800module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, uint, 0644);
1805 uint, S_IRUGO | S_IWUSR);
1806MODULE_PARM_DESC(uapsd_disable, 1801MODULE_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 */
1825module_param_named(bt_coex_active, iwlwifi_mod_params.bt_coex_active, 1820module_param_named(bt_coex_active, iwlwifi_mod_params.bt_coex_active,
1826 bool, S_IRUGO); 1821 bool, 0444);
1827MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)"); 1822MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)");
1828 1823
1829module_param_named(led_mode, iwlwifi_mod_params.led_mode, int, S_IRUGO); 1824module_param_named(led_mode, iwlwifi_mod_params.led_mode, int, 0444);
1830MODULE_PARM_DESC(led_mode, "0=system default, " 1825MODULE_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
1833module_param_named(power_save, iwlwifi_mod_params.power_save, 1828module_param_named(power_save, iwlwifi_mod_params.power_save, bool, 0444);
1834 bool, S_IRUGO);
1835MODULE_PARM_DESC(power_save, 1829MODULE_PARM_DESC(power_save,
1836 "enable WiFi power management (default: disable)"); 1830 "enable WiFi power management (default: disable)");
1837 1831
1838module_param_named(power_level, iwlwifi_mod_params.power_level, 1832module_param_named(power_level, iwlwifi_mod_params.power_level, int, 0444);
1839 int, S_IRUGO);
1840MODULE_PARM_DESC(power_level, 1833MODULE_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
1843module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, S_IRUGO); 1836module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, 0444);
1844MODULE_PARM_DESC(fw_monitor, 1837MODULE_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
1847module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_timeout, 1840module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_timeout, uint, 0444);
1848 uint, S_IRUGO);
1849MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)"); 1841MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)");
1850 1842
1851module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool, 1843module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool, 0444);
1852 S_IRUGO);
1853MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities (default: false)"); 1844MODULE_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;
1920err: 1920err:
@@ -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*/
308enum 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
1169static 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
1175static 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
1155static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm) 1181static 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 */
1743int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1769int 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? */
1746bool iwl_mvm_low_latency(struct iwl_mvm *mvm); 1773bool 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
1790static inline
1791void 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
107module_param_named(init_dbg, iwlmvm_mod_params.init_dbg, bool, S_IRUGO); 107module_param_named(init_dbg, iwlmvm_mod_params.init_dbg, bool, 0444);
108MODULE_PARM_DESC(init_dbg, 108MODULE_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");
110module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO); 110module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, 0444);
111MODULE_PARM_DESC(power_scheme, 111MODULE_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");
113module_param_named(tfd_q_hang_detect, iwlmvm_mod_params.tfd_q_hang_detect, 113module_param_named(tfd_q_hang_detect, iwlmvm_mod_params.tfd_q_hang_detect,
114 bool, S_IRUGO); 114 bool, 0444);
115MODULE_PARM_DESC(tfd_q_hang_detect, 115MODULE_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
291static void iwl_mvm_binding_iterator(void *_data, u8 *mac, 302static 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 }
256out:
257 rcu_read_unlock();
254} 258}
255 259
256void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 260void 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;
4026err: 4026err:
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
834static 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
834void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, 844void 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
89struct iwl_mvm_scan_timing_params { 101struct 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
161static inline struct iwl_scan_umac_chan_param *
162iwl_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
146static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm) 178static 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
2697static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm, 2682static 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
691static int
692iwl_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
690static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, 758static 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 */
814segment: 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 */
866static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, 874static 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
1029int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1036int 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
2627err: 2627err:
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
29static bool modparam_nohwcrypt; 29static bool modparam_nohwcrypt;
30module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 30module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
31MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 31MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
32MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); 32MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
33MODULE_DESCRIPTION("Softmac Prism54 common code"); 33MODULE_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 */
39static bool modparam_nohwcrypt; 39static bool modparam_nohwcrypt;
40module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 40module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
41MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 41MODULE_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 */
51static bool modparam_nohwcrypt = false; 51static bool modparam_nohwcrypt = false;
52module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 52module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
53MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 53MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
54 54
55static bool rt2800pci_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) 55static 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. */
43static bool modparam_nohwcrypt; 43static bool modparam_nohwcrypt;
44module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 44module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
45MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 45MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
46 46
47static bool rt2800soc_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) 47static 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 */
45static bool modparam_nohwcrypt; 45static bool modparam_nohwcrypt;
46module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 46module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
47MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 47MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
48 48
49static bool rt2800usb_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) 49static 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
612static struct dentry *rt2x00debug_create_file_chipset(const char *name, 612static 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
653void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) 653void 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 */
42static bool modparam_nohwcrypt = false; 42static bool modparam_nohwcrypt = false;
43module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 43module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
44MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 44MODULE_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 */
40static bool modparam_nohwcrypt; 40static bool modparam_nohwcrypt;
41module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 41module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
42MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 42MODULE_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
1439static
1439void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, 1440void 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
836void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist, 836static 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
429bool 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
462static void btc8821a1ant_update_bt_link_info(struct btc_coexist *btcoexist) 429static 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
362bool btc8821a2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) 362static 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
1520void btc8821a2ant_action_wifi_link_process(struct btc_coexist *btcoexist) 1520static 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
366static 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
376static 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
366static void halbtc_leave_low_power(struct btc_coexist *btcoexist) 382static 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
1147static u32 halbtc_get_bt_reg(void *btc_context, u8 reg_type, u32 offset)
1148{
1149 return 0;
1150}
1151
1104static bool halbtc_under_ips(struct btc_coexist *btcoexist) 1152static 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
1170static
1171u32 halbtc_get_phydm_version(void *btc_context)
1172{
1173 return 0;
1174}
1175
1176static
1177void halbtc_phydm_modify_ra_pcr_threshold(void *btc_context,
1178 u8 ra_offset_direction,
1179 u8 ra_threshold_offset)
1180{
1181}
1182
1183static
1184u32 halbtc_phydm_query_phy_counter(void *btc_context, enum dm_info_query dm_id)
1185{
1186 return 0;
1187}
1188
1122static u8 halbtc_get_ant_det_val_from_bt(void *btc_context) 1189static 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
1548void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action) 1620void 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
159enum btc_dbg_opcode { 162enum btc_dbg_opcode {
@@ -204,6 +207,7 @@ enum btc_wifi_traffic_dir {
204enum btc_wifi_pnp { 207enum 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 {
383enum btc_notify_type_scan { 392enum 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 {
397enum btc_notify_type_associate { 407enum 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
450enum {
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
544enum {
545 BTC_MULTIPORT_SCC,
546 BTC_MULTIPORT_MCC_2CHANNEL,
547 BTC_MULTIPORT_MCC_2BAND,
548 BTC_MULTIPORT_MAX
549};
550
438struct btc_bt_info { 551struct 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
530enum btc_antenna_pos { 645enum 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
561enum hw_descs { 562enum 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
981enum 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
980struct octet_string { 1013struct 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
14config RSI_91X 14config 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
45config RSI_COEX 46config 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;
646out_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; 711err:
712 kfree(data);
713 return status;
701} 714}
702 715
703static int rsi_sdio_master_reg_write(struct rsi_hw *adapter, 716static 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,
994fail_dev_init: 1012fail_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);
999fail_kill_thread: 1016fail_claim_irq:
1000 rsi_kill_thread(&sdev->rx_thread); 1017 rsi_kill_thread(&sdev->rx_thread);
1018fail_kill_thread:
1019 sdio_claim_host(pfunction);
1020 sdio_disable_func(pfunction);
1021 sdio_release_host(pfunction);
1001fail_free_adapter: 1022fail_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 */
48static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00}; 48static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00};
49module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, S_IRUGO); 49module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, 0444);
50MODULE_PARM_DESC(macaddr, "Override platform_data MAC address"); 50MODULE_PARM_DESC(macaddr, "Override platform_data MAC address");
51 51
52static char *cw1200_sdd_path; 52static 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
2094module_platform_driver(wl18xx_driver); 2094module_platform_driver(wl18xx_driver);
2095module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); 2095module_param_named(ht_mode, ht_mode_param, charp, 0400);
2096MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20"); 2096MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20");
2097 2097
2098module_param_named(board_type, board_type_param, charp, S_IRUSR); 2098module_param_named(board_type, board_type_param, charp, 0400);
2099MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or " 2099MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or "
2100 "dvp"); 2100 "dvp");
2101 2101
2102module_param_named(checksum, checksum_param, bool, S_IRUSR); 2102module_param_named(checksum, checksum_param, bool, 0400);
2103MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)"); 2103MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)");
2104 2104
2105module_param_named(dc2dc, dc2dc_param, int, S_IRUSR); 2105module_param_named(dc2dc, dc2dc_param, int, 0400);
2106MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)"); 2106MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)");
2107 2107
2108module_param_named(n_antennas_2, n_antennas_2_param, int, S_IRUSR); 2108module_param_named(n_antennas_2, n_antennas_2_param, int, 0400);
2109MODULE_PARM_DESC(n_antennas_2, 2109MODULE_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
2112module_param_named(n_antennas_5, n_antennas_5_param, int, S_IRUSR); 2112module_param_named(n_antennas_5, n_antennas_5_param, int, 0400);
2113MODULE_PARM_DESC(n_antennas_5, 2113MODULE_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
2116module_param_named(low_band_component, low_band_component_param, int, 2116module_param_named(low_band_component, low_band_component_param, int, 0400);
2117 S_IRUSR);
2118MODULE_PARM_DESC(low_band_component, "Low band component: u8 " 2117MODULE_PARM_DESC(low_band_component, "Low band component: u8 "
2119 "(default is 0x01)"); 2118 "(default is 0x01)");
2120 2119
2121module_param_named(low_band_component_type, low_band_component_type_param, 2120module_param_named(low_band_component_type, low_band_component_type_param,
2122 int, S_IRUSR); 2121 int, 0400);
2123MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 " 2122MODULE_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
2126module_param_named(high_band_component, high_band_component_param, int, 2125module_param_named(high_band_component, high_band_component_param, int, 0400);
2127 S_IRUSR);
2128MODULE_PARM_DESC(high_band_component, "High band component: u8, " 2126MODULE_PARM_DESC(high_band_component, "High band component: u8, "
2129 "(default is 0x01)"); 2127 "(default is 0x01)");
2130 2128
2131module_param_named(high_band_component_type, high_band_component_type_param, 2129module_param_named(high_band_component_type, high_band_component_type_param,
2132 int, S_IRUSR); 2130 int, 0400);
2133MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 " 2131MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 "
2134 "(default is 0x09)"); 2132 "(default is 0x09)");
2135 2133
2136module_param_named(pwr_limit_reference_11_abg, 2134module_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);
2138MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 " 2136MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 "
2139 "(default is 0xc8)"); 2137 "(default is 0xc8)");
2140 2138
2141module_param_named(num_rx_desc, 2139module_param_named(num_rx_desc, num_rx_desc_param, int, 0400);
2142 num_rx_desc_param, int, S_IRUSR);
2143MODULE_PARM_DESC(num_rx_desc_param, 2140MODULE_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
6631u32 wl12xx_debug_level = DEBUG_NONE; 6631u32 wl12xx_debug_level = DEBUG_NONE;
6632EXPORT_SYMBOL_GPL(wl12xx_debug_level); 6632EXPORT_SYMBOL_GPL(wl12xx_debug_level);
6633module_param_named(debug_level, wl12xx_debug_level, uint, S_IRUSR | S_IWUSR); 6633module_param_named(debug_level, wl12xx_debug_level, uint, 0600);
6634MODULE_PARM_DESC(debug_level, "wl12xx debugging level"); 6634MODULE_PARM_DESC(debug_level, "wl12xx debugging level");
6635 6635
6636module_param_named(fwlog, fwlog_param, charp, 0); 6636module_param_named(fwlog, fwlog_param, charp, 0);
6637MODULE_PARM_DESC(fwlog, 6637MODULE_PARM_DESC(fwlog,
6638 "FW logger options: continuous, dbgpins or disable"); 6638 "FW logger options: continuous, dbgpins or disable");
6639 6639
6640module_param(fwlog_mem_blocks, int, S_IRUSR | S_IWUSR); 6640module_param(fwlog_mem_blocks, int, 0600);
6641MODULE_PARM_DESC(fwlog_mem_blocks, "fwlog mem_blocks"); 6641MODULE_PARM_DESC(fwlog_mem_blocks, "fwlog mem_blocks");
6642 6642
6643module_param(bug_on_recovery, int, S_IRUSR | S_IWUSR); 6643module_param(bug_on_recovery, int, 0600);
6644MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); 6644MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery");
6645 6645
6646module_param(no_recovery, int, S_IRUSR | S_IWUSR); 6646module_param(no_recovery, int, 0600);
6647MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck."); 6647MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck.");
6648 6648
6649MODULE_LICENSE("GPL"); 6649MODULE_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)
469module_init(wl1271_init); 469module_init(wl1271_init);
470module_exit(wl1271_exit); 470module_exit(wl1271_exit);
471 471
472module_param(dump, bool, S_IRUSR | S_IWUSR); 472module_param(dump, bool, 0600);
473MODULE_PARM_DESC(dump, "Enable sdio read/write dumps."); 473MODULE_PARM_DESC(dump, "Enable sdio read/write dumps.");
474 474
475MODULE_LICENSE("GPL"); 475MODULE_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
83static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR, 83static 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
106static DEVICE_ATTR(hw_pg_ver, S_IRUGO, 106static DEVICE_ATTR(hw_pg_ver, 0444, wl1271_sysfs_show_hw_pg_ver, NULL);
107 wl1271_sysfs_show_hw_pg_ver, NULL);
108 107
109static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj, 108static 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
141static const struct bin_attribute fwlog_attr = { 140static 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