aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/bcma/Kconfig10
-rw-r--r--drivers/bcma/main.c2
-rw-r--r--drivers/bcma/scan.c28
-rw-r--r--drivers/net/ethernet/broadcom/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ath.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/bmi.c12
-rw-r--r--drivers/net/wireless/ath/ath10k/bmi.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c321
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h50
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c87
-rw-r--r--drivers/net/wireless/ath/ath10k/hif.h49
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.c61
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.h8
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.c27
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h3
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c3
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c12
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c409
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c304
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h4
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c40
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h19
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig10
-rw-r--r--drivers/net/wireless/ath/ath9k/antenna.c672
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c60
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c177
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h29
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c159
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h29
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c96
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c32
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c90
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c36
-rw-r--r--drivers/net/wireless/ath/wil6210/Makefile3
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/trace.h22
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c160
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h20
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h27
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c20
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c4
-rw-r--r--drivers/net/wireless/cw1200/wsm.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c4
-rw-r--r--drivers/net/wireless/iwlegacy/3945-rs.c1
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c31
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c18
-rw-r--r--drivers/net/wireless/iwlegacy/4965-rs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig17
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/debugfs.c15
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c172
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c62
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rxon.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c105
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c67
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c162
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h71
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c66
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c116
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h49
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h143
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c55
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c40
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h83
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c56
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c198
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power_legacy.c319
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c16
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c78
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c32
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c23
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h1
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c95
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c5
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c10
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c4
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c28
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c42
-rw-r--r--drivers/net/wireless/mwifiex/decl.h3
-rw-r--r--drivers/net/wireless/mwifiex/fw.h44
-rw-r--r--drivers/net/wireless/mwifiex/ie.c2
-rw-r--r--drivers/net/wireless/mwifiex/init.c14
-rw-r--r--drivers/net/wireless/mwifiex/join.c1
-rw-r--r--drivers/net/wireless/mwifiex/main.c96
-rw-r--r--drivers/net/wireless/mwifiex/main.h8
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c39
-rw-r--r--drivers/net/wireless/mwifiex/scan.c63
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c213
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c5
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c10
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c11
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c130
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c70
-rw-r--r--drivers/net/wireless/mwifiex/usb.c8
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c16
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig6
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h274
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c1524
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rc.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.h3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c10
-rw-r--r--drivers/ssb/Kconfig2
-rw-r--r--drivers/ssb/driver_chipcommon_sflash.c8
-rw-r--r--include/linux/bcma/bcma.h17
-rw-r--r--include/net/cfg80211.h164
-rw-r--r--include/net/ieee80211_radiotap.h4
-rw-r--r--include/net/mac80211.h30
-rw-r--r--include/uapi/linux/nl80211.h153
-rw-r--r--net/mac80211/cfg.c45
-rw-r--r--net/mac80211/ht.c53
-rw-r--r--net/mac80211/ibss.c154
-rw-r--r--net/mac80211/ieee80211_i.h49
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/main.c15
-rw-r--r--net/mac80211/mesh.c7
-rw-r--r--net/mac80211/mesh_plink.c2
-rw-r--r--net/mac80211/mlme.c98
-rw-r--r--net/mac80211/rate.c46
-rw-r--r--net/mac80211/rate.h22
-rw-r--r--net/mac80211/rc80211_minstrel.c33
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c15
-rw-r--r--net/mac80211/rc80211_pid_algo.c1
-rw-r--r--net/mac80211/rx.c97
-rw-r--r--net/mac80211/scan.c72
-rw-r--r--net/mac80211/status.c18
-rw-r--r--net/mac80211/tx.c29
-rw-r--r--net/mac80211/util.c216
-rw-r--r--net/wireless/core.c9
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/mesh.c5
-rw-r--r--net/wireless/nl80211.c358
-rw-r--r--net/wireless/nl80211.h2
-rw-r--r--net/wireless/scan.c31
-rw-r--r--net/wireless/trace.h12
-rw-r--r--net/wireless/util.c14
173 files changed, 7148 insertions, 2786 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 6447bec7f33f..1ea2d043bf58 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4362,7 +4362,7 @@ F: drivers/net/wireless/iwlegacy/
4362 4362
4363INTEL WIRELESS WIFI LINK (iwlwifi) 4363INTEL WIRELESS WIFI LINK (iwlwifi)
4364M: Johannes Berg <johannes.berg@intel.com> 4364M: Johannes Berg <johannes.berg@intel.com>
4365M: Wey-Yi Guy <wey-yi.w.guy@intel.com> 4365M: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
4366M: Intel Linux Wireless <ilw@linux.intel.com> 4366M: Intel Linux Wireless <ilw@linux.intel.com>
4367L: linux-wireless@vger.kernel.org 4367L: linux-wireless@vger.kernel.org
4368W: http://intellinuxwireless.org 4368W: http://intellinuxwireless.org
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index 380a2003231e..7c081b38ef3e 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -35,8 +35,14 @@ config BCMA_DRIVER_PCI_HOSTMODE
35 PCI core hostmode operation (external PCI bus). 35 PCI core hostmode operation (external PCI bus).
36 36
37config BCMA_HOST_SOC 37config BCMA_HOST_SOC
38 bool 38 bool "Support for BCMA in a SoC"
39 depends on BCMA_DRIVER_MIPS 39 depends on BCMA
40 help
41 Host interface for a Broadcom AIX bus directly mapped into
42 the memory. This only works with the Broadcom SoCs from the
43 BCM47XX line.
44
45 If unsure, say N
40 46
41config BCMA_DRIVER_MIPS 47config BCMA_DRIVER_MIPS
42 bool "BCMA Broadcom MIPS core driver" 48 bool "BCMA Broadcom MIPS core driver"
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 0067422ec17d..90ee350442a9 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -237,7 +237,7 @@ int bcma_bus_register(struct bcma_bus *bus)
237 err = bcma_bus_scan(bus); 237 err = bcma_bus_scan(bus);
238 if (err) { 238 if (err) {
239 bcma_err(bus, "Failed to scan: %d\n", err); 239 bcma_err(bus, "Failed to scan: %d\n", err);
240 return -1; 240 return err;
241 } 241 }
242 242
243 /* Early init CC core */ 243 /* Early init CC core */
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 8bffa5c9818c..cd6b20fce680 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -32,6 +32,18 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = {
32 { BCMA_CORE_4706_CHIPCOMMON, "BCM4706 ChipCommon" }, 32 { BCMA_CORE_4706_CHIPCOMMON, "BCM4706 ChipCommon" },
33 { BCMA_CORE_4706_SOC_RAM, "BCM4706 SOC RAM" }, 33 { BCMA_CORE_4706_SOC_RAM, "BCM4706 SOC RAM" },
34 { BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" }, 34 { BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" },
35 { BCMA_CORE_PCIEG2, "PCIe Gen 2" },
36 { BCMA_CORE_DMA, "DMA" },
37 { BCMA_CORE_SDIO3, "SDIO3" },
38 { BCMA_CORE_USB20, "USB 2.0" },
39 { BCMA_CORE_USB30, "USB 3.0" },
40 { BCMA_CORE_A9JTAG, "ARM Cortex A9 JTAG" },
41 { BCMA_CORE_DDR23, "Denali DDR2/DDR3 memory controller" },
42 { BCMA_CORE_ROM, "ROM" },
43 { BCMA_CORE_NAND, "NAND flash controller" },
44 { BCMA_CORE_QSPI, "SPI flash controller" },
45 { BCMA_CORE_CHIPCOMMON_B, "Chipcommon B" },
46 { BCMA_CORE_ARMCA9, "ARM Cortex A9 core (ihost)" },
35 { BCMA_CORE_AMEMC, "AMEMC (DDR)" }, 47 { BCMA_CORE_AMEMC, "AMEMC (DDR)" },
36 { BCMA_CORE_ALTA, "ALTA (I2S)" }, 48 { BCMA_CORE_ALTA, "ALTA (I2S)" },
37 { BCMA_CORE_INVALID, "Invalid" }, 49 { BCMA_CORE_INVALID, "Invalid" },
@@ -201,7 +213,7 @@ static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 __iomem **eromptr)
201 return ent; 213 return ent;
202} 214}
203 215
204static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr, 216static u32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
205 u32 type, u8 port) 217 u32 type, u8 port)
206{ 218{
207 u32 addrl, addrh, sizel, sizeh = 0; 219 u32 addrl, addrh, sizel, sizeh = 0;
@@ -213,7 +225,7 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
213 ((ent & SCAN_ADDR_TYPE) != type) || 225 ((ent & SCAN_ADDR_TYPE) != type) ||
214 (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) { 226 (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
215 bcma_erom_push_ent(eromptr); 227 bcma_erom_push_ent(eromptr);
216 return -EINVAL; 228 return (u32)-EINVAL;
217 } 229 }
218 230
219 addrl = ent & SCAN_ADDR_ADDR; 231 addrl = ent & SCAN_ADDR_ADDR;
@@ -261,7 +273,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
261 struct bcma_device_id *match, int core_num, 273 struct bcma_device_id *match, int core_num,
262 struct bcma_device *core) 274 struct bcma_device *core)
263{ 275{
264 s32 tmp; 276 u32 tmp;
265 u8 i, j; 277 u8 i, j;
266 s32 cia, cib; 278 s32 cia, cib;
267 u8 ports[2], wrappers[2]; 279 u8 ports[2], wrappers[2];
@@ -339,11 +351,11 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
339 * the main register space for the core 351 * the main register space for the core
340 */ 352 */
341 tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0); 353 tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
342 if (tmp <= 0) { 354 if (tmp == 0 || IS_ERR_VALUE(tmp)) {
343 /* Try again to see if it is a bridge */ 355 /* Try again to see if it is a bridge */
344 tmp = bcma_erom_get_addr_desc(bus, eromptr, 356 tmp = bcma_erom_get_addr_desc(bus, eromptr,
345 SCAN_ADDR_TYPE_BRIDGE, 0); 357 SCAN_ADDR_TYPE_BRIDGE, 0);
346 if (tmp <= 0) { 358 if (tmp == 0 || IS_ERR_VALUE(tmp)) {
347 return -EILSEQ; 359 return -EILSEQ;
348 } else { 360 } else {
349 bcma_info(bus, "Bridge found\n"); 361 bcma_info(bus, "Bridge found\n");
@@ -357,7 +369,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
357 for (j = 0; ; j++) { 369 for (j = 0; ; j++) {
358 tmp = bcma_erom_get_addr_desc(bus, eromptr, 370 tmp = bcma_erom_get_addr_desc(bus, eromptr,
359 SCAN_ADDR_TYPE_SLAVE, i); 371 SCAN_ADDR_TYPE_SLAVE, i);
360 if (tmp < 0) { 372 if (IS_ERR_VALUE(tmp)) {
361 /* no more entries for port _i_ */ 373 /* no more entries for port _i_ */
362 /* pr_debug("erom: slave port %d " 374 /* pr_debug("erom: slave port %d "
363 * "has %d descriptors\n", i, j); */ 375 * "has %d descriptors\n", i, j); */
@@ -374,7 +386,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
374 for (j = 0; ; j++) { 386 for (j = 0; ; j++) {
375 tmp = bcma_erom_get_addr_desc(bus, eromptr, 387 tmp = bcma_erom_get_addr_desc(bus, eromptr,
376 SCAN_ADDR_TYPE_MWRAP, i); 388 SCAN_ADDR_TYPE_MWRAP, i);
377 if (tmp < 0) { 389 if (IS_ERR_VALUE(tmp)) {
378 /* no more entries for port _i_ */ 390 /* no more entries for port _i_ */
379 /* pr_debug("erom: master wrapper %d " 391 /* pr_debug("erom: master wrapper %d "
380 * "has %d descriptors\n", i, j); */ 392 * "has %d descriptors\n", i, j); */
@@ -392,7 +404,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
392 for (j = 0; ; j++) { 404 for (j = 0; ; j++) {
393 tmp = bcma_erom_get_addr_desc(bus, eromptr, 405 tmp = bcma_erom_get_addr_desc(bus, eromptr,
394 SCAN_ADDR_TYPE_SWRAP, i + hack); 406 SCAN_ADDR_TYPE_SWRAP, i + hack);
395 if (tmp < 0) { 407 if (IS_ERR_VALUE(tmp)) {
396 /* no more entries for port _i_ */ 408 /* no more entries for port _i_ */
397 /* pr_debug("erom: master wrapper %d " 409 /* pr_debug("erom: master wrapper %d "
398 * has %d descriptors\n", i, j); */ 410 * has %d descriptors\n", i, j); */
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
index 1d680baf43d6..7b839bf5bb7a 100644
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -130,7 +130,7 @@ config BNX2X_SRIOV
130 130
131config BGMAC 131config BGMAC
132 tristate "BCMA bus GBit core support" 132 tristate "BCMA bus GBit core support"
133 depends on BCMA_HOST_SOC && HAS_DMA 133 depends on BCMA_HOST_SOC && HAS_DMA && BCM47XX
134 ---help--- 134 ---help---
135 This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus. 135 This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus.
136 They can be found on BCM47xx SoCs and provide gigabit ethernet. 136 They can be found on BCM47xx SoCs and provide gigabit ethernet.
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index daeafeff186b..e0ba7cd14252 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -159,7 +159,7 @@ struct ath_common {
159 159
160 bool btcoex_enabled; 160 bool btcoex_enabled;
161 bool disable_ani; 161 bool disable_ani;
162 bool antenna_diversity; 162 bool bt_ant_diversity;
163}; 163};
164 164
165struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, 165struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c
index 1a2ef51b69d9..744da6d1c405 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.c
+++ b/drivers/net/wireless/ath/ath10k/bmi.c
@@ -20,6 +20,12 @@
20#include "debug.h" 20#include "debug.h"
21#include "htc.h" 21#include "htc.h"
22 22
23void ath10k_bmi_start(struct ath10k *ar)
24{
25 ath10k_dbg(ATH10K_DBG_CORE, "BMI started\n");
26 ar->bmi.done_sent = false;
27}
28
23int ath10k_bmi_done(struct ath10k *ar) 29int ath10k_bmi_done(struct ath10k *ar)
24{ 30{
25 struct bmi_cmd cmd; 31 struct bmi_cmd cmd;
@@ -105,7 +111,8 @@ int ath10k_bmi_read_memory(struct ath10k *ar,
105 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, 111 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen,
106 &resp, &rxlen); 112 &resp, &rxlen);
107 if (ret) { 113 if (ret) {
108 ath10k_warn("unable to read from the device\n"); 114 ath10k_warn("unable to read from the device (%d)\n",
115 ret);
109 return ret; 116 return ret;
110 } 117 }
111 118
@@ -149,7 +156,8 @@ int ath10k_bmi_write_memory(struct ath10k *ar,
149 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen, 156 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen,
150 NULL, NULL); 157 NULL, NULL);
151 if (ret) { 158 if (ret) {
152 ath10k_warn("unable to write to the device\n"); 159 ath10k_warn("unable to write to the device (%d)\n",
160 ret);
153 return ret; 161 return ret;
154 } 162 }
155 163
diff --git a/drivers/net/wireless/ath/ath10k/bmi.h b/drivers/net/wireless/ath/ath10k/bmi.h
index 32c56aa33a5e..8d81ce1cec21 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.h
+++ b/drivers/net/wireless/ath/ath10k/bmi.h
@@ -184,6 +184,7 @@ struct bmi_target_info {
184#define BMI_CE_NUM_TO_TARG 0 184#define BMI_CE_NUM_TO_TARG 0
185#define BMI_CE_NUM_TO_HOST 1 185#define BMI_CE_NUM_TO_HOST 1
186 186
187void ath10k_bmi_start(struct ath10k *ar);
187int ath10k_bmi_done(struct ath10k *ar); 188int ath10k_bmi_done(struct ath10k *ar);
188int ath10k_bmi_get_target_info(struct ath10k *ar, 189int ath10k_bmi_get_target_info(struct ath10k *ar,
189 struct bmi_target_info *target_info); 190 struct bmi_target_info *target_info);
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 61a8ac70d3ca..b40792900bd5 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -79,7 +79,7 @@ static inline void ath10k_ce_src_ring_write_index_set(struct ath10k *ar,
79 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 79 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
80 void __iomem *indicator_addr; 80 void __iomem *indicator_addr;
81 81
82 if (!test_bit(ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND, ar_pci->features)) { 82 if (!test_bit(ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND, ar_pci->features)) {
83 ath10k_pci_write32(ar, ce_ctrl_addr + SR_WR_INDEX_ADDRESS, n); 83 ath10k_pci_write32(ar, ce_ctrl_addr + SR_WR_INDEX_ADDRESS, n);
84 return; 84 return;
85 } 85 }
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 2b3426b1ff3f..7226c23b9569 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -100,7 +100,7 @@ static int ath10k_init_connect_htc(struct ath10k *ar)
100 goto conn_fail; 100 goto conn_fail;
101 101
102 /* Start HTC */ 102 /* Start HTC */
103 status = ath10k_htc_start(ar->htc); 103 status = ath10k_htc_start(&ar->htc);
104 if (status) 104 if (status)
105 goto conn_fail; 105 goto conn_fail;
106 106
@@ -116,7 +116,7 @@ static int ath10k_init_connect_htc(struct ath10k *ar)
116 return 0; 116 return 0;
117 117
118timeout: 118timeout:
119 ath10k_htc_stop(ar->htc); 119 ath10k_htc_stop(&ar->htc);
120conn_fail: 120conn_fail:
121 return status; 121 return status;
122} 122}
@@ -247,19 +247,11 @@ static int ath10k_push_board_ext_data(struct ath10k *ar,
247 247
248static int ath10k_download_board_data(struct ath10k *ar) 248static int ath10k_download_board_data(struct ath10k *ar)
249{ 249{
250 const struct firmware *fw = ar->board_data;
250 u32 board_data_size = QCA988X_BOARD_DATA_SZ; 251 u32 board_data_size = QCA988X_BOARD_DATA_SZ;
251 u32 address; 252 u32 address;
252 const struct firmware *fw;
253 int ret; 253 int ret;
254 254
255 fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
256 ar->hw_params.fw.board);
257 if (IS_ERR(fw)) {
258 ath10k_err("could not fetch board data fw file (%ld)\n",
259 PTR_ERR(fw));
260 return PTR_ERR(fw);
261 }
262
263 ret = ath10k_push_board_ext_data(ar, fw); 255 ret = ath10k_push_board_ext_data(ar, fw);
264 if (ret) { 256 if (ret) {
265 ath10k_err("could not push board ext data (%d)\n", ret); 257 ath10k_err("could not push board ext data (%d)\n", ret);
@@ -286,32 +278,20 @@ static int ath10k_download_board_data(struct ath10k *ar)
286 } 278 }
287 279
288exit: 280exit:
289 release_firmware(fw);
290 return ret; 281 return ret;
291} 282}
292 283
293static int ath10k_download_and_run_otp(struct ath10k *ar) 284static int ath10k_download_and_run_otp(struct ath10k *ar)
294{ 285{
295 const struct firmware *fw; 286 const struct firmware *fw = ar->otp;
296 u32 address; 287 u32 address = ar->hw_params.patch_load_addr;
297 u32 exec_param; 288 u32 exec_param;
298 int ret; 289 int ret;
299 290
300 /* OTP is optional */ 291 /* OTP is optional */
301 292
302 if (ar->hw_params.fw.otp == NULL) { 293 if (!ar->otp)
303 ath10k_info("otp file not defined\n");
304 return 0;
305 }
306
307 address = ar->hw_params.patch_load_addr;
308
309 fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
310 ar->hw_params.fw.otp);
311 if (IS_ERR(fw)) {
312 ath10k_warn("could not fetch otp (%ld)\n", PTR_ERR(fw));
313 return 0; 294 return 0;
314 }
315 295
316 ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size); 296 ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size);
317 if (ret) { 297 if (ret) {
@@ -327,28 +307,17 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)
327 } 307 }
328 308
329exit: 309exit:
330 release_firmware(fw);
331 return ret; 310 return ret;
332} 311}
333 312
334static int ath10k_download_fw(struct ath10k *ar) 313static int ath10k_download_fw(struct ath10k *ar)
335{ 314{
336 const struct firmware *fw; 315 const struct firmware *fw = ar->firmware;
337 u32 address; 316 u32 address;
338 int ret; 317 int ret;
339 318
340 if (ar->hw_params.fw.fw == NULL)
341 return -EINVAL;
342
343 address = ar->hw_params.patch_load_addr; 319 address = ar->hw_params.patch_load_addr;
344 320
345 fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
346 ar->hw_params.fw.fw);
347 if (IS_ERR(fw)) {
348 ath10k_err("could not fetch fw (%ld)\n", PTR_ERR(fw));
349 return PTR_ERR(fw);
350 }
351
352 ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size); 321 ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size);
353 if (ret) { 322 if (ret) {
354 ath10k_err("could not write fw (%d)\n", ret); 323 ath10k_err("could not write fw (%d)\n", ret);
@@ -356,7 +325,74 @@ static int ath10k_download_fw(struct ath10k *ar)
356 } 325 }
357 326
358exit: 327exit:
359 release_firmware(fw); 328 return ret;
329}
330
331static void ath10k_core_free_firmware_files(struct ath10k *ar)
332{
333 if (ar->board_data && !IS_ERR(ar->board_data))
334 release_firmware(ar->board_data);
335
336 if (ar->otp && !IS_ERR(ar->otp))
337 release_firmware(ar->otp);
338
339 if (ar->firmware && !IS_ERR(ar->firmware))
340 release_firmware(ar->firmware);
341
342 ar->board_data = NULL;
343 ar->otp = NULL;
344 ar->firmware = NULL;
345}
346
347static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
348{
349 int ret = 0;
350
351 if (ar->hw_params.fw.fw == NULL) {
352 ath10k_err("firmware file not defined\n");
353 return -EINVAL;
354 }
355
356 if (ar->hw_params.fw.board == NULL) {
357 ath10k_err("board data file not defined");
358 return -EINVAL;
359 }
360
361 ar->board_data = ath10k_fetch_fw_file(ar,
362 ar->hw_params.fw.dir,
363 ar->hw_params.fw.board);
364 if (IS_ERR(ar->board_data)) {
365 ret = PTR_ERR(ar->board_data);
366 ath10k_err("could not fetch board data (%d)\n", ret);
367 goto err;
368 }
369
370 ar->firmware = ath10k_fetch_fw_file(ar,
371 ar->hw_params.fw.dir,
372 ar->hw_params.fw.fw);
373 if (IS_ERR(ar->firmware)) {
374 ret = PTR_ERR(ar->firmware);
375 ath10k_err("could not fetch firmware (%d)\n", ret);
376 goto err;
377 }
378
379 /* OTP may be undefined. If so, don't fetch it at all */
380 if (ar->hw_params.fw.otp == NULL)
381 return 0;
382
383 ar->otp = ath10k_fetch_fw_file(ar,
384 ar->hw_params.fw.dir,
385 ar->hw_params.fw.otp);
386 if (IS_ERR(ar->otp)) {
387 ret = PTR_ERR(ar->otp);
388 ath10k_err("could not fetch otp (%d)\n", ret);
389 goto err;
390 }
391
392 return 0;
393
394err:
395 ath10k_core_free_firmware_files(ar);
360 return ret; 396 return ret;
361} 397}
362 398
@@ -440,8 +476,35 @@ static int ath10k_init_hw_params(struct ath10k *ar)
440 return 0; 476 return 0;
441} 477}
442 478
479static void ath10k_core_restart(struct work_struct *work)
480{
481 struct ath10k *ar = container_of(work, struct ath10k, restart_work);
482
483 mutex_lock(&ar->conf_mutex);
484
485 switch (ar->state) {
486 case ATH10K_STATE_ON:
487 ath10k_halt(ar);
488 ar->state = ATH10K_STATE_RESTARTING;
489 ieee80211_restart_hw(ar->hw);
490 break;
491 case ATH10K_STATE_OFF:
492 /* this can happen if driver is being unloaded */
493 ath10k_warn("cannot restart a device that hasn't been started\n");
494 break;
495 case ATH10K_STATE_RESTARTING:
496 case ATH10K_STATE_RESTARTED:
497 ar->state = ATH10K_STATE_WEDGED;
498 /* fall through */
499 case ATH10K_STATE_WEDGED:
500 ath10k_warn("device is wedged, will not restart\n");
501 break;
502 }
503
504 mutex_unlock(&ar->conf_mutex);
505}
506
443struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, 507struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
444 enum ath10k_bus bus,
445 const struct ath10k_hif_ops *hif_ops) 508 const struct ath10k_hif_ops *hif_ops)
446{ 509{
447 struct ath10k *ar; 510 struct ath10k *ar;
@@ -458,9 +521,6 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
458 521
459 ar->hif.priv = hif_priv; 522 ar->hif.priv = hif_priv;
460 ar->hif.ops = hif_ops; 523 ar->hif.ops = hif_ops;
461 ar->hif.bus = bus;
462
463 ar->free_vdev_map = 0xFF; /* 8 vdevs */
464 524
465 init_completion(&ar->scan.started); 525 init_completion(&ar->scan.started);
466 init_completion(&ar->scan.completed); 526 init_completion(&ar->scan.completed);
@@ -487,6 +547,8 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
487 547
488 init_waitqueue_head(&ar->event_queue); 548 init_waitqueue_head(&ar->event_queue);
489 549
550 INIT_WORK(&ar->restart_work, ath10k_core_restart);
551
490 return ar; 552 return ar;
491 553
492err_wq: 554err_wq:
@@ -504,24 +566,11 @@ void ath10k_core_destroy(struct ath10k *ar)
504} 566}
505EXPORT_SYMBOL(ath10k_core_destroy); 567EXPORT_SYMBOL(ath10k_core_destroy);
506 568
507 569int ath10k_core_start(struct ath10k *ar)
508int ath10k_core_register(struct ath10k *ar)
509{ 570{
510 struct ath10k_htc_ops htc_ops;
511 struct bmi_target_info target_info;
512 int status; 571 int status;
513 572
514 memset(&target_info, 0, sizeof(target_info)); 573 ath10k_bmi_start(ar);
515 status = ath10k_bmi_get_target_info(ar, &target_info);
516 if (status)
517 goto err;
518
519 ar->target_version = target_info.version;
520 ar->hw->wiphy->hw_version = target_info.version;
521
522 status = ath10k_init_hw_params(ar);
523 if (status)
524 goto err;
525 574
526 if (ath10k_init_configure_target(ar)) { 575 if (ath10k_init_configure_target(ar)) {
527 status = -EINVAL; 576 status = -EINVAL;
@@ -536,32 +585,32 @@ int ath10k_core_register(struct ath10k *ar)
536 if (status) 585 if (status)
537 goto err; 586 goto err;
538 587
539 htc_ops.target_send_suspend_complete = ath10k_send_suspend_complete; 588 ar->htc.htc_ops.target_send_suspend_complete =
589 ath10k_send_suspend_complete;
540 590
541 ar->htc = ath10k_htc_create(ar, &htc_ops); 591 status = ath10k_htc_init(ar);
542 if (IS_ERR(ar->htc)) { 592 if (status) {
543 status = PTR_ERR(ar->htc); 593 ath10k_err("could not init HTC (%d)\n", status);
544 ath10k_err("could not create HTC (%d)\n", status);
545 goto err; 594 goto err;
546 } 595 }
547 596
548 status = ath10k_bmi_done(ar); 597 status = ath10k_bmi_done(ar);
549 if (status) 598 if (status)
550 goto err_htc_destroy; 599 goto err;
551 600
552 status = ath10k_wmi_attach(ar); 601 status = ath10k_wmi_attach(ar);
553 if (status) { 602 if (status) {
554 ath10k_err("WMI attach failed: %d\n", status); 603 ath10k_err("WMI attach failed: %d\n", status);
555 goto err_htc_destroy; 604 goto err;
556 } 605 }
557 606
558 status = ath10k_htc_wait_target(ar->htc); 607 status = ath10k_htc_wait_target(&ar->htc);
559 if (status) 608 if (status)
560 goto err_wmi_detach; 609 goto err_wmi_detach;
561 610
562 ar->htt = ath10k_htt_attach(ar); 611 status = ath10k_htt_attach(ar);
563 if (!ar->htt) { 612 if (status) {
564 status = -ENOMEM; 613 ath10k_err("could not attach htt (%d)\n", status);
565 goto err_wmi_detach; 614 goto err_wmi_detach;
566 } 615 }
567 616
@@ -588,77 +637,127 @@ int ath10k_core_register(struct ath10k *ar)
588 goto err_disconnect_htc; 637 goto err_disconnect_htc;
589 } 638 }
590 639
591 status = ath10k_htt_attach_target(ar->htt); 640 status = ath10k_htt_attach_target(&ar->htt);
592 if (status)
593 goto err_disconnect_htc;
594
595 status = ath10k_mac_register(ar);
596 if (status) 641 if (status)
597 goto err_disconnect_htc; 642 goto err_disconnect_htc;
598 643
599 status = ath10k_debug_create(ar); 644 ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
600 if (status) {
601 ath10k_err("unable to initialize debugfs\n");
602 goto err_unregister_mac;
603 }
604 645
605 return 0; 646 return 0;
606 647
607err_unregister_mac:
608 ath10k_mac_unregister(ar);
609err_disconnect_htc: 648err_disconnect_htc:
610 ath10k_htc_stop(ar->htc); 649 ath10k_htc_stop(&ar->htc);
611err_htt_detach: 650err_htt_detach:
612 ath10k_htt_detach(ar->htt); 651 ath10k_htt_detach(&ar->htt);
613err_wmi_detach: 652err_wmi_detach:
614 ath10k_wmi_detach(ar); 653 ath10k_wmi_detach(ar);
615err_htc_destroy:
616 ath10k_htc_destroy(ar->htc);
617err: 654err:
618 return status; 655 return status;
619} 656}
620EXPORT_SYMBOL(ath10k_core_register); 657EXPORT_SYMBOL(ath10k_core_start);
621 658
622void ath10k_core_unregister(struct ath10k *ar) 659void ath10k_core_stop(struct ath10k *ar)
623{ 660{
624 /* We must unregister from mac80211 before we stop HTC and HIF. 661 ath10k_htc_stop(&ar->htc);
625 * Otherwise we will fail to submit commands to FW and mac80211 will be 662 ath10k_htt_detach(&ar->htt);
626 * unhappy about callback failures. */
627 ath10k_mac_unregister(ar);
628 ath10k_htc_stop(ar->htc);
629 ath10k_htt_detach(ar->htt);
630 ath10k_wmi_detach(ar); 663 ath10k_wmi_detach(ar);
631 ath10k_htc_destroy(ar->htc);
632} 664}
633EXPORT_SYMBOL(ath10k_core_unregister); 665EXPORT_SYMBOL(ath10k_core_stop);
634 666
635int ath10k_core_target_suspend(struct ath10k *ar) 667/* mac80211 manages fw/hw initialization through start/stop hooks. However in
668 * order to know what hw capabilities should be advertised to mac80211 it is
669 * necessary to load the firmware (and tear it down immediately since start
670 * hook will try to init it again) before registering */
671static int ath10k_core_probe_fw(struct ath10k *ar)
636{ 672{
637 int ret; 673 struct bmi_target_info target_info;
674 int ret = 0;
675
676 ret = ath10k_hif_power_up(ar);
677 if (ret) {
678 ath10k_err("could not start pci hif (%d)\n", ret);
679 return ret;
680 }
638 681
639 ath10k_dbg(ATH10K_DBG_CORE, "%s: called", __func__); 682 memset(&target_info, 0, sizeof(target_info));
683 ret = ath10k_bmi_get_target_info(ar, &target_info);
684 if (ret) {
685 ath10k_err("could not get target info (%d)\n", ret);
686 ath10k_hif_power_down(ar);
687 return ret;
688 }
640 689
641 ret = ath10k_wmi_pdev_suspend_target(ar); 690 ar->target_version = target_info.version;
642 if (ret) 691 ar->hw->wiphy->hw_version = target_info.version;
643 ath10k_warn("could not suspend target (%d)\n", ret);
644 692
645 return ret; 693 ret = ath10k_init_hw_params(ar);
694 if (ret) {
695 ath10k_err("could not get hw params (%d)\n", ret);
696 ath10k_hif_power_down(ar);
697 return ret;
698 }
699
700 ret = ath10k_core_fetch_firmware_files(ar);
701 if (ret) {
702 ath10k_err("could not fetch firmware files (%d)\n", ret);
703 ath10k_hif_power_down(ar);
704 return ret;
705 }
706
707 ret = ath10k_core_start(ar);
708 if (ret) {
709 ath10k_err("could not init core (%d)\n", ret);
710 ath10k_core_free_firmware_files(ar);
711 ath10k_hif_power_down(ar);
712 return ret;
713 }
714
715 ath10k_core_stop(ar);
716 ath10k_hif_power_down(ar);
717 return 0;
646} 718}
647EXPORT_SYMBOL(ath10k_core_target_suspend);
648 719
649int ath10k_core_target_resume(struct ath10k *ar) 720int ath10k_core_register(struct ath10k *ar)
650{ 721{
651 int ret; 722 int status;
652 723
653 ath10k_dbg(ATH10K_DBG_CORE, "%s: called", __func__); 724 status = ath10k_core_probe_fw(ar);
725 if (status) {
726 ath10k_err("could not probe fw (%d)\n", status);
727 return status;
728 }
654 729
655 ret = ath10k_wmi_pdev_resume_target(ar); 730 status = ath10k_mac_register(ar);
656 if (ret) 731 if (status) {
657 ath10k_warn("could not resume target (%d)\n", ret); 732 ath10k_err("could not register to mac80211 (%d)\n", status);
733 goto err_release_fw;
734 }
658 735
659 return ret; 736 status = ath10k_debug_create(ar);
737 if (status) {
738 ath10k_err("unable to initialize debugfs\n");
739 goto err_unregister_mac;
740 }
741
742 return 0;
743
744err_unregister_mac:
745 ath10k_mac_unregister(ar);
746err_release_fw:
747 ath10k_core_free_firmware_files(ar);
748 return status;
749}
750EXPORT_SYMBOL(ath10k_core_register);
751
752void ath10k_core_unregister(struct ath10k *ar)
753{
754 /* We must unregister from mac80211 before we stop HTC and HIF.
755 * Otherwise we will fail to submit commands to FW and mac80211 will be
756 * unhappy about callback failures. */
757 ath10k_mac_unregister(ar);
758 ath10k_core_free_firmware_files(ar);
660} 759}
661EXPORT_SYMBOL(ath10k_core_target_resume); 760EXPORT_SYMBOL(ath10k_core_unregister);
662 761
663MODULE_AUTHOR("Qualcomm Atheros"); 762MODULE_AUTHOR("Qualcomm Atheros");
664MODULE_DESCRIPTION("Core module for QCA988X PCIe devices."); 763MODULE_DESCRIPTION("Core module for QCA988X PCIe devices.");
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 539336d1be4b..9f21ecb239d7 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -23,6 +23,7 @@
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/pci.h> 24#include <linux/pci.h>
25 25
26#include "htt.h"
26#include "htc.h" 27#include "htc.h"
27#include "hw.h" 28#include "hw.h"
28#include "targaddrs.h" 29#include "targaddrs.h"
@@ -43,10 +44,6 @@
43 44
44struct ath10k; 45struct ath10k;
45 46
46enum ath10k_bus {
47 ATH10K_BUS_PCI,
48};
49
50struct ath10k_skb_cb { 47struct ath10k_skb_cb {
51 dma_addr_t paddr; 48 dma_addr_t paddr;
52 bool is_mapped; 49 bool is_mapped;
@@ -250,6 +247,28 @@ struct ath10k_debug {
250 struct completion event_stats_compl; 247 struct completion event_stats_compl;
251}; 248};
252 249
250enum ath10k_state {
251 ATH10K_STATE_OFF = 0,
252 ATH10K_STATE_ON,
253
254 /* When doing firmware recovery the device is first powered down.
255 * mac80211 is supposed to call in to start() hook later on. It is
256 * however possible that driver unloading and firmware crash overlap.
257 * mac80211 can wait on conf_mutex in stop() while the device is
258 * stopped in ath10k_core_restart() work holding conf_mutex. The state
259 * RESTARTED means that the device is up and mac80211 has started hw
260 * reconfiguration. Once mac80211 is done with the reconfiguration we
261 * set the state to STATE_ON in restart_complete(). */
262 ATH10K_STATE_RESTARTING,
263 ATH10K_STATE_RESTARTED,
264
265 /* The device has crashed while restarting hw. This state is like ON
266 * but commands are blocked in HTC and -ECOMM response is given. This
267 * prevents completion timeouts and makes the driver more responsive to
268 * userspace commands. This is also prevents recursive recovery. */
269 ATH10K_STATE_WEDGED,
270};
271
253struct ath10k { 272struct ath10k {
254 struct ath_common ath_common; 273 struct ath_common ath_common;
255 struct ieee80211_hw *hw; 274 struct ieee80211_hw *hw;
@@ -274,19 +293,16 @@ struct ath10k {
274 293
275 struct { 294 struct {
276 void *priv; 295 void *priv;
277 enum ath10k_bus bus;
278 const struct ath10k_hif_ops *ops; 296 const struct ath10k_hif_ops *ops;
279 } hif; 297 } hif;
280 298
281 struct ath10k_wmi wmi;
282
283 wait_queue_head_t event_queue; 299 wait_queue_head_t event_queue;
284 bool is_target_paused; 300 bool is_target_paused;
285 301
286 struct ath10k_bmi bmi; 302 struct ath10k_bmi bmi;
287 303 struct ath10k_wmi wmi;
288 struct ath10k_htc *htc; 304 struct ath10k_htc htc;
289 struct ath10k_htt *htt; 305 struct ath10k_htt htt;
290 306
291 struct ath10k_hw_params { 307 struct ath10k_hw_params {
292 u32 id; 308 u32 id;
@@ -301,6 +317,10 @@ struct ath10k {
301 } fw; 317 } fw;
302 } hw_params; 318 } hw_params;
303 319
320 const struct firmware *board_data;
321 const struct firmware *otp;
322 const struct firmware *firmware;
323
304 struct { 324 struct {
305 struct completion started; 325 struct completion started;
306 struct completion completed; 326 struct completion completed;
@@ -350,20 +370,22 @@ struct ath10k {
350 struct completion offchan_tx_completed; 370 struct completion offchan_tx_completed;
351 struct sk_buff *offchan_tx_skb; 371 struct sk_buff *offchan_tx_skb;
352 372
373 enum ath10k_state state;
374
375 struct work_struct restart_work;
376
353#ifdef CONFIG_ATH10K_DEBUGFS 377#ifdef CONFIG_ATH10K_DEBUGFS
354 struct ath10k_debug debug; 378 struct ath10k_debug debug;
355#endif 379#endif
356}; 380};
357 381
358struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, 382struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
359 enum ath10k_bus bus,
360 const struct ath10k_hif_ops *hif_ops); 383 const struct ath10k_hif_ops *hif_ops);
361void ath10k_core_destroy(struct ath10k *ar); 384void ath10k_core_destroy(struct ath10k *ar);
362 385
386int ath10k_core_start(struct ath10k *ar);
387void ath10k_core_stop(struct ath10k *ar);
363int ath10k_core_register(struct ath10k *ar); 388int ath10k_core_register(struct ath10k *ar);
364void ath10k_core_unregister(struct ath10k *ar); 389void ath10k_core_unregister(struct ath10k *ar);
365 390
366int ath10k_core_target_suspend(struct ath10k *ar);
367int ath10k_core_target_resume(struct ath10k *ar);
368
369#endif /* _CORE_H_ */ 391#endif /* _CORE_H_ */
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 499034b873d1..3d65594fa098 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -161,7 +161,7 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
161 struct wmi_pdev_stats *ps; 161 struct wmi_pdev_stats *ps;
162 int i; 162 int i;
163 163
164 mutex_lock(&ar->conf_mutex); 164 spin_lock_bh(&ar->data_lock);
165 165
166 stats = &ar->debug.target_stats; 166 stats = &ar->debug.target_stats;
167 167
@@ -259,6 +259,7 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
259 } 259 }
260 } 260 }
261 261
262 spin_unlock_bh(&ar->data_lock);
262 mutex_unlock(&ar->conf_mutex); 263 mutex_unlock(&ar->conf_mutex);
263 complete(&ar->debug.event_stats_compl); 264 complete(&ar->debug.event_stats_compl);
264} 265}
@@ -268,35 +269,35 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
268{ 269{
269 struct ath10k *ar = file->private_data; 270 struct ath10k *ar = file->private_data;
270 struct ath10k_target_stats *fw_stats; 271 struct ath10k_target_stats *fw_stats;
271 char *buf; 272 char *buf = NULL;
272 unsigned int len = 0, buf_len = 2500; 273 unsigned int len = 0, buf_len = 2500;
273 ssize_t ret_cnt; 274 ssize_t ret_cnt = 0;
274 long left; 275 long left;
275 int i; 276 int i;
276 int ret; 277 int ret;
277 278
278 fw_stats = &ar->debug.target_stats; 279 fw_stats = &ar->debug.target_stats;
279 280
281 mutex_lock(&ar->conf_mutex);
282
283 if (ar->state != ATH10K_STATE_ON)
284 goto exit;
285
280 buf = kzalloc(buf_len, GFP_KERNEL); 286 buf = kzalloc(buf_len, GFP_KERNEL);
281 if (!buf) 287 if (!buf)
282 return -ENOMEM; 288 goto exit;
283 289
284 ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); 290 ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT);
285 if (ret) { 291 if (ret) {
286 ath10k_warn("could not request stats (%d)\n", ret); 292 ath10k_warn("could not request stats (%d)\n", ret);
287 kfree(buf); 293 goto exit;
288 return -EIO;
289 } 294 }
290 295
291 left = wait_for_completion_timeout(&ar->debug.event_stats_compl, 1*HZ); 296 left = wait_for_completion_timeout(&ar->debug.event_stats_compl, 1*HZ);
297 if (left <= 0)
298 goto exit;
292 299
293 if (left <= 0) { 300 spin_lock_bh(&ar->data_lock);
294 kfree(buf);
295 return -ETIMEDOUT;
296 }
297
298 mutex_lock(&ar->conf_mutex);
299
300 len += scnprintf(buf + len, buf_len - len, "\n"); 301 len += scnprintf(buf + len, buf_len - len, "\n");
301 len += scnprintf(buf + len, buf_len - len, "%30s\n", 302 len += scnprintf(buf + len, buf_len - len, "%30s\n",
302 "ath10k PDEV stats"); 303 "ath10k PDEV stats");
@@ -424,14 +425,15 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
424 fw_stats->peer_stat[i].peer_tx_rate); 425 fw_stats->peer_stat[i].peer_tx_rate);
425 len += scnprintf(buf + len, buf_len - len, "\n"); 426 len += scnprintf(buf + len, buf_len - len, "\n");
426 } 427 }
428 spin_unlock_bh(&ar->data_lock);
427 429
428 if (len > buf_len) 430 if (len > buf_len)
429 len = buf_len; 431 len = buf_len;
430 432
431 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 433 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
432 434
435exit:
433 mutex_unlock(&ar->conf_mutex); 436 mutex_unlock(&ar->conf_mutex);
434
435 kfree(buf); 437 kfree(buf);
436 return ret_cnt; 438 return ret_cnt;
437} 439}
@@ -443,6 +445,60 @@ static const struct file_operations fops_fw_stats = {
443 .llseek = default_llseek, 445 .llseek = default_llseek,
444}; 446};
445 447
448static ssize_t ath10k_read_simulate_fw_crash(struct file *file,
449 char __user *user_buf,
450 size_t count, loff_t *ppos)
451{
452 const char buf[] = "To simulate firmware crash write the keyword"
453 " `crash` to this file.\nThis will force firmware"
454 " to report a crash to the host system.\n";
455 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
456}
457
458static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
459 const char __user *user_buf,
460 size_t count, loff_t *ppos)
461{
462 struct ath10k *ar = file->private_data;
463 char buf[32] = {};
464 int ret;
465
466 mutex_lock(&ar->conf_mutex);
467
468 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
469 if (strcmp(buf, "crash") && strcmp(buf, "crash\n")) {
470 ret = -EINVAL;
471 goto exit;
472 }
473
474 if (ar->state != ATH10K_STATE_ON &&
475 ar->state != ATH10K_STATE_RESTARTED) {
476 ret = -ENETDOWN;
477 goto exit;
478 }
479
480 ath10k_info("simulating firmware crash\n");
481
482 ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
483 if (ret)
484 ath10k_warn("failed to force fw hang (%d)\n", ret);
485
486 if (ret == 0)
487 ret = count;
488
489exit:
490 mutex_unlock(&ar->conf_mutex);
491 return ret;
492}
493
494static const struct file_operations fops_simulate_fw_crash = {
495 .read = ath10k_read_simulate_fw_crash,
496 .write = ath10k_write_simulate_fw_crash,
497 .open = simple_open,
498 .owner = THIS_MODULE,
499 .llseek = default_llseek,
500};
501
446int ath10k_debug_create(struct ath10k *ar) 502int ath10k_debug_create(struct ath10k *ar)
447{ 503{
448 ar->debug.debugfs_phy = debugfs_create_dir("ath10k", 504 ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
@@ -459,6 +515,9 @@ int ath10k_debug_create(struct ath10k *ar)
459 debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar, 515 debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar,
460 &fops_wmi_services); 516 &fops_wmi_services);
461 517
518 debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy,
519 ar, &fops_simulate_fw_crash);
520
462 return 0; 521 return 0;
463} 522}
464#endif /* CONFIG_ATH10K_DEBUGFS */ 523#endif /* CONFIG_ATH10K_DEBUGFS */
diff --git a/drivers/net/wireless/ath/ath10k/hif.h b/drivers/net/wireless/ath/ath10k/hif.h
index 73a24d44d1b4..dcdea68bcc0a 100644
--- a/drivers/net/wireless/ath/ath10k/hif.h
+++ b/drivers/net/wireless/ath/ath10k/hif.h
@@ -46,8 +46,11 @@ struct ath10k_hif_ops {
46 void *request, u32 request_len, 46 void *request, u32 request_len,
47 void *response, u32 *response_len); 47 void *response, u32 *response_len);
48 48
49 /* Post BMI phase, after FW is loaded. Starts regular operation */
49 int (*start)(struct ath10k *ar); 50 int (*start)(struct ath10k *ar);
50 51
52 /* Clean up what start() did. This does not revert to BMI phase. If
53 * desired so, call power_down() and power_up() */
51 void (*stop)(struct ath10k *ar); 54 void (*stop)(struct ath10k *ar);
52 55
53 int (*map_service_to_pipe)(struct ath10k *ar, u16 service_id, 56 int (*map_service_to_pipe)(struct ath10k *ar, u16 service_id,
@@ -66,10 +69,20 @@ struct ath10k_hif_ops {
66 */ 69 */
67 void (*send_complete_check)(struct ath10k *ar, u8 pipe_id, int force); 70 void (*send_complete_check)(struct ath10k *ar, u8 pipe_id, int force);
68 71
69 void (*init)(struct ath10k *ar, 72 void (*set_callbacks)(struct ath10k *ar,
70 struct ath10k_hif_cb *callbacks); 73 struct ath10k_hif_cb *callbacks);
71 74
72 u16 (*get_free_queue_number)(struct ath10k *ar, u8 pipe_id); 75 u16 (*get_free_queue_number)(struct ath10k *ar, u8 pipe_id);
76
77 /* Power up the device and enter BMI transfer mode for FW download */
78 int (*power_up)(struct ath10k *ar);
79
80 /* Power down the device and free up resources. stop() must be called
81 * before this if start() was called earlier */
82 void (*power_down)(struct ath10k *ar);
83
84 int (*suspend)(struct ath10k *ar);
85 int (*resume)(struct ath10k *ar);
73}; 86};
74 87
75 88
@@ -122,10 +135,10 @@ static inline void ath10k_hif_send_complete_check(struct ath10k *ar,
122 ar->hif.ops->send_complete_check(ar, pipe_id, force); 135 ar->hif.ops->send_complete_check(ar, pipe_id, force);
123} 136}
124 137
125static inline void ath10k_hif_init(struct ath10k *ar, 138static inline void ath10k_hif_set_callbacks(struct ath10k *ar,
126 struct ath10k_hif_cb *callbacks) 139 struct ath10k_hif_cb *callbacks)
127{ 140{
128 ar->hif.ops->init(ar, callbacks); 141 ar->hif.ops->set_callbacks(ar, callbacks);
129} 142}
130 143
131static inline u16 ath10k_hif_get_free_queue_number(struct ath10k *ar, 144static inline u16 ath10k_hif_get_free_queue_number(struct ath10k *ar,
@@ -134,4 +147,30 @@ static inline u16 ath10k_hif_get_free_queue_number(struct ath10k *ar,
134 return ar->hif.ops->get_free_queue_number(ar, pipe_id); 147 return ar->hif.ops->get_free_queue_number(ar, pipe_id);
135} 148}
136 149
150static inline int ath10k_hif_power_up(struct ath10k *ar)
151{
152 return ar->hif.ops->power_up(ar);
153}
154
155static inline void ath10k_hif_power_down(struct ath10k *ar)
156{
157 ar->hif.ops->power_down(ar);
158}
159
160static inline int ath10k_hif_suspend(struct ath10k *ar)
161{
162 if (!ar->hif.ops->suspend)
163 return -EOPNOTSUPP;
164
165 return ar->hif.ops->suspend(ar);
166}
167
168static inline int ath10k_hif_resume(struct ath10k *ar)
169{
170 if (!ar->hif.ops->resume)
171 return -EOPNOTSUPP;
172
173 return ar->hif.ops->resume(ar);
174}
175
137#endif /* _HIF_H_ */ 176#endif /* _HIF_H_ */
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index 74363c949392..ef3329ef52f3 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -246,15 +246,22 @@ int ath10k_htc_send(struct ath10k_htc *htc,
246{ 246{
247 struct ath10k_htc_ep *ep = &htc->endpoint[eid]; 247 struct ath10k_htc_ep *ep = &htc->endpoint[eid];
248 248
249 if (htc->ar->state == ATH10K_STATE_WEDGED)
250 return -ECOMM;
251
249 if (eid >= ATH10K_HTC_EP_COUNT) { 252 if (eid >= ATH10K_HTC_EP_COUNT) {
250 ath10k_warn("Invalid endpoint id: %d\n", eid); 253 ath10k_warn("Invalid endpoint id: %d\n", eid);
251 return -ENOENT; 254 return -ENOENT;
252 } 255 }
253 256
254 skb_push(skb, sizeof(struct ath10k_htc_hdr));
255
256 spin_lock_bh(&htc->tx_lock); 257 spin_lock_bh(&htc->tx_lock);
258 if (htc->stopped) {
259 spin_unlock_bh(&htc->tx_lock);
260 return -ESHUTDOWN;
261 }
262
257 __skb_queue_tail(&ep->tx_queue, skb); 263 __skb_queue_tail(&ep->tx_queue, skb);
264 skb_push(skb, sizeof(struct ath10k_htc_hdr));
258 spin_unlock_bh(&htc->tx_lock); 265 spin_unlock_bh(&htc->tx_lock);
259 266
260 queue_work(htc->ar->workqueue, &ep->send_work); 267 queue_work(htc->ar->workqueue, &ep->send_work);
@@ -265,25 +272,19 @@ static int ath10k_htc_tx_completion_handler(struct ath10k *ar,
265 struct sk_buff *skb, 272 struct sk_buff *skb,
266 unsigned int eid) 273 unsigned int eid)
267{ 274{
268 struct ath10k_htc *htc = ar->htc; 275 struct ath10k_htc *htc = &ar->htc;
269 struct ath10k_htc_ep *ep = &htc->endpoint[eid]; 276 struct ath10k_htc_ep *ep = &htc->endpoint[eid];
270 bool stopping;
271 277
272 ath10k_htc_notify_tx_completion(ep, skb); 278 ath10k_htc_notify_tx_completion(ep, skb);
273 /* the skb now belongs to the completion handler */ 279 /* the skb now belongs to the completion handler */
274 280
281 /* note: when using TX credit flow, the re-checking of queues happens
282 * when credits flow back from the target. in the non-TX credit case,
283 * we recheck after the packet completes */
275 spin_lock_bh(&htc->tx_lock); 284 spin_lock_bh(&htc->tx_lock);
276 stopping = htc->stopping; 285 if (!ep->tx_credit_flow_enabled && !htc->stopped)
277 spin_unlock_bh(&htc->tx_lock);
278
279 if (!ep->tx_credit_flow_enabled && !stopping)
280 /*
281 * note: when using TX credit flow, the re-checking of
282 * queues happens when credits flow back from the target.
283 * in the non-TX credit case, we recheck after the packet
284 * completes
285 */
286 queue_work(ar->workqueue, &ep->send_work); 286 queue_work(ar->workqueue, &ep->send_work);
287 spin_unlock_bh(&htc->tx_lock);
287 288
288 return 0; 289 return 0;
289} 290}
@@ -414,7 +415,7 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
414 u8 pipe_id) 415 u8 pipe_id)
415{ 416{
416 int status = 0; 417 int status = 0;
417 struct ath10k_htc *htc = ar->htc; 418 struct ath10k_htc *htc = &ar->htc;
418 struct ath10k_htc_hdr *hdr; 419 struct ath10k_htc_hdr *hdr;
419 struct ath10k_htc_ep *ep; 420 struct ath10k_htc_ep *ep;
420 u16 payload_len; 421 u16 payload_len;
@@ -751,8 +752,9 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
751 tx_alloc = ath10k_htc_get_credit_allocation(htc, 752 tx_alloc = ath10k_htc_get_credit_allocation(htc,
752 conn_req->service_id); 753 conn_req->service_id);
753 if (!tx_alloc) 754 if (!tx_alloc)
754 ath10k_warn("HTC Service %s does not allocate target credits\n", 755 ath10k_dbg(ATH10K_DBG_HTC,
755 htc_service_name(conn_req->service_id)); 756 "HTC Service %s does not allocate target credits\n",
757 htc_service_name(conn_req->service_id));
756 758
757 skb = ath10k_htc_build_tx_ctrl_skb(htc->ar); 759 skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
758 if (!skb) { 760 if (!skb) {
@@ -947,7 +949,7 @@ void ath10k_htc_stop(struct ath10k_htc *htc)
947 struct ath10k_htc_ep *ep; 949 struct ath10k_htc_ep *ep;
948 950
949 spin_lock_bh(&htc->tx_lock); 951 spin_lock_bh(&htc->tx_lock);
950 htc->stopping = true; 952 htc->stopped = true;
951 spin_unlock_bh(&htc->tx_lock); 953 spin_unlock_bh(&htc->tx_lock);
952 954
953 for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) { 955 for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) {
@@ -956,26 +958,18 @@ void ath10k_htc_stop(struct ath10k_htc *htc)
956 } 958 }
957 959
958 ath10k_hif_stop(htc->ar); 960 ath10k_hif_stop(htc->ar);
959 ath10k_htc_reset_endpoint_states(htc);
960} 961}
961 962
962/* registered target arrival callback from the HIF layer */ 963/* registered target arrival callback from the HIF layer */
963struct ath10k_htc *ath10k_htc_create(struct ath10k *ar, 964int ath10k_htc_init(struct ath10k *ar)
964 struct ath10k_htc_ops *htc_ops)
965{ 965{
966 struct ath10k_hif_cb htc_callbacks; 966 struct ath10k_hif_cb htc_callbacks;
967 struct ath10k_htc_ep *ep = NULL; 967 struct ath10k_htc_ep *ep = NULL;
968 struct ath10k_htc *htc = NULL; 968 struct ath10k_htc *htc = &ar->htc;
969
970 /* FIXME: use struct ath10k instead */
971 htc = kzalloc(sizeof(struct ath10k_htc), GFP_KERNEL);
972 if (!htc)
973 return ERR_PTR(-ENOMEM);
974 969
975 spin_lock_init(&htc->tx_lock); 970 spin_lock_init(&htc->tx_lock);
976 971
977 memcpy(&htc->htc_ops, htc_ops, sizeof(struct ath10k_htc_ops)); 972 htc->stopped = false;
978
979 ath10k_htc_reset_endpoint_states(htc); 973 ath10k_htc_reset_endpoint_states(htc);
980 974
981 /* setup HIF layer callbacks */ 975 /* setup HIF layer callbacks */
@@ -986,15 +980,10 @@ struct ath10k_htc *ath10k_htc_create(struct ath10k *ar,
986 /* Get HIF default pipe for HTC message exchange */ 980 /* Get HIF default pipe for HTC message exchange */
987 ep = &htc->endpoint[ATH10K_HTC_EP_0]; 981 ep = &htc->endpoint[ATH10K_HTC_EP_0];
988 982
989 ath10k_hif_init(ar, &htc_callbacks); 983 ath10k_hif_set_callbacks(ar, &htc_callbacks);
990 ath10k_hif_get_default_pipe(ar, &ep->ul_pipe_id, &ep->dl_pipe_id); 984 ath10k_hif_get_default_pipe(ar, &ep->ul_pipe_id, &ep->dl_pipe_id);
991 985
992 init_completion(&htc->ctl_resp); 986 init_completion(&htc->ctl_resp);
993 987
994 return htc; 988 return 0;
995}
996
997void ath10k_htc_destroy(struct ath10k_htc *htc)
998{
999 kfree(htc);
1000} 989}
diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h
index fa45844b59fb..e1dd8c761853 100644
--- a/drivers/net/wireless/ath/ath10k/htc.h
+++ b/drivers/net/wireless/ath/ath10k/htc.h
@@ -335,7 +335,7 @@ struct ath10k_htc {
335 struct ath10k *ar; 335 struct ath10k *ar;
336 struct ath10k_htc_ep endpoint[ATH10K_HTC_EP_COUNT]; 336 struct ath10k_htc_ep endpoint[ATH10K_HTC_EP_COUNT];
337 337
338 /* protects endpoint and stopping fields */ 338 /* protects endpoint and stopped fields */
339 spinlock_t tx_lock; 339 spinlock_t tx_lock;
340 340
341 struct ath10k_htc_ops htc_ops; 341 struct ath10k_htc_ops htc_ops;
@@ -349,11 +349,10 @@ struct ath10k_htc {
349 struct ath10k_htc_svc_tx_credits service_tx_alloc[ATH10K_HTC_EP_COUNT]; 349 struct ath10k_htc_svc_tx_credits service_tx_alloc[ATH10K_HTC_EP_COUNT];
350 int target_credit_size; 350 int target_credit_size;
351 351
352 bool stopping; 352 bool stopped;
353}; 353};
354 354
355struct ath10k_htc *ath10k_htc_create(struct ath10k *ar, 355int ath10k_htc_init(struct ath10k *ar);
356 struct ath10k_htc_ops *htc_ops);
357int ath10k_htc_wait_target(struct ath10k_htc *htc); 356int ath10k_htc_wait_target(struct ath10k_htc *htc);
358int ath10k_htc_start(struct ath10k_htc *htc); 357int ath10k_htc_start(struct ath10k_htc *htc);
359int ath10k_htc_connect_service(struct ath10k_htc *htc, 358int ath10k_htc_connect_service(struct ath10k_htc *htc,
@@ -362,7 +361,6 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
362int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid, 361int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid,
363 struct sk_buff *packet); 362 struct sk_buff *packet);
364void ath10k_htc_stop(struct ath10k_htc *htc); 363void ath10k_htc_stop(struct ath10k_htc *htc);
365void ath10k_htc_destroy(struct ath10k_htc *htc);
366struct sk_buff *ath10k_htc_alloc_skb(int size); 364struct sk_buff *ath10k_htc_alloc_skb(int size);
367 365
368#endif 366#endif
diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c
index 185a5468a2f2..39342c5cfcb2 100644
--- a/drivers/net/wireless/ath/ath10k/htt.c
+++ b/drivers/net/wireless/ath/ath10k/htt.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/if_ether.h>
19 20
20#include "htt.h" 21#include "htt.h"
21#include "core.h" 22#include "core.h"
@@ -36,7 +37,7 @@ static int ath10k_htt_htc_attach(struct ath10k_htt *htt)
36 /* connect to control service */ 37 /* connect to control service */
37 conn_req.service_id = ATH10K_HTC_SVC_ID_HTT_DATA_MSG; 38 conn_req.service_id = ATH10K_HTC_SVC_ID_HTT_DATA_MSG;
38 39
39 status = ath10k_htc_connect_service(htt->ar->htc, &conn_req, 40 status = ath10k_htc_connect_service(&htt->ar->htc, &conn_req,
40 &conn_resp); 41 &conn_resp);
41 42
42 if (status) 43 if (status)
@@ -47,15 +48,11 @@ static int ath10k_htt_htc_attach(struct ath10k_htt *htt)
47 return 0; 48 return 0;
48} 49}
49 50
50struct ath10k_htt *ath10k_htt_attach(struct ath10k *ar) 51int ath10k_htt_attach(struct ath10k *ar)
51{ 52{
52 struct ath10k_htt *htt; 53 struct ath10k_htt *htt = &ar->htt;
53 int ret; 54 int ret;
54 55
55 htt = kzalloc(sizeof(*htt), GFP_KERNEL);
56 if (!htt)
57 return NULL;
58
59 htt->ar = ar; 56 htt->ar = ar;
60 htt->max_throughput_mbps = 800; 57 htt->max_throughput_mbps = 800;
61 58
@@ -65,8 +62,11 @@ struct ath10k_htt *ath10k_htt_attach(struct ath10k *ar)
65 * since ath10k_htt_rx_attach involves sending a rx ring configure 62 * since ath10k_htt_rx_attach involves sending a rx ring configure
66 * message to the target. 63 * message to the target.
67 */ 64 */
68 if (ath10k_htt_htc_attach(htt)) 65 ret = ath10k_htt_htc_attach(htt);
66 if (ret) {
67 ath10k_err("could not attach htt htc (%d)\n", ret);
69 goto err_htc_attach; 68 goto err_htc_attach;
69 }
70 70
71 ret = ath10k_htt_tx_attach(htt); 71 ret = ath10k_htt_tx_attach(htt);
72 if (ret) { 72 if (ret) {
@@ -74,8 +74,11 @@ struct ath10k_htt *ath10k_htt_attach(struct ath10k *ar)
74 goto err_htc_attach; 74 goto err_htc_attach;
75 } 75 }
76 76
77 if (ath10k_htt_rx_attach(htt)) 77 ret = ath10k_htt_rx_attach(htt);
78 if (ret) {
79 ath10k_err("could not attach htt rx (%d)\n", ret);
78 goto err_rx_attach; 80 goto err_rx_attach;
81 }
79 82
80 /* 83 /*
81 * Prefetch enough data to satisfy target 84 * Prefetch enough data to satisfy target
@@ -89,13 +92,12 @@ struct ath10k_htt *ath10k_htt_attach(struct ath10k *ar)
89 8 + /* llc snap */ 92 8 + /* llc snap */
90 2; /* ip4 dscp or ip6 priority */ 93 2; /* ip4 dscp or ip6 priority */
91 94
92 return htt; 95 return 0;
93 96
94err_rx_attach: 97err_rx_attach:
95 ath10k_htt_tx_detach(htt); 98 ath10k_htt_tx_detach(htt);
96err_htc_attach: 99err_htc_attach:
97 kfree(htt); 100 return ret;
98 return NULL;
99} 101}
100 102
101#define HTT_TARGET_VERSION_TIMEOUT_HZ (3*HZ) 103#define HTT_TARGET_VERSION_TIMEOUT_HZ (3*HZ)
@@ -148,5 +150,4 @@ void ath10k_htt_detach(struct ath10k_htt *htt)
148{ 150{
149 ath10k_htt_rx_detach(htt); 151 ath10k_htt_rx_detach(htt);
150 ath10k_htt_tx_detach(htt); 152 ath10k_htt_tx_detach(htt);
151 kfree(htt);
152} 153}
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index a7a7aa040536..318be4629cde 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -20,7 +20,6 @@
20 20
21#include <linux/bug.h> 21#include <linux/bug.h>
22 22
23#include "core.h"
24#include "htc.h" 23#include "htc.h"
25#include "rx_desc.h" 24#include "rx_desc.h"
26 25
@@ -1317,7 +1316,7 @@ struct htt_rx_desc {
1317#define HTT_LOG2_MAX_CACHE_LINE_SIZE 7 /* 2^7 = 128 */ 1316#define HTT_LOG2_MAX_CACHE_LINE_SIZE 7 /* 2^7 = 128 */
1318#define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1) 1317#define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1)
1319 1318
1320struct ath10k_htt *ath10k_htt_attach(struct ath10k *ar); 1319int ath10k_htt_attach(struct ath10k *ar);
1321int ath10k_htt_attach_target(struct ath10k_htt *htt); 1320int ath10k_htt_attach_target(struct ath10k_htt *htt);
1322void ath10k_htt_detach(struct ath10k_htt *htt); 1321void ath10k_htt_detach(struct ath10k_htt *htt);
1323 1322
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index de058d7adca8..04f08d946479 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -15,6 +15,7 @@
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 17
18#include "core.h"
18#include "htc.h" 19#include "htc.h"
19#include "htt.h" 20#include "htt.h"
20#include "txrx.h" 21#include "txrx.h"
@@ -1036,7 +1037,7 @@ end:
1036 1037
1037void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) 1038void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
1038{ 1039{
1039 struct ath10k_htt *htt = ar->htt; 1040 struct ath10k_htt *htt = &ar->htt;
1040 struct htt_resp *resp = (struct htt_resp *)skb->data; 1041 struct htt_resp *resp = (struct htt_resp *)skb->data;
1041 1042
1042 /* confirm alignment */ 1043 /* confirm alignment */
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index ef79106db247..dc3f3e8de32b 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -92,7 +92,7 @@ int ath10k_htt_tx_attach(struct ath10k_htt *htt)
92 92
93 /* At the beginning free queue number should hint us the maximum 93 /* At the beginning free queue number should hint us the maximum
94 * queue length */ 94 * queue length */
95 pipe = htt->ar->htc->endpoint[htt->eid].ul_pipe_id; 95 pipe = htt->ar->htc.endpoint[htt->eid].ul_pipe_id;
96 htt->max_num_pending_tx = ath10k_hif_get_free_queue_number(htt->ar, 96 htt->max_num_pending_tx = ath10k_hif_get_free_queue_number(htt->ar,
97 pipe); 97 pipe);
98 98
@@ -153,7 +153,7 @@ void ath10k_htt_tx_detach(struct ath10k_htt *htt)
153void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) 153void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
154{ 154{
155 struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); 155 struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
156 struct ath10k_htt *htt = ar->htt; 156 struct ath10k_htt *htt = &ar->htt;
157 157
158 if (skb_cb->htt.is_conf) { 158 if (skb_cb->htt.is_conf) {
159 dev_kfree_skb_any(skb); 159 dev_kfree_skb_any(skb);
@@ -194,7 +194,7 @@ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt)
194 194
195 ATH10K_SKB_CB(skb)->htt.is_conf = true; 195 ATH10K_SKB_CB(skb)->htt.is_conf = true;
196 196
197 ret = ath10k_htc_send(htt->ar->htc, htt->eid, skb); 197 ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
198 if (ret) { 198 if (ret) {
199 dev_kfree_skb_any(skb); 199 dev_kfree_skb_any(skb);
200 return ret; 200 return ret;
@@ -281,7 +281,7 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
281 281
282 ATH10K_SKB_CB(skb)->htt.is_conf = true; 282 ATH10K_SKB_CB(skb)->htt.is_conf = true;
283 283
284 ret = ath10k_htc_send(htt->ar->htc, htt->eid, skb); 284 ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
285 if (ret) { 285 if (ret) {
286 dev_kfree_skb_any(skb); 286 dev_kfree_skb_any(skb);
287 return ret; 287 return ret;
@@ -346,7 +346,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
346 skb_cb->htt.refcount = 2; 346 skb_cb->htt.refcount = 2;
347 skb_cb->htt.msdu = msdu; 347 skb_cb->htt.msdu = msdu;
348 348
349 res = ath10k_htc_send(htt->ar->htc, htt->eid, txdesc); 349 res = ath10k_htc_send(&htt->ar->htc, htt->eid, txdesc);
350 if (res) 350 if (res)
351 goto err; 351 goto err;
352 352
@@ -486,7 +486,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
486 skb_cb->htt.txfrag = txfrag; 486 skb_cb->htt.txfrag = txfrag;
487 skb_cb->htt.msdu = msdu; 487 skb_cb->htt.msdu = msdu;
488 488
489 res = ath10k_htc_send(htt->ar->htc, htt->eid, txdesc); 489 res = ath10k_htc_send(&htt->ar->htc, htt->eid, txdesc);
490 if (res) 490 if (res)
491 goto err; 491 goto err;
492 492
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index da5c333d0d4b..d0a776124f13 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -20,6 +20,7 @@
20#include <net/mac80211.h> 20#include <net/mac80211.h>
21#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
22 22
23#include "hif.h"
23#include "core.h" 24#include "core.h"
24#include "debug.h" 25#include "debug.h"
25#include "wmi.h" 26#include "wmi.h"
@@ -43,6 +44,8 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
43 .macaddr = macaddr, 44 .macaddr = macaddr,
44 }; 45 };
45 46
47 lockdep_assert_held(&arvif->ar->conf_mutex);
48
46 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) 49 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
47 arg.key_flags = WMI_KEY_PAIRWISE; 50 arg.key_flags = WMI_KEY_PAIRWISE;
48 else 51 else
@@ -87,6 +90,8 @@ static int ath10k_install_key(struct ath10k_vif *arvif,
87 struct ath10k *ar = arvif->ar; 90 struct ath10k *ar = arvif->ar;
88 int ret; 91 int ret;
89 92
93 lockdep_assert_held(&ar->conf_mutex);
94
90 INIT_COMPLETION(ar->install_key_done); 95 INIT_COMPLETION(ar->install_key_done);
91 96
92 ret = ath10k_send_key(arvif, key, cmd, macaddr); 97 ret = ath10k_send_key(arvif, key, cmd, macaddr);
@@ -327,6 +332,29 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
327 return 0; 332 return 0;
328} 333}
329 334
335static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
336{
337 if (value != 0xFFFFFFFF)
338 value = min_t(u32, arvif->ar->hw->wiphy->rts_threshold,
339 ATH10K_RTS_MAX);
340
341 return ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id,
342 WMI_VDEV_PARAM_RTS_THRESHOLD,
343 value);
344}
345
346static int ath10k_mac_set_frag(struct ath10k_vif *arvif, u32 value)
347{
348 if (value != 0xFFFFFFFF)
349 value = clamp_t(u32, arvif->ar->hw->wiphy->frag_threshold,
350 ATH10K_FRAGMT_THRESHOLD_MIN,
351 ATH10K_FRAGMT_THRESHOLD_MAX);
352
353 return ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id,
354 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
355 value);
356}
357
330static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) 358static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
331{ 359{
332 int ret; 360 int ret;
@@ -364,6 +392,20 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
364 spin_unlock_bh(&ar->data_lock); 392 spin_unlock_bh(&ar->data_lock);
365} 393}
366 394
395static void ath10k_peer_cleanup_all(struct ath10k *ar)
396{
397 struct ath10k_peer *peer, *tmp;
398
399 lockdep_assert_held(&ar->conf_mutex);
400
401 spin_lock_bh(&ar->data_lock);
402 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
403 list_del(&peer->list);
404 kfree(peer);
405 }
406 spin_unlock_bh(&ar->data_lock);
407}
408
367/************************/ 409/************************/
368/* Interface management */ 410/* Interface management */
369/************************/ 411/************************/
@@ -372,6 +414,8 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
372{ 414{
373 int ret; 415 int ret;
374 416
417 lockdep_assert_held(&ar->conf_mutex);
418
375 ret = wait_for_completion_timeout(&ar->vdev_setup_done, 419 ret = wait_for_completion_timeout(&ar->vdev_setup_done,
376 ATH10K_VDEV_SETUP_TIMEOUT_HZ); 420 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
377 if (ret == 0) 421 if (ret == 0)
@@ -605,6 +649,8 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif,
605{ 649{
606 int ret = 0; 650 int ret = 0;
607 651
652 lockdep_assert_held(&arvif->ar->conf_mutex);
653
608 if (!info->enable_beacon) { 654 if (!info->enable_beacon) {
609 ath10k_vdev_stop(arvif); 655 ath10k_vdev_stop(arvif);
610 return; 656 return;
@@ -631,6 +677,8 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
631{ 677{
632 int ret = 0; 678 int ret = 0;
633 679
680 lockdep_assert_held(&arvif->ar->conf_mutex);
681
634 if (!info->ibss_joined) { 682 if (!info->ibss_joined) {
635 ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer); 683 ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer);
636 if (ret) 684 if (ret)
@@ -680,6 +728,8 @@ static void ath10k_ps_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
680 enum wmi_sta_ps_mode psmode; 728 enum wmi_sta_ps_mode psmode;
681 int ret; 729 int ret;
682 730
731 lockdep_assert_held(&arvif->ar->conf_mutex);
732
683 if (vif->type != NL80211_IFTYPE_STATION) 733 if (vif->type != NL80211_IFTYPE_STATION)
684 return; 734 return;
685 735
@@ -722,6 +772,8 @@ static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
722 struct ieee80211_bss_conf *bss_conf, 772 struct ieee80211_bss_conf *bss_conf,
723 struct wmi_peer_assoc_complete_arg *arg) 773 struct wmi_peer_assoc_complete_arg *arg)
724{ 774{
775 lockdep_assert_held(&ar->conf_mutex);
776
725 memcpy(arg->addr, sta->addr, ETH_ALEN); 777 memcpy(arg->addr, sta->addr, ETH_ALEN);
726 arg->vdev_id = arvif->vdev_id; 778 arg->vdev_id = arvif->vdev_id;
727 arg->peer_aid = sta->aid; 779 arg->peer_aid = sta->aid;
@@ -764,6 +816,8 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
764 const u8 *rsnie = NULL; 816 const u8 *rsnie = NULL;
765 const u8 *wpaie = NULL; 817 const u8 *wpaie = NULL;
766 818
819 lockdep_assert_held(&ar->conf_mutex);
820
767 bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan, 821 bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan,
768 info->bssid, NULL, 0, 0, 0); 822 info->bssid, NULL, 0, 0, 0);
769 if (bss) { 823 if (bss) {
@@ -804,6 +858,8 @@ static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
804 u32 ratemask; 858 u32 ratemask;
805 int i; 859 int i;
806 860
861 lockdep_assert_held(&ar->conf_mutex);
862
807 sband = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band]; 863 sband = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band];
808 ratemask = sta->supp_rates[ar->hw->conf.chandef.chan->band]; 864 ratemask = sta->supp_rates[ar->hw->conf.chandef.chan->band];
809 rates = sband->bitrates; 865 rates = sband->bitrates;
@@ -827,6 +883,8 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
827 int smps; 883 int smps;
828 int i, n; 884 int i, n;
829 885
886 lockdep_assert_held(&ar->conf_mutex);
887
830 if (!ht_cap->ht_supported) 888 if (!ht_cap->ht_supported)
831 return; 889 return;
832 890
@@ -905,6 +963,8 @@ static void ath10k_peer_assoc_h_qos_ap(struct ath10k *ar,
905 u32 uapsd = 0; 963 u32 uapsd = 0;
906 u32 max_sp = 0; 964 u32 max_sp = 0;
907 965
966 lockdep_assert_held(&ar->conf_mutex);
967
908 if (sta->wme) 968 if (sta->wme)
909 arg->peer_flags |= WMI_PEER_QOS; 969 arg->peer_flags |= WMI_PEER_QOS;
910 970
@@ -1056,6 +1116,8 @@ static int ath10k_peer_assoc(struct ath10k *ar,
1056{ 1116{
1057 struct wmi_peer_assoc_complete_arg arg; 1117 struct wmi_peer_assoc_complete_arg arg;
1058 1118
1119 lockdep_assert_held(&ar->conf_mutex);
1120
1059 memset(&arg, 0, sizeof(struct wmi_peer_assoc_complete_arg)); 1121 memset(&arg, 0, sizeof(struct wmi_peer_assoc_complete_arg));
1060 1122
1061 ath10k_peer_assoc_h_basic(ar, arvif, sta, bss_conf, &arg); 1123 ath10k_peer_assoc_h_basic(ar, arvif, sta, bss_conf, &arg);
@@ -1079,6 +1141,8 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1079 struct ieee80211_sta *ap_sta; 1141 struct ieee80211_sta *ap_sta;
1080 int ret; 1142 int ret;
1081 1143
1144 lockdep_assert_held(&ar->conf_mutex);
1145
1082 rcu_read_lock(); 1146 rcu_read_lock();
1083 1147
1084 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid); 1148 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
@@ -1119,6 +1183,8 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
1119 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 1183 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1120 int ret; 1184 int ret;
1121 1185
1186 lockdep_assert_held(&ar->conf_mutex);
1187
1122 /* 1188 /*
1123 * For some reason, calling VDEV-DOWN before VDEV-STOP 1189 * For some reason, calling VDEV-DOWN before VDEV-STOP
1124 * makes the FW to send frames via HTT after disassociation. 1190 * makes the FW to send frames via HTT after disassociation.
@@ -1152,6 +1218,8 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
1152{ 1218{
1153 int ret = 0; 1219 int ret = 0;
1154 1220
1221 lockdep_assert_held(&ar->conf_mutex);
1222
1155 ret = ath10k_peer_assoc(ar, arvif, sta, NULL); 1223 ret = ath10k_peer_assoc(ar, arvif, sta, NULL);
1156 if (ret) { 1224 if (ret) {
1157 ath10k_warn("WMI peer assoc failed for %pM\n", sta->addr); 1225 ath10k_warn("WMI peer assoc failed for %pM\n", sta->addr);
@@ -1172,6 +1240,8 @@ static int ath10k_station_disassoc(struct ath10k *ar, struct ath10k_vif *arvif,
1172{ 1240{
1173 int ret = 0; 1241 int ret = 0;
1174 1242
1243 lockdep_assert_held(&ar->conf_mutex);
1244
1175 ret = ath10k_clear_peer_keys(arvif, sta->addr); 1245 ret = ath10k_clear_peer_keys(arvif, sta->addr);
1176 if (ret) { 1246 if (ret) {
1177 ath10k_warn("could not clear all peer wep keys (%d)\n", ret); 1247 ath10k_warn("could not clear all peer wep keys (%d)\n", ret);
@@ -1198,6 +1268,8 @@ static int ath10k_update_channel_list(struct ath10k *ar)
1198 int ret; 1268 int ret;
1199 int i; 1269 int i;
1200 1270
1271 lockdep_assert_held(&ar->conf_mutex);
1272
1201 bands = hw->wiphy->bands; 1273 bands = hw->wiphy->bands;
1202 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1274 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1203 if (!bands[band]) 1275 if (!bands[band])
@@ -1276,21 +1348,19 @@ static int ath10k_update_channel_list(struct ath10k *ar)
1276 return ret; 1348 return ret;
1277} 1349}
1278 1350
1279static void ath10k_reg_notifier(struct wiphy *wiphy, 1351static void ath10k_regd_update(struct ath10k *ar)
1280 struct regulatory_request *request)
1281{ 1352{
1282 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
1283 struct reg_dmn_pair_mapping *regpair; 1353 struct reg_dmn_pair_mapping *regpair;
1284 struct ath10k *ar = hw->priv;
1285 int ret; 1354 int ret;
1286 1355
1287 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory); 1356 lockdep_assert_held(&ar->conf_mutex);
1288 1357
1289 ret = ath10k_update_channel_list(ar); 1358 ret = ath10k_update_channel_list(ar);
1290 if (ret) 1359 if (ret)
1291 ath10k_warn("could not update channel list (%d)\n", ret); 1360 ath10k_warn("could not update channel list (%d)\n", ret);
1292 1361
1293 regpair = ar->ath_common.regulatory.regpair; 1362 regpair = ar->ath_common.regulatory.regpair;
1363
1294 /* Target allows setting up per-band regdomain but ath_common provides 1364 /* Target allows setting up per-band regdomain but ath_common provides
1295 * a combined one only */ 1365 * a combined one only */
1296 ret = ath10k_wmi_pdev_set_regdomain(ar, 1366 ret = ath10k_wmi_pdev_set_regdomain(ar,
@@ -1303,6 +1373,20 @@ static void ath10k_reg_notifier(struct wiphy *wiphy,
1303 ath10k_warn("could not set pdev regdomain (%d)\n", ret); 1373 ath10k_warn("could not set pdev regdomain (%d)\n", ret);
1304} 1374}
1305 1375
1376static void ath10k_reg_notifier(struct wiphy *wiphy,
1377 struct regulatory_request *request)
1378{
1379 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
1380 struct ath10k *ar = hw->priv;
1381
1382 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
1383
1384 mutex_lock(&ar->conf_mutex);
1385 if (ar->state == ATH10K_STATE_ON)
1386 ath10k_regd_update(ar);
1387 mutex_unlock(&ar->conf_mutex);
1388}
1389
1306/***************/ 1390/***************/
1307/* TX handlers */ 1391/* TX handlers */
1308/***************/ 1392/***************/
@@ -1397,15 +1481,15 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
1397 int ret; 1481 int ret;
1398 1482
1399 if (ieee80211_is_mgmt(hdr->frame_control)) 1483 if (ieee80211_is_mgmt(hdr->frame_control))
1400 ret = ath10k_htt_mgmt_tx(ar->htt, skb); 1484 ret = ath10k_htt_mgmt_tx(&ar->htt, skb);
1401 else if (ieee80211_is_nullfunc(hdr->frame_control)) 1485 else if (ieee80211_is_nullfunc(hdr->frame_control))
1402 /* FW does not report tx status properly for NullFunc frames 1486 /* FW does not report tx status properly for NullFunc frames
1403 * unless they are sent through mgmt tx path. mac80211 sends 1487 * unless they are sent through mgmt tx path. mac80211 sends
1404 * those frames when it detects link/beacon loss and depends on 1488 * those frames when it detects link/beacon loss and depends on
1405 * the tx status to be correct. */ 1489 * the tx status to be correct. */
1406 ret = ath10k_htt_mgmt_tx(ar->htt, skb); 1490 ret = ath10k_htt_mgmt_tx(&ar->htt, skb);
1407 else 1491 else
1408 ret = ath10k_htt_tx(ar->htt, skb); 1492 ret = ath10k_htt_tx(&ar->htt, skb);
1409 1493
1410 if (ret) { 1494 if (ret) {
1411 ath10k_warn("tx failed (%d). dropping packet.\n", ret); 1495 ath10k_warn("tx failed (%d). dropping packet.\n", ret);
@@ -1552,6 +1636,10 @@ static int ath10k_abort_scan(struct ath10k *ar)
1552 ret = ath10k_wmi_stop_scan(ar, &arg); 1636 ret = ath10k_wmi_stop_scan(ar, &arg);
1553 if (ret) { 1637 if (ret) {
1554 ath10k_warn("could not submit wmi stop scan (%d)\n", ret); 1638 ath10k_warn("could not submit wmi stop scan (%d)\n", ret);
1639 spin_lock_bh(&ar->data_lock);
1640 ar->scan.in_progress = false;
1641 ath10k_offchan_tx_purge(ar);
1642 spin_unlock_bh(&ar->data_lock);
1555 return -EIO; 1643 return -EIO;
1556 } 1644 }
1557 1645
@@ -1645,10 +1733,14 @@ static void ath10k_tx(struct ieee80211_hw *hw,
1645 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 1733 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
1646 } 1734 }
1647 1735
1648 ath10k_tx_h_qos_workaround(hw, control, skb); 1736 /* it makes no sense to process injected frames like that */
1649 ath10k_tx_h_update_wep_key(skb); 1737 if (info->control.vif &&
1650 ath10k_tx_h_add_p2p_noa_ie(ar, skb); 1738 info->control.vif->type != NL80211_IFTYPE_MONITOR) {
1651 ath10k_tx_h_seq_no(skb); 1739 ath10k_tx_h_qos_workaround(hw, control, skb);
1740 ath10k_tx_h_update_wep_key(skb);
1741 ath10k_tx_h_add_p2p_noa_ie(ar, skb);
1742 ath10k_tx_h_seq_no(skb);
1743 }
1652 1744
1653 memset(ATH10K_SKB_CB(skb), 0, sizeof(*ATH10K_SKB_CB(skb))); 1745 memset(ATH10K_SKB_CB(skb), 0, sizeof(*ATH10K_SKB_CB(skb)));
1654 ATH10K_SKB_CB(skb)->htt.vdev_id = vdev_id; 1746 ATH10K_SKB_CB(skb)->htt.vdev_id = vdev_id;
@@ -1673,10 +1765,57 @@ static void ath10k_tx(struct ieee80211_hw *hw,
1673/* 1765/*
1674 * Initialize various parameters with default vaules. 1766 * Initialize various parameters with default vaules.
1675 */ 1767 */
1768void ath10k_halt(struct ath10k *ar)
1769{
1770 lockdep_assert_held(&ar->conf_mutex);
1771
1772 del_timer_sync(&ar->scan.timeout);
1773 ath10k_offchan_tx_purge(ar);
1774 ath10k_peer_cleanup_all(ar);
1775 ath10k_core_stop(ar);
1776 ath10k_hif_power_down(ar);
1777
1778 spin_lock_bh(&ar->data_lock);
1779 if (ar->scan.in_progress) {
1780 del_timer(&ar->scan.timeout);
1781 ar->scan.in_progress = false;
1782 ieee80211_scan_completed(ar->hw, true);
1783 }
1784 spin_unlock_bh(&ar->data_lock);
1785}
1786
1676static int ath10k_start(struct ieee80211_hw *hw) 1787static int ath10k_start(struct ieee80211_hw *hw)
1677{ 1788{
1678 struct ath10k *ar = hw->priv; 1789 struct ath10k *ar = hw->priv;
1679 int ret; 1790 int ret = 0;
1791
1792 mutex_lock(&ar->conf_mutex);
1793
1794 if (ar->state != ATH10K_STATE_OFF &&
1795 ar->state != ATH10K_STATE_RESTARTING) {
1796 ret = -EINVAL;
1797 goto exit;
1798 }
1799
1800 ret = ath10k_hif_power_up(ar);
1801 if (ret) {
1802 ath10k_err("could not init hif (%d)\n", ret);
1803 ar->state = ATH10K_STATE_OFF;
1804 goto exit;
1805 }
1806
1807 ret = ath10k_core_start(ar);
1808 if (ret) {
1809 ath10k_err("could not init core (%d)\n", ret);
1810 ath10k_hif_power_down(ar);
1811 ar->state = ATH10K_STATE_OFF;
1812 goto exit;
1813 }
1814
1815 if (ar->state == ATH10K_STATE_OFF)
1816 ar->state = ATH10K_STATE_ON;
1817 else if (ar->state == ATH10K_STATE_RESTARTING)
1818 ar->state = ATH10K_STATE_RESTARTED;
1680 1819
1681 ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS, 1); 1820 ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS, 1);
1682 if (ret) 1821 if (ret)
@@ -1688,6 +1827,10 @@ static int ath10k_start(struct ieee80211_hw *hw)
1688 ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n", 1827 ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n",
1689 ret); 1828 ret);
1690 1829
1830 ath10k_regd_update(ar);
1831
1832exit:
1833 mutex_unlock(&ar->conf_mutex);
1691 return 0; 1834 return 0;
1692} 1835}
1693 1836
@@ -1695,18 +1838,48 @@ static void ath10k_stop(struct ieee80211_hw *hw)
1695{ 1838{
1696 struct ath10k *ar = hw->priv; 1839 struct ath10k *ar = hw->priv;
1697 1840
1698 /* avoid leaks in case FW never confirms scan for offchannel */ 1841 mutex_lock(&ar->conf_mutex);
1842 if (ar->state == ATH10K_STATE_ON ||
1843 ar->state == ATH10K_STATE_RESTARTED ||
1844 ar->state == ATH10K_STATE_WEDGED)
1845 ath10k_halt(ar);
1846
1847 ar->state = ATH10K_STATE_OFF;
1848 mutex_unlock(&ar->conf_mutex);
1849
1699 cancel_work_sync(&ar->offchan_tx_work); 1850 cancel_work_sync(&ar->offchan_tx_work);
1700 ath10k_offchan_tx_purge(ar); 1851 cancel_work_sync(&ar->restart_work);
1701} 1852}
1702 1853
1703static int ath10k_config(struct ieee80211_hw *hw, u32 changed) 1854static void ath10k_config_ps(struct ath10k *ar)
1704{ 1855{
1705 struct ath10k_generic_iter ar_iter; 1856 struct ath10k_generic_iter ar_iter;
1857
1858 lockdep_assert_held(&ar->conf_mutex);
1859
1860 /* During HW reconfiguration mac80211 reports all interfaces that were
1861 * running until reconfiguration was started. Since FW doesn't have any
1862 * vdevs at this point we must not iterate over this interface list.
1863 * This setting will be updated upon add_interface(). */
1864 if (ar->state == ATH10K_STATE_RESTARTED)
1865 return;
1866
1867 memset(&ar_iter, 0, sizeof(struct ath10k_generic_iter));
1868 ar_iter.ar = ar;
1869
1870 ieee80211_iterate_active_interfaces_atomic(
1871 ar->hw, IEEE80211_IFACE_ITER_NORMAL,
1872 ath10k_ps_iter, &ar_iter);
1873
1874 if (ar_iter.ret)
1875 ath10k_warn("failed to set ps config (%d)\n", ar_iter.ret);
1876}
1877
1878static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
1879{
1706 struct ath10k *ar = hw->priv; 1880 struct ath10k *ar = hw->priv;
1707 struct ieee80211_conf *conf = &hw->conf; 1881 struct ieee80211_conf *conf = &hw->conf;
1708 int ret = 0; 1882 int ret = 0;
1709 u32 flags;
1710 1883
1711 mutex_lock(&ar->conf_mutex); 1884 mutex_lock(&ar->conf_mutex);
1712 1885
@@ -1718,18 +1891,8 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
1718 spin_unlock_bh(&ar->data_lock); 1891 spin_unlock_bh(&ar->data_lock);
1719 } 1892 }
1720 1893
1721 if (changed & IEEE80211_CONF_CHANGE_PS) { 1894 if (changed & IEEE80211_CONF_CHANGE_PS)
1722 memset(&ar_iter, 0, sizeof(struct ath10k_generic_iter)); 1895 ath10k_config_ps(ar);
1723 ar_iter.ar = ar;
1724 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
1725
1726 ieee80211_iterate_active_interfaces_atomic(hw,
1727 flags,
1728 ath10k_ps_iter,
1729 &ar_iter);
1730
1731 ret = ar_iter.ret;
1732 }
1733 1896
1734 if (changed & IEEE80211_CONF_CHANGE_MONITOR) { 1897 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1735 if (conf->flags & IEEE80211_CONF_MONITOR) 1898 if (conf->flags & IEEE80211_CONF_MONITOR)
@@ -1738,6 +1901,7 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
1738 ret = ath10k_monitor_destroy(ar); 1901 ret = ath10k_monitor_destroy(ar);
1739 } 1902 }
1740 1903
1904 ath10k_wmi_flush_tx(ar);
1741 mutex_unlock(&ar->conf_mutex); 1905 mutex_unlock(&ar->conf_mutex);
1742 return ret; 1906 return ret;
1743} 1907}
@@ -1859,6 +2023,16 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
1859 ath10k_warn("Failed to set PSPOLL count: %d\n", ret); 2023 ath10k_warn("Failed to set PSPOLL count: %d\n", ret);
1860 } 2024 }
1861 2025
2026 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
2027 if (ret)
2028 ath10k_warn("failed to set rts threshold for vdev %d (%d)\n",
2029 arvif->vdev_id, ret);
2030
2031 ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold);
2032 if (ret)
2033 ath10k_warn("failed to set frag threshold for vdev %d (%d)\n",
2034 arvif->vdev_id, ret);
2035
1862 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) 2036 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
1863 ar->monitor_present = true; 2037 ar->monitor_present = true;
1864 2038
@@ -2363,6 +2537,8 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
2363 u32 value = 0; 2537 u32 value = 0;
2364 int ret = 0; 2538 int ret = 0;
2365 2539
2540 lockdep_assert_held(&ar->conf_mutex);
2541
2366 if (arvif->vdev_type != WMI_VDEV_TYPE_STA) 2542 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
2367 return 0; 2543 return 0;
2368 2544
@@ -2558,11 +2734,16 @@ static void ath10k_set_rts_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
2558 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 2734 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2559 u32 rts = ar_iter->ar->hw->wiphy->rts_threshold; 2735 u32 rts = ar_iter->ar->hw->wiphy->rts_threshold;
2560 2736
2561 rts = min_t(u32, rts, ATH10K_RTS_MAX); 2737 lockdep_assert_held(&arvif->ar->conf_mutex);
2562 2738
2563 ar_iter->ret = ath10k_wmi_vdev_set_param(ar_iter->ar, arvif->vdev_id, 2739 /* During HW reconfiguration mac80211 reports all interfaces that were
2564 WMI_VDEV_PARAM_RTS_THRESHOLD, 2740 * running until reconfiguration was started. Since FW doesn't have any
2565 rts); 2741 * vdevs at this point we must not iterate over this interface list.
2742 * This setting will be updated upon add_interface(). */
2743 if (ar_iter->ar->state == ATH10K_STATE_RESTARTED)
2744 return;
2745
2746 ar_iter->ret = ath10k_mac_set_rts(arvif, rts);
2566 if (ar_iter->ret) 2747 if (ar_iter->ret)
2567 ath10k_warn("Failed to set RTS threshold for VDEV: %d\n", 2748 ath10k_warn("Failed to set RTS threshold for VDEV: %d\n",
2568 arvif->vdev_id); 2749 arvif->vdev_id);
@@ -2581,8 +2762,9 @@ static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
2581 ar_iter.ar = ar; 2762 ar_iter.ar = ar;
2582 2763
2583 mutex_lock(&ar->conf_mutex); 2764 mutex_lock(&ar->conf_mutex);
2584 ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, 2765 ieee80211_iterate_active_interfaces_atomic(
2585 ath10k_set_rts_iter, &ar_iter); 2766 hw, IEEE80211_IFACE_ITER_NORMAL,
2767 ath10k_set_rts_iter, &ar_iter);
2586 mutex_unlock(&ar->conf_mutex); 2768 mutex_unlock(&ar->conf_mutex);
2587 2769
2588 return ar_iter.ret; 2770 return ar_iter.ret;
@@ -2593,17 +2775,17 @@ static void ath10k_set_frag_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
2593 struct ath10k_generic_iter *ar_iter = data; 2775 struct ath10k_generic_iter *ar_iter = data;
2594 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 2776 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2595 u32 frag = ar_iter->ar->hw->wiphy->frag_threshold; 2777 u32 frag = ar_iter->ar->hw->wiphy->frag_threshold;
2596 int ret;
2597 2778
2598 frag = clamp_t(u32, frag, 2779 lockdep_assert_held(&arvif->ar->conf_mutex);
2599 ATH10K_FRAGMT_THRESHOLD_MIN,
2600 ATH10K_FRAGMT_THRESHOLD_MAX);
2601 2780
2602 ret = ath10k_wmi_vdev_set_param(ar_iter->ar, arvif->vdev_id, 2781 /* During HW reconfiguration mac80211 reports all interfaces that were
2603 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 2782 * running until reconfiguration was started. Since FW doesn't have any
2604 frag); 2783 * vdevs at this point we must not iterate over this interface list.
2784 * This setting will be updated upon add_interface(). */
2785 if (ar_iter->ar->state == ATH10K_STATE_RESTARTED)
2786 return;
2605 2787
2606 ar_iter->ret = ret; 2788 ar_iter->ret = ath10k_mac_set_frag(arvif, frag);
2607 if (ar_iter->ret) 2789 if (ar_iter->ret)
2608 ath10k_warn("Failed to set frag threshold for VDEV: %d\n", 2790 ath10k_warn("Failed to set frag threshold for VDEV: %d\n",
2609 arvif->vdev_id); 2791 arvif->vdev_id);
@@ -2622,8 +2804,9 @@ static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
2622 ar_iter.ar = ar; 2804 ar_iter.ar = ar;
2623 2805
2624 mutex_lock(&ar->conf_mutex); 2806 mutex_lock(&ar->conf_mutex);
2625 ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, 2807 ieee80211_iterate_active_interfaces_atomic(
2626 ath10k_set_frag_iter, &ar_iter); 2808 hw, IEEE80211_IFACE_ITER_NORMAL,
2809 ath10k_set_frag_iter, &ar_iter);
2627 mutex_unlock(&ar->conf_mutex); 2810 mutex_unlock(&ar->conf_mutex);
2628 2811
2629 return ar_iter.ret; 2812 return ar_iter.ret;
@@ -2632,6 +2815,7 @@ static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
2632static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 2815static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
2633{ 2816{
2634 struct ath10k *ar = hw->priv; 2817 struct ath10k *ar = hw->priv;
2818 bool skip;
2635 int ret; 2819 int ret;
2636 2820
2637 /* mac80211 doesn't care if we really xmit queued frames or not 2821 /* mac80211 doesn't care if we really xmit queued frames or not
@@ -2639,16 +2823,29 @@ static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
2639 if (drop) 2823 if (drop)
2640 return; 2824 return;
2641 2825
2642 ret = wait_event_timeout(ar->htt->empty_tx_wq, ({ 2826 mutex_lock(&ar->conf_mutex);
2827
2828 if (ar->state == ATH10K_STATE_WEDGED)
2829 goto skip;
2830
2831 ret = wait_event_timeout(ar->htt.empty_tx_wq, ({
2643 bool empty; 2832 bool empty;
2644 spin_lock_bh(&ar->htt->tx_lock); 2833
2645 empty = bitmap_empty(ar->htt->used_msdu_ids, 2834 spin_lock_bh(&ar->htt.tx_lock);
2646 ar->htt->max_num_pending_tx); 2835 empty = bitmap_empty(ar->htt.used_msdu_ids,
2647 spin_unlock_bh(&ar->htt->tx_lock); 2836 ar->htt.max_num_pending_tx);
2648 (empty); 2837 spin_unlock_bh(&ar->htt.tx_lock);
2838
2839 skip = (ar->state == ATH10K_STATE_WEDGED);
2840
2841 (empty || skip);
2649 }), ATH10K_FLUSH_TIMEOUT_HZ); 2842 }), ATH10K_FLUSH_TIMEOUT_HZ);
2650 if (ret <= 0) 2843
2844 if (ret <= 0 || skip)
2651 ath10k_warn("tx not flushed\n"); 2845 ath10k_warn("tx not flushed\n");
2846
2847skip:
2848 mutex_unlock(&ar->conf_mutex);
2652} 2849}
2653 2850
2654/* TODO: Implement this function properly 2851/* TODO: Implement this function properly
@@ -2660,6 +2857,83 @@ static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
2660 return 1; 2857 return 1;
2661} 2858}
2662 2859
2860#ifdef CONFIG_PM
2861static int ath10k_suspend(struct ieee80211_hw *hw,
2862 struct cfg80211_wowlan *wowlan)
2863{
2864 struct ath10k *ar = hw->priv;
2865 int ret;
2866
2867 ar->is_target_paused = false;
2868
2869 ret = ath10k_wmi_pdev_suspend_target(ar);
2870 if (ret) {
2871 ath10k_warn("could not suspend target (%d)\n", ret);
2872 return 1;
2873 }
2874
2875 ret = wait_event_interruptible_timeout(ar->event_queue,
2876 ar->is_target_paused == true,
2877 1 * HZ);
2878 if (ret < 0) {
2879 ath10k_warn("suspend interrupted (%d)\n", ret);
2880 goto resume;
2881 } else if (ret == 0) {
2882 ath10k_warn("suspend timed out - target pause event never came\n");
2883 goto resume;
2884 }
2885
2886 ret = ath10k_hif_suspend(ar);
2887 if (ret) {
2888 ath10k_warn("could not suspend hif (%d)\n", ret);
2889 goto resume;
2890 }
2891
2892 return 0;
2893resume:
2894 ret = ath10k_wmi_pdev_resume_target(ar);
2895 if (ret)
2896 ath10k_warn("could not resume target (%d)\n", ret);
2897 return 1;
2898}
2899
2900static int ath10k_resume(struct ieee80211_hw *hw)
2901{
2902 struct ath10k *ar = hw->priv;
2903 int ret;
2904
2905 ret = ath10k_hif_resume(ar);
2906 if (ret) {
2907 ath10k_warn("could not resume hif (%d)\n", ret);
2908 return 1;
2909 }
2910
2911 ret = ath10k_wmi_pdev_resume_target(ar);
2912 if (ret) {
2913 ath10k_warn("could not resume target (%d)\n", ret);
2914 return 1;
2915 }
2916
2917 return 0;
2918}
2919#endif
2920
2921static void ath10k_restart_complete(struct ieee80211_hw *hw)
2922{
2923 struct ath10k *ar = hw->priv;
2924
2925 mutex_lock(&ar->conf_mutex);
2926
2927 /* If device failed to restart it will be in a different state, e.g.
2928 * ATH10K_STATE_WEDGED */
2929 if (ar->state == ATH10K_STATE_RESTARTED) {
2930 ath10k_info("device successfully recovered\n");
2931 ar->state = ATH10K_STATE_ON;
2932 }
2933
2934 mutex_unlock(&ar->conf_mutex);
2935}
2936
2663static const struct ieee80211_ops ath10k_ops = { 2937static const struct ieee80211_ops ath10k_ops = {
2664 .tx = ath10k_tx, 2938 .tx = ath10k_tx,
2665 .start = ath10k_start, 2939 .start = ath10k_start,
@@ -2680,6 +2954,11 @@ static const struct ieee80211_ops ath10k_ops = {
2680 .set_frag_threshold = ath10k_set_frag_threshold, 2954 .set_frag_threshold = ath10k_set_frag_threshold,
2681 .flush = ath10k_flush, 2955 .flush = ath10k_flush,
2682 .tx_last_beacon = ath10k_tx_last_beacon, 2956 .tx_last_beacon = ath10k_tx_last_beacon,
2957 .restart_complete = ath10k_restart_complete,
2958#ifdef CONFIG_PM
2959 .suspend = ath10k_suspend,
2960 .resume = ath10k_resume,
2961#endif
2683}; 2962};
2684 2963
2685#define RATETAB_ENT(_rate, _rateid, _flags) { \ 2964#define RATETAB_ENT(_rate, _rateid, _flags) { \
@@ -2948,8 +3227,10 @@ int ath10k_mac_register(struct ath10k *ar)
2948 channels = kmemdup(ath10k_2ghz_channels, 3227 channels = kmemdup(ath10k_2ghz_channels,
2949 sizeof(ath10k_2ghz_channels), 3228 sizeof(ath10k_2ghz_channels),
2950 GFP_KERNEL); 3229 GFP_KERNEL);
2951 if (!channels) 3230 if (!channels) {
2952 return -ENOMEM; 3231 ret = -ENOMEM;
3232 goto err_free;
3233 }
2953 3234
2954 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ]; 3235 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
2955 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels); 3236 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
@@ -2968,11 +3249,8 @@ int ath10k_mac_register(struct ath10k *ar)
2968 sizeof(ath10k_5ghz_channels), 3249 sizeof(ath10k_5ghz_channels),
2969 GFP_KERNEL); 3250 GFP_KERNEL);
2970 if (!channels) { 3251 if (!channels) {
2971 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) { 3252 ret = -ENOMEM;
2972 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ]; 3253 goto err_free;
2973 kfree(band->channels);
2974 }
2975 return -ENOMEM;
2976 } 3254 }
2977 3255
2978 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ]; 3256 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
@@ -3036,25 +3314,30 @@ int ath10k_mac_register(struct ath10k *ar)
3036 ath10k_reg_notifier); 3314 ath10k_reg_notifier);
3037 if (ret) { 3315 if (ret) {
3038 ath10k_err("Regulatory initialization failed\n"); 3316 ath10k_err("Regulatory initialization failed\n");
3039 return ret; 3317 goto err_free;
3040 } 3318 }
3041 3319
3042 ret = ieee80211_register_hw(ar->hw); 3320 ret = ieee80211_register_hw(ar->hw);
3043 if (ret) { 3321 if (ret) {
3044 ath10k_err("ieee80211 registration failed: %d\n", ret); 3322 ath10k_err("ieee80211 registration failed: %d\n", ret);
3045 return ret; 3323 goto err_free;
3046 } 3324 }
3047 3325
3048 if (!ath_is_world_regd(&ar->ath_common.regulatory)) { 3326 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
3049 ret = regulatory_hint(ar->hw->wiphy, 3327 ret = regulatory_hint(ar->hw->wiphy,
3050 ar->ath_common.regulatory.alpha2); 3328 ar->ath_common.regulatory.alpha2);
3051 if (ret) 3329 if (ret)
3052 goto exit; 3330 goto err_unregister;
3053 } 3331 }
3054 3332
3055 return 0; 3333 return 0;
3056exit: 3334
3335err_unregister:
3057 ieee80211_unregister_hw(ar->hw); 3336 ieee80211_unregister_hw(ar->hw);
3337err_free:
3338 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
3339 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
3340
3058 return ret; 3341 return ret;
3059} 3342}
3060 3343
diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h
index 27fc92e58829..6fce9bfb19a5 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -34,6 +34,7 @@ struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id);
34void ath10k_reset_scan(unsigned long ptr); 34void ath10k_reset_scan(unsigned long ptr);
35void ath10k_offchan_tx_purge(struct ath10k *ar); 35void ath10k_offchan_tx_purge(struct ath10k *ar);
36void ath10k_offchan_tx_work(struct work_struct *work); 36void ath10k_offchan_tx_work(struct work_struct *work);
37void ath10k_halt(struct ath10k *ar);
37 38
38static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif) 39static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif)
39{ 40{
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 33af4672c909..c71b488eba9f 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -54,6 +54,8 @@ static int ath10k_pci_post_rx_pipe(struct hif_ce_pipe_info *pipe_info,
54 int num); 54 int num);
55static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info); 55static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info);
56static void ath10k_pci_stop_ce(struct ath10k *ar); 56static void ath10k_pci_stop_ce(struct ath10k *ar);
57static void ath10k_pci_device_reset(struct ath10k *ar);
58static int ath10k_pci_reset_target(struct ath10k *ar);
57 59
58static const struct ce_attr host_ce_config_wlan[] = { 60static const struct ce_attr host_ce_config_wlan[] = {
59 /* host->target HTC control and raw streams */ 61 /* host->target HTC control and raw streams */
@@ -718,6 +720,8 @@ static void ath10k_pci_hif_dump_area(struct ath10k *ar)
718 reg_dump_values[i + 1], 720 reg_dump_values[i + 1],
719 reg_dump_values[i + 2], 721 reg_dump_values[i + 2],
720 reg_dump_values[i + 3]); 722 reg_dump_values[i + 3]);
723
724 ieee80211_queue_work(ar->hw, &ar->restart_work);
721} 725}
722 726
723static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, 727static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
@@ -744,8 +748,8 @@ static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
744 ath10k_ce_per_engine_service(ar, pipe); 748 ath10k_ce_per_engine_service(ar, pipe);
745} 749}
746 750
747static void ath10k_pci_hif_post_init(struct ath10k *ar, 751static void ath10k_pci_hif_set_callbacks(struct ath10k *ar,
748 struct ath10k_hif_cb *callbacks) 752 struct ath10k_hif_cb *callbacks)
749{ 753{
750 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 754 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
751 755
@@ -1263,7 +1267,6 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
1263 ath10k_pci_process_ce(ar); 1267 ath10k_pci_process_ce(ar);
1264 ath10k_pci_cleanup_ce(ar); 1268 ath10k_pci_cleanup_ce(ar);
1265 ath10k_pci_buffer_cleanup(ar); 1269 ath10k_pci_buffer_cleanup(ar);
1266 ath10k_pci_ce_deinit(ar);
1267} 1270}
1268 1271
1269static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, 1272static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
@@ -1735,6 +1738,115 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
1735 ath10k_pci_sleep(ar); 1738 ath10k_pci_sleep(ar);
1736} 1739}
1737 1740
1741static int ath10k_pci_hif_power_up(struct ath10k *ar)
1742{
1743 int ret;
1744
1745 /*
1746 * Bring the target up cleanly.
1747 *
1748 * The target may be in an undefined state with an AUX-powered Target
1749 * and a Host in WoW mode. If the Host crashes, loses power, or is
1750 * restarted (without unloading the driver) then the Target is left
1751 * (aux) powered and running. On a subsequent driver load, the Target
1752 * is in an unexpected state. We try to catch that here in order to
1753 * reset the Target and retry the probe.
1754 */
1755 ath10k_pci_device_reset(ar);
1756
1757 ret = ath10k_pci_reset_target(ar);
1758 if (ret)
1759 goto err;
1760
1761 if (ath10k_target_ps) {
1762 ath10k_dbg(ATH10K_DBG_PCI, "on-chip power save enabled\n");
1763 } else {
1764 /* Force AWAKE forever */
1765 ath10k_dbg(ATH10K_DBG_PCI, "on-chip power save disabled\n");
1766 ath10k_do_pci_wake(ar);
1767 }
1768
1769 ret = ath10k_pci_ce_init(ar);
1770 if (ret)
1771 goto err_ps;
1772
1773 ret = ath10k_pci_init_config(ar);
1774 if (ret)
1775 goto err_ce;
1776
1777 ret = ath10k_pci_wake_target_cpu(ar);
1778 if (ret) {
1779 ath10k_err("could not wake up target CPU (%d)\n", ret);
1780 goto err_ce;
1781 }
1782
1783 return 0;
1784
1785err_ce:
1786 ath10k_pci_ce_deinit(ar);
1787err_ps:
1788 if (!ath10k_target_ps)
1789 ath10k_do_pci_sleep(ar);
1790err:
1791 return ret;
1792}
1793
1794static void ath10k_pci_hif_power_down(struct ath10k *ar)
1795{
1796 ath10k_pci_ce_deinit(ar);
1797 if (!ath10k_target_ps)
1798 ath10k_do_pci_sleep(ar);
1799}
1800
1801#ifdef CONFIG_PM
1802
1803#define ATH10K_PCI_PM_CONTROL 0x44
1804
1805static int ath10k_pci_hif_suspend(struct ath10k *ar)
1806{
1807 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1808 struct pci_dev *pdev = ar_pci->pdev;
1809 u32 val;
1810
1811 pci_read_config_dword(pdev, ATH10K_PCI_PM_CONTROL, &val);
1812
1813 if ((val & 0x000000ff) != 0x3) {
1814 pci_save_state(pdev);
1815 pci_disable_device(pdev);
1816 pci_write_config_dword(pdev, ATH10K_PCI_PM_CONTROL,
1817 (val & 0xffffff00) | 0x03);
1818 }
1819
1820 return 0;
1821}
1822
1823static int ath10k_pci_hif_resume(struct ath10k *ar)
1824{
1825 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1826 struct pci_dev *pdev = ar_pci->pdev;
1827 u32 val;
1828
1829 pci_read_config_dword(pdev, ATH10K_PCI_PM_CONTROL, &val);
1830
1831 if ((val & 0x000000ff) != 0) {
1832 pci_restore_state(pdev);
1833 pci_write_config_dword(pdev, ATH10K_PCI_PM_CONTROL,
1834 val & 0xffffff00);
1835 /*
1836 * Suspend/Resume resets the PCI configuration space,
1837 * so we have to re-disable the RETRY_TIMEOUT register (0x41)
1838 * to keep PCI Tx retries from interfering with C3 CPU state
1839 */
1840 pci_read_config_dword(pdev, 0x40, &val);
1841
1842 if ((val & 0x0000ff00) != 0)
1843 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1844 }
1845
1846 return 0;
1847}
1848#endif
1849
1738static const struct ath10k_hif_ops ath10k_pci_hif_ops = { 1850static const struct ath10k_hif_ops ath10k_pci_hif_ops = {
1739 .send_head = ath10k_pci_hif_send_head, 1851 .send_head = ath10k_pci_hif_send_head,
1740 .exchange_bmi_msg = ath10k_pci_hif_exchange_bmi_msg, 1852 .exchange_bmi_msg = ath10k_pci_hif_exchange_bmi_msg,
@@ -1743,8 +1855,14 @@ static const struct ath10k_hif_ops ath10k_pci_hif_ops = {
1743 .map_service_to_pipe = ath10k_pci_hif_map_service_to_pipe, 1855 .map_service_to_pipe = ath10k_pci_hif_map_service_to_pipe,
1744 .get_default_pipe = ath10k_pci_hif_get_default_pipe, 1856 .get_default_pipe = ath10k_pci_hif_get_default_pipe,
1745 .send_complete_check = ath10k_pci_hif_send_complete_check, 1857 .send_complete_check = ath10k_pci_hif_send_complete_check,
1746 .init = ath10k_pci_hif_post_init, 1858 .set_callbacks = ath10k_pci_hif_set_callbacks,
1747 .get_free_queue_number = ath10k_pci_hif_get_free_queue_number, 1859 .get_free_queue_number = ath10k_pci_hif_get_free_queue_number,
1860 .power_up = ath10k_pci_hif_power_up,
1861 .power_down = ath10k_pci_hif_power_down,
1862#ifdef CONFIG_PM
1863 .suspend = ath10k_pci_hif_suspend,
1864 .resume = ath10k_pci_hif_resume,
1865#endif
1748}; 1866};
1749 1867
1750static void ath10k_pci_ce_tasklet(unsigned long ptr) 1868static void ath10k_pci_ce_tasklet(unsigned long ptr)
@@ -2059,9 +2177,9 @@ static int ath10k_pci_reset_target(struct ath10k *ar)
2059 return 0; 2177 return 0;
2060} 2178}
2061 2179
2062static void ath10k_pci_device_reset(struct ath10k_pci *ar_pci) 2180static void ath10k_pci_device_reset(struct ath10k *ar)
2063{ 2181{
2064 struct ath10k *ar = ar_pci->ar; 2182 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2065 void __iomem *mem = ar_pci->mem; 2183 void __iomem *mem = ar_pci->mem;
2066 int i; 2184 int i;
2067 u32 val; 2185 u32 val;
@@ -2118,7 +2236,7 @@ static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci)
2118 case ATH10K_PCI_FEATURE_MSI_X: 2236 case ATH10K_PCI_FEATURE_MSI_X:
2119 ath10k_dbg(ATH10K_DBG_PCI, "device supports MSI-X\n"); 2237 ath10k_dbg(ATH10K_DBG_PCI, "device supports MSI-X\n");
2120 break; 2238 break;
2121 case ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND: 2239 case ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND:
2122 ath10k_dbg(ATH10K_DBG_PCI, "QCA988X_1.0 workaround enabled\n"); 2240 ath10k_dbg(ATH10K_DBG_PCI, "QCA988X_1.0 workaround enabled\n");
2123 break; 2241 break;
2124 } 2242 }
@@ -2145,7 +2263,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2145 2263
2146 switch (pci_dev->device) { 2264 switch (pci_dev->device) {
2147 case QCA988X_1_0_DEVICE_ID: 2265 case QCA988X_1_0_DEVICE_ID:
2148 set_bit(ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND, ar_pci->features); 2266 set_bit(ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND, ar_pci->features);
2149 break; 2267 break;
2150 case QCA988X_2_0_DEVICE_ID: 2268 case QCA988X_2_0_DEVICE_ID:
2151 set_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features); 2269 set_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features);
@@ -2158,8 +2276,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2158 2276
2159 ath10k_pci_dump_features(ar_pci); 2277 ath10k_pci_dump_features(ar_pci);
2160 2278
2161 ar = ath10k_core_create(ar_pci, ar_pci->dev, ATH10K_BUS_PCI, 2279 ar = ath10k_core_create(ar_pci, ar_pci->dev, &ath10k_pci_hif_ops);
2162 &ath10k_pci_hif_ops);
2163 if (!ar) { 2280 if (!ar) {
2164 ath10k_err("ath10k_core_create failed!\n"); 2281 ath10k_err("ath10k_core_create failed!\n");
2165 ret = -EINVAL; 2282 ret = -EINVAL;
@@ -2167,7 +2284,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2167 } 2284 }
2168 2285
2169 /* Enable QCA988X_1.0 HW workarounds */ 2286 /* Enable QCA988X_1.0 HW workarounds */
2170 if (test_bit(ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND, ar_pci->features)) 2287 if (test_bit(ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND, ar_pci->features))
2171 spin_lock_init(&ar_pci->hw_v1_workaround_lock); 2288 spin_lock_init(&ar_pci->hw_v1_workaround_lock);
2172 2289
2173 ar_pci->ar = ar; 2290 ar_pci->ar = ar;
@@ -2247,54 +2364,14 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2247 goto err_iomap; 2364 goto err_iomap;
2248 } 2365 }
2249 2366
2250 /*
2251 * Bring the target up cleanly.
2252 *
2253 * The target may be in an undefined state with an AUX-powered Target
2254 * and a Host in WoW mode. If the Host crashes, loses power, or is
2255 * restarted (without unloading the driver) then the Target is left
2256 * (aux) powered and running. On a subsequent driver load, the Target
2257 * is in an unexpected state. We try to catch that here in order to
2258 * reset the Target and retry the probe.
2259 */
2260 ath10k_pci_device_reset(ar_pci);
2261
2262 ret = ath10k_pci_reset_target(ar);
2263 if (ret)
2264 goto err_intr;
2265
2266 if (ath10k_target_ps) {
2267 ath10k_dbg(ATH10K_DBG_PCI, "on-chip power save enabled\n");
2268 } else {
2269 /* Force AWAKE forever */
2270 ath10k_dbg(ATH10K_DBG_PCI, "on-chip power save disabled\n");
2271 ath10k_do_pci_wake(ar);
2272 }
2273
2274 ret = ath10k_pci_ce_init(ar);
2275 if (ret)
2276 goto err_intr;
2277
2278 ret = ath10k_pci_init_config(ar);
2279 if (ret)
2280 goto err_ce;
2281
2282 ret = ath10k_pci_wake_target_cpu(ar);
2283 if (ret) {
2284 ath10k_err("could not wake up target CPU (%d)\n", ret);
2285 goto err_ce;
2286 }
2287
2288 ret = ath10k_core_register(ar); 2367 ret = ath10k_core_register(ar);
2289 if (ret) { 2368 if (ret) {
2290 ath10k_err("could not register driver core (%d)\n", ret); 2369 ath10k_err("could not register driver core (%d)\n", ret);
2291 goto err_ce; 2370 goto err_intr;
2292 } 2371 }
2293 2372
2294 return 0; 2373 return 0;
2295 2374
2296err_ce:
2297 ath10k_pci_ce_deinit(ar);
2298err_intr: 2375err_intr:
2299 ath10k_pci_stop_intr(ar); 2376 ath10k_pci_stop_intr(ar);
2300err_iomap: 2377err_iomap:
@@ -2345,128 +2422,6 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
2345 kfree(ar_pci); 2422 kfree(ar_pci);
2346} 2423}
2347 2424
2348#if defined(CONFIG_PM_SLEEP)
2349
2350#define ATH10K_PCI_PM_CONTROL 0x44
2351
2352static int ath10k_pci_suspend(struct device *device)
2353{
2354 struct pci_dev *pdev = to_pci_dev(device);
2355 struct ath10k *ar = pci_get_drvdata(pdev);
2356 struct ath10k_pci *ar_pci;
2357 u32 val;
2358 int ret, retval;
2359
2360 ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
2361
2362 if (!ar)
2363 return -ENODEV;
2364
2365 ar_pci = ath10k_pci_priv(ar);
2366 if (!ar_pci)
2367 return -ENODEV;
2368
2369 if (ath10k_core_target_suspend(ar))
2370 return -EBUSY;
2371
2372 ret = wait_event_interruptible_timeout(ar->event_queue,
2373 ar->is_target_paused == true,
2374 1 * HZ);
2375 if (ret < 0) {
2376 ath10k_warn("suspend interrupted (%d)\n", ret);
2377 retval = ret;
2378 goto resume;
2379 } else if (ret == 0) {
2380 ath10k_warn("suspend timed out - target pause event never came\n");
2381 retval = EIO;
2382 goto resume;
2383 }
2384
2385 /*
2386 * reset is_target_paused and host can check that in next time,
2387 * or it will always be TRUE and host just skip the waiting
2388 * condition, it causes target assert due to host already
2389 * suspend
2390 */
2391 ar->is_target_paused = false;
2392
2393 pci_read_config_dword(pdev, ATH10K_PCI_PM_CONTROL, &val);
2394
2395 if ((val & 0x000000ff) != 0x3) {
2396 pci_save_state(pdev);
2397 pci_disable_device(pdev);
2398 pci_write_config_dword(pdev, ATH10K_PCI_PM_CONTROL,
2399 (val & 0xffffff00) | 0x03);
2400 }
2401
2402 return 0;
2403resume:
2404 ret = ath10k_core_target_resume(ar);
2405 if (ret)
2406 ath10k_warn("could not resume (%d)\n", ret);
2407
2408 return retval;
2409}
2410
2411static int ath10k_pci_resume(struct device *device)
2412{
2413 struct pci_dev *pdev = to_pci_dev(device);
2414 struct ath10k *ar = pci_get_drvdata(pdev);
2415 struct ath10k_pci *ar_pci;
2416 int ret;
2417 u32 val;
2418
2419 ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
2420
2421 if (!ar)
2422 return -ENODEV;
2423 ar_pci = ath10k_pci_priv(ar);
2424
2425 if (!ar_pci)
2426 return -ENODEV;
2427
2428 ret = pci_enable_device(pdev);
2429 if (ret) {
2430 ath10k_warn("cannot enable PCI device: %d\n", ret);
2431 return ret;
2432 }
2433
2434 pci_read_config_dword(pdev, ATH10K_PCI_PM_CONTROL, &val);
2435
2436 if ((val & 0x000000ff) != 0) {
2437 pci_restore_state(pdev);
2438 pci_write_config_dword(pdev, ATH10K_PCI_PM_CONTROL,
2439 val & 0xffffff00);
2440 /*
2441 * Suspend/Resume resets the PCI configuration space,
2442 * so we have to re-disable the RETRY_TIMEOUT register (0x41)
2443 * to keep PCI Tx retries from interfering with C3 CPU state
2444 */
2445 pci_read_config_dword(pdev, 0x40, &val);
2446
2447 if ((val & 0x0000ff00) != 0)
2448 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
2449 }
2450
2451 ret = ath10k_core_target_resume(ar);
2452 if (ret)
2453 ath10k_warn("target resume failed: %d\n", ret);
2454
2455 return ret;
2456}
2457
2458static SIMPLE_DEV_PM_OPS(ath10k_dev_pm_ops,
2459 ath10k_pci_suspend,
2460 ath10k_pci_resume);
2461
2462#define ATH10K_PCI_PM_OPS (&ath10k_dev_pm_ops)
2463
2464#else
2465
2466#define ATH10K_PCI_PM_OPS NULL
2467
2468#endif /* CONFIG_PM_SLEEP */
2469
2470MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table); 2425MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table);
2471 2426
2472static struct pci_driver ath10k_pci_driver = { 2427static struct pci_driver ath10k_pci_driver = {
@@ -2474,7 +2429,6 @@ static struct pci_driver ath10k_pci_driver = {
2474 .id_table = ath10k_pci_id_table, 2429 .id_table = ath10k_pci_id_table,
2475 .probe = ath10k_pci_probe, 2430 .probe = ath10k_pci_probe,
2476 .remove = ath10k_pci_remove, 2431 .remove = ath10k_pci_remove,
2477 .driver.pm = ATH10K_PCI_PM_OPS,
2478}; 2432};
2479 2433
2480static int __init ath10k_pci_init(void) 2434static int __init ath10k_pci_init(void)
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index d2a055a07dc6..d3a2e6cc9179 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -152,7 +152,7 @@ struct service_to_pipe {
152 152
153enum ath10k_pci_features { 153enum ath10k_pci_features {
154 ATH10K_PCI_FEATURE_MSI_X = 0, 154 ATH10K_PCI_FEATURE_MSI_X = 0,
155 ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND = 1, 155 ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND = 1,
156 156
157 /* keep last */ 157 /* keep last */
158 ATH10K_PCI_FEATURE_COUNT 158 ATH10K_PCI_FEATURE_COUNT
@@ -311,7 +311,7 @@ static inline void ath10k_pci_write32(struct ath10k *ar, u32 offset,
311 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 311 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
312 void __iomem *addr = ar_pci->mem; 312 void __iomem *addr = ar_pci->mem;
313 313
314 if (test_bit(ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND, ar_pci->features)) { 314 if (test_bit(ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND, ar_pci->features)) {
315 unsigned long irq_flags; 315 unsigned long irq_flags;
316 316
317 spin_lock_irqsave(&ar_pci->hw_v1_workaround_lock, irq_flags); 317 spin_lock_irqsave(&ar_pci->hw_v1_workaround_lock, irq_flags);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 7d4b7987422d..5e4246015cdc 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -27,6 +27,13 @@ void ath10k_wmi_flush_tx(struct ath10k *ar)
27{ 27{
28 int ret; 28 int ret;
29 29
30 lockdep_assert_held(&ar->conf_mutex);
31
32 if (ar->state == ATH10K_STATE_WEDGED) {
33 ath10k_warn("wmi flush skipped - device is wedged anyway\n");
34 return;
35 }
36
30 ret = wait_event_timeout(ar->wmi.wq, 37 ret = wait_event_timeout(ar->wmi.wq,
31 atomic_read(&ar->wmi.pending_tx_count) == 0, 38 atomic_read(&ar->wmi.pending_tx_count) == 0,
32 5*HZ); 39 5*HZ);
@@ -111,7 +118,7 @@ static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb,
111 118
112 trace_ath10k_wmi_cmd(cmd_id, skb->data, skb->len); 119 trace_ath10k_wmi_cmd(cmd_id, skb->data, skb->len);
113 120
114 status = ath10k_htc_send(ar->htc, ar->wmi.eid, skb); 121 status = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb);
115 if (status) { 122 if (status) {
116 dev_kfree_skb_any(skb); 123 dev_kfree_skb_any(skb);
117 atomic_dec(&ar->wmi.pending_tx_count); 124 atomic_dec(&ar->wmi.pending_tx_count);
@@ -501,8 +508,8 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
501 ie = (u8 *)cfg80211_find_ie(WLAN_EID_TIM, ies, 508 ie = (u8 *)cfg80211_find_ie(WLAN_EID_TIM, ies,
502 (u8 *)skb_tail_pointer(bcn) - ies); 509 (u8 *)skb_tail_pointer(bcn) - ies);
503 if (!ie) { 510 if (!ie) {
504 /* highly unlikely for mac80211 */ 511 if (arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
505 ath10k_warn("no tim ie found;\n"); 512 ath10k_warn("no tim ie found;\n");
506 return; 513 return;
507 } 514 }
508 515
@@ -1114,7 +1121,7 @@ int ath10k_wmi_connect_htc_service(struct ath10k *ar)
1114 /* connect to control service */ 1121 /* connect to control service */
1115 conn_req.service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL; 1122 conn_req.service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL;
1116 1123
1117 status = ath10k_htc_connect_service(ar->htc, &conn_req, &conn_resp); 1124 status = ath10k_htc_connect_service(&ar->htc, &conn_req, &conn_resp);
1118 if (status) { 1125 if (status) {
1119 ath10k_warn("failed to connect to WMI CONTROL service status: %d\n", 1126 ath10k_warn("failed to connect to WMI CONTROL service status: %d\n",
1120 status); 1127 status);
@@ -1748,6 +1755,9 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar,
1748 if (arg->key_data) 1755 if (arg->key_data)
1749 memcpy(cmd->key_data, arg->key_data, arg->key_len); 1756 memcpy(cmd->key_data, arg->key_data, arg->key_len);
1750 1757
1758 ath10k_dbg(ATH10K_DBG_WMI,
1759 "wmi vdev install key idx %d cipher %d len %d\n",
1760 arg->key_idx, arg->key_cipher, arg->key_len);
1751 return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_INSTALL_KEY_CMDID); 1761 return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_INSTALL_KEY_CMDID);
1752} 1762}
1753 1763
@@ -2011,6 +2021,9 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar,
2011 cmd->peer_vht_rates.tx_mcs_set = 2021 cmd->peer_vht_rates.tx_mcs_set =
2012 __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set); 2022 __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
2013 2023
2024 ath10k_dbg(ATH10K_DBG_WMI,
2025 "wmi peer assoc vdev %d addr %pM\n",
2026 arg->vdev_id, arg->addr);
2014 return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_ASSOC_CMDID); 2027 return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_ASSOC_CMDID);
2015} 2028}
2016 2029
@@ -2079,3 +2092,22 @@ int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id)
2079 ath10k_dbg(ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); 2092 ath10k_dbg(ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id);
2080 return ath10k_wmi_cmd_send(ar, skb, WMI_REQUEST_STATS_CMDID); 2093 return ath10k_wmi_cmd_send(ar, skb, WMI_REQUEST_STATS_CMDID);
2081} 2094}
2095
2096int ath10k_wmi_force_fw_hang(struct ath10k *ar,
2097 enum wmi_force_fw_hang_type type, u32 delay_ms)
2098{
2099 struct wmi_force_fw_hang_cmd *cmd;
2100 struct sk_buff *skb;
2101
2102 skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
2103 if (!skb)
2104 return -ENOMEM;
2105
2106 cmd = (struct wmi_force_fw_hang_cmd *)skb->data;
2107 cmd->type = __cpu_to_le32(type);
2108 cmd->delay_ms = __cpu_to_le32(delay_ms);
2109
2110 ath10k_dbg(ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n",
2111 type, delay_ms);
2112 return ath10k_wmi_cmd_send(ar, skb, WMI_FORCE_FW_HANG_CMDID);
2113}
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 9555f5a0e041..da3b2bc4c88a 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -416,6 +416,7 @@ enum wmi_cmd_id {
416 WMI_PDEV_FTM_INTG_CMDID, 416 WMI_PDEV_FTM_INTG_CMDID,
417 WMI_VDEV_SET_KEEPALIVE_CMDID, 417 WMI_VDEV_SET_KEEPALIVE_CMDID,
418 WMI_VDEV_GET_KEEPALIVE_CMDID, 418 WMI_VDEV_GET_KEEPALIVE_CMDID,
419 WMI_FORCE_FW_HANG_CMDID,
419 420
420 /* GPIO Configuration */ 421 /* GPIO Configuration */
421 WMI_GPIO_CONFIG_CMDID = WMI_CMD_GRP(WMI_GRP_GPIO), 422 WMI_GPIO_CONFIG_CMDID = WMI_CMD_GRP(WMI_GRP_GPIO),
@@ -2972,6 +2973,22 @@ struct wmi_sta_keepalive_cmd {
2972 struct wmi_sta_keepalive_arp_resp arp_resp; 2973 struct wmi_sta_keepalive_arp_resp arp_resp;
2973} __packed; 2974} __packed;
2974 2975
2976enum wmi_force_fw_hang_type {
2977 WMI_FORCE_FW_HANG_ASSERT = 1,
2978 WMI_FORCE_FW_HANG_NO_DETECT,
2979 WMI_FORCE_FW_HANG_CTRL_EP_FULL,
2980 WMI_FORCE_FW_HANG_EMPTY_POINT,
2981 WMI_FORCE_FW_HANG_STACK_OVERFLOW,
2982 WMI_FORCE_FW_HANG_INFINITE_LOOP,
2983};
2984
2985#define WMI_FORCE_FW_HANG_RANDOM_TIME 0xFFFFFFFF
2986
2987struct wmi_force_fw_hang_cmd {
2988 __le32 type;
2989 __le32 delay_ms;
2990} __packed;
2991
2975#define ATH10K_RTS_MAX 2347 2992#define ATH10K_RTS_MAX 2347
2976#define ATH10K_FRAGMT_THRESHOLD_MIN 540 2993#define ATH10K_FRAGMT_THRESHOLD_MIN 540
2977#define ATH10K_FRAGMT_THRESHOLD_MAX 2346 2994#define ATH10K_FRAGMT_THRESHOLD_MAX 2346
@@ -3048,5 +3065,7 @@ int ath10k_wmi_beacon_send(struct ath10k *ar, const struct wmi_bcn_tx_arg *arg);
3048int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, 3065int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
3049 const struct wmi_pdev_set_wmm_params_arg *arg); 3066 const struct wmi_pdev_set_wmm_params_arg *arg);
3050int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id); 3067int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id);
3068int ath10k_wmi_force_fw_hang(struct ath10k *ar,
3069 enum wmi_force_fw_hang_type type, u32 delay_ms);
3051 3070
3052#endif /* _WMI_H_ */ 3071#endif /* _WMI_H_ */
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index d491a3178986..c91bc6111c23 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -96,6 +96,16 @@ config ATH9K_LEGACY_RATE_CONTROL
96 has to be passed to mac80211 using the module parameter, 96 has to be passed to mac80211 using the module parameter,
97 ieee80211_default_rc_algo. 97 ieee80211_default_rc_algo.
98 98
99config ATH9K_RFKILL
100 bool "Atheros ath9k rfkill support" if EXPERT
101 depends on ATH9K
102 depends on RFKILL=y || RFKILL=ATH9K
103 default y
104 help
105 Say Y to have ath9k poll the RF-Kill GPIO every couple of
106 seconds. Turn off to save power, but enable it if you have
107 a platform that can toggle the RF-Kill GPIO.
108
99config ATH9K_HTC 109config ATH9K_HTC
100 tristate "Atheros HTC based wireless cards support" 110 tristate "Atheros HTC based wireless cards support"
101 depends on USB && MAC80211 111 depends on USB && MAC80211
diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c
index 664844c5d3d5..dd1cc73d7946 100644
--- a/drivers/net/wireless/ath/ath9k/antenna.c
+++ b/drivers/net/wireless/ath/ath9k/antenna.c
@@ -16,37 +16,119 @@
16 16
17#include "ath9k.h" 17#include "ath9k.h"
18 18
19static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, 19/*
20 * AR9285
21 * ======
22 *
23 * EEPROM has 2 4-bit fields containing the card configuration.
24 *
25 * antdiv_ctl1:
26 * ------------
27 * bb_enable_ant_div_lnadiv : 1
28 * bb_ant_div_alt_gaintb : 1
29 * bb_ant_div_main_gaintb : 1
30 * bb_enable_ant_fast_div : 1
31 *
32 * antdiv_ctl2:
33 * -----------
34 * bb_ant_div_alt_lnaconf : 2
35 * bb_ant_div_main_lnaconf : 2
36 *
37 * The EEPROM bits are used as follows:
38 * ------------------------------------
39 *
40 * bb_enable_ant_div_lnadiv - Enable LNA path rx antenna diversity/combining.
41 * Set in AR_PHY_MULTICHAIN_GAIN_CTL.
42 *
43 * bb_ant_div_[alt/main]_gaintb - 0 -> Antenna config Alt/Main uses gaintable 0
44 * 1 -> Antenna config Alt/Main uses gaintable 1
45 * Set in AR_PHY_MULTICHAIN_GAIN_CTL.
46 *
47 * bb_enable_ant_fast_div - Enable fast antenna diversity.
48 * Set in AR_PHY_CCK_DETECT.
49 *
50 * bb_ant_div_[alt/main]_lnaconf - Alt/Main LNA diversity/combining input config.
51 * Set in AR_PHY_MULTICHAIN_GAIN_CTL.
52 * 10=LNA1
53 * 01=LNA2
54 * 11=LNA1+LNA2
55 * 00=LNA1-LNA2
56 *
57 * AR9485 / AR9565 / AR9331
58 * ========================
59 *
60 * The same bits are present in the EEPROM, but the location in the
61 * EEPROM is different (ant_div_control in ar9300_BaseExtension_1).
62 *
63 * ant_div_alt_lnaconf ==> bit 0~1
64 * ant_div_main_lnaconf ==> bit 2~3
65 * ant_div_alt_gaintb ==> bit 4
66 * ant_div_main_gaintb ==> bit 5
67 * enable_ant_div_lnadiv ==> bit 6
68 * enable_ant_fast_div ==> bit 7
69 */
70
71static inline bool ath_is_alt_ant_ratio_better(struct ath_ant_comb *antcomb,
72 int alt_ratio, int maxdelta,
20 int mindelta, int main_rssi_avg, 73 int mindelta, int main_rssi_avg,
21 int alt_rssi_avg, int pkt_count) 74 int alt_rssi_avg, int pkt_count)
22{ 75{
23 return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && 76 if (pkt_count <= 50)
24 (alt_rssi_avg > main_rssi_avg + maxdelta)) || 77 return false;
25 (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); 78
79 if (alt_rssi_avg > main_rssi_avg + mindelta)
80 return true;
81
82 if (alt_ratio >= antcomb->ant_ratio2 &&
83 alt_rssi_avg >= antcomb->low_rssi_thresh &&
84 (alt_rssi_avg > main_rssi_avg + maxdelta))
85 return true;
86
87 return false;
26} 88}
27 89
28static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, 90static inline bool ath_ant_div_comb_alt_check(struct ath_hw_antcomb_conf *conf,
29 int curr_main_set, int curr_alt_set, 91 struct ath_ant_comb *antcomb,
30 int alt_rssi_avg, int main_rssi_avg) 92 int alt_ratio, int alt_rssi_avg,
93 int main_rssi_avg)
31{ 94{
32 bool result = false; 95 bool result, set1, set2;
33 switch (div_group) { 96
97 result = set1 = set2 = false;
98
99 if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2 &&
100 conf->alt_lna_conf == ATH_ANT_DIV_COMB_LNA1)
101 set1 = true;
102
103 if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA1 &&
104 conf->alt_lna_conf == ATH_ANT_DIV_COMB_LNA2)
105 set2 = true;
106
107 switch (conf->div_group) {
34 case 0: 108 case 0:
35 if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) 109 if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
36 result = true; 110 result = true;
37 break; 111 break;
38 case 1: 112 case 1:
39 case 2: 113 case 2:
40 if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && 114 if (alt_rssi_avg < 4 || alt_rssi_avg < antcomb->low_rssi_thresh)
41 (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && 115 break;
42 (alt_rssi_avg >= (main_rssi_avg - 5))) || 116
43 ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) && 117 if ((set1 && (alt_rssi_avg >= (main_rssi_avg - 5))) ||
44 (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) && 118 (set2 && (alt_rssi_avg >= (main_rssi_avg - 2))) ||
45 (alt_rssi_avg >= (main_rssi_avg - 2)))) && 119 (alt_ratio > antcomb->ant_ratio))
46 (alt_rssi_avg >= 4))
47 result = true; 120 result = true;
48 else 121
49 result = false; 122 break;
123 case 3:
124 if (alt_rssi_avg < 4 || alt_rssi_avg < antcomb->low_rssi_thresh)
125 break;
126
127 if ((set1 && (alt_rssi_avg >= (main_rssi_avg - 3))) ||
128 (set2 && (alt_rssi_avg >= (main_rssi_avg + 3))) ||
129 (alt_ratio > antcomb->ant_ratio))
130 result = true;
131
50 break; 132 break;
51 } 133 }
52 134
@@ -108,6 +190,74 @@ static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb,
108 } 190 }
109} 191}
110 192
193static void ath_ant_set_alt_ratio(struct ath_ant_comb *antcomb,
194 struct ath_hw_antcomb_conf *conf)
195{
196 /* set alt to the conf with maximun ratio */
197 if (antcomb->first_ratio && antcomb->second_ratio) {
198 if (antcomb->rssi_second > antcomb->rssi_third) {
199 /* first alt*/
200 if ((antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
201 (antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2))
202 /* Set alt LNA1 or LNA2*/
203 if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
204 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
205 else
206 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
207 else
208 /* Set alt to A+B or A-B */
209 conf->alt_lna_conf =
210 antcomb->first_quick_scan_conf;
211 } else if ((antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
212 (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2)) {
213 /* Set alt LNA1 or LNA2 */
214 if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
215 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
216 else
217 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
218 } else {
219 /* Set alt to A+B or A-B */
220 conf->alt_lna_conf = antcomb->second_quick_scan_conf;
221 }
222 } else if (antcomb->first_ratio) {
223 /* first alt */
224 if ((antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
225 (antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2))
226 /* Set alt LNA1 or LNA2 */
227 if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
228 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
229 else
230 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
231 else
232 /* Set alt to A+B or A-B */
233 conf->alt_lna_conf = antcomb->first_quick_scan_conf;
234 } else if (antcomb->second_ratio) {
235 /* second alt */
236 if ((antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
237 (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2))
238 /* Set alt LNA1 or LNA2 */
239 if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
240 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
241 else
242 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
243 else
244 /* Set alt to A+B or A-B */
245 conf->alt_lna_conf = antcomb->second_quick_scan_conf;
246 } else {
247 /* main is largest */
248 if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) ||
249 (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2))
250 /* Set alt LNA1 or LNA2 */
251 if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
252 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
253 else
254 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
255 else
256 /* Set alt to A+B or A-B */
257 conf->alt_lna_conf = antcomb->main_conf;
258 }
259}
260
111static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, 261static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
112 struct ath_hw_antcomb_conf *div_ant_conf, 262 struct ath_hw_antcomb_conf *div_ant_conf,
113 int main_rssi_avg, int alt_rssi_avg, 263 int main_rssi_avg, int alt_rssi_avg,
@@ -129,7 +279,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
129 279
130 if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { 280 if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
131 /* main is LNA1 */ 281 /* main is LNA1 */
132 if (ath_is_alt_ant_ratio_better(alt_ratio, 282 if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
133 ATH_ANT_DIV_COMB_LNA1_DELTA_HI, 283 ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
134 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, 284 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
135 main_rssi_avg, alt_rssi_avg, 285 main_rssi_avg, alt_rssi_avg,
@@ -138,7 +288,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
138 else 288 else
139 antcomb->first_ratio = false; 289 antcomb->first_ratio = false;
140 } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { 290 } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) {
141 if (ath_is_alt_ant_ratio_better(alt_ratio, 291 if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
142 ATH_ANT_DIV_COMB_LNA1_DELTA_MID, 292 ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
143 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, 293 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
144 main_rssi_avg, alt_rssi_avg, 294 main_rssi_avg, alt_rssi_avg,
@@ -147,11 +297,11 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
147 else 297 else
148 antcomb->first_ratio = false; 298 antcomb->first_ratio = false;
149 } else { 299 } else {
150 if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && 300 if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
151 (alt_rssi_avg > main_rssi_avg + 301 ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
152 ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || 302 0,
153 (alt_rssi_avg > main_rssi_avg)) && 303 main_rssi_avg, alt_rssi_avg,
154 (antcomb->total_pkt_count > 50)) 304 antcomb->total_pkt_count))
155 antcomb->first_ratio = true; 305 antcomb->first_ratio = true;
156 else 306 else
157 antcomb->first_ratio = false; 307 antcomb->first_ratio = false;
@@ -164,17 +314,21 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
164 antcomb->rssi_first = main_rssi_avg; 314 antcomb->rssi_first = main_rssi_avg;
165 antcomb->rssi_third = alt_rssi_avg; 315 antcomb->rssi_third = alt_rssi_avg;
166 316
167 if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) 317 switch(antcomb->second_quick_scan_conf) {
318 case ATH_ANT_DIV_COMB_LNA1:
168 antcomb->rssi_lna1 = alt_rssi_avg; 319 antcomb->rssi_lna1 = alt_rssi_avg;
169 else if (antcomb->second_quick_scan_conf == 320 break;
170 ATH_ANT_DIV_COMB_LNA2) 321 case ATH_ANT_DIV_COMB_LNA2:
171 antcomb->rssi_lna2 = alt_rssi_avg; 322 antcomb->rssi_lna2 = alt_rssi_avg;
172 else if (antcomb->second_quick_scan_conf == 323 break;
173 ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) { 324 case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2:
174 if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) 325 if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)
175 antcomb->rssi_lna2 = main_rssi_avg; 326 antcomb->rssi_lna2 = main_rssi_avg;
176 else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) 327 else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1)
177 antcomb->rssi_lna1 = main_rssi_avg; 328 antcomb->rssi_lna1 = main_rssi_avg;
329 break;
330 default:
331 break;
178 } 332 }
179 333
180 if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + 334 if (antcomb->rssi_lna2 > antcomb->rssi_lna1 +
@@ -184,7 +338,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
184 div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; 338 div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
185 339
186 if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { 340 if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
187 if (ath_is_alt_ant_ratio_better(alt_ratio, 341 if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
188 ATH_ANT_DIV_COMB_LNA1_DELTA_HI, 342 ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
189 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, 343 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
190 main_rssi_avg, alt_rssi_avg, 344 main_rssi_avg, alt_rssi_avg,
@@ -193,7 +347,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
193 else 347 else
194 antcomb->second_ratio = false; 348 antcomb->second_ratio = false;
195 } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { 349 } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) {
196 if (ath_is_alt_ant_ratio_better(alt_ratio, 350 if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
197 ATH_ANT_DIV_COMB_LNA1_DELTA_MID, 351 ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
198 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, 352 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
199 main_rssi_avg, alt_rssi_avg, 353 main_rssi_avg, alt_rssi_avg,
@@ -202,105 +356,18 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
202 else 356 else
203 antcomb->second_ratio = false; 357 antcomb->second_ratio = false;
204 } else { 358 } else {
205 if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && 359 if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
206 (alt_rssi_avg > main_rssi_avg + 360 ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
207 ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || 361 0,
208 (alt_rssi_avg > main_rssi_avg)) && 362 main_rssi_avg, alt_rssi_avg,
209 (antcomb->total_pkt_count > 50)) 363 antcomb->total_pkt_count))
210 antcomb->second_ratio = true; 364 antcomb->second_ratio = true;
211 else 365 else
212 antcomb->second_ratio = false; 366 antcomb->second_ratio = false;
213 } 367 }
214 368
215 /* set alt to the conf with maximun ratio */ 369 ath_ant_set_alt_ratio(antcomb, div_ant_conf);
216 if (antcomb->first_ratio && antcomb->second_ratio) { 370
217 if (antcomb->rssi_second > antcomb->rssi_third) {
218 /* first alt*/
219 if ((antcomb->first_quick_scan_conf ==
220 ATH_ANT_DIV_COMB_LNA1) ||
221 (antcomb->first_quick_scan_conf ==
222 ATH_ANT_DIV_COMB_LNA2))
223 /* Set alt LNA1 or LNA2*/
224 if (div_ant_conf->main_lna_conf ==
225 ATH_ANT_DIV_COMB_LNA2)
226 div_ant_conf->alt_lna_conf =
227 ATH_ANT_DIV_COMB_LNA1;
228 else
229 div_ant_conf->alt_lna_conf =
230 ATH_ANT_DIV_COMB_LNA2;
231 else
232 /* Set alt to A+B or A-B */
233 div_ant_conf->alt_lna_conf =
234 antcomb->first_quick_scan_conf;
235 } else if ((antcomb->second_quick_scan_conf ==
236 ATH_ANT_DIV_COMB_LNA1) ||
237 (antcomb->second_quick_scan_conf ==
238 ATH_ANT_DIV_COMB_LNA2)) {
239 /* Set alt LNA1 or LNA2 */
240 if (div_ant_conf->main_lna_conf ==
241 ATH_ANT_DIV_COMB_LNA2)
242 div_ant_conf->alt_lna_conf =
243 ATH_ANT_DIV_COMB_LNA1;
244 else
245 div_ant_conf->alt_lna_conf =
246 ATH_ANT_DIV_COMB_LNA2;
247 } else {
248 /* Set alt to A+B or A-B */
249 div_ant_conf->alt_lna_conf =
250 antcomb->second_quick_scan_conf;
251 }
252 } else if (antcomb->first_ratio) {
253 /* first alt */
254 if ((antcomb->first_quick_scan_conf ==
255 ATH_ANT_DIV_COMB_LNA1) ||
256 (antcomb->first_quick_scan_conf ==
257 ATH_ANT_DIV_COMB_LNA2))
258 /* Set alt LNA1 or LNA2 */
259 if (div_ant_conf->main_lna_conf ==
260 ATH_ANT_DIV_COMB_LNA2)
261 div_ant_conf->alt_lna_conf =
262 ATH_ANT_DIV_COMB_LNA1;
263 else
264 div_ant_conf->alt_lna_conf =
265 ATH_ANT_DIV_COMB_LNA2;
266 else
267 /* Set alt to A+B or A-B */
268 div_ant_conf->alt_lna_conf =
269 antcomb->first_quick_scan_conf;
270 } else if (antcomb->second_ratio) {
271 /* second alt */
272 if ((antcomb->second_quick_scan_conf ==
273 ATH_ANT_DIV_COMB_LNA1) ||
274 (antcomb->second_quick_scan_conf ==
275 ATH_ANT_DIV_COMB_LNA2))
276 /* Set alt LNA1 or LNA2 */
277 if (div_ant_conf->main_lna_conf ==
278 ATH_ANT_DIV_COMB_LNA2)
279 div_ant_conf->alt_lna_conf =
280 ATH_ANT_DIV_COMB_LNA1;
281 else
282 div_ant_conf->alt_lna_conf =
283 ATH_ANT_DIV_COMB_LNA2;
284 else
285 /* Set alt to A+B or A-B */
286 div_ant_conf->alt_lna_conf =
287 antcomb->second_quick_scan_conf;
288 } else {
289 /* main is largest */
290 if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) ||
291 (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2))
292 /* Set alt LNA1 or LNA2 */
293 if (div_ant_conf->main_lna_conf ==
294 ATH_ANT_DIV_COMB_LNA2)
295 div_ant_conf->alt_lna_conf =
296 ATH_ANT_DIV_COMB_LNA1;
297 else
298 div_ant_conf->alt_lna_conf =
299 ATH_ANT_DIV_COMB_LNA2;
300 else
301 /* Set alt to A+B or A-B */
302 div_ant_conf->alt_lna_conf = antcomb->main_conf;
303 }
304 break; 371 break;
305 default: 372 default:
306 break; 373 break;
@@ -430,8 +497,7 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
430 ant_conf->fast_div_bias = 0x1; 497 ant_conf->fast_div_bias = 0x1;
431 break; 498 break;
432 case 0x10: /* LNA2 A-B */ 499 case 0x10: /* LNA2 A-B */
433 if (!(antcomb->scan) && 500 if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
434 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
435 ant_conf->fast_div_bias = 0x1; 501 ant_conf->fast_div_bias = 0x1;
436 else 502 else
437 ant_conf->fast_div_bias = 0x2; 503 ant_conf->fast_div_bias = 0x2;
@@ -440,15 +506,13 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
440 ant_conf->fast_div_bias = 0x1; 506 ant_conf->fast_div_bias = 0x1;
441 break; 507 break;
442 case 0x13: /* LNA2 A+B */ 508 case 0x13: /* LNA2 A+B */
443 if (!(antcomb->scan) && 509 if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
444 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
445 ant_conf->fast_div_bias = 0x1; 510 ant_conf->fast_div_bias = 0x1;
446 else 511 else
447 ant_conf->fast_div_bias = 0x2; 512 ant_conf->fast_div_bias = 0x2;
448 break; 513 break;
449 case 0x20: /* LNA1 A-B */ 514 case 0x20: /* LNA1 A-B */
450 if (!(antcomb->scan) && 515 if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
451 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
452 ant_conf->fast_div_bias = 0x1; 516 ant_conf->fast_div_bias = 0x1;
453 else 517 else
454 ant_conf->fast_div_bias = 0x2; 518 ant_conf->fast_div_bias = 0x2;
@@ -457,8 +521,7 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
457 ant_conf->fast_div_bias = 0x1; 521 ant_conf->fast_div_bias = 0x1;
458 break; 522 break;
459 case 0x23: /* LNA1 A+B */ 523 case 0x23: /* LNA1 A+B */
460 if (!(antcomb->scan) && 524 if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
461 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
462 ant_conf->fast_div_bias = 0x1; 525 ant_conf->fast_div_bias = 0x1;
463 else 526 else
464 ant_conf->fast_div_bias = 0x2; 527 ant_conf->fast_div_bias = 0x2;
@@ -475,6 +538,9 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
475 default: 538 default:
476 break; 539 break;
477 } 540 }
541
542 if (antcomb->fast_div_bias)
543 ant_conf->fast_div_bias = antcomb->fast_div_bias;
478 } else if (ant_conf->div_group == 3) { 544 } else if (ant_conf->div_group == 3) {
479 switch ((ant_conf->main_lna_conf << 4) | 545 switch ((ant_conf->main_lna_conf << 4) |
480 ant_conf->alt_lna_conf) { 546 ant_conf->alt_lna_conf) {
@@ -540,6 +606,138 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
540 } 606 }
541} 607}
542 608
609static void ath_ant_try_scan(struct ath_ant_comb *antcomb,
610 struct ath_hw_antcomb_conf *conf,
611 int curr_alt_set, int alt_rssi_avg,
612 int main_rssi_avg)
613{
614 switch (curr_alt_set) {
615 case ATH_ANT_DIV_COMB_LNA2:
616 antcomb->rssi_lna2 = alt_rssi_avg;
617 antcomb->rssi_lna1 = main_rssi_avg;
618 antcomb->scan = true;
619 /* set to A+B */
620 conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
621 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
622 break;
623 case ATH_ANT_DIV_COMB_LNA1:
624 antcomb->rssi_lna1 = alt_rssi_avg;
625 antcomb->rssi_lna2 = main_rssi_avg;
626 antcomb->scan = true;
627 /* set to A+B */
628 conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
629 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
630 break;
631 case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2:
632 antcomb->rssi_add = alt_rssi_avg;
633 antcomb->scan = true;
634 /* set to A-B */
635 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
636 break;
637 case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2:
638 antcomb->rssi_sub = alt_rssi_avg;
639 antcomb->scan = false;
640 if (antcomb->rssi_lna2 >
641 (antcomb->rssi_lna1 + ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) {
642 /* use LNA2 as main LNA */
643 if ((antcomb->rssi_add > antcomb->rssi_lna1) &&
644 (antcomb->rssi_add > antcomb->rssi_sub)) {
645 /* set to A+B */
646 conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
647 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
648 } else if (antcomb->rssi_sub >
649 antcomb->rssi_lna1) {
650 /* set to A-B */
651 conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
652 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
653 } else {
654 /* set to LNA1 */
655 conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
656 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
657 }
658 } else {
659 /* use LNA1 as main LNA */
660 if ((antcomb->rssi_add > antcomb->rssi_lna2) &&
661 (antcomb->rssi_add > antcomb->rssi_sub)) {
662 /* set to A+B */
663 conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
664 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
665 } else if (antcomb->rssi_sub >
666 antcomb->rssi_lna1) {
667 /* set to A-B */
668 conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
669 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
670 } else {
671 /* set to LNA2 */
672 conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
673 conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
674 }
675 }
676 break;
677 default:
678 break;
679 }
680}
681
682static bool ath_ant_try_switch(struct ath_hw_antcomb_conf *div_ant_conf,
683 struct ath_ant_comb *antcomb,
684 int alt_ratio, int alt_rssi_avg,
685 int main_rssi_avg, int curr_main_set,
686 int curr_alt_set)
687{
688 bool ret = false;
689
690 if (ath_ant_div_comb_alt_check(div_ant_conf, antcomb, alt_ratio,
691 alt_rssi_avg, main_rssi_avg)) {
692 if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
693 /*
694 * Switch main and alt LNA.
695 */
696 div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
697 div_ant_conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
698 } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) {
699 div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
700 div_ant_conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
701 }
702
703 ret = true;
704 } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) &&
705 (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) {
706 /*
707 Set alt to another LNA.
708 */
709 if (curr_main_set == ATH_ANT_DIV_COMB_LNA2)
710 div_ant_conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
711 else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1)
712 div_ant_conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
713
714 ret = true;
715 }
716
717 return ret;
718}
719
720static bool ath_ant_short_scan_check(struct ath_ant_comb *antcomb)
721{
722 int alt_ratio;
723
724 if (!antcomb->scan || !antcomb->alt_good)
725 return false;
726
727 if (time_after(jiffies, antcomb->scan_start_time +
728 msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR)))
729 return true;
730
731 if (antcomb->total_pkt_count == ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) {
732 alt_ratio = ((antcomb->alt_recv_cnt * 100) /
733 antcomb->total_pkt_count);
734 if (alt_ratio < antcomb->ant_ratio)
735 return true;
736 }
737
738 return false;
739}
740
543void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) 741void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
544{ 742{
545 struct ath_hw_antcomb_conf div_ant_conf; 743 struct ath_hw_antcomb_conf div_ant_conf;
@@ -549,41 +747,46 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
549 int main_rssi = rs->rs_rssi_ctl0; 747 int main_rssi = rs->rs_rssi_ctl0;
550 int alt_rssi = rs->rs_rssi_ctl1; 748 int alt_rssi = rs->rs_rssi_ctl1;
551 int rx_ant_conf, main_ant_conf; 749 int rx_ant_conf, main_ant_conf;
552 bool short_scan = false; 750 bool short_scan = false, ret;
553 751
554 rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & 752 rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
555 ATH_ANT_RX_MASK; 753 ATH_ANT_RX_MASK;
556 main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & 754 main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
557 ATH_ANT_RX_MASK; 755 ATH_ANT_RX_MASK;
558 756
757 if (alt_rssi >= antcomb->low_rssi_thresh) {
758 antcomb->ant_ratio = ATH_ANT_DIV_COMB_ALT_ANT_RATIO;
759 antcomb->ant_ratio2 = ATH_ANT_DIV_COMB_ALT_ANT_RATIO2;
760 } else {
761 antcomb->ant_ratio = ATH_ANT_DIV_COMB_ALT_ANT_RATIO_LOW_RSSI;
762 antcomb->ant_ratio2 = ATH_ANT_DIV_COMB_ALT_ANT_RATIO2_LOW_RSSI;
763 }
764
559 /* Record packet only when both main_rssi and alt_rssi is positive */ 765 /* Record packet only when both main_rssi and alt_rssi is positive */
560 if (main_rssi > 0 && alt_rssi > 0) { 766 if (main_rssi > 0 && alt_rssi > 0) {
561 antcomb->total_pkt_count++; 767 antcomb->total_pkt_count++;
562 antcomb->main_total_rssi += main_rssi; 768 antcomb->main_total_rssi += main_rssi;
563 antcomb->alt_total_rssi += alt_rssi; 769 antcomb->alt_total_rssi += alt_rssi;
770
564 if (main_ant_conf == rx_ant_conf) 771 if (main_ant_conf == rx_ant_conf)
565 antcomb->main_recv_cnt++; 772 antcomb->main_recv_cnt++;
566 else 773 else
567 antcomb->alt_recv_cnt++; 774 antcomb->alt_recv_cnt++;
568 } 775 }
569 776
570 /* Short scan check */ 777 if (main_ant_conf == rx_ant_conf) {
571 if (antcomb->scan && antcomb->alt_good) { 778 ANT_STAT_INC(ANT_MAIN, recv_cnt);
572 if (time_after(jiffies, antcomb->scan_start_time + 779 ANT_LNA_INC(ANT_MAIN, rx_ant_conf);
573 msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR))) 780 } else {
574 short_scan = true; 781 ANT_STAT_INC(ANT_ALT, recv_cnt);
575 else 782 ANT_LNA_INC(ANT_ALT, rx_ant_conf);
576 if (antcomb->total_pkt_count ==
577 ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) {
578 alt_ratio = ((antcomb->alt_recv_cnt * 100) /
579 antcomb->total_pkt_count);
580 if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
581 short_scan = true;
582 }
583 } 783 }
584 784
785 /* Short scan check */
786 short_scan = ath_ant_short_scan_check(antcomb);
787
585 if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) || 788 if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) ||
586 rs->rs_moreaggr) && !short_scan) 789 rs->rs_moreaggr) && !short_scan)
587 return; 790 return;
588 791
589 if (antcomb->total_pkt_count) { 792 if (antcomb->total_pkt_count) {
@@ -595,15 +798,13 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
595 antcomb->total_pkt_count); 798 antcomb->total_pkt_count);
596 } 799 }
597 800
598
599 ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); 801 ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf);
600 curr_alt_set = div_ant_conf.alt_lna_conf; 802 curr_alt_set = div_ant_conf.alt_lna_conf;
601 curr_main_set = div_ant_conf.main_lna_conf; 803 curr_main_set = div_ant_conf.main_lna_conf;
602
603 antcomb->count++; 804 antcomb->count++;
604 805
605 if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) { 806 if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) {
606 if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { 807 if (alt_ratio > antcomb->ant_ratio) {
607 ath_lnaconf_alt_good_scan(antcomb, div_ant_conf, 808 ath_lnaconf_alt_good_scan(antcomb, div_ant_conf,
608 main_rssi_avg); 809 main_rssi_avg);
609 antcomb->alt_good = true; 810 antcomb->alt_good = true;
@@ -617,153 +818,47 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
617 } 818 }
618 819
619 if (!antcomb->scan) { 820 if (!antcomb->scan) {
620 if (ath_ant_div_comb_alt_check(div_ant_conf.div_group, 821 ret = ath_ant_try_switch(&div_ant_conf, antcomb, alt_ratio,
621 alt_ratio, curr_main_set, curr_alt_set, 822 alt_rssi_avg, main_rssi_avg,
622 alt_rssi_avg, main_rssi_avg)) { 823 curr_main_set, curr_alt_set);
623 if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { 824 if (ret)
624 /* Switch main and alt LNA */
625 div_ant_conf.main_lna_conf =
626 ATH_ANT_DIV_COMB_LNA2;
627 div_ant_conf.alt_lna_conf =
628 ATH_ANT_DIV_COMB_LNA1;
629 } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) {
630 div_ant_conf.main_lna_conf =
631 ATH_ANT_DIV_COMB_LNA1;
632 div_ant_conf.alt_lna_conf =
633 ATH_ANT_DIV_COMB_LNA2;
634 }
635
636 goto div_comb_done;
637 } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) &&
638 (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) {
639 /* Set alt to another LNA */
640 if (curr_main_set == ATH_ANT_DIV_COMB_LNA2)
641 div_ant_conf.alt_lna_conf =
642 ATH_ANT_DIV_COMB_LNA1;
643 else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1)
644 div_ant_conf.alt_lna_conf =
645 ATH_ANT_DIV_COMB_LNA2;
646
647 goto div_comb_done;
648 }
649
650 if ((alt_rssi_avg < (main_rssi_avg +
651 div_ant_conf.lna1_lna2_delta)))
652 goto div_comb_done; 825 goto div_comb_done;
653 } 826 }
654 827
828 if (!antcomb->scan &&
829 (alt_rssi_avg < (main_rssi_avg + div_ant_conf.lna1_lna2_delta)))
830 goto div_comb_done;
831
655 if (!antcomb->scan_not_start) { 832 if (!antcomb->scan_not_start) {
656 switch (curr_alt_set) { 833 ath_ant_try_scan(antcomb, &div_ant_conf, curr_alt_set,
657 case ATH_ANT_DIV_COMB_LNA2: 834 alt_rssi_avg, main_rssi_avg);
658 antcomb->rssi_lna2 = alt_rssi_avg;
659 antcomb->rssi_lna1 = main_rssi_avg;
660 antcomb->scan = true;
661 /* set to A+B */
662 div_ant_conf.main_lna_conf =
663 ATH_ANT_DIV_COMB_LNA1;
664 div_ant_conf.alt_lna_conf =
665 ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
666 break;
667 case ATH_ANT_DIV_COMB_LNA1:
668 antcomb->rssi_lna1 = alt_rssi_avg;
669 antcomb->rssi_lna2 = main_rssi_avg;
670 antcomb->scan = true;
671 /* set to A+B */
672 div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
673 div_ant_conf.alt_lna_conf =
674 ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
675 break;
676 case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2:
677 antcomb->rssi_add = alt_rssi_avg;
678 antcomb->scan = true;
679 /* set to A-B */
680 div_ant_conf.alt_lna_conf =
681 ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
682 break;
683 case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2:
684 antcomb->rssi_sub = alt_rssi_avg;
685 antcomb->scan = false;
686 if (antcomb->rssi_lna2 >
687 (antcomb->rssi_lna1 +
688 ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) {
689 /* use LNA2 as main LNA */
690 if ((antcomb->rssi_add > antcomb->rssi_lna1) &&
691 (antcomb->rssi_add > antcomb->rssi_sub)) {
692 /* set to A+B */
693 div_ant_conf.main_lna_conf =
694 ATH_ANT_DIV_COMB_LNA2;
695 div_ant_conf.alt_lna_conf =
696 ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
697 } else if (antcomb->rssi_sub >
698 antcomb->rssi_lna1) {
699 /* set to A-B */
700 div_ant_conf.main_lna_conf =
701 ATH_ANT_DIV_COMB_LNA2;
702 div_ant_conf.alt_lna_conf =
703 ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
704 } else {
705 /* set to LNA1 */
706 div_ant_conf.main_lna_conf =
707 ATH_ANT_DIV_COMB_LNA2;
708 div_ant_conf.alt_lna_conf =
709 ATH_ANT_DIV_COMB_LNA1;
710 }
711 } else {
712 /* use LNA1 as main LNA */
713 if ((antcomb->rssi_add > antcomb->rssi_lna2) &&
714 (antcomb->rssi_add > antcomb->rssi_sub)) {
715 /* set to A+B */
716 div_ant_conf.main_lna_conf =
717 ATH_ANT_DIV_COMB_LNA1;
718 div_ant_conf.alt_lna_conf =
719 ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
720 } else if (antcomb->rssi_sub >
721 antcomb->rssi_lna1) {
722 /* set to A-B */
723 div_ant_conf.main_lna_conf =
724 ATH_ANT_DIV_COMB_LNA1;
725 div_ant_conf.alt_lna_conf =
726 ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
727 } else {
728 /* set to LNA2 */
729 div_ant_conf.main_lna_conf =
730 ATH_ANT_DIV_COMB_LNA1;
731 div_ant_conf.alt_lna_conf =
732 ATH_ANT_DIV_COMB_LNA2;
733 }
734 }
735 break;
736 default:
737 break;
738 }
739 } else { 835 } else {
740 if (!antcomb->alt_good) { 836 if (!antcomb->alt_good) {
741 antcomb->scan_not_start = false; 837 antcomb->scan_not_start = false;
742 /* Set alt to another LNA */ 838 /* Set alt to another LNA */
743 if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) { 839 if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) {
744 div_ant_conf.main_lna_conf = 840 div_ant_conf.main_lna_conf =
745 ATH_ANT_DIV_COMB_LNA2; 841 ATH_ANT_DIV_COMB_LNA2;
746 div_ant_conf.alt_lna_conf = 842 div_ant_conf.alt_lna_conf =
747 ATH_ANT_DIV_COMB_LNA1; 843 ATH_ANT_DIV_COMB_LNA1;
748 } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) { 844 } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) {
749 div_ant_conf.main_lna_conf = 845 div_ant_conf.main_lna_conf =
750 ATH_ANT_DIV_COMB_LNA1; 846 ATH_ANT_DIV_COMB_LNA1;
751 div_ant_conf.alt_lna_conf = 847 div_ant_conf.alt_lna_conf =
752 ATH_ANT_DIV_COMB_LNA2; 848 ATH_ANT_DIV_COMB_LNA2;
753 } 849 }
754 goto div_comb_done; 850 goto div_comb_done;
755 } 851 }
852 ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf,
853 main_rssi_avg, alt_rssi_avg,
854 alt_ratio);
855 antcomb->quick_scan_cnt++;
756 } 856 }
757 857
758 ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf,
759 main_rssi_avg, alt_rssi_avg,
760 alt_ratio);
761
762 antcomb->quick_scan_cnt++;
763
764div_comb_done: 858div_comb_done:
765 ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio); 859 ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
766 ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); 860 ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
861 ath9k_debug_stat_ant(sc, &div_ant_conf, main_rssi_avg, alt_rssi_avg);
767 862
768 antcomb->scan_start_time = jiffies; 863 antcomb->scan_start_time = jiffies;
769 antcomb->total_pkt_count = 0; 864 antcomb->total_pkt_count = 0;
@@ -772,26 +867,3 @@ div_comb_done:
772 antcomb->main_recv_cnt = 0; 867 antcomb->main_recv_cnt = 0;
773 antcomb->alt_recv_cnt = 0; 868 antcomb->alt_recv_cnt = 0;
774} 869}
775
776void ath_ant_comb_update(struct ath_softc *sc)
777{
778 struct ath_hw *ah = sc->sc_ah;
779 struct ath_common *common = ath9k_hw_common(ah);
780 struct ath_hw_antcomb_conf div_ant_conf;
781 u8 lna_conf;
782
783 ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf);
784
785 if (sc->ant_rx == 1)
786 lna_conf = ATH_ANT_DIV_COMB_LNA1;
787 else
788 lna_conf = ATH_ANT_DIV_COMB_LNA2;
789
790 div_ant_conf.main_lna_conf = lna_conf;
791 div_ant_conf.alt_lna_conf = lna_conf;
792
793 ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf);
794
795 if (common->antenna_diversity)
796 ath9k_hw_antctrl_shared_chain_lnadiv(ah, true);
797}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index f4003512d8d5..456d8b917396 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -555,6 +555,65 @@ static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,
555 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval); 555 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
556} 556}
557 557
558static void ar9002_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
559{
560 struct ath_btcoex_hw *btcoex = &ah->btcoex_hw;
561 u8 antdiv_ctrl1, antdiv_ctrl2;
562 u32 regval;
563
564 if (enable) {
565 antdiv_ctrl1 = ATH_BT_COEX_ANTDIV_CONTROL1_ENABLE;
566 antdiv_ctrl2 = ATH_BT_COEX_ANTDIV_CONTROL2_ENABLE;
567
568 /*
569 * Don't disable BT ant to allow BB to control SWCOM.
570 */
571 btcoex->bt_coex_mode2 &= (~(AR_BT_DISABLE_BT_ANT));
572 REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2);
573
574 REG_WRITE(ah, AR_PHY_SWITCH_COM, ATH_BT_COEX_ANT_DIV_SWITCH_COM);
575 REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);
576 } else {
577 /*
578 * Disable antenna diversity, use LNA1 only.
579 */
580 antdiv_ctrl1 = ATH_BT_COEX_ANTDIV_CONTROL1_FIXED_A;
581 antdiv_ctrl2 = ATH_BT_COEX_ANTDIV_CONTROL2_FIXED_A;
582
583 /*
584 * Disable BT Ant. to allow concurrent BT and WLAN receive.
585 */
586 btcoex->bt_coex_mode2 |= AR_BT_DISABLE_BT_ANT;
587 REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2);
588
589 /*
590 * Program SWCOM table to make sure RF switch always parks
591 * at BT side.
592 */
593 REG_WRITE(ah, AR_PHY_SWITCH_COM, 0);
594 REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);
595 }
596
597 regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
598 regval &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
599 /*
600 * Clear ant_fast_div_bias [14:9] since for WB195,
601 * the main LNA is always LNA1.
602 */
603 regval &= (~(AR_PHY_9285_FAST_DIV_BIAS));
604 regval |= SM(antdiv_ctrl1, AR_PHY_9285_ANT_DIV_CTL);
605 regval |= SM(antdiv_ctrl2, AR_PHY_9285_ANT_DIV_ALT_LNACONF);
606 regval |= SM((antdiv_ctrl2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
607 regval |= SM((antdiv_ctrl1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB);
608 regval |= SM((antdiv_ctrl1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
609 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
610
611 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
612 regval &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
613 regval |= SM((antdiv_ctrl1 >> 3), AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
614 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
615}
616
558static void ar9002_hw_spectral_scan_config(struct ath_hw *ah, 617static void ar9002_hw_spectral_scan_config(struct ath_hw *ah,
559 struct ath_spec_scan *param) 618 struct ath_spec_scan *param)
560{ 619{
@@ -630,6 +689,7 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
630 689
631 ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get; 690 ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
632 ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set; 691 ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
692 ops->set_bt_ant_diversity = ar9002_hw_set_bt_ant_diversity;
633 ops->spectral_scan_config = ar9002_hw_spectral_scan_config; 693 ops->spectral_scan_config = ar9002_hw_spectral_scan_config;
634 ops->spectral_scan_trigger = ar9002_hw_spectral_scan_trigger; 694 ops->spectral_scan_trigger = ar9002_hw_spectral_scan_trigger;
635 ops->spectral_scan_wait = ar9002_hw_spectral_scan_wait; 695 ops->spectral_scan_wait = ar9002_hw_spectral_scan_wait;
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
index f9eb2c357169..6314ae2e93e3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -317,13 +317,15 @@
317#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S 29 317#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S 29
318#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000 318#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000
319#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30 319#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30
320#define AR_PHY_9285_ANT_DIV_LNA1 2
321#define AR_PHY_9285_ANT_DIV_LNA2 1
322#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3
323#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
324#define AR_PHY_9285_ANT_DIV_GAINTB_0 0 320#define AR_PHY_9285_ANT_DIV_GAINTB_0 0
325#define AR_PHY_9285_ANT_DIV_GAINTB_1 1 321#define AR_PHY_9285_ANT_DIV_GAINTB_1 1
326 322
323#define ATH_BT_COEX_ANTDIV_CONTROL1_ENABLE 0x0b
324#define ATH_BT_COEX_ANTDIV_CONTROL2_ENABLE 0x09
325#define ATH_BT_COEX_ANTDIV_CONTROL1_FIXED_A 0x04
326#define ATH_BT_COEX_ANTDIV_CONTROL2_FIXED_A 0x09
327#define ATH_BT_COEX_ANT_DIV_SWITCH_COM 0x66666666
328
327#define AR_PHY_EXT_CCA0 0x99b8 329#define AR_PHY_EXT_CCA0 0x99b8
328#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF 330#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
329#define AR_PHY_EXT_CCA0_THRESH62_S 0 331#define AR_PHY_EXT_CCA0_THRESH62_S 0
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index d105e43d22e1..abdc7ee87413 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3541,13 +3541,12 @@ static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
3541 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt); 3541 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
3542} 3542}
3543 3543
3544 3544u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3545static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3546{ 3545{
3547 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon); 3546 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3548} 3547}
3549 3548
3550static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz) 3549u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3551{ 3550{
3552 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2); 3551 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3553} 3552}
@@ -3561,6 +3560,7 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3561 3560
3562static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) 3561static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3563{ 3562{
3563 struct ath_common *common = ath9k_hw_common(ah);
3564 struct ath9k_hw_capabilities *pCap = &ah->caps; 3564 struct ath9k_hw_capabilities *pCap = &ah->caps;
3565 int chain; 3565 int chain;
3566 u32 regval, value, gpio; 3566 u32 regval, value, gpio;
@@ -3614,6 +3614,11 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3614 } 3614 }
3615 3615
3616 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); 3616 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3617 if (AR_SREV_9485(ah) && common->bt_ant_diversity) {
3618 regval &= ~AR_SWITCH_TABLE_COM2_ALL;
3619 regval |= ah->config.ant_ctrl_comm2g_switch_enable;
3620
3621 }
3617 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); 3622 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3618 3623
3619 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) { 3624 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
@@ -3645,8 +3650,11 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3645 regval &= (~AR_PHY_ANT_DIV_LNADIV); 3650 regval &= (~AR_PHY_ANT_DIV_LNADIV);
3646 regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S; 3651 regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
3647 3652
3653 if (AR_SREV_9485(ah) && common->bt_ant_diversity)
3654 regval |= AR_ANT_DIV_ENABLE;
3655
3648 if (AR_SREV_9565(ah)) { 3656 if (AR_SREV_9565(ah)) {
3649 if (ah->shared_chain_lnadiv) { 3657 if (common->bt_ant_diversity) {
3650 regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S); 3658 regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S);
3651 } else { 3659 } else {
3652 regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S); 3660 regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S);
@@ -3656,10 +3664,14 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3656 3664
3657 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 3665 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3658 3666
3659 /*enable fast_div */ 3667 /* enable fast_div */
3660 regval = REG_READ(ah, AR_PHY_CCK_DETECT); 3668 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3661 regval &= (~AR_FAST_DIV_ENABLE); 3669 regval &= (~AR_FAST_DIV_ENABLE);
3662 regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S; 3670 regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
3671
3672 if (AR_SREV_9485(ah) && common->bt_ant_diversity)
3673 regval |= AR_FAST_DIV_ENABLE;
3674
3663 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); 3675 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3664 3676
3665 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) { 3677 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
@@ -3673,9 +3685,9 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3673 AR_PHY_ANT_DIV_ALT_GAINTB | 3685 AR_PHY_ANT_DIV_ALT_GAINTB |
3674 AR_PHY_ANT_DIV_MAIN_GAINTB)); 3686 AR_PHY_ANT_DIV_MAIN_GAINTB));
3675 /* by default use LNA1 for the main antenna */ 3687 /* by default use LNA1 for the main antenna */
3676 regval |= (AR_PHY_ANT_DIV_LNA1 << 3688 regval |= (ATH_ANT_DIV_COMB_LNA1 <<
3677 AR_PHY_ANT_DIV_MAIN_LNACONF_S); 3689 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
3678 regval |= (AR_PHY_ANT_DIV_LNA2 << 3690 regval |= (ATH_ANT_DIV_COMB_LNA2 <<
3679 AR_PHY_ANT_DIV_ALT_LNACONF_S); 3691 AR_PHY_ANT_DIV_ALT_LNACONF_S);
3680 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 3692 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3681 } 3693 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 874f6570bd1c..75d4fb41962f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -334,6 +334,8 @@ struct ar9300_eeprom {
334 334
335s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah); 335s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
336s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah); 336s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
337u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz);
338u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz);
337 339
338u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); 340u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz);
339 341
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 1f694ab3cc78..4898829e6549 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -632,6 +632,22 @@ static void ar9003_hw_override_ini(struct ath_hw *ah)
632 632
633 REG_SET_BIT(ah, AR_PHY_CCK_DETECT, 633 REG_SET_BIT(ah, AR_PHY_CCK_DETECT,
634 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 634 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
635
636 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
637 REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE,
638 AR_GLB_SWREG_DISCONT_EN_BT_WLAN);
639
640 if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
641 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL))
642 ah->enabled_cals |= TX_IQ_CAL;
643 else
644 ah->enabled_cals &= ~TX_IQ_CAL;
645
646 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
647 ah->enabled_cals |= TX_CL_CAL;
648 else
649 ah->enabled_cals &= ~TX_CL_CAL;
650 }
635} 651}
636 652
637static void ar9003_hw_prog_ini(struct ath_hw *ah, 653static void ar9003_hw_prog_ini(struct ath_hw *ah,
@@ -814,29 +830,12 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
814 if (chan->channel == 2484) 830 if (chan->channel == 2484)
815 ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1); 831 ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1);
816 832
817 if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
818 REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE,
819 AR_GLB_SWREG_DISCONT_EN_BT_WLAN);
820
821 ah->modes_index = modesIndex; 833 ah->modes_index = modesIndex;
822 ar9003_hw_override_ini(ah); 834 ar9003_hw_override_ini(ah);
823 ar9003_hw_set_channel_regs(ah, chan); 835 ar9003_hw_set_channel_regs(ah, chan);
824 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); 836 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
825 ath9k_hw_apply_txpower(ah, chan, false); 837 ath9k_hw_apply_txpower(ah, chan, false);
826 838
827 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
828 if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
829 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL))
830 ah->enabled_cals |= TX_IQ_CAL;
831 else
832 ah->enabled_cals &= ~TX_IQ_CAL;
833
834 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
835 ah->enabled_cals |= TX_CL_CAL;
836 else
837 ah->enabled_cals &= ~TX_CL_CAL;
838 }
839
840 return 0; 839 return 0;
841} 840}
842 841
@@ -1413,62 +1412,104 @@ static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah,
1413 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 1412 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1414} 1413}
1415 1414
1416static void ar9003_hw_antctrl_shared_chain_lnadiv(struct ath_hw *ah, 1415static void ar9003_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
1417 bool enable)
1418{ 1416{
1417 struct ath9k_hw_capabilities *pCap = &ah->caps;
1419 u8 ant_div_ctl1; 1418 u8 ant_div_ctl1;
1420 u32 regval; 1419 u32 regval;
1421 1420
1422 if (!AR_SREV_9565(ah)) 1421 if (!AR_SREV_9485(ah) && !AR_SREV_9565(ah))
1423 return; 1422 return;
1424 1423
1425 ah->shared_chain_lnadiv = enable; 1424 if (AR_SREV_9485(ah)) {
1425 regval = ar9003_hw_ant_ctrl_common_2_get(ah,
1426 IS_CHAN_2GHZ(ah->curchan));
1427 if (enable) {
1428 regval &= ~AR_SWITCH_TABLE_COM2_ALL;
1429 regval |= ah->config.ant_ctrl_comm2g_switch_enable;
1430 }
1431 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2,
1432 AR_SWITCH_TABLE_COM2_ALL, regval);
1433 }
1434
1426 ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); 1435 ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
1427 1436
1437 /*
1438 * Set MAIN/ALT LNA conf.
1439 * Set MAIN/ALT gain_tb.
1440 */
1428 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 1441 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1429 regval &= (~AR_ANT_DIV_CTRL_ALL); 1442 regval &= (~AR_ANT_DIV_CTRL_ALL);
1430 regval |= (ant_div_ctl1 & 0x3f) << AR_ANT_DIV_CTRL_ALL_S; 1443 regval |= (ant_div_ctl1 & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
1431 regval &= ~AR_PHY_ANT_DIV_LNADIV;
1432 regval |= ((ant_div_ctl1 >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
1433
1434 if (enable)
1435 regval |= AR_ANT_DIV_ENABLE;
1436
1437 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 1444 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1438 1445
1439 regval = REG_READ(ah, AR_PHY_CCK_DETECT); 1446 if (AR_SREV_9485_11(ah)) {
1440 regval &= ~AR_FAST_DIV_ENABLE; 1447 /*
1441 regval |= ((ant_div_ctl1 >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S; 1448 * Enable LNA diversity.
1442 1449 */
1443 if (enable)
1444 regval |= AR_FAST_DIV_ENABLE;
1445
1446 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
1447
1448 if (enable) {
1449 REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL,
1450 (1 << AR_PHY_ANT_SW_RX_PROT_S));
1451 if (ah->curchan && IS_CHAN_2GHZ(ah->curchan))
1452 REG_SET_BIT(ah, AR_PHY_RESTART,
1453 AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
1454 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
1455 AR_BTCOEX_WL_LNADIV_FORCE_ON);
1456 } else {
1457 REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE);
1458 REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL,
1459 (1 << AR_PHY_ANT_SW_RX_PROT_S));
1460 REG_CLR_BIT(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE);
1461 REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV,
1462 AR_BTCOEX_WL_LNADIV_FORCE_ON);
1463
1464 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 1450 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1465 regval &= ~(AR_PHY_ANT_DIV_MAIN_LNACONF | 1451 regval &= ~AR_PHY_ANT_DIV_LNADIV;
1466 AR_PHY_ANT_DIV_ALT_LNACONF | 1452 regval |= ((ant_div_ctl1 >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
1467 AR_PHY_ANT_DIV_MAIN_GAINTB | 1453 if (enable)
1468 AR_PHY_ANT_DIV_ALT_GAINTB); 1454 regval |= AR_ANT_DIV_ENABLE;
1469 regval |= (AR_PHY_ANT_DIV_LNA1 << AR_PHY_ANT_DIV_MAIN_LNACONF_S); 1455
1470 regval |= (AR_PHY_ANT_DIV_LNA2 << AR_PHY_ANT_DIV_ALT_LNACONF_S);
1471 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 1456 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1457
1458 /*
1459 * Enable fast antenna diversity.
1460 */
1461 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
1462 regval &= ~AR_FAST_DIV_ENABLE;
1463 regval |= ((ant_div_ctl1 >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
1464 if (enable)
1465 regval |= AR_FAST_DIV_ENABLE;
1466
1467 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
1468
1469 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
1470 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1471 regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF |
1472 AR_PHY_ANT_DIV_ALT_LNACONF |
1473 AR_PHY_ANT_DIV_ALT_GAINTB |
1474 AR_PHY_ANT_DIV_MAIN_GAINTB));
1475 /*
1476 * Set MAIN to LNA1 and ALT to LNA2 at the
1477 * beginning.
1478 */
1479 regval |= (ATH_ANT_DIV_COMB_LNA1 <<
1480 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
1481 regval |= (ATH_ANT_DIV_COMB_LNA2 <<
1482 AR_PHY_ANT_DIV_ALT_LNACONF_S);
1483 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1484 }
1485 } else if (AR_SREV_9565(ah)) {
1486 if (enable) {
1487 REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL,
1488 (1 << AR_PHY_ANT_SW_RX_PROT_S));
1489 if (ah->curchan && IS_CHAN_2GHZ(ah->curchan))
1490 REG_SET_BIT(ah, AR_PHY_RESTART,
1491 AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
1492 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
1493 AR_BTCOEX_WL_LNADIV_FORCE_ON);
1494 } else {
1495 REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE);
1496 REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL,
1497 (1 << AR_PHY_ANT_SW_RX_PROT_S));
1498 REG_CLR_BIT(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE);
1499 REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV,
1500 AR_BTCOEX_WL_LNADIV_FORCE_ON);
1501
1502 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1503 regval &= ~(AR_PHY_ANT_DIV_MAIN_LNACONF |
1504 AR_PHY_ANT_DIV_ALT_LNACONF |
1505 AR_PHY_ANT_DIV_MAIN_GAINTB |
1506 AR_PHY_ANT_DIV_ALT_GAINTB);
1507 regval |= (ATH_ANT_DIV_COMB_LNA1 <<
1508 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
1509 regval |= (ATH_ANT_DIV_COMB_LNA2 <<
1510 AR_PHY_ANT_DIV_ALT_LNACONF_S);
1511 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1512 }
1472 } 1513 }
1473} 1514}
1474 1515
@@ -1518,6 +1559,18 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
1518 1559
1519 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); 1560 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
1520 1561
1562 if (AR_SREV_9462_20_OR_LATER(ah)) {
1563 /*
1564 * CUS217 mix LNA mode.
1565 */
1566 if (ar9003_hw_get_rx_gain_idx(ah) == 2) {
1567 REG_WRITE_ARRAY(&ah->ini_modes_rxgain_bb_core,
1568 1, regWrites);
1569 REG_WRITE_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
1570 modesIndex, regWrites);
1571 }
1572 }
1573
1521 /* 1574 /*
1522 * For 5GHz channels requiring Fast Clock, apply 1575 * For 5GHz channels requiring Fast Clock, apply
1523 * different modal values. 1576 * different modal values.
@@ -1528,7 +1581,11 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
1528 if (AR_SREV_9565(ah)) 1581 if (AR_SREV_9565(ah))
1529 REG_WRITE_ARRAY(&ah->iniModesFastClock, 1, regWrites); 1582 REG_WRITE_ARRAY(&ah->iniModesFastClock, 1, regWrites);
1530 1583
1531 REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); 1584 /*
1585 * JAPAN regulatory.
1586 */
1587 if (chan->channel == 2484)
1588 ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1);
1532 1589
1533 ah->modes_index = modesIndex; 1590 ah->modes_index = modesIndex;
1534 *ini_reloaded = true; 1591 *ini_reloaded = true;
@@ -1631,7 +1688,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1631 1688
1632 ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; 1689 ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
1633 ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; 1690 ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
1634 ops->antctrl_shared_chain_lnadiv = ar9003_hw_antctrl_shared_chain_lnadiv; 1691 ops->set_bt_ant_diversity = ar9003_hw_set_bt_ant_diversity;
1635 ops->spectral_scan_config = ar9003_hw_spectral_scan_config; 1692 ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
1636 ops->spectral_scan_trigger = ar9003_hw_spectral_scan_trigger; 1693 ops->spectral_scan_trigger = ar9003_hw_spectral_scan_trigger;
1637 ops->spectral_scan_wait = ar9003_hw_spectral_scan_wait; 1694 ops->spectral_scan_wait = ar9003_hw_spectral_scan_wait;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index d4d39f305a0b..23c019d0d9aa 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -296,11 +296,6 @@
296#define AR_PHY_ANT_DIV_MAIN_GAINTB 0x40000000 296#define AR_PHY_ANT_DIV_MAIN_GAINTB 0x40000000
297#define AR_PHY_ANT_DIV_MAIN_GAINTB_S 30 297#define AR_PHY_ANT_DIV_MAIN_GAINTB_S 30
298 298
299#define AR_PHY_ANT_DIV_LNA1_MINUS_LNA2 0x0
300#define AR_PHY_ANT_DIV_LNA2 0x1
301#define AR_PHY_ANT_DIV_LNA1 0x2
302#define AR_PHY_ANT_DIV_LNA1_PLUS_LNA2 0x3
303
304#define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c) 299#define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c)
305#define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30) 300#define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30)
306#define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34) 301#define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index c1224b5a257b..c497d529ce86 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -585,19 +585,14 @@ static inline void ath_fill_led_pin(struct ath_softc *sc)
585#define ATH_ANT_DIV_COMB_MAX_COUNT 100 585#define ATH_ANT_DIV_COMB_MAX_COUNT 100
586#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30 586#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30
587#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20 587#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20
588#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO_LOW_RSSI 50
589#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2_LOW_RSSI 50
588 590
589#define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1 591#define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1
590#define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4 592#define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4
591#define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2 593#define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2
592#define ATH_ANT_DIV_COMB_LNA1_DELTA_LOW 2 594#define ATH_ANT_DIV_COMB_LNA1_DELTA_LOW 2
593 595
594enum ath9k_ant_div_comb_lna_conf {
595 ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2,
596 ATH_ANT_DIV_COMB_LNA2,
597 ATH_ANT_DIV_COMB_LNA1,
598 ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2,
599};
600
601struct ath_ant_comb { 596struct ath_ant_comb {
602 u16 count; 597 u16 count;
603 u16 total_pkt_count; 598 u16 total_pkt_count;
@@ -614,27 +609,35 @@ struct ath_ant_comb {
614 int rssi_first; 609 int rssi_first;
615 int rssi_second; 610 int rssi_second;
616 int rssi_third; 611 int rssi_third;
612 int ant_ratio;
613 int ant_ratio2;
617 bool alt_good; 614 bool alt_good;
618 int quick_scan_cnt; 615 int quick_scan_cnt;
619 int main_conf; 616 enum ath9k_ant_div_comb_lna_conf main_conf;
620 enum ath9k_ant_div_comb_lna_conf first_quick_scan_conf; 617 enum ath9k_ant_div_comb_lna_conf first_quick_scan_conf;
621 enum ath9k_ant_div_comb_lna_conf second_quick_scan_conf; 618 enum ath9k_ant_div_comb_lna_conf second_quick_scan_conf;
622 bool first_ratio; 619 bool first_ratio;
623 bool second_ratio; 620 bool second_ratio;
624 unsigned long scan_start_time; 621 unsigned long scan_start_time;
622
623 /*
624 * Card-specific config values.
625 */
626 int low_rssi_thresh;
627 int fast_div_bias;
625}; 628};
626 629
627void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs); 630void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
628void ath_ant_comb_update(struct ath_softc *sc);
629 631
630/********************/ 632/********************/
631/* Main driver core */ 633/* Main driver core */
632/********************/ 634/********************/
633 635
634#define ATH9K_PCI_CUS198 0x0001 636#define ATH9K_PCI_CUS198 0x0001
635#define ATH9K_PCI_CUS230 0x0002 637#define ATH9K_PCI_CUS230 0x0002
636#define ATH9K_PCI_CUS217 0x0004 638#define ATH9K_PCI_CUS217 0x0004
637#define ATH9K_PCI_WOW 0x0008 639#define ATH9K_PCI_WOW 0x0008
640#define ATH9K_PCI_BT_ANT_DIV 0x0010
638 641
639/* 642/*
640 * Default cache line size, in bytes. 643 * Default cache line size, in bytes.
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 87454f6c7b4f..a155190e2c84 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -270,25 +270,27 @@ static const struct file_operations fops_ani = {
270 .llseek = default_llseek, 270 .llseek = default_llseek,
271}; 271};
272 272
273static ssize_t read_file_ant_diversity(struct file *file, char __user *user_buf, 273static ssize_t read_file_bt_ant_diversity(struct file *file,
274 size_t count, loff_t *ppos) 274 char __user *user_buf,
275 size_t count, loff_t *ppos)
275{ 276{
276 struct ath_softc *sc = file->private_data; 277 struct ath_softc *sc = file->private_data;
277 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 278 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
278 char buf[32]; 279 char buf[32];
279 unsigned int len; 280 unsigned int len;
280 281
281 len = sprintf(buf, "%d\n", common->antenna_diversity); 282 len = sprintf(buf, "%d\n", common->bt_ant_diversity);
282 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 283 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
283} 284}
284 285
285static ssize_t write_file_ant_diversity(struct file *file, 286static ssize_t write_file_bt_ant_diversity(struct file *file,
286 const char __user *user_buf, 287 const char __user *user_buf,
287 size_t count, loff_t *ppos) 288 size_t count, loff_t *ppos)
288{ 289{
289 struct ath_softc *sc = file->private_data; 290 struct ath_softc *sc = file->private_data;
290 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 291 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
291 unsigned long antenna_diversity; 292 struct ath9k_hw_capabilities *pCap = &sc->sc_ah->caps;
293 unsigned long bt_ant_diversity;
292 char buf[32]; 294 char buf[32];
293 ssize_t len; 295 ssize_t len;
294 296
@@ -296,26 +298,145 @@ static ssize_t write_file_ant_diversity(struct file *file,
296 if (copy_from_user(buf, user_buf, len)) 298 if (copy_from_user(buf, user_buf, len))
297 return -EFAULT; 299 return -EFAULT;
298 300
299 if (!AR_SREV_9565(sc->sc_ah)) 301 if (!(pCap->hw_caps & ATH9K_HW_CAP_BT_ANT_DIV))
300 goto exit; 302 goto exit;
301 303
302 buf[len] = '\0'; 304 buf[len] = '\0';
303 if (kstrtoul(buf, 0, &antenna_diversity)) 305 if (kstrtoul(buf, 0, &bt_ant_diversity))
304 return -EINVAL; 306 return -EINVAL;
305 307
306 common->antenna_diversity = !!antenna_diversity; 308 common->bt_ant_diversity = !!bt_ant_diversity;
307 ath9k_ps_wakeup(sc); 309 ath9k_ps_wakeup(sc);
308 ath_ant_comb_update(sc); 310 ath9k_hw_set_bt_ant_diversity(sc->sc_ah, common->bt_ant_diversity);
309 ath_dbg(common, CONFIG, "Antenna diversity: %d\n", 311 ath_dbg(common, CONFIG, "Enable WLAN/BT RX Antenna diversity: %d\n",
310 common->antenna_diversity); 312 common->bt_ant_diversity);
311 ath9k_ps_restore(sc); 313 ath9k_ps_restore(sc);
312exit: 314exit:
313 return count; 315 return count;
314} 316}
315 317
316static const struct file_operations fops_ant_diversity = { 318static const struct file_operations fops_bt_ant_diversity = {
317 .read = read_file_ant_diversity, 319 .read = read_file_bt_ant_diversity,
318 .write = write_file_ant_diversity, 320 .write = write_file_bt_ant_diversity,
321 .open = simple_open,
322 .owner = THIS_MODULE,
323 .llseek = default_llseek,
324};
325
326void ath9k_debug_stat_ant(struct ath_softc *sc,
327 struct ath_hw_antcomb_conf *div_ant_conf,
328 int main_rssi_avg, int alt_rssi_avg)
329{
330 struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
331 struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
332
333 as_main->lna_attempt_cnt[div_ant_conf->main_lna_conf]++;
334 as_alt->lna_attempt_cnt[div_ant_conf->alt_lna_conf]++;
335
336 as_main->rssi_avg = main_rssi_avg;
337 as_alt->rssi_avg = alt_rssi_avg;
338}
339
340static ssize_t read_file_antenna_diversity(struct file *file,
341 char __user *user_buf,
342 size_t count, loff_t *ppos)
343{
344 struct ath_softc *sc = file->private_data;
345 struct ath_hw *ah = sc->sc_ah;
346 struct ath9k_hw_capabilities *pCap = &ah->caps;
347 struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
348 struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
349 struct ath_hw_antcomb_conf div_ant_conf;
350 unsigned int len = 0, size = 1024;
351 ssize_t retval = 0;
352 char *buf;
353 char *lna_conf_str[4] = {"LNA1_MINUS_LNA2",
354 "LNA2",
355 "LNA1",
356 "LNA1_PLUS_LNA2"};
357
358 buf = kzalloc(size, GFP_KERNEL);
359 if (buf == NULL)
360 return -ENOMEM;
361
362 if (!(pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)) {
363 len += snprintf(buf + len, size - len, "%s\n",
364 "Antenna Diversity Combining is disabled");
365 goto exit;
366 }
367
368 ath9k_ps_wakeup(sc);
369 ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf);
370 len += snprintf(buf + len, size - len, "Current MAIN config : %s\n",
371 lna_conf_str[div_ant_conf.main_lna_conf]);
372 len += snprintf(buf + len, size - len, "Current ALT config : %s\n",
373 lna_conf_str[div_ant_conf.alt_lna_conf]);
374 len += snprintf(buf + len, size - len, "Average MAIN RSSI : %d\n",
375 as_main->rssi_avg);
376 len += snprintf(buf + len, size - len, "Average ALT RSSI : %d\n\n",
377 as_alt->rssi_avg);
378 ath9k_ps_restore(sc);
379
380 len += snprintf(buf + len, size - len, "Packet Receive Cnt:\n");
381 len += snprintf(buf + len, size - len, "-------------------\n");
382
383 len += snprintf(buf + len, size - len, "%30s%15s\n",
384 "MAIN", "ALT");
385 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
386 "TOTAL COUNT",
387 as_main->recv_cnt,
388 as_alt->recv_cnt);
389 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
390 "LNA1",
391 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1],
392 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1]);
393 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
394 "LNA2",
395 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2],
396 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2]);
397 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
398 "LNA1 + LNA2",
399 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
400 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
401 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
402 "LNA1 - LNA2",
403 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
404 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
405
406 len += snprintf(buf + len, size - len, "\nLNA Config Attempts:\n");
407 len += snprintf(buf + len, size - len, "--------------------\n");
408
409 len += snprintf(buf + len, size - len, "%30s%15s\n",
410 "MAIN", "ALT");
411 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
412 "LNA1",
413 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1],
414 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1]);
415 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
416 "LNA2",
417 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2],
418 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2]);
419 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
420 "LNA1 + LNA2",
421 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
422 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
423 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
424 "LNA1 - LNA2",
425 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
426 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
427
428exit:
429 if (len > size)
430 len = size;
431
432 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
433 kfree(buf);
434
435 return retval;
436}
437
438static const struct file_operations fops_antenna_diversity = {
439 .read = read_file_antenna_diversity,
319 .open = simple_open, 440 .open = simple_open,
320 .owner = THIS_MODULE, 441 .owner = THIS_MODULE,
321 .llseek = default_llseek, 442 .llseek = default_llseek,
@@ -1814,8 +1935,10 @@ int ath9k_init_debug(struct ath_hw *ah)
1814 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); 1935 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
1815 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, 1936 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
1816 sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); 1937 sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
1817 debugfs_create_file("diversity", S_IRUSR | S_IWUSR, 1938 debugfs_create_file("bt_ant_diversity", S_IRUSR | S_IWUSR,
1818 sc->debug.debugfs_phy, sc, &fops_ant_diversity); 1939 sc->debug.debugfs_phy, sc, &fops_bt_ant_diversity);
1940 debugfs_create_file("antenna_diversity", S_IRUSR,
1941 sc->debug.debugfs_phy, sc, &fops_antenna_diversity);
1819#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 1942#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
1820 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, 1943 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc,
1821 &fops_btcoex); 1944 &fops_btcoex);
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index fc679198a0f3..01c5c6a22e1b 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -28,9 +28,13 @@ struct fft_sample_tlv;
28#ifdef CONFIG_ATH9K_DEBUGFS 28#ifdef CONFIG_ATH9K_DEBUGFS
29#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++ 29#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
30#define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++ 30#define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++
31#define ANT_STAT_INC(i, c) sc->debug.stats.ant_stats[i].c++
32#define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_recv_cnt[c]++;
31#else 33#else
32#define TX_STAT_INC(q, c) do { } while (0) 34#define TX_STAT_INC(q, c) do { } while (0)
33#define RESET_STAT_INC(sc, type) do { } while (0) 35#define RESET_STAT_INC(sc, type) do { } while (0)
36#define ANT_STAT_INC(i, c) do { } while (0)
37#define ANT_LNA_INC(i, c) do { } while (0)
34#endif 38#endif
35 39
36enum ath_reset_type { 40enum ath_reset_type {
@@ -243,11 +247,22 @@ struct ath_rx_stats {
243 u32 rx_spectral; 247 u32 rx_spectral;
244}; 248};
245 249
250#define ANT_MAIN 0
251#define ANT_ALT 1
252
253struct ath_antenna_stats {
254 u32 recv_cnt;
255 u32 rssi_avg;
256 u32 lna_recv_cnt[4];
257 u32 lna_attempt_cnt[4];
258};
259
246struct ath_stats { 260struct ath_stats {
247 struct ath_interrupt_stats istats; 261 struct ath_interrupt_stats istats;
248 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; 262 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
249 struct ath_rx_stats rxstats; 263 struct ath_rx_stats rxstats;
250 struct ath_dfs_stats dfs_stats; 264 struct ath_dfs_stats dfs_stats;
265 struct ath_antenna_stats ant_stats[2];
251 u32 reset[__RESET_TYPE_MAX]; 266 u32 reset[__RESET_TYPE_MAX];
252}; 267};
253 268
@@ -281,10 +296,11 @@ void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw,
281 struct ieee80211_vif *vif, 296 struct ieee80211_vif *vif,
282 struct ieee80211_sta *sta, 297 struct ieee80211_sta *sta,
283 struct dentry *dir); 298 struct dentry *dir);
284
285void ath_debug_send_fft_sample(struct ath_softc *sc, 299void ath_debug_send_fft_sample(struct ath_softc *sc,
286 struct fft_sample_tlv *fft_sample); 300 struct fft_sample_tlv *fft_sample);
287 301void ath9k_debug_stat_ant(struct ath_softc *sc,
302 struct ath_hw_antcomb_conf *div_ant_conf,
303 int main_rssi_avg, int alt_rssi_avg);
288#else 304#else
289 305
290#define RX_STAT_INC(c) /* NOP */ 306#define RX_STAT_INC(c) /* NOP */
@@ -297,12 +313,10 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
297static inline void ath9k_deinit_debug(struct ath_softc *sc) 313static inline void ath9k_deinit_debug(struct ath_softc *sc)
298{ 314{
299} 315}
300
301static inline void ath_debug_stat_interrupt(struct ath_softc *sc, 316static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
302 enum ath9k_int status) 317 enum ath9k_int status)
303{ 318{
304} 319}
305
306static inline void ath_debug_stat_tx(struct ath_softc *sc, 320static inline void ath_debug_stat_tx(struct ath_softc *sc,
307 struct ath_buf *bf, 321 struct ath_buf *bf,
308 struct ath_tx_status *ts, 322 struct ath_tx_status *ts,
@@ -310,11 +324,16 @@ static inline void ath_debug_stat_tx(struct ath_softc *sc,
310 unsigned int flags) 324 unsigned int flags)
311{ 325{
312} 326}
313
314static inline void ath_debug_stat_rx(struct ath_softc *sc, 327static inline void ath_debug_stat_rx(struct ath_softc *sc,
315 struct ath_rx_status *rs) 328 struct ath_rx_status *rs)
316{ 329{
317} 330}
331static inline void ath9k_debug_stat_ant(struct ath_softc *sc,
332 struct ath_hw_antcomb_conf *div_ant_conf,
333 int main_rssi_avg, int alt_rssi_avg)
334{
335
336}
318 337
319#endif /* CONFIG_ATH9K_DEBUGFS */ 338#endif /* CONFIG_ATH9K_DEBUGFS */
320 339
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index c2bfd748eed8..9ea8e4b779c9 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -812,6 +812,7 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
812static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, 812static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
813 struct ath9k_channel *chan) 813 struct ath9k_channel *chan)
814{ 814{
815 struct ath9k_hw_capabilities *pCap = &ah->caps;
815 struct modal_eep_4k_header *pModal; 816 struct modal_eep_4k_header *pModal;
816 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 817 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
817 struct base_eep_header_4k *pBase = &eep->baseEepHeader; 818 struct base_eep_header_4k *pBase = &eep->baseEepHeader;
@@ -858,6 +859,24 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
858 859
859 REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal); 860 REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);
860 regVal = REG_READ(ah, AR_PHY_CCK_DETECT); 861 regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
862
863 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
864 /*
865 * If diversity combining is enabled,
866 * set MAIN to LNA1 and ALT to LNA2 initially.
867 */
868 regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
869 regVal &= (~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF |
870 AR_PHY_9285_ANT_DIV_ALT_LNACONF));
871
872 regVal |= (ATH_ANT_DIV_COMB_LNA1 <<
873 AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S);
874 regVal |= (ATH_ANT_DIV_COMB_LNA2 <<
875 AR_PHY_9285_ANT_DIV_ALT_LNACONF_S);
876 regVal &= (~(AR_PHY_9285_FAST_DIV_BIAS));
877 regVal |= (0 << AR_PHY_9285_FAST_DIV_BIAS_S);
878 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
879 }
861 } 880 }
862 881
863 if (pModal->version >= 2) { 882 if (pModal->version >= 2) {
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 14b701140b49..a78d48c3ad21 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -78,11 +78,10 @@ static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
78 ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf); 78 ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf);
79} 79}
80 80
81static inline void ath9k_hw_antctrl_shared_chain_lnadiv(struct ath_hw *ah, 81static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
82 bool enable)
83{ 82{
84 if (ath9k_hw_ops(ah)->antctrl_shared_chain_lnadiv) 83 if (ath9k_hw_ops(ah)->set_bt_ant_diversity)
85 ath9k_hw_ops(ah)->antctrl_shared_chain_lnadiv(ah, enable); 84 ath9k_hw_ops(ah)->set_bt_ant_diversity(ah, enable);
86} 85}
87 86
88/* Private hardware call ops */ 87/* Private hardware call ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4ca0cb060106..151443bddbde 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1496,16 +1496,18 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1496 struct ath9k_channel *chan) 1496 struct ath9k_channel *chan)
1497{ 1497{
1498 struct ath_common *common = ath9k_hw_common(ah); 1498 struct ath_common *common = ath9k_hw_common(ah);
1499 struct ath9k_hw_capabilities *pCap = &ah->caps;
1500 bool band_switch = false, mode_diff = false;
1501 u8 ini_reloaded = 0;
1499 u32 qnum; 1502 u32 qnum;
1500 int r; 1503 int r;
1501 bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
1502 bool band_switch, mode_diff;
1503 u8 ini_reloaded;
1504 1504
1505 band_switch = (chan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ)) != 1505 if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) {
1506 (ah->curchan->channelFlags & (CHANNEL_2GHZ | 1506 u32 cur = ah->curchan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ);
1507 CHANNEL_5GHZ)); 1507 u32 new = chan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ);
1508 mode_diff = (chan->chanmode != ah->curchan->chanmode); 1508 band_switch = (cur != new);
1509 mode_diff = (chan->chanmode != ah->curchan->chanmode);
1510 }
1509 1511
1510 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { 1512 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
1511 if (ath9k_hw_numtxpending(ah, qnum)) { 1513 if (ath9k_hw_numtxpending(ah, qnum)) {
@@ -1520,11 +1522,12 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1520 return false; 1522 return false;
1521 } 1523 }
1522 1524
1523 if (edma && (band_switch || mode_diff)) { 1525 if (band_switch || mode_diff) {
1524 ath9k_hw_mark_phy_inactive(ah); 1526 ath9k_hw_mark_phy_inactive(ah);
1525 udelay(5); 1527 udelay(5);
1526 1528
1527 ath9k_hw_init_pll(ah, NULL); 1529 if (band_switch)
1530 ath9k_hw_init_pll(ah, chan);
1528 1531
1529 if (ath9k_hw_fast_chan_change(ah, chan, &ini_reloaded)) { 1532 if (ath9k_hw_fast_chan_change(ah, chan, &ini_reloaded)) {
1530 ath_err(common, "Failed to do fast channel change\n"); 1533 ath_err(common, "Failed to do fast channel change\n");
@@ -1541,22 +1544,21 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1541 } 1544 }
1542 ath9k_hw_set_clockrate(ah); 1545 ath9k_hw_set_clockrate(ah);
1543 ath9k_hw_apply_txpower(ah, chan, false); 1546 ath9k_hw_apply_txpower(ah, chan, false);
1544 ath9k_hw_rfbus_done(ah);
1545 1547
1546 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) 1548 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
1547 ath9k_hw_set_delta_slope(ah, chan); 1549 ath9k_hw_set_delta_slope(ah, chan);
1548 1550
1549 ath9k_hw_spur_mitigate_freq(ah, chan); 1551 ath9k_hw_spur_mitigate_freq(ah, chan);
1550 1552
1551 if (edma && (band_switch || mode_diff)) { 1553 if (band_switch || ini_reloaded)
1552 ah->ah_flags |= AH_FASTCC; 1554 ah->eep_ops->set_board_values(ah, chan);
1553 if (band_switch || ini_reloaded)
1554 ah->eep_ops->set_board_values(ah, chan);
1555 1555
1556 ath9k_hw_init_bb(ah, chan); 1556 ath9k_hw_init_bb(ah, chan);
1557 ath9k_hw_rfbus_done(ah);
1557 1558
1558 if (band_switch || ini_reloaded) 1559 if (band_switch || ini_reloaded) {
1559 ath9k_hw_init_cal(ah, chan); 1560 ah->ah_flags |= AH_FASTCC;
1561 ath9k_hw_init_cal(ah, chan);
1560 ah->ah_flags &= ~AH_FASTCC; 1562 ah->ah_flags &= ~AH_FASTCC;
1561 } 1563 }
1562 1564
@@ -1778,16 +1780,11 @@ static void ath9k_hw_init_desc(struct ath_hw *ah)
1778/* 1780/*
1779 * Fast channel change: 1781 * Fast channel change:
1780 * (Change synthesizer based on channel freq without resetting chip) 1782 * (Change synthesizer based on channel freq without resetting chip)
1781 *
1782 * Don't do FCC when
1783 * - Flag is not set
1784 * - Chip is just coming out of full sleep
1785 * - Channel to be set is same as current channel
1786 * - Channel flags are different, (eg.,moving from 2GHz to 5GHz channel)
1787 */ 1783 */
1788static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) 1784static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
1789{ 1785{
1790 struct ath_common *common = ath9k_hw_common(ah); 1786 struct ath_common *common = ath9k_hw_common(ah);
1787 struct ath9k_hw_capabilities *pCap = &ah->caps;
1791 int ret; 1788 int ret;
1792 1789
1793 if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) 1790 if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI)
@@ -1806,9 +1803,21 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
1806 (CHANNEL_HALF | CHANNEL_QUARTER)) 1803 (CHANNEL_HALF | CHANNEL_QUARTER))
1807 goto fail; 1804 goto fail;
1808 1805
1809 if ((chan->channelFlags & CHANNEL_ALL) != 1806 /*
1810 (ah->curchan->channelFlags & CHANNEL_ALL)) 1807 * If cross-band fcc is not supoprted, bail out if
1811 goto fail; 1808 * either channelFlags or chanmode differ.
1809 *
1810 * chanmode will be different if the HT operating mode
1811 * changes because of CSA.
1812 */
1813 if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH)) {
1814 if ((chan->channelFlags & CHANNEL_ALL) !=
1815 (ah->curchan->channelFlags & CHANNEL_ALL))
1816 goto fail;
1817
1818 if (chan->chanmode != ah->curchan->chanmode)
1819 goto fail;
1820 }
1812 1821
1813 if (!ath9k_hw_check_alive(ah)) 1822 if (!ath9k_hw_check_alive(ah))
1814 goto fail; 1823 goto fail;
@@ -2047,7 +2056,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2047 2056
2048 ath9k_hw_apply_gpio_override(ah); 2057 ath9k_hw_apply_gpio_override(ah);
2049 2058
2050 if (AR_SREV_9565(ah) && ah->shared_chain_lnadiv) 2059 if (AR_SREV_9565(ah) && common->bt_ant_diversity)
2051 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); 2060 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
2052 2061
2053 return 0; 2062 return 0;
@@ -2504,7 +2513,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2504 else 2513 else
2505 pCap->rts_aggr_limit = (8 * 1024); 2514 pCap->rts_aggr_limit = (8 * 1024);
2506 2515
2507#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 2516#ifdef CONFIG_ATH9K_RFKILL
2508 ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT); 2517 ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
2509 if (ah->rfsilent & EEP_RFSILENT_ENABLED) { 2518 if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
2510 ah->rfkill_gpio = 2519 ah->rfkill_gpio =
@@ -2550,34 +2559,28 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2550 if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah)) 2559 if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah))
2551 pCap->hw_caps |= ATH9K_HW_CAP_SGI_20; 2560 pCap->hw_caps |= ATH9K_HW_CAP_SGI_20;
2552 2561
2553 if (AR_SREV_9285(ah)) 2562 if (AR_SREV_9285(ah)) {
2554 if (ah->eep_ops->get_eeprom(ah, EEP_MODAL_VER) >= 3) { 2563 if (ah->eep_ops->get_eeprom(ah, EEP_MODAL_VER) >= 3) {
2555 ant_div_ctl1 = 2564 ant_div_ctl1 =
2556 ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); 2565 ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
2557 if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1)) 2566 if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1)) {
2558 pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; 2567 pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
2568 ath_info(common, "Enable LNA combining\n");
2569 }
2559 } 2570 }
2571 }
2572
2560 if (AR_SREV_9300_20_OR_LATER(ah)) { 2573 if (AR_SREV_9300_20_OR_LATER(ah)) {
2561 if (ah->eep_ops->get_eeprom(ah, EEP_CHAIN_MASK_REDUCE)) 2574 if (ah->eep_ops->get_eeprom(ah, EEP_CHAIN_MASK_REDUCE))
2562 pCap->hw_caps |= ATH9K_HW_CAP_APM; 2575 pCap->hw_caps |= ATH9K_HW_CAP_APM;
2563 } 2576 }
2564 2577
2565
2566 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) { 2578 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
2567 ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); 2579 ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
2568 /* 2580 if ((ant_div_ctl1 >> 0x6) == 0x3) {
2569 * enable the diversity-combining algorithm only when
2570 * both enable_lna_div and enable_fast_div are set
2571 * Table for Diversity
2572 * ant_div_alt_lnaconf bit 0-1
2573 * ant_div_main_lnaconf bit 2-3
2574 * ant_div_alt_gaintb bit 4
2575 * ant_div_main_gaintb bit 5
2576 * enable_ant_div_lnadiv bit 6
2577 * enable_ant_fast_div bit 7
2578 */
2579 if ((ant_div_ctl1 >> 0x6) == 0x3)
2580 pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; 2581 pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
2582 ath_info(common, "Enable LNA combining\n");
2583 }
2581 } 2584 }
2582 2585
2583 if (ath9k_hw_dfs_tested(ah)) 2586 if (ath9k_hw_dfs_tested(ah))
@@ -2610,6 +2613,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2610 ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) 2613 ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
2611 pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; 2614 pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
2612 2615
2616 /*
2617 * Fast channel change across bands is available
2618 * only for AR9462 and AR9565.
2619 */
2620 if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
2621 pCap->hw_caps |= ATH9K_HW_CAP_FCC_BAND_SWITCH;
2622
2613 return 0; 2623 return 0;
2614} 2624}
2615 2625
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index cd74b3afef7d..38f461c11c33 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -247,6 +247,8 @@ enum ath9k_hw_caps {
247 ATH9K_HW_CAP_DFS = BIT(16), 247 ATH9K_HW_CAP_DFS = BIT(16),
248 ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17), 248 ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17),
249 ATH9K_HW_CAP_PAPRD = BIT(18), 249 ATH9K_HW_CAP_PAPRD = BIT(18),
250 ATH9K_HW_CAP_FCC_BAND_SWITCH = BIT(19),
251 ATH9K_HW_CAP_BT_ANT_DIV = BIT(20),
250}; 252};
251 253
252/* 254/*
@@ -310,6 +312,7 @@ struct ath9k_ops_config {
310 312
311 /* Platform specific config */ 313 /* Platform specific config */
312 u32 xlna_gpio; 314 u32 xlna_gpio;
315 u32 ant_ctrl_comm2g_switch_enable;
313 bool xatten_margin_cfg; 316 bool xatten_margin_cfg;
314}; 317};
315 318
@@ -716,7 +719,7 @@ struct ath_hw_ops {
716 struct ath_hw_antcomb_conf *antconf); 719 struct ath_hw_antcomb_conf *antconf);
717 void (*antdiv_comb_conf_set)(struct ath_hw *ah, 720 void (*antdiv_comb_conf_set)(struct ath_hw *ah,
718 struct ath_hw_antcomb_conf *antconf); 721 struct ath_hw_antcomb_conf *antconf);
719 void (*antctrl_shared_chain_lnadiv)(struct ath_hw *hw, bool enable); 722 void (*set_bt_ant_diversity)(struct ath_hw *hw, bool enable);
720 void (*spectral_scan_config)(struct ath_hw *ah, 723 void (*spectral_scan_config)(struct ath_hw *ah,
721 struct ath_spec_scan *param); 724 struct ath_spec_scan *param);
722 void (*spectral_scan_trigger)(struct ath_hw *ah); 725 void (*spectral_scan_trigger)(struct ath_hw *ah);
@@ -765,7 +768,6 @@ struct ath_hw {
765 bool aspm_enabled; 768 bool aspm_enabled;
766 bool is_monitoring; 769 bool is_monitoring;
767 bool need_an_top2_fixup; 770 bool need_an_top2_fixup;
768 bool shared_chain_lnadiv;
769 u16 tx_trig_level; 771 u16 tx_trig_level;
770 772
771 u32 nf_regs[6]; 773 u32 nf_regs[6];
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 16f8b201642b..4afe30e0bf49 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -53,9 +53,9 @@ static int ath9k_btcoex_enable;
53module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); 53module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
54MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); 54MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
55 55
56static int ath9k_enable_diversity; 56static int ath9k_bt_ant_diversity;
57module_param_named(enable_diversity, ath9k_enable_diversity, int, 0444); 57module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444);
58MODULE_PARM_DESC(enable_diversity, "Enable Antenna diversity for AR9565"); 58MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity");
59 59
60bool is_ath9k_unloaded; 60bool is_ath9k_unloaded;
61/* We use the hw_value as an index into our private channel structure */ 61/* We use the hw_value as an index into our private channel structure */
@@ -516,6 +516,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
516static void ath9k_init_platform(struct ath_softc *sc) 516static void ath9k_init_platform(struct ath_softc *sc)
517{ 517{
518 struct ath_hw *ah = sc->sc_ah; 518 struct ath_hw *ah = sc->sc_ah;
519 struct ath9k_hw_capabilities *pCap = &ah->caps;
519 struct ath_common *common = ath9k_hw_common(ah); 520 struct ath_common *common = ath9k_hw_common(ah);
520 521
521 if (common->bus_ops->ath_bus_type != ATH_PCI) 522 if (common->bus_ops->ath_bus_type != ATH_PCI)
@@ -525,12 +526,21 @@ static void ath9k_init_platform(struct ath_softc *sc)
525 ATH9K_PCI_CUS230)) { 526 ATH9K_PCI_CUS230)) {
526 ah->config.xlna_gpio = 9; 527 ah->config.xlna_gpio = 9;
527 ah->config.xatten_margin_cfg = true; 528 ah->config.xatten_margin_cfg = true;
529 ah->config.ant_ctrl_comm2g_switch_enable = 0x000BBB88;
530 sc->ant_comb.low_rssi_thresh = 20;
531 sc->ant_comb.fast_div_bias = 3;
528 532
529 ath_info(common, "Set parameters for %s\n", 533 ath_info(common, "Set parameters for %s\n",
530 (sc->driver_data & ATH9K_PCI_CUS198) ? 534 (sc->driver_data & ATH9K_PCI_CUS198) ?
531 "CUS198" : "CUS230"); 535 "CUS198" : "CUS230");
532 } else if (sc->driver_data & ATH9K_PCI_CUS217) { 536 }
537
538 if (sc->driver_data & ATH9K_PCI_CUS217)
533 ath_info(common, "CUS217 card detected\n"); 539 ath_info(common, "CUS217 card detected\n");
540
541 if (sc->driver_data & ATH9K_PCI_BT_ANT_DIV) {
542 pCap->hw_caps |= ATH9K_HW_CAP_BT_ANT_DIV;
543 ath_info(common, "Set BT/WLAN RX diversity capability\n");
534 } 544 }
535} 545}
536 546
@@ -584,6 +594,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
584{ 594{
585 struct ath9k_platform_data *pdata = sc->dev->platform_data; 595 struct ath9k_platform_data *pdata = sc->dev->platform_data;
586 struct ath_hw *ah = NULL; 596 struct ath_hw *ah = NULL;
597 struct ath9k_hw_capabilities *pCap;
587 struct ath_common *common; 598 struct ath_common *common;
588 int ret = 0, i; 599 int ret = 0, i;
589 int csz = 0; 600 int csz = 0;
@@ -600,6 +611,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
600 ah->reg_ops.rmw = ath9k_reg_rmw; 611 ah->reg_ops.rmw = ath9k_reg_rmw;
601 atomic_set(&ah->intr_ref_cnt, -1); 612 atomic_set(&ah->intr_ref_cnt, -1);
602 sc->sc_ah = ah; 613 sc->sc_ah = ah;
614 pCap = &ah->caps;
603 615
604 sc->dfs_detector = dfs_pattern_detector_init(ah, NL80211_DFS_UNSET); 616 sc->dfs_detector = dfs_pattern_detector_init(ah, NL80211_DFS_UNSET);
605 617
@@ -631,11 +643,15 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
631 ath9k_init_platform(sc); 643 ath9k_init_platform(sc);
632 644
633 /* 645 /*
634 * Enable Antenna diversity only when BTCOEX is disabled 646 * Enable WLAN/BT RX Antenna diversity only when:
635 * and the user manually requests the feature. 647 *
648 * - BTCOEX is enabled
649 * - the user manually requests the feature.
650 * - the HW cap is set using the platform data.
636 */ 651 */
637 if (!common->btcoex_enabled && ath9k_enable_diversity) 652 if (common->btcoex_enabled && ath9k_bt_ant_diversity &&
638 common->antenna_diversity = 1; 653 (pCap->hw_caps & ATH9K_HW_CAP_BT_ANT_DIV))
654 common->bt_ant_diversity = 1;
639 655
640 spin_lock_init(&common->cc_lock); 656 spin_lock_init(&common->cc_lock);
641 657
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 1737a3e33685..afeab3ca9a69 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -238,9 +238,6 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
238 ath_restart_work(sc); 238 ath_restart_work(sc);
239 } 239 }
240 240
241 if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3)
242 ath_ant_comb_update(sc);
243
244 ieee80211_wake_queues(sc->hw); 241 ieee80211_wake_queues(sc->hw);
245 242
246 return true; 243 return true;
@@ -2094,7 +2091,7 @@ static void ath9k_wow_add_pattern(struct ath_softc *sc,
2094{ 2091{
2095 struct ath_hw *ah = sc->sc_ah; 2092 struct ath_hw *ah = sc->sc_ah;
2096 struct ath9k_wow_pattern *wow_pattern = NULL; 2093 struct ath9k_wow_pattern *wow_pattern = NULL;
2097 struct cfg80211_wowlan_trig_pkt_pattern *patterns = wowlan->patterns; 2094 struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
2098 int mask_len; 2095 int mask_len;
2099 s8 i = 0; 2096 s8 i = 0;
2100 2097
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index c585c9b35973..76e8c359bbf8 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -29,6 +29,14 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
29 { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ 29 { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
30 { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ 30 { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
31 { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ 31 { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
32
33 /* AR9285 card for Asus */
34 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
35 0x002B,
36 PCI_VENDOR_ID_AZWAVE,
37 0x2C37),
38 .driver_data = ATH9K_PCI_BT_ANT_DIV },
39
32 { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ 40 { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
33 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ 41 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
34 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ 42 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
@@ -40,29 +48,101 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
40 0x0032, 48 0x0032,
41 PCI_VENDOR_ID_AZWAVE, 49 PCI_VENDOR_ID_AZWAVE,
42 0x2086), 50 0x2086),
43 .driver_data = ATH9K_PCI_CUS198 }, 51 .driver_data = ATH9K_PCI_CUS198 | ATH9K_PCI_BT_ANT_DIV },
44 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 52 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
45 0x0032, 53 0x0032,
46 PCI_VENDOR_ID_AZWAVE, 54 PCI_VENDOR_ID_AZWAVE,
47 0x1237), 55 0x1237),
48 .driver_data = ATH9K_PCI_CUS198 }, 56 .driver_data = ATH9K_PCI_CUS198 | ATH9K_PCI_BT_ANT_DIV },
49 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 57 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
50 0x0032, 58 0x0032,
51 PCI_VENDOR_ID_AZWAVE, 59 PCI_VENDOR_ID_AZWAVE,
52 0x2126), 60 0x2126),
53 .driver_data = ATH9K_PCI_CUS198 }, 61 .driver_data = ATH9K_PCI_CUS198 | ATH9K_PCI_BT_ANT_DIV },
54 62
55 /* PCI-E CUS230 */ 63 /* PCI-E CUS230 */
56 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 64 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
57 0x0032, 65 0x0032,
58 PCI_VENDOR_ID_AZWAVE, 66 PCI_VENDOR_ID_AZWAVE,
59 0x2152), 67 0x2152),
60 .driver_data = ATH9K_PCI_CUS230 }, 68 .driver_data = ATH9K_PCI_CUS230 | ATH9K_PCI_BT_ANT_DIV },
61 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 69 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
62 0x0032, 70 0x0032,
63 PCI_VENDOR_ID_FOXCONN, 71 PCI_VENDOR_ID_FOXCONN,
64 0xE075), 72 0xE075),
65 .driver_data = ATH9K_PCI_CUS230 }, 73 .driver_data = ATH9K_PCI_CUS230 | ATH9K_PCI_BT_ANT_DIV },
74
75 /* WB225 */
76 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
77 0x0032,
78 PCI_VENDOR_ID_ATHEROS,
79 0x3119),
80 .driver_data = ATH9K_PCI_BT_ANT_DIV },
81 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
82 0x0032,
83 PCI_VENDOR_ID_ATHEROS,
84 0x3122),
85 .driver_data = ATH9K_PCI_BT_ANT_DIV },
86 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
87 0x0032,
88 0x185F, /* WNC */
89 0x3119),
90 .driver_data = ATH9K_PCI_BT_ANT_DIV },
91 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
92 0x0032,
93 0x185F, /* WNC */
94 0x3027),
95 .driver_data = ATH9K_PCI_BT_ANT_DIV },
96 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
97 0x0032,
98 PCI_VENDOR_ID_SAMSUNG,
99 0x4105),
100 .driver_data = ATH9K_PCI_BT_ANT_DIV },
101 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
102 0x0032,
103 PCI_VENDOR_ID_SAMSUNG,
104 0x4106),
105 .driver_data = ATH9K_PCI_BT_ANT_DIV },
106 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
107 0x0032,
108 PCI_VENDOR_ID_SAMSUNG,
109 0x410D),
110 .driver_data = ATH9K_PCI_BT_ANT_DIV },
111 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
112 0x0032,
113 PCI_VENDOR_ID_SAMSUNG,
114 0x410E),
115 .driver_data = ATH9K_PCI_BT_ANT_DIV },
116 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
117 0x0032,
118 PCI_VENDOR_ID_SAMSUNG,
119 0x410F),
120 .driver_data = ATH9K_PCI_BT_ANT_DIV },
121 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
122 0x0032,
123 PCI_VENDOR_ID_SAMSUNG,
124 0xC706),
125 .driver_data = ATH9K_PCI_BT_ANT_DIV },
126 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
127 0x0032,
128 PCI_VENDOR_ID_SAMSUNG,
129 0xC680),
130 .driver_data = ATH9K_PCI_BT_ANT_DIV },
131 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
132 0x0032,
133 PCI_VENDOR_ID_SAMSUNG,
134 0xC708),
135 .driver_data = ATH9K_PCI_BT_ANT_DIV },
136 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
137 0x0032,
138 PCI_VENDOR_ID_LENOVO,
139 0x3218),
140 .driver_data = ATH9K_PCI_BT_ANT_DIV },
141 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
142 0x0032,
143 PCI_VENDOR_ID_LENOVO,
144 0x3219),
145 .driver_data = ATH9K_PCI_BT_ANT_DIV },
66 146
67 { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ 147 { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */
68 { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ 148 { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 8b380305b0fc..4a1b99238ec2 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -48,4 +48,11 @@
48#define AR_PHY_PLL_CONTROL 0x16180 48#define AR_PHY_PLL_CONTROL 0x16180
49#define AR_PHY_PLL_MODE 0x16184 49#define AR_PHY_PLL_MODE 0x16184
50 50
51enum ath9k_ant_div_comb_lna_conf {
52 ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2,
53 ATH_ANT_DIV_COMB_LNA2,
54 ATH_ANT_DIV_COMB_LNA1,
55 ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2,
56};
57
51#endif 58#endif
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 7eb1f4b458e4..a3c4ca0c94bf 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1275,6 +1275,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1275} 1275}
1276 1276
1277static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, 1277static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1278 struct cfg80211_chan_def *chandef,
1278 struct ieee80211_sta *sta, void *priv_sta) 1279 struct ieee80211_sta *sta, void *priv_sta)
1279{ 1280{
1280 struct ath_softc *sc = priv; 1281 struct ath_softc *sc = priv;
@@ -1313,6 +1314,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1313} 1314}
1314 1315
1315static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, 1316static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1317 struct cfg80211_chan_def *chandef,
1316 struct ieee80211_sta *sta, void *priv_sta, 1318 struct ieee80211_sta *sta, void *priv_sta,
1317 u32 changed) 1319 u32 changed)
1318{ 1320{
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 927992732620..52cd5219aba9 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1023,7 +1023,7 @@ void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop)
1023} 1023}
1024 1024
1025static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, 1025static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1026 struct ath_tx_info *info, int len) 1026 struct ath_tx_info *info, int len, bool rts)
1027{ 1027{
1028 struct ath_hw *ah = sc->sc_ah; 1028 struct ath_hw *ah = sc->sc_ah;
1029 struct sk_buff *skb; 1029 struct sk_buff *skb;
@@ -1032,6 +1032,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1032 const struct ieee80211_rate *rate; 1032 const struct ieee80211_rate *rate;
1033 struct ieee80211_hdr *hdr; 1033 struct ieee80211_hdr *hdr;
1034 struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); 1034 struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
1035 u32 rts_thresh = sc->hw->wiphy->rts_threshold;
1035 int i; 1036 int i;
1036 u8 rix = 0; 1037 u8 rix = 0;
1037 1038
@@ -1054,7 +1055,17 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1054 rix = rates[i].idx; 1055 rix = rates[i].idx;
1055 info->rates[i].Tries = rates[i].count; 1056 info->rates[i].Tries = rates[i].count;
1056 1057
1057 if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) { 1058 /*
1059 * Handle RTS threshold for unaggregated HT frames.
1060 */
1061 if (bf_isampdu(bf) && !bf_isaggr(bf) &&
1062 (rates[i].flags & IEEE80211_TX_RC_MCS) &&
1063 unlikely(rts_thresh != (u32) -1)) {
1064 if (!rts_thresh || (len > rts_thresh))
1065 rts = true;
1066 }
1067
1068 if (rts || rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
1058 info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; 1069 info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
1059 info->flags |= ATH9K_TXDESC_RTSENA; 1070 info->flags |= ATH9K_TXDESC_RTSENA;
1060 } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 1071 } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
@@ -1147,6 +1158,8 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf,
1147 struct ath_hw *ah = sc->sc_ah; 1158 struct ath_hw *ah = sc->sc_ah;
1148 struct ath_buf *bf_first = NULL; 1159 struct ath_buf *bf_first = NULL;
1149 struct ath_tx_info info; 1160 struct ath_tx_info info;
1161 u32 rts_thresh = sc->hw->wiphy->rts_threshold;
1162 bool rts = false;
1150 1163
1151 memset(&info, 0, sizeof(info)); 1164 memset(&info, 0, sizeof(info));
1152 info.is_first = true; 1165 info.is_first = true;
@@ -1183,7 +1196,22 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf,
1183 info.flags |= (u32) bf->bf_state.bfs_paprd << 1196 info.flags |= (u32) bf->bf_state.bfs_paprd <<
1184 ATH9K_TXDESC_PAPRD_S; 1197 ATH9K_TXDESC_PAPRD_S;
1185 1198
1186 ath_buf_set_rate(sc, bf, &info, len); 1199 /*
1200 * mac80211 doesn't handle RTS threshold for HT because
1201 * the decision has to be taken based on AMPDU length
1202 * and aggregation is done entirely inside ath9k.
1203 * Set the RTS/CTS flag for the first subframe based
1204 * on the threshold.
1205 */
1206 if (aggr && (bf == bf_first) &&
1207 unlikely(rts_thresh != (u32) -1)) {
1208 /*
1209 * "len" is the size of the entire AMPDU.
1210 */
1211 if (!rts_thresh || (len > rts_thresh))
1212 rts = true;
1213 }
1214 ath_buf_set_rate(sc, bf, &info, len, rts);
1187 } 1215 }
1188 1216
1189 info.buf_addr[0] = bf->bf_buf_addr; 1217 info.buf_addr[0] = bf->bf_buf_addr;
@@ -2168,7 +2196,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2168 2196
2169 bf->bf_lastbf = bf; 2197 bf->bf_lastbf = bf;
2170 ath_set_rates(vif, NULL, bf); 2198 ath_set_rates(vif, NULL, bf);
2171 ath_buf_set_rate(sc, bf, &info, fi->framelen); 2199 ath_buf_set_rate(sc, bf, &info, fi->framelen, false);
2172 duration += info.rates[0].PktDuration; 2200 duration += info.rates[0].PktDuration;
2173 if (bf_tail) 2201 if (bf_tail)
2174 bf_tail->bf_next = bf; 2202 bf_tail->bf_next = bf;
diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile
index f891d514d881..990dd42ae79e 100644
--- a/drivers/net/wireless/ath/wil6210/Makefile
+++ b/drivers/net/wireless/ath/wil6210/Makefile
@@ -11,9 +11,6 @@ wil6210-y += txrx.o
11wil6210-y += debug.o 11wil6210-y += debug.o
12wil6210-$(CONFIG_WIL6210_TRACING) += trace.o 12wil6210-$(CONFIG_WIL6210_TRACING) += trace.o
13 13
14ifeq (, $(findstring -W,$(EXTRA_CFLAGS)))
15 subdir-ccflags-y += -Werror
16endif
17# for tracing framework to find trace.h 14# for tracing framework to find trace.h
18CFLAGS_trace.o := -I$(src) 15CFLAGS_trace.o := -I$(src)
19 16
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index ab636767fbde..1caa31992a7e 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -51,7 +51,7 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
51 if ((i % 64) == 0 && (i != 0)) 51 if ((i % 64) == 0 && (i != 0))
52 seq_printf(s, "\n"); 52 seq_printf(s, "\n");
53 seq_printf(s, "%s", (d->dma.status & BIT(0)) ? 53 seq_printf(s, "%s", (d->dma.status & BIT(0)) ?
54 "S" : (vring->ctx[i] ? "H" : "h")); 54 "S" : (vring->ctx[i].skb ? "H" : "h"));
55 } 55 }
56 seq_printf(s, "\n"); 56 seq_printf(s, "\n");
57 } 57 }
@@ -406,7 +406,7 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
406 volatile struct vring_tx_desc *d = 406 volatile struct vring_tx_desc *d =
407 &(vring->va[dbg_txdesc_index].tx); 407 &(vring->va[dbg_txdesc_index].tx);
408 volatile u32 *u = (volatile u32 *)d; 408 volatile u32 *u = (volatile u32 *)d;
409 struct sk_buff *skb = vring->ctx[dbg_txdesc_index]; 409 struct sk_buff *skb = vring->ctx[dbg_txdesc_index].skb;
410 410
411 seq_printf(s, "Tx[%3d] = {\n", dbg_txdesc_index); 411 seq_printf(s, "Tx[%3d] = {\n", dbg_txdesc_index);
412 seq_printf(s, " MAC = 0x%08x 0x%08x 0x%08x 0x%08x\n", 412 seq_printf(s, " MAC = 0x%08x 0x%08x 0x%08x 0x%08x\n",
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 29dd1e58cb17..717178f09aa8 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -127,6 +127,8 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
127 127
128 ndev->netdev_ops = &wil_netdev_ops; 128 ndev->netdev_ops = &wil_netdev_ops;
129 ndev->ieee80211_ptr = wdev; 129 ndev->ieee80211_ptr = wdev;
130 ndev->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
131 ndev->features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
130 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 132 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
131 wdev->netdev = ndev; 133 wdev->netdev = ndev;
132 134
diff --git a/drivers/net/wireless/ath/wil6210/trace.h b/drivers/net/wireless/ath/wil6210/trace.h
index eff1239be53a..e59239d22b94 100644
--- a/drivers/net/wireless/ath/wil6210/trace.h
+++ b/drivers/net/wireless/ath/wil6210/trace.h
@@ -37,36 +37,40 @@ static inline void trace_ ## name(proto) {}
37#endif /* !CONFIG_WIL6210_TRACING || defined(__CHECKER__) */ 37#endif /* !CONFIG_WIL6210_TRACING || defined(__CHECKER__) */
38 38
39DECLARE_EVENT_CLASS(wil6210_wmi, 39DECLARE_EVENT_CLASS(wil6210_wmi,
40 TP_PROTO(u16 id, void *buf, u16 buf_len), 40 TP_PROTO(struct wil6210_mbox_hdr_wmi *wmi, void *buf, u16 buf_len),
41 41
42 TP_ARGS(id, buf, buf_len), 42 TP_ARGS(wmi, buf, buf_len),
43 43
44 TP_STRUCT__entry( 44 TP_STRUCT__entry(
45 __field(u8, mid)
45 __field(u16, id) 46 __field(u16, id)
47 __field(u32, timestamp)
46 __field(u16, buf_len) 48 __field(u16, buf_len)
47 __dynamic_array(u8, buf, buf_len) 49 __dynamic_array(u8, buf, buf_len)
48 ), 50 ),
49 51
50 TP_fast_assign( 52 TP_fast_assign(
51 __entry->id = id; 53 __entry->mid = wmi->mid;
54 __entry->id = le16_to_cpu(wmi->id);
55 __entry->timestamp = le32_to_cpu(wmi->timestamp);
52 __entry->buf_len = buf_len; 56 __entry->buf_len = buf_len;
53 memcpy(__get_dynamic_array(buf), buf, buf_len); 57 memcpy(__get_dynamic_array(buf), buf, buf_len);
54 ), 58 ),
55 59
56 TP_printk( 60 TP_printk(
57 "id 0x%04x len %d", 61 "MID %d id 0x%04x len %d timestamp %d",
58 __entry->id, __entry->buf_len 62 __entry->mid, __entry->id, __entry->buf_len, __entry->timestamp
59 ) 63 )
60); 64);
61 65
62DEFINE_EVENT(wil6210_wmi, wil6210_wmi_cmd, 66DEFINE_EVENT(wil6210_wmi, wil6210_wmi_cmd,
63 TP_PROTO(u16 id, void *buf, u16 buf_len), 67 TP_PROTO(struct wil6210_mbox_hdr_wmi *wmi, void *buf, u16 buf_len),
64 TP_ARGS(id, buf, buf_len) 68 TP_ARGS(wmi, buf, buf_len)
65); 69);
66 70
67DEFINE_EVENT(wil6210_wmi, wil6210_wmi_event, 71DEFINE_EVENT(wil6210_wmi, wil6210_wmi_event,
68 TP_PROTO(u16 id, void *buf, u16 buf_len), 72 TP_PROTO(struct wil6210_mbox_hdr_wmi *wmi, void *buf, u16 buf_len),
69 TP_ARGS(id, buf, buf_len) 73 TP_ARGS(wmi, buf, buf_len)
70); 74);
71 75
72#define WIL6210_MSG_MAX (200) 76#define WIL6210_MSG_MAX (200)
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index d240b24e1ccf..ea1abeb18e5b 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -18,6 +18,9 @@
18#include <net/ieee80211_radiotap.h> 18#include <net/ieee80211_radiotap.h>
19#include <linux/if_arp.h> 19#include <linux/if_arp.h>
20#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21#include <linux/ip.h>
22#include <linux/ipv6.h>
23#include <net/ipv6.h>
21 24
22#include "wil6210.h" 25#include "wil6210.h"
23#include "wmi.h" 26#include "wmi.h"
@@ -70,7 +73,7 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
70 73
71 vring->swhead = 0; 74 vring->swhead = 0;
72 vring->swtail = 0; 75 vring->swtail = 0;
73 vring->ctx = kzalloc(vring->size * sizeof(vring->ctx[0]), GFP_KERNEL); 76 vring->ctx = kcalloc(vring->size, sizeof(vring->ctx[0]), GFP_KERNEL);
74 if (!vring->ctx) { 77 if (!vring->ctx) {
75 vring->va = NULL; 78 vring->va = NULL;
76 return -ENOMEM; 79 return -ENOMEM;
@@ -108,39 +111,39 @@ static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring,
108 111
109 while (!wil_vring_is_empty(vring)) { 112 while (!wil_vring_is_empty(vring)) {
110 dma_addr_t pa; 113 dma_addr_t pa;
111 struct sk_buff *skb;
112 u16 dmalen; 114 u16 dmalen;
115 struct wil_ctx *ctx;
113 116
114 if (tx) { 117 if (tx) {
115 struct vring_tx_desc dd, *d = &dd; 118 struct vring_tx_desc dd, *d = &dd;
116 volatile struct vring_tx_desc *_d = 119 volatile struct vring_tx_desc *_d =
117 &vring->va[vring->swtail].tx; 120 &vring->va[vring->swtail].tx;
118 121
122 ctx = &vring->ctx[vring->swtail];
119 *d = *_d; 123 *d = *_d;
120 pa = wil_desc_addr(&d->dma.addr); 124 pa = wil_desc_addr(&d->dma.addr);
121 dmalen = le16_to_cpu(d->dma.length); 125 dmalen = le16_to_cpu(d->dma.length);
122 skb = vring->ctx[vring->swtail]; 126 if (vring->ctx[vring->swtail].mapped_as_page) {
123 if (skb) {
124 dma_unmap_single(dev, pa, dmalen,
125 DMA_TO_DEVICE);
126 dev_kfree_skb_any(skb);
127 vring->ctx[vring->swtail] = NULL;
128 } else {
129 dma_unmap_page(dev, pa, dmalen, 127 dma_unmap_page(dev, pa, dmalen,
130 DMA_TO_DEVICE); 128 DMA_TO_DEVICE);
129 } else {
130 dma_unmap_single(dev, pa, dmalen,
131 DMA_TO_DEVICE);
131 } 132 }
133 if (ctx->skb)
134 dev_kfree_skb_any(ctx->skb);
132 vring->swtail = wil_vring_next_tail(vring); 135 vring->swtail = wil_vring_next_tail(vring);
133 } else { /* rx */ 136 } else { /* rx */
134 struct vring_rx_desc dd, *d = &dd; 137 struct vring_rx_desc dd, *d = &dd;
135 volatile struct vring_rx_desc *_d = 138 volatile struct vring_rx_desc *_d =
136 &vring->va[vring->swtail].rx; 139 &vring->va[vring->swhead].rx;
137 140
141 ctx = &vring->ctx[vring->swhead];
138 *d = *_d; 142 *d = *_d;
139 pa = wil_desc_addr(&d->dma.addr); 143 pa = wil_desc_addr(&d->dma.addr);
140 dmalen = le16_to_cpu(d->dma.length); 144 dmalen = le16_to_cpu(d->dma.length);
141 skb = vring->ctx[vring->swhead];
142 dma_unmap_single(dev, pa, dmalen, DMA_FROM_DEVICE); 145 dma_unmap_single(dev, pa, dmalen, DMA_FROM_DEVICE);
143 kfree_skb(skb); 146 kfree_skb(ctx->skb);
144 wil_vring_advance_head(vring, 1); 147 wil_vring_advance_head(vring, 1);
145 } 148 }
146 } 149 }
@@ -187,7 +190,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
187 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ 190 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
188 d->dma.length = cpu_to_le16(sz); 191 d->dma.length = cpu_to_le16(sz);
189 *_d = *d; 192 *_d = *d;
190 vring->ctx[i] = skb; 193 vring->ctx[i].skb = skb;
191 194
192 return 0; 195 return 0;
193} 196}
@@ -352,11 +355,11 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
352 return NULL; 355 return NULL;
353 } 356 }
354 357
355 skb = vring->ctx[vring->swhead]; 358 skb = vring->ctx[vring->swhead].skb;
356 d = wil_skb_rxdesc(skb); 359 d = wil_skb_rxdesc(skb);
357 *d = *_d; 360 *d = *_d;
358 pa = wil_desc_addr(&d->dma.addr); 361 pa = wil_desc_addr(&d->dma.addr);
359 vring->ctx[vring->swhead] = NULL; 362 vring->ctx[vring->swhead].skb = NULL;
360 wil_vring_advance_head(vring, 1); 363 wil_vring_advance_head(vring, 1);
361 364
362 dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); 365 dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE);
@@ -407,6 +410,21 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
407 return NULL; 410 return NULL;
408 } 411 }
409 412
413 /* L4 IDENT is on when HW calculated checksum, check status
414 * and in case of error drop the packet
415 * higher stack layers will handle retransmission (if required)
416 */
417 if (d->dma.status & RX_DMA_STATUS_L4_IDENT) {
418 /* L4 protocol identified, csum calculated */
419 if ((d->dma.error & RX_DMA_ERROR_L4_ERR) == 0) {
420 skb->ip_summed = CHECKSUM_UNNECESSARY;
421 } else {
422 wil_err(wil, "Incorrect checksum reported\n");
423 kfree_skb(skb);
424 return NULL;
425 }
426 }
427
410 ds_bits = wil_rxdesc_ds_bits(d); 428 ds_bits = wil_rxdesc_ds_bits(d);
411 if (ds_bits == 1) { 429 if (ds_bits == 1) {
412 /* 430 /*
@@ -646,6 +664,53 @@ static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len,
646 return 0; 664 return 0;
647} 665}
648 666
667static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil,
668 struct vring_tx_desc *d,
669 struct sk_buff *skb)
670{
671 int protocol;
672
673 if (skb->ip_summed != CHECKSUM_PARTIAL)
674 return 0;
675
676 switch (skb->protocol) {
677 case cpu_to_be16(ETH_P_IP):
678 protocol = ip_hdr(skb)->protocol;
679 break;
680 case cpu_to_be16(ETH_P_IPV6):
681 protocol = ipv6_hdr(skb)->nexthdr;
682 break;
683 default:
684 return -EINVAL;
685 }
686
687 switch (protocol) {
688 case IPPROTO_TCP:
689 d->dma.d0 |= (2 << DMA_CFG_DESC_TX_0_L4_TYPE_POS);
690 /* L4 header len: TCP header length */
691 d->dma.d0 |=
692 (tcp_hdrlen(skb) & DMA_CFG_DESC_TX_0_L4_LENGTH_MSK);
693 break;
694 case IPPROTO_UDP:
695 /* L4 header len: UDP header length */
696 d->dma.d0 |=
697 (sizeof(struct udphdr) & DMA_CFG_DESC_TX_0_L4_LENGTH_MSK);
698 break;
699 default:
700 return -EINVAL;
701 }
702
703 d->dma.ip_length = skb_network_header_len(skb);
704 d->dma.b11 = ETH_HLEN; /* MAC header length */
705 d->dma.b11 |= BIT(DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_POS);
706 /* Enable TCP/UDP checksum */
707 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_POS);
708 /* Calculate pseudo-header */
709 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_PSEUDO_HEADER_CALC_EN_POS);
710
711 return 0;
712}
713
649static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 714static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
650 struct sk_buff *skb) 715 struct sk_buff *skb)
651{ 716{
@@ -655,7 +720,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
655 u32 swhead = vring->swhead; 720 u32 swhead = vring->swhead;
656 int avail = wil_vring_avail_tx(vring); 721 int avail = wil_vring_avail_tx(vring);
657 int nr_frags = skb_shinfo(skb)->nr_frags; 722 int nr_frags = skb_shinfo(skb)->nr_frags;
658 uint f; 723 uint f = 0;
659 int vring_index = vring - wil->vring_tx; 724 int vring_index = vring - wil->vring_tx;
660 uint i = swhead; 725 uint i = swhead;
661 dma_addr_t pa; 726 dma_addr_t pa;
@@ -686,13 +751,20 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
686 return -EINVAL; 751 return -EINVAL;
687 /* 1-st segment */ 752 /* 1-st segment */
688 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); 753 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index);
754 /* Process TCP/UDP checksum offloading */
755 if (wil_tx_desc_offload_cksum_set(wil, d, skb)) {
756 wil_err(wil, "VRING #%d Failed to set cksum, drop packet\n",
757 vring_index);
758 goto dma_error;
759 }
760
689 d->mac.d[2] |= ((nr_frags + 1) << 761 d->mac.d[2] |= ((nr_frags + 1) <<
690 MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); 762 MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS);
691 if (nr_frags) 763 if (nr_frags)
692 *_d = *d; 764 *_d = *d;
693 765
694 /* middle segments */ 766 /* middle segments */
695 for (f = 0; f < nr_frags; f++) { 767 for (; f < nr_frags; f++) {
696 const struct skb_frag_struct *frag = 768 const struct skb_frag_struct *frag =
697 &skb_shinfo(skb)->frags[f]; 769 &skb_shinfo(skb)->frags[f];
698 int len = skb_frag_size(frag); 770 int len = skb_frag_size(frag);
@@ -703,7 +775,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
703 if (unlikely(dma_mapping_error(dev, pa))) 775 if (unlikely(dma_mapping_error(dev, pa)))
704 goto dma_error; 776 goto dma_error;
705 wil_tx_desc_map(d, pa, len, vring_index); 777 wil_tx_desc_map(d, pa, len, vring_index);
706 vring->ctx[i] = NULL; 778 vring->ctx[i].mapped_as_page = 1;
707 *_d = *d; 779 *_d = *d;
708 } 780 }
709 /* for the last seg only */ 781 /* for the last seg only */
@@ -712,6 +784,12 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
712 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); 784 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
713 *_d = *d; 785 *_d = *d;
714 786
787 /* hold reference to skb
788 * to prevent skb release before accounting
789 * in case of immediate "tx done"
790 */
791 vring->ctx[i].skb = skb_get(skb);
792
715 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4, 793 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
716 (const void *)d, sizeof(*d), false); 794 (const void *)d, sizeof(*d), false);
717 795
@@ -720,29 +798,31 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
720 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead); 798 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
721 trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags); 799 trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags);
722 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail)); 800 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
723 /* hold reference to skb
724 * to prevent skb release before accounting
725 * in case of immediate "tx done"
726 */
727 vring->ctx[i] = skb_get(skb);
728 801
729 return 0; 802 return 0;
730 dma_error: 803 dma_error:
731 /* unmap what we have mapped */ 804 /* unmap what we have mapped */
732 /* Note: increment @f to operate with positive index */ 805 nr_frags = f + 1; /* frags mapped + one for skb head */
733 for (f++; f > 0; f--) { 806 for (f = 0; f < nr_frags; f++) {
734 u16 dmalen; 807 u16 dmalen;
808 struct wil_ctx *ctx;
735 809
736 i = (swhead + f) % vring->size; 810 i = (swhead + f) % vring->size;
811 ctx = &vring->ctx[i];
737 _d = &(vring->va[i].tx); 812 _d = &(vring->va[i].tx);
738 *d = *_d; 813 *d = *_d;
739 _d->dma.status = TX_DMA_STATUS_DU; 814 _d->dma.status = TX_DMA_STATUS_DU;
740 pa = wil_desc_addr(&d->dma.addr); 815 pa = wil_desc_addr(&d->dma.addr);
741 dmalen = le16_to_cpu(d->dma.length); 816 dmalen = le16_to_cpu(d->dma.length);
742 if (vring->ctx[i]) 817 if (ctx->mapped_as_page)
743 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
744 else
745 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE); 818 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
819 else
820 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
821
822 if (ctx->skb)
823 dev_kfree_skb_any(ctx->skb);
824
825 memset(ctx, 0, sizeof(*ctx));
746 } 826 }
747 827
748 return -EINVAL; 828 return -EINVAL;
@@ -821,8 +901,9 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
821 &vring->va[vring->swtail].tx; 901 &vring->va[vring->swtail].tx;
822 struct vring_tx_desc dd, *d = &dd; 902 struct vring_tx_desc dd, *d = &dd;
823 dma_addr_t pa; 903 dma_addr_t pa;
824 struct sk_buff *skb;
825 u16 dmalen; 904 u16 dmalen;
905 struct wil_ctx *ctx = &vring->ctx[vring->swtail];
906 struct sk_buff *skb = ctx->skb;
826 907
827 *d = *_d; 908 *d = *_d;
828 909
@@ -840,7 +921,11 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
840 (const void *)d, sizeof(*d), false); 921 (const void *)d, sizeof(*d), false);
841 922
842 pa = wil_desc_addr(&d->dma.addr); 923 pa = wil_desc_addr(&d->dma.addr);
843 skb = vring->ctx[vring->swtail]; 924 if (ctx->mapped_as_page)
925 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
926 else
927 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
928
844 if (skb) { 929 if (skb) {
845 if (d->dma.error == 0) { 930 if (d->dma.error == 0) {
846 ndev->stats.tx_packets++; 931 ndev->stats.tx_packets++;
@@ -849,16 +934,15 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
849 ndev->stats.tx_errors++; 934 ndev->stats.tx_errors++;
850 } 935 }
851 936
852 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
853 dev_kfree_skb_any(skb); 937 dev_kfree_skb_any(skb);
854 vring->ctx[vring->swtail] = NULL;
855 } else {
856 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
857 } 938 }
858 d->dma.addr.addr_low = 0; 939 memset(ctx, 0, sizeof(*ctx));
859 d->dma.addr.addr_high = 0; 940 /*
860 d->dma.length = 0; 941 * There is no need to touch HW descriptor:
861 d->dma.status = TX_DMA_STATUS_DU; 942 * - ststus bit TX_DMA_STATUS_DU is set by design,
943 * so hardware will not try to process this desc.,
944 * - rest of descriptor will be initialized on Tx.
945 */
862 vring->swtail = wil_vring_next_tail(vring); 946 vring->swtail = wil_vring_next_tail(vring);
863 done++; 947 done++;
864 } 948 }
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index 859aea68a1fa..b3828279204c 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -235,7 +235,16 @@ struct vring_tx_mac {
235 235
236#define DMA_CFG_DESC_TX_0_L4_TYPE_POS 30 236#define DMA_CFG_DESC_TX_0_L4_TYPE_POS 30
237#define DMA_CFG_DESC_TX_0_L4_TYPE_LEN 2 237#define DMA_CFG_DESC_TX_0_L4_TYPE_LEN 2
238#define DMA_CFG_DESC_TX_0_L4_TYPE_MSK 0xC0000000 238#define DMA_CFG_DESC_TX_0_L4_TYPE_MSK 0xC0000000 /* L4 type: 0-UDP, 2-TCP */
239
240
241#define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_POS 0
242#define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_LEN 7
243#define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_MSK 0x7F /* MAC hdr len */
244
245#define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_POS 7
246#define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_LEN 1
247#define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_MSK 0x80 /* 1-IPv4, 0-IPv6 */
239 248
240 249
241#define TX_DMA_STATUS_DU BIT(0) 250#define TX_DMA_STATUS_DU BIT(0)
@@ -334,8 +343,17 @@ struct vring_rx_mac {
334 343
335#define RX_DMA_D0_CMD_DMA_IT BIT(10) 344#define RX_DMA_D0_CMD_DMA_IT BIT(10)
336 345
346/* Error field, offload bits */
347#define RX_DMA_ERROR_L3_ERR BIT(4)
348#define RX_DMA_ERROR_L4_ERR BIT(5)
349
350
351/* Status field */
337#define RX_DMA_STATUS_DU BIT(0) 352#define RX_DMA_STATUS_DU BIT(0)
338#define RX_DMA_STATUS_ERROR BIT(2) 353#define RX_DMA_STATUS_ERROR BIT(2)
354
355#define RX_DMA_STATUS_L3_IDENT BIT(4)
356#define RX_DMA_STATUS_L4_IDENT BIT(5)
339#define RX_DMA_STATUS_PHY_INFO BIT(6) 357#define RX_DMA_STATUS_PHY_INFO BIT(6)
340 358
341struct vring_rx_dma { 359struct vring_rx_dma {
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 44fdab51de7e..c4a51638736a 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -156,11 +156,22 @@ struct wil6210_mbox_hdr {
156/* max. value for wil6210_mbox_hdr.len */ 156/* max. value for wil6210_mbox_hdr.len */
157#define MAX_MBOXITEM_SIZE (240) 157#define MAX_MBOXITEM_SIZE (240)
158 158
159/**
160 * struct wil6210_mbox_hdr_wmi - WMI header
161 *
162 * @mid: MAC ID
163 * 00 - default, created by FW
164 * 01..0f - WiFi ports, driver to create
165 * 10..fe - debug
166 * ff - broadcast
167 * @id: command/event ID
168 * @timestamp: FW fills for events, free-running msec timer
169 */
159struct wil6210_mbox_hdr_wmi { 170struct wil6210_mbox_hdr_wmi {
160 u8 reserved0[2]; 171 u8 mid;
172 u8 reserved;
161 __le16 id; 173 __le16 id;
162 __le16 info1; /* bits [0..3] - device_id, rest - unused */ 174 __le32 timestamp;
163 u8 reserved1[2];
164} __packed; 175} __packed;
165 176
166struct pending_wmi_event { 177struct pending_wmi_event {
@@ -172,6 +183,14 @@ struct pending_wmi_event {
172 } __packed event; 183 } __packed event;
173}; 184};
174 185
186/**
187 * struct wil_ctx - software context for Vring descriptor
188 */
189struct wil_ctx {
190 struct sk_buff *skb;
191 u8 mapped_as_page:1;
192};
193
175union vring_desc; 194union vring_desc;
176 195
177struct vring { 196struct vring {
@@ -181,7 +200,7 @@ struct vring {
181 u32 swtail; 200 u32 swtail;
182 u32 swhead; 201 u32 swhead;
183 u32 hwtail; /* write here to inform hw */ 202 u32 hwtail; /* write here to inform hw */
184 void **ctx; /* void *ctx[size] - software context */ 203 struct wil_ctx *ctx; /* ctx[size] - software context */
185}; 204};
186 205
187enum { /* for wil6210_priv.status */ 206enum { /* for wil6210_priv.status */
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index dc8059ad4bab..5220f158b8f5 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -172,8 +172,8 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
172 .len = cpu_to_le16(sizeof(cmd.wmi) + len), 172 .len = cpu_to_le16(sizeof(cmd.wmi) + len),
173 }, 173 },
174 .wmi = { 174 .wmi = {
175 .mid = 0,
175 .id = cpu_to_le16(cmdid), 176 .id = cpu_to_le16(cmdid),
176 .info1 = 0,
177 }, 177 },
178 }; 178 };
179 struct wil6210_mbox_ring *r = &wil->mbox_ctl.tx; 179 struct wil6210_mbox_ring *r = &wil->mbox_ctl.tx;
@@ -248,7 +248,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
248 iowrite32(r->head = next_head, wil->csr + HOST_MBOX + 248 iowrite32(r->head = next_head, wil->csr + HOST_MBOX +
249 offsetof(struct wil6210_mbox_ctl, tx.head)); 249 offsetof(struct wil6210_mbox_ctl, tx.head));
250 250
251 trace_wil6210_wmi_cmd(cmdid, buf, len); 251 trace_wil6210_wmi_cmd(&cmd.wmi, buf, len);
252 252
253 /* interrupt to FW */ 253 /* interrupt to FW */
254 iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT); 254 iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT);
@@ -640,9 +640,13 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
640 hdr.flags); 640 hdr.flags);
641 if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) && 641 if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) &&
642 (len >= sizeof(struct wil6210_mbox_hdr_wmi))) { 642 (len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
643 u16 id = le16_to_cpu(evt->event.wmi.id); 643 struct wil6210_mbox_hdr_wmi *wmi = &evt->event.wmi;
644 wil_dbg_wmi(wil, "WMI event 0x%04x\n", id); 644 u16 id = le16_to_cpu(wmi->id);
645 trace_wil6210_wmi_event(id, &evt->event.wmi, len); 645 u32 tstamp = le32_to_cpu(wmi->timestamp);
646 wil_dbg_wmi(wil, "WMI event 0x%04x MID %d @%d msec\n",
647 id, wmi->mid, tstamp);
648 trace_wil6210_wmi_event(wmi, &wmi[1],
649 len - sizeof(*wmi));
646 } 650 }
647 wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1, 651 wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1,
648 &evt->event.hdr, sizeof(hdr) + len, true); 652 &evt->event.hdr, sizeof(hdr) + len, true);
@@ -920,6 +924,12 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
920 cmd.sniffer_cfg.phy_support = 924 cmd.sniffer_cfg.phy_support =
921 cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL) 925 cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL)
922 ? WMI_SNIFFER_CP : WMI_SNIFFER_DP); 926 ? WMI_SNIFFER_CP : WMI_SNIFFER_DP);
927 } else {
928 /* Initialize offload (in non-sniffer mode).
929 * Linux IP stack always calculates IP checksum
930 * HW always calculate TCP/UDP checksum
931 */
932 cmd.l3_l4_ctrl |= (1 << L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS);
923 } 933 }
924 /* typical time for secure PCP is 840ms */ 934 /* typical time for secure PCP is 840ms */
925 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd), 935 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index bd982856d385..fa391e4eb098 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -928,9 +928,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
928 } 928 }
929 } else if (txs->phyerr) { 929 } else if (txs->phyerr) {
930 update_rate = false; 930 update_rate = false;
931 brcms_err(wlc->hw->d11core, 931 brcms_dbg_ht(wlc->hw->d11core,
932 "%s: ampdu tx phy error (0x%x)\n", 932 "%s: ampdu tx phy error (0x%x)\n",
933 __func__, txs->phyerr); 933 __func__, txs->phyerr);
934 } 934 }
935 } 935 }
936 936
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 9fd6f2fef11b..7ca10bf4a4d3 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -882,8 +882,8 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
882 mcl = le16_to_cpu(txh->MacTxControlLow); 882 mcl = le16_to_cpu(txh->MacTxControlLow);
883 883
884 if (txs->phyerr) 884 if (txs->phyerr)
885 brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n", 885 brcms_dbg_tx(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n",
886 txs->phyerr, txh->MainRates); 886 txs->phyerr, txh->MainRates);
887 887
888 if (txs->frameid != le16_to_cpu(txh->TxFrameID)) { 888 if (txs->frameid != le16_to_cpu(txh->TxFrameID)) {
889 brcms_err(wlc->hw->d11core, "frameid != txh->TxFrameID\n"); 889 brcms_err(wlc->hw->d11core, "frameid != txh->TxFrameID\n");
diff --git a/drivers/net/wireless/cw1200/wsm.h b/drivers/net/wireless/cw1200/wsm.h
index 7afc613c3706..48086e849515 100644
--- a/drivers/net/wireless/cw1200/wsm.h
+++ b/drivers/net/wireless/cw1200/wsm.h
@@ -832,7 +832,7 @@ struct wsm_tx {
832 /* the MSDU shall be terminated. Overrides the global */ 832 /* the MSDU shall be terminated. Overrides the global */
833 /* dot11MaxTransmitMsduLifeTime setting [optional] */ 833 /* dot11MaxTransmitMsduLifeTime setting [optional] */
834 /* Device will set the default value if this is 0. */ 834 /* Device will set the default value if this is 0. */
835 u32 expire_time; 835 __le32 expire_time;
836 836
837 /* WSM_HT_TX_... */ 837 /* WSM_HT_TX_... */
838 __le32 ht_tx_parameters; 838 __le32 ht_tx_parameters;
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 15f0fad39add..e4f56ad26cd8 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -667,7 +667,7 @@ static int prism2_open(struct net_device *dev)
667 if (local->no_pri) { 667 if (local->no_pri) {
668 printk(KERN_DEBUG "%s: could not set interface UP - no PRI " 668 printk(KERN_DEBUG "%s: could not set interface UP - no PRI "
669 "f/w\n", dev->name); 669 "f/w\n", dev->name);
670 return 1; 670 return -ENODEV;
671 } 671 }
672 672
673 if ((local->func->card_present && !local->func->card_present(local)) || 673 if ((local->func->card_present && !local->func->card_present(local)) ||
@@ -682,7 +682,7 @@ static int prism2_open(struct net_device *dev)
682 printk(KERN_WARNING "%s: could not enable MAC port\n", 682 printk(KERN_WARNING "%s: could not enable MAC port\n",
683 dev->name); 683 dev->name);
684 prism2_close(dev); 684 prism2_close(dev);
685 return 1; 685 return -ENODEV;
686 } 686 }
687 if (!local->dev_enabled) 687 if (!local->dev_enabled)
688 prism2_callback(local, PRISM2_CALLBACK_ENABLE); 688 prism2_callback(local, PRISM2_CALLBACK_ENABLE);
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c
index fe31590a51b2..aea667b430c3 100644
--- a/drivers/net/wireless/iwlegacy/3945-rs.c
+++ b/drivers/net/wireless/iwlegacy/3945-rs.c
@@ -887,6 +887,7 @@ il3945_remove_debugfs(void *il, void *il_sta)
887 */ 887 */
888static void 888static void
889il3945_rs_rate_init_stub(void *il_r, struct ieee80211_supported_band *sband, 889il3945_rs_rate_init_stub(void *il_r, struct ieee80211_supported_band *sband,
890 struct cfg80211_chan_def *chandef,
890 struct ieee80211_sta *sta, void *il_sta) 891 struct ieee80211_sta *sta, void *il_sta)
891{ 892{
892} 893}
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index c092033945cc..f09e257759d5 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -475,6 +475,8 @@ il3945_is_network_packet(struct il_priv *il, struct ieee80211_hdr *header)
475 } 475 }
476} 476}
477 477
478#define SMALL_PACKET_SIZE 256
479
478static void 480static void
479il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb, 481il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,
480 struct ieee80211_rx_status *stats) 482 struct ieee80211_rx_status *stats)
@@ -483,14 +485,13 @@ il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,
483 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IL_RX_DATA(pkt); 485 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IL_RX_DATA(pkt);
484 struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt); 486 struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt);
485 struct il3945_rx_frame_end *rx_end = IL_RX_END(pkt); 487 struct il3945_rx_frame_end *rx_end = IL_RX_END(pkt);
486 u16 len = le16_to_cpu(rx_hdr->len); 488 u32 len = le16_to_cpu(rx_hdr->len);
487 struct sk_buff *skb; 489 struct sk_buff *skb;
488 __le16 fc = hdr->frame_control; 490 __le16 fc = hdr->frame_control;
491 u32 fraglen = PAGE_SIZE << il->hw_params.rx_page_order;
489 492
490 /* We received data from the HW, so stop the watchdog */ 493 /* We received data from the HW, so stop the watchdog */
491 if (unlikely 494 if (unlikely(len + IL39_RX_FRAME_SIZE > fraglen)) {
492 (len + IL39_RX_FRAME_SIZE >
493 PAGE_SIZE << il->hw_params.rx_page_order)) {
494 D_DROP("Corruption detected!\n"); 495 D_DROP("Corruption detected!\n");
495 return; 496 return;
496 } 497 }
@@ -506,26 +507,32 @@ il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,
506 D_INFO("Woke queues - frame received on passive channel\n"); 507 D_INFO("Woke queues - frame received on passive channel\n");
507 } 508 }
508 509
509 skb = dev_alloc_skb(128); 510 skb = dev_alloc_skb(SMALL_PACKET_SIZE);
510 if (!skb) { 511 if (!skb) {
511 IL_ERR("dev_alloc_skb failed\n"); 512 IL_ERR("dev_alloc_skb failed\n");
512 return; 513 return;
513 } 514 }
514 515
515 if (!il3945_mod_params.sw_crypto) 516 if (!il3945_mod_params.sw_crypto)
516 il_set_decrypted_flag(il, (struct ieee80211_hdr *)rxb_addr(rxb), 517 il_set_decrypted_flag(il, (struct ieee80211_hdr *)pkt,
517 le32_to_cpu(rx_end->status), stats); 518 le32_to_cpu(rx_end->status), stats);
518 519
519 skb_add_rx_frag(skb, 0, rxb->page, 520 /* If frame is small enough to fit into skb->head, copy it
520 (void *)rx_hdr->payload - (void *)pkt, len, 521 * and do not consume a full page
521 len); 522 */
522 523 if (len <= SMALL_PACKET_SIZE) {
524 memcpy(skb_put(skb, len), rx_hdr->payload, len);
525 } else {
526 skb_add_rx_frag(skb, 0, rxb->page,
527 (void *)rx_hdr->payload - (void *)pkt, len,
528 fraglen);
529 il->alloc_rxb_page--;
530 rxb->page = NULL;
531 }
523 il_update_stats(il, false, fc, len); 532 il_update_stats(il, false, fc, len);
524 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); 533 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
525 534
526 ieee80211_rx(il->hw, skb); 535 ieee80211_rx(il->hw, skb);
527 il->alloc_rxb_page--;
528 rxb->page = NULL;
529} 536}
530 537
531#define IL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) 538#define IL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index f2ed62e37340..b411ab905284 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -574,9 +574,11 @@ il4965_translate_rx_status(struct il_priv *il, u32 decrypt_in)
574 return decrypt_out; 574 return decrypt_out;
575} 575}
576 576
577#define SMALL_PACKET_SIZE 256
578
577static void 579static void
578il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr, 580il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
579 u16 len, u32 ampdu_status, struct il_rx_buf *rxb, 581 u32 len, u32 ampdu_status, struct il_rx_buf *rxb,
580 struct ieee80211_rx_status *stats) 582 struct ieee80211_rx_status *stats)
581{ 583{
582 struct sk_buff *skb; 584 struct sk_buff *skb;
@@ -598,21 +600,25 @@ il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
598 il_set_decrypted_flag(il, hdr, ampdu_status, stats)) 600 il_set_decrypted_flag(il, hdr, ampdu_status, stats))
599 return; 601 return;
600 602
601 skb = dev_alloc_skb(128); 603 skb = dev_alloc_skb(SMALL_PACKET_SIZE);
602 if (!skb) { 604 if (!skb) {
603 IL_ERR("dev_alloc_skb failed\n"); 605 IL_ERR("dev_alloc_skb failed\n");
604 return; 606 return;
605 } 607 }
606 608
607 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len, 609 if (len <= SMALL_PACKET_SIZE) {
608 len); 610 memcpy(skb_put(skb, len), hdr, len);
611 } else {
612 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb),
613 len, PAGE_SIZE << il->hw_params.rx_page_order);
614 il->alloc_rxb_page--;
615 rxb->page = NULL;
616 }
609 617
610 il_update_stats(il, false, fc, len); 618 il_update_stats(il, false, fc, len);
611 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); 619 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
612 620
613 ieee80211_rx(il->hw, skb); 621 ieee80211_rx(il->hw, skb);
614 il->alloc_rxb_page--;
615 rxb->page = NULL;
616} 622}
617 623
618/* Called for N_RX (legacy ABG frames), or 624/* Called for N_RX (legacy ABG frames), or
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c
index ed3c42a63a43..3ccbaf791b48 100644
--- a/drivers/net/wireless/iwlegacy/4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/4965-rs.c
@@ -2803,6 +2803,7 @@ il4965_rs_remove_debugfs(void *il, void *il_sta)
2803 */ 2803 */
2804static void 2804static void
2805il4965_rs_rate_init_stub(void *il_r, struct ieee80211_supported_band *sband, 2805il4965_rs_rate_init_stub(void *il_r, struct ieee80211_supported_band *sband,
2806 struct cfg80211_chan_def *chandef,
2806 struct ieee80211_sta *sta, void *il_sta) 2807 struct ieee80211_sta *sta, void *il_sta)
2807{ 2808{
2808} 2809}
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index cbaa5c2c410f..e5c133ee7901 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -127,20 +127,3 @@ config IWLWIFI_DEVICE_TRACING
127 If unsure, say Y so we can help you better when problems 127 If unsure, say Y so we can help you better when problems
128 occur. 128 occur.
129endmenu 129endmenu
130
131config IWLWIFI_P2P
132 def_bool y
133 bool "iwlwifi experimental P2P support"
134 depends on IWLWIFI
135 help
136 This option enables experimental P2P support for some devices
137 based on microcode support. Since P2P support is still under
138 development, this option may even enable it for some devices
139 now that turn out to not support it in the future due to
140 microcode restrictions.
141
142 To determine if your microcode supports the experimental P2P
143 offered by this option, check if the driver advertises AP
144 support when it is loaded.
145
146 Say Y only if you want to experiment with P2P.
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 18355110deff..f2a86ffc3b4c 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -106,7 +106,6 @@ extern const struct iwl_dvm_cfg iwl_dvm_6030_cfg;
106#define STATUS_CHANNEL_SWITCH_PENDING 11 106#define STATUS_CHANNEL_SWITCH_PENDING 11
107#define STATUS_SCAN_COMPLETE 12 107#define STATUS_SCAN_COMPLETE 12
108#define STATUS_POWER_PMI 13 108#define STATUS_POWER_PMI 13
109#define STATUS_SCAN_ROC_EXPIRED 14
110 109
111struct iwl_ucode_capabilities; 110struct iwl_ucode_capabilities;
112 111
@@ -250,7 +249,6 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
250 249
251/* scan */ 250/* scan */
252void iwlagn_post_scan(struct iwl_priv *priv); 251void iwlagn_post_scan(struct iwl_priv *priv);
253void iwlagn_disable_roc(struct iwl_priv *priv);
254int iwl_force_rf_reset(struct iwl_priv *priv, bool external); 252int iwl_force_rf_reset(struct iwl_priv *priv, bool external);
255void iwl_init_scan_params(struct iwl_priv *priv); 253void iwl_init_scan_params(struct iwl_priv *priv);
256int iwl_scan_cancel(struct iwl_priv *priv); 254int iwl_scan_cancel(struct iwl_priv *priv);
@@ -265,10 +263,6 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
265 enum iwl_scan_type scan_type, 263 enum iwl_scan_type scan_type,
266 enum ieee80211_band band); 264 enum ieee80211_band band);
267 265
268void iwl_scan_roc_expired(struct iwl_priv *priv);
269void iwl_scan_offchannel_skb(struct iwl_priv *priv);
270void iwl_scan_offchannel_skb_status(struct iwl_priv *priv);
271
272/* For faster active scanning, scan will move to the next channel if fewer than 266/* For faster active scanning, scan will move to the next channel if fewer than
273 * PLCP_QUIET_THRESH packets are heard on this channel within 267 * PLCP_QUIET_THRESH packets are heard on this channel within
274 * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell 268 * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
index d5329489245a..d94f8ab15004 100644
--- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
@@ -69,19 +69,7 @@
69} while (0) 69} while (0)
70 70
71/* file operation */ 71/* file operation */
72#define DEBUGFS_READ_FUNC(name) \
73static ssize_t iwl_dbgfs_##name##_read(struct file *file, \
74 char __user *user_buf, \
75 size_t count, loff_t *ppos);
76
77#define DEBUGFS_WRITE_FUNC(name) \
78static ssize_t iwl_dbgfs_##name##_write(struct file *file, \
79 const char __user *user_buf, \
80 size_t count, loff_t *ppos);
81
82
83#define DEBUGFS_READ_FILE_OPS(name) \ 72#define DEBUGFS_READ_FILE_OPS(name) \
84 DEBUGFS_READ_FUNC(name); \
85static const struct file_operations iwl_dbgfs_##name##_ops = { \ 73static const struct file_operations iwl_dbgfs_##name##_ops = { \
86 .read = iwl_dbgfs_##name##_read, \ 74 .read = iwl_dbgfs_##name##_read, \
87 .open = simple_open, \ 75 .open = simple_open, \
@@ -89,7 +77,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
89}; 77};
90 78
91#define DEBUGFS_WRITE_FILE_OPS(name) \ 79#define DEBUGFS_WRITE_FILE_OPS(name) \
92 DEBUGFS_WRITE_FUNC(name); \
93static const struct file_operations iwl_dbgfs_##name##_ops = { \ 80static const struct file_operations iwl_dbgfs_##name##_ops = { \
94 .write = iwl_dbgfs_##name##_write, \ 81 .write = iwl_dbgfs_##name##_write, \
95 .open = simple_open, \ 82 .open = simple_open, \
@@ -98,8 +85,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
98 85
99 86
100#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ 87#define DEBUGFS_READ_WRITE_FILE_OPS(name) \
101 DEBUGFS_READ_FUNC(name); \
102 DEBUGFS_WRITE_FUNC(name); \
103static const struct file_operations iwl_dbgfs_##name##_ops = { \ 88static const struct file_operations iwl_dbgfs_##name##_ops = { \
104 .write = iwl_dbgfs_##name##_write, \ 89 .write = iwl_dbgfs_##name##_write, \
105 .read = iwl_dbgfs_##name##_read, \ 90 .read = iwl_dbgfs_##name##_read, \
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 60a4e0d15715..a79fdd137f95 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -540,7 +540,6 @@ struct iwl_rxon_context {
540enum iwl_scan_type { 540enum iwl_scan_type {
541 IWL_SCAN_NORMAL, 541 IWL_SCAN_NORMAL,
542 IWL_SCAN_RADIO_RESET, 542 IWL_SCAN_RADIO_RESET,
543 IWL_SCAN_ROC,
544}; 543};
545 544
546/** 545/**
@@ -825,12 +824,6 @@ struct iwl_priv {
825 struct reply_tx_error_statistics reply_tx_stats; 824 struct reply_tx_error_statistics reply_tx_stats;
826 struct reply_agg_tx_error_statistics reply_agg_tx_stats; 825 struct reply_agg_tx_error_statistics reply_agg_tx_stats;
827 826
828 /* remain-on-channel offload support */
829 struct ieee80211_channel *hw_roc_channel;
830 struct delayed_work hw_roc_disable_work;
831 int hw_roc_duration;
832 bool hw_roc_setup, hw_roc_start_notified;
833
834 /* bt coex */ 827 /* bt coex */
835 u8 bt_enable_flag; 828 u8 bt_enable_flag;
836 u8 bt_status; 829 u8 bt_status;
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 822f1a00efbb..f0a2c957d503 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -76,29 +76,6 @@ static const struct ieee80211_iface_limit iwlagn_2sta_limits[] = {
76 }, 76 },
77}; 77};
78 78
79static const struct ieee80211_iface_limit iwlagn_p2p_sta_go_limits[] = {
80 {
81 .max = 1,
82 .types = BIT(NL80211_IFTYPE_STATION),
83 },
84 {
85 .max = 1,
86 .types = BIT(NL80211_IFTYPE_P2P_GO) |
87 BIT(NL80211_IFTYPE_AP),
88 },
89};
90
91static const struct ieee80211_iface_limit iwlagn_p2p_2sta_limits[] = {
92 {
93 .max = 2,
94 .types = BIT(NL80211_IFTYPE_STATION),
95 },
96 {
97 .max = 1,
98 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
99 },
100};
101
102static const struct ieee80211_iface_combination 79static const struct ieee80211_iface_combination
103iwlagn_iface_combinations_dualmode[] = { 80iwlagn_iface_combinations_dualmode[] = {
104 { .num_different_channels = 1, 81 { .num_different_channels = 1,
@@ -114,21 +91,6 @@ iwlagn_iface_combinations_dualmode[] = {
114 }, 91 },
115}; 92};
116 93
117static const struct ieee80211_iface_combination
118iwlagn_iface_combinations_p2p[] = {
119 { .num_different_channels = 1,
120 .max_interfaces = 2,
121 .beacon_int_infra_match = true,
122 .limits = iwlagn_p2p_sta_go_limits,
123 .n_limits = ARRAY_SIZE(iwlagn_p2p_sta_go_limits),
124 },
125 { .num_different_channels = 1,
126 .max_interfaces = 2,
127 .limits = iwlagn_p2p_2sta_limits,
128 .n_limits = ARRAY_SIZE(iwlagn_p2p_2sta_limits),
129 },
130};
131
132/* 94/*
133 * Not a mac80211 entry point function, but it fits in with all the 95 * Not a mac80211 entry point function, but it fits in with all the
134 * other mac80211 functions grouped here. 96 * other mac80211 functions grouped here.
@@ -186,19 +148,13 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
186 148
187 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); 149 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
188 150
189 if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) { 151 if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
190 hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p;
191 hw->wiphy->n_iface_combinations =
192 ARRAY_SIZE(iwlagn_iface_combinations_p2p);
193 } else if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
194 hw->wiphy->iface_combinations = 152 hw->wiphy->iface_combinations =
195 iwlagn_iface_combinations_dualmode; 153 iwlagn_iface_combinations_dualmode;
196 hw->wiphy->n_iface_combinations = 154 hw->wiphy->n_iface_combinations =
197 ARRAY_SIZE(iwlagn_iface_combinations_dualmode); 155 ARRAY_SIZE(iwlagn_iface_combinations_dualmode);
198 } 156 }
199 157
200 hw->wiphy->max_remain_on_channel_duration = 500;
201
202 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 158 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
203 WIPHY_FLAG_DISABLE_BEACON_HINTS | 159 WIPHY_FLAG_DISABLE_BEACON_HINTS |
204 WIPHY_FLAG_IBSS_RSN; 160 WIPHY_FLAG_IBSS_RSN;
@@ -1156,126 +1112,6 @@ done:
1156 IWL_DEBUG_MAC80211(priv, "leave\n"); 1112 IWL_DEBUG_MAC80211(priv, "leave\n");
1157} 1113}
1158 1114
1159static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
1160 struct ieee80211_vif *vif,
1161 struct ieee80211_channel *channel,
1162 int duration,
1163 enum ieee80211_roc_type type)
1164{
1165 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1166 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
1167 int err = 0;
1168
1169 if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
1170 return -EOPNOTSUPP;
1171
1172 if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)))
1173 return -EOPNOTSUPP;
1174
1175 IWL_DEBUG_MAC80211(priv, "enter\n");
1176 mutex_lock(&priv->mutex);
1177
1178 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
1179 /* mac80211 should not scan while ROC or ROC while scanning */
1180 if (WARN_ON_ONCE(priv->scan_type != IWL_SCAN_RADIO_RESET)) {
1181 err = -EBUSY;
1182 goto out;
1183 }
1184
1185 iwl_scan_cancel_timeout(priv, 100);
1186
1187 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
1188 err = -EBUSY;
1189 goto out;
1190 }
1191 }
1192
1193 priv->hw_roc_channel = channel;
1194 /* convert from ms to TU */
1195 priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024);
1196 priv->hw_roc_start_notified = false;
1197 cancel_delayed_work(&priv->hw_roc_disable_work);
1198
1199 if (!ctx->is_active) {
1200 static const struct iwl_qos_info default_qos_data = {
1201 .def_qos_parm = {
1202 .ac[0] = {
1203 .cw_min = cpu_to_le16(3),
1204 .cw_max = cpu_to_le16(7),
1205 .aifsn = 2,
1206 .edca_txop = cpu_to_le16(1504),
1207 },
1208 .ac[1] = {
1209 .cw_min = cpu_to_le16(7),
1210 .cw_max = cpu_to_le16(15),
1211 .aifsn = 2,
1212 .edca_txop = cpu_to_le16(3008),
1213 },
1214 .ac[2] = {
1215 .cw_min = cpu_to_le16(15),
1216 .cw_max = cpu_to_le16(1023),
1217 .aifsn = 3,
1218 },
1219 .ac[3] = {
1220 .cw_min = cpu_to_le16(15),
1221 .cw_max = cpu_to_le16(1023),
1222 .aifsn = 7,
1223 },
1224 },
1225 };
1226
1227 ctx->is_active = true;
1228 ctx->qos_data = default_qos_data;
1229 ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
1230 memcpy(ctx->staging.node_addr,
1231 priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr,
1232 ETH_ALEN);
1233 memcpy(ctx->staging.bssid_addr,
1234 priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr,
1235 ETH_ALEN);
1236 err = iwlagn_commit_rxon(priv, ctx);
1237 if (err)
1238 goto out;
1239 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK |
1240 RXON_FILTER_PROMISC_MSK |
1241 RXON_FILTER_CTL2HOST_MSK;
1242
1243 err = iwlagn_commit_rxon(priv, ctx);
1244 if (err) {
1245 iwlagn_disable_roc(priv);
1246 goto out;
1247 }
1248 priv->hw_roc_setup = true;
1249 }
1250
1251 err = iwl_scan_initiate(priv, ctx->vif, IWL_SCAN_ROC, channel->band);
1252 if (err)
1253 iwlagn_disable_roc(priv);
1254
1255 out:
1256 mutex_unlock(&priv->mutex);
1257 IWL_DEBUG_MAC80211(priv, "leave\n");
1258
1259 return err;
1260}
1261
1262static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
1263{
1264 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1265
1266 if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
1267 return -EOPNOTSUPP;
1268
1269 IWL_DEBUG_MAC80211(priv, "enter\n");
1270 mutex_lock(&priv->mutex);
1271 iwl_scan_cancel_timeout(priv, priv->hw_roc_duration);
1272 iwlagn_disable_roc(priv);
1273 mutex_unlock(&priv->mutex);
1274 IWL_DEBUG_MAC80211(priv, "leave\n");
1275
1276 return 0;
1277}
1278
1279static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, 1115static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
1280 struct ieee80211_vif *vif, 1116 struct ieee80211_vif *vif,
1281 enum ieee80211_rssi_event rssi_event) 1117 enum ieee80211_rssi_event rssi_event)
@@ -1431,12 +1267,8 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
1431 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", 1267 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
1432 viftype, vif->addr); 1268 viftype, vif->addr);
1433 1269
1434 cancel_delayed_work_sync(&priv->hw_roc_disable_work);
1435
1436 mutex_lock(&priv->mutex); 1270 mutex_lock(&priv->mutex);
1437 1271
1438 iwlagn_disable_roc(priv);
1439
1440 if (!iwl_is_ready_rf(priv)) { 1272 if (!iwl_is_ready_rf(priv)) {
1441 IWL_WARN(priv, "Try to add interface when device not ready\n"); 1273 IWL_WARN(priv, "Try to add interface when device not ready\n");
1442 err = -EINVAL; 1274 err = -EINVAL;
@@ -1763,8 +1595,6 @@ struct ieee80211_ops iwlagn_hw_ops = {
1763 .channel_switch = iwlagn_mac_channel_switch, 1595 .channel_switch = iwlagn_mac_channel_switch,
1764 .flush = iwlagn_mac_flush, 1596 .flush = iwlagn_mac_flush,
1765 .tx_last_beacon = iwlagn_mac_tx_last_beacon, 1597 .tx_last_beacon = iwlagn_mac_tx_last_beacon,
1766 .remain_on_channel = iwlagn_mac_remain_on_channel,
1767 .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel,
1768 .rssi_callback = iwlagn_mac_rssi_callback, 1598 .rssi_callback = iwlagn_mac_rssi_callback,
1769 .set_tim = iwlagn_mac_set_tim, 1599 .set_tim = iwlagn_mac_set_tim,
1770}; 1600};
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 1531a4fc0960..7aad766865cf 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -587,11 +587,6 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
587 priv->contexts[IWL_RXON_CTX_PAN].interface_modes = 587 priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
588 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); 588 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
589 589
590 if (ucode_flags & IWL_UCODE_TLV_FLAGS_P2P)
591 priv->contexts[IWL_RXON_CTX_PAN].interface_modes |=
592 BIT(NL80211_IFTYPE_P2P_CLIENT) |
593 BIT(NL80211_IFTYPE_P2P_GO);
594
595 priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; 590 priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
596 priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; 591 priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
597 priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; 592 priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;
@@ -854,14 +849,6 @@ void iwl_down(struct iwl_priv *priv)
854 849
855 iwl_scan_cancel_timeout(priv, 200); 850 iwl_scan_cancel_timeout(priv, 200);
856 851
857 /*
858 * If active, scanning won't cancel it, so say it expired.
859 * No race since we hold the mutex here and a new one
860 * can't come in at this time.
861 */
862 if (priv->ucode_loaded && priv->cur_ucode != IWL_UCODE_INIT)
863 ieee80211_remain_on_channel_expired(priv->hw);
864
865 exit_pending = 852 exit_pending =
866 test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); 853 test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
867 854
@@ -1002,41 +989,6 @@ static void iwl_bg_restart(struct work_struct *data)
1002 } 989 }
1003} 990}
1004 991
1005
1006
1007
1008void iwlagn_disable_roc(struct iwl_priv *priv)
1009{
1010 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
1011
1012 lockdep_assert_held(&priv->mutex);
1013
1014 if (!priv->hw_roc_setup)
1015 return;
1016
1017 ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
1018 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1019
1020 priv->hw_roc_channel = NULL;
1021
1022 memset(ctx->staging.node_addr, 0, ETH_ALEN);
1023
1024 iwlagn_commit_rxon(priv, ctx);
1025
1026 ctx->is_active = false;
1027 priv->hw_roc_setup = false;
1028}
1029
1030static void iwlagn_disable_roc_work(struct work_struct *work)
1031{
1032 struct iwl_priv *priv = container_of(work, struct iwl_priv,
1033 hw_roc_disable_work.work);
1034
1035 mutex_lock(&priv->mutex);
1036 iwlagn_disable_roc(priv);
1037 mutex_unlock(&priv->mutex);
1038}
1039
1040/***************************************************************************** 992/*****************************************************************************
1041 * 993 *
1042 * driver setup and teardown 994 * driver setup and teardown
@@ -1053,8 +1005,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
1053 INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); 1005 INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
1054 INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); 1006 INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency);
1055 INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); 1007 INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
1056 INIT_DELAYED_WORK(&priv->hw_roc_disable_work,
1057 iwlagn_disable_roc_work);
1058 1008
1059 iwl_setup_scan_deferred_work(priv); 1009 iwl_setup_scan_deferred_work(priv);
1060 1010
@@ -1082,7 +1032,6 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv)
1082 1032
1083 cancel_work_sync(&priv->bt_full_concurrency); 1033 cancel_work_sync(&priv->bt_full_concurrency);
1084 cancel_work_sync(&priv->bt_runtime_config); 1034 cancel_work_sync(&priv->bt_runtime_config);
1085 cancel_delayed_work_sync(&priv->hw_roc_disable_work);
1086 1035
1087 del_timer_sync(&priv->statistics_periodic); 1036 del_timer_sync(&priv->statistics_periodic);
1088 del_timer_sync(&priv->ucode_trace); 1037 del_timer_sync(&priv->ucode_trace);
@@ -1169,12 +1118,6 @@ static void iwl_option_config(struct iwl_priv *priv)
1169#else 1118#else
1170 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n"); 1119 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n");
1171#endif 1120#endif
1172
1173#ifdef CONFIG_IWLWIFI_P2P
1174 IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n");
1175#else
1176 IWL_INFO(priv, "CONFIG_IWLWIFI_P2P disabled\n");
1177#endif
1178} 1121}
1179 1122
1180static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) 1123static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
@@ -1315,10 +1258,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1315 1258
1316 ucode_flags = fw->ucode_capa.flags; 1259 ucode_flags = fw->ucode_capa.flags;
1317 1260
1318#ifndef CONFIG_IWLWIFI_P2P
1319 ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
1320#endif
1321
1322 if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { 1261 if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) {
1323 priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; 1262 priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
1324 trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; 1263 trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
@@ -1413,7 +1352,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1413 * if not PAN, then don't support P2P -- might be a uCode 1352 * if not PAN, then don't support P2P -- might be a uCode
1414 * packaging bug or due to the eeprom check above 1353 * packaging bug or due to the eeprom check above
1415 */ 1354 */
1416 ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
1417 priv->sta_key_max_num = STA_KEY_MAX_NUM; 1355 priv->sta_key_max_num = STA_KEY_MAX_NUM;
1418 trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; 1356 trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
1419 1357
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c
index 1b693944123b..b647e506564c 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.c
@@ -2826,9 +2826,6 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2826 2826
2827 lq_sta->flush_timer = 0; 2827 lq_sta->flush_timer = 0;
2828 lq_sta->supp_rates = sta->supp_rates[sband->band]; 2828 lq_sta->supp_rates = sta->supp_rates[sband->band];
2829 for (j = 0; j < LQ_SIZE; j++)
2830 for (i = 0; i < IWL_RATE_COUNT; i++)
2831 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2832 2829
2833 IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init for station %d ***\n", 2830 IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init for station %d ***\n",
2834 sta_id); 2831 sta_id);
@@ -3319,7 +3316,8 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
3319 * station is added we ignore it. 3316 * station is added we ignore it.
3320 */ 3317 */
3321static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband, 3318static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband,
3322 struct ieee80211_sta *sta, void *priv_sta) 3319 struct cfg80211_chan_def *chandef,
3320 struct ieee80211_sta *sta, void *priv_sta)
3323{ 3321{
3324} 3322}
3325static struct rate_control_ops rs_ops = { 3323static struct rate_control_ops rs_ops = {
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index cd1ad0019185..d7ce2f12a907 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -564,11 +564,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
564 cmd.slots[0].type = 0; /* BSS */ 564 cmd.slots[0].type = 0; /* BSS */
565 cmd.slots[1].type = 1; /* PAN */ 565 cmd.slots[1].type = 1; /* PAN */
566 566
567 if (priv->hw_roc_setup) { 567 if (ctx_bss->vif && ctx_pan->vif) {
568 /* both contexts must be used for this to happen */
569 slot1 = IWL_MIN_SLOT_TIME;
570 slot0 = 3000;
571 } else if (ctx_bss->vif && ctx_pan->vif) {
572 int bcnint = ctx_pan->beacon_int; 568 int bcnint = ctx_pan->beacon_int;
573 int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1; 569 int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
574 570
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c
index 8c686a5b90ac..35e0ee8b4e5b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -100,9 +100,6 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
100 ieee80211_scan_completed(priv->hw, aborted); 100 ieee80211_scan_completed(priv->hw, aborted);
101 } 101 }
102 102
103 if (priv->scan_type == IWL_SCAN_ROC)
104 iwl_scan_roc_expired(priv);
105
106 priv->scan_type = IWL_SCAN_NORMAL; 103 priv->scan_type = IWL_SCAN_NORMAL;
107 priv->scan_vif = NULL; 104 priv->scan_vif = NULL;
108 priv->scan_request = NULL; 105 priv->scan_request = NULL;
@@ -130,9 +127,6 @@ static void iwl_process_scan_complete(struct iwl_priv *priv)
130 goto out_settings; 127 goto out_settings;
131 } 128 }
132 129
133 if (priv->scan_type == IWL_SCAN_ROC)
134 iwl_scan_roc_expired(priv);
135
136 if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) { 130 if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) {
137 int err; 131 int err;
138 132
@@ -284,12 +278,6 @@ static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
284 le32_to_cpu(notif->tsf_low), 278 le32_to_cpu(notif->tsf_low),
285 notif->status, notif->beacon_timer); 279 notif->status, notif->beacon_timer);
286 280
287 if (priv->scan_type == IWL_SCAN_ROC &&
288 !priv->hw_roc_start_notified) {
289 ieee80211_ready_on_channel(priv->hw);
290 priv->hw_roc_start_notified = true;
291 }
292
293 return 0; 281 return 0;
294} 282}
295 283
@@ -697,8 +685,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
697 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; 685 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
698 scan->quiet_time = IWL_ACTIVE_QUIET_TIME; 686 scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
699 687
700 if (priv->scan_type != IWL_SCAN_ROC && 688 if (iwl_is_any_associated(priv)) {
701 iwl_is_any_associated(priv)) {
702 u16 interval = 0; 689 u16 interval = 0;
703 u32 extra; 690 u32 extra;
704 u32 suspend_time = 100; 691 u32 suspend_time = 100;
@@ -706,9 +693,6 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
706 693
707 IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); 694 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
708 switch (priv->scan_type) { 695 switch (priv->scan_type) {
709 case IWL_SCAN_ROC:
710 WARN_ON(1);
711 break;
712 case IWL_SCAN_RADIO_RESET: 696 case IWL_SCAN_RADIO_RESET:
713 interval = 0; 697 interval = 0;
714 break; 698 break;
@@ -728,11 +712,6 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
728 scan->suspend_time = cpu_to_le32(scan_suspend_time); 712 scan->suspend_time = cpu_to_le32(scan_suspend_time);
729 IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", 713 IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
730 scan_suspend_time, interval); 714 scan_suspend_time, interval);
731 } else if (priv->scan_type == IWL_SCAN_ROC) {
732 scan->suspend_time = 0;
733 scan->max_out_time = 0;
734 scan->quiet_time = 0;
735 scan->quiet_plcp_th = 0;
736 } 715 }
737 716
738 switch (priv->scan_type) { 717 switch (priv->scan_type) {
@@ -774,9 +753,6 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
774 } else 753 } else
775 IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); 754 IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
776 break; 755 break;
777 case IWL_SCAN_ROC:
778 IWL_DEBUG_SCAN(priv, "Start ROC scan.\n");
779 break;
780 } 756 }
781 757
782 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; 758 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
@@ -898,7 +874,6 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
898 scan_cmd_size - sizeof(*scan)); 874 scan_cmd_size - sizeof(*scan));
899 break; 875 break;
900 case IWL_SCAN_RADIO_RESET: 876 case IWL_SCAN_RADIO_RESET:
901 case IWL_SCAN_ROC:
902 /* use bcast addr, will not be transmitted but must be valid */ 877 /* use bcast addr, will not be transmitted but must be valid */
903 cmd_len = iwl_fill_probe_req( 878 cmd_len = iwl_fill_probe_req(
904 (struct ieee80211_mgmt *)scan->data, 879 (struct ieee80211_mgmt *)scan->data,
@@ -926,46 +901,6 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
926 is_active, n_probes, 901 is_active, n_probes,
927 (void *)&scan->data[cmd_len]); 902 (void *)&scan->data[cmd_len]);
928 break; 903 break;
929 case IWL_SCAN_ROC: {
930 struct iwl_scan_channel *scan_ch;
931 int n_chan, i;
932 u16 dwell;
933
934 dwell = iwl_limit_dwell(priv, priv->hw_roc_duration);
935 n_chan = DIV_ROUND_UP(priv->hw_roc_duration, dwell);
936
937 scan->channel_count = n_chan;
938
939 scan_ch = (void *)&scan->data[cmd_len];
940
941 for (i = 0; i < n_chan; i++) {
942 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
943 scan_ch->channel =
944 cpu_to_le16(priv->hw_roc_channel->hw_value);
945
946 if (i == n_chan - 1)
947 dwell = priv->hw_roc_duration - i * dwell;
948
949 scan_ch->active_dwell =
950 scan_ch->passive_dwell = cpu_to_le16(dwell);
951
952 /* Set txpower levels to defaults */
953 scan_ch->dsp_atten = 110;
954
955 /* NOTE: if we were doing 6Mb OFDM for scans we'd use
956 * power level:
957 * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
958 */
959 if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ)
960 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
961 else
962 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
963
964 scan_ch++;
965 }
966 }
967
968 break;
969 } 904 }
970 905
971 if (scan->channel_count == 0) { 906 if (scan->channel_count == 0) {
@@ -1035,7 +970,6 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
1035 970
1036 IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", 971 IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
1037 scan_type == IWL_SCAN_NORMAL ? "" : 972 scan_type == IWL_SCAN_NORMAL ? "" :
1038 scan_type == IWL_SCAN_ROC ? "remain-on-channel " :
1039 "internal short "); 973 "internal short ");
1040 974
1041 set_bit(STATUS_SCANNING, &priv->status); 975 set_bit(STATUS_SCANNING, &priv->status);
@@ -1149,40 +1083,3 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv)
1149 mutex_unlock(&priv->mutex); 1083 mutex_unlock(&priv->mutex);
1150 } 1084 }
1151} 1085}
1152
1153void iwl_scan_roc_expired(struct iwl_priv *priv)
1154{
1155 /*
1156 * The status bit should be set here, to prevent a race
1157 * where the atomic_read returns 1, but before the execution continues
1158 * iwl_scan_offchannel_skb_status() checks if the status bit is set
1159 */
1160 set_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status);
1161
1162 if (atomic_read(&priv->num_aux_in_flight) == 0) {
1163 ieee80211_remain_on_channel_expired(priv->hw);
1164 priv->hw_roc_channel = NULL;
1165 schedule_delayed_work(&priv->hw_roc_disable_work,
1166 10 * HZ);
1167
1168 clear_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status);
1169 } else {
1170 IWL_DEBUG_SCAN(priv, "ROC done with %d frames in aux\n",
1171 atomic_read(&priv->num_aux_in_flight));
1172 }
1173}
1174
1175void iwl_scan_offchannel_skb(struct iwl_priv *priv)
1176{
1177 WARN_ON(!priv->hw_roc_start_notified);
1178 atomic_inc(&priv->num_aux_in_flight);
1179}
1180
1181void iwl_scan_offchannel_skb_status(struct iwl_priv *priv)
1182{
1183 if (atomic_dec_return(&priv->num_aux_in_flight) == 0 &&
1184 test_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status)) {
1185 IWL_DEBUG_SCAN(priv, "0 aux frames. Calling ROC expired\n");
1186 iwl_scan_roc_expired(priv);
1187 }
1188}
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 5ee983faa679..3db0bbb1d123 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -478,9 +478,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
478 if (sta_priv && sta_priv->client && !is_agg) 478 if (sta_priv && sta_priv->client && !is_agg)
479 atomic_inc(&sta_priv->pending_frames); 479 atomic_inc(&sta_priv->pending_frames);
480 480
481 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
482 iwl_scan_offchannel_skb(priv);
483
484 return 0; 481 return 0;
485 482
486drop_unlock_sta: 483drop_unlock_sta:
@@ -1158,7 +1155,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1158 struct sk_buff *skb; 1155 struct sk_buff *skb;
1159 struct iwl_rxon_context *ctx; 1156 struct iwl_rxon_context *ctx;
1160 bool is_agg = (txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); 1157 bool is_agg = (txq_id >= IWLAGN_FIRST_AMPDU_QUEUE);
1161 bool is_offchannel_skb;
1162 1158
1163 tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> 1159 tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >>
1164 IWLAGN_TX_RES_TID_POS; 1160 IWLAGN_TX_RES_TID_POS;
@@ -1178,8 +1174,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1178 1174
1179 __skb_queue_head_init(&skbs); 1175 __skb_queue_head_init(&skbs);
1180 1176
1181 is_offchannel_skb = false;
1182
1183 if (tx_resp->frame_count == 1) { 1177 if (tx_resp->frame_count == 1) {
1184 u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); 1178 u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl);
1185 next_reclaimed = IEEE80211_SEQ_TO_SN(next_reclaimed + 0x10); 1179 next_reclaimed = IEEE80211_SEQ_TO_SN(next_reclaimed + 0x10);
@@ -1256,8 +1250,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1256 if (!is_agg) 1250 if (!is_agg)
1257 iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); 1251 iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
1258 1252
1259 is_offchannel_skb =
1260 (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN);
1261 freed++; 1253 freed++;
1262 } 1254 }
1263 1255
@@ -1271,14 +1263,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1271 if (!is_agg && freed != 1) 1263 if (!is_agg && freed != 1)
1272 IWL_ERR(priv, "Q: %d, freed %d\n", txq_id, freed); 1264 IWL_ERR(priv, "Q: %d, freed %d\n", txq_id, freed);
1273 1265
1274 /*
1275 * An offchannel frame can be send only on the AUX queue, where
1276 * there is no aggregation (and reordering) so it only is single
1277 * skb is expected to be processed.
1278 */
1279 if (is_offchannel_skb && freed != 1)
1280 IWL_ERR(priv, "OFFCHANNEL SKB freed %d\n", freed);
1281
1282 IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id, 1266 IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id,
1283 iwl_get_tx_fail_reason(status), status); 1267 iwl_get_tx_fail_reason(status), status);
1284 1268
@@ -1298,9 +1282,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1298 ieee80211_tx_status_ni(priv->hw, skb); 1282 ieee80211_tx_status_ni(priv->hw, skb);
1299 } 1283 }
1300 1284
1301 if (is_offchannel_skb)
1302 iwl_scan_offchannel_skb_status(priv);
1303
1304 return 0; 1285 return 0;
1305} 1286}
1306 1287
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 22b7fa5b971a..76e14c046d94 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -99,6 +99,7 @@ static const struct iwl_base_params iwl7000_base_params = {
99 .wd_timeout = IWL_LONG_WD_TIMEOUT, 99 .wd_timeout = IWL_LONG_WD_TIMEOUT,
100 .max_event_log_size = 512, 100 .max_event_log_size = 512,
101 .shadow_reg_enable = true, 101 .shadow_reg_enable = true,
102 .pcie_l1_allowed = true,
102}; 103};
103 104
104static const struct iwl_ht_params iwl7000_ht_params = { 105static const struct iwl_ht_params iwl7000_ht_params = {
@@ -126,6 +127,16 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
126 .nvm_calib_ver = IWL7260_TX_POWER_VERSION, 127 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
127}; 128};
128 129
130const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
131 .name = "Intel(R) Dual Band Wireless AC 7260",
132 .fw_name_pre = IWL7260_FW_PRE,
133 IWL_DEVICE_7000,
134 .ht_params = &iwl7000_ht_params,
135 .nvm_ver = IWL7260_NVM_VERSION,
136 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
137 .high_temp = true,
138};
139
129const struct iwl_cfg iwl7260_2n_cfg = { 140const struct iwl_cfg iwl7260_2n_cfg = {
130 .name = "Intel(R) Dual Band Wireless N 7260", 141 .name = "Intel(R) Dual Band Wireless N 7260",
131 .fw_name_pre = IWL7260_FW_PRE, 142 .fw_name_pre = IWL7260_FW_PRE,
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 83b9ff6ff3ad..e4d370bff306 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -152,6 +152,7 @@ struct iwl_base_params {
152 unsigned int wd_timeout; 152 unsigned int wd_timeout;
153 u32 max_event_log_size; 153 u32 max_event_log_size;
154 const bool shadow_reg_enable; 154 const bool shadow_reg_enable;
155 const bool pcie_l1_allowed;
155}; 156};
156 157
157/* 158/*
@@ -205,6 +206,7 @@ struct iwl_eeprom_params {
205 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) 206 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
206 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity 207 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
207 * @internal_wimax_coex: internal wifi/wimax combo device 208 * @internal_wimax_coex: internal wifi/wimax combo device
209 * @high_temp: Is this NIC is designated to be in high temperature.
208 * 210 *
209 * We enable the driver to be backward compatible wrt. hardware features. 211 * We enable the driver to be backward compatible wrt. hardware features.
210 * API differences in uCode shouldn't be handled here but through TLVs 212 * API differences in uCode shouldn't be handled here but through TLVs
@@ -233,6 +235,7 @@ struct iwl_cfg {
233 enum iwl_led_mode led_mode; 235 enum iwl_led_mode led_mode;
234 const bool rx_with_siso_diversity; 236 const bool rx_with_siso_diversity;
235 const bool internal_wimax_coex; 237 const bool internal_wimax_coex;
238 bool high_temp;
236}; 239};
237 240
238/* 241/*
@@ -283,6 +286,7 @@ extern const struct iwl_cfg iwl135_bgn_cfg;
283#endif /* CONFIG_IWLDVM */ 286#endif /* CONFIG_IWLDVM */
284#if IS_ENABLED(CONFIG_IWLMVM) 287#if IS_ENABLED(CONFIG_IWLMVM)
285extern const struct iwl_cfg iwl7260_2ac_cfg; 288extern const struct iwl_cfg iwl7260_2ac_cfg;
289extern const struct iwl_cfg iwl7260_2ac_cfg_high_temp;
286extern const struct iwl_cfg iwl7260_2n_cfg; 290extern const struct iwl_cfg iwl7260_2n_cfg;
287extern const struct iwl_cfg iwl7260_n_cfg; 291extern const struct iwl_cfg iwl7260_n_cfg;
288extern const struct iwl_cfg iwl3160_2ac_cfg; 292extern const struct iwl_cfg iwl3160_2ac_cfg;
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index f844d5c748c0..bd335f0c40d1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -74,13 +74,22 @@
74 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). 74 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
75 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. 75 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
76 * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS 76 * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
77 * @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD
78 * @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api
79 * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
80 * (rather than two) IPv6 addresses
81 * @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API
77 */ 82 */
78enum iwl_ucode_tlv_flag { 83enum iwl_ucode_tlv_flag {
79 IWL_UCODE_TLV_FLAGS_PAN = BIT(0), 84 IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
80 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), 85 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
81 IWL_UCODE_TLV_FLAGS_MFP = BIT(2), 86 IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
82 IWL_UCODE_TLV_FLAGS_P2P = BIT(3), 87 IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
83 IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), 88 IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
89 IWL_UCODE_TLV_FLAGS_UAPSD = BIT(6),
90 IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8),
91 IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10),
92 IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11),
84}; 93};
85 94
86/* The default calibrate table size if not specified by firmware file */ 95/* The default calibrate table size if not specified by firmware file */
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 305c81f2c2b4..dfa4d2e3aaa2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -33,6 +33,8 @@
33#include "iwl-io.h" 33#include "iwl-io.h"
34#include "iwl-csr.h" 34#include "iwl-csr.h"
35#include "iwl-debug.h" 35#include "iwl-debug.h"
36#include "iwl-fh.h"
37#include "iwl-csr.h"
36 38
37#define IWL_POLL_INTERVAL 10 /* microseconds */ 39#define IWL_POLL_INTERVAL 10 /* microseconds */
38 40
@@ -166,3 +168,68 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
166 } 168 }
167} 169}
168IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); 170IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
171
172static const char *get_fh_string(int cmd)
173{
174#define IWL_CMD(x) case x: return #x
175 switch (cmd) {
176 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
177 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
178 IWL_CMD(FH_RSCSR_CHNL0_WPTR);
179 IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
180 IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
181 IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
182 IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
183 IWL_CMD(FH_TSSR_TX_STATUS_REG);
184 IWL_CMD(FH_TSSR_TX_ERROR_REG);
185 default:
186 return "UNKNOWN";
187 }
188#undef IWL_CMD
189}
190
191int iwl_dump_fh(struct iwl_trans *trans, char **buf)
192{
193 int i;
194 static const u32 fh_tbl[] = {
195 FH_RSCSR_CHNL0_STTS_WPTR_REG,
196 FH_RSCSR_CHNL0_RBDCB_BASE_REG,
197 FH_RSCSR_CHNL0_WPTR,
198 FH_MEM_RCSR_CHNL0_CONFIG_REG,
199 FH_MEM_RSSR_SHARED_CTRL_REG,
200 FH_MEM_RSSR_RX_STATUS_REG,
201 FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
202 FH_TSSR_TX_STATUS_REG,
203 FH_TSSR_TX_ERROR_REG
204 };
205
206#ifdef CONFIG_IWLWIFI_DEBUGFS
207 if (buf) {
208 int pos = 0;
209 size_t bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
210
211 *buf = kmalloc(bufsz, GFP_KERNEL);
212 if (!*buf)
213 return -ENOMEM;
214
215 pos += scnprintf(*buf + pos, bufsz - pos,
216 "FH register values:\n");
217
218 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++)
219 pos += scnprintf(*buf + pos, bufsz - pos,
220 " %34s: 0X%08x\n",
221 get_fh_string(fh_tbl[i]),
222 iwl_read_direct32(trans, fh_tbl[i]));
223
224 return pos;
225 }
226#endif
227
228 IWL_ERR(trans, "FH register values:\n");
229 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++)
230 IWL_ERR(trans, " %34s: 0X%08x\n",
231 get_fh_string(fh_tbl[i]),
232 iwl_read_direct32(trans, fh_tbl[i]));
233
234 return 0;
235}
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index fd9f5b97fff3..63d10ec08dbc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -77,4 +77,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
77 u32 bits, u32 mask); 77 u32 bits, u32 mask);
78void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask); 78void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
79 79
80/* Error handling */
81int iwl_dump_fh(struct iwl_trans *trans, char **buf);
82
80#endif 83#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index acd2665afb8c..b76a9a8fc0b3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -118,6 +118,7 @@ static const u8 iwl_nvm_channels[] = {
118#define LAST_2GHZ_HT_PLUS 9 118#define LAST_2GHZ_HT_PLUS 9
119#define LAST_5GHZ_HT 161 119#define LAST_5GHZ_HT 161
120 120
121#define DEFAULT_MAX_TX_POWER 16
121 122
122/* rate data (static) */ 123/* rate data (static) */
123static struct ieee80211_rate iwl_cfg80211_rates[] = { 124static struct ieee80211_rate iwl_cfg80211_rates[] = {
@@ -232,8 +233,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
232 233
233 /* Initialize regulatory-based run-time data */ 234 /* Initialize regulatory-based run-time data */
234 235
235 /* TODO: read the real value from the NVM */ 236 /*
236 channel->max_power = 0; 237 * Default value - highest tx power value. max_power
238 * is not used in mvm, and is used for backwards compatibility
239 */
240 channel->max_power = DEFAULT_MAX_TX_POWER;
237 is_5ghz = channel->band == IEEE80211_BAND_5GHZ; 241 is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
238 IWL_DEBUG_EEPROM(dev, 242 IWL_DEBUG_EEPROM(dev,
239 "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n", 243 "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index ff856e543ae8..6d73817850ce 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o
2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o 2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o bt-coex.o 5iwlmvm-y += power.o power_legacy.o bt-coex.o
6iwlmvm-y += led.o tt.o 6iwlmvm-y += led.o tt.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index dbd622a3929c..0fad98b85f60 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -220,66 +220,87 @@ static const __le32 iwl_single_shared_ant_lookup[BT_COEX_LUT_SIZE] = {
220 220
221int iwl_send_bt_init_conf(struct iwl_mvm *mvm) 221int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
222{ 222{
223 struct iwl_bt_coex_cmd cmd = { 223 struct iwl_bt_coex_cmd *bt_cmd;
224 .max_kill = 5, 224 struct iwl_host_cmd cmd = {
225 .bt3_time_t7_value = 1, 225 .id = BT_CONFIG,
226 .bt3_prio_sample_time = 2, 226 .len = { sizeof(*bt_cmd), },
227 .bt3_timer_t2_value = 0xc, 227 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
228 .flags = CMD_SYNC,
228 }; 229 };
229 int ret; 230 int ret;
230 231
231 cmd.flags = iwlwifi_mod_params.bt_coex_active ? 232 /* go to CALIB state in internal BT-Coex state machine */
233 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN,
234 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
235 if (ret)
236 return ret;
237
238 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE,
239 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
240 if (ret)
241 return ret;
242
243 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
244 if (!bt_cmd)
245 return -ENOMEM;
246 cmd.data[0] = bt_cmd;
247
248 bt_cmd->max_kill = 5;
249 bt_cmd->bt3_time_t7_value = 1;
250 bt_cmd->bt3_prio_sample_time = 2;
251 bt_cmd->bt3_timer_t2_value = 0xc;
252
253 bt_cmd->flags = iwlwifi_mod_params.bt_coex_active ?
232 BT_COEX_NW : BT_COEX_DISABLE; 254 BT_COEX_NW : BT_COEX_DISABLE;
233 cmd.flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE; 255 bt_cmd->flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE;
234 256
235 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | 257 bt_cmd->valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE |
236 BT_VALID_BT_PRIO_BOOST | 258 BT_VALID_BT_PRIO_BOOST |
237 BT_VALID_MAX_KILL | 259 BT_VALID_MAX_KILL |
238 BT_VALID_3W_TMRS | 260 BT_VALID_3W_TMRS |
239 BT_VALID_KILL_ACK | 261 BT_VALID_KILL_ACK |
240 BT_VALID_KILL_CTS | 262 BT_VALID_KILL_CTS |
241 BT_VALID_REDUCED_TX_POWER | 263 BT_VALID_REDUCED_TX_POWER |
242 BT_VALID_LUT); 264 BT_VALID_LUT);
243 265
244 if (mvm->cfg->bt_shared_single_ant) 266 if (mvm->cfg->bt_shared_single_ant)
245 memcpy(&cmd.decision_lut, iwl_single_shared_ant_lookup, 267 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant_lookup,
246 sizeof(iwl_single_shared_ant_lookup)); 268 sizeof(iwl_single_shared_ant_lookup));
247 else if (is_loose_coex()) 269 else if (is_loose_coex())
248 memcpy(&cmd.decision_lut, iwl_loose_lookup, 270 memcpy(&bt_cmd->decision_lut, iwl_loose_lookup,
249 sizeof(iwl_tight_lookup)); 271 sizeof(iwl_tight_lookup));
250 else 272 else
251 memcpy(&cmd.decision_lut, iwl_tight_lookup, 273 memcpy(&bt_cmd->decision_lut, iwl_tight_lookup,
252 sizeof(iwl_tight_lookup)); 274 sizeof(iwl_tight_lookup));
253 275
254 cmd.bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST); 276 bt_cmd->bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST);
255 cmd.kill_ack_msk = 277 bt_cmd->kill_ack_msk =
256 cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]); 278 cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]);
257 cmd.kill_cts_msk = 279 bt_cmd->kill_cts_msk =
258 cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); 280 cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]);
259 281
260 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); 282 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
261 283
262 /* go to CALIB state in internal BT-Coex state machine */ 284 ret = iwl_mvm_send_cmd(mvm, &cmd);
263 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN,
264 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
265 if (ret)
266 return ret;
267
268 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE,
269 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
270 if (ret)
271 return ret;
272 285
273 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, 286 kfree(bt_cmd);
274 sizeof(cmd), &cmd); 287 return ret;
275} 288}
276 289
277static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm, 290static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm,
278 bool reduced_tx_power) 291 bool reduced_tx_power)
279{ 292{
280 enum iwl_bt_kill_msk bt_kill_msk; 293 enum iwl_bt_kill_msk bt_kill_msk;
281 struct iwl_bt_coex_cmd cmd = {}; 294 struct iwl_bt_coex_cmd *bt_cmd;
282 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; 295 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
296 struct iwl_host_cmd cmd = {
297 .id = BT_CONFIG,
298 .data[0] = &bt_cmd,
299 .len = { sizeof(*bt_cmd), },
300 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
301 .flags = CMD_SYNC,
302 };
303 int ret = 0;
283 304
284 lockdep_assert_held(&mvm->mutex); 305 lockdep_assert_held(&mvm->mutex);
285 306
@@ -308,24 +329,40 @@ static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm,
308 return 0; 329 return 0;
309 330
310 mvm->bt_kill_msk = bt_kill_msk; 331 mvm->bt_kill_msk = bt_kill_msk;
311 cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); 332
312 cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); 333 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
313 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); 334 if (!bt_cmd)
335 return -ENOMEM;
336 cmd.data[0] = bt_cmd;
337
338 bt_cmd->kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
339 bt_cmd->kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
340 bt_cmd->valid_bit_msk =
341 cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS);
314 342
315 IWL_DEBUG_COEX(mvm, "bt_kill_msk = %d\n", bt_kill_msk); 343 IWL_DEBUG_COEX(mvm, "bt_kill_msk = %d\n", bt_kill_msk);
316 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, 344
317 sizeof(cmd), &cmd); 345 ret = iwl_mvm_send_cmd(mvm, &cmd);
346
347 kfree(bt_cmd);
348 return ret;
318} 349}
319 350
320static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, 351static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
321 bool enable) 352 bool enable)
322{ 353{
323 struct iwl_bt_coex_cmd cmd = { 354 struct iwl_bt_coex_cmd *bt_cmd;
324 .valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER), 355 /* Send ASYNC since this can be sent from an atomic context */
325 .bt_reduced_tx_power = sta_id, 356 struct iwl_host_cmd cmd = {
357 .id = BT_CONFIG,
358 .len = { sizeof(*bt_cmd), },
359 .dataflags = { IWL_HCMD_DFL_DUP, },
360 .flags = CMD_ASYNC,
326 }; 361 };
362
327 struct ieee80211_sta *sta; 363 struct ieee80211_sta *sta;
328 struct iwl_mvm_sta *mvmsta; 364 struct iwl_mvm_sta *mvmsta;
365 int ret;
329 366
330 /* This can happen if the station has been removed right now */ 367 /* This can happen if the station has been removed right now */
331 if (sta_id == IWL_MVM_STATION_COUNT) 368 if (sta_id == IWL_MVM_STATION_COUNT)
@@ -339,17 +376,26 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
339 if (mvmsta->bt_reduced_txpower == enable) 376 if (mvmsta->bt_reduced_txpower == enable)
340 return 0; 377 return 0;
341 378
379 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_ATOMIC);
380 if (!bt_cmd)
381 return -ENOMEM;
382 cmd.data[0] = bt_cmd;
383
384 bt_cmd->valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER),
385 bt_cmd->bt_reduced_tx_power = sta_id;
386
342 if (enable) 387 if (enable)
343 cmd.bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT; 388 bt_cmd->bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT;
344 389
345 IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n", 390 IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n",
346 enable ? "en" : "dis", sta_id); 391 enable ? "en" : "dis", sta_id);
347 392
348 mvmsta->bt_reduced_txpower = enable; 393 mvmsta->bt_reduced_txpower = enable;
349 394
350 /* Send ASYNC since this can be sent from an atomic context */ 395 ret = iwl_mvm_send_cmd(mvm, &cmd);
351 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_ASYNC, 396
352 sizeof(cmd), &cmd); 397 kfree(bt_cmd);
398 return ret;
353} 399}
354 400
355struct iwl_bt_iterator_data { 401struct iwl_bt_iterator_data {
@@ -384,6 +430,10 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
384 430
385 smps_mode = IEEE80211_SMPS_AUTOMATIC; 431 smps_mode = IEEE80211_SMPS_AUTOMATIC;
386 432
433 /* non associated BSSes aren't to be considered */
434 if (!vif->bss_conf.assoc)
435 return;
436
387 if (band != IEEE80211_BAND_2GHZ) { 437 if (band != IEEE80211_BAND_2GHZ) {
388 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, 438 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
389 smps_mode); 439 smps_mode);
@@ -523,6 +573,8 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
523 lockdep_is_held(&mvm->mutex)); 573 lockdep_is_held(&mvm->mutex));
524 mvmsta = (void *)sta->drv_priv; 574 mvmsta = (void *)sta->drv_priv;
525 575
576 data->num_bss_ifaces++;
577
526 /* 578 /*
527 * This interface doesn't support reduced Tx power (because of low 579 * This interface doesn't support reduced Tx power (because of low
528 * RSSI probably), then set bt_kill_msk to default values. 580 * RSSI probably), then set bt_kill_msk to default values.
@@ -588,23 +640,5 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
588 640
589void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 641void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
590{ 642{
591 struct ieee80211_chanctx_conf *chanctx_conf;
592 enum ieee80211_band band;
593
594 rcu_read_lock();
595 chanctx_conf = rcu_dereference(vif->chanctx_conf);
596 if (chanctx_conf && chanctx_conf->def.chan)
597 band = chanctx_conf->def.chan->band;
598 else
599 band = -1;
600 rcu_read_unlock();
601
602 /* if we are in 2GHz we will get a notification from the fw */
603 if (band == IEEE80211_BAND_2GHZ)
604 return;
605
606 /* else, we can remove all the constraints */
607 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
608
609 iwl_mvm_bt_coex_notif_handle(mvm); 643 iwl_mvm_bt_coex_notif_handle(mvm);
610} 644}
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
new file mode 100644
index 000000000000..64656e0c8f91
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -0,0 +1,71 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved.
9 *
10 * 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 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#ifndef __MVM_CONSTANTS_H
64#define __MVM_CONSTANTS_H
65
66#define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
67#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
68#define IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * USEC_PER_MSEC)
69#define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * USEC_PER_MSEC)
70
71#endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 83da884cf303..d0d7a20266e6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -105,7 +105,7 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
105 list_for_each_entry(ifa, &idev->addr_list, if_list) { 105 list_for_each_entry(ifa, &idev->addr_list, if_list) {
106 mvmvif->target_ipv6_addrs[idx] = ifa->addr; 106 mvmvif->target_ipv6_addrs[idx] = ifa->addr;
107 idx++; 107 idx++;
108 if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS) 108 if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX)
109 break; 109 break;
110 } 110 }
111 read_unlock_bh(&idev->lock); 111 read_unlock_bh(&idev->lock);
@@ -378,36 +378,68 @@ static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
378static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, 378static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
379 struct ieee80211_vif *vif) 379 struct ieee80211_vif *vif)
380{ 380{
381 struct iwl_proto_offload_cmd cmd = {}; 381 union {
382 struct iwl_proto_offload_cmd_v1 v1;
383 struct iwl_proto_offload_cmd_v2 v2;
384 } cmd = {};
385 struct iwl_proto_offload_cmd_common *common;
386 u32 enabled = 0, size;
382#if IS_ENABLED(CONFIG_IPV6) 387#if IS_ENABLED(CONFIG_IPV6)
383 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 388 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
384 int i; 389 int i;
385 390
386 if (mvmvif->num_target_ipv6_addrs) { 391 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
387 cmd.enabled |= cpu_to_le32(IWL_D3_PROTO_OFFLOAD_NS); 392 if (mvmvif->num_target_ipv6_addrs) {
388 memcpy(cmd.ndp_mac_addr, vif->addr, ETH_ALEN); 393 enabled |= IWL_D3_PROTO_OFFLOAD_NS;
389 } 394 memcpy(cmd.v2.ndp_mac_addr, vif->addr, ETH_ALEN);
395 }
396
397 BUILD_BUG_ON(sizeof(cmd.v2.target_ipv6_addr[0]) !=
398 sizeof(mvmvif->target_ipv6_addrs[0]));
399
400 for (i = 0; i < min(mvmvif->num_target_ipv6_addrs,
401 IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2); i++)
402 memcpy(cmd.v2.target_ipv6_addr[i],
403 &mvmvif->target_ipv6_addrs[i],
404 sizeof(cmd.v2.target_ipv6_addr[i]));
405 } else {
406 if (mvmvif->num_target_ipv6_addrs) {
407 enabled |= IWL_D3_PROTO_OFFLOAD_NS;
408 memcpy(cmd.v1.ndp_mac_addr, vif->addr, ETH_ALEN);
409 }
390 410
391 BUILD_BUG_ON(sizeof(cmd.target_ipv6_addr[i]) != 411 BUILD_BUG_ON(sizeof(cmd.v1.target_ipv6_addr[0]) !=
392 sizeof(mvmvif->target_ipv6_addrs[i])); 412 sizeof(mvmvif->target_ipv6_addrs[0]));
393 413
394 for (i = 0; i < mvmvif->num_target_ipv6_addrs; i++) 414 for (i = 0; i < min(mvmvif->num_target_ipv6_addrs,
395 memcpy(cmd.target_ipv6_addr[i], 415 IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1); i++)
396 &mvmvif->target_ipv6_addrs[i], 416 memcpy(cmd.v1.target_ipv6_addr[i],
397 sizeof(cmd.target_ipv6_addr[i])); 417 &mvmvif->target_ipv6_addrs[i],
418 sizeof(cmd.v1.target_ipv6_addr[i]));
419 }
398#endif 420#endif
399 421
422 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
423 common = &cmd.v2.common;
424 size = sizeof(cmd.v2);
425 } else {
426 common = &cmd.v1.common;
427 size = sizeof(cmd.v1);
428 }
429
400 if (vif->bss_conf.arp_addr_cnt) { 430 if (vif->bss_conf.arp_addr_cnt) {
401 cmd.enabled |= cpu_to_le32(IWL_D3_PROTO_OFFLOAD_ARP); 431 enabled |= IWL_D3_PROTO_OFFLOAD_ARP;
402 cmd.host_ipv4_addr = vif->bss_conf.arp_addr_list[0]; 432 common->host_ipv4_addr = vif->bss_conf.arp_addr_list[0];
403 memcpy(cmd.arp_mac_addr, vif->addr, ETH_ALEN); 433 memcpy(common->arp_mac_addr, vif->addr, ETH_ALEN);
404 } 434 }
405 435
406 if (!cmd.enabled) 436 if (!enabled)
407 return 0; 437 return 0;
408 438
439 common->enabled = cpu_to_le32(enabled);
440
409 return iwl_mvm_send_cmd_pdu(mvm, PROT_OFFLOAD_CONFIG_CMD, CMD_SYNC, 441 return iwl_mvm_send_cmd_pdu(mvm, PROT_OFFLOAD_CONFIG_CMD, CMD_SYNC,
410 sizeof(cmd), &cmd); 442 size, &cmd);
411} 443}
412 444
413enum iwl_mvm_tcp_packet_type { 445enum iwl_mvm_tcp_packet_type {
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index c24a744910ac..56f6827b19e5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -424,40 +424,11 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
424 struct ieee80211_vif *vif = file->private_data; 424 struct ieee80211_vif *vif = file->private_data;
425 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 425 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
426 struct iwl_mvm *mvm = mvmvif->dbgfs_data; 426 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
427 struct iwl_powertable_cmd cmd = {};
428 char buf[256]; 427 char buf[256];
429 int bufsz = sizeof(buf); 428 int bufsz = sizeof(buf);
430 int pos = 0; 429 int pos;
431 430
432 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 431 pos = iwl_mvm_power_dbgfs_read(mvm, vif, buf, bufsz);
433
434 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
435 (cmd.flags &
436 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
437 0 : 1);
438 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
439 le32_to_cpu(cmd.skip_dtim_periods));
440 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
441 iwlmvm_mod_params.power_scheme);
442 pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
443 le16_to_cpu(cmd.flags));
444 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
445 cmd.keep_alive_seconds);
446
447 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
448 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
449 (cmd.flags &
450 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ?
451 1 : 0);
452 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
453 le32_to_cpu(cmd.rx_data_timeout));
454 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
455 le32_to_cpu(cmd.tx_data_timeout));
456 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
457 pos += scnprintf(buf+pos, bufsz-pos,
458 "lprx_rssi_threshold = %d\n",
459 le32_to_cpu(cmd.lprx_rssi_threshold));
460 }
461 432
462 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 433 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
463} 434}
@@ -626,20 +597,19 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
626 size_t count, loff_t *ppos) 597 size_t count, loff_t *ppos)
627{ 598{
628 struct iwl_mvm *mvm = file->private_data; 599 struct iwl_mvm *mvm = file->private_data;
629 bool restart_fw = iwlwifi_mod_params.restart_fw;
630 int ret; 600 int ret;
631 601
632 iwlwifi_mod_params.restart_fw = true;
633
634 mutex_lock(&mvm->mutex); 602 mutex_lock(&mvm->mutex);
635 603
604 /* allow one more restart that we're provoking here */
605 if (mvm->restart_fw >= 0)
606 mvm->restart_fw++;
607
636 /* take the return value to make compiler happy - it will fail anyway */ 608 /* take the return value to make compiler happy - it will fail anyway */
637 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, CMD_SYNC, 0, NULL); 609 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, CMD_SYNC, 0, NULL);
638 610
639 mutex_unlock(&mvm->mutex); 611 mutex_unlock(&mvm->mutex);
640 612
641 iwlwifi_mod_params.restart_fw = restart_fw;
642
643 return count; 613 return count;
644} 614}
645 615
@@ -661,8 +631,14 @@ static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
661 case MVM_DEBUGFS_BF_ROAMING_STATE: 631 case MVM_DEBUGFS_BF_ROAMING_STATE:
662 dbgfs_bf->bf_roaming_state = value; 632 dbgfs_bf->bf_roaming_state = value;
663 break; 633 break;
664 case MVM_DEBUGFS_BF_TEMPERATURE_DELTA: 634 case MVM_DEBUGFS_BF_TEMP_THRESHOLD:
665 dbgfs_bf->bf_temperature_delta = value; 635 dbgfs_bf->bf_temp_threshold = value;
636 break;
637 case MVM_DEBUGFS_BF_TEMP_FAST_FILTER:
638 dbgfs_bf->bf_temp_fast_filter = value;
639 break;
640 case MVM_DEBUGFS_BF_TEMP_SLOW_FILTER:
641 dbgfs_bf->bf_temp_slow_filter = value;
666 break; 642 break;
667 case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER: 643 case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
668 dbgfs_bf->bf_enable_beacon_filter = value; 644 dbgfs_bf->bf_enable_beacon_filter = value;
@@ -721,13 +697,27 @@ static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
721 value > IWL_BF_ROAMING_STATE_MAX) 697 value > IWL_BF_ROAMING_STATE_MAX)
722 return -EINVAL; 698 return -EINVAL;
723 param = MVM_DEBUGFS_BF_ROAMING_STATE; 699 param = MVM_DEBUGFS_BF_ROAMING_STATE;
724 } else if (!strncmp("bf_temperature_delta=", buf, 21)) { 700 } else if (!strncmp("bf_temp_threshold=", buf, 18)) {
725 if (sscanf(buf+21, "%d", &value) != 1) 701 if (sscanf(buf+18, "%d", &value) != 1)
702 return -EINVAL;
703 if (value < IWL_BF_TEMP_THRESHOLD_MIN ||
704 value > IWL_BF_TEMP_THRESHOLD_MAX)
705 return -EINVAL;
706 param = MVM_DEBUGFS_BF_TEMP_THRESHOLD;
707 } else if (!strncmp("bf_temp_fast_filter=", buf, 20)) {
708 if (sscanf(buf+20, "%d", &value) != 1)
709 return -EINVAL;
710 if (value < IWL_BF_TEMP_FAST_FILTER_MIN ||
711 value > IWL_BF_TEMP_FAST_FILTER_MAX)
712 return -EINVAL;
713 param = MVM_DEBUGFS_BF_TEMP_FAST_FILTER;
714 } else if (!strncmp("bf_temp_slow_filter=", buf, 20)) {
715 if (sscanf(buf+20, "%d", &value) != 1)
726 return -EINVAL; 716 return -EINVAL;
727 if (value < IWL_BF_TEMPERATURE_DELTA_MIN || 717 if (value < IWL_BF_TEMP_SLOW_FILTER_MIN ||
728 value > IWL_BF_TEMPERATURE_DELTA_MAX) 718 value > IWL_BF_TEMP_SLOW_FILTER_MAX)
729 return -EINVAL; 719 return -EINVAL;
730 param = MVM_DEBUGFS_BF_TEMPERATURE_DELTA; 720 param = MVM_DEBUGFS_BF_TEMP_SLOW_FILTER;
731 } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) { 721 } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
732 if (sscanf(buf+24, "%d", &value) != 1) 722 if (sscanf(buf+24, "%d", &value) != 1)
733 return -EINVAL; 723 return -EINVAL;
@@ -789,41 +779,41 @@ static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
789 int pos = 0; 779 int pos = 0;
790 const size_t bufsz = sizeof(buf); 780 const size_t bufsz = sizeof(buf);
791 struct iwl_beacon_filter_cmd cmd = { 781 struct iwl_beacon_filter_cmd cmd = {
792 .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT, 782 IWL_BF_CMD_CONFIG_DEFAULTS,
793 .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT, 783 .bf_enable_beacon_filter =
794 .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT, 784 cpu_to_le32(IWL_BF_ENABLE_BEACON_FILTER_DEFAULT),
795 .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT, 785 .ba_enable_beacon_abort =
796 .bf_enable_beacon_filter = IWL_BF_ENABLE_BEACON_FILTER_DEFAULT, 786 cpu_to_le32(IWL_BA_ENABLE_BEACON_ABORT_DEFAULT),
797 .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT,
798 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT),
799 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT),
800 .ba_enable_beacon_abort = IWL_BA_ENABLE_BEACON_ABORT_DEFAULT,
801 }; 787 };
802 788
803 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); 789 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
804 if (mvmvif->bf_enabled) 790 if (mvmvif->bf_enabled)
805 cmd.bf_enable_beacon_filter = 1; 791 cmd.bf_enable_beacon_filter = cpu_to_le32(1);
806 else 792 else
807 cmd.bf_enable_beacon_filter = 0; 793 cmd.bf_enable_beacon_filter = 0;
808 794
809 pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n", 795 pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
810 cmd.bf_energy_delta); 796 le32_to_cpu(cmd.bf_energy_delta));
811 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n", 797 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
812 cmd.bf_roaming_energy_delta); 798 le32_to_cpu(cmd.bf_roaming_energy_delta));
813 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n", 799 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
814 cmd.bf_roaming_state); 800 le32_to_cpu(cmd.bf_roaming_state));
815 pos += scnprintf(buf+pos, bufsz-pos, "bf_temperature_delta = %d\n", 801 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_threshold = %d\n",
816 cmd.bf_temperature_delta); 802 le32_to_cpu(cmd.bf_temp_threshold));
803 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_fast_filter = %d\n",
804 le32_to_cpu(cmd.bf_temp_fast_filter));
805 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_slow_filter = %d\n",
806 le32_to_cpu(cmd.bf_temp_slow_filter));
817 pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n", 807 pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
818 cmd.bf_enable_beacon_filter); 808 le32_to_cpu(cmd.bf_enable_beacon_filter));
819 pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n", 809 pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
820 cmd.bf_debug_flag); 810 le32_to_cpu(cmd.bf_debug_flag));
821 pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n", 811 pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
822 cmd.bf_escape_timer); 812 le32_to_cpu(cmd.bf_escape_timer));
823 pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n", 813 pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
824 cmd.ba_escape_timer); 814 le32_to_cpu(cmd.ba_escape_timer));
825 pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n", 815 pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
826 cmd.ba_enable_beacon_abort); 816 le32_to_cpu(cmd.ba_enable_beacon_abort));
827 817
828 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 818 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
829} 819}
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index 6f8b2c16ae17..df72fcdf8170 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -98,34 +98,63 @@ enum iwl_proto_offloads {
98 IWL_D3_PROTO_OFFLOAD_NS = BIT(1), 98 IWL_D3_PROTO_OFFLOAD_NS = BIT(1),
99}; 99};
100 100
101#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS 2 101#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1 2
102#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2 6
103#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX 6
102 104
103/** 105/**
104 * struct iwl_proto_offload_cmd - ARP/NS offload configuration 106 * struct iwl_proto_offload_cmd_common - ARP/NS offload common part
105 * @enabled: enable flags 107 * @enabled: enable flags
106 * @remote_ipv4_addr: remote address to answer to (or zero if all) 108 * @remote_ipv4_addr: remote address to answer to (or zero if all)
107 * @host_ipv4_addr: our IPv4 address to respond to queries for 109 * @host_ipv4_addr: our IPv4 address to respond to queries for
108 * @arp_mac_addr: our MAC address for ARP responses 110 * @arp_mac_addr: our MAC address for ARP responses
109 * @remote_ipv6_addr: remote address to answer to (or zero if all) 111 * @reserved: unused
110 * @solicited_node_ipv6_addr: broken -- solicited node address exists
111 * for each target address
112 * @target_ipv6_addr: our target addresses
113 * @ndp_mac_addr: neighbor soliciation response MAC address
114 */ 112 */
115struct iwl_proto_offload_cmd { 113struct iwl_proto_offload_cmd_common {
116 __le32 enabled; 114 __le32 enabled;
117 __be32 remote_ipv4_addr; 115 __be32 remote_ipv4_addr;
118 __be32 host_ipv4_addr; 116 __be32 host_ipv4_addr;
119 u8 arp_mac_addr[ETH_ALEN]; 117 u8 arp_mac_addr[ETH_ALEN];
120 __le16 reserved1; 118 __le16 reserved;
119} __packed;
121 120
121/**
122 * struct iwl_proto_offload_cmd_v1 - ARP/NS offload configuration
123 * @common: common/IPv4 configuration
124 * @remote_ipv6_addr: remote address to answer to (or zero if all)
125 * @solicited_node_ipv6_addr: broken -- solicited node address exists
126 * for each target address
127 * @target_ipv6_addr: our target addresses
128 * @ndp_mac_addr: neighbor soliciation response MAC address
129 */
130struct iwl_proto_offload_cmd_v1 {
131 struct iwl_proto_offload_cmd_common common;
122 u8 remote_ipv6_addr[16]; 132 u8 remote_ipv6_addr[16];
123 u8 solicited_node_ipv6_addr[16]; 133 u8 solicited_node_ipv6_addr[16];
124 u8 target_ipv6_addr[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS][16]; 134 u8 target_ipv6_addr[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1][16];
125 u8 ndp_mac_addr[ETH_ALEN]; 135 u8 ndp_mac_addr[ETH_ALEN];
126 __le16 reserved2; 136 __le16 reserved2;
127} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_1 */ 137} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_1 */
128 138
139/**
140 * struct iwl_proto_offload_cmd_v2 - ARP/NS offload configuration
141 * @common: common/IPv4 configuration
142 * @remote_ipv6_addr: remote address to answer to (or zero if all)
143 * @solicited_node_ipv6_addr: broken -- solicited node address exists
144 * for each target address
145 * @target_ipv6_addr: our target addresses
146 * @ndp_mac_addr: neighbor soliciation response MAC address
147 */
148struct iwl_proto_offload_cmd_v2 {
149 struct iwl_proto_offload_cmd_common common;
150 u8 remote_ipv6_addr[16];
151 u8 solicited_node_ipv6_addr[16];
152 u8 target_ipv6_addr[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2][16];
153 u8 ndp_mac_addr[ETH_ALEN];
154 u8 numValidIPv6Addresses;
155 u8 reserved2[3];
156} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_2 */
157
129 158
130/* 159/*
131 * WOWLAN_PATTERNS 160 * WOWLAN_PATTERNS
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index a6da359a80c3..060e630b3d82 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -79,6 +79,10 @@
79 * '1' Driver enables PM (use rest of parameters) 79 * '1' Driver enables PM (use rest of parameters)
80 * @POWER_FLAGS_SKIP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM, 80 * @POWER_FLAGS_SKIP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM,
81 * '1' PM could sleep over DTIM till listen Interval. 81 * '1' PM could sleep over DTIM till listen Interval.
82 * @POWER_FLAGS_SNOOZE_ENA_MSK: Enable snoozing only if uAPSD is enabled and all
83 * access categories are both delivery and trigger enabled.
84 * @POWER_FLAGS_BT_SCO_ENA: Enable BT SCO coex only if uAPSD and
85 * PBW Snoozing enabled
82 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask 86 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask
83 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable. 87 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
84*/ 88*/
@@ -86,6 +90,8 @@ enum iwl_power_flags {
86 POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0), 90 POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0),
87 POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(1), 91 POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(1),
88 POWER_FLAGS_SKIP_OVER_DTIM_MSK = BIT(2), 92 POWER_FLAGS_SKIP_OVER_DTIM_MSK = BIT(2),
93 POWER_FLAGS_SNOOZE_ENA_MSK = BIT(5),
94 POWER_FLAGS_BT_SCO_ENA = BIT(8),
89 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9), 95 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9),
90 POWER_FLAGS_LPRX_ENA_MSK = BIT(11), 96 POWER_FLAGS_LPRX_ENA_MSK = BIT(11),
91}; 97};
@@ -93,7 +99,8 @@ enum iwl_power_flags {
93#define IWL_POWER_VEC_SIZE 5 99#define IWL_POWER_VEC_SIZE 5
94 100
95/** 101/**
96 * struct iwl_powertable_cmd - Power Table Command 102 * struct iwl_powertable_cmd - legacy power command. Beside old API support this
103 * is used also with a new power API for device wide power settings.
97 * POWER_TABLE_CMD = 0x77 (command, has simple generic response) 104 * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
98 * 105 *
99 * @flags: Power table command flags from POWER_FLAGS_* 106 * @flags: Power table command flags from POWER_FLAGS_*
@@ -125,6 +132,72 @@ struct iwl_powertable_cmd {
125} __packed; 132} __packed;
126 133
127/** 134/**
135 * struct iwl_mac_power_cmd - New power command containing uAPSD support
136 * MAC_PM_POWER_TABLE = 0xA9 (command, has simple generic response)
137 * @id_and_color: MAC contex identifier
138 * @flags: Power table command flags from POWER_FLAGS_*
139 * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec.
140 * Minimum allowed:- 3 * DTIM. Keep alive period must be
141 * set regardless of power scheme or current power state.
142 * FW use this value also when PM is disabled.
143 * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to
144 * PSM transition - legacy PM
145 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to
146 * PSM transition - legacy PM
147 * @sleep_interval: not in use
148 * @skip_dtim_periods: Number of DTIM periods to skip if Skip over DTIM flag
149 * is set. For example, if it is required to skip over
150 * one DTIM, this value need to be set to 2 (DTIM periods).
151 * @rx_data_timeout_uapsd: Minimum time (usec) from last Rx packet for AM to
152 * PSM transition - uAPSD
153 * @tx_data_timeout_uapsd: Minimum time (usec) from last Tx packet for AM to
154 * PSM transition - uAPSD
155 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
156 * Default: 80dbm
157 * @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set
158 * @snooze_interval: TBD
159 * @snooze_window: TBD
160 * @snooze_step: TBD
161 * @qndp_tid: TID client shall use for uAPSD QNDP triggers
162 * @uapsd_ac_flags: Set trigger-enabled and delivery-enabled indication for
163 * each corresponding AC.
164 * Use IEEE80211_WMM_IE_STA_QOSINFO_AC* for correct values.
165 * @uapsd_max_sp: Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct
166 * values.
167 * @heavy_traffic_thr_tx_pkts: TX threshold measured in number of packets
168 * @heavy_traffic_thr_rx_pkts: RX threshold measured in number of packets
169 * @heavy_traffic_thr_tx_load: TX threshold measured in load's percentage
170 * @heavy_traffic_thr_rx_load: RX threshold measured in load's percentage
171 * @limited_ps_threshold:
172*/
173struct iwl_mac_power_cmd {
174 /* CONTEXT_DESC_API_T_VER_1 */
175 __le32 id_and_color;
176
177 /* CLIENT_PM_POWER_TABLE_S_VER_1 */
178 __le16 flags;
179 __le16 keep_alive_seconds;
180 __le32 rx_data_timeout;
181 __le32 tx_data_timeout;
182 __le32 rx_data_timeout_uapsd;
183 __le32 tx_data_timeout_uapsd;
184 u8 lprx_rssi_threshold;
185 u8 skip_dtim_periods;
186 __le16 snooze_interval;
187 __le16 snooze_window;
188 u8 snooze_step;
189 u8 qndp_tid;
190 u8 uapsd_ac_flags;
191 u8 uapsd_max_sp;
192 u8 heavy_traffic_threshold_tx_packets;
193 u8 heavy_traffic_threshold_rx_packets;
194 u8 heavy_traffic_threshold_tx_percentage;
195 u8 heavy_traffic_threshold_rx_percentage;
196 u8 limited_ps_threshold;
197 u8 reserved;
198} __packed;
199
200/**
128 * struct iwl_beacon_filter_cmd 201 * struct iwl_beacon_filter_cmd
129 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command) 202 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
130 * @id_and_color: MAC contex identifier 203 * @id_and_color: MAC contex identifier
@@ -143,11 +216,21 @@ struct iwl_powertable_cmd {
143 * calculated for current beacon is less than the threshold, use 216 * calculated for current beacon is less than the threshold, use
144 * Roaming Energy Delta Threshold, otherwise use normal Energy Delta 217 * Roaming Energy Delta Threshold, otherwise use normal Energy Delta
145 * Threshold. Typical energy threshold is -72dBm. 218 * Threshold. Typical energy threshold is -72dBm.
146 * @bf_temperature_delta: Send Beacon to driver if delta in temperature values 219 * @bf_temp_threshold: This threshold determines the type of temperature
147 * calculated for this and the last passed beacon is greater than this 220 * filtering (Slow or Fast) that is selected (Units are in Celsuis):
148 * threshold. Zero value means that the temperature changeis ignored for 221 * If the current temperature is above this threshold - Fast filter
222 * will be used, If the current temperature is below this threshold -
223 * Slow filter will be used.
224 * @bf_temp_fast_filter: Send Beacon to driver if delta in temperature values
225 * calculated for this and the last passed beacon is greater than this
226 * threshold. Zero value means that the temperature change is ignored for
149 * beacon filtering; beacons will not be forced to be sent to driver 227 * beacon filtering; beacons will not be forced to be sent to driver
150 * regardless of whether its temerature has been changed. 228 * regardless of whether its temerature has been changed.
229 * @bf_temp_slow_filter: Send Beacon to driver if delta in temperature values
230 * calculated for this and the last passed beacon is greater than this
231 * threshold. Zero value means that the temperature change is ignored for
232 * beacon filtering; beacons will not be forced to be sent to driver
233 * regardless of whether its temerature has been changed.
151 * @bf_enable_beacon_filter: 1, beacon filtering is enabled; 0, disabled. 234 * @bf_enable_beacon_filter: 1, beacon filtering is enabled; 0, disabled.
152 * @bf_filter_escape_timer: Send beacons to to driver if no beacons were passed 235 * @bf_filter_escape_timer: Send beacons to to driver if no beacons were passed
153 * for a specific period of time. Units: Beacons. 236 * for a specific period of time. Units: Beacons.
@@ -156,17 +239,17 @@ struct iwl_powertable_cmd {
156 * @ba_enable_beacon_abort: 1, beacon abort is enabled; 0, disabled. 239 * @ba_enable_beacon_abort: 1, beacon abort is enabled; 0, disabled.
157 */ 240 */
158struct iwl_beacon_filter_cmd { 241struct iwl_beacon_filter_cmd {
159 u8 bf_energy_delta; 242 __le32 bf_energy_delta;
160 u8 bf_roaming_energy_delta; 243 __le32 bf_roaming_energy_delta;
161 u8 bf_roaming_state; 244 __le32 bf_roaming_state;
162 u8 bf_temperature_delta; 245 __le32 bf_temp_threshold;
163 u8 bf_enable_beacon_filter; 246 __le32 bf_temp_fast_filter;
164 u8 bf_debug_flag; 247 __le32 bf_temp_slow_filter;
165 __le16 reserved1; 248 __le32 bf_enable_beacon_filter;
249 __le32 bf_debug_flag;
166 __le32 bf_escape_timer; 250 __le32 bf_escape_timer;
167 __le32 ba_escape_timer; 251 __le32 ba_escape_timer;
168 u8 ba_enable_beacon_abort; 252 __le32 ba_enable_beacon_abort;
169 u8 reserved2[3];
170} __packed; 253} __packed;
171 254
172/* Beacon filtering and beacon abort */ 255/* Beacon filtering and beacon abort */
@@ -182,9 +265,17 @@ struct iwl_beacon_filter_cmd {
182#define IWL_BF_ROAMING_STATE_MAX 255 265#define IWL_BF_ROAMING_STATE_MAX 255
183#define IWL_BF_ROAMING_STATE_MIN 0 266#define IWL_BF_ROAMING_STATE_MIN 0
184 267
185#define IWL_BF_TEMPERATURE_DELTA_DEFAULT 5 268#define IWL_BF_TEMP_THRESHOLD_DEFAULT 112
186#define IWL_BF_TEMPERATURE_DELTA_MAX 255 269#define IWL_BF_TEMP_THRESHOLD_MAX 255
187#define IWL_BF_TEMPERATURE_DELTA_MIN 0 270#define IWL_BF_TEMP_THRESHOLD_MIN 0
271
272#define IWL_BF_TEMP_FAST_FILTER_DEFAULT 1
273#define IWL_BF_TEMP_FAST_FILTER_MAX 255
274#define IWL_BF_TEMP_FAST_FILTER_MIN 0
275
276#define IWL_BF_TEMP_SLOW_FILTER_DEFAULT 5
277#define IWL_BF_TEMP_SLOW_FILTER_MAX 255
278#define IWL_BF_TEMP_SLOW_FILTER_MIN 0
188 279
189#define IWL_BF_ENABLE_BEACON_FILTER_DEFAULT 1 280#define IWL_BF_ENABLE_BEACON_FILTER_DEFAULT 1
190 281
@@ -194,19 +285,23 @@ struct iwl_beacon_filter_cmd {
194#define IWL_BF_ESCAPE_TIMER_MAX 1024 285#define IWL_BF_ESCAPE_TIMER_MAX 1024
195#define IWL_BF_ESCAPE_TIMER_MIN 0 286#define IWL_BF_ESCAPE_TIMER_MIN 0
196 287
197#define IWL_BA_ESCAPE_TIMER_DEFAULT 3 288#define IWL_BA_ESCAPE_TIMER_DEFAULT 6
289#define IWL_BA_ESCAPE_TIMER_D3 6
198#define IWL_BA_ESCAPE_TIMER_MAX 1024 290#define IWL_BA_ESCAPE_TIMER_MAX 1024
199#define IWL_BA_ESCAPE_TIMER_MIN 0 291#define IWL_BA_ESCAPE_TIMER_MIN 0
200 292
201#define IWL_BA_ENABLE_BEACON_ABORT_DEFAULT 1 293#define IWL_BA_ENABLE_BEACON_ABORT_DEFAULT 1
202 294
203#define IWL_BF_CMD_CONFIG_DEFAULTS \ 295#define IWL_BF_CMD_CONFIG_DEFAULTS \
204 .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT, \ 296 .bf_energy_delta = cpu_to_le32(IWL_BF_ENERGY_DELTA_DEFAULT), \
205 .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT, \ 297 .bf_roaming_energy_delta = \
206 .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT, \ 298 cpu_to_le32(IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT), \
207 .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT, \ 299 .bf_roaming_state = cpu_to_le32(IWL_BF_ROAMING_STATE_DEFAULT), \
208 .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT, \ 300 .bf_temp_threshold = cpu_to_le32(IWL_BF_TEMP_THRESHOLD_DEFAULT), \
209 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT), \ 301 .bf_temp_fast_filter = cpu_to_le32(IWL_BF_TEMP_FAST_FILTER_DEFAULT), \
302 .bf_temp_slow_filter = cpu_to_le32(IWL_BF_TEMP_SLOW_FILTER_DEFAULT), \
303 .bf_debug_flag = cpu_to_le32(IWL_BF_DEBUG_FLAG_DEFAULT), \
304 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT), \
210 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT) 305 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT)
211 306
212#endif 307#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 365095a0c3b3..83cb9b992ea4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -137,6 +137,8 @@ struct iwl_ssid_ie {
137 *@SCAN_FLAGS_DELAYED_SCAN_LOWBAND: 137 *@SCAN_FLAGS_DELAYED_SCAN_LOWBAND:
138 *@SCAN_FLAGS_DELAYED_SCAN_HIGHBAND: 138 *@SCAN_FLAGS_DELAYED_SCAN_HIGHBAND:
139 *@SCAN_FLAGS_FRAGMENTED_SCAN: 139 *@SCAN_FLAGS_FRAGMENTED_SCAN:
140 *@SCAN_FLAGS_PASSIVE2ACTIVE: use active scan on channels that was active
141 * in the past hour, even if they are marked as passive.
140 */ 142 */
141enum iwl_scan_flags { 143enum iwl_scan_flags {
142 SCAN_FLAGS_PERIODIC_SCAN = BIT(0), 144 SCAN_FLAGS_PERIODIC_SCAN = BIT(0),
@@ -144,6 +146,7 @@ enum iwl_scan_flags {
144 SCAN_FLAGS_DELAYED_SCAN_LOWBAND = BIT(2), 146 SCAN_FLAGS_DELAYED_SCAN_LOWBAND = BIT(2),
145 SCAN_FLAGS_DELAYED_SCAN_HIGHBAND = BIT(3), 147 SCAN_FLAGS_DELAYED_SCAN_HIGHBAND = BIT(3),
146 SCAN_FLAGS_FRAGMENTED_SCAN = BIT(4), 148 SCAN_FLAGS_FRAGMENTED_SCAN = BIT(4),
149 SCAN_FLAGS_PASSIVE2ACTIVE = BIT(5),
147}; 150};
148 151
149/** 152/**
@@ -178,7 +181,7 @@ enum iwl_scan_type {
178 * @quiet_time: in msecs, dwell this time for active scan on quiet channels 181 * @quiet_time: in msecs, dwell this time for active scan on quiet channels
179 * @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than 182 * @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
180 * this number of packets were received (typically 1) 183 * this number of packets were received (typically 1)
181 * @passive2active: is auto switching from passive to active allowed (0 or 1) 184 * @passive2active: is auto switching from passive to active during scan allowed
182 * @rxchain_sel_flags: RXON_RX_CHAIN_* 185 * @rxchain_sel_flags: RXON_RX_CHAIN_*
183 * @max_out_time: in usecs, max out of serving channel time 186 * @max_out_time: in usecs, max out of serving channel time
184 * @suspend_time: how long to pause scan when returning to service channel: 187 * @suspend_time: how long to pause scan when returning to service channel:
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 700cce731770..d606197bde8f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -91,7 +91,6 @@
91 * @TX_CMD_FLG_RESP_TO_DRV: zero this if the response should go only to FW 91 * @TX_CMD_FLG_RESP_TO_DRV: zero this if the response should go only to FW
92 * @TX_CMD_FLG_CCMP_AGG: this frame uses CCMP for aggregation acceleration 92 * @TX_CMD_FLG_CCMP_AGG: this frame uses CCMP for aggregation acceleration
93 * @TX_CMD_FLG_TKIP_MIC_DONE: FW already performed TKIP MIC calculation 93 * @TX_CMD_FLG_TKIP_MIC_DONE: FW already performed TKIP MIC calculation
94 * @TX_CMD_FLG_CTS_ONLY: send CTS only, no data after that
95 * @TX_CMD_FLG_DUR: disable duration overwriting used in PS-Poll Assoc-id 94 * @TX_CMD_FLG_DUR: disable duration overwriting used in PS-Poll Assoc-id
96 * @TX_CMD_FLG_FW_DROP: FW should mark frame to be dropped 95 * @TX_CMD_FLG_FW_DROP: FW should mark frame to be dropped
97 * @TX_CMD_FLG_EXEC_PAPD: execute PAPD 96 * @TX_CMD_FLG_EXEC_PAPD: execute PAPD
@@ -120,7 +119,6 @@ enum iwl_tx_flags {
120 TX_CMD_FLG_RESP_TO_DRV = BIT(21), 119 TX_CMD_FLG_RESP_TO_DRV = BIT(21),
121 TX_CMD_FLG_CCMP_AGG = BIT(22), 120 TX_CMD_FLG_CCMP_AGG = BIT(22),
122 TX_CMD_FLG_TKIP_MIC_DONE = BIT(23), 121 TX_CMD_FLG_TKIP_MIC_DONE = BIT(23),
123 TX_CMD_FLG_CTS_ONLY = BIT(24),
124 TX_CMD_FLG_DUR = BIT(25), 122 TX_CMD_FLG_DUR = BIT(25),
125 TX_CMD_FLG_FW_DROP = BIT(26), 123 TX_CMD_FLG_FW_DROP = BIT(26),
126 TX_CMD_FLG_EXEC_PAPD = BIT(27), 124 TX_CMD_FLG_EXEC_PAPD = BIT(27),
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index cbfb3beae783..55854a309f94 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -136,7 +136,7 @@ enum {
136 CALIB_RES_NOTIF_PHY_DB = 0x6b, 136 CALIB_RES_NOTIF_PHY_DB = 0x6b,
137 /* PHY_DB_CMD = 0x6c, */ 137 /* PHY_DB_CMD = 0x6c, */
138 138
139 /* Power */ 139 /* Power - legacy power table command */
140 POWER_TABLE_CMD = 0x77, 140 POWER_TABLE_CMD = 0x77,
141 141
142 /* Thermal Throttling*/ 142 /* Thermal Throttling*/
@@ -159,6 +159,7 @@ enum {
159 TX_ANT_CONFIGURATION_CMD = 0x98, 159 TX_ANT_CONFIGURATION_CMD = 0x98,
160 BT_CONFIG = 0x9b, 160 BT_CONFIG = 0x9b,
161 STATISTICS_NOTIFICATION = 0x9d, 161 STATISTICS_NOTIFICATION = 0x9d,
162 REDUCE_TX_POWER_CMD = 0x9f,
162 163
163 /* RF-KILL commands and notifications */ 164 /* RF-KILL commands and notifications */
164 CARD_STATE_CMD = 0xa0, 165 CARD_STATE_CMD = 0xa0,
@@ -166,6 +167,9 @@ enum {
166 167
167 MISSED_BEACONS_NOTIFICATION = 0xa2, 168 MISSED_BEACONS_NOTIFICATION = 0xa2,
168 169
170 /* Power - new power table command */
171 MAC_PM_POWER_TABLE = 0xa9,
172
169 REPLY_RX_PHY_CMD = 0xc0, 173 REPLY_RX_PHY_CMD = 0xc0,
170 REPLY_RX_MPDU_CMD = 0xc1, 174 REPLY_RX_MPDU_CMD = 0xc1,
171 BA_NOTIF = 0xc5, 175 BA_NOTIF = 0xc5,
@@ -223,6 +227,19 @@ struct iwl_tx_ant_cfg_cmd {
223 __le32 valid; 227 __le32 valid;
224} __packed; 228} __packed;
225 229
230/**
231 * struct iwl_reduce_tx_power_cmd - TX power reduction command
232 * REDUCE_TX_POWER_CMD = 0x9f
233 * @flags: (reserved for future implementation)
234 * @mac_context_id: id of the mac ctx for which we are reducing TX power.
235 * @pwr_restriction: TX power restriction in dBms.
236 */
237struct iwl_reduce_tx_power_cmd {
238 u8 flags;
239 u8 mac_context_id;
240 __le16 pwr_restriction;
241} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */
242
226/* 243/*
227 * Calibration control struct. 244 * Calibration control struct.
228 * Sent as part of the phy configuration command. 245 * Sent as part of the phy configuration command.
@@ -765,6 +782,14 @@ struct iwl_phy_context_cmd {
765} __packed; /* PHY_CONTEXT_CMD_API_VER_1 */ 782} __packed; /* PHY_CONTEXT_CMD_API_VER_1 */
766 783
767#define IWL_RX_INFO_PHY_CNT 8 784#define IWL_RX_INFO_PHY_CNT 8
785#define IWL_RX_INFO_ENERGY_ANT_ABC_IDX 1
786#define IWL_RX_INFO_ENERGY_ANT_A_MSK 0x000000ff
787#define IWL_RX_INFO_ENERGY_ANT_B_MSK 0x0000ff00
788#define IWL_RX_INFO_ENERGY_ANT_C_MSK 0x00ff0000
789#define IWL_RX_INFO_ENERGY_ANT_A_POS 0
790#define IWL_RX_INFO_ENERGY_ANT_B_POS 8
791#define IWL_RX_INFO_ENERGY_ANT_C_POS 16
792
768#define IWL_RX_INFO_AGC_IDX 1 793#define IWL_RX_INFO_AGC_IDX 1
769#define IWL_RX_INFO_RSSI_AB_IDX 2 794#define IWL_RX_INFO_RSSI_AB_IDX 2
770#define IWL_OFDM_AGC_A_MSK 0x0000007f 795#define IWL_OFDM_AGC_A_MSK 0x0000007f
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index cd7c0032cc58..c76299a3a1e0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -78,22 +78,6 @@
78 78
79#define UCODE_VALID_OK cpu_to_le32(0x1) 79#define UCODE_VALID_OK cpu_to_le32(0x1)
80 80
81/* Default calibration values for WkP - set to INIT image w/o running */
82static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 };
83static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 };
84
85struct iwl_calib_default_data {
86 u16 size;
87 void *data;
88};
89
90#define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf}
91
92static const struct iwl_calib_default_data wkp_calib_default_data[12] = {
93 [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew),
94 [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew),
95};
96
97struct iwl_mvm_alive_data { 81struct iwl_mvm_alive_data {
98 bool valid; 82 bool valid;
99 u32 scd_base_addr; 83 u32 scd_base_addr;
@@ -248,40 +232,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
248 sizeof(phy_cfg_cmd), &phy_cfg_cmd); 232 sizeof(phy_cfg_cmd), &phy_cfg_cmd);
249} 233}
250 234
251static int iwl_set_default_calibrations(struct iwl_mvm *mvm)
252{
253 u8 cmd_raw[16]; /* holds the variable size commands */
254 struct iwl_set_calib_default_cmd *cmd =
255 (struct iwl_set_calib_default_cmd *)cmd_raw;
256 int ret, i;
257
258 /* Setting default values for calibrations we don't run */
259 for (i = 0; i < ARRAY_SIZE(wkp_calib_default_data); i++) {
260 u16 cmd_len;
261
262 if (wkp_calib_default_data[i].size == 0)
263 continue;
264
265 memset(cmd_raw, 0, sizeof(cmd_raw));
266 cmd_len = wkp_calib_default_data[i].size + sizeof(cmd);
267 cmd->calib_index = cpu_to_le16(i);
268 cmd->length = cpu_to_le16(wkp_calib_default_data[i].size);
269 if (WARN_ONCE(cmd_len > sizeof(cmd_raw),
270 "Need to enlarge cmd_raw to %d\n", cmd_len))
271 break;
272 memcpy(cmd->data, wkp_calib_default_data[i].data,
273 wkp_calib_default_data[i].size);
274 ret = iwl_mvm_send_cmd_pdu(mvm, SET_CALIB_DEFAULT_CMD, 0,
275 sizeof(*cmd) +
276 wkp_calib_default_data[i].size,
277 cmd);
278 if (ret)
279 return ret;
280 }
281
282 return 0;
283}
284
285int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) 235int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
286{ 236{
287 struct iwl_notification_wait calib_wait; 237 struct iwl_notification_wait calib_wait;
@@ -342,11 +292,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
342 if (ret) 292 if (ret)
343 goto error; 293 goto error;
344 294
345 /* need to set default values */
346 ret = iwl_set_default_calibrations(mvm);
347 if (ret)
348 goto error;
349
350 /* 295 /*
351 * Send phy configurations command to init uCode 296 * Send phy configurations command to init uCode
352 * to start the 16.0 uCode init image internal calibrations. 297 * to start the 16.0 uCode init image internal calibrations.
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 94aae9c8562c..5fe23a5ea9b6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -264,7 +264,8 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
264 return 0; 264 return 0;
265 265
266 /* Therefore, in recovery, we can't get here */ 266 /* Therefore, in recovery, we can't get here */
267 WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)); 267 if (WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)))
268 return -EBUSY;
268 269
269 mvmvif->id = find_first_bit(data.available_mac_ids, 270 mvmvif->id = find_first_bit(data.available_mac_ids,
270 NUM_MAC_INDEX_DRIVER); 271 NUM_MAC_INDEX_DRIVER);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index f19baf0dea6b..785c782b166f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -153,7 +153,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
153 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 153 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
154 IEEE80211_HW_AMPDU_AGGREGATION | 154 IEEE80211_HW_AMPDU_AGGREGATION |
155 IEEE80211_HW_TIMING_BEACON_ONLY | 155 IEEE80211_HW_TIMING_BEACON_ONLY |
156 IEEE80211_HW_CONNECTION_MONITOR; 156 IEEE80211_HW_CONNECTION_MONITOR |
157 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
158 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
157 159
158 hw->queues = IWL_MVM_FIRST_AGG_QUEUE; 160 hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
159 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; 161 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
@@ -552,6 +554,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
552 goto out_release; 554 goto out_release;
553 } 555 }
554 556
557 iwl_mvm_vif_dbgfs_register(mvm, vif);
555 goto out_unlock; 558 goto out_unlock;
556 } 559 }
557 560
@@ -567,7 +570,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
567 570
568 /* beacon filtering */ 571 /* beacon filtering */
569 if (!mvm->bf_allowed_vif && 572 if (!mvm->bf_allowed_vif &&
570 vif->type == NL80211_IFTYPE_STATION && !vif->p2p){ 573 vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
574 mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED){
571 mvm->bf_allowed_vif = mvmvif; 575 mvm->bf_allowed_vif = mvmvif;
572 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; 576 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
573 } 577 }
@@ -719,6 +723,20 @@ out_release:
719 mutex_unlock(&mvm->mutex); 723 mutex_unlock(&mvm->mutex);
720} 724}
721 725
726static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
727 s8 tx_power)
728{
729 /* FW is in charge of regulatory enforcement */
730 struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = {
731 .mac_context_id = iwl_mvm_vif_from_mac80211(vif)->id,
732 .pwr_restriction = cpu_to_le16(tx_power),
733 };
734
735 return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, CMD_SYNC,
736 sizeof(reduce_txpwr_cmd),
737 &reduce_txpwr_cmd);
738}
739
722static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed) 740static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed)
723{ 741{
724 return 0; 742 return 0;
@@ -766,7 +784,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
766 IWL_ERR(mvm, "failed to update quotas\n"); 784 IWL_ERR(mvm, "failed to update quotas\n");
767 return; 785 return;
768 } 786 }
769 iwl_mvm_bt_coex_vif_assoc(mvm, vif);
770 iwl_mvm_configure_mcast_filter(mvm, vif); 787 iwl_mvm_configure_mcast_filter(mvm, vif);
771 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 788 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
772 /* remove AP station now that the MAC is unassoc */ 789 /* remove AP station now that the MAC is unassoc */
@@ -779,9 +796,15 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
779 if (ret) 796 if (ret)
780 IWL_ERR(mvm, "failed to update quotas\n"); 797 IWL_ERR(mvm, "failed to update quotas\n");
781 } 798 }
782 ret = iwl_mvm_power_update_mode(mvm, vif); 799 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD)) {
783 if (ret) 800 /* Workaround for FW bug, otherwise FW disables device
784 IWL_ERR(mvm, "failed to update power mode\n"); 801 * power save upon disassociation
802 */
803 ret = iwl_mvm_power_update_mode(mvm, vif);
804 if (ret)
805 IWL_ERR(mvm, "failed to update power mode\n");
806 }
807 iwl_mvm_bt_coex_vif_assoc(mvm, vif);
785 } else if (changes & BSS_CHANGED_BEACON_INFO) { 808 } else if (changes & BSS_CHANGED_BEACON_INFO) {
786 /* 809 /*
787 * We received a beacon _after_ association so 810 * We received a beacon _after_ association so
@@ -794,6 +817,11 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
794 if (ret) 817 if (ret)
795 IWL_ERR(mvm, "failed to update power mode\n"); 818 IWL_ERR(mvm, "failed to update power mode\n");
796 } 819 }
820 if (changes & BSS_CHANGED_TXPOWER) {
821 IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d\n",
822 bss_conf->txpower);
823 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
824 }
797} 825}
798 826
799static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 827static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 420e82d379d9..29bebae7f003 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -76,6 +76,7 @@
76#include "iwl-trans.h" 76#include "iwl-trans.h"
77#include "sta.h" 77#include "sta.h"
78#include "fw-api.h" 78#include "fw-api.h"
79#include "constants.h"
79 80
80#define IWL_INVALID_MAC80211_QUEUE 0xff 81#define IWL_INVALID_MAC80211_QUEUE 0xff
81#define IWL_MVM_MAX_ADDRESSES 5 82#define IWL_MVM_MAX_ADDRESSES 5
@@ -91,6 +92,9 @@ enum iwl_mvm_tx_fifo {
91}; 92};
92 93
93extern struct ieee80211_ops iwl_mvm_hw_ops; 94extern struct ieee80211_ops iwl_mvm_hw_ops;
95extern const struct iwl_mvm_power_ops pm_legacy_ops;
96extern const struct iwl_mvm_power_ops pm_mac_ops;
97
94/** 98/**
95 * struct iwl_mvm_mod_params - module parameters for iwlmvm 99 * struct iwl_mvm_mod_params - module parameters for iwlmvm
96 * @init_dbg: if true, then the NIC won't be stopped if the INIT fw asserted. 100 * @init_dbg: if true, then the NIC won't be stopped if the INIT fw asserted.
@@ -150,6 +154,17 @@ enum iwl_power_scheme {
150 154
151#define IWL_CONN_MAX_LISTEN_INTERVAL 70 155#define IWL_CONN_MAX_LISTEN_INTERVAL 70
152 156
157struct iwl_mvm_power_ops {
158 int (*power_update_mode)(struct iwl_mvm *mvm,
159 struct ieee80211_vif *vif);
160 int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
161#ifdef CONFIG_IWLWIFI_DEBUGFS
162 int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
163 char *buf, int bufsz);
164#endif
165};
166
167
153#ifdef CONFIG_IWLWIFI_DEBUGFS 168#ifdef CONFIG_IWLWIFI_DEBUGFS
154enum iwl_dbgfs_pm_mask { 169enum iwl_dbgfs_pm_mask {
155 MVM_DEBUGFS_PM_KEEP_ALIVE = BIT(0), 170 MVM_DEBUGFS_PM_KEEP_ALIVE = BIT(0),
@@ -163,7 +178,7 @@ enum iwl_dbgfs_pm_mask {
163}; 178};
164 179
165struct iwl_dbgfs_pm { 180struct iwl_dbgfs_pm {
166 u8 keep_alive_seconds; 181 u16 keep_alive_seconds;
167 u32 rx_data_timeout; 182 u32 rx_data_timeout;
168 u32 tx_data_timeout; 183 u32 tx_data_timeout;
169 bool skip_over_dtim; 184 bool skip_over_dtim;
@@ -180,24 +195,28 @@ enum iwl_dbgfs_bf_mask {
180 MVM_DEBUGFS_BF_ENERGY_DELTA = BIT(0), 195 MVM_DEBUGFS_BF_ENERGY_DELTA = BIT(0),
181 MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA = BIT(1), 196 MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA = BIT(1),
182 MVM_DEBUGFS_BF_ROAMING_STATE = BIT(2), 197 MVM_DEBUGFS_BF_ROAMING_STATE = BIT(2),
183 MVM_DEBUGFS_BF_TEMPERATURE_DELTA = BIT(3), 198 MVM_DEBUGFS_BF_TEMP_THRESHOLD = BIT(3),
184 MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER = BIT(4), 199 MVM_DEBUGFS_BF_TEMP_FAST_FILTER = BIT(4),
185 MVM_DEBUGFS_BF_DEBUG_FLAG = BIT(5), 200 MVM_DEBUGFS_BF_TEMP_SLOW_FILTER = BIT(5),
186 MVM_DEBUGFS_BF_ESCAPE_TIMER = BIT(6), 201 MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER = BIT(6),
187 MVM_DEBUGFS_BA_ESCAPE_TIMER = BIT(7), 202 MVM_DEBUGFS_BF_DEBUG_FLAG = BIT(7),
188 MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT = BIT(8), 203 MVM_DEBUGFS_BF_ESCAPE_TIMER = BIT(8),
204 MVM_DEBUGFS_BA_ESCAPE_TIMER = BIT(9),
205 MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT = BIT(10),
189}; 206};
190 207
191struct iwl_dbgfs_bf { 208struct iwl_dbgfs_bf {
192 u8 bf_energy_delta; 209 u32 bf_energy_delta;
193 u8 bf_roaming_energy_delta; 210 u32 bf_roaming_energy_delta;
194 u8 bf_roaming_state; 211 u32 bf_roaming_state;
195 u8 bf_temperature_delta; 212 u32 bf_temp_threshold;
196 u8 bf_enable_beacon_filter; 213 u32 bf_temp_fast_filter;
197 u8 bf_debug_flag; 214 u32 bf_temp_slow_filter;
215 u32 bf_enable_beacon_filter;
216 u32 bf_debug_flag;
198 u32 bf_escape_timer; 217 u32 bf_escape_timer;
199 u32 ba_escape_timer; 218 u32 ba_escape_timer;
200 u8 ba_enable_beacon_abort; 219 u32 ba_enable_beacon_abort;
201 int mask; 220 int mask;
202}; 221};
203#endif 222#endif
@@ -268,7 +287,7 @@ struct iwl_mvm_vif {
268 287
269#if IS_ENABLED(CONFIG_IPV6) 288#if IS_ENABLED(CONFIG_IPV6)
270 /* IPv6 addresses for WoWLAN */ 289 /* IPv6 addresses for WoWLAN */
271 struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS]; 290 struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX];
272 int num_target_ipv6_addrs; 291 int num_target_ipv6_addrs;
273#endif 292#endif
274#endif 293#endif
@@ -459,6 +478,9 @@ struct iwl_mvm {
459 */ 478 */
460 u8 vif_count; 479 u8 vif_count;
461 480
481 /* -1 for always, 0 for never, >0 for that many times */
482 s8 restart_fw;
483
462 struct led_classdev led; 484 struct led_classdev led;
463 485
464 struct ieee80211_vif *p2p_device_vif; 486 struct ieee80211_vif *p2p_device_vif;
@@ -482,6 +504,8 @@ struct iwl_mvm {
482 /* Thermal Throttling and CTkill */ 504 /* Thermal Throttling and CTkill */
483 struct iwl_mvm_tt_mgmt thermal_throttle; 505 struct iwl_mvm_tt_mgmt thermal_throttle;
484 s32 temperature; /* Celsius */ 506 s32 temperature; /* Celsius */
507
508 const struct iwl_mvm_power_ops *pm_ops;
485}; 509};
486 510
487/* Extract MVM priv from op_mode and _hw */ 511/* Extract MVM priv from op_mode and _hw */
@@ -525,6 +549,7 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
525 enum ieee80211_band band); 549 enum ieee80211_band band);
526u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx); 550u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
527void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm); 551void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm);
552void iwl_mvm_dump_sram(struct iwl_mvm *mvm);
528u8 first_antenna(u8 mask); 553u8 first_antenna(u8 mask);
529u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx); 554u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx);
530 555
@@ -660,10 +685,26 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
660 u8 flags, bool init); 685 u8 flags, bool init);
661 686
662/* power managment */ 687/* power managment */
663int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 688static inline int iwl_mvm_power_update_mode(struct iwl_mvm *mvm,
664int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 689 struct ieee80211_vif *vif)
665void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 690{
666 struct iwl_powertable_cmd *cmd); 691 return mvm->pm_ops->power_update_mode(mvm, vif);
692}
693
694static inline int iwl_mvm_power_disable(struct iwl_mvm *mvm,
695 struct ieee80211_vif *vif)
696{
697 return mvm->pm_ops->power_disable(mvm, vif);
698}
699
700#ifdef CONFIG_IWLWIFI_DEBUGFS
701static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm,
702 struct ieee80211_vif *vif,
703 char *buf, int bufsz)
704{
705 return mvm->pm_ops->power_dbgfs_read(mvm, vif, buf, bufsz);
706}
707#endif
667 708
668int iwl_mvm_leds_init(struct iwl_mvm *mvm); 709int iwl_mvm_leds_init(struct iwl_mvm *mvm);
669void iwl_mvm_leds_exit(struct iwl_mvm *mvm); 710void iwl_mvm_leds_exit(struct iwl_mvm *mvm);
@@ -707,6 +748,10 @@ int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
707 struct ieee80211_vif *vif); 748 struct ieee80211_vif *vif);
708int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, 749int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
709 struct ieee80211_vif *vif); 750 struct ieee80211_vif *vif);
751int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
752 struct iwl_beacon_filter_cmd *cmd);
753int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
754 struct ieee80211_vif *vif, bool enable);
710 755
711/* SMPS */ 756/* SMPS */
712void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 757void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index af79a14063a9..65e5fb86291f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -275,6 +275,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
275 CMD(BEACON_NOTIFICATION), 275 CMD(BEACON_NOTIFICATION),
276 CMD(BEACON_TEMPLATE_CMD), 276 CMD(BEACON_TEMPLATE_CMD),
277 CMD(STATISTICS_NOTIFICATION), 277 CMD(STATISTICS_NOTIFICATION),
278 CMD(REDUCE_TX_POWER_CMD),
278 CMD(TX_ANT_CONFIGURATION_CMD), 279 CMD(TX_ANT_CONFIGURATION_CMD),
279 CMD(D3_CONFIG_CMD), 280 CMD(D3_CONFIG_CMD),
280 CMD(PROT_OFFLOAD_CONFIG_CMD), 281 CMD(PROT_OFFLOAD_CONFIG_CMD),
@@ -301,6 +302,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
301 CMD(MCAST_FILTER_CMD), 302 CMD(MCAST_FILTER_CMD),
302 CMD(REPLY_BEACON_FILTERING_CMD), 303 CMD(REPLY_BEACON_FILTERING_CMD),
303 CMD(REPLY_THERMAL_MNG_BACKOFF), 304 CMD(REPLY_THERMAL_MNG_BACKOFF),
305 CMD(MAC_PM_POWER_TABLE),
304}; 306};
305#undef CMD 307#undef CMD
306 308
@@ -340,6 +342,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
340 mvm->fw = fw; 342 mvm->fw = fw;
341 mvm->hw = hw; 343 mvm->hw = hw;
342 344
345 mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0;
346
343 mutex_init(&mvm->mutex); 347 mutex_init(&mvm->mutex);
344 spin_lock_init(&mvm->async_handlers_lock); 348 spin_lock_init(&mvm->async_handlers_lock);
345 INIT_LIST_HEAD(&mvm->time_event_list); 349 INIT_LIST_HEAD(&mvm->time_event_list);
@@ -431,6 +435,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
431 if (err) 435 if (err)
432 goto out_unregister; 436 goto out_unregister;
433 437
438 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD)
439 mvm->pm_ops = &pm_mac_ops;
440 else
441 mvm->pm_ops = &pm_legacy_ops;
442
434 return op_mode; 443 return op_mode;
435 444
436 out_unregister: 445 out_unregister:
@@ -638,6 +647,22 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
638 ieee80211_free_txskb(mvm->hw, skb); 647 ieee80211_free_txskb(mvm->hw, skb);
639} 648}
640 649
650struct iwl_mvm_reprobe {
651 struct device *dev;
652 struct work_struct work;
653};
654
655static void iwl_mvm_reprobe_wk(struct work_struct *wk)
656{
657 struct iwl_mvm_reprobe *reprobe;
658
659 reprobe = container_of(wk, struct iwl_mvm_reprobe, work);
660 if (device_reprobe(reprobe->dev))
661 dev_err(reprobe->dev, "reprobe failed!\n");
662 kfree(reprobe);
663 module_put(THIS_MODULE);
664}
665
641static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) 666static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
642{ 667{
643 iwl_abort_notification_waits(&mvm->notif_wait); 668 iwl_abort_notification_waits(&mvm->notif_wait);
@@ -649,9 +674,30 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
649 * can't recover this since we're already half suspended. 674 * can't recover this since we're already half suspended.
650 */ 675 */
651 if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 676 if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
652 IWL_ERR(mvm, "Firmware error during reconfiguration! Abort.\n"); 677 struct iwl_mvm_reprobe *reprobe;
653 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && 678
654 iwlwifi_mod_params.restart_fw) { 679 IWL_ERR(mvm,
680 "Firmware error during reconfiguration - reprobe!\n");
681
682 /*
683 * get a module reference to avoid doing this while unloading
684 * anyway and to avoid scheduling a work with code that's
685 * being removed.
686 */
687 if (!try_module_get(THIS_MODULE)) {
688 IWL_ERR(mvm, "Module is being unloaded - abort\n");
689 return;
690 }
691
692 reprobe = kzalloc(sizeof(*reprobe), GFP_ATOMIC);
693 if (!reprobe) {
694 module_put(THIS_MODULE);
695 return;
696 }
697 reprobe->dev = mvm->trans->dev;
698 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
699 schedule_work(&reprobe->work);
700 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && mvm->restart_fw) {
655 /* 701 /*
656 * This is a bit racy, but worst case we tell mac80211 about 702 * This is a bit racy, but worst case we tell mac80211 about
657 * a stopped/aborted (sched) scan when that was already done 703 * a stopped/aborted (sched) scan when that was already done
@@ -669,6 +715,8 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
669 break; 715 break;
670 } 716 }
671 717
718 if (mvm->restart_fw > 0)
719 mvm->restart_fw--;
672 ieee80211_restart_hw(mvm->hw); 720 ieee80211_restart_hw(mvm->hw);
673 } 721 }
674} 722}
@@ -678,6 +726,8 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
678 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 726 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
679 727
680 iwl_mvm_dump_nic_error_log(mvm); 728 iwl_mvm_dump_nic_error_log(mvm);
729 if (!mvm->restart_fw)
730 iwl_mvm_dump_sram(mvm);
681 731
682 iwl_mvm_nic_restart(mvm); 732 iwl_mvm_nic_restart(mvm);
683} 733}
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index e7ca965a89b8..4e7c9f245846 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -75,8 +75,8 @@
75 75
76#define POWER_KEEP_ALIVE_PERIOD_SEC 25 76#define POWER_KEEP_ALIVE_PERIOD_SEC 25
77 77
78static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm, 78int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
79 struct iwl_beacon_filter_cmd *cmd) 79 struct iwl_beacon_filter_cmd *cmd)
80{ 80{
81 int ret; 81 int ret;
82 82
@@ -85,52 +85,60 @@ static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
85 85
86 if (!ret) { 86 if (!ret) {
87 IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n", 87 IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
88 cmd->ba_enable_beacon_abort); 88 le32_to_cpu(cmd->ba_enable_beacon_abort));
89 IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n", 89 IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
90 cmd->ba_escape_timer); 90 le32_to_cpu(cmd->ba_escape_timer));
91 IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n", 91 IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
92 cmd->bf_debug_flag); 92 le32_to_cpu(cmd->bf_debug_flag));
93 IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n", 93 IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
94 cmd->bf_enable_beacon_filter); 94 le32_to_cpu(cmd->bf_enable_beacon_filter));
95 IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n", 95 IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
96 cmd->bf_energy_delta); 96 le32_to_cpu(cmd->bf_energy_delta));
97 IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n", 97 IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
98 cmd->bf_escape_timer); 98 le32_to_cpu(cmd->bf_escape_timer));
99 IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n", 99 IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
100 cmd->bf_roaming_energy_delta); 100 le32_to_cpu(cmd->bf_roaming_energy_delta));
101 IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n", 101 IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
102 cmd->bf_roaming_state); 102 le32_to_cpu(cmd->bf_roaming_state));
103 IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n", 103 IWL_DEBUG_POWER(mvm, "bf_temp_threshold is: %d\n",
104 cmd->bf_temperature_delta); 104 le32_to_cpu(cmd->bf_temp_threshold));
105 IWL_DEBUG_POWER(mvm, "bf_temp_fast_filter is: %d\n",
106 le32_to_cpu(cmd->bf_temp_fast_filter));
107 IWL_DEBUG_POWER(mvm, "bf_temp_slow_filter is: %d\n",
108 le32_to_cpu(cmd->bf_temp_slow_filter));
105 } 109 }
106 return ret; 110 return ret;
107} 111}
108 112
109static int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm, 113int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
110 struct ieee80211_vif *vif, bool enable) 114 struct ieee80211_vif *vif, bool enable)
111{ 115{
112 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 116 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
113 struct iwl_beacon_filter_cmd cmd = { 117 struct iwl_beacon_filter_cmd cmd = {
114 IWL_BF_CMD_CONFIG_DEFAULTS, 118 IWL_BF_CMD_CONFIG_DEFAULTS,
115 .bf_enable_beacon_filter = 1, 119 .bf_enable_beacon_filter = cpu_to_le32(1),
116 .ba_enable_beacon_abort = enable, 120 .ba_enable_beacon_abort = cpu_to_le32(enable),
117 }; 121 };
118 122
119 if (!mvmvif->bf_enabled) 123 if (!mvmvif->bf_enabled)
120 return 0; 124 return 0;
121 125
126 if (mvm->cur_ucode == IWL_UCODE_WOWLAN)
127 cmd.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_D3);
128
122 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); 129 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
123 return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); 130 return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
124} 131}
125 132
126static void iwl_mvm_power_log(struct iwl_mvm *mvm, 133static void iwl_mvm_power_log(struct iwl_mvm *mvm,
127 struct iwl_powertable_cmd *cmd) 134 struct iwl_mac_power_cmd *cmd)
128{ 135{
129 IWL_DEBUG_POWER(mvm, 136 IWL_DEBUG_POWER(mvm,
130 "Sending power table command for power level %d, flags = 0x%X\n", 137 "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
131 iwlmvm_mod_params.power_scheme, 138 cmd->id_and_color, iwlmvm_mod_params.power_scheme,
132 le16_to_cpu(cmd->flags)); 139 le16_to_cpu(cmd->flags));
133 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", cmd->keep_alive_seconds); 140 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n",
141 le16_to_cpu(cmd->keep_alive_seconds));
134 142
135 if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { 143 if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
136 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", 144 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n",
@@ -139,15 +147,16 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
139 le32_to_cpu(cmd->tx_data_timeout)); 147 le32_to_cpu(cmd->tx_data_timeout));
140 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) 148 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK))
141 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n", 149 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n",
142 le32_to_cpu(cmd->skip_dtim_periods)); 150 cmd->skip_dtim_periods);
143 if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) 151 if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
144 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", 152 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
145 le32_to_cpu(cmd->lprx_rssi_threshold)); 153 cmd->lprx_rssi_threshold);
146 } 154 }
147} 155}
148 156
149void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 157static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
150 struct iwl_powertable_cmd *cmd) 158 struct ieee80211_vif *vif,
159 struct iwl_mac_power_cmd *cmd)
151{ 160{
152 struct ieee80211_hw *hw = mvm->hw; 161 struct ieee80211_hw *hw = mvm->hw;
153 struct ieee80211_chanctx_conf *chanctx_conf; 162 struct ieee80211_chanctx_conf *chanctx_conf;
@@ -158,19 +167,26 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
158 struct iwl_mvm_vif *mvmvif __maybe_unused = 167 struct iwl_mvm_vif *mvmvif __maybe_unused =
159 iwl_mvm_vif_from_mac80211(vif); 168 iwl_mvm_vif_from_mac80211(vif);
160 169
170 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
171 mvmvif->color));
172 dtimper = hw->conf.ps_dtim_period ?: 1;
173
161 /* 174 /*
162 * Regardless of power management state the driver must set 175 * Regardless of power management state the driver must set
163 * keep alive period. FW will use it for sending keep alive NDPs 176 * keep alive period. FW will use it for sending keep alive NDPs
164 * immediately after association. 177 * immediately after association. Check that keep alive period
178 * is at least 3 * DTIM
165 */ 179 */
166 cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC; 180 dtimper_msec = dtimper * vif->bss_conf.beacon_int;
181 keep_alive = max_t(int, 3 * dtimper_msec,
182 MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC);
183 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
184 cmd->keep_alive_seconds = cpu_to_le16(keep_alive);
167 185
168 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) 186 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)
169 return; 187 return;
170 188
171 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 189 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
172 if (!vif->bss_conf.assoc)
173 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
174 190
175#ifdef CONFIG_IWLWIFI_DEBUGFS 191#ifdef CONFIG_IWLWIFI_DEBUGFS
176 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF && 192 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
@@ -186,12 +202,9 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
186 (vif->bss_conf.beacon_rate->bitrate == 10 || 202 (vif->bss_conf.beacon_rate->bitrate == 10 ||
187 vif->bss_conf.beacon_rate->bitrate == 60)) { 203 vif->bss_conf.beacon_rate->bitrate == 60)) {
188 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK); 204 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
189 cmd->lprx_rssi_threshold = 205 cmd->lprx_rssi_threshold = POWER_LPRX_RSSI_THRESHOLD;
190 cpu_to_le32(POWER_LPRX_RSSI_THRESHOLD);
191 } 206 }
192 207
193 dtimper = hw->conf.ps_dtim_period ?: 1;
194
195 /* Check if radar detection is required on current channel */ 208 /* Check if radar detection is required on current channel */
196 rcu_read_lock(); 209 rcu_read_lock();
197 chanctx_conf = rcu_dereference(vif->chanctx_conf); 210 chanctx_conf = rcu_dereference(vif->chanctx_conf);
@@ -207,27 +220,25 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
207 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP || 220 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP ||
208 mvm->cur_ucode == IWL_UCODE_WOWLAN)) { 221 mvm->cur_ucode == IWL_UCODE_WOWLAN)) {
209 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); 222 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
210 cmd->skip_dtim_periods = cpu_to_le32(3); 223 cmd->skip_dtim_periods = 3;
211 } 224 }
212 225
213 /* Check that keep alive period is at least 3 * DTIM */
214 dtimper_msec = dtimper * vif->bss_conf.beacon_int;
215 keep_alive = max_t(int, 3 * dtimper_msec,
216 MSEC_PER_SEC * cmd->keep_alive_seconds);
217 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
218 cmd->keep_alive_seconds = keep_alive;
219
220 if (mvm->cur_ucode != IWL_UCODE_WOWLAN) { 226 if (mvm->cur_ucode != IWL_UCODE_WOWLAN) {
221 cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); 227 cmd->rx_data_timeout =
222 cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); 228 cpu_to_le32(IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT);
229 cmd->tx_data_timeout =
230 cpu_to_le32(IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT);
223 } else { 231 } else {
224 cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); 232 cmd->rx_data_timeout =
225 cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); 233 cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
234 cmd->tx_data_timeout =
235 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
226 } 236 }
227 237
228#ifdef CONFIG_IWLWIFI_DEBUGFS 238#ifdef CONFIG_IWLWIFI_DEBUGFS
229 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) 239 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
230 cmd->keep_alive_seconds = mvmvif->dbgfs_pm.keep_alive_seconds; 240 cmd->keep_alive_seconds =
241 cpu_to_le16(mvmvif->dbgfs_pm.keep_alive_seconds);
231 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) { 242 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) {
232 if (mvmvif->dbgfs_pm.skip_over_dtim) 243 if (mvmvif->dbgfs_pm.skip_over_dtim)
233 cmd->flags |= 244 cmd->flags |=
@@ -243,8 +254,7 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
243 cmd->tx_data_timeout = 254 cmd->tx_data_timeout =
244 cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout); 255 cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout);
245 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS) 256 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS)
246 cmd->skip_dtim_periods = 257 cmd->skip_dtim_periods = mvmvif->dbgfs_pm.skip_dtim_periods;
247 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods);
248 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) { 258 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) {
249 if (mvmvif->dbgfs_pm.lprx_ena) 259 if (mvmvif->dbgfs_pm.lprx_ena)
250 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK); 260 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
@@ -252,16 +262,16 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
252 cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK); 262 cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK);
253 } 263 }
254 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD) 264 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD)
255 cmd->lprx_rssi_threshold = 265 cmd->lprx_rssi_threshold = mvmvif->dbgfs_pm.lprx_rssi_threshold;
256 cpu_to_le32(mvmvif->dbgfs_pm.lprx_rssi_threshold);
257#endif /* CONFIG_IWLWIFI_DEBUGFS */ 266#endif /* CONFIG_IWLWIFI_DEBUGFS */
258} 267}
259 268
260int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 269static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
270 struct ieee80211_vif *vif)
261{ 271{
262 int ret; 272 int ret;
263 bool ba_enable; 273 bool ba_enable;
264 struct iwl_powertable_cmd cmd = {}; 274 struct iwl_mac_power_cmd cmd = {};
265 275
266 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 276 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
267 return 0; 277 return 0;
@@ -280,7 +290,7 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
280 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 290 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
281 iwl_mvm_power_log(mvm, &cmd); 291 iwl_mvm_power_log(mvm, &cmd);
282 292
283 ret = iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, 293 ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_SYNC,
284 sizeof(cmd), &cmd); 294 sizeof(cmd), &cmd);
285 if (ret) 295 if (ret)
286 return ret; 296 return ret;
@@ -291,15 +301,19 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
291 return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable); 301 return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable);
292} 302}
293 303
294int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 304static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
305 struct ieee80211_vif *vif)
295{ 306{
296 struct iwl_powertable_cmd cmd = {}; 307 struct iwl_mac_power_cmd cmd = {};
297 struct iwl_mvm_vif *mvmvif __maybe_unused = 308 struct iwl_mvm_vif *mvmvif __maybe_unused =
298 iwl_mvm_vif_from_mac80211(vif); 309 iwl_mvm_vif_from_mac80211(vif);
299 310
300 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 311 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
301 return 0; 312 return 0;
302 313
314 cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
315 mvmvif->color));
316
303 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) 317 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
304 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 318 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
305 319
@@ -310,11 +324,50 @@ int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
310#endif 324#endif
311 iwl_mvm_power_log(mvm, &cmd); 325 iwl_mvm_power_log(mvm, &cmd);
312 326
313 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, 327 return iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_ASYNC,
314 sizeof(cmd), &cmd); 328 sizeof(cmd), &cmd);
315} 329}
316 330
317#ifdef CONFIG_IWLWIFI_DEBUGFS 331#ifdef CONFIG_IWLWIFI_DEBUGFS
332static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
333 struct ieee80211_vif *vif, char *buf,
334 int bufsz)
335{
336 struct iwl_mac_power_cmd cmd = {};
337 int pos = 0;
338
339 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
340
341 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
342 (cmd.flags &
343 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
344 0 : 1);
345 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
346 cmd.skip_dtim_periods);
347 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
348 iwlmvm_mod_params.power_scheme);
349 pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
350 le16_to_cpu(cmd.flags));
351 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
352 le16_to_cpu(cmd.keep_alive_seconds));
353
354 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
355 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
356 (cmd.flags &
357 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ?
358 1 : 0);
359 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
360 le32_to_cpu(cmd.rx_data_timeout));
361 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
362 le32_to_cpu(cmd.tx_data_timeout));
363 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
364 pos += scnprintf(buf+pos, bufsz-pos,
365 "lprx_rssi_threshold = %d\n",
366 cmd.lprx_rssi_threshold);
367 }
368 return pos;
369}
370
318void 371void
319iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif, 372iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
320 struct iwl_beacon_filter_cmd *cmd) 373 struct iwl_beacon_filter_cmd *cmd)
@@ -323,22 +376,30 @@ iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
323 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf; 376 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
324 377
325 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ENERGY_DELTA) 378 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ENERGY_DELTA)
326 cmd->bf_energy_delta = dbgfs_bf->bf_energy_delta; 379 cmd->bf_energy_delta = cpu_to_le32(dbgfs_bf->bf_energy_delta);
327 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA) 380 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA)
328 cmd->bf_roaming_energy_delta = 381 cmd->bf_roaming_energy_delta =
329 dbgfs_bf->bf_roaming_energy_delta; 382 cpu_to_le32(dbgfs_bf->bf_roaming_energy_delta);
330 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_STATE) 383 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_STATE)
331 cmd->bf_roaming_state = dbgfs_bf->bf_roaming_state; 384 cmd->bf_roaming_state = cpu_to_le32(dbgfs_bf->bf_roaming_state);
332 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMPERATURE_DELTA) 385 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMP_THRESHOLD)
333 cmd->bf_temperature_delta = dbgfs_bf->bf_temperature_delta; 386 cmd->bf_temp_threshold =
387 cpu_to_le32(dbgfs_bf->bf_temp_threshold);
388 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMP_FAST_FILTER)
389 cmd->bf_temp_fast_filter =
390 cpu_to_le32(dbgfs_bf->bf_temp_fast_filter);
391 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMP_SLOW_FILTER)
392 cmd->bf_temp_slow_filter =
393 cpu_to_le32(dbgfs_bf->bf_temp_slow_filter);
334 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_DEBUG_FLAG) 394 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_DEBUG_FLAG)
335 cmd->bf_debug_flag = dbgfs_bf->bf_debug_flag; 395 cmd->bf_debug_flag = cpu_to_le32(dbgfs_bf->bf_debug_flag);
336 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ESCAPE_TIMER) 396 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ESCAPE_TIMER)
337 cmd->bf_escape_timer = cpu_to_le32(dbgfs_bf->bf_escape_timer); 397 cmd->bf_escape_timer = cpu_to_le32(dbgfs_bf->bf_escape_timer);
338 if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ESCAPE_TIMER) 398 if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ESCAPE_TIMER)
339 cmd->ba_escape_timer = cpu_to_le32(dbgfs_bf->ba_escape_timer); 399 cmd->ba_escape_timer = cpu_to_le32(dbgfs_bf->ba_escape_timer);
340 if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT) 400 if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT)
341 cmd->ba_enable_beacon_abort = dbgfs_bf->ba_enable_beacon_abort; 401 cmd->ba_enable_beacon_abort =
402 cpu_to_le32(dbgfs_bf->ba_enable_beacon_abort);
342} 403}
343#endif 404#endif
344 405
@@ -348,7 +409,7 @@ int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
348 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 409 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
349 struct iwl_beacon_filter_cmd cmd = { 410 struct iwl_beacon_filter_cmd cmd = {
350 IWL_BF_CMD_CONFIG_DEFAULTS, 411 IWL_BF_CMD_CONFIG_DEFAULTS,
351 .bf_enable_beacon_filter = 1, 412 .bf_enable_beacon_filter = cpu_to_le32(1),
352 }; 413 };
353 int ret; 414 int ret;
354 415
@@ -372,7 +433,8 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
372 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 433 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
373 int ret; 434 int ret;
374 435
375 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 436 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED) ||
437 vif->type != NL80211_IFTYPE_STATION || vif->p2p)
376 return 0; 438 return 0;
377 439
378 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); 440 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
@@ -382,3 +444,11 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
382 444
383 return ret; 445 return ret;
384} 446}
447
448const struct iwl_mvm_power_ops pm_mac_ops = {
449 .power_update_mode = iwl_mvm_power_mac_update_mode,
450 .power_disable = iwl_mvm_power_mac_disable,
451#ifdef CONFIG_IWLWIFI_DEBUGFS
452 .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read,
453#endif
454};
diff --git a/drivers/net/wireless/iwlwifi/mvm/power_legacy.c b/drivers/net/wireless/iwlwifi/mvm/power_legacy.c
new file mode 100644
index 000000000000..2ce79bad5845
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/power_legacy.c
@@ -0,0 +1,319 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
10 * 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 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/kernel.h>
65#include <linux/module.h>
66#include <linux/slab.h>
67#include <linux/init.h>
68
69#include <net/mac80211.h>
70
71#include "iwl-debug.h"
72#include "mvm.h"
73#include "iwl-modparams.h"
74#include "fw-api-power.h"
75
76#define POWER_KEEP_ALIVE_PERIOD_SEC 25
77
78static void iwl_mvm_power_log(struct iwl_mvm *mvm,
79 struct iwl_powertable_cmd *cmd)
80{
81 IWL_DEBUG_POWER(mvm,
82 "Sending power table command for power level %d, flags = 0x%X\n",
83 iwlmvm_mod_params.power_scheme,
84 le16_to_cpu(cmd->flags));
85 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", cmd->keep_alive_seconds);
86
87 if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
88 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n",
89 le32_to_cpu(cmd->rx_data_timeout));
90 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
91 le32_to_cpu(cmd->tx_data_timeout));
92 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK))
93 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n",
94 le32_to_cpu(cmd->skip_dtim_periods));
95 if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
96 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
97 le32_to_cpu(cmd->lprx_rssi_threshold));
98 }
99}
100
101static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
102 struct ieee80211_vif *vif,
103 struct iwl_powertable_cmd *cmd)
104{
105 struct ieee80211_hw *hw = mvm->hw;
106 struct ieee80211_chanctx_conf *chanctx_conf;
107 struct ieee80211_channel *chan;
108 int dtimper, dtimper_msec;
109 int keep_alive;
110 bool radar_detect = false;
111 struct iwl_mvm_vif *mvmvif __maybe_unused =
112 iwl_mvm_vif_from_mac80211(vif);
113
114 /*
115 * Regardless of power management state the driver must set
116 * keep alive period. FW will use it for sending keep alive NDPs
117 * immediately after association.
118 */
119 cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC;
120
121 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)
122 return;
123
124 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
125 if (!vif->bss_conf.assoc)
126 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
127
128#ifdef CONFIG_IWLWIFI_DEBUGFS
129 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
130 mvmvif->dbgfs_pm.disable_power_off)
131 cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
132#endif
133 if (!vif->bss_conf.ps)
134 return;
135
136 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
137
138 if (vif->bss_conf.beacon_rate &&
139 (vif->bss_conf.beacon_rate->bitrate == 10 ||
140 vif->bss_conf.beacon_rate->bitrate == 60)) {
141 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
142 cmd->lprx_rssi_threshold =
143 cpu_to_le32(POWER_LPRX_RSSI_THRESHOLD);
144 }
145
146 dtimper = hw->conf.ps_dtim_period ?: 1;
147
148 /* Check if radar detection is required on current channel */
149 rcu_read_lock();
150 chanctx_conf = rcu_dereference(vif->chanctx_conf);
151 WARN_ON(!chanctx_conf);
152 if (chanctx_conf) {
153 chan = chanctx_conf->def.chan;
154 radar_detect = chan->flags & IEEE80211_CHAN_RADAR;
155 }
156 rcu_read_unlock();
157
158 /* Check skip over DTIM conditions */
159 if (!radar_detect && (dtimper <= 10) &&
160 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP ||
161 mvm->cur_ucode == IWL_UCODE_WOWLAN)) {
162 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
163 cmd->skip_dtim_periods = cpu_to_le32(3);
164 }
165
166 /* Check that keep alive period is at least 3 * DTIM */
167 dtimper_msec = dtimper * vif->bss_conf.beacon_int;
168 keep_alive = max_t(int, 3 * dtimper_msec,
169 MSEC_PER_SEC * cmd->keep_alive_seconds);
170 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
171 cmd->keep_alive_seconds = keep_alive;
172
173 if (mvm->cur_ucode != IWL_UCODE_WOWLAN) {
174 cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
175 cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
176 } else {
177 cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
178 cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
179 }
180
181#ifdef CONFIG_IWLWIFI_DEBUGFS
182 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
183 cmd->keep_alive_seconds = mvmvif->dbgfs_pm.keep_alive_seconds;
184 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) {
185 if (mvmvif->dbgfs_pm.skip_over_dtim)
186 cmd->flags |=
187 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
188 else
189 cmd->flags &=
190 cpu_to_le16(~POWER_FLAGS_SKIP_OVER_DTIM_MSK);
191 }
192 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_RX_DATA_TIMEOUT)
193 cmd->rx_data_timeout =
194 cpu_to_le32(mvmvif->dbgfs_pm.rx_data_timeout);
195 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_TX_DATA_TIMEOUT)
196 cmd->tx_data_timeout =
197 cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout);
198 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS)
199 cmd->skip_dtim_periods =
200 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods);
201 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) {
202 if (mvmvif->dbgfs_pm.lprx_ena)
203 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
204 else
205 cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK);
206 }
207 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD)
208 cmd->lprx_rssi_threshold =
209 cpu_to_le32(mvmvif->dbgfs_pm.lprx_rssi_threshold);
210#endif /* CONFIG_IWLWIFI_DEBUGFS */
211}
212
213static int iwl_mvm_power_legacy_update_mode(struct iwl_mvm *mvm,
214 struct ieee80211_vif *vif)
215{
216 int ret;
217 bool ba_enable;
218 struct iwl_powertable_cmd cmd = {};
219
220 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
221 return 0;
222
223 /*
224 * TODO: The following vif_count verification is temporary condition.
225 * Avoid power mode update if more than one interface is currently
226 * active. Remove this condition when FW will support power management
227 * on multiple MACs.
228 */
229 IWL_DEBUG_POWER(mvm, "Currently %d interfaces active\n",
230 mvm->vif_count);
231 if (mvm->vif_count > 1)
232 return 0;
233
234 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
235 iwl_mvm_power_log(mvm, &cmd);
236
237 ret = iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
238 sizeof(cmd), &cmd);
239 if (ret)
240 return ret;
241
242 ba_enable = !!(cmd.flags &
243 cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
244
245 return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable);
246}
247
248static int iwl_mvm_power_legacy_disable(struct iwl_mvm *mvm,
249 struct ieee80211_vif *vif)
250{
251 struct iwl_powertable_cmd cmd = {};
252 struct iwl_mvm_vif *mvmvif __maybe_unused =
253 iwl_mvm_vif_from_mac80211(vif);
254
255 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
256 return 0;
257
258 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
259 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
260
261#ifdef CONFIG_IWLWIFI_DEBUGFS
262 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
263 mvmvif->dbgfs_pm.disable_power_off)
264 cmd.flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
265#endif
266 iwl_mvm_power_log(mvm, &cmd);
267
268 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC,
269 sizeof(cmd), &cmd);
270}
271
272#ifdef CONFIG_IWLWIFI_DEBUGFS
273static int iwl_mvm_power_legacy_dbgfs_read(struct iwl_mvm *mvm,
274 struct ieee80211_vif *vif, char *buf,
275 int bufsz)
276{
277 struct iwl_powertable_cmd cmd = {};
278 int pos = 0;
279
280 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
281
282 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
283 (cmd.flags &
284 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
285 0 : 1);
286 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
287 le32_to_cpu(cmd.skip_dtim_periods));
288 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
289 iwlmvm_mod_params.power_scheme);
290 pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
291 le16_to_cpu(cmd.flags));
292 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
293 cmd.keep_alive_seconds);
294
295 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
296 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
297 (cmd.flags &
298 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ?
299 1 : 0);
300 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
301 le32_to_cpu(cmd.rx_data_timeout));
302 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
303 le32_to_cpu(cmd.tx_data_timeout));
304 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
305 pos += scnprintf(buf+pos, bufsz-pos,
306 "lprx_rssi_threshold = %d\n",
307 le32_to_cpu(cmd.lprx_rssi_threshold));
308 }
309 return pos;
310}
311#endif
312
313const struct iwl_mvm_power_ops pm_legacy_ops = {
314 .power_update_mode = iwl_mvm_power_legacy_update_mode,
315 .power_disable = iwl_mvm_power_legacy_disable,
316#ifdef CONFIG_IWLWIFI_DEBUGFS
317 .power_dbgfs_read = iwl_mvm_power_legacy_dbgfs_read,
318#endif
319};
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 29d49cf0fdb2..18973874b77a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -132,7 +132,7 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
132int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) 132int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
133{ 133{
134 struct iwl_time_quota_cmd cmd; 134 struct iwl_time_quota_cmd cmd;
135 int i, idx, ret, num_active_bindings, quota, quota_rem; 135 int i, idx, ret, num_active_macs, quota, quota_rem;
136 struct iwl_mvm_quota_iterator_data data = { 136 struct iwl_mvm_quota_iterator_data data = {
137 .n_interfaces = {}, 137 .n_interfaces = {},
138 .colors = { -1, -1, -1, -1 }, 138 .colors = { -1, -1, -1, -1 },
@@ -162,18 +162,17 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
162 * IWL_MVM_MAX_QUOTA fragments. Divide these fragments 162 * IWL_MVM_MAX_QUOTA fragments. Divide these fragments
163 * equally between all the bindings that require quota 163 * equally between all the bindings that require quota
164 */ 164 */
165 num_active_bindings = 0; 165 num_active_macs = 0;
166 for (i = 0; i < MAX_BINDINGS; i++) { 166 for (i = 0; i < MAX_BINDINGS; i++) {
167 cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID); 167 cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
168 if (data.n_interfaces[i] > 0) 168 num_active_macs += data.n_interfaces[i];
169 num_active_bindings++;
170 } 169 }
171 170
172 quota = 0; 171 quota = 0;
173 quota_rem = 0; 172 quota_rem = 0;
174 if (num_active_bindings) { 173 if (num_active_macs) {
175 quota = IWL_MVM_MAX_QUOTA / num_active_bindings; 174 quota = IWL_MVM_MAX_QUOTA / num_active_macs;
176 quota_rem = IWL_MVM_MAX_QUOTA % num_active_bindings; 175 quota_rem = IWL_MVM_MAX_QUOTA % num_active_macs;
177 } 176 }
178 177
179 for (idx = 0, i = 0; i < MAX_BINDINGS; i++) { 178 for (idx = 0, i = 0; i < MAX_BINDINGS; i++) {
@@ -187,7 +186,8 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
187 cmd.quotas[idx].quota = cpu_to_le32(0); 186 cmd.quotas[idx].quota = cpu_to_le32(0);
188 cmd.quotas[idx].max_duration = cpu_to_le32(0); 187 cmd.quotas[idx].max_duration = cpu_to_le32(0);
189 } else { 188 } else {
190 cmd.quotas[idx].quota = cpu_to_le32(quota); 189 cmd.quotas[idx].quota =
190 cpu_to_le32(quota * data.n_interfaces[i]);
191 cmd.quotas[idx].max_duration = 191 cmd.quotas[idx].max_duration =
192 cpu_to_le32(IWL_MVM_MAX_QUOTA); 192 cpu_to_le32(IWL_MVM_MAX_QUOTA);
193 } 193 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index b328a988c130..9eeb21f62ef7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -2688,9 +2688,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2688 2688
2689 lq_sta->flush_timer = 0; 2689 lq_sta->flush_timer = 0;
2690 lq_sta->supp_rates = sta->supp_rates[sband->band]; 2690 lq_sta->supp_rates = sta->supp_rates[sband->band];
2691 for (j = 0; j < LQ_SIZE; j++)
2692 for (i = 0; i < IWL_RATE_COUNT; i++)
2693 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2694 2691
2695 IWL_DEBUG_RATE(mvm, 2692 IWL_DEBUG_RATE(mvm,
2696 "LQ: *** rate scale station global init for station %d ***\n", 2693 "LQ: *** rate scale station global init for station %d ***\n",
@@ -3159,8 +3156,9 @@ static void rs_remove_debugfs(void *mvm, void *mvm_sta)
3159 * station is added we ignore it. 3156 * station is added we ignore it.
3160 */ 3157 */
3161static void rs_rate_init_stub(void *mvm_r, 3158static void rs_rate_init_stub(void *mvm_r,
3162 struct ieee80211_supported_band *sband, 3159 struct ieee80211_supported_band *sband,
3163 struct ieee80211_sta *sta, void *mvm_sta) 3160 struct cfg80211_chan_def *chandef,
3161 struct ieee80211_sta *sta, void *mvm_sta)
3164{ 3162{
3165} 3163}
3166static struct rate_control_ops rs_mvm_ops = { 3164static struct rate_control_ops rs_mvm_ops = {
@@ -3193,13 +3191,14 @@ void iwl_mvm_rate_control_unregister(void)
3193 * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable 3191 * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable
3194 * Tx protection, according to this rquest and previous requests, 3192 * Tx protection, according to this rquest and previous requests,
3195 * and send the LQ command. 3193 * and send the LQ command.
3196 * @lq: The LQ command
3197 * @mvmsta: The station 3194 * @mvmsta: The station
3198 * @enable: Enable Tx protection? 3195 * @enable: Enable Tx protection?
3199 */ 3196 */
3200int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, 3197int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
3201 struct iwl_mvm_sta *mvmsta, bool enable) 3198 bool enable)
3202{ 3199{
3200 struct iwl_lq_cmd *lq = &mvmsta->lq_sta.lq;
3201
3203 lockdep_assert_held(&mvm->mutex); 3202 lockdep_assert_held(&mvm->mutex);
3204 3203
3205 if (enable) { 3204 if (enable) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index cff4f6da7733..29d699ac07c9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -404,7 +404,7 @@ extern void iwl_mvm_rate_control_unregister(void);
404 404
405struct iwl_mvm_sta; 405struct iwl_mvm_sta;
406 406
407int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, 407int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
408 struct iwl_mvm_sta *mvmsta, bool enable); 408 bool enable);
409 409
410#endif /* __rs__ */ 410#endif /* __rs__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index e4930d5027d2..6fd7fae30c0a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -124,24 +124,15 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
124 ieee80211_rx_ni(mvm->hw, skb); 124 ieee80211_rx_ni(mvm->hw, skb);
125} 125}
126 126
127/* 127static void iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
128 * iwl_mvm_calc_rssi - calculate the rssi in dBm 128 struct iwl_rx_phy_info *phy_info,
129 * @phy_info: the phy information for the coming packet 129 struct ieee80211_rx_status *rx_status)
130 */
131static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
132 struct iwl_rx_phy_info *phy_info)
133{ 130{
134 int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm; 131 int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
135 int rssi_all_band_a, rssi_all_band_b; 132 int rssi_all_band_a, rssi_all_band_b;
136 u32 agc_a, agc_b, max_agc; 133 u32 agc_a, agc_b, max_agc;
137 u32 val; 134 u32 val;
138 135
139 /* Find max rssi among 2 possible receivers.
140 * These values are measured by the Digital Signal Processor (DSP).
141 * They should stay fairly constant even as the signal strength varies,
142 * if the radio's Automatic Gain Control (AGC) is working right.
143 * AGC value (see below) will provide the "interesting" info.
144 */
145 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); 136 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
146 agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS; 137 agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS;
147 agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS; 138 agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS;
@@ -166,7 +157,45 @@ static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
166 IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n", 157 IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
167 rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b); 158 rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);
168 159
169 return max_rssi_dbm; 160 rx_status->signal = max_rssi_dbm;
161 rx_status->chains = (le16_to_cpu(phy_info->phy_flags) &
162 RX_RES_PHY_FLAGS_ANTENNA)
163 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
164 rx_status->chain_signal[0] = rssi_a_dbm;
165 rx_status->chain_signal[1] = rssi_b_dbm;
166}
167
168/*
169 * iwl_mvm_get_signal_strength - use new rx PHY INFO API
170 */
171static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
172 struct iwl_rx_phy_info *phy_info,
173 struct ieee80211_rx_status *rx_status)
174{
175 int energy_a, energy_b, energy_c, max_energy;
176 u32 val;
177
178 val =
179 le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_ENERGY_ANT_ABC_IDX]);
180 energy_a = -((val & IWL_RX_INFO_ENERGY_ANT_A_MSK) >>
181 IWL_RX_INFO_ENERGY_ANT_A_POS);
182 energy_b = -((val & IWL_RX_INFO_ENERGY_ANT_B_MSK) >>
183 IWL_RX_INFO_ENERGY_ANT_B_POS);
184 energy_c = -((val & IWL_RX_INFO_ENERGY_ANT_C_MSK) >>
185 IWL_RX_INFO_ENERGY_ANT_C_POS);
186 max_energy = max(energy_a, energy_b);
187 max_energy = max(max_energy, energy_c);
188
189 IWL_DEBUG_STATS(mvm, "energy In A %d B %d C %d , and max %d\n",
190 energy_a, energy_b, energy_c, max_energy);
191
192 rx_status->signal = max_energy;
193 rx_status->chains = (le16_to_cpu(phy_info->phy_flags) &
194 RX_RES_PHY_FLAGS_ANTENNA)
195 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
196 rx_status->chain_signal[0] = energy_a;
197 rx_status->chain_signal[1] = energy_b;
198 rx_status->chain_signal[2] = energy_c;
170} 199}
171 200
172/* 201/*
@@ -289,29 +318,14 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
289 */ 318 */
290 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ 319 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
291 320
292 /* Find max signal strength (dBm) among 3 antenna/receiver chains */ 321 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_RX_ENERGY_API)
293 rx_status.signal = iwl_mvm_calc_rssi(mvm, phy_info); 322 iwl_mvm_get_signal_strength(mvm, phy_info, &rx_status);
323 else
324 iwl_mvm_calc_rssi(mvm, phy_info, &rx_status);
294 325
295 IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal, 326 IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal,
296 (unsigned long long)rx_status.mactime); 327 (unsigned long long)rx_status.mactime);
297 328
298 /*
299 * "antenna number"
300 *
301 * It seems that the antenna field in the phy flags value
302 * is actually a bit field. This is undefined by radiotap,
303 * it wants an actual antenna number but I always get "7"
304 * for most legacy frames I receive indicating that the
305 * same frame was received on all three RX chains.
306 *
307 * I think this field should be removed in favor of a
308 * new 802.11n radiotap field "RX chains" that is defined
309 * as a bitmask.
310 */
311 rx_status.antenna = (le16_to_cpu(phy_info->phy_flags) &
312 RX_RES_PHY_FLAGS_ANTENNA)
313 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
314
315 /* set the preamble flag if appropriate */ 329 /* set the preamble flag if appropriate */
316 if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE)) 330 if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE))
317 rx_status.flag |= RX_FLAG_SHORTPRE; 331 rx_status.flag |= RX_FLAG_SHORTPRE;
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index acdff6b67e04..9a7ab8495300 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -301,10 +301,12 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
301 */ 301 */
302 if (req->n_ssids > 0) { 302 if (req->n_ssids > 0) {
303 cmd->passive2active = cpu_to_le16(1); 303 cmd->passive2active = cpu_to_le16(1);
304 cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE;
304 ssid = req->ssids[0].ssid; 305 ssid = req->ssids[0].ssid;
305 ssid_len = req->ssids[0].ssid_len; 306 ssid_len = req->ssids[0].ssid_len;
306 } else { 307 } else {
307 cmd->passive2active = 0; 308 cmd->passive2active = 0;
309 cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE;
308 } 310 }
309 311
310 iwl_mvm_scan_fill_ssids(cmd, req); 312 iwl_mvm_scan_fill_ssids(cmd, req);
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 563f559b902d..44add291531b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -826,8 +826,7 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
826 * method for HT traffic 826 * method for HT traffic
827 * this function also sends the LQ command 827 * this function also sends the LQ command
828 */ 828 */
829 return iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq, 829 return iwl_mvm_tx_protection(mvm, mvmsta, true);
830 mvmsta, true);
831 /* 830 /*
832 * TODO: remove the TLC_RTS flag when we tear down the last 831 * TODO: remove the TLC_RTS flag when we tear down the last
833 * AGG session (agg_tids_count in DVM) 832 * AGG session (agg_tids_count in DVM)
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index d6ae7f16ac11..1f3282dff513 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -391,8 +391,7 @@ static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
391 mvmsta = (void *)sta->drv_priv; 391 mvmsta = (void *)sta->drv_priv;
392 if (enable == mvmsta->tt_tx_protection) 392 if (enable == mvmsta->tt_tx_protection)
393 continue; 393 continue;
394 err = iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq, 394 err = iwl_mvm_tx_protection(mvm, mvmsta, enable);
395 mvmsta, enable);
396 if (err) { 395 if (err) {
397 IWL_ERR(mvm, "Failed to %s Tx protection\n", 396 IWL_ERR(mvm, "Failed to %s Tx protection\n",
398 enable ? "enable" : "disable"); 397 enable ? "enable" : "disable");
@@ -513,12 +512,39 @@ static const struct iwl_tt_params iwl7000_tt_params = {
513 .support_tx_backoff = true, 512 .support_tx_backoff = true,
514}; 513};
515 514
515static const struct iwl_tt_params iwl7000_high_temp_tt_params = {
516 .ct_kill_entry = 118,
517 .ct_kill_exit = 96,
518 .ct_kill_duration = 5,
519 .dynamic_smps_entry = 114,
520 .dynamic_smps_exit = 110,
521 .tx_protection_entry = 114,
522 .tx_protection_exit = 108,
523 .tx_backoff = {
524 {.temperature = 112, .backoff = 300},
525 {.temperature = 113, .backoff = 800},
526 {.temperature = 114, .backoff = 1500},
527 {.temperature = 115, .backoff = 3000},
528 {.temperature = 116, .backoff = 5000},
529 {.temperature = 117, .backoff = 10000},
530 },
531 .support_ct_kill = true,
532 .support_dynamic_smps = true,
533 .support_tx_protection = true,
534 .support_tx_backoff = true,
535};
536
516void iwl_mvm_tt_initialize(struct iwl_mvm *mvm) 537void iwl_mvm_tt_initialize(struct iwl_mvm *mvm)
517{ 538{
518 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle; 539 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
519 540
520 IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n"); 541 IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n");
521 tt->params = &iwl7000_tt_params; 542
543 if (mvm->cfg->high_temp)
544 tt->params = &iwl7000_high_temp_tt_params;
545 else
546 tt->params = &iwl7000_tt_params;
547
522 tt->throttle = false; 548 tt->throttle = false;
523 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill); 549 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);
524} 550}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index f0e96a927407..7694b8fa4c37 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -123,6 +123,8 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
123 * it 123 * it
124 */ 124 */
125 WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU); 125 WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU);
126 } else if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
127 tx_cmd->pm_frame_timeout = cpu_to_le16(2);
126 } else { 128 } else {
127 tx_cmd->pm_frame_timeout = 0; 129 tx_cmd->pm_frame_timeout = 0;
128 } 130 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 1e1332839e4a..a9c357491434 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -453,6 +453,29 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
453 IWL_ERR(mvm, "0x%08X | flow_handler\n", table.flow_handler); 453 IWL_ERR(mvm, "0x%08X | flow_handler\n", table.flow_handler);
454} 454}
455 455
456void iwl_mvm_dump_sram(struct iwl_mvm *mvm)
457{
458 const struct fw_img *img;
459 int ofs, len = 0;
460 u8 *buf;
461
462 if (!mvm->ucode_loaded)
463 return;
464
465 img = &mvm->fw->img[mvm->cur_ucode];
466 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
467 len = img->sec[IWL_UCODE_SECTION_DATA].len;
468
469 buf = kzalloc(len, GFP_KERNEL);
470 if (!buf)
471 return;
472
473 iwl_trans_read_mem_bytes(mvm->trans, ofs, buf, len);
474 iwl_print_hex_error(mvm->trans, buf, len);
475
476 kfree(buf);
477}
478
456/** 479/**
457 * iwl_mvm_send_lq_cmd() - Send link quality command 480 * iwl_mvm_send_lq_cmd() - Send link quality command
458 * @init: This command is sent as part of station initialization right 481 * @init: This command is sent as part of station initialization right
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index ff13458efc27..c96070fa93e4 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -273,9 +273,9 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
273 {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)}, 273 {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)},
274 {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)}, 274 {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)},
275 {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)}, 275 {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)},
276 {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg)}, 276 {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg_high_temp)},
277 {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg)}, 277 {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg_high_temp)},
278 {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg)}, 278 {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg_high_temp)},
279 {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)}, 279 {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
280 {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)}, 280 {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
281 {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)}, 281 {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index b654dcdd048a..fa22639b63c9 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -392,7 +392,6 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
392/***************************************************** 392/*****************************************************
393* Error handling 393* Error handling
394******************************************************/ 394******************************************************/
395int iwl_pcie_dump_fh(struct iwl_trans *trans, char **buf);
396void iwl_pcie_dump_csr(struct iwl_trans *trans); 395void iwl_pcie_dump_csr(struct iwl_trans *trans);
397 396
398/***************************************************** 397/*****************************************************
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index f600e68a410a..68837d4e9fa0 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -793,7 +793,7 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
793 } 793 }
794 794
795 iwl_pcie_dump_csr(trans); 795 iwl_pcie_dump_csr(trans);
796 iwl_pcie_dump_fh(trans, NULL); 796 iwl_dump_fh(trans, NULL);
797 797
798 set_bit(STATUS_FW_ERROR, &trans_pcie->status); 798 set_bit(STATUS_FW_ERROR, &trans_pcie->status);
799 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 799 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 96cfcdd39079..805e303dc4d9 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -1038,71 +1038,6 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
1038 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1038 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1039} 1039}
1040 1040
1041static const char *get_fh_string(int cmd)
1042{
1043#define IWL_CMD(x) case x: return #x
1044 switch (cmd) {
1045 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
1046 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
1047 IWL_CMD(FH_RSCSR_CHNL0_WPTR);
1048 IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
1049 IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
1050 IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
1051 IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
1052 IWL_CMD(FH_TSSR_TX_STATUS_REG);
1053 IWL_CMD(FH_TSSR_TX_ERROR_REG);
1054 default:
1055 return "UNKNOWN";
1056 }
1057#undef IWL_CMD
1058}
1059
1060int iwl_pcie_dump_fh(struct iwl_trans *trans, char **buf)
1061{
1062 int i;
1063 static const u32 fh_tbl[] = {
1064 FH_RSCSR_CHNL0_STTS_WPTR_REG,
1065 FH_RSCSR_CHNL0_RBDCB_BASE_REG,
1066 FH_RSCSR_CHNL0_WPTR,
1067 FH_MEM_RCSR_CHNL0_CONFIG_REG,
1068 FH_MEM_RSSR_SHARED_CTRL_REG,
1069 FH_MEM_RSSR_RX_STATUS_REG,
1070 FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
1071 FH_TSSR_TX_STATUS_REG,
1072 FH_TSSR_TX_ERROR_REG
1073 };
1074
1075#ifdef CONFIG_IWLWIFI_DEBUGFS
1076 if (buf) {
1077 int pos = 0;
1078 size_t bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
1079
1080 *buf = kmalloc(bufsz, GFP_KERNEL);
1081 if (!*buf)
1082 return -ENOMEM;
1083
1084 pos += scnprintf(*buf + pos, bufsz - pos,
1085 "FH register values:\n");
1086
1087 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++)
1088 pos += scnprintf(*buf + pos, bufsz - pos,
1089 " %34s: 0X%08x\n",
1090 get_fh_string(fh_tbl[i]),
1091 iwl_read_direct32(trans, fh_tbl[i]));
1092
1093 return pos;
1094 }
1095#endif
1096
1097 IWL_ERR(trans, "FH register values:\n");
1098 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++)
1099 IWL_ERR(trans, " %34s: 0X%08x\n",
1100 get_fh_string(fh_tbl[i]),
1101 iwl_read_direct32(trans, fh_tbl[i]));
1102
1103 return 0;
1104}
1105
1106static const char *get_csr_string(int cmd) 1041static const char *get_csr_string(int cmd)
1107{ 1042{
1108#define IWL_CMD(x) case x: return #x 1043#define IWL_CMD(x) case x: return #x
@@ -1183,18 +1118,7 @@ void iwl_pcie_dump_csr(struct iwl_trans *trans)
1183} while (0) 1118} while (0)
1184 1119
1185/* file operation */ 1120/* file operation */
1186#define DEBUGFS_READ_FUNC(name) \
1187static ssize_t iwl_dbgfs_##name##_read(struct file *file, \
1188 char __user *user_buf, \
1189 size_t count, loff_t *ppos);
1190
1191#define DEBUGFS_WRITE_FUNC(name) \
1192static ssize_t iwl_dbgfs_##name##_write(struct file *file, \
1193 const char __user *user_buf, \
1194 size_t count, loff_t *ppos);
1195
1196#define DEBUGFS_READ_FILE_OPS(name) \ 1121#define DEBUGFS_READ_FILE_OPS(name) \
1197 DEBUGFS_READ_FUNC(name); \
1198static const struct file_operations iwl_dbgfs_##name##_ops = { \ 1122static const struct file_operations iwl_dbgfs_##name##_ops = { \
1199 .read = iwl_dbgfs_##name##_read, \ 1123 .read = iwl_dbgfs_##name##_read, \
1200 .open = simple_open, \ 1124 .open = simple_open, \
@@ -1202,7 +1126,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
1202}; 1126};
1203 1127
1204#define DEBUGFS_WRITE_FILE_OPS(name) \ 1128#define DEBUGFS_WRITE_FILE_OPS(name) \
1205 DEBUGFS_WRITE_FUNC(name); \
1206static const struct file_operations iwl_dbgfs_##name##_ops = { \ 1129static const struct file_operations iwl_dbgfs_##name##_ops = { \
1207 .write = iwl_dbgfs_##name##_write, \ 1130 .write = iwl_dbgfs_##name##_write, \
1208 .open = simple_open, \ 1131 .open = simple_open, \
@@ -1210,8 +1133,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
1210}; 1133};
1211 1134
1212#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ 1135#define DEBUGFS_READ_WRITE_FILE_OPS(name) \
1213 DEBUGFS_READ_FUNC(name); \
1214 DEBUGFS_WRITE_FUNC(name); \
1215static const struct file_operations iwl_dbgfs_##name##_ops = { \ 1136static const struct file_operations iwl_dbgfs_##name##_ops = { \
1216 .write = iwl_dbgfs_##name##_write, \ 1137 .write = iwl_dbgfs_##name##_write, \
1217 .read = iwl_dbgfs_##name##_read, \ 1138 .read = iwl_dbgfs_##name##_read, \
@@ -1395,7 +1316,7 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
1395 int pos = 0; 1316 int pos = 0;
1396 ssize_t ret = -EFAULT; 1317 ssize_t ret = -EFAULT;
1397 1318
1398 ret = pos = iwl_pcie_dump_fh(trans, &buf); 1319 ret = pos = iwl_dump_fh(trans, &buf);
1399 if (buf) { 1320 if (buf) {
1400 ret = simple_read_from_buffer(user_buf, 1321 ret = simple_read_from_buffer(user_buf,
1401 count, ppos, buf, pos); 1322 count, ppos, buf, pos);
@@ -1502,10 +1423,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1502 spin_lock_init(&trans_pcie->reg_lock); 1423 spin_lock_init(&trans_pcie->reg_lock);
1503 init_waitqueue_head(&trans_pcie->ucode_write_waitq); 1424 init_waitqueue_head(&trans_pcie->ucode_write_waitq);
1504 1425
1505 /* W/A - seems to solve weird behavior. We need to remove this if we 1426 if (!cfg->base_params->pcie_l1_allowed) {
1506 * don't want to stay in L1 all the time. This wastes a lot of power */ 1427 /*
1507 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | 1428 * W/A - seems to solve weird behavior. We need to remove this
1508 PCIE_LINK_STATE_CLKPM); 1429 * if we don't want to stay in L1 all the time. This wastes a
1430 * lot of power.
1431 */
1432 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S |
1433 PCIE_LINK_STATE_L1 |
1434 PCIE_LINK_STATE_CLKPM);
1435 }
1509 1436
1510 if (pci_enable_device(pdev)) { 1437 if (pci_enable_device(pdev)) {
1511 err = -ENODEV; 1438 err = -ENODEV;
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index c47c92165aba..134f7a109f47 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1619,10 +1619,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1619 txq = &trans_pcie->txq[txq_id]; 1619 txq = &trans_pcie->txq[txq_id];
1620 q = &txq->q; 1620 q = &txq->q;
1621 1621
1622 if (unlikely(!test_bit(txq_id, trans_pcie->queue_used))) { 1622 if (WARN_ONCE(!test_bit(txq_id, trans_pcie->queue_used),
1623 WARN_ON_ONCE(1); 1623 "TX on unused queue %d\n", txq_id))
1624 return -EINVAL; 1624 return -EINVAL;
1625 }
1626 1625
1627 spin_lock(&txq->lock); 1626 spin_lock(&txq->lock);
1628 1627
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index cb34c7895f2a..7b2a6229eedb 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -867,7 +867,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
867 867
868 if (WARN_ON(skb->len < 10)) { 868 if (WARN_ON(skb->len < 10)) {
869 /* Should not happen; just a sanity check for addr1 use */ 869 /* Should not happen; just a sanity check for addr1 use */
870 dev_kfree_skb(skb); 870 ieee80211_free_txskb(hw, skb);
871 return; 871 return;
872 } 872 }
873 873
@@ -884,13 +884,13 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
884 } 884 }
885 885
886 if (WARN(!channel, "TX w/o channel - queue = %d\n", txi->hw_queue)) { 886 if (WARN(!channel, "TX w/o channel - queue = %d\n", txi->hw_queue)) {
887 dev_kfree_skb(skb); 887 ieee80211_free_txskb(hw, skb);
888 return; 888 return;
889 } 889 }
890 890
891 if (data->idle && !data->tmp_chan) { 891 if (data->idle && !data->tmp_chan) {
892 wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); 892 wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n");
893 dev_kfree_skb(skb); 893 ieee80211_free_txskb(hw, skb);
894 return; 894 return;
895 } 895 }
896 896
@@ -2309,7 +2309,9 @@ static int __init init_mac80211_hwsim(void)
2309 hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE; 2309 hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE;
2310 2310
2311 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | 2311 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
2312 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 2312 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
2313 WIPHY_FLAG_AP_UAPSD;
2314 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
2313 2315
2314 /* ask mac80211 to reserve space for magic */ 2316 /* ask mac80211 to reserve space for magic */
2315 hw->vif_data_size = sizeof(struct hwsim_vif_priv); 2317 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index a78e0651409c..8f9f54231a1c 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -189,7 +189,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
189 189
190 skb_src = skb_dequeue(&pra_list->skb_head); 190 skb_src = skb_dequeue(&pra_list->skb_head);
191 191
192 pra_list->total_pkts_size -= skb_src->len; 192 pra_list->total_pkt_count--;
193 193
194 atomic_dec(&priv->wmm.tx_pkts_queued); 194 atomic_dec(&priv->wmm.tx_pkts_queued);
195 195
@@ -268,7 +268,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
268 268
269 skb_queue_tail(&pra_list->skb_head, skb_aggr); 269 skb_queue_tail(&pra_list->skb_head, skb_aggr);
270 270
271 pra_list->total_pkts_size += skb_aggr->len; 271 pra_list->total_pkt_count++;
272 272
273 atomic_inc(&priv->wmm.tx_pkts_queued); 273 atomic_inc(&priv->wmm.tx_pkts_queued);
274 274
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 89459db4c53b..c5e21ede60f2 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -25,7 +25,9 @@ module_param(reg_alpha2, charp, 0);
25 25
26static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = { 26static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
27 { 27 {
28 .max = 2, .types = BIT(NL80211_IFTYPE_STATION), 28 .max = 2, .types = BIT(NL80211_IFTYPE_STATION) |
29 BIT(NL80211_IFTYPE_P2P_GO) |
30 BIT(NL80211_IFTYPE_P2P_CLIENT),
29 }, 31 },
30 { 32 {
31 .max = 1, .types = BIT(NL80211_IFTYPE_AP), 33 .max = 1, .types = BIT(NL80211_IFTYPE_AP),
@@ -189,6 +191,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
189 struct sk_buff *skb; 191 struct sk_buff *skb;
190 u16 pkt_len; 192 u16 pkt_len;
191 const struct ieee80211_mgmt *mgmt; 193 const struct ieee80211_mgmt *mgmt;
194 struct mwifiex_txinfo *tx_info;
192 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); 195 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
193 196
194 if (!buf || !len) { 197 if (!buf || !len) {
@@ -216,6 +219,10 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
216 return -ENOMEM; 219 return -ENOMEM;
217 } 220 }
218 221
222 tx_info = MWIFIEX_SKB_TXCB(skb);
223 tx_info->bss_num = priv->bss_num;
224 tx_info->bss_type = priv->bss_type;
225
219 mwifiex_form_mgmt_frame(skb, buf, len); 226 mwifiex_form_mgmt_frame(skb, buf, len);
220 mwifiex_queue_tx_pkt(priv, skb); 227 mwifiex_queue_tx_pkt(priv, skb);
221 228
@@ -235,16 +242,20 @@ mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
235 u16 frame_type, bool reg) 242 u16 frame_type, bool reg)
236{ 243{
237 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); 244 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
245 u32 mask;
238 246
239 if (reg) 247 if (reg)
240 priv->mgmt_frame_mask |= BIT(frame_type >> 4); 248 mask = priv->mgmt_frame_mask | BIT(frame_type >> 4);
241 else 249 else
242 priv->mgmt_frame_mask &= ~BIT(frame_type >> 4); 250 mask = priv->mgmt_frame_mask & ~BIT(frame_type >> 4);
243
244 mwifiex_send_cmd_async(priv, HostCmd_CMD_MGMT_FRAME_REG,
245 HostCmd_ACT_GEN_SET, 0, &priv->mgmt_frame_mask);
246 251
247 wiphy_dbg(wiphy, "info: mgmt frame registered\n"); 252 if (mask != priv->mgmt_frame_mask) {
253 priv->mgmt_frame_mask = mask;
254 mwifiex_send_cmd_async(priv, HostCmd_CMD_MGMT_FRAME_REG,
255 HostCmd_ACT_GEN_SET, 0,
256 &priv->mgmt_frame_mask);
257 wiphy_dbg(wiphy, "info: mgmt frame registered\n");
258 }
248} 259}
249 260
250/* 261/*
@@ -2298,8 +2309,7 @@ EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
2298 2309
2299#ifdef CONFIG_PM 2310#ifdef CONFIG_PM
2300static bool 2311static bool
2301mwifiex_is_pattern_supported(struct cfg80211_wowlan_trig_pkt_pattern *pat, 2312mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq)
2302 s8 *byte_seq)
2303{ 2313{
2304 int j, k, valid_byte_cnt = 0; 2314 int j, k, valid_byte_cnt = 0;
2305 bool dont_care_byte = false; 2315 bool dont_care_byte = false;
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 5178c4630d89..9eefacbc844b 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -404,11 +404,43 @@ mwifiex_is_rate_auto(struct mwifiex_private *priv)
404 return false; 404 return false;
405} 405}
406 406
407/* 407/* This function gets the supported data rates from bitmask inside
408 * This function gets the supported data rates. 408 * cfg80211_scan_request.
409 * 409 */
410 * The function works in both Ad-Hoc and infra mode by printing the 410u32 mwifiex_get_rates_from_cfg80211(struct mwifiex_private *priv,
411 * band and returning the data rates. 411 u8 *rates, u8 radio_type)
412{
413 struct wiphy *wiphy = priv->adapter->wiphy;
414 struct cfg80211_scan_request *request = priv->scan_request;
415 u32 num_rates, rate_mask;
416 struct ieee80211_supported_band *sband;
417 int i;
418
419 if (radio_type) {
420 sband = wiphy->bands[IEEE80211_BAND_5GHZ];
421 if (WARN_ON_ONCE(!sband))
422 return 0;
423 rate_mask = request->rates[IEEE80211_BAND_5GHZ];
424 } else {
425 sband = wiphy->bands[IEEE80211_BAND_2GHZ];
426 if (WARN_ON_ONCE(!sband))
427 return 0;
428 rate_mask = request->rates[IEEE80211_BAND_2GHZ];
429 }
430
431 num_rates = 0;
432 for (i = 0; i < sband->n_bitrates; i++) {
433 if ((BIT(i) & rate_mask) == 0)
434 continue; /* skip rate */
435 rates[num_rates++] = (u8)(sband->bitrates[i].bitrate / 5);
436 }
437
438 return num_rates;
439}
440
441/* This function gets the supported data rates. The function works in
442 * both Ad-Hoc and infra mode by printing the band and returning the
443 * data rates.
412 */ 444 */
413u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates) 445u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
414{ 446{
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 94cc09d48444..a5993475daef 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -75,7 +75,8 @@
75#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) 75#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
76#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1) 76#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1)
77 77
78#define MWIFIEX_BRIDGED_PKTS_THRESHOLD 1024 78#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
79#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128
79 80
80enum mwifiex_bss_type { 81enum mwifiex_bss_type {
81 MWIFIEX_BSS_TYPE_STA = 0, 82 MWIFIEX_BSS_TYPE_STA = 0,
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 1b45aa533300..c0dfc4dea75a 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -85,9 +85,6 @@ enum KEY_TYPE_ID {
85#define WAPI_KEY_LEN 50 85#define WAPI_KEY_LEN 50
86 86
87#define MAX_POLL_TRIES 100 87#define MAX_POLL_TRIES 100
88
89#define MAX_MULTI_INTERFACE_POLL_TRIES 1000
90
91#define MAX_FIRMWARE_POLL_TRIES 100 88#define MAX_FIRMWARE_POLL_TRIES 100
92 89
93#define FIRMWARE_READY_SDIO 0xfedc 90#define FIRMWARE_READY_SDIO 0xfedc
@@ -1369,11 +1366,6 @@ struct host_cmd_ds_802_11_eeprom_access {
1369 u8 value; 1366 u8 value;
1370} __packed; 1367} __packed;
1371 1368
1372struct host_cmd_tlv {
1373 __le16 type;
1374 __le16 len;
1375} __packed;
1376
1377struct mwifiex_assoc_event { 1369struct mwifiex_assoc_event {
1378 u8 sta_addr[ETH_ALEN]; 1370 u8 sta_addr[ETH_ALEN];
1379 __le16 type; 1371 __le16 type;
@@ -1399,99 +1391,99 @@ struct host_cmd_11ac_vht_cfg {
1399} __packed; 1391} __packed;
1400 1392
1401struct host_cmd_tlv_akmp { 1393struct host_cmd_tlv_akmp {
1402 struct host_cmd_tlv tlv; 1394 struct mwifiex_ie_types_header header;
1403 __le16 key_mgmt; 1395 __le16 key_mgmt;
1404 __le16 key_mgmt_operation; 1396 __le16 key_mgmt_operation;
1405} __packed; 1397} __packed;
1406 1398
1407struct host_cmd_tlv_pwk_cipher { 1399struct host_cmd_tlv_pwk_cipher {
1408 struct host_cmd_tlv tlv; 1400 struct mwifiex_ie_types_header header;
1409 __le16 proto; 1401 __le16 proto;
1410 u8 cipher; 1402 u8 cipher;
1411 u8 reserved; 1403 u8 reserved;
1412} __packed; 1404} __packed;
1413 1405
1414struct host_cmd_tlv_gwk_cipher { 1406struct host_cmd_tlv_gwk_cipher {
1415 struct host_cmd_tlv tlv; 1407 struct mwifiex_ie_types_header header;
1416 u8 cipher; 1408 u8 cipher;
1417 u8 reserved; 1409 u8 reserved;
1418} __packed; 1410} __packed;
1419 1411
1420struct host_cmd_tlv_passphrase { 1412struct host_cmd_tlv_passphrase {
1421 struct host_cmd_tlv tlv; 1413 struct mwifiex_ie_types_header header;
1422 u8 passphrase[0]; 1414 u8 passphrase[0];
1423} __packed; 1415} __packed;
1424 1416
1425struct host_cmd_tlv_wep_key { 1417struct host_cmd_tlv_wep_key {
1426 struct host_cmd_tlv tlv; 1418 struct mwifiex_ie_types_header header;
1427 u8 key_index; 1419 u8 key_index;
1428 u8 is_default; 1420 u8 is_default;
1429 u8 key[1]; 1421 u8 key[1];
1430}; 1422};
1431 1423
1432struct host_cmd_tlv_auth_type { 1424struct host_cmd_tlv_auth_type {
1433 struct host_cmd_tlv tlv; 1425 struct mwifiex_ie_types_header header;
1434 u8 auth_type; 1426 u8 auth_type;
1435} __packed; 1427} __packed;
1436 1428
1437struct host_cmd_tlv_encrypt_protocol { 1429struct host_cmd_tlv_encrypt_protocol {
1438 struct host_cmd_tlv tlv; 1430 struct mwifiex_ie_types_header header;
1439 __le16 proto; 1431 __le16 proto;
1440} __packed; 1432} __packed;
1441 1433
1442struct host_cmd_tlv_ssid { 1434struct host_cmd_tlv_ssid {
1443 struct host_cmd_tlv tlv; 1435 struct mwifiex_ie_types_header header;
1444 u8 ssid[0]; 1436 u8 ssid[0];
1445} __packed; 1437} __packed;
1446 1438
1447struct host_cmd_tlv_rates { 1439struct host_cmd_tlv_rates {
1448 struct host_cmd_tlv tlv; 1440 struct mwifiex_ie_types_header header;
1449 u8 rates[0]; 1441 u8 rates[0];
1450} __packed; 1442} __packed;
1451 1443
1452struct host_cmd_tlv_bcast_ssid { 1444struct host_cmd_tlv_bcast_ssid {
1453 struct host_cmd_tlv tlv; 1445 struct mwifiex_ie_types_header header;
1454 u8 bcast_ctl; 1446 u8 bcast_ctl;
1455} __packed; 1447} __packed;
1456 1448
1457struct host_cmd_tlv_beacon_period { 1449struct host_cmd_tlv_beacon_period {
1458 struct host_cmd_tlv tlv; 1450 struct mwifiex_ie_types_header header;
1459 __le16 period; 1451 __le16 period;
1460} __packed; 1452} __packed;
1461 1453
1462struct host_cmd_tlv_dtim_period { 1454struct host_cmd_tlv_dtim_period {
1463 struct host_cmd_tlv tlv; 1455 struct mwifiex_ie_types_header header;
1464 u8 period; 1456 u8 period;
1465} __packed; 1457} __packed;
1466 1458
1467struct host_cmd_tlv_frag_threshold { 1459struct host_cmd_tlv_frag_threshold {
1468 struct host_cmd_tlv tlv; 1460 struct mwifiex_ie_types_header header;
1469 __le16 frag_thr; 1461 __le16 frag_thr;
1470} __packed; 1462} __packed;
1471 1463
1472struct host_cmd_tlv_rts_threshold { 1464struct host_cmd_tlv_rts_threshold {
1473 struct host_cmd_tlv tlv; 1465 struct mwifiex_ie_types_header header;
1474 __le16 rts_thr; 1466 __le16 rts_thr;
1475} __packed; 1467} __packed;
1476 1468
1477struct host_cmd_tlv_retry_limit { 1469struct host_cmd_tlv_retry_limit {
1478 struct host_cmd_tlv tlv; 1470 struct mwifiex_ie_types_header header;
1479 u8 limit; 1471 u8 limit;
1480} __packed; 1472} __packed;
1481 1473
1482struct host_cmd_tlv_mac_addr { 1474struct host_cmd_tlv_mac_addr {
1483 struct host_cmd_tlv tlv; 1475 struct mwifiex_ie_types_header header;
1484 u8 mac_addr[ETH_ALEN]; 1476 u8 mac_addr[ETH_ALEN];
1485} __packed; 1477} __packed;
1486 1478
1487struct host_cmd_tlv_channel_band { 1479struct host_cmd_tlv_channel_band {
1488 struct host_cmd_tlv tlv; 1480 struct mwifiex_ie_types_header header;
1489 u8 band_config; 1481 u8 band_config;
1490 u8 channel; 1482 u8 channel;
1491} __packed; 1483} __packed;
1492 1484
1493struct host_cmd_tlv_ageout_timer { 1485struct host_cmd_tlv_ageout_timer {
1494 struct host_cmd_tlv tlv; 1486 struct mwifiex_ie_types_header header;
1495 __le32 sta_ao_timer; 1487 __le32 sta_ao_timer;
1496} __packed; 1488} __packed;
1497 1489
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index e38342f86c51..220af4fe0fc6 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -87,7 +87,7 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
87 u8 *tmp; 87 u8 *tmp;
88 88
89 input_len = le16_to_cpu(ie_list->len); 89 input_len = le16_to_cpu(ie_list->len);
90 travel_len = sizeof(struct host_cmd_tlv); 90 travel_len = sizeof(struct mwifiex_ie_types_header);
91 91
92 ie_list->len = 0; 92 ie_list->len = 0;
93 93
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 2cf8b964e966..e021a581a143 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -135,6 +135,7 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
135 135
136 priv->csa_chan = 0; 136 priv->csa_chan = 0;
137 priv->csa_expire_time = 0; 137 priv->csa_expire_time = 0;
138 priv->del_list_idx = 0;
138 139
139 return mwifiex_add_bss_prio_tbl(priv); 140 return mwifiex_add_bss_prio_tbl(priv);
140} 141}
@@ -377,18 +378,11 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
377static void 378static void
378mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) 379mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
379{ 380{
380 int i;
381
382 if (!adapter) { 381 if (!adapter) {
383 pr_err("%s: adapter is NULL\n", __func__); 382 pr_err("%s: adapter is NULL\n", __func__);
384 return; 383 return;
385 } 384 }
386 385
387 for (i = 0; i < adapter->priv_num; i++) {
388 if (adapter->priv[i])
389 del_timer_sync(&adapter->priv[i]->scan_delay_timer);
390 }
391
392 mwifiex_cancel_all_pending_cmd(adapter); 386 mwifiex_cancel_all_pending_cmd(adapter);
393 387
394 /* Free lock variables */ 388 /* Free lock variables */
@@ -398,13 +392,8 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
398 dev_dbg(adapter->dev, "info: free cmd buffer\n"); 392 dev_dbg(adapter->dev, "info: free cmd buffer\n");
399 mwifiex_free_cmd_buffer(adapter); 393 mwifiex_free_cmd_buffer(adapter);
400 394
401 del_timer(&adapter->cmd_timer);
402
403 dev_dbg(adapter->dev, "info: free scan table\n"); 395 dev_dbg(adapter->dev, "info: free scan table\n");
404 396
405 if (adapter->if_ops.cleanup_if)
406 adapter->if_ops.cleanup_if(adapter);
407
408 if (adapter->sleep_cfm) 397 if (adapter->sleep_cfm)
409 dev_kfree_skb_any(adapter->sleep_cfm); 398 dev_kfree_skb_any(adapter->sleep_cfm);
410} 399}
@@ -702,7 +691,6 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
702 if (!adapter->winner) { 691 if (!adapter->winner) {
703 dev_notice(adapter->dev, 692 dev_notice(adapter->dev,
704 "FW already running! Skip FW dnld\n"); 693 "FW already running! Skip FW dnld\n");
705 poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
706 goto poll_fw; 694 goto poll_fw;
707 } 695 }
708 } 696 }
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 12e778159ec5..9d7c0e6c4fc7 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1427,6 +1427,7 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
1427 1427
1428 switch (priv->bss_mode) { 1428 switch (priv->bss_mode) {
1429 case NL80211_IFTYPE_STATION: 1429 case NL80211_IFTYPE_STATION:
1430 case NL80211_IFTYPE_P2P_CLIENT:
1430 return mwifiex_deauthenticate_infra(priv, mac); 1431 return mwifiex_deauthenticate_infra(priv, mac);
1431 case NL80211_IFTYPE_ADHOC: 1432 case NL80211_IFTYPE_ADHOC:
1432 return mwifiex_send_cmd_sync(priv, 1433 return mwifiex_send_cmd_sync(priv,
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 1753431de361..3402bffdd016 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -191,12 +191,16 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
191{ 191{
192 s32 i; 192 s32 i;
193 193
194 if (adapter->if_ops.cleanup_if)
195 adapter->if_ops.cleanup_if(adapter);
196
194 del_timer(&adapter->cmd_timer); 197 del_timer(&adapter->cmd_timer);
195 198
196 /* Free private structures */ 199 /* Free private structures */
197 for (i = 0; i < adapter->priv_num; i++) { 200 for (i = 0; i < adapter->priv_num; i++) {
198 if (adapter->priv[i]) { 201 if (adapter->priv[i]) {
199 mwifiex_free_curr_bcn(adapter->priv[i]); 202 mwifiex_free_curr_bcn(adapter->priv[i]);
203 del_timer_sync(&adapter->priv[i]->scan_delay_timer);
200 kfree(adapter->priv[i]); 204 kfree(adapter->priv[i]);
201 } 205 }
202 } 206 }
@@ -386,6 +390,17 @@ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
386} 390}
387 391
388/* 392/*
393 * This function cancels all works in the queue and destroys
394 * the main workqueue.
395 */
396static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
397{
398 flush_workqueue(adapter->workqueue);
399 destroy_workqueue(adapter->workqueue);
400 adapter->workqueue = NULL;
401}
402
403/*
389 * This function gets firmware and initializes it. 404 * This function gets firmware and initializes it.
390 * 405 *
391 * The main initialization steps followed are - 406 * The main initialization steps followed are -
@@ -394,16 +409,18 @@ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
394 */ 409 */
395static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) 410static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
396{ 411{
397 int ret; 412 int ret, i;
398 char fmt[64]; 413 char fmt[64];
399 struct mwifiex_private *priv; 414 struct mwifiex_private *priv;
400 struct mwifiex_adapter *adapter = context; 415 struct mwifiex_adapter *adapter = context;
401 struct mwifiex_fw_image fw; 416 struct mwifiex_fw_image fw;
417 struct semaphore *sem = adapter->card_sem;
418 bool init_failed = false;
402 419
403 if (!firmware) { 420 if (!firmware) {
404 dev_err(adapter->dev, 421 dev_err(adapter->dev,
405 "Failed to get firmware %s\n", adapter->fw_name); 422 "Failed to get firmware %s\n", adapter->fw_name);
406 goto done; 423 goto err_dnld_fw;
407 } 424 }
408 425
409 memset(&fw, 0, sizeof(struct mwifiex_fw_image)); 426 memset(&fw, 0, sizeof(struct mwifiex_fw_image));
@@ -416,7 +433,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
416 else 433 else
417 ret = mwifiex_dnld_fw(adapter, &fw); 434 ret = mwifiex_dnld_fw(adapter, &fw);
418 if (ret == -1) 435 if (ret == -1)
419 goto done; 436 goto err_dnld_fw;
420 437
421 dev_notice(adapter->dev, "WLAN FW is active\n"); 438 dev_notice(adapter->dev, "WLAN FW is active\n");
422 439
@@ -428,13 +445,15 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
428 } 445 }
429 446
430 /* enable host interrupt after fw dnld is successful */ 447 /* enable host interrupt after fw dnld is successful */
431 if (adapter->if_ops.enable_int) 448 if (adapter->if_ops.enable_int) {
432 adapter->if_ops.enable_int(adapter); 449 if (adapter->if_ops.enable_int(adapter))
450 goto err_dnld_fw;
451 }
433 452
434 adapter->init_wait_q_woken = false; 453 adapter->init_wait_q_woken = false;
435 ret = mwifiex_init_fw(adapter); 454 ret = mwifiex_init_fw(adapter);
436 if (ret == -1) { 455 if (ret == -1) {
437 goto done; 456 goto err_init_fw;
438 } else if (!ret) { 457 } else if (!ret) {
439 adapter->hw_status = MWIFIEX_HW_STATUS_READY; 458 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
440 goto done; 459 goto done;
@@ -443,12 +462,12 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
443 wait_event_interruptible(adapter->init_wait_q, 462 wait_event_interruptible(adapter->init_wait_q,
444 adapter->init_wait_q_woken); 463 adapter->init_wait_q_woken);
445 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) 464 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
446 goto done; 465 goto err_init_fw;
447 466
448 priv = adapter->priv[MWIFIEX_BSS_ROLE_STA]; 467 priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
449 if (mwifiex_register_cfg80211(adapter)) { 468 if (mwifiex_register_cfg80211(adapter)) {
450 dev_err(adapter->dev, "cannot register with cfg80211\n"); 469 dev_err(adapter->dev, "cannot register with cfg80211\n");
451 goto err_init_fw; 470 goto err_register_cfg80211;
452 } 471 }
453 472
454 rtnl_lock(); 473 rtnl_lock();
@@ -479,20 +498,52 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
479 goto done; 498 goto done;
480 499
481err_add_intf: 500err_add_intf:
482 mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev); 501 for (i = 0; i < adapter->priv_num; i++) {
502 priv = adapter->priv[i];
503
504 if (!priv)
505 continue;
506
507 if (priv->wdev && priv->netdev)
508 mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
509 }
483 rtnl_unlock(); 510 rtnl_unlock();
511err_register_cfg80211:
512 wiphy_unregister(adapter->wiphy);
513 wiphy_free(adapter->wiphy);
484err_init_fw: 514err_init_fw:
485 if (adapter->if_ops.disable_int) 515 if (adapter->if_ops.disable_int)
486 adapter->if_ops.disable_int(adapter); 516 adapter->if_ops.disable_int(adapter);
517err_dnld_fw:
487 pr_debug("info: %s: unregister device\n", __func__); 518 pr_debug("info: %s: unregister device\n", __func__);
488 adapter->if_ops.unregister_dev(adapter); 519 if (adapter->if_ops.unregister_dev)
520 adapter->if_ops.unregister_dev(adapter);
521
522 if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
523 (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
524 pr_debug("info: %s: shutdown mwifiex\n", __func__);
525 adapter->init_wait_q_woken = false;
526
527 if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
528 wait_event_interruptible(adapter->init_wait_q,
529 adapter->init_wait_q_woken);
530 }
531 adapter->surprise_removed = true;
532 mwifiex_terminate_workqueue(adapter);
533 init_failed = true;
489done: 534done:
490 if (adapter->cal_data) { 535 if (adapter->cal_data) {
491 release_firmware(adapter->cal_data); 536 release_firmware(adapter->cal_data);
492 adapter->cal_data = NULL; 537 adapter->cal_data = NULL;
493 } 538 }
494 release_firmware(adapter->firmware); 539 if (adapter->firmware) {
540 release_firmware(adapter->firmware);
541 adapter->firmware = NULL;
542 }
495 complete(&adapter->fw_load); 543 complete(&adapter->fw_load);
544 if (init_failed)
545 mwifiex_free_adapter(adapter);
546 up(sem);
496 return; 547 return;
497} 548}
498 549
@@ -803,18 +854,6 @@ static void mwifiex_main_work_queue(struct work_struct *work)
803} 854}
804 855
805/* 856/*
806 * This function cancels all works in the queue and destroys
807 * the main workqueue.
808 */
809static void
810mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
811{
812 flush_workqueue(adapter->workqueue);
813 destroy_workqueue(adapter->workqueue);
814 adapter->workqueue = NULL;
815}
816
817/*
818 * This function adds the card. 857 * This function adds the card.
819 * 858 *
820 * This function follows the following major steps to set up the device - 859 * This function follows the following major steps to set up the device -
@@ -842,6 +881,7 @@ mwifiex_add_card(void *card, struct semaphore *sem,
842 } 881 }
843 882
844 adapter->iface_type = iface_type; 883 adapter->iface_type = iface_type;
884 adapter->card_sem = sem;
845 885
846 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; 886 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
847 adapter->surprise_removed = false; 887 adapter->surprise_removed = false;
@@ -872,17 +912,12 @@ mwifiex_add_card(void *card, struct semaphore *sem,
872 goto err_init_fw; 912 goto err_init_fw;
873 } 913 }
874 914
875 up(sem);
876 return 0; 915 return 0;
877 916
878err_init_fw: 917err_init_fw:
879 pr_debug("info: %s: unregister device\n", __func__); 918 pr_debug("info: %s: unregister device\n", __func__);
880 if (adapter->if_ops.unregister_dev) 919 if (adapter->if_ops.unregister_dev)
881 adapter->if_ops.unregister_dev(adapter); 920 adapter->if_ops.unregister_dev(adapter);
882err_registerdev:
883 adapter->surprise_removed = true;
884 mwifiex_terminate_workqueue(adapter);
885err_kmalloc:
886 if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) || 921 if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
887 (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) { 922 (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
888 pr_debug("info: %s: shutdown mwifiex\n", __func__); 923 pr_debug("info: %s: shutdown mwifiex\n", __func__);
@@ -892,7 +927,10 @@ err_kmalloc:
892 wait_event_interruptible(adapter->init_wait_q, 927 wait_event_interruptible(adapter->init_wait_q,
893 adapter->init_wait_q_woken); 928 adapter->init_wait_q_woken);
894 } 929 }
895 930err_registerdev:
931 adapter->surprise_removed = true;
932 mwifiex_terminate_workqueue(adapter);
933err_kmalloc:
896 mwifiex_free_adapter(adapter); 934 mwifiex_free_adapter(adapter);
897 935
898err_init_sw: 936err_init_sw:
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 253e0bd38e25..d2e5ccd891da 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -204,11 +204,11 @@ struct mwifiex_ra_list_tbl {
204 struct list_head list; 204 struct list_head list;
205 struct sk_buff_head skb_head; 205 struct sk_buff_head skb_head;
206 u8 ra[ETH_ALEN]; 206 u8 ra[ETH_ALEN];
207 u32 total_pkts_size;
208 u32 is_11n_enabled; 207 u32 is_11n_enabled;
209 u16 max_amsdu; 208 u16 max_amsdu;
210 u16 pkt_count; 209 u16 ba_pkt_count;
211 u8 ba_packet_thr; 210 u8 ba_packet_thr;
211 u16 total_pkt_count;
212}; 212};
213 213
214struct mwifiex_tid_tbl { 214struct mwifiex_tid_tbl {
@@ -515,6 +515,7 @@ struct mwifiex_private {
515 bool scan_aborting; 515 bool scan_aborting;
516 u8 csa_chan; 516 u8 csa_chan;
517 unsigned long csa_expire_time; 517 unsigned long csa_expire_time;
518 u8 del_list_idx;
518}; 519};
519 520
520enum mwifiex_ba_status { 521enum mwifiex_ba_status {
@@ -748,6 +749,7 @@ struct mwifiex_adapter {
748 749
749 atomic_t is_tx_received; 750 atomic_t is_tx_received;
750 atomic_t pending_bridged_pkts; 751 atomic_t pending_bridged_pkts;
752 struct semaphore *card_sem;
751}; 753};
752 754
753int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 755int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -900,6 +902,8 @@ int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask,
900u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, 902u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv,
901 u8 *rates); 903 u8 *rates);
902u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); 904u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates);
905u32 mwifiex_get_rates_from_cfg80211(struct mwifiex_private *priv,
906 u8 *rates, u8 radio_type);
903u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); 907u8 mwifiex_is_rate_auto(struct mwifiex_private *priv);
904extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; 908extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE];
905void mwifiex_save_curr_bcn(struct mwifiex_private *priv); 909void mwifiex_save_curr_bcn(struct mwifiex_private *priv);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 20c9c4c7b0b2..52da8ee7599a 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -76,7 +76,7 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
76 return false; 76 return false;
77} 77}
78 78
79#ifdef CONFIG_PM 79#ifdef CONFIG_PM_SLEEP
80/* 80/*
81 * Kernel needs to suspend all functions separately. Therefore all 81 * Kernel needs to suspend all functions separately. Therefore all
82 * registered functions must have drivers with suspend and resume 82 * registered functions must have drivers with suspend and resume
@@ -85,11 +85,12 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
85 * If already not suspended, this function allocates and sends a host 85 * If already not suspended, this function allocates and sends a host
86 * sleep activate request to the firmware and turns off the traffic. 86 * sleep activate request to the firmware and turns off the traffic.
87 */ 87 */
88static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state) 88static int mwifiex_pcie_suspend(struct device *dev)
89{ 89{
90 struct mwifiex_adapter *adapter; 90 struct mwifiex_adapter *adapter;
91 struct pcie_service_card *card; 91 struct pcie_service_card *card;
92 int hs_actived; 92 int hs_actived;
93 struct pci_dev *pdev = to_pci_dev(dev);
93 94
94 if (pdev) { 95 if (pdev) {
95 card = (struct pcie_service_card *) pci_get_drvdata(pdev); 96 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
@@ -120,10 +121,11 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
120 * If already not resumed, this function turns on the traffic and 121 * If already not resumed, this function turns on the traffic and
121 * sends a host sleep cancel request to the firmware. 122 * sends a host sleep cancel request to the firmware.
122 */ 123 */
123static int mwifiex_pcie_resume(struct pci_dev *pdev) 124static int mwifiex_pcie_resume(struct device *dev)
124{ 125{
125 struct mwifiex_adapter *adapter; 126 struct mwifiex_adapter *adapter;
126 struct pcie_service_card *card; 127 struct pcie_service_card *card;
128 struct pci_dev *pdev = to_pci_dev(dev);
127 129
128 if (pdev) { 130 if (pdev) {
129 card = (struct pcie_service_card *) pci_get_drvdata(pdev); 131 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
@@ -211,9 +213,9 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
211 wait_for_completion(&adapter->fw_load); 213 wait_for_completion(&adapter->fw_load);
212 214
213 if (user_rmmod) { 215 if (user_rmmod) {
214#ifdef CONFIG_PM 216#ifdef CONFIG_PM_SLEEP
215 if (adapter->is_suspended) 217 if (adapter->is_suspended)
216 mwifiex_pcie_resume(pdev); 218 mwifiex_pcie_resume(&pdev->dev);
217#endif 219#endif
218 220
219 for (i = 0; i < adapter->priv_num; i++) 221 for (i = 0; i < adapter->priv_num; i++)
@@ -233,6 +235,14 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
233 kfree(card); 235 kfree(card);
234} 236}
235 237
238static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
239{
240 user_rmmod = 1;
241 mwifiex_pcie_remove(pdev);
242
243 return;
244}
245
236static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = { 246static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
237 { 247 {
238 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P, 248 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
@@ -249,17 +259,24 @@ static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
249 259
250MODULE_DEVICE_TABLE(pci, mwifiex_ids); 260MODULE_DEVICE_TABLE(pci, mwifiex_ids);
251 261
262#ifdef CONFIG_PM_SLEEP
263/* Power Management Hooks */
264static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
265 mwifiex_pcie_resume);
266#endif
267
252/* PCI Device Driver */ 268/* PCI Device Driver */
253static struct pci_driver __refdata mwifiex_pcie = { 269static struct pci_driver __refdata mwifiex_pcie = {
254 .name = "mwifiex_pcie", 270 .name = "mwifiex_pcie",
255 .id_table = mwifiex_ids, 271 .id_table = mwifiex_ids,
256 .probe = mwifiex_pcie_probe, 272 .probe = mwifiex_pcie_probe,
257 .remove = mwifiex_pcie_remove, 273 .remove = mwifiex_pcie_remove,
258#ifdef CONFIG_PM 274#ifdef CONFIG_PM_SLEEP
259 /* Power Management Hooks */ 275 .driver = {
260 .suspend = mwifiex_pcie_suspend, 276 .pm = &mwifiex_pcie_pm_ops,
261 .resume = mwifiex_pcie_resume, 277 },
262#endif 278#endif
279 .shutdown = mwifiex_pcie_shutdown,
263}; 280};
264 281
265/* 282/*
@@ -1925,7 +1942,7 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1925 ret = 0; 1942 ret = 0;
1926 break; 1943 break;
1927 } else { 1944 } else {
1928 mdelay(100); 1945 msleep(100);
1929 ret = -1; 1946 ret = -1;
1930 } 1947 }
1931 } 1948 }
@@ -1937,12 +1954,10 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1937 else if (!winner_status) { 1954 else if (!winner_status) {
1938 dev_err(adapter->dev, "PCI-E is the winner\n"); 1955 dev_err(adapter->dev, "PCI-E is the winner\n");
1939 adapter->winner = 1; 1956 adapter->winner = 1;
1940 ret = -1;
1941 } else { 1957 } else {
1942 dev_err(adapter->dev, 1958 dev_err(adapter->dev,
1943 "PCI-E is not the winner <%#x,%d>, exit dnld\n", 1959 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1944 ret, adapter->winner); 1960 ret, adapter->winner);
1945 ret = 0;
1946 } 1961 }
1947 } 1962 }
1948 1963
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index c447d9bd1aa9..8cf7d50a7603 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -543,6 +543,37 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
543 return chan_idx; 543 return chan_idx;
544} 544}
545 545
546/* This function appends rate TLV to scan config command. */
547static int
548mwifiex_append_rate_tlv(struct mwifiex_private *priv,
549 struct mwifiex_scan_cmd_config *scan_cfg_out,
550 u8 radio)
551{
552 struct mwifiex_ie_types_rates_param_set *rates_tlv;
553 u8 rates[MWIFIEX_SUPPORTED_RATES], *tlv_pos;
554 u32 rates_size;
555
556 memset(rates, 0, sizeof(rates));
557
558 tlv_pos = (u8 *)scan_cfg_out->tlv_buf + scan_cfg_out->tlv_buf_len;
559
560 if (priv->scan_request)
561 rates_size = mwifiex_get_rates_from_cfg80211(priv, rates,
562 radio);
563 else
564 rates_size = mwifiex_get_supported_rates(priv, rates);
565
566 dev_dbg(priv->adapter->dev, "info: SCAN_CMD: Rates size = %d\n",
567 rates_size);
568 rates_tlv = (struct mwifiex_ie_types_rates_param_set *)tlv_pos;
569 rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
570 rates_tlv->header.len = cpu_to_le16((u16) rates_size);
571 memcpy(rates_tlv->rates, rates, rates_size);
572 scan_cfg_out->tlv_buf_len += sizeof(rates_tlv->header) + rates_size;
573
574 return rates_size;
575}
576
546/* 577/*
547 * This function constructs and sends multiple scan config commands to 578 * This function constructs and sends multiple scan config commands to
548 * the firmware. 579 * the firmware.
@@ -564,9 +595,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
564 struct mwifiex_chan_scan_param_set *tmp_chan_list; 595 struct mwifiex_chan_scan_param_set *tmp_chan_list;
565 struct mwifiex_chan_scan_param_set *start_chan; 596 struct mwifiex_chan_scan_param_set *start_chan;
566 597
567 u32 tlv_idx; 598 u32 tlv_idx, rates_size;
568 u32 total_scan_time; 599 u32 total_scan_time;
569 u32 done_early; 600 u32 done_early;
601 u8 radio_type;
570 602
571 if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) { 603 if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) {
572 dev_dbg(priv->adapter->dev, 604 dev_dbg(priv->adapter->dev,
@@ -591,6 +623,7 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
591 623
592 tlv_idx = 0; 624 tlv_idx = 0;
593 total_scan_time = 0; 625 total_scan_time = 0;
626 radio_type = 0;
594 chan_tlv_out->header.len = 0; 627 chan_tlv_out->header.len = 0;
595 start_chan = tmp_chan_list; 628 start_chan = tmp_chan_list;
596 done_early = false; 629 done_early = false;
@@ -612,6 +645,7 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
612 continue; 645 continue;
613 } 646 }
614 647
648 radio_type = tmp_chan_list->radio_type;
615 dev_dbg(priv->adapter->dev, 649 dev_dbg(priv->adapter->dev,
616 "info: Scan: Chan(%3d), Radio(%d)," 650 "info: Scan: Chan(%3d), Radio(%d),"
617 " Mode(%d, %d), Dur(%d)\n", 651 " Mode(%d, %d), Dur(%d)\n",
@@ -692,6 +726,9 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
692 break; 726 break;
693 } 727 }
694 728
729 rates_size = mwifiex_append_rate_tlv(priv, scan_cfg_out,
730 radio_type);
731
695 priv->adapter->scan_channels = start_chan; 732 priv->adapter->scan_channels = start_chan;
696 733
697 /* Send the scan command to the firmware with the specified 734 /* Send the scan command to the firmware with the specified
@@ -699,6 +736,14 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
699 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN, 736 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN,
700 HostCmd_ACT_GEN_SET, 0, 737 HostCmd_ACT_GEN_SET, 0,
701 scan_cfg_out); 738 scan_cfg_out);
739
740 /* rate IE is updated per scan command but same starting
741 * pointer is used each time so that rate IE from earlier
742 * scan_cfg_out->buf is overwritten with new one.
743 */
744 scan_cfg_out->tlv_buf_len -=
745 sizeof(struct mwifiex_ie_types_header) + rates_size;
746
702 if (ret) 747 if (ret)
703 break; 748 break;
704 } 749 }
@@ -741,7 +786,6 @@ mwifiex_config_scan(struct mwifiex_private *priv,
741 struct mwifiex_adapter *adapter = priv->adapter; 786 struct mwifiex_adapter *adapter = priv->adapter;
742 struct mwifiex_ie_types_num_probes *num_probes_tlv; 787 struct mwifiex_ie_types_num_probes *num_probes_tlv;
743 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv; 788 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
744 struct mwifiex_ie_types_rates_param_set *rates_tlv;
745 u8 *tlv_pos; 789 u8 *tlv_pos;
746 u32 num_probes; 790 u32 num_probes;
747 u32 ssid_len; 791 u32 ssid_len;
@@ -753,8 +797,6 @@ mwifiex_config_scan(struct mwifiex_private *priv,
753 u8 radio_type; 797 u8 radio_type;
754 int i; 798 int i;
755 u8 ssid_filter; 799 u8 ssid_filter;
756 u8 rates[MWIFIEX_SUPPORTED_RATES];
757 u32 rates_size;
758 struct mwifiex_ie_types_htcap *ht_cap; 800 struct mwifiex_ie_types_htcap *ht_cap;
759 801
760 /* The tlv_buf_len is calculated for each scan command. The TLVs added 802 /* The tlv_buf_len is calculated for each scan command. The TLVs added
@@ -889,19 +931,6 @@ mwifiex_config_scan(struct mwifiex_private *priv,
889 931
890 } 932 }
891 933
892 /* Append rates tlv */
893 memset(rates, 0, sizeof(rates));
894
895 rates_size = mwifiex_get_supported_rates(priv, rates);
896
897 rates_tlv = (struct mwifiex_ie_types_rates_param_set *) tlv_pos;
898 rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
899 rates_tlv->header.len = cpu_to_le16((u16) rates_size);
900 memcpy(rates_tlv->rates, rates, rates_size);
901 tlv_pos += sizeof(rates_tlv->header) + rates_size;
902
903 dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size);
904
905 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && 934 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
906 (priv->adapter->config_bands & BAND_GN || 935 (priv->adapter->config_bands & BAND_GN ||
907 priv->adapter->config_bands & BAND_AN)) { 936 priv->adapter->config_bands & BAND_AN)) {
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 09185c963248..0e2070f72fed 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -50,9 +50,6 @@ static struct mwifiex_if_ops sdio_ops;
50 50
51static struct semaphore add_remove_card_sem; 51static struct semaphore add_remove_card_sem;
52 52
53static int mwifiex_sdio_resume(struct device *dev);
54static void mwifiex_sdio_interrupt(struct sdio_func *func);
55
56/* 53/*
57 * SDIO probe. 54 * SDIO probe.
58 * 55 *
@@ -113,6 +110,51 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
113} 110}
114 111
115/* 112/*
113 * SDIO resume.
114 *
115 * Kernel needs to suspend all functions separately. Therefore all
116 * registered functions must have drivers with suspend and resume
117 * methods. Failing that the kernel simply removes the whole card.
118 *
119 * If already not resumed, this function turns on the traffic and
120 * sends a host sleep cancel request to the firmware.
121 */
122static int mwifiex_sdio_resume(struct device *dev)
123{
124 struct sdio_func *func = dev_to_sdio_func(dev);
125 struct sdio_mmc_card *card;
126 struct mwifiex_adapter *adapter;
127 mmc_pm_flag_t pm_flag = 0;
128
129 if (func) {
130 pm_flag = sdio_get_host_pm_caps(func);
131 card = sdio_get_drvdata(func);
132 if (!card || !card->adapter) {
133 pr_err("resume: invalid card or adapter\n");
134 return 0;
135 }
136 } else {
137 pr_err("resume: sdio_func is not specified\n");
138 return 0;
139 }
140
141 adapter = card->adapter;
142
143 if (!adapter->is_suspended) {
144 dev_warn(adapter->dev, "device already resumed\n");
145 return 0;
146 }
147
148 adapter->is_suspended = false;
149
150 /* Disable Host Sleep */
151 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
152 MWIFIEX_ASYNC_CMD);
153
154 return 0;
155}
156
157/*
116 * SDIO remove. 158 * SDIO remove.
117 * 159 *
118 * This function removes the interface and frees up the card structure. 160 * This function removes the interface and frees up the card structure.
@@ -212,51 +254,6 @@ static int mwifiex_sdio_suspend(struct device *dev)
212 return ret; 254 return ret;
213} 255}
214 256
215/*
216 * SDIO resume.
217 *
218 * Kernel needs to suspend all functions separately. Therefore all
219 * registered functions must have drivers with suspend and resume
220 * methods. Failing that the kernel simply removes the whole card.
221 *
222 * If already not resumed, this function turns on the traffic and
223 * sends a host sleep cancel request to the firmware.
224 */
225static int mwifiex_sdio_resume(struct device *dev)
226{
227 struct sdio_func *func = dev_to_sdio_func(dev);
228 struct sdio_mmc_card *card;
229 struct mwifiex_adapter *adapter;
230 mmc_pm_flag_t pm_flag = 0;
231
232 if (func) {
233 pm_flag = sdio_get_host_pm_caps(func);
234 card = sdio_get_drvdata(func);
235 if (!card || !card->adapter) {
236 pr_err("resume: invalid card or adapter\n");
237 return 0;
238 }
239 } else {
240 pr_err("resume: sdio_func is not specified\n");
241 return 0;
242 }
243
244 adapter = card->adapter;
245
246 if (!adapter->is_suspended) {
247 dev_warn(adapter->dev, "device already resumed\n");
248 return 0;
249 }
250
251 adapter->is_suspended = false;
252
253 /* Disable Host Sleep */
254 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
255 MWIFIEX_ASYNC_CMD);
256
257 return 0;
258}
259
260/* Device ID for SD8786 */ 257/* Device ID for SD8786 */
261#define SDIO_DEVICE_ID_MARVELL_8786 (0x9116) 258#define SDIO_DEVICE_ID_MARVELL_8786 (0x9116)
262/* Device ID for SD8787 */ 259/* Device ID for SD8787 */
@@ -707,6 +704,65 @@ static void mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
707} 704}
708 705
709/* 706/*
707 * This function reads the interrupt status from card.
708 */
709static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
710{
711 struct sdio_mmc_card *card = adapter->card;
712 u8 sdio_ireg;
713 unsigned long flags;
714
715 if (mwifiex_read_data_sync(adapter, card->mp_regs,
716 card->reg->max_mp_regs,
717 REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
718 dev_err(adapter->dev, "read mp_regs failed\n");
719 return;
720 }
721
722 sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
723 if (sdio_ireg) {
724 /*
725 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
726 * For SDIO new mode CMD port interrupts
727 * DN_LD_CMD_PORT_HOST_INT_STATUS and/or
728 * UP_LD_CMD_PORT_HOST_INT_STATUS
729 * Clear the interrupt status register
730 */
731 dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
732 spin_lock_irqsave(&adapter->int_lock, flags);
733 adapter->int_status |= sdio_ireg;
734 spin_unlock_irqrestore(&adapter->int_lock, flags);
735 }
736}
737
738/*
739 * SDIO interrupt handler.
740 *
741 * This function reads the interrupt status from firmware and handles
742 * the interrupt in current thread (ksdioirqd) right away.
743 */
744static void
745mwifiex_sdio_interrupt(struct sdio_func *func)
746{
747 struct mwifiex_adapter *adapter;
748 struct sdio_mmc_card *card;
749
750 card = sdio_get_drvdata(func);
751 if (!card || !card->adapter) {
752 pr_debug("int: func=%p card=%p adapter=%p\n",
753 func, card, card ? card->adapter : NULL);
754 return;
755 }
756 adapter = card->adapter;
757
758 if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
759 adapter->ps_state = PS_STATE_AWAKE;
760
761 mwifiex_interrupt_status(adapter);
762 mwifiex_main_process(adapter);
763}
764
765/*
710 * This function enables the host interrupt. 766 * This function enables the host interrupt.
711 * 767 *
712 * The host interrupt enable mask is written to the card 768 * The host interrupt enable mask is written to the card
@@ -944,7 +1000,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
944 ret = 0; 1000 ret = 0;
945 break; 1001 break;
946 } else { 1002 } else {
947 mdelay(100); 1003 msleep(100);
948 ret = -1; 1004 ret = -1;
949 } 1005 }
950 } 1006 }
@@ -963,65 +1019,6 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
963} 1019}
964 1020
965/* 1021/*
966 * This function reads the interrupt status from card.
967 */
968static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
969{
970 struct sdio_mmc_card *card = adapter->card;
971 u8 sdio_ireg;
972 unsigned long flags;
973
974 if (mwifiex_read_data_sync(adapter, card->mp_regs,
975 card->reg->max_mp_regs,
976 REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
977 dev_err(adapter->dev, "read mp_regs failed\n");
978 return;
979 }
980
981 sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
982 if (sdio_ireg) {
983 /*
984 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
985 * For SDIO new mode CMD port interrupts
986 * DN_LD_CMD_PORT_HOST_INT_STATUS and/or
987 * UP_LD_CMD_PORT_HOST_INT_STATUS
988 * Clear the interrupt status register
989 */
990 dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
991 spin_lock_irqsave(&adapter->int_lock, flags);
992 adapter->int_status |= sdio_ireg;
993 spin_unlock_irqrestore(&adapter->int_lock, flags);
994 }
995}
996
997/*
998 * SDIO interrupt handler.
999 *
1000 * This function reads the interrupt status from firmware and handles
1001 * the interrupt in current thread (ksdioirqd) right away.
1002 */
1003static void
1004mwifiex_sdio_interrupt(struct sdio_func *func)
1005{
1006 struct mwifiex_adapter *adapter;
1007 struct sdio_mmc_card *card;
1008
1009 card = sdio_get_drvdata(func);
1010 if (!card || !card->adapter) {
1011 pr_debug("int: func=%p card=%p adapter=%p\n",
1012 func, card, card ? card->adapter : NULL);
1013 return;
1014 }
1015 adapter = card->adapter;
1016
1017 if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
1018 adapter->ps_state = PS_STATE_AWAKE;
1019
1020 mwifiex_interrupt_status(adapter);
1021 mwifiex_main_process(adapter);
1022}
1023
1024/*
1025 * This function decodes a received packet. 1022 * This function decodes a received packet.
1026 * 1023 *
1027 * Based on the type, the packet is treated as either a data, or 1024 * Based on the type, the packet is treated as either a data, or
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 8ece48580642..9b75ed8563b6 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -707,8 +707,9 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
707 if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) { 707 if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
708 tlv_mac = (void *)((u8 *)&key_material->key_param_set + 708 tlv_mac = (void *)((u8 *)&key_material->key_param_set +
709 key_param_len); 709 key_param_len);
710 tlv_mac->tlv.type = cpu_to_le16(TLV_TYPE_STA_MAC_ADDR); 710 tlv_mac->header.type =
711 tlv_mac->tlv.len = cpu_to_le16(ETH_ALEN); 711 cpu_to_le16(TLV_TYPE_STA_MAC_ADDR);
712 tlv_mac->header.len = cpu_to_le16(ETH_ALEN);
712 memcpy(tlv_mac->mac_addr, enc_key->mac_addr, ETH_ALEN); 713 memcpy(tlv_mac->mac_addr, enc_key->mac_addr, ETH_ALEN);
713 cmd_size = key_param_len + S_DS_GEN + 714 cmd_size = key_param_len + S_DS_GEN +
714 sizeof(key_material->action) + 715 sizeof(key_material->action) +
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index ea265ec0e522..8b057524b252 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -201,6 +201,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
201 201
202 case EVENT_DEAUTHENTICATED: 202 case EVENT_DEAUTHENTICATED:
203 dev_dbg(adapter->dev, "event: Deauthenticated\n"); 203 dev_dbg(adapter->dev, "event: Deauthenticated\n");
204 if (priv->wps.session_enable) {
205 dev_dbg(adapter->dev,
206 "info: receive deauth event in wps session\n");
207 break;
208 }
204 adapter->dbg.num_event_deauth++; 209 adapter->dbg.num_event_deauth++;
205 if (priv->media_connected) { 210 if (priv->media_connected) {
206 reason_code = 211 reason_code =
@@ -211,6 +216,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
211 216
212 case EVENT_DISASSOCIATED: 217 case EVENT_DISASSOCIATED:
213 dev_dbg(adapter->dev, "event: Disassociated\n"); 218 dev_dbg(adapter->dev, "event: Disassociated\n");
219 if (priv->wps.session_enable) {
220 dev_dbg(adapter->dev,
221 "info: receive disassoc event in wps session\n");
222 break;
223 }
214 adapter->dbg.num_event_disassoc++; 224 adapter->dbg.num_event_disassoc++;
215 if (priv->media_connected) { 225 if (priv->media_connected) {
216 reason_code = 226 reason_code =
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 8af97abf7108..f084412eee0b 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -797,15 +797,16 @@ static int mwifiex_set_wps_ie(struct mwifiex_private *priv,
797 u8 *ie_data_ptr, u16 ie_len) 797 u8 *ie_data_ptr, u16 ie_len)
798{ 798{
799 if (ie_len) { 799 if (ie_len) {
800 priv->wps_ie = kzalloc(MWIFIEX_MAX_VSIE_LEN, GFP_KERNEL); 800 if (ie_len > MWIFIEX_MAX_VSIE_LEN) {
801 if (!priv->wps_ie)
802 return -ENOMEM;
803 if (ie_len > sizeof(priv->wps_ie)) {
804 dev_dbg(priv->adapter->dev, 801 dev_dbg(priv->adapter->dev,
805 "info: failed to copy WPS IE, too big\n"); 802 "info: failed to copy WPS IE, too big\n");
806 kfree(priv->wps_ie);
807 return -1; 803 return -1;
808 } 804 }
805
806 priv->wps_ie = kzalloc(MWIFIEX_MAX_VSIE_LEN, GFP_KERNEL);
807 if (!priv->wps_ie)
808 return -ENOMEM;
809
809 memcpy(priv->wps_ie, ie_data_ptr, ie_len); 810 memcpy(priv->wps_ie, ie_data_ptr, ie_len);
810 priv->wps_ie_len = ie_len; 811 priv->wps_ie_len = ie_len;
811 dev_dbg(priv->adapter->dev, "cmd: Set wps_ie_len=%d IE=%#x\n", 812 dev_dbg(priv->adapter->dev, "cmd: Set wps_ie_len=%d IE=%#x\n",
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 2de882dead0f..64424c81b44f 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -293,9 +293,9 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
293 u8 *tlv = *tlv_buf; 293 u8 *tlv = *tlv_buf;
294 294
295 tlv_akmp = (struct host_cmd_tlv_akmp *)tlv; 295 tlv_akmp = (struct host_cmd_tlv_akmp *)tlv;
296 tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP); 296 tlv_akmp->header.type = cpu_to_le16(TLV_TYPE_UAP_AKMP);
297 tlv_akmp->tlv.len = cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) - 297 tlv_akmp->header.len = cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) -
298 sizeof(struct host_cmd_tlv)); 298 sizeof(struct mwifiex_ie_types_header));
299 tlv_akmp->key_mgmt_operation = cpu_to_le16(bss_cfg->key_mgmt_operation); 299 tlv_akmp->key_mgmt_operation = cpu_to_le16(bss_cfg->key_mgmt_operation);
300 tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt); 300 tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt);
301 cmd_size += sizeof(struct host_cmd_tlv_akmp); 301 cmd_size += sizeof(struct host_cmd_tlv_akmp);
@@ -303,10 +303,10 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
303 303
304 if (bss_cfg->wpa_cfg.pairwise_cipher_wpa & VALID_CIPHER_BITMAP) { 304 if (bss_cfg->wpa_cfg.pairwise_cipher_wpa & VALID_CIPHER_BITMAP) {
305 pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; 305 pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
306 pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER); 306 pwk_cipher->header.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
307 pwk_cipher->tlv.len = 307 pwk_cipher->header.len =
308 cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) - 308 cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) -
309 sizeof(struct host_cmd_tlv)); 309 sizeof(struct mwifiex_ie_types_header));
310 pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA); 310 pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA);
311 pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa; 311 pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa;
312 cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); 312 cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
@@ -315,10 +315,10 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
315 315
316 if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 & VALID_CIPHER_BITMAP) { 316 if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 & VALID_CIPHER_BITMAP) {
317 pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; 317 pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
318 pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER); 318 pwk_cipher->header.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
319 pwk_cipher->tlv.len = 319 pwk_cipher->header.len =
320 cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) - 320 cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) -
321 sizeof(struct host_cmd_tlv)); 321 sizeof(struct mwifiex_ie_types_header));
322 pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2); 322 pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2);
323 pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa2; 323 pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa2;
324 cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); 324 cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
@@ -327,10 +327,10 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
327 327
328 if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) { 328 if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) {
329 gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv; 329 gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv;
330 gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER); 330 gwk_cipher->header.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER);
331 gwk_cipher->tlv.len = 331 gwk_cipher->header.len =
332 cpu_to_le16(sizeof(struct host_cmd_tlv_gwk_cipher) - 332 cpu_to_le16(sizeof(struct host_cmd_tlv_gwk_cipher) -
333 sizeof(struct host_cmd_tlv)); 333 sizeof(struct mwifiex_ie_types_header));
334 gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher; 334 gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher;
335 cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher); 335 cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher);
336 tlv += sizeof(struct host_cmd_tlv_gwk_cipher); 336 tlv += sizeof(struct host_cmd_tlv_gwk_cipher);
@@ -338,13 +338,15 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
338 338
339 if (bss_cfg->wpa_cfg.length) { 339 if (bss_cfg->wpa_cfg.length) {
340 passphrase = (struct host_cmd_tlv_passphrase *)tlv; 340 passphrase = (struct host_cmd_tlv_passphrase *)tlv;
341 passphrase->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE); 341 passphrase->header.type =
342 passphrase->tlv.len = cpu_to_le16(bss_cfg->wpa_cfg.length); 342 cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE);
343 passphrase->header.len = cpu_to_le16(bss_cfg->wpa_cfg.length);
343 memcpy(passphrase->passphrase, bss_cfg->wpa_cfg.passphrase, 344 memcpy(passphrase->passphrase, bss_cfg->wpa_cfg.passphrase,
344 bss_cfg->wpa_cfg.length); 345 bss_cfg->wpa_cfg.length);
345 cmd_size += sizeof(struct host_cmd_tlv) + 346 cmd_size += sizeof(struct mwifiex_ie_types_header) +
346 bss_cfg->wpa_cfg.length; 347 bss_cfg->wpa_cfg.length;
347 tlv += sizeof(struct host_cmd_tlv) + bss_cfg->wpa_cfg.length; 348 tlv += sizeof(struct mwifiex_ie_types_header) +
349 bss_cfg->wpa_cfg.length;
348 } 350 }
349 351
350 *param_size = cmd_size; 352 *param_size = cmd_size;
@@ -403,16 +405,17 @@ mwifiex_uap_bss_wep(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
403 (bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP40 || 405 (bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP40 ||
404 bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP104)) { 406 bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP104)) {
405 wep_key = (struct host_cmd_tlv_wep_key *)tlv; 407 wep_key = (struct host_cmd_tlv_wep_key *)tlv;
406 wep_key->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WEP_KEY); 408 wep_key->header.type =
407 wep_key->tlv.len = 409 cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
410 wep_key->header.len =
408 cpu_to_le16(bss_cfg->wep_cfg[i].length + 2); 411 cpu_to_le16(bss_cfg->wep_cfg[i].length + 2);
409 wep_key->key_index = bss_cfg->wep_cfg[i].key_index; 412 wep_key->key_index = bss_cfg->wep_cfg[i].key_index;
410 wep_key->is_default = bss_cfg->wep_cfg[i].is_default; 413 wep_key->is_default = bss_cfg->wep_cfg[i].is_default;
411 memcpy(wep_key->key, bss_cfg->wep_cfg[i].key, 414 memcpy(wep_key->key, bss_cfg->wep_cfg[i].key,
412 bss_cfg->wep_cfg[i].length); 415 bss_cfg->wep_cfg[i].length);
413 cmd_size += sizeof(struct host_cmd_tlv) + 2 + 416 cmd_size += sizeof(struct mwifiex_ie_types_header) + 2 +
414 bss_cfg->wep_cfg[i].length; 417 bss_cfg->wep_cfg[i].length;
415 tlv += sizeof(struct host_cmd_tlv) + 2 + 418 tlv += sizeof(struct mwifiex_ie_types_header) + 2 +
416 bss_cfg->wep_cfg[i].length; 419 bss_cfg->wep_cfg[i].length;
417 } 420 }
418 } 421 }
@@ -449,16 +452,17 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
449 452
450 if (bss_cfg->ssid.ssid_len) { 453 if (bss_cfg->ssid.ssid_len) {
451 ssid = (struct host_cmd_tlv_ssid *)tlv; 454 ssid = (struct host_cmd_tlv_ssid *)tlv;
452 ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_SSID); 455 ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_SSID);
453 ssid->tlv.len = cpu_to_le16((u16)bss_cfg->ssid.ssid_len); 456 ssid->header.len = cpu_to_le16((u16)bss_cfg->ssid.ssid_len);
454 memcpy(ssid->ssid, bss_cfg->ssid.ssid, bss_cfg->ssid.ssid_len); 457 memcpy(ssid->ssid, bss_cfg->ssid.ssid, bss_cfg->ssid.ssid_len);
455 cmd_size += sizeof(struct host_cmd_tlv) + 458 cmd_size += sizeof(struct mwifiex_ie_types_header) +
456 bss_cfg->ssid.ssid_len; 459 bss_cfg->ssid.ssid_len;
457 tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len; 460 tlv += sizeof(struct mwifiex_ie_types_header) +
461 bss_cfg->ssid.ssid_len;
458 462
459 bcast_ssid = (struct host_cmd_tlv_bcast_ssid *)tlv; 463 bcast_ssid = (struct host_cmd_tlv_bcast_ssid *)tlv;
460 bcast_ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID); 464 bcast_ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID);
461 bcast_ssid->tlv.len = 465 bcast_ssid->header.len =
462 cpu_to_le16(sizeof(bcast_ssid->bcast_ctl)); 466 cpu_to_le16(sizeof(bcast_ssid->bcast_ctl));
463 bcast_ssid->bcast_ctl = bss_cfg->bcast_ssid_ctl; 467 bcast_ssid->bcast_ctl = bss_cfg->bcast_ssid_ctl;
464 cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid); 468 cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid);
@@ -466,13 +470,13 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
466 } 470 }
467 if (bss_cfg->rates[0]) { 471 if (bss_cfg->rates[0]) {
468 tlv_rates = (struct host_cmd_tlv_rates *)tlv; 472 tlv_rates = (struct host_cmd_tlv_rates *)tlv;
469 tlv_rates->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RATES); 473 tlv_rates->header.type = cpu_to_le16(TLV_TYPE_UAP_RATES);
470 474
471 for (i = 0; i < MWIFIEX_SUPPORTED_RATES && bss_cfg->rates[i]; 475 for (i = 0; i < MWIFIEX_SUPPORTED_RATES && bss_cfg->rates[i];
472 i++) 476 i++)
473 tlv_rates->rates[i] = bss_cfg->rates[i]; 477 tlv_rates->rates[i] = bss_cfg->rates[i];
474 478
475 tlv_rates->tlv.len = cpu_to_le16(i); 479 tlv_rates->header.len = cpu_to_le16(i);
476 cmd_size += sizeof(struct host_cmd_tlv_rates) + i; 480 cmd_size += sizeof(struct host_cmd_tlv_rates) + i;
477 tlv += sizeof(struct host_cmd_tlv_rates) + i; 481 tlv += sizeof(struct host_cmd_tlv_rates) + i;
478 } 482 }
@@ -482,10 +486,10 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
482 (bss_cfg->band_cfg == BAND_CONFIG_A && 486 (bss_cfg->band_cfg == BAND_CONFIG_A &&
483 bss_cfg->channel <= MAX_CHANNEL_BAND_A))) { 487 bss_cfg->channel <= MAX_CHANNEL_BAND_A))) {
484 chan_band = (struct host_cmd_tlv_channel_band *)tlv; 488 chan_band = (struct host_cmd_tlv_channel_band *)tlv;
485 chan_band->tlv.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST); 489 chan_band->header.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
486 chan_band->tlv.len = 490 chan_band->header.len =
487 cpu_to_le16(sizeof(struct host_cmd_tlv_channel_band) - 491 cpu_to_le16(sizeof(struct host_cmd_tlv_channel_band) -
488 sizeof(struct host_cmd_tlv)); 492 sizeof(struct mwifiex_ie_types_header));
489 chan_band->band_config = bss_cfg->band_cfg; 493 chan_band->band_config = bss_cfg->band_cfg;
490 chan_band->channel = bss_cfg->channel; 494 chan_band->channel = bss_cfg->channel;
491 cmd_size += sizeof(struct host_cmd_tlv_channel_band); 495 cmd_size += sizeof(struct host_cmd_tlv_channel_band);
@@ -494,11 +498,11 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
494 if (bss_cfg->beacon_period >= MIN_BEACON_PERIOD && 498 if (bss_cfg->beacon_period >= MIN_BEACON_PERIOD &&
495 bss_cfg->beacon_period <= MAX_BEACON_PERIOD) { 499 bss_cfg->beacon_period <= MAX_BEACON_PERIOD) {
496 beacon_period = (struct host_cmd_tlv_beacon_period *)tlv; 500 beacon_period = (struct host_cmd_tlv_beacon_period *)tlv;
497 beacon_period->tlv.type = 501 beacon_period->header.type =
498 cpu_to_le16(TLV_TYPE_UAP_BEACON_PERIOD); 502 cpu_to_le16(TLV_TYPE_UAP_BEACON_PERIOD);
499 beacon_period->tlv.len = 503 beacon_period->header.len =
500 cpu_to_le16(sizeof(struct host_cmd_tlv_beacon_period) - 504 cpu_to_le16(sizeof(struct host_cmd_tlv_beacon_period) -
501 sizeof(struct host_cmd_tlv)); 505 sizeof(struct mwifiex_ie_types_header));
502 beacon_period->period = cpu_to_le16(bss_cfg->beacon_period); 506 beacon_period->period = cpu_to_le16(bss_cfg->beacon_period);
503 cmd_size += sizeof(struct host_cmd_tlv_beacon_period); 507 cmd_size += sizeof(struct host_cmd_tlv_beacon_period);
504 tlv += sizeof(struct host_cmd_tlv_beacon_period); 508 tlv += sizeof(struct host_cmd_tlv_beacon_period);
@@ -506,21 +510,22 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
506 if (bss_cfg->dtim_period >= MIN_DTIM_PERIOD && 510 if (bss_cfg->dtim_period >= MIN_DTIM_PERIOD &&
507 bss_cfg->dtim_period <= MAX_DTIM_PERIOD) { 511 bss_cfg->dtim_period <= MAX_DTIM_PERIOD) {
508 dtim_period = (struct host_cmd_tlv_dtim_period *)tlv; 512 dtim_period = (struct host_cmd_tlv_dtim_period *)tlv;
509 dtim_period->tlv.type = cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD); 513 dtim_period->header.type =
510 dtim_period->tlv.len = 514 cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD);
515 dtim_period->header.len =
511 cpu_to_le16(sizeof(struct host_cmd_tlv_dtim_period) - 516 cpu_to_le16(sizeof(struct host_cmd_tlv_dtim_period) -
512 sizeof(struct host_cmd_tlv)); 517 sizeof(struct mwifiex_ie_types_header));
513 dtim_period->period = bss_cfg->dtim_period; 518 dtim_period->period = bss_cfg->dtim_period;
514 cmd_size += sizeof(struct host_cmd_tlv_dtim_period); 519 cmd_size += sizeof(struct host_cmd_tlv_dtim_period);
515 tlv += sizeof(struct host_cmd_tlv_dtim_period); 520 tlv += sizeof(struct host_cmd_tlv_dtim_period);
516 } 521 }
517 if (bss_cfg->rts_threshold <= MWIFIEX_RTS_MAX_VALUE) { 522 if (bss_cfg->rts_threshold <= MWIFIEX_RTS_MAX_VALUE) {
518 rts_threshold = (struct host_cmd_tlv_rts_threshold *)tlv; 523 rts_threshold = (struct host_cmd_tlv_rts_threshold *)tlv;
519 rts_threshold->tlv.type = 524 rts_threshold->header.type =
520 cpu_to_le16(TLV_TYPE_UAP_RTS_THRESHOLD); 525 cpu_to_le16(TLV_TYPE_UAP_RTS_THRESHOLD);
521 rts_threshold->tlv.len = 526 rts_threshold->header.len =
522 cpu_to_le16(sizeof(struct host_cmd_tlv_rts_threshold) - 527 cpu_to_le16(sizeof(struct host_cmd_tlv_rts_threshold) -
523 sizeof(struct host_cmd_tlv)); 528 sizeof(struct mwifiex_ie_types_header));
524 rts_threshold->rts_thr = cpu_to_le16(bss_cfg->rts_threshold); 529 rts_threshold->rts_thr = cpu_to_le16(bss_cfg->rts_threshold);
525 cmd_size += sizeof(struct host_cmd_tlv_frag_threshold); 530 cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
526 tlv += sizeof(struct host_cmd_tlv_frag_threshold); 531 tlv += sizeof(struct host_cmd_tlv_frag_threshold);
@@ -528,21 +533,22 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
528 if ((bss_cfg->frag_threshold >= MWIFIEX_FRAG_MIN_VALUE) && 533 if ((bss_cfg->frag_threshold >= MWIFIEX_FRAG_MIN_VALUE) &&
529 (bss_cfg->frag_threshold <= MWIFIEX_FRAG_MAX_VALUE)) { 534 (bss_cfg->frag_threshold <= MWIFIEX_FRAG_MAX_VALUE)) {
530 frag_threshold = (struct host_cmd_tlv_frag_threshold *)tlv; 535 frag_threshold = (struct host_cmd_tlv_frag_threshold *)tlv;
531 frag_threshold->tlv.type = 536 frag_threshold->header.type =
532 cpu_to_le16(TLV_TYPE_UAP_FRAG_THRESHOLD); 537 cpu_to_le16(TLV_TYPE_UAP_FRAG_THRESHOLD);
533 frag_threshold->tlv.len = 538 frag_threshold->header.len =
534 cpu_to_le16(sizeof(struct host_cmd_tlv_frag_threshold) - 539 cpu_to_le16(sizeof(struct host_cmd_tlv_frag_threshold) -
535 sizeof(struct host_cmd_tlv)); 540 sizeof(struct mwifiex_ie_types_header));
536 frag_threshold->frag_thr = cpu_to_le16(bss_cfg->frag_threshold); 541 frag_threshold->frag_thr = cpu_to_le16(bss_cfg->frag_threshold);
537 cmd_size += sizeof(struct host_cmd_tlv_frag_threshold); 542 cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
538 tlv += sizeof(struct host_cmd_tlv_frag_threshold); 543 tlv += sizeof(struct host_cmd_tlv_frag_threshold);
539 } 544 }
540 if (bss_cfg->retry_limit <= MWIFIEX_RETRY_LIMIT) { 545 if (bss_cfg->retry_limit <= MWIFIEX_RETRY_LIMIT) {
541 retry_limit = (struct host_cmd_tlv_retry_limit *)tlv; 546 retry_limit = (struct host_cmd_tlv_retry_limit *)tlv;
542 retry_limit->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT); 547 retry_limit->header.type =
543 retry_limit->tlv.len = 548 cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT);
549 retry_limit->header.len =
544 cpu_to_le16(sizeof(struct host_cmd_tlv_retry_limit) - 550 cpu_to_le16(sizeof(struct host_cmd_tlv_retry_limit) -
545 sizeof(struct host_cmd_tlv)); 551 sizeof(struct mwifiex_ie_types_header));
546 retry_limit->limit = (u8)bss_cfg->retry_limit; 552 retry_limit->limit = (u8)bss_cfg->retry_limit;
547 cmd_size += sizeof(struct host_cmd_tlv_retry_limit); 553 cmd_size += sizeof(struct host_cmd_tlv_retry_limit);
548 tlv += sizeof(struct host_cmd_tlv_retry_limit); 554 tlv += sizeof(struct host_cmd_tlv_retry_limit);
@@ -557,21 +563,21 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
557 if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) || 563 if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) ||
558 (bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) { 564 (bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) {
559 auth_type = (struct host_cmd_tlv_auth_type *)tlv; 565 auth_type = (struct host_cmd_tlv_auth_type *)tlv;
560 auth_type->tlv.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); 566 auth_type->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
561 auth_type->tlv.len = 567 auth_type->header.len =
562 cpu_to_le16(sizeof(struct host_cmd_tlv_auth_type) - 568 cpu_to_le16(sizeof(struct host_cmd_tlv_auth_type) -
563 sizeof(struct host_cmd_tlv)); 569 sizeof(struct mwifiex_ie_types_header));
564 auth_type->auth_type = (u8)bss_cfg->auth_mode; 570 auth_type->auth_type = (u8)bss_cfg->auth_mode;
565 cmd_size += sizeof(struct host_cmd_tlv_auth_type); 571 cmd_size += sizeof(struct host_cmd_tlv_auth_type);
566 tlv += sizeof(struct host_cmd_tlv_auth_type); 572 tlv += sizeof(struct host_cmd_tlv_auth_type);
567 } 573 }
568 if (bss_cfg->protocol) { 574 if (bss_cfg->protocol) {
569 encrypt_protocol = (struct host_cmd_tlv_encrypt_protocol *)tlv; 575 encrypt_protocol = (struct host_cmd_tlv_encrypt_protocol *)tlv;
570 encrypt_protocol->tlv.type = 576 encrypt_protocol->header.type =
571 cpu_to_le16(TLV_TYPE_UAP_ENCRY_PROTOCOL); 577 cpu_to_le16(TLV_TYPE_UAP_ENCRY_PROTOCOL);
572 encrypt_protocol->tlv.len = 578 encrypt_protocol->header.len =
573 cpu_to_le16(sizeof(struct host_cmd_tlv_encrypt_protocol) 579 cpu_to_le16(sizeof(struct host_cmd_tlv_encrypt_protocol)
574 - sizeof(struct host_cmd_tlv)); 580 - sizeof(struct mwifiex_ie_types_header));
575 encrypt_protocol->proto = cpu_to_le16(bss_cfg->protocol); 581 encrypt_protocol->proto = cpu_to_le16(bss_cfg->protocol);
576 cmd_size += sizeof(struct host_cmd_tlv_encrypt_protocol); 582 cmd_size += sizeof(struct host_cmd_tlv_encrypt_protocol);
577 tlv += sizeof(struct host_cmd_tlv_encrypt_protocol); 583 tlv += sizeof(struct host_cmd_tlv_encrypt_protocol);
@@ -608,9 +614,9 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
608 614
609 if (bss_cfg->sta_ao_timer) { 615 if (bss_cfg->sta_ao_timer) {
610 ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv; 616 ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
611 ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER); 617 ao_timer->header.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER);
612 ao_timer->tlv.len = cpu_to_le16(sizeof(*ao_timer) - 618 ao_timer->header.len = cpu_to_le16(sizeof(*ao_timer) -
613 sizeof(struct host_cmd_tlv)); 619 sizeof(struct mwifiex_ie_types_header));
614 ao_timer->sta_ao_timer = cpu_to_le32(bss_cfg->sta_ao_timer); 620 ao_timer->sta_ao_timer = cpu_to_le32(bss_cfg->sta_ao_timer);
615 cmd_size += sizeof(*ao_timer); 621 cmd_size += sizeof(*ao_timer);
616 tlv += sizeof(*ao_timer); 622 tlv += sizeof(*ao_timer);
@@ -618,9 +624,10 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
618 624
619 if (bss_cfg->ps_sta_ao_timer) { 625 if (bss_cfg->ps_sta_ao_timer) {
620 ps_ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv; 626 ps_ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
621 ps_ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_PS_AO_TIMER); 627 ps_ao_timer->header.type =
622 ps_ao_timer->tlv.len = cpu_to_le16(sizeof(*ps_ao_timer) - 628 cpu_to_le16(TLV_TYPE_UAP_PS_AO_TIMER);
623 sizeof(struct host_cmd_tlv)); 629 ps_ao_timer->header.len = cpu_to_le16(sizeof(*ps_ao_timer) -
630 sizeof(struct mwifiex_ie_types_header));
624 ps_ao_timer->sta_ao_timer = 631 ps_ao_timer->sta_ao_timer =
625 cpu_to_le32(bss_cfg->ps_sta_ao_timer); 632 cpu_to_le32(bss_cfg->ps_sta_ao_timer);
626 cmd_size += sizeof(*ps_ao_timer); 633 cmd_size += sizeof(*ps_ao_timer);
@@ -636,16 +643,17 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
636static int mwifiex_uap_custom_ie_prepare(u8 *tlv, void *cmd_buf, u16 *ie_size) 643static int mwifiex_uap_custom_ie_prepare(u8 *tlv, void *cmd_buf, u16 *ie_size)
637{ 644{
638 struct mwifiex_ie_list *ap_ie = cmd_buf; 645 struct mwifiex_ie_list *ap_ie = cmd_buf;
639 struct host_cmd_tlv *tlv_ie = (struct host_cmd_tlv *)tlv; 646 struct mwifiex_ie_types_header *tlv_ie = (void *)tlv;
640 647
641 if (!ap_ie || !ap_ie->len || !ap_ie->ie_list) 648 if (!ap_ie || !ap_ie->len || !ap_ie->ie_list)
642 return -1; 649 return -1;
643 650
644 *ie_size += le16_to_cpu(ap_ie->len) + sizeof(struct host_cmd_tlv); 651 *ie_size += le16_to_cpu(ap_ie->len) +
652 sizeof(struct mwifiex_ie_types_header);
645 653
646 tlv_ie->type = cpu_to_le16(TLV_TYPE_MGMT_IE); 654 tlv_ie->type = cpu_to_le16(TLV_TYPE_MGMT_IE);
647 tlv_ie->len = ap_ie->len; 655 tlv_ie->len = ap_ie->len;
648 tlv += sizeof(struct host_cmd_tlv); 656 tlv += sizeof(struct mwifiex_ie_types_header);
649 657
650 memcpy(tlv, ap_ie->ie_list, le16_to_cpu(ap_ie->len)); 658 memcpy(tlv, ap_ie->ie_list, le16_to_cpu(ap_ie->len));
651 659
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index a018e42d117e..1cfe5a738c47 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -24,6 +24,69 @@
24#include "11n_aggr.h" 24#include "11n_aggr.h"
25#include "11n_rxreorder.h" 25#include "11n_rxreorder.h"
26 26
27/* This function checks if particular RA list has packets more than low bridge
28 * packet threshold and then deletes packet from this RA list.
29 * Function deletes packets from such RA list and returns true. If no such list
30 * is found, false is returned.
31 */
32static bool
33mwifiex_uap_del_tx_pkts_in_ralist(struct mwifiex_private *priv,
34 struct list_head *ra_list_head)
35{
36 struct mwifiex_ra_list_tbl *ra_list;
37 struct sk_buff *skb, *tmp;
38 bool pkt_deleted = false;
39 struct mwifiex_txinfo *tx_info;
40 struct mwifiex_adapter *adapter = priv->adapter;
41
42 list_for_each_entry(ra_list, ra_list_head, list) {
43 if (skb_queue_empty(&ra_list->skb_head))
44 continue;
45
46 skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) {
47 tx_info = MWIFIEX_SKB_TXCB(skb);
48 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) {
49 __skb_unlink(skb, &ra_list->skb_head);
50 mwifiex_write_data_complete(adapter, skb, 0,
51 -1);
52 atomic_dec(&priv->wmm.tx_pkts_queued);
53 pkt_deleted = true;
54 }
55 if ((atomic_read(&adapter->pending_bridged_pkts) <=
56 MWIFIEX_BRIDGED_PKTS_THR_LOW))
57 break;
58 }
59 }
60
61 return pkt_deleted;
62}
63
64/* This function deletes packets from particular RA List. RA list index
65 * from which packets are deleted is preserved so that packets from next RA
66 * list are deleted upon subsequent call thus maintaining fairness.
67 */
68static void mwifiex_uap_cleanup_tx_queues(struct mwifiex_private *priv)
69{
70 unsigned long flags;
71 struct list_head *ra_list;
72 int i;
73
74 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
75
76 for (i = 0; i < MAX_NUM_TID; i++, priv->del_list_idx++) {
77 if (priv->del_list_idx == MAX_NUM_TID)
78 priv->del_list_idx = 0;
79 ra_list = &priv->wmm.tid_tbl_ptr[priv->del_list_idx].ra_list;
80 if (mwifiex_uap_del_tx_pkts_in_ralist(priv, ra_list)) {
81 priv->del_list_idx++;
82 break;
83 }
84 }
85
86 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
87}
88
89
27static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, 90static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
28 struct sk_buff *skb) 91 struct sk_buff *skb)
29{ 92{
@@ -40,10 +103,11 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
40 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); 103 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
41 104
42 if ((atomic_read(&adapter->pending_bridged_pkts) >= 105 if ((atomic_read(&adapter->pending_bridged_pkts) >=
43 MWIFIEX_BRIDGED_PKTS_THRESHOLD)) { 106 MWIFIEX_BRIDGED_PKTS_THR_HIGH)) {
44 dev_err(priv->adapter->dev, 107 dev_err(priv->adapter->dev,
45 "Tx: Bridge packet limit reached. Drop packet!\n"); 108 "Tx: Bridge packet limit reached. Drop packet!\n");
46 kfree_skb(skb); 109 kfree_skb(skb);
110 mwifiex_uap_cleanup_tx_queues(priv);
47 return; 111 return;
48 } 112 }
49 113
@@ -95,10 +159,6 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
95 atomic_inc(&adapter->tx_pending); 159 atomic_inc(&adapter->tx_pending);
96 atomic_inc(&adapter->pending_bridged_pkts); 160 atomic_inc(&adapter->pending_bridged_pkts);
97 161
98 if ((atomic_read(&adapter->tx_pending) >= MAX_TX_PENDING)) {
99 mwifiex_set_trans_start(priv->netdev);
100 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
101 }
102 return; 162 return;
103} 163}
104 164
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index f90fe21e5bfd..fca98b5d7de4 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -786,6 +786,13 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
786 return 0; 786 return 0;
787} 787}
788 788
789static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
790{
791 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
792
793 usb_set_intfdata(card->intf, NULL);
794}
795
789static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, 796static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
790 struct mwifiex_fw_image *fw) 797 struct mwifiex_fw_image *fw)
791{ 798{
@@ -978,6 +985,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
978 985
979static struct mwifiex_if_ops usb_ops = { 986static struct mwifiex_if_ops usb_ops = {
980 .register_dev = mwifiex_register_dev, 987 .register_dev = mwifiex_register_dev,
988 .unregister_dev = mwifiex_unregister_dev,
981 .wakeup = mwifiex_pm_wakeup_card, 989 .wakeup = mwifiex_pm_wakeup_card,
982 .wakeup_complete = mwifiex_pm_wakeup_card_complete, 990 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
983 991
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 944e8846f6fc..2e8f9cdea54d 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -120,7 +120,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
120 120
121 memcpy(ra_list->ra, ra, ETH_ALEN); 121 memcpy(ra_list->ra, ra, ETH_ALEN);
122 122
123 ra_list->total_pkts_size = 0; 123 ra_list->total_pkt_count = 0;
124 124
125 dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list); 125 dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list);
126 126
@@ -188,7 +188,7 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
188 ra_list, ra_list->is_11n_enabled); 188 ra_list, ra_list->is_11n_enabled);
189 189
190 if (ra_list->is_11n_enabled) { 190 if (ra_list->is_11n_enabled) {
191 ra_list->pkt_count = 0; 191 ra_list->ba_pkt_count = 0;
192 ra_list->ba_packet_thr = 192 ra_list->ba_packet_thr =
193 mwifiex_get_random_ba_threshold(); 193 mwifiex_get_random_ba_threshold();
194 } 194 }
@@ -679,8 +679,8 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
679 679
680 skb_queue_tail(&ra_list->skb_head, skb); 680 skb_queue_tail(&ra_list->skb_head, skb);
681 681
682 ra_list->total_pkts_size += skb->len; 682 ra_list->ba_pkt_count++;
683 ra_list->pkt_count++; 683 ra_list->total_pkt_count++;
684 684
685 if (atomic_read(&priv->wmm.highest_queued_prio) < 685 if (atomic_read(&priv->wmm.highest_queued_prio) <
686 tos_to_tid_inv[tid_down]) 686 tos_to_tid_inv[tid_down])
@@ -1037,7 +1037,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
1037 tx_info = MWIFIEX_SKB_TXCB(skb); 1037 tx_info = MWIFIEX_SKB_TXCB(skb);
1038 dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb); 1038 dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb);
1039 1039
1040 ptr->total_pkts_size -= skb->len; 1040 ptr->total_pkt_count--;
1041 1041
1042 if (!skb_queue_empty(&ptr->skb_head)) 1042 if (!skb_queue_empty(&ptr->skb_head))
1043 skb_next = skb_peek(&ptr->skb_head); 1043 skb_next = skb_peek(&ptr->skb_head);
@@ -1062,8 +1062,8 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
1062 1062
1063 skb_queue_tail(&ptr->skb_head, skb); 1063 skb_queue_tail(&ptr->skb_head, skb);
1064 1064
1065 ptr->total_pkts_size += skb->len; 1065 ptr->total_pkt_count++;
1066 ptr->pkt_count++; 1066 ptr->ba_pkt_count++;
1067 tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; 1067 tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
1068 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1068 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1069 ra_list_flags); 1069 ra_list_flags);
@@ -1224,7 +1224,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1224 mwifiex_send_single_packet() */ 1224 mwifiex_send_single_packet() */
1225 } else { 1225 } else {
1226 if (mwifiex_is_ampdu_allowed(priv, tid) && 1226 if (mwifiex_is_ampdu_allowed(priv, tid) &&
1227 ptr->pkt_count > ptr->ba_packet_thr) { 1227 ptr->ba_pkt_count > ptr->ba_packet_thr) {
1228 if (mwifiex_space_avail_for_new_ba_stream(adapter)) { 1228 if (mwifiex_space_avail_for_new_ba_stream(adapter)) {
1229 mwifiex_create_ba_tbl(priv, ptr->ra, tid, 1229 mwifiex_create_ba_tbl(priv, ptr->ra, tid,
1230 BA_SETUP_INPROGRESS); 1230 BA_SETUP_INPROGRESS);
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 3e60a31582f8..68dbbb9c6d12 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -166,6 +166,12 @@ config RT2800USB_RT35XX
166 rt2800usb driver. 166 rt2800usb driver.
167 Supported chips: RT3572 167 Supported chips: RT3572
168 168
169config RT2800USB_RT3573
170 bool "rt2800usb - Include support for rt3573 devices (EXPERIMENTAL)"
171 ---help---
172 This enables support for RT3573 chipset based wireless USB devices
173 in the rt2800usb driver.
174
169config RT2800USB_RT53XX 175config RT2800USB_RT53XX
170 bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)" 176 bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
171 ---help--- 177 ---help---
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index d78c495a86a0..a3132414ac9f 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -88,6 +88,7 @@
88#define REV_RT3071E 0x0211 88#define REV_RT3071E 0x0211
89#define REV_RT3090E 0x0211 89#define REV_RT3090E 0x0211
90#define REV_RT3390E 0x0211 90#define REV_RT3390E 0x0211
91#define REV_RT3593E 0x0211
91#define REV_RT5390F 0x0502 92#define REV_RT5390F 0x0502
92#define REV_RT5390R 0x1502 93#define REV_RT5390R 0x1502
93#define REV_RT5592C 0x0221 94#define REV_RT5592C 0x0221
@@ -1082,6 +1083,15 @@
1082#define TX_PWR_CFG_0_9MBS FIELD32(0x00f00000) 1083#define TX_PWR_CFG_0_9MBS FIELD32(0x00f00000)
1083#define TX_PWR_CFG_0_12MBS FIELD32(0x0f000000) 1084#define TX_PWR_CFG_0_12MBS FIELD32(0x0f000000)
1084#define TX_PWR_CFG_0_18MBS FIELD32(0xf0000000) 1085#define TX_PWR_CFG_0_18MBS FIELD32(0xf0000000)
1086/* bits for 3T devices */
1087#define TX_PWR_CFG_0_CCK1_CH0 FIELD32(0x0000000f)
1088#define TX_PWR_CFG_0_CCK1_CH1 FIELD32(0x000000f0)
1089#define TX_PWR_CFG_0_CCK5_CH0 FIELD32(0x00000f00)
1090#define TX_PWR_CFG_0_CCK5_CH1 FIELD32(0x0000f000)
1091#define TX_PWR_CFG_0_OFDM6_CH0 FIELD32(0x000f0000)
1092#define TX_PWR_CFG_0_OFDM6_CH1 FIELD32(0x00f00000)
1093#define TX_PWR_CFG_0_OFDM12_CH0 FIELD32(0x0f000000)
1094#define TX_PWR_CFG_0_OFDM12_CH1 FIELD32(0xf0000000)
1085 1095
1086/* 1096/*
1087 * TX_PWR_CFG_1: 1097 * TX_PWR_CFG_1:
@@ -1095,6 +1105,15 @@
1095#define TX_PWR_CFG_1_MCS1 FIELD32(0x00f00000) 1105#define TX_PWR_CFG_1_MCS1 FIELD32(0x00f00000)
1096#define TX_PWR_CFG_1_MCS2 FIELD32(0x0f000000) 1106#define TX_PWR_CFG_1_MCS2 FIELD32(0x0f000000)
1097#define TX_PWR_CFG_1_MCS3 FIELD32(0xf0000000) 1107#define TX_PWR_CFG_1_MCS3 FIELD32(0xf0000000)
1108/* bits for 3T devices */
1109#define TX_PWR_CFG_1_OFDM24_CH0 FIELD32(0x0000000f)
1110#define TX_PWR_CFG_1_OFDM24_CH1 FIELD32(0x000000f0)
1111#define TX_PWR_CFG_1_OFDM48_CH0 FIELD32(0x00000f00)
1112#define TX_PWR_CFG_1_OFDM48_CH1 FIELD32(0x0000f000)
1113#define TX_PWR_CFG_1_MCS0_CH0 FIELD32(0x000f0000)
1114#define TX_PWR_CFG_1_MCS0_CH1 FIELD32(0x00f00000)
1115#define TX_PWR_CFG_1_MCS2_CH0 FIELD32(0x0f000000)
1116#define TX_PWR_CFG_1_MCS2_CH1 FIELD32(0xf0000000)
1098 1117
1099/* 1118/*
1100 * TX_PWR_CFG_2: 1119 * TX_PWR_CFG_2:
@@ -1108,6 +1127,15 @@
1108#define TX_PWR_CFG_2_MCS9 FIELD32(0x00f00000) 1127#define TX_PWR_CFG_2_MCS9 FIELD32(0x00f00000)
1109#define TX_PWR_CFG_2_MCS10 FIELD32(0x0f000000) 1128#define TX_PWR_CFG_2_MCS10 FIELD32(0x0f000000)
1110#define TX_PWR_CFG_2_MCS11 FIELD32(0xf0000000) 1129#define TX_PWR_CFG_2_MCS11 FIELD32(0xf0000000)
1130/* bits for 3T devices */
1131#define TX_PWR_CFG_2_MCS4_CH0 FIELD32(0x0000000f)
1132#define TX_PWR_CFG_2_MCS4_CH1 FIELD32(0x000000f0)
1133#define TX_PWR_CFG_2_MCS6_CH0 FIELD32(0x00000f00)
1134#define TX_PWR_CFG_2_MCS6_CH1 FIELD32(0x0000f000)
1135#define TX_PWR_CFG_2_MCS8_CH0 FIELD32(0x000f0000)
1136#define TX_PWR_CFG_2_MCS8_CH1 FIELD32(0x00f00000)
1137#define TX_PWR_CFG_2_MCS10_CH0 FIELD32(0x0f000000)
1138#define TX_PWR_CFG_2_MCS10_CH1 FIELD32(0xf0000000)
1111 1139
1112/* 1140/*
1113 * TX_PWR_CFG_3: 1141 * TX_PWR_CFG_3:
@@ -1121,6 +1149,15 @@
1121#define TX_PWR_CFG_3_UKNOWN2 FIELD32(0x00f00000) 1149#define TX_PWR_CFG_3_UKNOWN2 FIELD32(0x00f00000)
1122#define TX_PWR_CFG_3_UKNOWN3 FIELD32(0x0f000000) 1150#define TX_PWR_CFG_3_UKNOWN3 FIELD32(0x0f000000)
1123#define TX_PWR_CFG_3_UKNOWN4 FIELD32(0xf0000000) 1151#define TX_PWR_CFG_3_UKNOWN4 FIELD32(0xf0000000)
1152/* bits for 3T devices */
1153#define TX_PWR_CFG_3_MCS12_CH0 FIELD32(0x0000000f)
1154#define TX_PWR_CFG_3_MCS12_CH1 FIELD32(0x000000f0)
1155#define TX_PWR_CFG_3_MCS14_CH0 FIELD32(0x00000f00)
1156#define TX_PWR_CFG_3_MCS14_CH1 FIELD32(0x0000f000)
1157#define TX_PWR_CFG_3_STBC0_CH0 FIELD32(0x000f0000)
1158#define TX_PWR_CFG_3_STBC0_CH1 FIELD32(0x00f00000)
1159#define TX_PWR_CFG_3_STBC2_CH0 FIELD32(0x0f000000)
1160#define TX_PWR_CFG_3_STBC2_CH1 FIELD32(0xf0000000)
1124 1161
1125/* 1162/*
1126 * TX_PWR_CFG_4: 1163 * TX_PWR_CFG_4:
@@ -1130,6 +1167,11 @@
1130#define TX_PWR_CFG_4_UKNOWN6 FIELD32(0x000000f0) 1167#define TX_PWR_CFG_4_UKNOWN6 FIELD32(0x000000f0)
1131#define TX_PWR_CFG_4_UKNOWN7 FIELD32(0x00000f00) 1168#define TX_PWR_CFG_4_UKNOWN7 FIELD32(0x00000f00)
1132#define TX_PWR_CFG_4_UKNOWN8 FIELD32(0x0000f000) 1169#define TX_PWR_CFG_4_UKNOWN8 FIELD32(0x0000f000)
1170/* bits for 3T devices */
1171#define TX_PWR_CFG_3_STBC4_CH0 FIELD32(0x0000000f)
1172#define TX_PWR_CFG_3_STBC4_CH1 FIELD32(0x000000f0)
1173#define TX_PWR_CFG_3_STBC6_CH0 FIELD32(0x00000f00)
1174#define TX_PWR_CFG_3_STBC6_CH1 FIELD32(0x0000f000)
1133 1175
1134/* 1176/*
1135 * TX_PIN_CFG: 1177 * TX_PIN_CFG:
@@ -1451,6 +1493,81 @@
1451 */ 1493 */
1452#define EXP_ACK_TIME 0x1380 1494#define EXP_ACK_TIME 0x1380
1453 1495
1496/* TX_PWR_CFG_5 */
1497#define TX_PWR_CFG_5 0x1384
1498#define TX_PWR_CFG_5_MCS16_CH0 FIELD32(0x0000000f)
1499#define TX_PWR_CFG_5_MCS16_CH1 FIELD32(0x000000f0)
1500#define TX_PWR_CFG_5_MCS16_CH2 FIELD32(0x00000f00)
1501#define TX_PWR_CFG_5_MCS18_CH0 FIELD32(0x000f0000)
1502#define TX_PWR_CFG_5_MCS18_CH1 FIELD32(0x00f00000)
1503#define TX_PWR_CFG_5_MCS18_CH2 FIELD32(0x0f000000)
1504
1505/* TX_PWR_CFG_6 */
1506#define TX_PWR_CFG_6 0x1388
1507#define TX_PWR_CFG_6_MCS20_CH0 FIELD32(0x0000000f)
1508#define TX_PWR_CFG_6_MCS20_CH1 FIELD32(0x000000f0)
1509#define TX_PWR_CFG_6_MCS20_CH2 FIELD32(0x00000f00)
1510#define TX_PWR_CFG_6_MCS22_CH0 FIELD32(0x000f0000)
1511#define TX_PWR_CFG_6_MCS22_CH1 FIELD32(0x00f00000)
1512#define TX_PWR_CFG_6_MCS22_CH2 FIELD32(0x0f000000)
1513
1514/* TX_PWR_CFG_0_EXT */
1515#define TX_PWR_CFG_0_EXT 0x1390
1516#define TX_PWR_CFG_0_EXT_CCK1_CH2 FIELD32(0x0000000f)
1517#define TX_PWR_CFG_0_EXT_CCK5_CH2 FIELD32(0x00000f00)
1518#define TX_PWR_CFG_0_EXT_OFDM6_CH2 FIELD32(0x000f0000)
1519#define TX_PWR_CFG_0_EXT_OFDM12_CH2 FIELD32(0x0f000000)
1520
1521/* TX_PWR_CFG_1_EXT */
1522#define TX_PWR_CFG_1_EXT 0x1394
1523#define TX_PWR_CFG_1_EXT_OFDM24_CH2 FIELD32(0x0000000f)
1524#define TX_PWR_CFG_1_EXT_OFDM48_CH2 FIELD32(0x00000f00)
1525#define TX_PWR_CFG_1_EXT_MCS0_CH2 FIELD32(0x000f0000)
1526#define TX_PWR_CFG_1_EXT_MCS2_CH2 FIELD32(0x0f000000)
1527
1528/* TX_PWR_CFG_2_EXT */
1529#define TX_PWR_CFG_2_EXT 0x1398
1530#define TX_PWR_CFG_2_EXT_MCS4_CH2 FIELD32(0x0000000f)
1531#define TX_PWR_CFG_2_EXT_MCS6_CH2 FIELD32(0x00000f00)
1532#define TX_PWR_CFG_2_EXT_MCS8_CH2 FIELD32(0x000f0000)
1533#define TX_PWR_CFG_2_EXT_MCS10_CH2 FIELD32(0x0f000000)
1534
1535/* TX_PWR_CFG_3_EXT */
1536#define TX_PWR_CFG_3_EXT 0x139c
1537#define TX_PWR_CFG_3_EXT_MCS12_CH2 FIELD32(0x0000000f)
1538#define TX_PWR_CFG_3_EXT_MCS14_CH2 FIELD32(0x00000f00)
1539#define TX_PWR_CFG_3_EXT_STBC0_CH2 FIELD32(0x000f0000)
1540#define TX_PWR_CFG_3_EXT_STBC2_CH2 FIELD32(0x0f000000)
1541
1542/* TX_PWR_CFG_4_EXT */
1543#define TX_PWR_CFG_4_EXT 0x13a0
1544#define TX_PWR_CFG_4_EXT_STBC4_CH2 FIELD32(0x0000000f)
1545#define TX_PWR_CFG_4_EXT_STBC6_CH2 FIELD32(0x00000f00)
1546
1547/* TX_PWR_CFG_7 */
1548#define TX_PWR_CFG_7 0x13d4
1549#define TX_PWR_CFG_7_OFDM54_CH0 FIELD32(0x0000000f)
1550#define TX_PWR_CFG_7_OFDM54_CH1 FIELD32(0x000000f0)
1551#define TX_PWR_CFG_7_OFDM54_CH2 FIELD32(0x00000f00)
1552#define TX_PWR_CFG_7_MCS7_CH0 FIELD32(0x000f0000)
1553#define TX_PWR_CFG_7_MCS7_CH1 FIELD32(0x00f00000)
1554#define TX_PWR_CFG_7_MCS7_CH2 FIELD32(0x0f000000)
1555
1556/* TX_PWR_CFG_8 */
1557#define TX_PWR_CFG_8 0x13d8
1558#define TX_PWR_CFG_8_MCS15_CH0 FIELD32(0x0000000f)
1559#define TX_PWR_CFG_8_MCS15_CH1 FIELD32(0x000000f0)
1560#define TX_PWR_CFG_8_MCS15_CH2 FIELD32(0x00000f00)
1561#define TX_PWR_CFG_8_MCS23_CH0 FIELD32(0x000f0000)
1562#define TX_PWR_CFG_8_MCS23_CH1 FIELD32(0x00f00000)
1563#define TX_PWR_CFG_8_MCS23_CH2 FIELD32(0x0f000000)
1564
1565/* TX_PWR_CFG_9 */
1566#define TX_PWR_CFG_9 0x13dc
1567#define TX_PWR_CFG_9_STBC7_CH0 FIELD32(0x0000000f)
1568#define TX_PWR_CFG_9_STBC7_CH1 FIELD32(0x000000f0)
1569#define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00)
1570
1454/* 1571/*
1455 * RX_FILTER_CFG: RX configuration register. 1572 * RX_FILTER_CFG: RX configuration register.
1456 */ 1573 */
@@ -1975,6 +2092,10 @@ struct mac_iveiv_entry {
1975#define BBP109_TX0_POWER FIELD8(0x0f) 2092#define BBP109_TX0_POWER FIELD8(0x0f)
1976#define BBP109_TX1_POWER FIELD8(0xf0) 2093#define BBP109_TX1_POWER FIELD8(0xf0)
1977 2094
2095/* BBP 110 */
2096#define BBP110_TX2_POWER FIELD8(0x0f)
2097
2098
1978/* 2099/*
1979 * BBP 138: Unknown 2100 * BBP 138: Unknown
1980 */ 2101 */
@@ -2024,6 +2145,12 @@ struct mac_iveiv_entry {
2024#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80) 2145#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80)
2025/* Bits for RF3290/RF5360/RF5370/RF5372/RF5390/RF5392 */ 2146/* Bits for RF3290/RF5360/RF5370/RF5372/RF5390/RF5392 */
2026#define RFCSR3_VCOCAL_EN FIELD8(0x80) 2147#define RFCSR3_VCOCAL_EN FIELD8(0x80)
2148/* Bits for RF3050 */
2149#define RFCSR3_BIT1 FIELD8(0x02)
2150#define RFCSR3_BIT2 FIELD8(0x04)
2151#define RFCSR3_BIT3 FIELD8(0x08)
2152#define RFCSR3_BIT4 FIELD8(0x10)
2153#define RFCSR3_BIT5 FIELD8(0x20)
2027 2154
2028/* 2155/*
2029 * FRCSR 5: 2156 * FRCSR 5:
@@ -2036,6 +2163,8 @@ struct mac_iveiv_entry {
2036#define RFCSR6_R1 FIELD8(0x03) 2163#define RFCSR6_R1 FIELD8(0x03)
2037#define RFCSR6_R2 FIELD8(0x40) 2164#define RFCSR6_R2 FIELD8(0x40)
2038#define RFCSR6_TXDIV FIELD8(0x0c) 2165#define RFCSR6_TXDIV FIELD8(0x0c)
2166/* bits for RF3053 */
2167#define RFCSR6_VCO_IC FIELD8(0xc0)
2039 2168
2040/* 2169/*
2041 * RFCSR 7: 2170 * RFCSR 7:
@@ -2060,7 +2189,12 @@ struct mac_iveiv_entry {
2060 * RFCSR 11: 2189 * RFCSR 11:
2061 */ 2190 */
2062#define RFCSR11_R FIELD8(0x03) 2191#define RFCSR11_R FIELD8(0x03)
2192#define RFCSR11_PLL_MOD FIELD8(0x0c)
2063#define RFCSR11_MOD FIELD8(0xc0) 2193#define RFCSR11_MOD FIELD8(0xc0)
2194/* bits for RF3053 */
2195/* TODO: verify RFCSR11_MOD usage on other chips */
2196#define RFCSR11_PLL_IDOH FIELD8(0x40)
2197
2064 2198
2065/* 2199/*
2066 * RFCSR 12: 2200 * RFCSR 12:
@@ -2092,6 +2226,10 @@ struct mac_iveiv_entry {
2092#define RFCSR17_R FIELD8(0x20) 2226#define RFCSR17_R FIELD8(0x20)
2093#define RFCSR17_CODE FIELD8(0x7f) 2227#define RFCSR17_CODE FIELD8(0x7f)
2094 2228
2229/* RFCSR 18 */
2230#define RFCSR18_XO_TUNE_BYPASS FIELD8(0x40)
2231
2232
2095/* 2233/*
2096 * RFCSR 20: 2234 * RFCSR 20:
2097 */ 2235 */
@@ -2152,6 +2290,12 @@ struct mac_iveiv_entry {
2152#define RFCSR31_RX_H20M FIELD8(0x20) 2290#define RFCSR31_RX_H20M FIELD8(0x20)
2153#define RFCSR31_RX_CALIB FIELD8(0x7f) 2291#define RFCSR31_RX_CALIB FIELD8(0x7f)
2154 2292
2293/* RFCSR 32 bits for RF3053 */
2294#define RFCSR32_TX_AGC_FC FIELD8(0xf8)
2295
2296/* RFCSR 36 bits for RF3053 */
2297#define RFCSR36_RF_BS FIELD8(0x80)
2298
2155/* 2299/*
2156 * RFCSR 38: 2300 * RFCSR 38:
2157 */ 2301 */
@@ -2160,6 +2304,7 @@ struct mac_iveiv_entry {
2160/* 2304/*
2161 * RFCSR 39: 2305 * RFCSR 39:
2162 */ 2306 */
2307#define RFCSR39_RX_DIV FIELD8(0x40)
2163#define RFCSR39_RX_LO2_EN FIELD8(0x80) 2308#define RFCSR39_RX_LO2_EN FIELD8(0x80)
2164 2309
2165/* 2310/*
@@ -2167,12 +2312,36 @@ struct mac_iveiv_entry {
2167 */ 2312 */
2168#define RFCSR49_TX FIELD8(0x3f) 2313#define RFCSR49_TX FIELD8(0x3f)
2169#define RFCSR49_EP FIELD8(0xc0) 2314#define RFCSR49_EP FIELD8(0xc0)
2315/* bits for RT3593 */
2316#define RFCSR49_TX_LO1_IC FIELD8(0x1c)
2317#define RFCSR49_TX_DIV FIELD8(0x20)
2170 2318
2171/* 2319/*
2172 * RFCSR 50: 2320 * RFCSR 50:
2173 */ 2321 */
2174#define RFCSR50_TX FIELD8(0x3f) 2322#define RFCSR50_TX FIELD8(0x3f)
2175#define RFCSR50_EP FIELD8(0xc0) 2323#define RFCSR50_EP FIELD8(0xc0)
2324/* bits for RT3593 */
2325#define RFCSR50_TX_LO1_EN FIELD8(0x20)
2326#define RFCSR50_TX_LO2_EN FIELD8(0x10)
2327
2328/* RFCSR 51 */
2329/* bits for RT3593 */
2330#define RFCSR51_BITS01 FIELD8(0x03)
2331#define RFCSR51_BITS24 FIELD8(0x1c)
2332#define RFCSR51_BITS57 FIELD8(0xe0)
2333
2334#define RFCSR53_TX_POWER FIELD8(0x3f)
2335#define RFCSR53_UNKNOWN FIELD8(0xc0)
2336
2337#define RFCSR54_TX_POWER FIELD8(0x3f)
2338#define RFCSR54_UNKNOWN FIELD8(0xc0)
2339
2340#define RFCSR55_TX_POWER FIELD8(0x3f)
2341#define RFCSR55_UNKNOWN FIELD8(0xc0)
2342
2343#define RFCSR57_DRV_CC FIELD8(0xfc)
2344
2176 2345
2177/* 2346/*
2178 * RF registers 2347 * RF registers
@@ -2206,28 +2375,67 @@ struct mac_iveiv_entry {
2206 * The wordsize of the EEPROM is 16 bits. 2375 * The wordsize of the EEPROM is 16 bits.
2207 */ 2376 */
2208 2377
2209/* 2378enum rt2800_eeprom_word {
2210 * Chip ID 2379 EEPROM_CHIP_ID = 0,
2211 */ 2380 EEPROM_VERSION,
2212#define EEPROM_CHIP_ID 0x0000 2381 EEPROM_MAC_ADDR_0,
2382 EEPROM_MAC_ADDR_1,
2383 EEPROM_MAC_ADDR_2,
2384 EEPROM_NIC_CONF0,
2385 EEPROM_NIC_CONF1,
2386 EEPROM_FREQ,
2387 EEPROM_LED_AG_CONF,
2388 EEPROM_LED_ACT_CONF,
2389 EEPROM_LED_POLARITY,
2390 EEPROM_NIC_CONF2,
2391 EEPROM_LNA,
2392 EEPROM_RSSI_BG,
2393 EEPROM_RSSI_BG2,
2394 EEPROM_TXMIXER_GAIN_BG,
2395 EEPROM_RSSI_A,
2396 EEPROM_RSSI_A2,
2397 EEPROM_TXMIXER_GAIN_A,
2398 EEPROM_EIRP_MAX_TX_POWER,
2399 EEPROM_TXPOWER_DELTA,
2400 EEPROM_TXPOWER_BG1,
2401 EEPROM_TXPOWER_BG2,
2402 EEPROM_TSSI_BOUND_BG1,
2403 EEPROM_TSSI_BOUND_BG2,
2404 EEPROM_TSSI_BOUND_BG3,
2405 EEPROM_TSSI_BOUND_BG4,
2406 EEPROM_TSSI_BOUND_BG5,
2407 EEPROM_TXPOWER_A1,
2408 EEPROM_TXPOWER_A2,
2409 EEPROM_TSSI_BOUND_A1,
2410 EEPROM_TSSI_BOUND_A2,
2411 EEPROM_TSSI_BOUND_A3,
2412 EEPROM_TSSI_BOUND_A4,
2413 EEPROM_TSSI_BOUND_A5,
2414 EEPROM_TXPOWER_BYRATE,
2415 EEPROM_BBP_START,
2416
2417 /* IDs for extended EEPROM format used by three-chain devices */
2418 EEPROM_EXT_LNA2,
2419 EEPROM_EXT_TXPOWER_BG3,
2420 EEPROM_EXT_TXPOWER_A3,
2421
2422 /* New values must be added before this */
2423 EEPROM_WORD_COUNT
2424};
2213 2425
2214/* 2426/*
2215 * EEPROM Version 2427 * EEPROM Version
2216 */ 2428 */
2217#define EEPROM_VERSION 0x0001
2218#define EEPROM_VERSION_FAE FIELD16(0x00ff) 2429#define EEPROM_VERSION_FAE FIELD16(0x00ff)
2219#define EEPROM_VERSION_VERSION FIELD16(0xff00) 2430#define EEPROM_VERSION_VERSION FIELD16(0xff00)
2220 2431
2221/* 2432/*
2222 * HW MAC address. 2433 * HW MAC address.
2223 */ 2434 */
2224#define EEPROM_MAC_ADDR_0 0x0002
2225#define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) 2435#define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff)
2226#define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) 2436#define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00)
2227#define EEPROM_MAC_ADDR_1 0x0003
2228#define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) 2437#define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff)
2229#define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) 2438#define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00)
2230#define EEPROM_MAC_ADDR_2 0x0004
2231#define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) 2439#define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff)
2232#define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) 2440#define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00)
2233 2441
@@ -2237,7 +2445,6 @@ struct mac_iveiv_entry {
2237 * TXPATH: 1: 1T, 2: 2T, 3: 3T 2445 * TXPATH: 1: 1T, 2: 2T, 3: 3T
2238 * RF_TYPE: RFIC type 2446 * RF_TYPE: RFIC type
2239 */ 2447 */
2240#define EEPROM_NIC_CONF0 0x001a
2241#define EEPROM_NIC_CONF0_RXPATH FIELD16(0x000f) 2448#define EEPROM_NIC_CONF0_RXPATH FIELD16(0x000f)
2242#define EEPROM_NIC_CONF0_TXPATH FIELD16(0x00f0) 2449#define EEPROM_NIC_CONF0_TXPATH FIELD16(0x00f0)
2243#define EEPROM_NIC_CONF0_RF_TYPE FIELD16(0x0f00) 2450#define EEPROM_NIC_CONF0_RF_TYPE FIELD16(0x0f00)
@@ -2261,7 +2468,6 @@ struct mac_iveiv_entry {
2261 * BT_COEXIST: 0: disable, 1: enable 2468 * BT_COEXIST: 0: disable, 1: enable
2262 * DAC_TEST: 0: disable, 1: enable 2469 * DAC_TEST: 0: disable, 1: enable
2263 */ 2470 */
2264#define EEPROM_NIC_CONF1 0x001b
2265#define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001) 2471#define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001)
2266#define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002) 2472#define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002)
2267#define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G FIELD16(0x0004) 2473#define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G FIELD16(0x0004)
@@ -2281,7 +2487,6 @@ struct mac_iveiv_entry {
2281/* 2487/*
2282 * EEPROM frequency 2488 * EEPROM frequency
2283 */ 2489 */
2284#define EEPROM_FREQ 0x001d
2285#define EEPROM_FREQ_OFFSET FIELD16(0x00ff) 2490#define EEPROM_FREQ_OFFSET FIELD16(0x00ff)
2286#define EEPROM_FREQ_LED_MODE FIELD16(0x7f00) 2491#define EEPROM_FREQ_LED_MODE FIELD16(0x7f00)
2287#define EEPROM_FREQ_LED_POLARITY FIELD16(0x1000) 2492#define EEPROM_FREQ_LED_POLARITY FIELD16(0x1000)
@@ -2298,9 +2503,6 @@ struct mac_iveiv_entry {
2298 * POLARITY_GPIO_4: Polarity GPIO4 setting. 2503 * POLARITY_GPIO_4: Polarity GPIO4 setting.
2299 * LED_MODE: Led mode. 2504 * LED_MODE: Led mode.
2300 */ 2505 */
2301#define EEPROM_LED_AG_CONF 0x001e
2302#define EEPROM_LED_ACT_CONF 0x001f
2303#define EEPROM_LED_POLARITY 0x0020
2304#define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001) 2506#define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001)
2305#define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002) 2507#define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002)
2306#define EEPROM_LED_POLARITY_ACT FIELD16(0x0004) 2508#define EEPROM_LED_POLARITY_ACT FIELD16(0x0004)
@@ -2317,7 +2519,6 @@ struct mac_iveiv_entry {
2317 * TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream 2519 * TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
2318 * CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved 2520 * CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved
2319 */ 2521 */
2320#define EEPROM_NIC_CONF2 0x0021
2321#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f) 2522#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f)
2322#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0) 2523#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0)
2323#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600) 2524#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600)
@@ -2325,54 +2526,46 @@ struct mac_iveiv_entry {
2325/* 2526/*
2326 * EEPROM LNA 2527 * EEPROM LNA
2327 */ 2528 */
2328#define EEPROM_LNA 0x0022
2329#define EEPROM_LNA_BG FIELD16(0x00ff) 2529#define EEPROM_LNA_BG FIELD16(0x00ff)
2330#define EEPROM_LNA_A0 FIELD16(0xff00) 2530#define EEPROM_LNA_A0 FIELD16(0xff00)
2331 2531
2332/* 2532/*
2333 * EEPROM RSSI BG offset 2533 * EEPROM RSSI BG offset
2334 */ 2534 */
2335#define EEPROM_RSSI_BG 0x0023
2336#define EEPROM_RSSI_BG_OFFSET0 FIELD16(0x00ff) 2535#define EEPROM_RSSI_BG_OFFSET0 FIELD16(0x00ff)
2337#define EEPROM_RSSI_BG_OFFSET1 FIELD16(0xff00) 2536#define EEPROM_RSSI_BG_OFFSET1 FIELD16(0xff00)
2338 2537
2339/* 2538/*
2340 * EEPROM RSSI BG2 offset 2539 * EEPROM RSSI BG2 offset
2341 */ 2540 */
2342#define EEPROM_RSSI_BG2 0x0024
2343#define EEPROM_RSSI_BG2_OFFSET2 FIELD16(0x00ff) 2541#define EEPROM_RSSI_BG2_OFFSET2 FIELD16(0x00ff)
2344#define EEPROM_RSSI_BG2_LNA_A1 FIELD16(0xff00) 2542#define EEPROM_RSSI_BG2_LNA_A1 FIELD16(0xff00)
2345 2543
2346/* 2544/*
2347 * EEPROM TXMIXER GAIN BG offset (note overlaps with EEPROM RSSI BG2). 2545 * EEPROM TXMIXER GAIN BG offset (note overlaps with EEPROM RSSI BG2).
2348 */ 2546 */
2349#define EEPROM_TXMIXER_GAIN_BG 0x0024
2350#define EEPROM_TXMIXER_GAIN_BG_VAL FIELD16(0x0007) 2547#define EEPROM_TXMIXER_GAIN_BG_VAL FIELD16(0x0007)
2351 2548
2352/* 2549/*
2353 * EEPROM RSSI A offset 2550 * EEPROM RSSI A offset
2354 */ 2551 */
2355#define EEPROM_RSSI_A 0x0025
2356#define EEPROM_RSSI_A_OFFSET0 FIELD16(0x00ff) 2552#define EEPROM_RSSI_A_OFFSET0 FIELD16(0x00ff)
2357#define EEPROM_RSSI_A_OFFSET1 FIELD16(0xff00) 2553#define EEPROM_RSSI_A_OFFSET1 FIELD16(0xff00)
2358 2554
2359/* 2555/*
2360 * EEPROM RSSI A2 offset 2556 * EEPROM RSSI A2 offset
2361 */ 2557 */
2362#define EEPROM_RSSI_A2 0x0026
2363#define EEPROM_RSSI_A2_OFFSET2 FIELD16(0x00ff) 2558#define EEPROM_RSSI_A2_OFFSET2 FIELD16(0x00ff)
2364#define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) 2559#define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00)
2365 2560
2366/* 2561/*
2367 * EEPROM TXMIXER GAIN A offset (note overlaps with EEPROM RSSI A2). 2562 * EEPROM TXMIXER GAIN A offset (note overlaps with EEPROM RSSI A2).
2368 */ 2563 */
2369#define EEPROM_TXMIXER_GAIN_A 0x0026
2370#define EEPROM_TXMIXER_GAIN_A_VAL FIELD16(0x0007) 2564#define EEPROM_TXMIXER_GAIN_A_VAL FIELD16(0x0007)
2371 2565
2372/* 2566/*
2373 * EEPROM EIRP Maximum TX power values(unit: dbm) 2567 * EEPROM EIRP Maximum TX power values(unit: dbm)
2374 */ 2568 */
2375#define EEPROM_EIRP_MAX_TX_POWER 0x0027
2376#define EEPROM_EIRP_MAX_TX_POWER_2GHZ FIELD16(0x00ff) 2569#define EEPROM_EIRP_MAX_TX_POWER_2GHZ FIELD16(0x00ff)
2377#define EEPROM_EIRP_MAX_TX_POWER_5GHZ FIELD16(0xff00) 2570#define EEPROM_EIRP_MAX_TX_POWER_5GHZ FIELD16(0xff00)
2378 2571
@@ -2383,7 +2576,6 @@ struct mac_iveiv_entry {
2383 * TYPE: 1: Plus the delta value, 0: minus the delta value 2576 * TYPE: 1: Plus the delta value, 0: minus the delta value
2384 * ENABLE: enable tx power compensation for 40BW 2577 * ENABLE: enable tx power compensation for 40BW
2385 */ 2578 */
2386#define EEPROM_TXPOWER_DELTA 0x0028
2387#define EEPROM_TXPOWER_DELTA_VALUE_2G FIELD16(0x003f) 2579#define EEPROM_TXPOWER_DELTA_VALUE_2G FIELD16(0x003f)
2388#define EEPROM_TXPOWER_DELTA_TYPE_2G FIELD16(0x0040) 2580#define EEPROM_TXPOWER_DELTA_TYPE_2G FIELD16(0x0040)
2389#define EEPROM_TXPOWER_DELTA_ENABLE_2G FIELD16(0x0080) 2581#define EEPROM_TXPOWER_DELTA_ENABLE_2G FIELD16(0x0080)
@@ -2394,8 +2586,6 @@ struct mac_iveiv_entry {
2394/* 2586/*
2395 * EEPROM TXPOWER 802.11BG 2587 * EEPROM TXPOWER 802.11BG
2396 */ 2588 */
2397#define EEPROM_TXPOWER_BG1 0x0029
2398#define EEPROM_TXPOWER_BG2 0x0030
2399#define EEPROM_TXPOWER_BG_SIZE 7 2589#define EEPROM_TXPOWER_BG_SIZE 7
2400#define EEPROM_TXPOWER_BG_1 FIELD16(0x00ff) 2590#define EEPROM_TXPOWER_BG_1 FIELD16(0x00ff)
2401#define EEPROM_TXPOWER_BG_2 FIELD16(0xff00) 2591#define EEPROM_TXPOWER_BG_2 FIELD16(0xff00)
@@ -2407,7 +2597,6 @@ struct mac_iveiv_entry {
2407 * MINUS3: If the actual TSSI is below this boundary, tx power needs to be 2597 * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
2408 * reduced by (agc_step * -3) 2598 * reduced by (agc_step * -3)
2409 */ 2599 */
2410#define EEPROM_TSSI_BOUND_BG1 0x0037
2411#define EEPROM_TSSI_BOUND_BG1_MINUS4 FIELD16(0x00ff) 2600#define EEPROM_TSSI_BOUND_BG1_MINUS4 FIELD16(0x00ff)
2412#define EEPROM_TSSI_BOUND_BG1_MINUS3 FIELD16(0xff00) 2601#define EEPROM_TSSI_BOUND_BG1_MINUS3 FIELD16(0xff00)
2413 2602
@@ -2418,7 +2607,6 @@ struct mac_iveiv_entry {
2418 * MINUS1: If the actual TSSI is below this boundary, tx power needs to be 2607 * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
2419 * reduced by (agc_step * -1) 2608 * reduced by (agc_step * -1)
2420 */ 2609 */
2421#define EEPROM_TSSI_BOUND_BG2 0x0038
2422#define EEPROM_TSSI_BOUND_BG2_MINUS2 FIELD16(0x00ff) 2610#define EEPROM_TSSI_BOUND_BG2_MINUS2 FIELD16(0x00ff)
2423#define EEPROM_TSSI_BOUND_BG2_MINUS1 FIELD16(0xff00) 2611#define EEPROM_TSSI_BOUND_BG2_MINUS1 FIELD16(0xff00)
2424 2612
@@ -2428,7 +2616,6 @@ struct mac_iveiv_entry {
2428 * PLUS1: If the actual TSSI is above this boundary, tx power needs to be 2616 * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
2429 * increased by (agc_step * 1) 2617 * increased by (agc_step * 1)
2430 */ 2618 */
2431#define EEPROM_TSSI_BOUND_BG3 0x0039
2432#define EEPROM_TSSI_BOUND_BG3_REF FIELD16(0x00ff) 2619#define EEPROM_TSSI_BOUND_BG3_REF FIELD16(0x00ff)
2433#define EEPROM_TSSI_BOUND_BG3_PLUS1 FIELD16(0xff00) 2620#define EEPROM_TSSI_BOUND_BG3_PLUS1 FIELD16(0xff00)
2434 2621
@@ -2439,7 +2626,6 @@ struct mac_iveiv_entry {
2439 * PLUS3: If the actual TSSI is above this boundary, tx power needs to be 2626 * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
2440 * increased by (agc_step * 3) 2627 * increased by (agc_step * 3)
2441 */ 2628 */
2442#define EEPROM_TSSI_BOUND_BG4 0x003a
2443#define EEPROM_TSSI_BOUND_BG4_PLUS2 FIELD16(0x00ff) 2629#define EEPROM_TSSI_BOUND_BG4_PLUS2 FIELD16(0x00ff)
2444#define EEPROM_TSSI_BOUND_BG4_PLUS3 FIELD16(0xff00) 2630#define EEPROM_TSSI_BOUND_BG4_PLUS3 FIELD16(0xff00)
2445 2631
@@ -2449,19 +2635,20 @@ struct mac_iveiv_entry {
2449 * increased by (agc_step * 4) 2635 * increased by (agc_step * 4)
2450 * AGC_STEP: Temperature compensation step. 2636 * AGC_STEP: Temperature compensation step.
2451 */ 2637 */
2452#define EEPROM_TSSI_BOUND_BG5 0x003b
2453#define EEPROM_TSSI_BOUND_BG5_PLUS4 FIELD16(0x00ff) 2638#define EEPROM_TSSI_BOUND_BG5_PLUS4 FIELD16(0x00ff)
2454#define EEPROM_TSSI_BOUND_BG5_AGC_STEP FIELD16(0xff00) 2639#define EEPROM_TSSI_BOUND_BG5_AGC_STEP FIELD16(0xff00)
2455 2640
2456/* 2641/*
2457 * EEPROM TXPOWER 802.11A 2642 * EEPROM TXPOWER 802.11A
2458 */ 2643 */
2459#define EEPROM_TXPOWER_A1 0x003c
2460#define EEPROM_TXPOWER_A2 0x0053
2461#define EEPROM_TXPOWER_A_SIZE 6 2644#define EEPROM_TXPOWER_A_SIZE 6
2462#define EEPROM_TXPOWER_A_1 FIELD16(0x00ff) 2645#define EEPROM_TXPOWER_A_1 FIELD16(0x00ff)
2463#define EEPROM_TXPOWER_A_2 FIELD16(0xff00) 2646#define EEPROM_TXPOWER_A_2 FIELD16(0xff00)
2464 2647
2648/* EEPROM_TXPOWER_{A,G} fields for RT3593 */
2649#define EEPROM_TXPOWER_ALC FIELD8(0x1f)
2650#define EEPROM_TXPOWER_FINE_CTRL FIELD8(0xe0)
2651
2465/* 2652/*
2466 * EEPROM temperature compensation boundaries 802.11A 2653 * EEPROM temperature compensation boundaries 802.11A
2467 * MINUS4: If the actual TSSI is below this boundary, tx power needs to be 2654 * MINUS4: If the actual TSSI is below this boundary, tx power needs to be
@@ -2469,7 +2656,6 @@ struct mac_iveiv_entry {
2469 * MINUS3: If the actual TSSI is below this boundary, tx power needs to be 2656 * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
2470 * reduced by (agc_step * -3) 2657 * reduced by (agc_step * -3)
2471 */ 2658 */
2472#define EEPROM_TSSI_BOUND_A1 0x006a
2473#define EEPROM_TSSI_BOUND_A1_MINUS4 FIELD16(0x00ff) 2659#define EEPROM_TSSI_BOUND_A1_MINUS4 FIELD16(0x00ff)
2474#define EEPROM_TSSI_BOUND_A1_MINUS3 FIELD16(0xff00) 2660#define EEPROM_TSSI_BOUND_A1_MINUS3 FIELD16(0xff00)
2475 2661
@@ -2480,7 +2666,6 @@ struct mac_iveiv_entry {
2480 * MINUS1: If the actual TSSI is below this boundary, tx power needs to be 2666 * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
2481 * reduced by (agc_step * -1) 2667 * reduced by (agc_step * -1)
2482 */ 2668 */
2483#define EEPROM_TSSI_BOUND_A2 0x006b
2484#define EEPROM_TSSI_BOUND_A2_MINUS2 FIELD16(0x00ff) 2669#define EEPROM_TSSI_BOUND_A2_MINUS2 FIELD16(0x00ff)
2485#define EEPROM_TSSI_BOUND_A2_MINUS1 FIELD16(0xff00) 2670#define EEPROM_TSSI_BOUND_A2_MINUS1 FIELD16(0xff00)
2486 2671
@@ -2490,7 +2675,6 @@ struct mac_iveiv_entry {
2490 * PLUS1: If the actual TSSI is above this boundary, tx power needs to be 2675 * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
2491 * increased by (agc_step * 1) 2676 * increased by (agc_step * 1)
2492 */ 2677 */
2493#define EEPROM_TSSI_BOUND_A3 0x006c
2494#define EEPROM_TSSI_BOUND_A3_REF FIELD16(0x00ff) 2678#define EEPROM_TSSI_BOUND_A3_REF FIELD16(0x00ff)
2495#define EEPROM_TSSI_BOUND_A3_PLUS1 FIELD16(0xff00) 2679#define EEPROM_TSSI_BOUND_A3_PLUS1 FIELD16(0xff00)
2496 2680
@@ -2501,7 +2685,6 @@ struct mac_iveiv_entry {
2501 * PLUS3: If the actual TSSI is above this boundary, tx power needs to be 2685 * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
2502 * increased by (agc_step * 3) 2686 * increased by (agc_step * 3)
2503 */ 2687 */
2504#define EEPROM_TSSI_BOUND_A4 0x006d
2505#define EEPROM_TSSI_BOUND_A4_PLUS2 FIELD16(0x00ff) 2688#define EEPROM_TSSI_BOUND_A4_PLUS2 FIELD16(0x00ff)
2506#define EEPROM_TSSI_BOUND_A4_PLUS3 FIELD16(0xff00) 2689#define EEPROM_TSSI_BOUND_A4_PLUS3 FIELD16(0xff00)
2507 2690
@@ -2511,14 +2694,12 @@ struct mac_iveiv_entry {
2511 * increased by (agc_step * 4) 2694 * increased by (agc_step * 4)
2512 * AGC_STEP: Temperature compensation step. 2695 * AGC_STEP: Temperature compensation step.
2513 */ 2696 */
2514#define EEPROM_TSSI_BOUND_A5 0x006e
2515#define EEPROM_TSSI_BOUND_A5_PLUS4 FIELD16(0x00ff) 2697#define EEPROM_TSSI_BOUND_A5_PLUS4 FIELD16(0x00ff)
2516#define EEPROM_TSSI_BOUND_A5_AGC_STEP FIELD16(0xff00) 2698#define EEPROM_TSSI_BOUND_A5_AGC_STEP FIELD16(0xff00)
2517 2699
2518/* 2700/*
2519 * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode 2701 * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode
2520 */ 2702 */
2521#define EEPROM_TXPOWER_BYRATE 0x006f
2522#define EEPROM_TXPOWER_BYRATE_SIZE 9 2703#define EEPROM_TXPOWER_BYRATE_SIZE 9
2523 2704
2524#define EEPROM_TXPOWER_BYRATE_RATE0 FIELD16(0x000f) 2705#define EEPROM_TXPOWER_BYRATE_RATE0 FIELD16(0x000f)
@@ -2529,11 +2710,14 @@ struct mac_iveiv_entry {
2529/* 2710/*
2530 * EEPROM BBP. 2711 * EEPROM BBP.
2531 */ 2712 */
2532#define EEPROM_BBP_START 0x0078
2533#define EEPROM_BBP_SIZE 16 2713#define EEPROM_BBP_SIZE 16
2534#define EEPROM_BBP_VALUE FIELD16(0x00ff) 2714#define EEPROM_BBP_VALUE FIELD16(0x00ff)
2535#define EEPROM_BBP_REG_ID FIELD16(0xff00) 2715#define EEPROM_BBP_REG_ID FIELD16(0xff00)
2536 2716
2717/* EEPROM_EXT_LNA2 */
2718#define EEPROM_EXT_LNA2_A1 FIELD16(0x00ff)
2719#define EEPROM_EXT_LNA2_A2 FIELD16(0xff00)
2720
2537/* 2721/*
2538 * EEPROM IQ Calibration, unlike other entries those are byte addresses. 2722 * EEPROM IQ Calibration, unlike other entries those are byte addresses.
2539 */ 2723 */
@@ -2630,6 +2814,7 @@ struct mac_iveiv_entry {
2630#define TXWI_DESC_SIZE_5WORDS (5 * sizeof(__le32)) 2814#define TXWI_DESC_SIZE_5WORDS (5 * sizeof(__le32))
2631 2815
2632#define RXWI_DESC_SIZE_4WORDS (4 * sizeof(__le32)) 2816#define RXWI_DESC_SIZE_4WORDS (4 * sizeof(__le32))
2817#define RXWI_DESC_SIZE_5WORDS (5 * sizeof(__le32))
2633#define RXWI_DESC_SIZE_6WORDS (6 * sizeof(__le32)) 2818#define RXWI_DESC_SIZE_6WORDS (6 * sizeof(__le32))
2634 2819
2635/* 2820/*
@@ -2750,18 +2935,15 @@ struct mac_iveiv_entry {
2750#define MAX_A_TXPOWER 15 2935#define MAX_A_TXPOWER 15
2751#define DEFAULT_TXPOWER 5 2936#define DEFAULT_TXPOWER 5
2752 2937
2938#define MIN_A_TXPOWER_3593 0
2939#define MAX_A_TXPOWER_3593 31
2940
2753#define TXPOWER_G_FROM_DEV(__txpower) \ 2941#define TXPOWER_G_FROM_DEV(__txpower) \
2754 ((__txpower) > MAX_G_TXPOWER) ? DEFAULT_TXPOWER : (__txpower) 2942 ((__txpower) > MAX_G_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
2755 2943
2756#define TXPOWER_G_TO_DEV(__txpower) \
2757 clamp_t(char, __txpower, MIN_G_TXPOWER, MAX_G_TXPOWER)
2758
2759#define TXPOWER_A_FROM_DEV(__txpower) \ 2944#define TXPOWER_A_FROM_DEV(__txpower) \
2760 ((__txpower) > MAX_A_TXPOWER) ? DEFAULT_TXPOWER : (__txpower) 2945 ((__txpower) > MAX_A_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
2761 2946
2762#define TXPOWER_A_TO_DEV(__txpower) \
2763 clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER)
2764
2765/* 2947/*
2766 * Board's maximun TX power limitation 2948 * Board's maximun TX power limitation
2767 */ 2949 */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 1f80ea5e29dd..dedc3d4ae365 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -221,6 +221,157 @@ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
221 mutex_unlock(&rt2x00dev->csr_mutex); 221 mutex_unlock(&rt2x00dev->csr_mutex);
222} 222}
223 223
224static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
225 [EEPROM_CHIP_ID] = 0x0000,
226 [EEPROM_VERSION] = 0x0001,
227 [EEPROM_MAC_ADDR_0] = 0x0002,
228 [EEPROM_MAC_ADDR_1] = 0x0003,
229 [EEPROM_MAC_ADDR_2] = 0x0004,
230 [EEPROM_NIC_CONF0] = 0x001a,
231 [EEPROM_NIC_CONF1] = 0x001b,
232 [EEPROM_FREQ] = 0x001d,
233 [EEPROM_LED_AG_CONF] = 0x001e,
234 [EEPROM_LED_ACT_CONF] = 0x001f,
235 [EEPROM_LED_POLARITY] = 0x0020,
236 [EEPROM_NIC_CONF2] = 0x0021,
237 [EEPROM_LNA] = 0x0022,
238 [EEPROM_RSSI_BG] = 0x0023,
239 [EEPROM_RSSI_BG2] = 0x0024,
240 [EEPROM_TXMIXER_GAIN_BG] = 0x0024, /* overlaps with RSSI_BG2 */
241 [EEPROM_RSSI_A] = 0x0025,
242 [EEPROM_RSSI_A2] = 0x0026,
243 [EEPROM_TXMIXER_GAIN_A] = 0x0026, /* overlaps with RSSI_A2 */
244 [EEPROM_EIRP_MAX_TX_POWER] = 0x0027,
245 [EEPROM_TXPOWER_DELTA] = 0x0028,
246 [EEPROM_TXPOWER_BG1] = 0x0029,
247 [EEPROM_TXPOWER_BG2] = 0x0030,
248 [EEPROM_TSSI_BOUND_BG1] = 0x0037,
249 [EEPROM_TSSI_BOUND_BG2] = 0x0038,
250 [EEPROM_TSSI_BOUND_BG3] = 0x0039,
251 [EEPROM_TSSI_BOUND_BG4] = 0x003a,
252 [EEPROM_TSSI_BOUND_BG5] = 0x003b,
253 [EEPROM_TXPOWER_A1] = 0x003c,
254 [EEPROM_TXPOWER_A2] = 0x0053,
255 [EEPROM_TSSI_BOUND_A1] = 0x006a,
256 [EEPROM_TSSI_BOUND_A2] = 0x006b,
257 [EEPROM_TSSI_BOUND_A3] = 0x006c,
258 [EEPROM_TSSI_BOUND_A4] = 0x006d,
259 [EEPROM_TSSI_BOUND_A5] = 0x006e,
260 [EEPROM_TXPOWER_BYRATE] = 0x006f,
261 [EEPROM_BBP_START] = 0x0078,
262};
263
264static const unsigned int rt2800_eeprom_map_ext[EEPROM_WORD_COUNT] = {
265 [EEPROM_CHIP_ID] = 0x0000,
266 [EEPROM_VERSION] = 0x0001,
267 [EEPROM_MAC_ADDR_0] = 0x0002,
268 [EEPROM_MAC_ADDR_1] = 0x0003,
269 [EEPROM_MAC_ADDR_2] = 0x0004,
270 [EEPROM_NIC_CONF0] = 0x001a,
271 [EEPROM_NIC_CONF1] = 0x001b,
272 [EEPROM_NIC_CONF2] = 0x001c,
273 [EEPROM_EIRP_MAX_TX_POWER] = 0x0020,
274 [EEPROM_FREQ] = 0x0022,
275 [EEPROM_LED_AG_CONF] = 0x0023,
276 [EEPROM_LED_ACT_CONF] = 0x0024,
277 [EEPROM_LED_POLARITY] = 0x0025,
278 [EEPROM_LNA] = 0x0026,
279 [EEPROM_EXT_LNA2] = 0x0027,
280 [EEPROM_RSSI_BG] = 0x0028,
281 [EEPROM_TXPOWER_DELTA] = 0x0028, /* Overlaps with RSSI_BG */
282 [EEPROM_RSSI_BG2] = 0x0029,
283 [EEPROM_TXMIXER_GAIN_BG] = 0x0029, /* Overlaps with RSSI_BG2 */
284 [EEPROM_RSSI_A] = 0x002a,
285 [EEPROM_RSSI_A2] = 0x002b,
286 [EEPROM_TXMIXER_GAIN_A] = 0x002b, /* Overlaps with RSSI_A2 */
287 [EEPROM_TXPOWER_BG1] = 0x0030,
288 [EEPROM_TXPOWER_BG2] = 0x0037,
289 [EEPROM_EXT_TXPOWER_BG3] = 0x003e,
290 [EEPROM_TSSI_BOUND_BG1] = 0x0045,
291 [EEPROM_TSSI_BOUND_BG2] = 0x0046,
292 [EEPROM_TSSI_BOUND_BG3] = 0x0047,
293 [EEPROM_TSSI_BOUND_BG4] = 0x0048,
294 [EEPROM_TSSI_BOUND_BG5] = 0x0049,
295 [EEPROM_TXPOWER_A1] = 0x004b,
296 [EEPROM_TXPOWER_A2] = 0x0065,
297 [EEPROM_EXT_TXPOWER_A3] = 0x007f,
298 [EEPROM_TSSI_BOUND_A1] = 0x009a,
299 [EEPROM_TSSI_BOUND_A2] = 0x009b,
300 [EEPROM_TSSI_BOUND_A3] = 0x009c,
301 [EEPROM_TSSI_BOUND_A4] = 0x009d,
302 [EEPROM_TSSI_BOUND_A5] = 0x009e,
303 [EEPROM_TXPOWER_BYRATE] = 0x00a0,
304};
305
306static unsigned int rt2800_eeprom_word_index(struct rt2x00_dev *rt2x00dev,
307 const enum rt2800_eeprom_word word)
308{
309 const unsigned int *map;
310 unsigned int index;
311
312 if (WARN_ONCE(word >= EEPROM_WORD_COUNT,
313 "%s: invalid EEPROM word %d\n",
314 wiphy_name(rt2x00dev->hw->wiphy), word))
315 return 0;
316
317 if (rt2x00_rt(rt2x00dev, RT3593))
318 map = rt2800_eeprom_map_ext;
319 else
320 map = rt2800_eeprom_map;
321
322 index = map[word];
323
324 /* Index 0 is valid only for EEPROM_CHIP_ID.
325 * Otherwise it means that the offset of the
326 * given word is not initialized in the map,
327 * or that the field is not usable on the
328 * actual chipset.
329 */
330 WARN_ONCE(word != EEPROM_CHIP_ID && index == 0,
331 "%s: invalid access of EEPROM word %d\n",
332 wiphy_name(rt2x00dev->hw->wiphy), word);
333
334 return index;
335}
336
337static void *rt2800_eeprom_addr(struct rt2x00_dev *rt2x00dev,
338 const enum rt2800_eeprom_word word)
339{
340 unsigned int index;
341
342 index = rt2800_eeprom_word_index(rt2x00dev, word);
343 return rt2x00_eeprom_addr(rt2x00dev, index);
344}
345
346static void rt2800_eeprom_read(struct rt2x00_dev *rt2x00dev,
347 const enum rt2800_eeprom_word word, u16 *data)
348{
349 unsigned int index;
350
351 index = rt2800_eeprom_word_index(rt2x00dev, word);
352 rt2x00_eeprom_read(rt2x00dev, index, data);
353}
354
355static void rt2800_eeprom_write(struct rt2x00_dev *rt2x00dev,
356 const enum rt2800_eeprom_word word, u16 data)
357{
358 unsigned int index;
359
360 index = rt2800_eeprom_word_index(rt2x00dev, word);
361 rt2x00_eeprom_write(rt2x00dev, index, data);
362}
363
364static void rt2800_eeprom_read_from_array(struct rt2x00_dev *rt2x00dev,
365 const enum rt2800_eeprom_word array,
366 unsigned int offset,
367 u16 *data)
368{
369 unsigned int index;
370
371 index = rt2800_eeprom_word_index(rt2x00dev, array);
372 rt2x00_eeprom_read(rt2x00dev, index + offset, data);
373}
374
224static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev) 375static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
225{ 376{
226 u32 reg; 377 u32 reg;
@@ -609,16 +760,16 @@ static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
609 u8 offset2; 760 u8 offset2;
610 761
611 if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { 762 if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
612 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom); 763 rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom);
613 offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0); 764 offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0);
614 offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1); 765 offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1);
615 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom); 766 rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
616 offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_OFFSET2); 767 offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_OFFSET2);
617 } else { 768 } else {
618 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &eeprom); 769 rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &eeprom);
619 offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET0); 770 offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET0);
620 offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET1); 771 offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET1);
621 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom); 772 rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
622 offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_OFFSET2); 773 offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_OFFSET2);
623 } 774 }
624 775
@@ -890,6 +1041,9 @@ const struct rt2x00debug rt2800_rt2x00debug = {
890 .word_count = CSR_REG_SIZE / sizeof(u32), 1041 .word_count = CSR_REG_SIZE / sizeof(u32),
891 }, 1042 },
892 .eeprom = { 1043 .eeprom = {
1044 /* NOTE: The local EEPROM access functions can't
1045 * be used here, use the generic versions instead.
1046 */
893 .read = rt2x00_eeprom_read, 1047 .read = rt2x00_eeprom_read,
894 .write = rt2x00_eeprom_write, 1048 .write = rt2x00_eeprom_write,
895 .word_base = EEPROM_BASE, 1049 .word_base = EEPROM_BASE,
@@ -1547,7 +1701,7 @@ static void rt2800_config_3572bt_ant(struct rt2x00_dev *rt2x00dev)
1547 led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3; 1701 led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3;
1548 if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) || 1702 if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) ||
1549 led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) { 1703 led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) {
1550 rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); 1704 rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
1551 led_ctrl = rt2x00_get_field16(eeprom, EEPROM_FREQ_LED_MODE); 1705 led_ctrl = rt2x00_get_field16(eeprom, EEPROM_FREQ_LED_MODE);
1552 if (led_ctrl == 0 || led_ctrl > 0x40) { 1706 if (led_ctrl == 0 || led_ctrl > 0x40) {
1553 rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, led_g_mode); 1707 rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, led_g_mode);
@@ -1609,7 +1763,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
1609 rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2); 1763 rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
1610 break; 1764 break;
1611 case 3: 1765 case 3:
1612 rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); 1766 rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
1613 break; 1767 break;
1614 } 1768 }
1615 1769
@@ -1622,7 +1776,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
1622 rt2x00_rt(rt2x00dev, RT3090) || 1776 rt2x00_rt(rt2x00dev, RT3090) ||
1623 rt2x00_rt(rt2x00dev, RT3352) || 1777 rt2x00_rt(rt2x00dev, RT3352) ||
1624 rt2x00_rt(rt2x00dev, RT3390)) { 1778 rt2x00_rt(rt2x00dev, RT3390)) {
1625 rt2x00_eeprom_read(rt2x00dev, 1779 rt2800_eeprom_read(rt2x00dev,
1626 EEPROM_NIC_CONF1, &eeprom); 1780 EEPROM_NIC_CONF1, &eeprom);
1627 if (rt2x00_get_field16(eeprom, 1781 if (rt2x00_get_field16(eeprom,
1628 EEPROM_NIC_CONF1_ANT_DIVERSITY)) 1782 EEPROM_NIC_CONF1_ANT_DIVERSITY))
@@ -1649,6 +1803,13 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
1649 1803
1650 rt2800_bbp_write(rt2x00dev, 3, r3); 1804 rt2800_bbp_write(rt2x00dev, 3, r3);
1651 rt2800_bbp_write(rt2x00dev, 1, r1); 1805 rt2800_bbp_write(rt2x00dev, 1, r1);
1806
1807 if (rt2x00_rt(rt2x00dev, RT3593)) {
1808 if (ant->rx_chain_num == 1)
1809 rt2800_bbp_write(rt2x00dev, 86, 0x00);
1810 else
1811 rt2800_bbp_write(rt2x00dev, 86, 0x46);
1812 }
1652} 1813}
1653EXPORT_SYMBOL_GPL(rt2800_config_ant); 1814EXPORT_SYMBOL_GPL(rt2800_config_ant);
1654 1815
@@ -1659,17 +1820,31 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
1659 short lna_gain; 1820 short lna_gain;
1660 1821
1661 if (libconf->rf.channel <= 14) { 1822 if (libconf->rf.channel <= 14) {
1662 rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom); 1823 rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
1663 lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG); 1824 lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG);
1664 } else if (libconf->rf.channel <= 64) { 1825 } else if (libconf->rf.channel <= 64) {
1665 rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom); 1826 rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
1666 lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0); 1827 lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
1667 } else if (libconf->rf.channel <= 128) { 1828 } else if (libconf->rf.channel <= 128) {
1668 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom); 1829 if (rt2x00_rt(rt2x00dev, RT3593)) {
1669 lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1); 1830 rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
1831 lna_gain = rt2x00_get_field16(eeprom,
1832 EEPROM_EXT_LNA2_A1);
1833 } else {
1834 rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
1835 lna_gain = rt2x00_get_field16(eeprom,
1836 EEPROM_RSSI_BG2_LNA_A1);
1837 }
1670 } else { 1838 } else {
1671 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom); 1839 if (rt2x00_rt(rt2x00dev, RT3593)) {
1672 lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2); 1840 rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
1841 lna_gain = rt2x00_get_field16(eeprom,
1842 EEPROM_EXT_LNA2_A2);
1843 } else {
1844 rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
1845 lna_gain = rt2x00_get_field16(eeprom,
1846 EEPROM_RSSI_A2_LNA_A2);
1847 }
1673 } 1848 }
1674 1849
1675 rt2x00dev->lna_gain = lna_gain; 1850 rt2x00dev->lna_gain = lna_gain;
@@ -1993,6 +2168,303 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
1993 rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); 2168 rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
1994} 2169}
1995 2170
2171static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
2172 struct ieee80211_conf *conf,
2173 struct rf_channel *rf,
2174 struct channel_info *info)
2175{
2176 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
2177 u8 txrx_agc_fc;
2178 u8 txrx_h20m;
2179 u8 rfcsr;
2180 u8 bbp;
2181 const bool txbf_enabled = false; /* TODO */
2182
2183 /* TODO: use TX{0,1,2}FinePowerControl values from EEPROM */
2184 rt2800_bbp_read(rt2x00dev, 109, &bbp);
2185 rt2x00_set_field8(&bbp, BBP109_TX0_POWER, 0);
2186 rt2x00_set_field8(&bbp, BBP109_TX1_POWER, 0);
2187 rt2800_bbp_write(rt2x00dev, 109, bbp);
2188
2189 rt2800_bbp_read(rt2x00dev, 110, &bbp);
2190 rt2x00_set_field8(&bbp, BBP110_TX2_POWER, 0);
2191 rt2800_bbp_write(rt2x00dev, 110, bbp);
2192
2193 if (rf->channel <= 14) {
2194 /* Restore BBP 25 & 26 for 2.4 GHz */
2195 rt2800_bbp_write(rt2x00dev, 25, drv_data->bbp25);
2196 rt2800_bbp_write(rt2x00dev, 26, drv_data->bbp26);
2197 } else {
2198 /* Hard code BBP 25 & 26 for 5GHz */
2199
2200 /* Enable IQ Phase correction */
2201 rt2800_bbp_write(rt2x00dev, 25, 0x09);
2202 /* Setup IQ Phase correction value */
2203 rt2800_bbp_write(rt2x00dev, 26, 0xff);
2204 }
2205
2206 rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
2207 rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3 & 0xf);
2208
2209 rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr);
2210 rt2x00_set_field8(&rfcsr, RFCSR11_R, (rf->rf2 & 0x3));
2211 rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
2212
2213 rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr);
2214 rt2x00_set_field8(&rfcsr, RFCSR11_PLL_IDOH, 1);
2215 if (rf->channel <= 14)
2216 rt2x00_set_field8(&rfcsr, RFCSR11_PLL_MOD, 1);
2217 else
2218 rt2x00_set_field8(&rfcsr, RFCSR11_PLL_MOD, 2);
2219 rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
2220
2221 rt2800_rfcsr_read(rt2x00dev, 53, &rfcsr);
2222 if (rf->channel <= 14) {
2223 rfcsr = 0;
2224 rt2x00_set_field8(&rfcsr, RFCSR53_TX_POWER,
2225 info->default_power1 & 0x1f);
2226 } else {
2227 if (rt2x00_is_usb(rt2x00dev))
2228 rfcsr = 0x40;
2229
2230 rt2x00_set_field8(&rfcsr, RFCSR53_TX_POWER,
2231 ((info->default_power1 & 0x18) << 1) |
2232 (info->default_power1 & 7));
2233 }
2234 rt2800_rfcsr_write(rt2x00dev, 53, rfcsr);
2235
2236 rt2800_rfcsr_read(rt2x00dev, 55, &rfcsr);
2237 if (rf->channel <= 14) {
2238 rfcsr = 0;
2239 rt2x00_set_field8(&rfcsr, RFCSR55_TX_POWER,
2240 info->default_power2 & 0x1f);
2241 } else {
2242 if (rt2x00_is_usb(rt2x00dev))
2243 rfcsr = 0x40;
2244
2245 rt2x00_set_field8(&rfcsr, RFCSR55_TX_POWER,
2246 ((info->default_power2 & 0x18) << 1) |
2247 (info->default_power2 & 7));
2248 }
2249 rt2800_rfcsr_write(rt2x00dev, 55, rfcsr);
2250
2251 rt2800_rfcsr_read(rt2x00dev, 54, &rfcsr);
2252 if (rf->channel <= 14) {
2253 rfcsr = 0;
2254 rt2x00_set_field8(&rfcsr, RFCSR54_TX_POWER,
2255 info->default_power3 & 0x1f);
2256 } else {
2257 if (rt2x00_is_usb(rt2x00dev))
2258 rfcsr = 0x40;
2259
2260 rt2x00_set_field8(&rfcsr, RFCSR54_TX_POWER,
2261 ((info->default_power3 & 0x18) << 1) |
2262 (info->default_power3 & 7));
2263 }
2264 rt2800_rfcsr_write(rt2x00dev, 54, rfcsr);
2265
2266 rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
2267 rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
2268 rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
2269 rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
2270 rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
2271 rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
2272 rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
2273 rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
2274 rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
2275
2276 switch (rt2x00dev->default_ant.tx_chain_num) {
2277 case 3:
2278 rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
2279 /* fallthrough */
2280 case 2:
2281 rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
2282 /* fallthrough */
2283 case 1:
2284 rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
2285 break;
2286 }
2287
2288 switch (rt2x00dev->default_ant.rx_chain_num) {
2289 case 3:
2290 rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
2291 /* fallthrough */
2292 case 2:
2293 rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
2294 /* fallthrough */
2295 case 1:
2296 rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
2297 break;
2298 }
2299 rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
2300
2301 /* TODO: frequency calibration? */
2302
2303 if (conf_is_ht40(conf)) {
2304 txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw40,
2305 RFCSR24_TX_AGC_FC);
2306 txrx_h20m = rt2x00_get_field8(drv_data->calibration_bw40,
2307 RFCSR24_TX_H20M);
2308 } else {
2309 txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw20,
2310 RFCSR24_TX_AGC_FC);
2311 txrx_h20m = rt2x00_get_field8(drv_data->calibration_bw20,
2312 RFCSR24_TX_H20M);
2313 }
2314
2315 /* NOTE: the reference driver does not writes the new value
2316 * back to RFCSR 32
2317 */
2318 rt2800_rfcsr_read(rt2x00dev, 32, &rfcsr);
2319 rt2x00_set_field8(&rfcsr, RFCSR32_TX_AGC_FC, txrx_agc_fc);
2320
2321 if (rf->channel <= 14)
2322 rfcsr = 0xa0;
2323 else
2324 rfcsr = 0x80;
2325 rt2800_rfcsr_write(rt2x00dev, 31, rfcsr);
2326
2327 rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
2328 rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, txrx_h20m);
2329 rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, txrx_h20m);
2330 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
2331
2332 /* Band selection */
2333 rt2800_rfcsr_read(rt2x00dev, 36, &rfcsr);
2334 if (rf->channel <= 14)
2335 rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1);
2336 else
2337 rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0);
2338 rt2800_rfcsr_write(rt2x00dev, 36, rfcsr);
2339
2340 rt2800_rfcsr_read(rt2x00dev, 34, &rfcsr);
2341 if (rf->channel <= 14)
2342 rfcsr = 0x3c;
2343 else
2344 rfcsr = 0x20;
2345 rt2800_rfcsr_write(rt2x00dev, 34, rfcsr);
2346
2347 rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
2348 if (rf->channel <= 14)
2349 rfcsr = 0x1a;
2350 else
2351 rfcsr = 0x12;
2352 rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
2353
2354 rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
2355 if (rf->channel >= 1 && rf->channel <= 14)
2356 rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 1);
2357 else if (rf->channel >= 36 && rf->channel <= 64)
2358 rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 2);
2359 else if (rf->channel >= 100 && rf->channel <= 128)
2360 rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 2);
2361 else
2362 rt2x00_set_field8(&rfcsr, RFCSR6_VCO_IC, 1);
2363 rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
2364
2365 rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
2366 rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2);
2367 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
2368
2369 rt2800_rfcsr_write(rt2x00dev, 46, 0x60);
2370
2371 if (rf->channel <= 14) {
2372 rt2800_rfcsr_write(rt2x00dev, 10, 0xd3);
2373 rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
2374 } else {
2375 rt2800_rfcsr_write(rt2x00dev, 10, 0xd8);
2376 rt2800_rfcsr_write(rt2x00dev, 13, 0x23);
2377 }
2378
2379 rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
2380 rt2x00_set_field8(&rfcsr, RFCSR51_BITS01, 1);
2381 rt2800_rfcsr_write(rt2x00dev, 51, rfcsr);
2382
2383 rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
2384 if (rf->channel <= 14) {
2385 rt2x00_set_field8(&rfcsr, RFCSR51_BITS24, 5);
2386 rt2x00_set_field8(&rfcsr, RFCSR51_BITS57, 3);
2387 } else {
2388 rt2x00_set_field8(&rfcsr, RFCSR51_BITS24, 4);
2389 rt2x00_set_field8(&rfcsr, RFCSR51_BITS57, 2);
2390 }
2391 rt2800_rfcsr_write(rt2x00dev, 51, rfcsr);
2392
2393 rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr);
2394 if (rf->channel <= 14)
2395 rt2x00_set_field8(&rfcsr, RFCSR49_TX_LO1_IC, 3);
2396 else
2397 rt2x00_set_field8(&rfcsr, RFCSR49_TX_LO1_IC, 2);
2398
2399 if (txbf_enabled)
2400 rt2x00_set_field8(&rfcsr, RFCSR49_TX_DIV, 1);
2401
2402 rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
2403
2404 rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
2405 rt2x00_set_field8(&rfcsr, RFCSR50_TX_LO1_EN, 0);
2406 rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
2407
2408 rt2800_rfcsr_read(rt2x00dev, 57, &rfcsr);
2409 if (rf->channel <= 14)
2410 rt2x00_set_field8(&rfcsr, RFCSR57_DRV_CC, 0x1b);
2411 else
2412 rt2x00_set_field8(&rfcsr, RFCSR57_DRV_CC, 0x0f);
2413 rt2800_rfcsr_write(rt2x00dev, 57, rfcsr);
2414
2415 if (rf->channel <= 14) {
2416 rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
2417 rt2800_rfcsr_write(rt2x00dev, 52, 0x45);
2418 } else {
2419 rt2800_rfcsr_write(rt2x00dev, 44, 0x9b);
2420 rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
2421 }
2422
2423 /* Initiate VCO calibration */
2424 rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
2425 if (rf->channel <= 14) {
2426 rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
2427 } else {
2428 rt2x00_set_field8(&rfcsr, RFCSR3_BIT1, 1);
2429 rt2x00_set_field8(&rfcsr, RFCSR3_BIT2, 1);
2430 rt2x00_set_field8(&rfcsr, RFCSR3_BIT3, 1);
2431 rt2x00_set_field8(&rfcsr, RFCSR3_BIT4, 1);
2432 rt2x00_set_field8(&rfcsr, RFCSR3_BIT5, 1);
2433 rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
2434 }
2435 rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
2436
2437 if (rf->channel >= 1 && rf->channel <= 14) {
2438 rfcsr = 0x23;
2439 if (txbf_enabled)
2440 rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
2441 rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
2442
2443 rt2800_rfcsr_write(rt2x00dev, 45, 0xbb);
2444 } else if (rf->channel >= 36 && rf->channel <= 64) {
2445 rfcsr = 0x36;
2446 if (txbf_enabled)
2447 rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
2448 rt2800_rfcsr_write(rt2x00dev, 39, 0x36);
2449
2450 rt2800_rfcsr_write(rt2x00dev, 45, 0xeb);
2451 } else if (rf->channel >= 100 && rf->channel <= 128) {
2452 rfcsr = 0x32;
2453 if (txbf_enabled)
2454 rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
2455 rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
2456
2457 rt2800_rfcsr_write(rt2x00dev, 45, 0xb3);
2458 } else {
2459 rfcsr = 0x30;
2460 if (txbf_enabled)
2461 rt2x00_set_field8(&rfcsr, RFCSR39_RX_DIV, 1);
2462 rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
2463
2464 rt2800_rfcsr_write(rt2x00dev, 45, 0x9b);
2465 }
2466}
2467
1996#define POWER_BOUND 0x27 2468#define POWER_BOUND 0x27
1997#define POWER_BOUND_5G 0x2b 2469#define POWER_BOUND_5G 0x2b
1998#define FREQ_OFFSET_BOUND 0x5f 2470#define FREQ_OFFSET_BOUND 0x5f
@@ -2563,6 +3035,23 @@ static void rt2800_iq_calibrate(struct rt2x00_dev *rt2x00dev, int channel)
2563 rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0); 3035 rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0);
2564} 3036}
2565 3037
3038static char rt2800_txpower_to_dev(struct rt2x00_dev *rt2x00dev,
3039 unsigned int channel,
3040 char txpower)
3041{
3042 if (rt2x00_rt(rt2x00dev, RT3593))
3043 txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC);
3044
3045 if (channel <= 14)
3046 return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER);
3047
3048 if (rt2x00_rt(rt2x00dev, RT3593))
3049 return clamp_t(char, txpower, MIN_A_TXPOWER_3593,
3050 MAX_A_TXPOWER_3593);
3051 else
3052 return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
3053}
3054
2566static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, 3055static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2567 struct ieee80211_conf *conf, 3056 struct ieee80211_conf *conf,
2568 struct rf_channel *rf, 3057 struct rf_channel *rf,
@@ -2572,13 +3061,14 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2572 unsigned int tx_pin; 3061 unsigned int tx_pin;
2573 u8 bbp, rfcsr; 3062 u8 bbp, rfcsr;
2574 3063
2575 if (rf->channel <= 14) { 3064 info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
2576 info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1); 3065 info->default_power1);
2577 info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2); 3066 info->default_power2 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
2578 } else { 3067 info->default_power2);
2579 info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1); 3068 if (rt2x00dev->default_ant.tx_chain_num > 2)
2580 info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2); 3069 info->default_power3 =
2581 } 3070 rt2800_txpower_to_dev(rt2x00dev, rf->channel,
3071 info->default_power3);
2582 3072
2583 switch (rt2x00dev->chip.rf) { 3073 switch (rt2x00dev->chip.rf) {
2584 case RF2020: 3074 case RF2020:
@@ -2591,6 +3081,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2591 case RF3052: 3081 case RF3052:
2592 rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); 3082 rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
2593 break; 3083 break;
3084 case RF3053:
3085 rt2800_config_channel_rf3053(rt2x00dev, conf, rf, info);
3086 break;
2594 case RF3290: 3087 case RF3290:
2595 rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info); 3088 rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info);
2596 break; 3089 break;
@@ -2636,6 +3129,23 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2636 rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); 3129 rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
2637 rt2800_bbp_write(rt2x00dev, 27, 0x20); 3130 rt2800_bbp_write(rt2x00dev, 27, 0x20);
2638 rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); 3131 rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
3132 } else if (rt2x00_rt(rt2x00dev, RT3593)) {
3133 if (rf->channel > 14) {
3134 /* Disable CCK Packet detection on 5GHz */
3135 rt2800_bbp_write(rt2x00dev, 70, 0x00);
3136 } else {
3137 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
3138 }
3139
3140 if (conf_is_ht40(conf))
3141 rt2800_bbp_write(rt2x00dev, 105, 0x04);
3142 else
3143 rt2800_bbp_write(rt2x00dev, 105, 0x34);
3144
3145 rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
3146 rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
3147 rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
3148 rt2800_bbp_write(rt2x00dev, 77, 0x98);
2639 } else { 3149 } else {
2640 rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); 3150 rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
2641 rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); 3151 rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
@@ -2651,16 +3161,27 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2651 rt2800_bbp_write(rt2x00dev, 82, 0x62); 3161 rt2800_bbp_write(rt2x00dev, 82, 0x62);
2652 rt2800_bbp_write(rt2x00dev, 75, 0x46); 3162 rt2800_bbp_write(rt2x00dev, 75, 0x46);
2653 } else { 3163 } else {
2654 rt2800_bbp_write(rt2x00dev, 82, 0x84); 3164 if (rt2x00_rt(rt2x00dev, RT3593))
3165 rt2800_bbp_write(rt2x00dev, 82, 0x62);
3166 else
3167 rt2800_bbp_write(rt2x00dev, 82, 0x84);
2655 rt2800_bbp_write(rt2x00dev, 75, 0x50); 3168 rt2800_bbp_write(rt2x00dev, 75, 0x50);
2656 } 3169 }
3170 if (rt2x00_rt(rt2x00dev, RT3593))
3171 rt2800_bbp_write(rt2x00dev, 83, 0x8a);
2657 } 3172 }
3173
2658 } else { 3174 } else {
2659 if (rt2x00_rt(rt2x00dev, RT3572)) 3175 if (rt2x00_rt(rt2x00dev, RT3572))
2660 rt2800_bbp_write(rt2x00dev, 82, 0x94); 3176 rt2800_bbp_write(rt2x00dev, 82, 0x94);
3177 else if (rt2x00_rt(rt2x00dev, RT3593))
3178 rt2800_bbp_write(rt2x00dev, 82, 0x82);
2661 else 3179 else
2662 rt2800_bbp_write(rt2x00dev, 82, 0xf2); 3180 rt2800_bbp_write(rt2x00dev, 82, 0xf2);
2663 3181
3182 if (rt2x00_rt(rt2x00dev, RT3593))
3183 rt2800_bbp_write(rt2x00dev, 83, 0x9a);
3184
2664 if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) 3185 if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
2665 rt2800_bbp_write(rt2x00dev, 75, 0x46); 3186 rt2800_bbp_write(rt2x00dev, 75, 0x46);
2666 else 3187 else
@@ -2731,6 +3252,41 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2731 if (rt2x00_rt(rt2x00dev, RT3572)) 3252 if (rt2x00_rt(rt2x00dev, RT3572))
2732 rt2800_rfcsr_write(rt2x00dev, 8, 0x80); 3253 rt2800_rfcsr_write(rt2x00dev, 8, 0x80);
2733 3254
3255 if (rt2x00_rt(rt2x00dev, RT3593)) {
3256 if (rt2x00_is_usb(rt2x00dev)) {
3257 rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
3258
3259 /* Band selection. GPIO #8 controls all paths */
3260 rt2x00_set_field32(&reg, GPIO_CTRL_DIR8, 0);
3261 if (rf->channel <= 14)
3262 rt2x00_set_field32(&reg, GPIO_CTRL_VAL8, 1);
3263 else
3264 rt2x00_set_field32(&reg, GPIO_CTRL_VAL8, 0);
3265
3266 rt2x00_set_field32(&reg, GPIO_CTRL_DIR4, 0);
3267 rt2x00_set_field32(&reg, GPIO_CTRL_DIR7, 0);
3268
3269 /* LNA PE control.
3270 * GPIO #4 controls PE0 and PE1,
3271 * GPIO #7 controls PE2
3272 */
3273 rt2x00_set_field32(&reg, GPIO_CTRL_VAL4, 1);
3274 rt2x00_set_field32(&reg, GPIO_CTRL_VAL7, 1);
3275
3276 rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
3277 }
3278
3279 /* AGC init */
3280 if (rf->channel <= 14)
3281 reg = 0x1c + 2 * rt2x00dev->lna_gain;
3282 else
3283 reg = 0x22 + ((rt2x00dev->lna_gain * 5) / 3);
3284
3285 rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
3286
3287 usleep_range(1000, 1500);
3288 }
3289
2734 if (rt2x00_rt(rt2x00dev, RT5592)) { 3290 if (rt2x00_rt(rt2x00dev, RT5592)) {
2735 rt2800_bbp_write(rt2x00dev, 195, 141); 3291 rt2800_bbp_write(rt2x00dev, 195, 141);
2736 rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a); 3292 rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a);
@@ -2798,62 +3354,62 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
2798 * Example TSSI bounds 0xF0 0xD0 0xB5 0xA0 0x88 0x45 0x25 0x15 0x00 3354 * Example TSSI bounds 0xF0 0xD0 0xB5 0xA0 0x88 0x45 0x25 0x15 0x00
2799 */ 3355 */
2800 if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { 3356 if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
2801 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom); 3357 rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom);
2802 tssi_bounds[0] = rt2x00_get_field16(eeprom, 3358 tssi_bounds[0] = rt2x00_get_field16(eeprom,
2803 EEPROM_TSSI_BOUND_BG1_MINUS4); 3359 EEPROM_TSSI_BOUND_BG1_MINUS4);
2804 tssi_bounds[1] = rt2x00_get_field16(eeprom, 3360 tssi_bounds[1] = rt2x00_get_field16(eeprom,
2805 EEPROM_TSSI_BOUND_BG1_MINUS3); 3361 EEPROM_TSSI_BOUND_BG1_MINUS3);
2806 3362
2807 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom); 3363 rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom);
2808 tssi_bounds[2] = rt2x00_get_field16(eeprom, 3364 tssi_bounds[2] = rt2x00_get_field16(eeprom,
2809 EEPROM_TSSI_BOUND_BG2_MINUS2); 3365 EEPROM_TSSI_BOUND_BG2_MINUS2);
2810 tssi_bounds[3] = rt2x00_get_field16(eeprom, 3366 tssi_bounds[3] = rt2x00_get_field16(eeprom,
2811 EEPROM_TSSI_BOUND_BG2_MINUS1); 3367 EEPROM_TSSI_BOUND_BG2_MINUS1);
2812 3368
2813 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom); 3369 rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom);
2814 tssi_bounds[4] = rt2x00_get_field16(eeprom, 3370 tssi_bounds[4] = rt2x00_get_field16(eeprom,
2815 EEPROM_TSSI_BOUND_BG3_REF); 3371 EEPROM_TSSI_BOUND_BG3_REF);
2816 tssi_bounds[5] = rt2x00_get_field16(eeprom, 3372 tssi_bounds[5] = rt2x00_get_field16(eeprom,
2817 EEPROM_TSSI_BOUND_BG3_PLUS1); 3373 EEPROM_TSSI_BOUND_BG3_PLUS1);
2818 3374
2819 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom); 3375 rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom);
2820 tssi_bounds[6] = rt2x00_get_field16(eeprom, 3376 tssi_bounds[6] = rt2x00_get_field16(eeprom,
2821 EEPROM_TSSI_BOUND_BG4_PLUS2); 3377 EEPROM_TSSI_BOUND_BG4_PLUS2);
2822 tssi_bounds[7] = rt2x00_get_field16(eeprom, 3378 tssi_bounds[7] = rt2x00_get_field16(eeprom,
2823 EEPROM_TSSI_BOUND_BG4_PLUS3); 3379 EEPROM_TSSI_BOUND_BG4_PLUS3);
2824 3380
2825 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom); 3381 rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom);
2826 tssi_bounds[8] = rt2x00_get_field16(eeprom, 3382 tssi_bounds[8] = rt2x00_get_field16(eeprom,
2827 EEPROM_TSSI_BOUND_BG5_PLUS4); 3383 EEPROM_TSSI_BOUND_BG5_PLUS4);
2828 3384
2829 step = rt2x00_get_field16(eeprom, 3385 step = rt2x00_get_field16(eeprom,
2830 EEPROM_TSSI_BOUND_BG5_AGC_STEP); 3386 EEPROM_TSSI_BOUND_BG5_AGC_STEP);
2831 } else { 3387 } else {
2832 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom); 3388 rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom);
2833 tssi_bounds[0] = rt2x00_get_field16(eeprom, 3389 tssi_bounds[0] = rt2x00_get_field16(eeprom,
2834 EEPROM_TSSI_BOUND_A1_MINUS4); 3390 EEPROM_TSSI_BOUND_A1_MINUS4);
2835 tssi_bounds[1] = rt2x00_get_field16(eeprom, 3391 tssi_bounds[1] = rt2x00_get_field16(eeprom,
2836 EEPROM_TSSI_BOUND_A1_MINUS3); 3392 EEPROM_TSSI_BOUND_A1_MINUS3);
2837 3393
2838 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom); 3394 rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom);
2839 tssi_bounds[2] = rt2x00_get_field16(eeprom, 3395 tssi_bounds[2] = rt2x00_get_field16(eeprom,
2840 EEPROM_TSSI_BOUND_A2_MINUS2); 3396 EEPROM_TSSI_BOUND_A2_MINUS2);
2841 tssi_bounds[3] = rt2x00_get_field16(eeprom, 3397 tssi_bounds[3] = rt2x00_get_field16(eeprom,
2842 EEPROM_TSSI_BOUND_A2_MINUS1); 3398 EEPROM_TSSI_BOUND_A2_MINUS1);
2843 3399
2844 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom); 3400 rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom);
2845 tssi_bounds[4] = rt2x00_get_field16(eeprom, 3401 tssi_bounds[4] = rt2x00_get_field16(eeprom,
2846 EEPROM_TSSI_BOUND_A3_REF); 3402 EEPROM_TSSI_BOUND_A3_REF);
2847 tssi_bounds[5] = rt2x00_get_field16(eeprom, 3403 tssi_bounds[5] = rt2x00_get_field16(eeprom,
2848 EEPROM_TSSI_BOUND_A3_PLUS1); 3404 EEPROM_TSSI_BOUND_A3_PLUS1);
2849 3405
2850 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom); 3406 rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom);
2851 tssi_bounds[6] = rt2x00_get_field16(eeprom, 3407 tssi_bounds[6] = rt2x00_get_field16(eeprom,
2852 EEPROM_TSSI_BOUND_A4_PLUS2); 3408 EEPROM_TSSI_BOUND_A4_PLUS2);
2853 tssi_bounds[7] = rt2x00_get_field16(eeprom, 3409 tssi_bounds[7] = rt2x00_get_field16(eeprom,
2854 EEPROM_TSSI_BOUND_A4_PLUS3); 3410 EEPROM_TSSI_BOUND_A4_PLUS3);
2855 3411
2856 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom); 3412 rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom);
2857 tssi_bounds[8] = rt2x00_get_field16(eeprom, 3413 tssi_bounds[8] = rt2x00_get_field16(eeprom,
2858 EEPROM_TSSI_BOUND_A5_PLUS4); 3414 EEPROM_TSSI_BOUND_A5_PLUS4);
2859 3415
@@ -2899,7 +3455,7 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev,
2899 u8 comp_type; 3455 u8 comp_type;
2900 int comp_value = 0; 3456 int comp_value = 0;
2901 3457
2902 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom); 3458 rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
2903 3459
2904 /* 3460 /*
2905 * HT40 compensation not required. 3461 * HT40 compensation not required.
@@ -2966,6 +3522,9 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
2966 u8 eirp_txpower_criterion; 3522 u8 eirp_txpower_criterion;
2967 u8 reg_limit; 3523 u8 reg_limit;
2968 3524
3525 if (rt2x00_rt(rt2x00dev, RT3593))
3526 return min_t(u8, txpower, 0xc);
3527
2969 if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) { 3528 if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) {
2970 /* 3529 /*
2971 * Check if eirp txpower exceed txpower_limit. 3530 * Check if eirp txpower exceed txpower_limit.
@@ -2974,12 +3533,12 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
2974 * .11b data rate need add additional 4dbm 3533 * .11b data rate need add additional 4dbm
2975 * when calculating eirp txpower. 3534 * when calculating eirp txpower.
2976 */ 3535 */
2977 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1, 3536 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
2978 &eeprom); 3537 1, &eeprom);
2979 criterion = rt2x00_get_field16(eeprom, 3538 criterion = rt2x00_get_field16(eeprom,
2980 EEPROM_TXPOWER_BYRATE_RATE0); 3539 EEPROM_TXPOWER_BYRATE_RATE0);
2981 3540
2982 rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, 3541 rt2800_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER,
2983 &eeprom); 3542 &eeprom);
2984 3543
2985 if (band == IEEE80211_BAND_2GHZ) 3544 if (band == IEEE80211_BAND_2GHZ)
@@ -3001,6 +3560,412 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
3001 return min_t(u8, txpower, 0xc); 3560 return min_t(u8, txpower, 0xc);
3002} 3561}
3003 3562
3563
3564enum {
3565 TX_PWR_CFG_0_IDX,
3566 TX_PWR_CFG_1_IDX,
3567 TX_PWR_CFG_2_IDX,
3568 TX_PWR_CFG_3_IDX,
3569 TX_PWR_CFG_4_IDX,
3570 TX_PWR_CFG_5_IDX,
3571 TX_PWR_CFG_6_IDX,
3572 TX_PWR_CFG_7_IDX,
3573 TX_PWR_CFG_8_IDX,
3574 TX_PWR_CFG_9_IDX,
3575 TX_PWR_CFG_0_EXT_IDX,
3576 TX_PWR_CFG_1_EXT_IDX,
3577 TX_PWR_CFG_2_EXT_IDX,
3578 TX_PWR_CFG_3_EXT_IDX,
3579 TX_PWR_CFG_4_EXT_IDX,
3580 TX_PWR_CFG_IDX_COUNT,
3581};
3582
3583static void rt2800_config_txpower_rt3593(struct rt2x00_dev *rt2x00dev,
3584 struct ieee80211_channel *chan,
3585 int power_level)
3586{
3587 u8 txpower;
3588 u16 eeprom;
3589 u32 regs[TX_PWR_CFG_IDX_COUNT];
3590 unsigned int offset;
3591 enum ieee80211_band band = chan->band;
3592 int delta;
3593 int i;
3594
3595 memset(regs, '\0', sizeof(regs));
3596
3597 /* TODO: adapt TX power reduction from the rt28xx code */
3598
3599 /* calculate temperature compensation delta */
3600 delta = rt2800_get_gain_calibration_delta(rt2x00dev);
3601
3602 if (band == IEEE80211_BAND_5GHZ)
3603 offset = 16;
3604 else
3605 offset = 0;
3606
3607 if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
3608 offset += 8;
3609
3610 /* read the next four txpower values */
3611 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
3612 offset, &eeprom);
3613
3614 /* CCK 1MBS,2MBS */
3615 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
3616 txpower = rt2800_compensate_txpower(rt2x00dev, 1, band, power_level,
3617 txpower, delta);
3618 rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
3619 TX_PWR_CFG_0_CCK1_CH0, txpower);
3620 rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
3621 TX_PWR_CFG_0_CCK1_CH1, txpower);
3622 rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
3623 TX_PWR_CFG_0_EXT_CCK1_CH2, txpower);
3624
3625 /* CCK 5.5MBS,11MBS */
3626 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
3627 txpower = rt2800_compensate_txpower(rt2x00dev, 1, band, power_level,
3628 txpower, delta);
3629 rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
3630 TX_PWR_CFG_0_CCK5_CH0, txpower);
3631 rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
3632 TX_PWR_CFG_0_CCK5_CH1, txpower);
3633 rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
3634 TX_PWR_CFG_0_EXT_CCK5_CH2, txpower);
3635
3636 /* OFDM 6MBS,9MBS */
3637 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
3638 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3639 txpower, delta);
3640 rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
3641 TX_PWR_CFG_0_OFDM6_CH0, txpower);
3642 rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
3643 TX_PWR_CFG_0_OFDM6_CH1, txpower);
3644 rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
3645 TX_PWR_CFG_0_EXT_OFDM6_CH2, txpower);
3646
3647 /* OFDM 12MBS,18MBS */
3648 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
3649 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3650 txpower, delta);
3651 rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
3652 TX_PWR_CFG_0_OFDM12_CH0, txpower);
3653 rt2x00_set_field32(&regs[TX_PWR_CFG_0_IDX],
3654 TX_PWR_CFG_0_OFDM12_CH1, txpower);
3655 rt2x00_set_field32(&regs[TX_PWR_CFG_0_EXT_IDX],
3656 TX_PWR_CFG_0_EXT_OFDM12_CH2, txpower);
3657
3658 /* read the next four txpower values */
3659 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
3660 offset + 1, &eeprom);
3661
3662 /* OFDM 24MBS,36MBS */
3663 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
3664 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3665 txpower, delta);
3666 rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
3667 TX_PWR_CFG_1_OFDM24_CH0, txpower);
3668 rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
3669 TX_PWR_CFG_1_OFDM24_CH1, txpower);
3670 rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
3671 TX_PWR_CFG_1_EXT_OFDM24_CH2, txpower);
3672
3673 /* OFDM 48MBS */
3674 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
3675 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3676 txpower, delta);
3677 rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
3678 TX_PWR_CFG_1_OFDM48_CH0, txpower);
3679 rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
3680 TX_PWR_CFG_1_OFDM48_CH1, txpower);
3681 rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
3682 TX_PWR_CFG_1_EXT_OFDM48_CH2, txpower);
3683
3684 /* OFDM 54MBS */
3685 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
3686 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3687 txpower, delta);
3688 rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
3689 TX_PWR_CFG_7_OFDM54_CH0, txpower);
3690 rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
3691 TX_PWR_CFG_7_OFDM54_CH1, txpower);
3692 rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
3693 TX_PWR_CFG_7_OFDM54_CH2, txpower);
3694
3695 /* read the next four txpower values */
3696 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
3697 offset + 2, &eeprom);
3698
3699 /* MCS 0,1 */
3700 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
3701 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3702 txpower, delta);
3703 rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
3704 TX_PWR_CFG_1_MCS0_CH0, txpower);
3705 rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
3706 TX_PWR_CFG_1_MCS0_CH1, txpower);
3707 rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
3708 TX_PWR_CFG_1_EXT_MCS0_CH2, txpower);
3709
3710 /* MCS 2,3 */
3711 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
3712 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3713 txpower, delta);
3714 rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
3715 TX_PWR_CFG_1_MCS2_CH0, txpower);
3716 rt2x00_set_field32(&regs[TX_PWR_CFG_1_IDX],
3717 TX_PWR_CFG_1_MCS2_CH1, txpower);
3718 rt2x00_set_field32(&regs[TX_PWR_CFG_1_EXT_IDX],
3719 TX_PWR_CFG_1_EXT_MCS2_CH2, txpower);
3720
3721 /* MCS 4,5 */
3722 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
3723 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3724 txpower, delta);
3725 rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
3726 TX_PWR_CFG_2_MCS4_CH0, txpower);
3727 rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
3728 TX_PWR_CFG_2_MCS4_CH1, txpower);
3729 rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
3730 TX_PWR_CFG_2_EXT_MCS4_CH2, txpower);
3731
3732 /* MCS 6 */
3733 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
3734 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3735 txpower, delta);
3736 rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
3737 TX_PWR_CFG_2_MCS6_CH0, txpower);
3738 rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
3739 TX_PWR_CFG_2_MCS6_CH1, txpower);
3740 rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
3741 TX_PWR_CFG_2_EXT_MCS6_CH2, txpower);
3742
3743 /* read the next four txpower values */
3744 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
3745 offset + 3, &eeprom);
3746
3747 /* MCS 7 */
3748 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
3749 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3750 txpower, delta);
3751 rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
3752 TX_PWR_CFG_7_MCS7_CH0, txpower);
3753 rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
3754 TX_PWR_CFG_7_MCS7_CH1, txpower);
3755 rt2x00_set_field32(&regs[TX_PWR_CFG_7_IDX],
3756 TX_PWR_CFG_7_MCS7_CH2, txpower);
3757
3758 /* MCS 8,9 */
3759 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
3760 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3761 txpower, delta);
3762 rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
3763 TX_PWR_CFG_2_MCS8_CH0, txpower);
3764 rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
3765 TX_PWR_CFG_2_MCS8_CH1, txpower);
3766 rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
3767 TX_PWR_CFG_2_EXT_MCS8_CH2, txpower);
3768
3769 /* MCS 10,11 */
3770 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
3771 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3772 txpower, delta);
3773 rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
3774 TX_PWR_CFG_2_MCS10_CH0, txpower);
3775 rt2x00_set_field32(&regs[TX_PWR_CFG_2_IDX],
3776 TX_PWR_CFG_2_MCS10_CH1, txpower);
3777 rt2x00_set_field32(&regs[TX_PWR_CFG_2_EXT_IDX],
3778 TX_PWR_CFG_2_EXT_MCS10_CH2, txpower);
3779
3780 /* MCS 12,13 */
3781 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
3782 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3783 txpower, delta);
3784 rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
3785 TX_PWR_CFG_3_MCS12_CH0, txpower);
3786 rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
3787 TX_PWR_CFG_3_MCS12_CH1, txpower);
3788 rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
3789 TX_PWR_CFG_3_EXT_MCS12_CH2, txpower);
3790
3791 /* read the next four txpower values */
3792 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
3793 offset + 4, &eeprom);
3794
3795 /* MCS 14 */
3796 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
3797 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3798 txpower, delta);
3799 rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
3800 TX_PWR_CFG_3_MCS14_CH0, txpower);
3801 rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
3802 TX_PWR_CFG_3_MCS14_CH1, txpower);
3803 rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
3804 TX_PWR_CFG_3_EXT_MCS14_CH2, txpower);
3805
3806 /* MCS 15 */
3807 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
3808 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3809 txpower, delta);
3810 rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
3811 TX_PWR_CFG_8_MCS15_CH0, txpower);
3812 rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
3813 TX_PWR_CFG_8_MCS15_CH1, txpower);
3814 rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
3815 TX_PWR_CFG_8_MCS15_CH2, txpower);
3816
3817 /* MCS 16,17 */
3818 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
3819 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3820 txpower, delta);
3821 rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
3822 TX_PWR_CFG_5_MCS16_CH0, txpower);
3823 rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
3824 TX_PWR_CFG_5_MCS16_CH1, txpower);
3825 rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
3826 TX_PWR_CFG_5_MCS16_CH2, txpower);
3827
3828 /* MCS 18,19 */
3829 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
3830 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3831 txpower, delta);
3832 rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
3833 TX_PWR_CFG_5_MCS18_CH0, txpower);
3834 rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
3835 TX_PWR_CFG_5_MCS18_CH1, txpower);
3836 rt2x00_set_field32(&regs[TX_PWR_CFG_5_IDX],
3837 TX_PWR_CFG_5_MCS18_CH2, txpower);
3838
3839 /* read the next four txpower values */
3840 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
3841 offset + 5, &eeprom);
3842
3843 /* MCS 20,21 */
3844 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
3845 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3846 txpower, delta);
3847 rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
3848 TX_PWR_CFG_6_MCS20_CH0, txpower);
3849 rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
3850 TX_PWR_CFG_6_MCS20_CH1, txpower);
3851 rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
3852 TX_PWR_CFG_6_MCS20_CH2, txpower);
3853
3854 /* MCS 22 */
3855 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
3856 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3857 txpower, delta);
3858 rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
3859 TX_PWR_CFG_6_MCS22_CH0, txpower);
3860 rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
3861 TX_PWR_CFG_6_MCS22_CH1, txpower);
3862 rt2x00_set_field32(&regs[TX_PWR_CFG_6_IDX],
3863 TX_PWR_CFG_6_MCS22_CH2, txpower);
3864
3865 /* MCS 23 */
3866 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
3867 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3868 txpower, delta);
3869 rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
3870 TX_PWR_CFG_8_MCS23_CH0, txpower);
3871 rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
3872 TX_PWR_CFG_8_MCS23_CH1, txpower);
3873 rt2x00_set_field32(&regs[TX_PWR_CFG_8_IDX],
3874 TX_PWR_CFG_8_MCS23_CH2, txpower);
3875
3876 /* read the next four txpower values */
3877 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
3878 offset + 6, &eeprom);
3879
3880 /* STBC, MCS 0,1 */
3881 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
3882 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3883 txpower, delta);
3884 rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
3885 TX_PWR_CFG_3_STBC0_CH0, txpower);
3886 rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
3887 TX_PWR_CFG_3_STBC0_CH1, txpower);
3888 rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
3889 TX_PWR_CFG_3_EXT_STBC0_CH2, txpower);
3890
3891 /* STBC, MCS 2,3 */
3892 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1);
3893 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3894 txpower, delta);
3895 rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
3896 TX_PWR_CFG_3_STBC2_CH0, txpower);
3897 rt2x00_set_field32(&regs[TX_PWR_CFG_3_IDX],
3898 TX_PWR_CFG_3_STBC2_CH1, txpower);
3899 rt2x00_set_field32(&regs[TX_PWR_CFG_3_EXT_IDX],
3900 TX_PWR_CFG_3_EXT_STBC2_CH2, txpower);
3901
3902 /* STBC, MCS 4,5 */
3903 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2);
3904 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3905 txpower, delta);
3906 rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE0, txpower);
3907 rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE1, txpower);
3908 rt2x00_set_field32(&regs[TX_PWR_CFG_4_EXT_IDX], TX_PWR_CFG_RATE0,
3909 txpower);
3910
3911 /* STBC, MCS 6 */
3912 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3);
3913 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3914 txpower, delta);
3915 rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE2, txpower);
3916 rt2x00_set_field32(&regs[TX_PWR_CFG_4_IDX], TX_PWR_CFG_RATE3, txpower);
3917 rt2x00_set_field32(&regs[TX_PWR_CFG_4_EXT_IDX], TX_PWR_CFG_RATE2,
3918 txpower);
3919
3920 /* read the next four txpower values */
3921 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
3922 offset + 7, &eeprom);
3923
3924 /* STBC, MCS 7 */
3925 txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0);
3926 txpower = rt2800_compensate_txpower(rt2x00dev, 0, band, power_level,
3927 txpower, delta);
3928 rt2x00_set_field32(&regs[TX_PWR_CFG_9_IDX],
3929 TX_PWR_CFG_9_STBC7_CH0, txpower);
3930 rt2x00_set_field32(&regs[TX_PWR_CFG_9_IDX],
3931 TX_PWR_CFG_9_STBC7_CH1, txpower);
3932 rt2x00_set_field32(&regs[TX_PWR_CFG_9_IDX],
3933 TX_PWR_CFG_9_STBC7_CH2, txpower);
3934
3935 rt2800_register_write(rt2x00dev, TX_PWR_CFG_0, regs[TX_PWR_CFG_0_IDX]);
3936 rt2800_register_write(rt2x00dev, TX_PWR_CFG_1, regs[TX_PWR_CFG_1_IDX]);
3937 rt2800_register_write(rt2x00dev, TX_PWR_CFG_2, regs[TX_PWR_CFG_2_IDX]);
3938 rt2800_register_write(rt2x00dev, TX_PWR_CFG_3, regs[TX_PWR_CFG_3_IDX]);
3939 rt2800_register_write(rt2x00dev, TX_PWR_CFG_4, regs[TX_PWR_CFG_4_IDX]);
3940 rt2800_register_write(rt2x00dev, TX_PWR_CFG_5, regs[TX_PWR_CFG_5_IDX]);
3941 rt2800_register_write(rt2x00dev, TX_PWR_CFG_6, regs[TX_PWR_CFG_6_IDX]);
3942 rt2800_register_write(rt2x00dev, TX_PWR_CFG_7, regs[TX_PWR_CFG_7_IDX]);
3943 rt2800_register_write(rt2x00dev, TX_PWR_CFG_8, regs[TX_PWR_CFG_8_IDX]);
3944 rt2800_register_write(rt2x00dev, TX_PWR_CFG_9, regs[TX_PWR_CFG_9_IDX]);
3945
3946 rt2800_register_write(rt2x00dev, TX_PWR_CFG_0_EXT,
3947 regs[TX_PWR_CFG_0_EXT_IDX]);
3948 rt2800_register_write(rt2x00dev, TX_PWR_CFG_1_EXT,
3949 regs[TX_PWR_CFG_1_EXT_IDX]);
3950 rt2800_register_write(rt2x00dev, TX_PWR_CFG_2_EXT,
3951 regs[TX_PWR_CFG_2_EXT_IDX]);
3952 rt2800_register_write(rt2x00dev, TX_PWR_CFG_3_EXT,
3953 regs[TX_PWR_CFG_3_EXT_IDX]);
3954 rt2800_register_write(rt2x00dev, TX_PWR_CFG_4_EXT,
3955 regs[TX_PWR_CFG_4_EXT_IDX]);
3956
3957 for (i = 0; i < TX_PWR_CFG_IDX_COUNT; i++)
3958 rt2x00_dbg(rt2x00dev,
3959 "band:%cGHz, BW:%c0MHz, TX_PWR_CFG_%d%s = %08lx\n",
3960 (band == IEEE80211_BAND_5GHZ) ? '5' : '2',
3961 (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) ?
3962 '4' : '2',
3963 (i > TX_PWR_CFG_9_IDX) ?
3964 (i - TX_PWR_CFG_9_IDX - 1) : i,
3965 (i > TX_PWR_CFG_9_IDX) ? "_EXT" : "",
3966 (unsigned long) regs[i]);
3967}
3968
3004/* 3969/*
3005 * We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and 3970 * We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and
3006 * BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values, 3971 * BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values,
@@ -3010,9 +3975,9 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
3010 * EEPROM_TXPOWER_BYRATE offset. We adjust them and BBP R1 settings according to 3975 * EEPROM_TXPOWER_BYRATE offset. We adjust them and BBP R1 settings according to
3011 * current conditions (i.e. band, bandwidth, temperature, user settings). 3976 * current conditions (i.e. band, bandwidth, temperature, user settings).
3012 */ 3977 */
3013static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, 3978static void rt2800_config_txpower_rt28xx(struct rt2x00_dev *rt2x00dev,
3014 struct ieee80211_channel *chan, 3979 struct ieee80211_channel *chan,
3015 int power_level) 3980 int power_level)
3016{ 3981{
3017 u8 txpower, r1; 3982 u8 txpower, r1;
3018 u16 eeprom; 3983 u16 eeprom;
@@ -3080,8 +4045,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
3080 rt2800_register_read(rt2x00dev, offset, &reg); 4045 rt2800_register_read(rt2x00dev, offset, &reg);
3081 4046
3082 /* read the next four txpower values */ 4047 /* read the next four txpower values */
3083 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i, 4048 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
3084 &eeprom); 4049 i, &eeprom);
3085 4050
3086 is_rate_b = i ? 0 : 1; 4051 is_rate_b = i ? 0 : 1;
3087 /* 4052 /*
@@ -3129,8 +4094,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
3129 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3, txpower); 4094 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3, txpower);
3130 4095
3131 /* read the next four txpower values */ 4096 /* read the next four txpower values */
3132 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1, 4097 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
3133 &eeprom); 4098 i + 1, &eeprom);
3134 4099
3135 is_rate_b = 0; 4100 is_rate_b = 0;
3136 /* 4101 /*
@@ -3184,6 +4149,16 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
3184 } 4149 }
3185} 4150}
3186 4151
4152static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
4153 struct ieee80211_channel *chan,
4154 int power_level)
4155{
4156 if (rt2x00_rt(rt2x00dev, RT3593))
4157 rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level);
4158 else
4159 rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level);
4160}
4161
3187void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) 4162void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
3188{ 4163{
3189 rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.chandef.chan, 4164 rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.chandef.chan,
@@ -3219,6 +4194,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
3219 rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); 4194 rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
3220 rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); 4195 rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
3221 break; 4196 break;
4197 case RF3053:
3222 case RF3290: 4198 case RF3290:
3223 case RF5360: 4199 case RF5360:
3224 case RF5370: 4200 case RF5370:
@@ -3528,7 +4504,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
3528 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || 4504 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
3529 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || 4505 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
3530 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { 4506 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
3531 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); 4507 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1,
4508 &eeprom);
3532 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST)) 4509 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
3533 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 4510 rt2800_register_write(rt2x00dev, TX_SW_CFG2,
3534 0x0000002c); 4511 0x0000002c);
@@ -3559,6 +4536,23 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
3559 } else if (rt2x00_rt(rt2x00dev, RT3572)) { 4536 } else if (rt2x00_rt(rt2x00dev, RT3572)) {
3560 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); 4537 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
3561 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); 4538 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
4539 } else if (rt2x00_rt(rt2x00dev, RT3593)) {
4540 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402);
4541 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
4542 if (rt2x00_rt_rev_lt(rt2x00dev, RT3593, REV_RT3593E)) {
4543 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1,
4544 &eeprom);
4545 if (rt2x00_get_field16(eeprom,
4546 EEPROM_NIC_CONF1_DAC_TEST))
4547 rt2800_register_write(rt2x00dev, TX_SW_CFG2,
4548 0x0000001f);
4549 else
4550 rt2800_register_write(rt2x00dev, TX_SW_CFG2,
4551 0x0000000f);
4552 } else {
4553 rt2800_register_write(rt2x00dev, TX_SW_CFG2,
4554 0x00000000);
4555 }
3562 } else if (rt2x00_rt(rt2x00dev, RT5390) || 4556 } else if (rt2x00_rt(rt2x00dev, RT5390) ||
3563 rt2x00_rt(rt2x00dev, RT5392) || 4557 rt2x00_rt(rt2x00dev, RT5392) ||
3564 rt2x00_rt(rt2x00dev, RT5592)) { 4558 rt2x00_rt(rt2x00dev, RT5592)) {
@@ -3989,7 +4983,7 @@ static void rt2800_disable_unused_dac_adc(struct rt2x00_dev *rt2x00dev)
3989 u8 value; 4983 u8 value;
3990 4984
3991 rt2800_bbp_read(rt2x00dev, 138, &value); 4985 rt2800_bbp_read(rt2x00dev, 138, &value);
3992 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); 4986 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
3993 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) 4987 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
3994 value |= 0x20; 4988 value |= 0x20;
3995 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) 4989 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
@@ -4332,6 +5326,22 @@ static void rt2800_init_bbp_3572(struct rt2x00_dev *rt2x00dev)
4332 rt2800_disable_unused_dac_adc(rt2x00dev); 5326 rt2800_disable_unused_dac_adc(rt2x00dev);
4333} 5327}
4334 5328
5329static void rt2800_init_bbp_3593(struct rt2x00_dev *rt2x00dev)
5330{
5331 rt2800_init_bbp_early(rt2x00dev);
5332
5333 rt2800_bbp_write(rt2x00dev, 79, 0x13);
5334 rt2800_bbp_write(rt2x00dev, 80, 0x05);
5335 rt2800_bbp_write(rt2x00dev, 81, 0x33);
5336 rt2800_bbp_write(rt2x00dev, 137, 0x0f);
5337
5338 rt2800_bbp_write(rt2x00dev, 84, 0x19);
5339
5340 /* Enable DC filter */
5341 if (rt2x00_rt_rev_gte(rt2x00dev, RT3593, REV_RT3593E))
5342 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
5343}
5344
4335static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) 5345static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
4336{ 5346{
4337 int ant, div_mode; 5347 int ant, div_mode;
@@ -4402,7 +5412,7 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
4402 5412
4403 rt2800_disable_unused_dac_adc(rt2x00dev); 5413 rt2800_disable_unused_dac_adc(rt2x00dev);
4404 5414
4405 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); 5415 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
4406 div_mode = rt2x00_get_field16(eeprom, 5416 div_mode = rt2x00_get_field16(eeprom,
4407 EEPROM_NIC_CONF1_ANT_DIVERSITY); 5417 EEPROM_NIC_CONF1_ANT_DIVERSITY);
4408 ant = (div_mode == 3) ? 1 : 0; 5418 ant = (div_mode == 3) ? 1 : 0;
@@ -4488,7 +5498,7 @@ static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev)
4488 5498
4489 rt2800_bbp4_mac_if_ctrl(rt2x00dev); 5499 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
4490 5500
4491 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); 5501 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
4492 div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY); 5502 div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY);
4493 ant = (div_mode == 3) ? 1 : 0; 5503 ant = (div_mode == 3) ? 1 : 0;
4494 rt2800_bbp_read(rt2x00dev, 152, &value); 5504 rt2800_bbp_read(rt2x00dev, 152, &value);
@@ -4547,6 +5557,9 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
4547 case RT3572: 5557 case RT3572:
4548 rt2800_init_bbp_3572(rt2x00dev); 5558 rt2800_init_bbp_3572(rt2x00dev);
4549 break; 5559 break;
5560 case RT3593:
5561 rt2800_init_bbp_3593(rt2x00dev);
5562 return;
4550 case RT5390: 5563 case RT5390:
4551 case RT5392: 5564 case RT5392:
4552 rt2800_init_bbp_53xx(rt2x00dev); 5565 rt2800_init_bbp_53xx(rt2x00dev);
@@ -4557,7 +5570,8 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
4557 } 5570 }
4558 5571
4559 for (i = 0; i < EEPROM_BBP_SIZE; i++) { 5572 for (i = 0; i < EEPROM_BBP_SIZE; i++) {
4560 rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); 5573 rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_BBP_START, i,
5574 &eeprom);
4561 5575
4562 if (eeprom != 0xffff && eeprom != 0x0000) { 5576 if (eeprom != 0xffff && eeprom != 0x0000) {
4563 reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); 5577 reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
@@ -4728,7 +5742,7 @@ static void rt2800_normal_mode_setup_3xxx(struct rt2x00_dev *rt2x00dev)
4728 if (rt2x00_rt(rt2x00dev, RT3090)) { 5742 if (rt2x00_rt(rt2x00dev, RT3090)) {
4729 /* Turn off unused DAC1 and ADC1 to reduce power consumption */ 5743 /* Turn off unused DAC1 and ADC1 to reduce power consumption */
4730 rt2800_bbp_read(rt2x00dev, 138, &bbp); 5744 rt2800_bbp_read(rt2x00dev, 138, &bbp);
4731 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); 5745 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
4732 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) 5746 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
4733 rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0); 5747 rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0);
4734 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) 5748 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
@@ -4771,6 +5785,42 @@ static void rt2800_normal_mode_setup_3xxx(struct rt2x00_dev *rt2x00dev)
4771 } 5785 }
4772} 5786}
4773 5787
5788static void rt2800_normal_mode_setup_3593(struct rt2x00_dev *rt2x00dev)
5789{
5790 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
5791 u8 rfcsr;
5792 u8 tx_gain;
5793
5794 rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
5795 rt2x00_set_field8(&rfcsr, RFCSR50_TX_LO2_EN, 0);
5796 rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
5797
5798 rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
5799 tx_gain = rt2x00_get_field8(drv_data->txmixer_gain_24g,
5800 RFCSR17_TXMIXER_GAIN);
5801 rt2x00_set_field8(&rfcsr, RFCSR51_BITS24, tx_gain);
5802 rt2800_rfcsr_write(rt2x00dev, 51, rfcsr);
5803
5804 rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
5805 rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0);
5806 rt2800_rfcsr_write(rt2x00dev, 38, rfcsr);
5807
5808 rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr);
5809 rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0);
5810 rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
5811
5812 rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
5813 rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
5814 rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
5815 rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
5816
5817 rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
5818 rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2);
5819 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
5820
5821 /* TODO: enable stream mode */
5822}
5823
4774static void rt2800_normal_mode_setup_5xxx(struct rt2x00_dev *rt2x00dev) 5824static void rt2800_normal_mode_setup_5xxx(struct rt2x00_dev *rt2x00dev)
4775{ 5825{
4776 u8 reg; 5826 u8 reg;
@@ -4778,7 +5828,7 @@ static void rt2800_normal_mode_setup_5xxx(struct rt2x00_dev *rt2x00dev)
4778 5828
4779 /* Turn off unused DAC1 and ADC1 to reduce power consumption */ 5829 /* Turn off unused DAC1 and ADC1 to reduce power consumption */
4780 rt2800_bbp_read(rt2x00dev, 138, &reg); 5830 rt2800_bbp_read(rt2x00dev, 138, &reg);
4781 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); 5831 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
4782 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) 5832 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
4783 rt2x00_set_field8(&reg, BBP138_RX_ADC1, 0); 5833 rt2x00_set_field8(&reg, BBP138_RX_ADC1, 0);
4784 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) 5834 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
@@ -4884,7 +5934,8 @@ static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev)
4884 rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1); 5934 rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
4885 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || 5935 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
4886 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) { 5936 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
4887 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); 5937 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1,
5938 &eeprom);
4888 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST)) 5939 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
4889 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3); 5940 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
4890 else 5941 else
@@ -5152,6 +6203,136 @@ static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev)
5152 rt2800_normal_mode_setup_3xxx(rt2x00dev); 6203 rt2800_normal_mode_setup_3xxx(rt2x00dev);
5153} 6204}
5154 6205
6206static void rt3593_post_bbp_init(struct rt2x00_dev *rt2x00dev)
6207{
6208 u8 bbp;
6209 bool txbf_enabled = false; /* FIXME */
6210
6211 rt2800_bbp_read(rt2x00dev, 105, &bbp);
6212 if (rt2x00dev->default_ant.rx_chain_num == 1)
6213 rt2x00_set_field8(&bbp, BBP105_MLD, 0);
6214 else
6215 rt2x00_set_field8(&bbp, BBP105_MLD, 1);
6216 rt2800_bbp_write(rt2x00dev, 105, bbp);
6217
6218 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
6219
6220 rt2800_bbp_write(rt2x00dev, 92, 0x02);
6221 rt2800_bbp_write(rt2x00dev, 82, 0x82);
6222 rt2800_bbp_write(rt2x00dev, 106, 0x05);
6223 rt2800_bbp_write(rt2x00dev, 104, 0x92);
6224 rt2800_bbp_write(rt2x00dev, 88, 0x90);
6225 rt2800_bbp_write(rt2x00dev, 148, 0xc8);
6226 rt2800_bbp_write(rt2x00dev, 47, 0x48);
6227 rt2800_bbp_write(rt2x00dev, 120, 0x50);
6228
6229 if (txbf_enabled)
6230 rt2800_bbp_write(rt2x00dev, 163, 0xbd);
6231 else
6232 rt2800_bbp_write(rt2x00dev, 163, 0x9d);
6233
6234 /* SNR mapping */
6235 rt2800_bbp_write(rt2x00dev, 142, 6);
6236 rt2800_bbp_write(rt2x00dev, 143, 160);
6237 rt2800_bbp_write(rt2x00dev, 142, 7);
6238 rt2800_bbp_write(rt2x00dev, 143, 161);
6239 rt2800_bbp_write(rt2x00dev, 142, 8);
6240 rt2800_bbp_write(rt2x00dev, 143, 162);
6241
6242 /* ADC/DAC control */
6243 rt2800_bbp_write(rt2x00dev, 31, 0x08);
6244
6245 /* RX AGC energy lower bound in log2 */
6246 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
6247
6248 /* FIXME: BBP 105 owerwrite? */
6249 rt2800_bbp_write(rt2x00dev, 105, 0x04);
6250
6251}
6252
6253static void rt2800_init_rfcsr_3593(struct rt2x00_dev *rt2x00dev)
6254{
6255 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
6256 u32 reg;
6257 u8 rfcsr;
6258
6259 /* Disable GPIO #4 and #7 function for LAN PE control */
6260 rt2800_register_read(rt2x00dev, GPIO_SWITCH, &reg);
6261 rt2x00_set_field32(&reg, GPIO_SWITCH_4, 0);
6262 rt2x00_set_field32(&reg, GPIO_SWITCH_7, 0);
6263 rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
6264
6265 /* Initialize default register values */
6266 rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
6267 rt2800_rfcsr_write(rt2x00dev, 3, 0x80);
6268 rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
6269 rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
6270 rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
6271 rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
6272 rt2800_rfcsr_write(rt2x00dev, 10, 0xd3);
6273 rt2800_rfcsr_write(rt2x00dev, 11, 0x40);
6274 rt2800_rfcsr_write(rt2x00dev, 12, 0x4e);
6275 rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
6276 rt2800_rfcsr_write(rt2x00dev, 18, 0x40);
6277 rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
6278 rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
6279 rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
6280 rt2800_rfcsr_write(rt2x00dev, 32, 0x78);
6281 rt2800_rfcsr_write(rt2x00dev, 33, 0x3b);
6282 rt2800_rfcsr_write(rt2x00dev, 34, 0x3c);
6283 rt2800_rfcsr_write(rt2x00dev, 35, 0xe0);
6284 rt2800_rfcsr_write(rt2x00dev, 38, 0x86);
6285 rt2800_rfcsr_write(rt2x00dev, 39, 0x23);
6286 rt2800_rfcsr_write(rt2x00dev, 44, 0xd3);
6287 rt2800_rfcsr_write(rt2x00dev, 45, 0xbb);
6288 rt2800_rfcsr_write(rt2x00dev, 46, 0x60);
6289 rt2800_rfcsr_write(rt2x00dev, 49, 0x8e);
6290 rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
6291 rt2800_rfcsr_write(rt2x00dev, 51, 0x75);
6292 rt2800_rfcsr_write(rt2x00dev, 52, 0x45);
6293 rt2800_rfcsr_write(rt2x00dev, 53, 0x18);
6294 rt2800_rfcsr_write(rt2x00dev, 54, 0x18);
6295 rt2800_rfcsr_write(rt2x00dev, 55, 0x18);
6296 rt2800_rfcsr_write(rt2x00dev, 56, 0xdb);
6297 rt2800_rfcsr_write(rt2x00dev, 57, 0x6e);
6298
6299 /* Initiate calibration */
6300 /* TODO: use rt2800_rf_init_calibration ? */
6301 rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
6302 rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
6303 rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
6304
6305 rt2800_adjust_freq_offset(rt2x00dev);
6306
6307 rt2800_rfcsr_read(rt2x00dev, 18, &rfcsr);
6308 rt2x00_set_field8(&rfcsr, RFCSR18_XO_TUNE_BYPASS, 1);
6309 rt2800_rfcsr_write(rt2x00dev, 18, rfcsr);
6310
6311 rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
6312 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
6313 rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
6314 rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
6315 usleep_range(1000, 1500);
6316 rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
6317 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
6318 rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
6319
6320 /* Set initial values for RX filter calibration */
6321 drv_data->calibration_bw20 = 0x1f;
6322 drv_data->calibration_bw40 = 0x2f;
6323
6324 /* Save BBP 25 & 26 values for later use in channel switching */
6325 rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25);
6326 rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26);
6327
6328 rt2800_led_open_drain_enable(rt2x00dev);
6329 rt2800_normal_mode_setup_3593(rt2x00dev);
6330
6331 rt3593_post_bbp_init(rt2x00dev);
6332
6333 /* TODO: enable stream mode support */
6334}
6335
5155static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) 6336static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
5156{ 6337{
5157 rt2800_rf_init_calibration(rt2x00dev, 2); 6338 rt2800_rf_init_calibration(rt2x00dev, 2);
@@ -5380,6 +6561,9 @@ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
5380 case RT3572: 6561 case RT3572:
5381 rt2800_init_rfcsr_3572(rt2x00dev); 6562 rt2800_init_rfcsr_3572(rt2x00dev);
5382 break; 6563 break;
6564 case RT3593:
6565 rt2800_init_rfcsr_3593(rt2x00dev);
6566 break;
5383 case RT5390: 6567 case RT5390:
5384 rt2800_init_rfcsr_5390(rt2x00dev); 6568 rt2800_init_rfcsr_5390(rt2x00dev);
5385 break; 6569 break;
@@ -5456,15 +6640,15 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
5456 /* 6640 /*
5457 * Initialize LED control 6641 * Initialize LED control
5458 */ 6642 */
5459 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word); 6643 rt2800_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
5460 rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff, 6644 rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff,
5461 word & 0xff, (word >> 8) & 0xff); 6645 word & 0xff, (word >> 8) & 0xff);
5462 6646
5463 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word); 6647 rt2800_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
5464 rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff, 6648 rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff,
5465 word & 0xff, (word >> 8) & 0xff); 6649 word & 0xff, (word >> 8) & 0xff);
5466 6650
5467 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word); 6651 rt2800_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
5468 rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff, 6652 rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff,
5469 word & 0xff, (word >> 8) & 0xff); 6653 word & 0xff, (word >> 8) & 0xff);
5470 6654
@@ -5560,6 +6744,34 @@ int rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
5560} 6744}
5561EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse); 6745EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse);
5562 6746
6747static u8 rt2800_get_txmixer_gain_24g(struct rt2x00_dev *rt2x00dev)
6748{
6749 u16 word;
6750
6751 if (rt2x00_rt(rt2x00dev, RT3593))
6752 return 0;
6753
6754 rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
6755 if ((word & 0x00ff) != 0x00ff)
6756 return rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
6757
6758 return 0;
6759}
6760
6761static u8 rt2800_get_txmixer_gain_5g(struct rt2x00_dev *rt2x00dev)
6762{
6763 u16 word;
6764
6765 if (rt2x00_rt(rt2x00dev, RT3593))
6766 return 0;
6767
6768 rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
6769 if ((word & 0x00ff) != 0x00ff)
6770 return rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
6771
6772 return 0;
6773}
6774
5563static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) 6775static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
5564{ 6776{
5565 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; 6777 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
@@ -5578,18 +6790,18 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
5578 /* 6790 /*
5579 * Start validation of the data that has been read. 6791 * Start validation of the data that has been read.
5580 */ 6792 */
5581 mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); 6793 mac = rt2800_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
5582 if (!is_valid_ether_addr(mac)) { 6794 if (!is_valid_ether_addr(mac)) {
5583 eth_random_addr(mac); 6795 eth_random_addr(mac);
5584 rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); 6796 rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
5585 } 6797 }
5586 6798
5587 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word); 6799 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
5588 if (word == 0xffff) { 6800 if (word == 0xffff) {
5589 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2); 6801 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
5590 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1); 6802 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
5591 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820); 6803 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
5592 rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); 6804 rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
5593 rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); 6805 rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
5594 } else if (rt2x00_rt(rt2x00dev, RT2860) || 6806 } else if (rt2x00_rt(rt2x00dev, RT2860) ||
5595 rt2x00_rt(rt2x00dev, RT2872)) { 6807 rt2x00_rt(rt2x00dev, RT2872)) {
@@ -5598,10 +6810,10 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
5598 */ 6810 */
5599 if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2) 6811 if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2)
5600 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2); 6812 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
5601 rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); 6813 rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
5602 } 6814 }
5603 6815
5604 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word); 6816 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
5605 if (word == 0xffff) { 6817 if (word == 0xffff) {
5606 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0); 6818 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0);
5607 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0); 6819 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0);
@@ -5618,24 +6830,24 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
5618 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0); 6830 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0);
5619 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0); 6831 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0);
5620 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0); 6832 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0);
5621 rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word); 6833 rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
5622 rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); 6834 rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word);
5623 } 6835 }
5624 6836
5625 rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); 6837 rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
5626 if ((word & 0x00ff) == 0x00ff) { 6838 if ((word & 0x00ff) == 0x00ff) {
5627 rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); 6839 rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);
5628 rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); 6840 rt2800_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
5629 rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word); 6841 rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word);
5630 } 6842 }
5631 if ((word & 0xff00) == 0xff00) { 6843 if ((word & 0xff00) == 0xff00) {
5632 rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE, 6844 rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE,
5633 LED_MODE_TXRX_ACTIVITY); 6845 LED_MODE_TXRX_ACTIVITY);
5634 rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); 6846 rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
5635 rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); 6847 rt2800_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
5636 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555); 6848 rt2800_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
5637 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221); 6849 rt2800_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
5638 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8); 6850 rt2800_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
5639 rt2x00_eeprom_dbg(rt2x00dev, "Led Mode: 0x%04x\n", word); 6851 rt2x00_eeprom_dbg(rt2x00dev, "Led Mode: 0x%04x\n", word);
5640 } 6852 }
5641 6853
@@ -5644,56 +6856,61 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
5644 * lna0 as correct value. Note that EEPROM_LNA 6856 * lna0 as correct value. Note that EEPROM_LNA
5645 * is never validated. 6857 * is never validated.
5646 */ 6858 */
5647 rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word); 6859 rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
5648 default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0); 6860 default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0);
5649 6861
5650 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word); 6862 rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
5651 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10) 6863 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10)
5652 rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0); 6864 rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0);
5653 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10) 6865 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10)
5654 rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0); 6866 rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
5655 rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word); 6867 rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
5656 6868
5657 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word); 6869 drv_data->txmixer_gain_24g = rt2800_get_txmixer_gain_24g(rt2x00dev);
5658 if ((word & 0x00ff) != 0x00ff) {
5659 drv_data->txmixer_gain_24g =
5660 rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
5661 } else {
5662 drv_data->txmixer_gain_24g = 0;
5663 }
5664 6870
5665 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); 6871 rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
5666 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) 6872 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
5667 rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); 6873 rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
5668 if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || 6874 if (!rt2x00_rt(rt2x00dev, RT3593)) {
5669 rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) 6875 if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
5670 rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, 6876 rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
5671 default_lna_gain); 6877 rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
5672 rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word); 6878 default_lna_gain);
5673
5674 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
5675 if ((word & 0x00ff) != 0x00ff) {
5676 drv_data->txmixer_gain_5g =
5677 rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
5678 } else {
5679 drv_data->txmixer_gain_5g = 0;
5680 } 6879 }
6880 rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
6881
6882 drv_data->txmixer_gain_5g = rt2800_get_txmixer_gain_5g(rt2x00dev);
5681 6883
5682 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word); 6884 rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
5683 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10) 6885 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
5684 rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0); 6886 rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
5685 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10) 6887 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10)
5686 rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0); 6888 rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0);
5687 rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word); 6889 rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
5688 6890
5689 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word); 6891 rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
5690 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) 6892 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
5691 rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); 6893 rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
5692 if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || 6894 if (!rt2x00_rt(rt2x00dev, RT3593)) {
5693 rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) 6895 if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
5694 rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, 6896 rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
5695 default_lna_gain); 6897 rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
5696 rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); 6898 default_lna_gain);
6899 }
6900 rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
6901
6902 if (rt2x00_rt(rt2x00dev, RT3593)) {
6903 rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &word);
6904 if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 ||
6905 rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff)
6906 rt2x00_set_field16(&word, EEPROM_EXT_LNA2_A1,
6907 default_lna_gain);
6908 if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A2) == 0x00 ||
6909 rt2x00_get_field16(word, EEPROM_EXT_LNA2_A2) == 0xff)
6910 rt2x00_set_field16(&word, EEPROM_EXT_LNA2_A1,
6911 default_lna_gain);
6912 rt2800_eeprom_write(rt2x00dev, EEPROM_EXT_LNA2, word);
6913 }
5697 6914
5698 return 0; 6915 return 0;
5699} 6916}
@@ -5707,7 +6924,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
5707 /* 6924 /*
5708 * Read EEPROM word for configuration. 6925 * Read EEPROM word for configuration.
5709 */ 6926 */
5710 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); 6927 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
5711 6928
5712 /* 6929 /*
5713 * Identify RF chipset by EEPROM value 6930 * Identify RF chipset by EEPROM value
@@ -5717,7 +6934,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
5717 if (rt2x00_rt(rt2x00dev, RT3290) || 6934 if (rt2x00_rt(rt2x00dev, RT3290) ||
5718 rt2x00_rt(rt2x00dev, RT5390) || 6935 rt2x00_rt(rt2x00dev, RT5390) ||
5719 rt2x00_rt(rt2x00dev, RT5392)) 6936 rt2x00_rt(rt2x00dev, RT5392))
5720 rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); 6937 rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
5721 else 6938 else
5722 rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); 6939 rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
5723 6940
@@ -5731,6 +6948,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
5731 case RF3021: 6948 case RF3021:
5732 case RF3022: 6949 case RF3022:
5733 case RF3052: 6950 case RF3052:
6951 case RF3053:
5734 case RF3290: 6952 case RF3290:
5735 case RF3320: 6953 case RF3320:
5736 case RF3322: 6954 case RF3322:
@@ -5757,7 +6975,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
5757 rt2x00dev->default_ant.rx_chain_num = 6975 rt2x00dev->default_ant.rx_chain_num =
5758 rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH); 6976 rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH);
5759 6977
5760 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); 6978 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
5761 6979
5762 if (rt2x00_rt(rt2x00dev, RT3070) || 6980 if (rt2x00_rt(rt2x00dev, RT3070) ||
5763 rt2x00_rt(rt2x00dev, RT3090) || 6981 rt2x00_rt(rt2x00dev, RT3090) ||
@@ -5810,7 +7028,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
5810 /* 7028 /*
5811 * Read frequency offset and RF programming sequence. 7029 * Read frequency offset and RF programming sequence.
5812 */ 7030 */
5813 rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); 7031 rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
5814 rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); 7032 rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
5815 7033
5816 /* 7034 /*
@@ -5827,7 +7045,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
5827 /* 7045 /*
5828 * Check if support EIRP tx power limit feature. 7046 * Check if support EIRP tx power limit feature.
5829 */ 7047 */
5830 rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom); 7048 rt2800_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom);
5831 7049
5832 if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) < 7050 if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) <
5833 EIRP_MAX_TX_POWER_LIMIT) 7051 EIRP_MAX_TX_POWER_LIMIT)
@@ -6109,12 +7327,79 @@ static const struct rf_channel rf_vals_5592_xtal40[] = {
6109 {196, 83, 0, 12, 1}, 7327 {196, 83, 0, 12, 1},
6110}; 7328};
6111 7329
7330static const struct rf_channel rf_vals_3053[] = {
7331 /* Channel, N, R, K */
7332 {1, 241, 2, 2},
7333 {2, 241, 2, 7},
7334 {3, 242, 2, 2},
7335 {4, 242, 2, 7},
7336 {5, 243, 2, 2},
7337 {6, 243, 2, 7},
7338 {7, 244, 2, 2},
7339 {8, 244, 2, 7},
7340 {9, 245, 2, 2},
7341 {10, 245, 2, 7},
7342 {11, 246, 2, 2},
7343 {12, 246, 2, 7},
7344 {13, 247, 2, 2},
7345 {14, 248, 2, 4},
7346
7347 {36, 0x56, 0, 4},
7348 {38, 0x56, 0, 6},
7349 {40, 0x56, 0, 8},
7350 {44, 0x57, 0, 0},
7351 {46, 0x57, 0, 2},
7352 {48, 0x57, 0, 4},
7353 {52, 0x57, 0, 8},
7354 {54, 0x57, 0, 10},
7355 {56, 0x58, 0, 0},
7356 {60, 0x58, 0, 4},
7357 {62, 0x58, 0, 6},
7358 {64, 0x58, 0, 8},
7359
7360 {100, 0x5B, 0, 8},
7361 {102, 0x5B, 0, 10},
7362 {104, 0x5C, 0, 0},
7363 {108, 0x5C, 0, 4},
7364 {110, 0x5C, 0, 6},
7365 {112, 0x5C, 0, 8},
7366
7367 /* NOTE: Channel 114 has been removed intentionally.
7368 * The EEPROM contains no TX power values for that,
7369 * and it is disabled in the vendor driver as well.
7370 */
7371
7372 {116, 0x5D, 0, 0},
7373 {118, 0x5D, 0, 2},
7374 {120, 0x5D, 0, 4},
7375 {124, 0x5D, 0, 8},
7376 {126, 0x5D, 0, 10},
7377 {128, 0x5E, 0, 0},
7378 {132, 0x5E, 0, 4},
7379 {134, 0x5E, 0, 6},
7380 {136, 0x5E, 0, 8},
7381 {140, 0x5F, 0, 0},
7382
7383 {149, 0x5F, 0, 9},
7384 {151, 0x5F, 0, 11},
7385 {153, 0x60, 0, 1},
7386 {157, 0x60, 0, 5},
7387 {159, 0x60, 0, 7},
7388 {161, 0x60, 0, 9},
7389 {165, 0x61, 0, 1},
7390 {167, 0x61, 0, 3},
7391 {169, 0x61, 0, 5},
7392 {171, 0x61, 0, 7},
7393 {173, 0x61, 0, 9},
7394};
7395
6112static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) 7396static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
6113{ 7397{
6114 struct hw_mode_spec *spec = &rt2x00dev->spec; 7398 struct hw_mode_spec *spec = &rt2x00dev->spec;
6115 struct channel_info *info; 7399 struct channel_info *info;
6116 char *default_power1; 7400 char *default_power1;
6117 char *default_power2; 7401 char *default_power2;
7402 char *default_power3;
6118 unsigned int i; 7403 unsigned int i;
6119 u16 eeprom; 7404 u16 eeprom;
6120 u32 reg; 7405 u32 reg;
@@ -6148,7 +7433,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
6148 7433
6149 SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); 7434 SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
6150 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, 7435 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
6151 rt2x00_eeprom_addr(rt2x00dev, 7436 rt2800_eeprom_addr(rt2x00dev,
6152 EEPROM_MAC_ADDR_0)); 7437 EEPROM_MAC_ADDR_0));
6153 7438
6154 /* 7439 /*
@@ -6164,7 +7449,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
6164 rt2x00dev->hw->max_report_rates = 7; 7449 rt2x00dev->hw->max_report_rates = 7;
6165 rt2x00dev->hw->max_rate_tries = 1; 7450 rt2x00dev->hw->max_rate_tries = 1;
6166 7451
6167 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); 7452 rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
6168 7453
6169 /* 7454 /*
6170 * Initialize hw_mode information. 7455 * Initialize hw_mode information.
@@ -6199,6 +7484,10 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
6199 spec->supported_bands |= SUPPORT_BAND_5GHZ; 7484 spec->supported_bands |= SUPPORT_BAND_5GHZ;
6200 spec->num_channels = ARRAY_SIZE(rf_vals_3x); 7485 spec->num_channels = ARRAY_SIZE(rf_vals_3x);
6201 spec->channels = rf_vals_3x; 7486 spec->channels = rf_vals_3x;
7487 } else if (rt2x00_rf(rt2x00dev, RF3053)) {
7488 spec->supported_bands |= SUPPORT_BAND_5GHZ;
7489 spec->num_channels = ARRAY_SIZE(rf_vals_3053);
7490 spec->channels = rf_vals_3053;
6202 } else if (rt2x00_rf(rt2x00dev, RF5592)) { 7491 } else if (rt2x00_rf(rt2x00dev, RF5592)) {
6203 spec->supported_bands |= SUPPORT_BAND_5GHZ; 7492 spec->supported_bands |= SUPPORT_BAND_5GHZ;
6204 7493
@@ -6264,21 +7553,40 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
6264 7553
6265 spec->channels_info = info; 7554 spec->channels_info = info;
6266 7555
6267 default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); 7556 default_power1 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
6268 default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); 7557 default_power2 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
7558
7559 if (rt2x00dev->default_ant.tx_chain_num > 2)
7560 default_power3 = rt2800_eeprom_addr(rt2x00dev,
7561 EEPROM_EXT_TXPOWER_BG3);
7562 else
7563 default_power3 = NULL;
6269 7564
6270 for (i = 0; i < 14; i++) { 7565 for (i = 0; i < 14; i++) {
6271 info[i].default_power1 = default_power1[i]; 7566 info[i].default_power1 = default_power1[i];
6272 info[i].default_power2 = default_power2[i]; 7567 info[i].default_power2 = default_power2[i];
7568 if (default_power3)
7569 info[i].default_power3 = default_power3[i];
6273 } 7570 }
6274 7571
6275 if (spec->num_channels > 14) { 7572 if (spec->num_channels > 14) {
6276 default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); 7573 default_power1 = rt2800_eeprom_addr(rt2x00dev,
6277 default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); 7574 EEPROM_TXPOWER_A1);
7575 default_power2 = rt2800_eeprom_addr(rt2x00dev,
7576 EEPROM_TXPOWER_A2);
7577
7578 if (rt2x00dev->default_ant.tx_chain_num > 2)
7579 default_power3 =
7580 rt2800_eeprom_addr(rt2x00dev,
7581 EEPROM_EXT_TXPOWER_A3);
7582 else
7583 default_power3 = NULL;
6278 7584
6279 for (i = 14; i < spec->num_channels; i++) { 7585 for (i = 14; i < spec->num_channels; i++) {
6280 info[i].default_power1 = default_power1[i - 14]; 7586 info[i].default_power1 = default_power1[i - 14];
6281 info[i].default_power2 = default_power2[i - 14]; 7587 info[i].default_power2 = default_power2[i - 14];
7588 if (default_power3)
7589 info[i].default_power3 = default_power3[i - 14];
6282 } 7590 }
6283 } 7591 }
6284 7592
@@ -6289,6 +7597,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
6289 case RF3022: 7597 case RF3022:
6290 case RF3320: 7598 case RF3320:
6291 case RF3052: 7599 case RF3052:
7600 case RF3053:
6292 case RF3290: 7601 case RF3290:
6293 case RF5360: 7602 case RF5360:
6294 case RF5370: 7603 case RF5370:
@@ -6327,6 +7636,7 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev)
6327 case RT3352: 7636 case RT3352:
6328 case RT3390: 7637 case RT3390:
6329 case RT3572: 7638 case RT3572:
7639 case RT3593:
6330 case RT5390: 7640 case RT5390:
6331 case RT5392: 7641 case RT5392:
6332 case RT5592: 7642 case RT5592:
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 840833b26bfa..fc9efdfca8f2 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -854,7 +854,10 @@ static void rt2800usb_queue_init(struct data_queue *queue)
854 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; 854 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
855 unsigned short txwi_size, rxwi_size; 855 unsigned short txwi_size, rxwi_size;
856 856
857 if (rt2x00_rt(rt2x00dev, RT5592)) { 857 if (rt2x00_rt(rt2x00dev, RT3593)) {
858 txwi_size = TXWI_DESC_SIZE_4WORDS;
859 rxwi_size = RXWI_DESC_SIZE_5WORDS;
860 } else if (rt2x00_rt(rt2x00dev, RT5592)) {
858 txwi_size = TXWI_DESC_SIZE_5WORDS; 861 txwi_size = TXWI_DESC_SIZE_5WORDS;
859 rxwi_size = RXWI_DESC_SIZE_6WORDS; 862 rxwi_size = RXWI_DESC_SIZE_6WORDS;
860 } else { 863 } else {
@@ -1194,6 +1197,40 @@ static struct usb_device_id rt2800usb_device_table[] = {
1194 /* Zinwell */ 1197 /* Zinwell */
1195 { USB_DEVICE(0x5a57, 0x0284) }, 1198 { USB_DEVICE(0x5a57, 0x0284) },
1196#endif 1199#endif
1200#ifdef CONFIG_RT2800USB_RT3573
1201 /* AirLive */
1202 { USB_DEVICE(0x1b75, 0x7733) },
1203 /* ASUS */
1204 { USB_DEVICE(0x0b05, 0x17bc) },
1205 { USB_DEVICE(0x0b05, 0x17ad) },
1206 /* Belkin */
1207 { USB_DEVICE(0x050d, 0x1103) },
1208 /* Cameo */
1209 { USB_DEVICE(0x148f, 0xf301) },
1210 /* Edimax */
1211 { USB_DEVICE(0x7392, 0x7733) },
1212 /* Hawking */
1213 { USB_DEVICE(0x0e66, 0x0020) },
1214 { USB_DEVICE(0x0e66, 0x0021) },
1215 /* I-O DATA */
1216 { USB_DEVICE(0x04bb, 0x094e) },
1217 /* Linksys */
1218 { USB_DEVICE(0x13b1, 0x003b) },
1219 /* Logitec */
1220 { USB_DEVICE(0x0789, 0x016b) },
1221 /* NETGEAR */
1222 { USB_DEVICE(0x0846, 0x9012) },
1223 { USB_DEVICE(0x0846, 0x9019) },
1224 /* Planex */
1225 { USB_DEVICE(0x2019, 0xed19) },
1226 /* Ralink */
1227 { USB_DEVICE(0x148f, 0x3573) },
1228 /* Sitecom */
1229 { USB_DEVICE(0x0df6, 0x0067) },
1230 { USB_DEVICE(0x0df6, 0x006a) },
1231 /* ZyXEL */
1232 { USB_DEVICE(0x0586, 0x3421) },
1233#endif
1197#ifdef CONFIG_RT2800USB_RT53XX 1234#ifdef CONFIG_RT2800USB_RT53XX
1198 /* Arcadyan */ 1235 /* Arcadyan */
1199 { USB_DEVICE(0x043e, 0x7a12) }, 1236 { USB_DEVICE(0x043e, 0x7a12) },
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index ee3fc570b11d..fe4c572db52c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -211,6 +211,7 @@ struct channel_info {
211 short max_power; 211 short max_power;
212 short default_power1; 212 short default_power1;
213 short default_power2; 213 short default_power2;
214 short default_power3;
214}; 215};
215 216
216/* 217/*
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c
index f9f059dadb73..a98acefb8c06 100644
--- a/drivers/net/wireless/rtlwifi/rc.c
+++ b/drivers/net/wireless/rtlwifi/rc.c
@@ -218,6 +218,7 @@ static void rtl_tx_status(void *ppriv,
218 218
219static void rtl_rate_init(void *ppriv, 219static void rtl_rate_init(void *ppriv,
220 struct ieee80211_supported_band *sband, 220 struct ieee80211_supported_band *sband,
221 struct cfg80211_chan_def *chandef,
221 struct ieee80211_sta *sta, void *priv_sta) 222 struct ieee80211_sta *sta, void *priv_sta)
222{ 223{
223} 224}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
index 8e3ec1e25644..0f7812e0c8aa 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
@@ -109,5 +109,8 @@ void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
109void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, 109void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
110 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer); 110 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer);
111bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw); 111bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw);
112void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
113 struct ieee80211_sta *sta,
114 u8 rssi_level);
112 115
113#endif 116#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
index 262e1e4c6e5b..a1310abd0d54 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
@@ -49,8 +49,5 @@ bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
49u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, 49u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
50 enum radio_path rfpath, u32 regaddr, u32 bitmask); 50 enum radio_path rfpath, u32 regaddr, u32 bitmask);
51void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw); 51void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
52void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
53 struct ieee80211_sta *sta,
54 u8 rssi_level);
55 52
56#endif 53#endif
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index b8db55c868c7..d1b19c38a907 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1315,7 +1315,7 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
1315 1315
1316#ifdef CONFIG_PM 1316#ifdef CONFIG_PM
1317static int 1317static int
1318wl1271_validate_wowlan_pattern(struct cfg80211_wowlan_trig_pkt_pattern *p) 1318wl1271_validate_wowlan_pattern(struct cfg80211_pkt_pattern *p)
1319{ 1319{
1320 int num_fields = 0, in_field = 0, fields_size = 0; 1320 int num_fields = 0, in_field = 0, fields_size = 0;
1321 int i, pattern_len = 0; 1321 int i, pattern_len = 0;
@@ -1458,9 +1458,9 @@ void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
1458 * Allocates an RX filter returned through f 1458 * Allocates an RX filter returned through f
1459 * which needs to be freed using rx_filter_free() 1459 * which needs to be freed using rx_filter_free()
1460 */ 1460 */
1461static int wl1271_convert_wowlan_pattern_to_rx_filter( 1461static int
1462 struct cfg80211_wowlan_trig_pkt_pattern *p, 1462wl1271_convert_wowlan_pattern_to_rx_filter(struct cfg80211_pkt_pattern *p,
1463 struct wl12xx_rx_filter **f) 1463 struct wl12xx_rx_filter **f)
1464{ 1464{
1465 int i, j, ret = 0; 1465 int i, j, ret = 0;
1466 struct wl12xx_rx_filter *filter; 1466 struct wl12xx_rx_filter *filter;
@@ -1562,7 +1562,7 @@ static int wl1271_configure_wowlan(struct wl1271 *wl,
1562 1562
1563 /* Translate WoWLAN patterns into filters */ 1563 /* Translate WoWLAN patterns into filters */
1564 for (i = 0; i < wow->n_patterns; i++) { 1564 for (i = 0; i < wow->n_patterns; i++) {
1565 struct cfg80211_wowlan_trig_pkt_pattern *p; 1565 struct cfg80211_pkt_pattern *p;
1566 struct wl12xx_rx_filter *filter = NULL; 1566 struct wl12xx_rx_filter *filter = NULL;
1567 1567
1568 p = &wow->patterns[i]; 1568 p = &wow->patterns[i];
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index 36171fd2826b..2cd9b0e44a41 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -138,7 +138,7 @@ config SSB_DRIVER_MIPS
138 138
139config SSB_SFLASH 139config SSB_SFLASH
140 bool "SSB serial flash support" 140 bool "SSB serial flash support"
141 depends on SSB_DRIVER_MIPS && BROKEN 141 depends on SSB_DRIVER_MIPS
142 default y 142 default y
143 143
144# Assumption: We are on embedded, if we compile the MIPS core. 144# Assumption: We are on embedded, if we compile the MIPS core.
diff --git a/drivers/ssb/driver_chipcommon_sflash.c b/drivers/ssb/driver_chipcommon_sflash.c
index e84cf04f4416..50328de712fa 100644
--- a/drivers/ssb/driver_chipcommon_sflash.c
+++ b/drivers/ssb/driver_chipcommon_sflash.c
@@ -151,8 +151,8 @@ int ssb_sflash_init(struct ssb_chipcommon *cc)
151 sflash->size = sflash->blocksize * sflash->numblocks; 151 sflash->size = sflash->blocksize * sflash->numblocks;
152 sflash->present = true; 152 sflash->present = true;
153 153
154 pr_info("Found %s serial flash (blocksize: 0x%X, blocks: %d)\n", 154 pr_info("Found %s serial flash (size: %dKiB, blocksize: 0x%X, blocks: %d)\n",
155 e->name, e->blocksize, e->numblocks); 155 e->name, sflash->size / 1024, e->blocksize, e->numblocks);
156 156
157 /* Prepare platform device, but don't register it yet. It's too early, 157 /* Prepare platform device, but don't register it yet. It's too early,
158 * malloc (required by device_private_init) is not available yet. */ 158 * malloc (required by device_private_init) is not available yet. */
@@ -160,7 +160,5 @@ int ssb_sflash_init(struct ssb_chipcommon *cc)
160 sflash->size; 160 sflash->size;
161 ssb_sflash_dev.dev.platform_data = sflash; 161 ssb_sflash_dev.dev.platform_data = sflash;
162 162
163 pr_err("Serial flash support is not implemented yet!\n"); 163 return 0;
164
165 return -ENOTSUPP;
166} 164}
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 622fc505d3e1..4d043c30216f 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -72,7 +72,19 @@ struct bcma_host_ops {
72/* Core-ID values. */ 72/* Core-ID values. */
73#define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */ 73#define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */
74#define BCMA_CORE_4706_CHIPCOMMON 0x500 74#define BCMA_CORE_4706_CHIPCOMMON 0x500
75#define BCMA_CORE_PCIEG2 0x501
76#define BCMA_CORE_DMA 0x502
77#define BCMA_CORE_SDIO3 0x503
78#define BCMA_CORE_USB20 0x504
79#define BCMA_CORE_USB30 0x505
80#define BCMA_CORE_A9JTAG 0x506
81#define BCMA_CORE_DDR23 0x507
82#define BCMA_CORE_ROM 0x508
83#define BCMA_CORE_NAND 0x509
84#define BCMA_CORE_QSPI 0x50A
85#define BCMA_CORE_CHIPCOMMON_B 0x50B
75#define BCMA_CORE_4706_SOC_RAM 0x50E 86#define BCMA_CORE_4706_SOC_RAM 0x50E
87#define BCMA_CORE_ARMCA9 0x510
76#define BCMA_CORE_4706_MAC_GBIT 0x52D 88#define BCMA_CORE_4706_MAC_GBIT 0x52D
77#define BCMA_CORE_AMEMC 0x52E /* DDR1/2 memory controller core */ 89#define BCMA_CORE_AMEMC 0x52E /* DDR1/2 memory controller core */
78#define BCMA_CORE_ALTA 0x534 /* I2S core */ 90#define BCMA_CORE_ALTA 0x534 /* I2S core */
@@ -177,6 +189,11 @@ struct bcma_host_ops {
177#define BCMA_PKG_ID_BCM5357 11 189#define BCMA_PKG_ID_BCM5357 11
178#define BCMA_CHIP_ID_BCM53572 53572 190#define BCMA_CHIP_ID_BCM53572 53572
179#define BCMA_PKG_ID_BCM47188 9 191#define BCMA_PKG_ID_BCM47188 9
192#define BCMA_CHIP_ID_BCM4707 53010
193#define BCMA_PKG_ID_BCM4707 1
194#define BCMA_PKG_ID_BCM4708 2
195#define BCMA_PKG_ID_BCM4709 0
196#define BCMA_CHIP_ID_BCM53018 53018
180 197
181/* Board types (on PCI usually equals to the subsystem dev id) */ 198/* Board types (on PCI usually equals to the subsystem dev id) */
182/* BCM4313 */ 199/* BCM4313 */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7b0730aeb892..aeaf6dff6e05 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -461,6 +461,33 @@ ieee80211_chandef_rate_flags(struct cfg80211_chan_def *chandef)
461} 461}
462 462
463/** 463/**
464 * ieee80211_chandef_max_power - maximum transmission power for the chandef
465 *
466 * In some regulations, the transmit power may depend on the configured channel
467 * bandwidth which may be defined as dBm/MHz. This function returns the actual
468 * max_power for non-standard (20 MHz) channels.
469 *
470 * @chandef: channel definition for the channel
471 *
472 * Returns: maximum allowed transmission power in dBm for the chandef
473 */
474static inline int
475ieee80211_chandef_max_power(struct cfg80211_chan_def *chandef)
476{
477 switch (chandef->width) {
478 case NL80211_CHAN_WIDTH_5:
479 return min(chandef->chan->max_reg_power - 6,
480 chandef->chan->max_power);
481 case NL80211_CHAN_WIDTH_10:
482 return min(chandef->chan->max_reg_power - 3,
483 chandef->chan->max_power);
484 default:
485 break;
486 }
487 return chandef->chan->max_power;
488}
489
490/**
464 * enum survey_info_flags - survey information flags 491 * enum survey_info_flags - survey information flags
465 * 492 *
466 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in 493 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
@@ -490,7 +517,7 @@ enum survey_info_flags {
490 * @channel: the channel this survey record reports, mandatory 517 * @channel: the channel this survey record reports, mandatory
491 * @filled: bitflag of flags from &enum survey_info_flags 518 * @filled: bitflag of flags from &enum survey_info_flags
492 * @noise: channel noise in dBm. This and all following fields are 519 * @noise: channel noise in dBm. This and all following fields are
493 * optional 520 * optional
494 * @channel_time: amount of time in ms the radio spent on the channel 521 * @channel_time: amount of time in ms the radio spent on the channel
495 * @channel_time_busy: amount of time the primary channel was sensed busy 522 * @channel_time_busy: amount of time the primary channel was sensed busy
496 * @channel_time_ext_busy: amount of time the extension channel was sensed busy 523 * @channel_time_ext_busy: amount of time the extension channel was sensed busy
@@ -546,9 +573,9 @@ struct cfg80211_crypto_settings {
546/** 573/**
547 * struct cfg80211_beacon_data - beacon data 574 * struct cfg80211_beacon_data - beacon data
548 * @head: head portion of beacon (before TIM IE) 575 * @head: head portion of beacon (before TIM IE)
549 * or %NULL if not changed 576 * or %NULL if not changed
550 * @tail: tail portion of beacon (after TIM IE) 577 * @tail: tail portion of beacon (after TIM IE)
551 * or %NULL if not changed 578 * or %NULL if not changed
552 * @head_len: length of @head 579 * @head_len: length of @head
553 * @tail_len: length of @tail 580 * @tail_len: length of @tail
554 * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL 581 * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL
@@ -764,7 +791,7 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
764 * @STATION_INFO_PLINK_STATE: @plink_state filled 791 * @STATION_INFO_PLINK_STATE: @plink_state filled
765 * @STATION_INFO_SIGNAL: @signal filled 792 * @STATION_INFO_SIGNAL: @signal filled
766 * @STATION_INFO_TX_BITRATE: @txrate fields are filled 793 * @STATION_INFO_TX_BITRATE: @txrate fields are filled
767 * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) 794 * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs)
768 * @STATION_INFO_RX_PACKETS: @rx_packets filled with 32-bit value 795 * @STATION_INFO_RX_PACKETS: @rx_packets filled with 32-bit value
769 * @STATION_INFO_TX_PACKETS: @tx_packets filled with 32-bit value 796 * @STATION_INFO_TX_PACKETS: @tx_packets filled with 32-bit value
770 * @STATION_INFO_TX_RETRIES: @tx_retries filled 797 * @STATION_INFO_TX_RETRIES: @tx_retries filled
@@ -1285,6 +1312,7 @@ struct cfg80211_ssid {
1285 * @n_ssids: number of SSIDs 1312 * @n_ssids: number of SSIDs
1286 * @channels: channels to scan on. 1313 * @channels: channels to scan on.
1287 * @n_channels: total number of channels to scan 1314 * @n_channels: total number of channels to scan
1315 * @scan_width: channel width for scanning
1288 * @ie: optional information element(s) to add into Probe Request or %NULL 1316 * @ie: optional information element(s) to add into Probe Request or %NULL
1289 * @ie_len: length of ie in octets 1317 * @ie_len: length of ie in octets
1290 * @flags: bit field of flags controlling operation 1318 * @flags: bit field of flags controlling operation
@@ -1300,6 +1328,7 @@ struct cfg80211_scan_request {
1300 struct cfg80211_ssid *ssids; 1328 struct cfg80211_ssid *ssids;
1301 int n_ssids; 1329 int n_ssids;
1302 u32 n_channels; 1330 u32 n_channels;
1331 enum nl80211_bss_scan_width scan_width;
1303 const u8 *ie; 1332 const u8 *ie;
1304 size_t ie_len; 1333 size_t ie_len;
1305 u32 flags; 1334 u32 flags;
@@ -1333,6 +1362,7 @@ struct cfg80211_match_set {
1333 * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans) 1362 * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans)
1334 * @n_ssids: number of SSIDs 1363 * @n_ssids: number of SSIDs
1335 * @n_channels: total number of channels to scan 1364 * @n_channels: total number of channels to scan
1365 * @scan_width: channel width for scanning
1336 * @interval: interval between each scheduled scan cycle 1366 * @interval: interval between each scheduled scan cycle
1337 * @ie: optional information element(s) to add into Probe Request or %NULL 1367 * @ie: optional information element(s) to add into Probe Request or %NULL
1338 * @ie_len: length of ie in octets 1368 * @ie_len: length of ie in octets
@@ -1352,6 +1382,7 @@ struct cfg80211_sched_scan_request {
1352 struct cfg80211_ssid *ssids; 1382 struct cfg80211_ssid *ssids;
1353 int n_ssids; 1383 int n_ssids;
1354 u32 n_channels; 1384 u32 n_channels;
1385 enum nl80211_bss_scan_width scan_width;
1355 u32 interval; 1386 u32 interval;
1356 const u8 *ie; 1387 const u8 *ie;
1357 size_t ie_len; 1388 size_t ie_len;
@@ -1403,6 +1434,7 @@ struct cfg80211_bss_ies {
1403 * for use in scan results and similar. 1434 * for use in scan results and similar.
1404 * 1435 *
1405 * @channel: channel this BSS is on 1436 * @channel: channel this BSS is on
1437 * @scan_width: width of the control channel
1406 * @bssid: BSSID of the BSS 1438 * @bssid: BSSID of the BSS
1407 * @beacon_interval: the beacon interval as from the frame 1439 * @beacon_interval: the beacon interval as from the frame
1408 * @capability: the capability field in host byte order 1440 * @capability: the capability field in host byte order
@@ -1424,6 +1456,7 @@ struct cfg80211_bss_ies {
1424 */ 1456 */
1425struct cfg80211_bss { 1457struct cfg80211_bss {
1426 struct ieee80211_channel *channel; 1458 struct ieee80211_channel *channel;
1459 enum nl80211_bss_scan_width scan_width;
1427 1460
1428 const struct cfg80211_bss_ies __rcu *ies; 1461 const struct cfg80211_bss_ies __rcu *ies;
1429 const struct cfg80211_bss_ies __rcu *beacon_ies; 1462 const struct cfg80211_bss_ies __rcu *beacon_ies;
@@ -1509,7 +1542,7 @@ enum cfg80211_assoc_req_flags {
1509 * @prev_bssid: previous BSSID, if not %NULL use reassociate frame 1542 * @prev_bssid: previous BSSID, if not %NULL use reassociate frame
1510 * @flags: See &enum cfg80211_assoc_req_flags 1543 * @flags: See &enum cfg80211_assoc_req_flags
1511 * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask 1544 * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask
1512 * will be used in ht_capa. Un-supported values will be ignored. 1545 * will be used in ht_capa. Un-supported values will be ignored.
1513 * @ht_capa_mask: The bits of ht_capa which are to be used. 1546 * @ht_capa_mask: The bits of ht_capa which are to be used.
1514 * @vht_capa: VHT capability override 1547 * @vht_capa: VHT capability override
1515 * @vht_capa_mask: VHT capability mask indicating which fields to use 1548 * @vht_capa_mask: VHT capability mask indicating which fields to use
@@ -1592,6 +1625,9 @@ struct cfg80211_disassoc_request {
1592 * user space. Otherwise, port is marked authorized by default. 1625 * user space. Otherwise, port is marked authorized by default.
1593 * @basic_rates: bitmap of basic rates to use when creating the IBSS 1626 * @basic_rates: bitmap of basic rates to use when creating the IBSS
1594 * @mcast_rate: per-band multicast rate index + 1 (0: disabled) 1627 * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
1628 * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask
1629 * will be used in ht_capa. Un-supported values will be ignored.
1630 * @ht_capa_mask: The bits of ht_capa which are to be used.
1595 */ 1631 */
1596struct cfg80211_ibss_params { 1632struct cfg80211_ibss_params {
1597 u8 *ssid; 1633 u8 *ssid;
@@ -1605,6 +1641,8 @@ struct cfg80211_ibss_params {
1605 bool privacy; 1641 bool privacy;
1606 bool control_port; 1642 bool control_port;
1607 int mcast_rate[IEEE80211_NUM_BANDS]; 1643 int mcast_rate[IEEE80211_NUM_BANDS];
1644 struct ieee80211_ht_cap ht_capa;
1645 struct ieee80211_ht_cap ht_capa_mask;
1608}; 1646};
1609 1647
1610/** 1648/**
@@ -1630,9 +1668,9 @@ struct cfg80211_ibss_params {
1630 * @key: WEP key for shared key authentication 1668 * @key: WEP key for shared key authentication
1631 * @flags: See &enum cfg80211_assoc_req_flags 1669 * @flags: See &enum cfg80211_assoc_req_flags
1632 * @bg_scan_period: Background scan period in seconds 1670 * @bg_scan_period: Background scan period in seconds
1633 * or -1 to indicate that default value is to be used. 1671 * or -1 to indicate that default value is to be used.
1634 * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask 1672 * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask
1635 * will be used in ht_capa. Un-supported values will be ignored. 1673 * will be used in ht_capa. Un-supported values will be ignored.
1636 * @ht_capa_mask: The bits of ht_capa which are to be used. 1674 * @ht_capa_mask: The bits of ht_capa which are to be used.
1637 * @vht_capa: VHT Capability overrides 1675 * @vht_capa: VHT Capability overrides
1638 * @vht_capa_mask: The bits of vht_capa which are to be used. 1676 * @vht_capa_mask: The bits of vht_capa which are to be used.
@@ -1698,7 +1736,7 @@ struct cfg80211_pmksa {
1698}; 1736};
1699 1737
1700/** 1738/**
1701 * struct cfg80211_wowlan_trig_pkt_pattern - packet pattern 1739 * struct cfg80211_pkt_pattern - packet pattern
1702 * @mask: bitmask where to match pattern and where to ignore bytes, 1740 * @mask: bitmask where to match pattern and where to ignore bytes,
1703 * one bit per byte, in same format as nl80211 1741 * one bit per byte, in same format as nl80211
1704 * @pattern: bytes to match where bitmask is 1 1742 * @pattern: bytes to match where bitmask is 1
@@ -1708,7 +1746,7 @@ struct cfg80211_pmksa {
1708 * Internal note: @mask and @pattern are allocated in one chunk of 1746 * Internal note: @mask and @pattern are allocated in one chunk of
1709 * memory, free @mask only! 1747 * memory, free @mask only!
1710 */ 1748 */
1711struct cfg80211_wowlan_trig_pkt_pattern { 1749struct cfg80211_pkt_pattern {
1712 u8 *mask, *pattern; 1750 u8 *mask, *pattern;
1713 int pattern_len; 1751 int pattern_len;
1714 int pkt_offset; 1752 int pkt_offset;
@@ -1770,12 +1808,41 @@ struct cfg80211_wowlan {
1770 bool any, disconnect, magic_pkt, gtk_rekey_failure, 1808 bool any, disconnect, magic_pkt, gtk_rekey_failure,
1771 eap_identity_req, four_way_handshake, 1809 eap_identity_req, four_way_handshake,
1772 rfkill_release; 1810 rfkill_release;
1773 struct cfg80211_wowlan_trig_pkt_pattern *patterns; 1811 struct cfg80211_pkt_pattern *patterns;
1774 struct cfg80211_wowlan_tcp *tcp; 1812 struct cfg80211_wowlan_tcp *tcp;
1775 int n_patterns; 1813 int n_patterns;
1776}; 1814};
1777 1815
1778/** 1816/**
1817 * struct cfg80211_coalesce_rules - Coalesce rule parameters
1818 *
1819 * This structure defines coalesce rule for the device.
1820 * @delay: maximum coalescing delay in msecs.
1821 * @condition: condition for packet coalescence.
1822 * see &enum nl80211_coalesce_condition.
1823 * @patterns: array of packet patterns
1824 * @n_patterns: number of patterns
1825 */
1826struct cfg80211_coalesce_rules {
1827 int delay;
1828 enum nl80211_coalesce_condition condition;
1829 struct cfg80211_pkt_pattern *patterns;
1830 int n_patterns;
1831};
1832
1833/**
1834 * struct cfg80211_coalesce - Packet coalescing settings
1835 *
1836 * This structure defines coalescing settings.
1837 * @rules: array of coalesce rules
1838 * @n_rules: number of rules
1839 */
1840struct cfg80211_coalesce {
1841 struct cfg80211_coalesce_rules *rules;
1842 int n_rules;
1843};
1844
1845/**
1779 * struct cfg80211_wowlan_wakeup - wakeup report 1846 * struct cfg80211_wowlan_wakeup - wakeup report
1780 * @disconnect: woke up by getting disconnected 1847 * @disconnect: woke up by getting disconnected
1781 * @magic_pkt: woke up by receiving magic packet 1848 * @magic_pkt: woke up by receiving magic packet
@@ -2071,6 +2138,7 @@ struct cfg80211_update_ft_ies_params {
2071 * driver can take the most appropriate actions. 2138 * driver can take the most appropriate actions.
2072 * @crit_proto_stop: Indicates critical protocol no longer needs increased link 2139 * @crit_proto_stop: Indicates critical protocol no longer needs increased link
2073 * reliability. This operation can not fail. 2140 * reliability. This operation can not fail.
2141 * @set_coalesce: Set coalesce parameters.
2074 */ 2142 */
2075struct cfg80211_ops { 2143struct cfg80211_ops {
2076 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); 2144 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2306,6 +2374,8 @@ struct cfg80211_ops {
2306 u16 duration); 2374 u16 duration);
2307 void (*crit_proto_stop)(struct wiphy *wiphy, 2375 void (*crit_proto_stop)(struct wiphy *wiphy,
2308 struct wireless_dev *wdev); 2376 struct wireless_dev *wdev);
2377 int (*set_coalesce)(struct wiphy *wiphy,
2378 struct cfg80211_coalesce *coalesce);
2309}; 2379};
2310 2380
2311/* 2381/*
@@ -2532,6 +2602,25 @@ struct wiphy_wowlan_support {
2532}; 2602};
2533 2603
2534/** 2604/**
2605 * struct wiphy_coalesce_support - coalesce support data
2606 * @n_rules: maximum number of coalesce rules
2607 * @max_delay: maximum supported coalescing delay in msecs
2608 * @n_patterns: number of supported patterns in a rule
2609 * (see nl80211.h for the pattern definition)
2610 * @pattern_max_len: maximum length of each pattern
2611 * @pattern_min_len: minimum length of each pattern
2612 * @max_pkt_offset: maximum Rx packet offset
2613 */
2614struct wiphy_coalesce_support {
2615 int n_rules;
2616 int max_delay;
2617 int n_patterns;
2618 int pattern_max_len;
2619 int pattern_min_len;
2620 int max_pkt_offset;
2621};
2622
2623/**
2535 * struct wiphy - wireless hardware description 2624 * struct wiphy - wireless hardware description
2536 * @reg_notifier: the driver's regulatory notification callback, 2625 * @reg_notifier: the driver's regulatory notification callback,
2537 * note that if your driver uses wiphy_apply_custom_regulatory() 2626 * note that if your driver uses wiphy_apply_custom_regulatory()
@@ -2641,6 +2730,7 @@ struct wiphy_wowlan_support {
2641 * 802.11-2012 8.4.2.29 for the defined fields. 2730 * 802.11-2012 8.4.2.29 for the defined fields.
2642 * @extended_capabilities_mask: mask of the valid values 2731 * @extended_capabilities_mask: mask of the valid values
2643 * @extended_capabilities_len: length of the extended capabilities 2732 * @extended_capabilities_len: length of the extended capabilities
2733 * @coalesce: packet coalescing support information
2644 */ 2734 */
2645struct wiphy { 2735struct wiphy {
2646 /* assign these fields before you register the wiphy */ 2736 /* assign these fields before you register the wiphy */
@@ -2750,6 +2840,8 @@ struct wiphy {
2750 const struct iw_handler_def *wext; 2840 const struct iw_handler_def *wext;
2751#endif 2841#endif
2752 2842
2843 const struct wiphy_coalesce_support *coalesce;
2844
2753 char priv[0] __aligned(NETDEV_ALIGN); 2845 char priv[0] __aligned(NETDEV_ALIGN);
2754}; 2846};
2755 2847
@@ -3063,11 +3155,13 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
3063/** 3155/**
3064 * ieee80211_mandatory_rates - get mandatory rates for a given band 3156 * ieee80211_mandatory_rates - get mandatory rates for a given band
3065 * @sband: the band to look for rates in 3157 * @sband: the band to look for rates in
3158 * @scan_width: width of the control channel
3066 * 3159 *
3067 * This function returns a bitmap of the mandatory rates for the given 3160 * This function returns a bitmap of the mandatory rates for the given
3068 * band, bits are set according to the rate position in the bitrates array. 3161 * band, bits are set according to the rate position in the bitrates array.
3069 */ 3162 */
3070u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband); 3163u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband,
3164 enum nl80211_bss_scan_width scan_width);
3071 3165
3072/* 3166/*
3073 * Radiotap parsing functions -- for controlled injection support 3167 * Radiotap parsing functions -- for controlled injection support
@@ -3379,10 +3473,11 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy);
3379void cfg80211_sched_scan_stopped(struct wiphy *wiphy); 3473void cfg80211_sched_scan_stopped(struct wiphy *wiphy);
3380 3474
3381/** 3475/**
3382 * cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame 3476 * cfg80211_inform_bss_width_frame - inform cfg80211 of a received BSS frame
3383 * 3477 *
3384 * @wiphy: the wiphy reporting the BSS 3478 * @wiphy: the wiphy reporting the BSS
3385 * @channel: The channel the frame was received on 3479 * @channel: The channel the frame was received on
3480 * @scan_width: width of the control channel
3386 * @mgmt: the management frame (probe response or beacon) 3481 * @mgmt: the management frame (probe response or beacon)
3387 * @len: length of the management frame 3482 * @len: length of the management frame
3388 * @signal: the signal strength, type depends on the wiphy's signal_type 3483 * @signal: the signal strength, type depends on the wiphy's signal_type
@@ -3395,16 +3490,29 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy);
3395 * Or %NULL on error. 3490 * Or %NULL on error.
3396 */ 3491 */
3397struct cfg80211_bss * __must_check 3492struct cfg80211_bss * __must_check
3493cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
3494 struct ieee80211_channel *channel,
3495 enum nl80211_bss_scan_width scan_width,
3496 struct ieee80211_mgmt *mgmt, size_t len,
3497 s32 signal, gfp_t gfp);
3498
3499static inline struct cfg80211_bss * __must_check
3398cfg80211_inform_bss_frame(struct wiphy *wiphy, 3500cfg80211_inform_bss_frame(struct wiphy *wiphy,
3399 struct ieee80211_channel *channel, 3501 struct ieee80211_channel *channel,
3400 struct ieee80211_mgmt *mgmt, size_t len, 3502 struct ieee80211_mgmt *mgmt, size_t len,
3401 s32 signal, gfp_t gfp); 3503 s32 signal, gfp_t gfp)
3504{
3505 return cfg80211_inform_bss_width_frame(wiphy, channel,
3506 NL80211_BSS_CHAN_WIDTH_20,
3507 mgmt, len, signal, gfp);
3508}
3402 3509
3403/** 3510/**
3404 * cfg80211_inform_bss - inform cfg80211 of a new BSS 3511 * cfg80211_inform_bss - inform cfg80211 of a new BSS
3405 * 3512 *
3406 * @wiphy: the wiphy reporting the BSS 3513 * @wiphy: the wiphy reporting the BSS
3407 * @channel: The channel the frame was received on 3514 * @channel: The channel the frame was received on
3515 * @scan_width: width of the control channel
3408 * @bssid: the BSSID of the BSS 3516 * @bssid: the BSSID of the BSS
3409 * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) 3517 * @tsf: the TSF sent by the peer in the beacon/probe response (or 0)
3410 * @capability: the capability field sent by the peer 3518 * @capability: the capability field sent by the peer
@@ -3421,11 +3529,26 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
3421 * Or %NULL on error. 3529 * Or %NULL on error.
3422 */ 3530 */
3423struct cfg80211_bss * __must_check 3531struct cfg80211_bss * __must_check
3532cfg80211_inform_bss_width(struct wiphy *wiphy,
3533 struct ieee80211_channel *channel,
3534 enum nl80211_bss_scan_width scan_width,
3535 const u8 *bssid, u64 tsf, u16 capability,
3536 u16 beacon_interval, const u8 *ie, size_t ielen,
3537 s32 signal, gfp_t gfp);
3538
3539static inline struct cfg80211_bss * __must_check
3424cfg80211_inform_bss(struct wiphy *wiphy, 3540cfg80211_inform_bss(struct wiphy *wiphy,
3425 struct ieee80211_channel *channel, 3541 struct ieee80211_channel *channel,
3426 const u8 *bssid, u64 tsf, u16 capability, 3542 const u8 *bssid, u64 tsf, u16 capability,
3427 u16 beacon_interval, const u8 *ie, size_t ielen, 3543 u16 beacon_interval, const u8 *ie, size_t ielen,
3428 s32 signal, gfp_t gfp); 3544 s32 signal, gfp_t gfp)
3545{
3546 return cfg80211_inform_bss_width(wiphy, channel,
3547 NL80211_BSS_CHAN_WIDTH_20,
3548 bssid, tsf, capability,
3549 beacon_interval, ie, ielen, signal,
3550 gfp);
3551}
3429 3552
3430struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, 3553struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
3431 struct ieee80211_channel *channel, 3554 struct ieee80211_channel *channel,
@@ -3471,6 +3594,19 @@ void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
3471 */ 3594 */
3472void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss); 3595void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
3473 3596
3597static inline enum nl80211_bss_scan_width
3598cfg80211_chandef_to_scan_width(const struct cfg80211_chan_def *chandef)
3599{
3600 switch (chandef->width) {
3601 case NL80211_CHAN_WIDTH_5:
3602 return NL80211_BSS_CHAN_WIDTH_5;
3603 case NL80211_CHAN_WIDTH_10:
3604 return NL80211_BSS_CHAN_WIDTH_10;
3605 default:
3606 return NL80211_BSS_CHAN_WIDTH_20;
3607 }
3608}
3609
3474/** 3610/**
3475 * cfg80211_rx_mlme_mgmt - notification of processed MLME management frame 3611 * cfg80211_rx_mlme_mgmt - notification of processed MLME management frame
3476 * @dev: network device 3612 * @dev: network device
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index c6d07cb074bc..8b5b71433297 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -230,6 +230,10 @@ enum ieee80211_radiotap_type {
230#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */ 230#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
231#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */ 231#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
232#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */ 232#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
233#define IEEE80211_CHAN_GSM 0x1000 /* GSM (900 MHz) */
234#define IEEE80211_CHAN_STURBO 0x2000 /* Static Turbo */
235#define IEEE80211_CHAN_HALF 0x4000 /* Half channel (10 MHz wide) */
236#define IEEE80211_CHAN_QUARTER 0x8000 /* Quarter channel (5 MHz wide) */
233 237
234/* For IEEE80211_RADIOTAP_FLAGS */ 238/* For IEEE80211_RADIOTAP_FLAGS */
235#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received 239#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5b7a3dadadde..3124036285eb 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -811,6 +811,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
811 * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC 811 * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
812 * is stored in the @ampdu_delimiter_crc field) 812 * is stored in the @ampdu_delimiter_crc field)
813 * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3 813 * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
814 * @RX_FLAG_10MHZ: 10 MHz (half channel) was used
815 * @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used
814 */ 816 */
815enum mac80211_rx_flags { 817enum mac80211_rx_flags {
816 RX_FLAG_MMIC_ERROR = BIT(0), 818 RX_FLAG_MMIC_ERROR = BIT(0),
@@ -839,6 +841,8 @@ enum mac80211_rx_flags {
839 RX_FLAG_80P80MHZ = BIT(24), 841 RX_FLAG_80P80MHZ = BIT(24),
840 RX_FLAG_160MHZ = BIT(25), 842 RX_FLAG_160MHZ = BIT(25),
841 RX_FLAG_STBC_MASK = BIT(26) | BIT(27), 843 RX_FLAG_STBC_MASK = BIT(26) | BIT(27),
844 RX_FLAG_10MHZ = BIT(28),
845 RX_FLAG_5MHZ = BIT(29),
842}; 846};
843 847
844#define RX_FLAG_STBC_SHIFT 26 848#define RX_FLAG_STBC_SHIFT 26
@@ -1004,11 +1008,11 @@ enum ieee80211_smps_mode {
1004 * @radar_enabled: whether radar detection is enabled 1008 * @radar_enabled: whether radar detection is enabled
1005 * 1009 *
1006 * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame 1010 * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame
1007 * (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11, 1011 * (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11,
1008 * but actually means the number of transmissions not the number of retries 1012 * but actually means the number of transmissions not the number of retries
1009 * @short_frame_max_tx_count: Maximum number of transmissions for a "short" 1013 * @short_frame_max_tx_count: Maximum number of transmissions for a "short"
1010 * frame, called "dot11ShortRetryLimit" in 802.11, but actually means the 1014 * frame, called "dot11ShortRetryLimit" in 802.11, but actually means the
1011 * number of transmissions not the number of retries 1015 * number of transmissions not the number of retries
1012 * 1016 *
1013 * @smps_mode: spatial multiplexing powersave mode; note that 1017 * @smps_mode: spatial multiplexing powersave mode; note that
1014 * %IEEE80211_SMPS_STATIC is used when the device is not 1018 * %IEEE80211_SMPS_STATIC is used when the device is not
@@ -1092,7 +1096,7 @@ enum ieee80211_vif_flags {
1092 * be off when it is %NULL there can still be races and packets could be 1096 * be off when it is %NULL there can still be races and packets could be
1093 * processed after it switches back to %NULL. 1097 * processed after it switches back to %NULL.
1094 * @debugfs_dir: debugfs dentry, can be used by drivers to create own per 1098 * @debugfs_dir: debugfs dentry, can be used by drivers to create own per
1095 * interface debug files. Note that it will be NULL for the virtual 1099 * interface debug files. Note that it will be NULL for the virtual
1096 * monitor interface (if that is requested.) 1100 * monitor interface (if that is requested.)
1097 * @drv_priv: data area for driver use, will always be aligned to 1101 * @drv_priv: data area for driver use, will always be aligned to
1098 * sizeof(void *). 1102 * sizeof(void *).
@@ -1425,10 +1429,10 @@ struct ieee80211_tx_control {
1425 * the stack. 1429 * the stack.
1426 * 1430 *
1427 * @IEEE80211_HW_CONNECTION_MONITOR: 1431 * @IEEE80211_HW_CONNECTION_MONITOR:
1428 * The hardware performs its own connection monitoring, including 1432 * The hardware performs its own connection monitoring, including
1429 * periodic keep-alives to the AP and probing the AP on beacon loss. 1433 * periodic keep-alives to the AP and probing the AP on beacon loss.
1430 * When this flag is set, signaling beacon-loss will cause an immediate 1434 * When this flag is set, signaling beacon-loss will cause an immediate
1431 * change to disassociated state. 1435 * change to disassociated state.
1432 * 1436 *
1433 * @IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC: 1437 * @IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC:
1434 * This device needs to get data from beacon before association (i.e. 1438 * This device needs to get data from beacon before association (i.e.
@@ -1526,10 +1530,10 @@ enum ieee80211_hw_flags {
1526 * @channel_change_time: time (in microseconds) it takes to change channels. 1530 * @channel_change_time: time (in microseconds) it takes to change channels.
1527 * 1531 *
1528 * @max_signal: Maximum value for signal (rssi) in RX information, used 1532 * @max_signal: Maximum value for signal (rssi) in RX information, used
1529 * only when @IEEE80211_HW_SIGNAL_UNSPEC or @IEEE80211_HW_SIGNAL_DB 1533 * only when @IEEE80211_HW_SIGNAL_UNSPEC or @IEEE80211_HW_SIGNAL_DB
1530 * 1534 *
1531 * @max_listen_interval: max listen interval in units of beacon interval 1535 * @max_listen_interval: max listen interval in units of beacon interval
1532 * that HW supports 1536 * that HW supports
1533 * 1537 *
1534 * @queues: number of available hardware transmit queues for 1538 * @queues: number of available hardware transmit queues for
1535 * data packets. WMM/QoS requires at least four, these 1539 * data packets. WMM/QoS requires at least four, these
@@ -2443,7 +2447,7 @@ enum ieee80211_roc_type {
2443 * The callback can sleep. 2447 * The callback can sleep.
2444 * 2448 *
2445 * @set_tsf: Set the TSF timer to the specified value in the firmware/hardware. 2449 * @set_tsf: Set the TSF timer to the specified value in the firmware/hardware.
2446 * Currently, this is only used for IBSS mode debugging. Is not a 2450 * Currently, this is only used for IBSS mode debugging. Is not a
2447 * required function. 2451 * required function.
2448 * The callback can sleep. 2452 * The callback can sleep.
2449 * 2453 *
@@ -4204,8 +4208,10 @@ struct rate_control_ops {
4204 4208
4205 void *(*alloc_sta)(void *priv, struct ieee80211_sta *sta, gfp_t gfp); 4209 void *(*alloc_sta)(void *priv, struct ieee80211_sta *sta, gfp_t gfp);
4206 void (*rate_init)(void *priv, struct ieee80211_supported_band *sband, 4210 void (*rate_init)(void *priv, struct ieee80211_supported_band *sband,
4211 struct cfg80211_chan_def *chandef,
4207 struct ieee80211_sta *sta, void *priv_sta); 4212 struct ieee80211_sta *sta, void *priv_sta);
4208 void (*rate_update)(void *priv, struct ieee80211_supported_band *sband, 4213 void (*rate_update)(void *priv, struct ieee80211_supported_band *sband,
4214 struct cfg80211_chan_def *chandef,
4209 struct ieee80211_sta *sta, void *priv_sta, 4215 struct ieee80211_sta *sta, void *priv_sta,
4210 u32 changed); 4216 u32 changed);
4211 void (*free_sta)(void *priv, struct ieee80211_sta *sta, 4217 void (*free_sta)(void *priv, struct ieee80211_sta *sta,
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 861e5eba3953..eb68735b3318 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -126,6 +126,31 @@
126 */ 126 */
127 127
128/** 128/**
129 * DOC: packet coalesce support
130 *
131 * In most cases, host that receives IPv4 and IPv6 multicast/broadcast
132 * packets does not do anything with these packets. Therefore the
133 * reception of these unwanted packets causes unnecessary processing
134 * and power consumption.
135 *
136 * Packet coalesce feature helps to reduce number of received interrupts
137 * to host by buffering these packets in firmware/hardware for some
138 * predefined time. Received interrupt will be generated when one of the
139 * following events occur.
140 * a) Expiration of hardware timer whose expiration time is set to maximum
141 * coalescing delay of matching coalesce rule.
142 * b) Coalescing buffer in hardware reaches it's limit.
143 * c) Packet doesn't match any of the configured coalesce rules.
144 *
145 * User needs to configure following parameters for creating a coalesce
146 * rule.
147 * a) Maximum coalescing delay
148 * b) List of packet patterns which needs to be matched
149 * c) Condition for coalescence. pattern 'match' or 'no match'
150 * Multiple such rules can be created.
151 */
152
153/**
129 * enum nl80211_commands - supported nl80211 commands 154 * enum nl80211_commands - supported nl80211 commands
130 * 155 *
131 * @NL80211_CMD_UNSPEC: unspecified command to catch errors 156 * @NL80211_CMD_UNSPEC: unspecified command to catch errors
@@ -648,6 +673,9 @@
648 * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can 673 * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can
649 * return back to normal. 674 * return back to normal.
650 * 675 *
676 * @NL80211_CMD_GET_COALESCE: Get currently supported coalesce rules.
677 * @NL80211_CMD_SET_COALESCE: Configure coalesce rules or clear existing rules.
678 *
651 * @NL80211_CMD_MAX: highest used command number 679 * @NL80211_CMD_MAX: highest used command number
652 * @__NL80211_CMD_AFTER_LAST: internal use 680 * @__NL80211_CMD_AFTER_LAST: internal use
653 */ 681 */
@@ -810,6 +838,9 @@ enum nl80211_commands {
810 NL80211_CMD_CRIT_PROTOCOL_START, 838 NL80211_CMD_CRIT_PROTOCOL_START,
811 NL80211_CMD_CRIT_PROTOCOL_STOP, 839 NL80211_CMD_CRIT_PROTOCOL_STOP,
812 840
841 NL80211_CMD_GET_COALESCE,
842 NL80211_CMD_SET_COALESCE,
843
813 /* add new commands above here */ 844 /* add new commands above here */
814 845
815 /* used to define NL80211_CMD_MAX below */ 846 /* used to define NL80211_CMD_MAX below */
@@ -1436,6 +1467,8 @@ enum nl80211_commands {
1436 * allowed to be used with the first @NL80211_CMD_SET_STATION command to 1467 * allowed to be used with the first @NL80211_CMD_SET_STATION command to
1437 * update a TDLS peer STA entry. 1468 * update a TDLS peer STA entry.
1438 * 1469 *
1470 * @NL80211_ATTR_COALESCE_RULE: Coalesce rule information.
1471 *
1439 * @NL80211_ATTR_MAX: highest attribute number currently defined 1472 * @NL80211_ATTR_MAX: highest attribute number currently defined
1440 * @__NL80211_ATTR_AFTER_LAST: internal use 1473 * @__NL80211_ATTR_AFTER_LAST: internal use
1441 */ 1474 */
@@ -1736,6 +1769,8 @@ enum nl80211_attrs {
1736 1769
1737 NL80211_ATTR_PEER_AID, 1770 NL80211_ATTR_PEER_AID,
1738 1771
1772 NL80211_ATTR_COALESCE_RULE,
1773
1739 /* add attributes here, update the policy in nl80211.c */ 1774 /* add attributes here, update the policy in nl80211.c */
1740 1775
1741 __NL80211_ATTR_AFTER_LAST, 1776 __NL80211_ATTR_AFTER_LAST,
@@ -2773,6 +2808,21 @@ enum nl80211_chan_width {
2773}; 2808};
2774 2809
2775/** 2810/**
2811 * enum nl80211_bss_scan_width - control channel width for a BSS
2812 *
2813 * These values are used with the %NL80211_BSS_CHAN_WIDTH attribute.
2814 *
2815 * @NL80211_BSS_CHAN_WIDTH_20: control channel is 20 MHz wide or compatible
2816 * @NL80211_BSS_CHAN_WIDTH_10: control channel is 10 MHz wide
2817 * @NL80211_BSS_CHAN_WIDTH_5: control channel is 5 MHz wide
2818 */
2819enum nl80211_bss_scan_width {
2820 NL80211_BSS_CHAN_WIDTH_20,
2821 NL80211_BSS_CHAN_WIDTH_10,
2822 NL80211_BSS_CHAN_WIDTH_5,
2823};
2824
2825/**
2776 * enum nl80211_bss - netlink attributes for a BSS 2826 * enum nl80211_bss - netlink attributes for a BSS
2777 * 2827 *
2778 * @__NL80211_BSS_INVALID: invalid 2828 * @__NL80211_BSS_INVALID: invalid
@@ -2796,6 +2846,8 @@ enum nl80211_chan_width {
2796 * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information 2846 * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information
2797 * elements from a Beacon frame (bin); not present if no Beacon frame has 2847 * elements from a Beacon frame (bin); not present if no Beacon frame has
2798 * yet been received 2848 * yet been received
2849 * @NL80211_BSS_CHAN_WIDTH: channel width of the control channel
2850 * (u32, enum nl80211_bss_scan_width)
2799 * @__NL80211_BSS_AFTER_LAST: internal 2851 * @__NL80211_BSS_AFTER_LAST: internal
2800 * @NL80211_BSS_MAX: highest BSS attribute 2852 * @NL80211_BSS_MAX: highest BSS attribute
2801 */ 2853 */
@@ -2812,6 +2864,7 @@ enum nl80211_bss {
2812 NL80211_BSS_STATUS, 2864 NL80211_BSS_STATUS,
2813 NL80211_BSS_SEEN_MS_AGO, 2865 NL80211_BSS_SEEN_MS_AGO,
2814 NL80211_BSS_BEACON_IES, 2866 NL80211_BSS_BEACON_IES,
2867 NL80211_BSS_CHAN_WIDTH,
2815 2868
2816 /* keep last */ 2869 /* keep last */
2817 __NL80211_BSS_AFTER_LAST, 2870 __NL80211_BSS_AFTER_LAST,
@@ -3060,11 +3113,11 @@ enum nl80211_tx_power_setting {
3060}; 3113};
3061 3114
3062/** 3115/**
3063 * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute 3116 * enum nl80211_packet_pattern_attr - packet pattern attribute
3064 * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute 3117 * @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
3065 * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has 3118 * @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has
3066 * a zero bit are ignored 3119 * a zero bit are ignored
3067 * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have 3120 * @NL80211_PKTPAT_MASK: pattern mask, must be long enough to have
3068 * a bit for each byte in the pattern. The lowest-order bit corresponds 3121 * a bit for each byte in the pattern. The lowest-order bit corresponds
3069 * to the first byte of the pattern, but the bytes of the pattern are 3122 * to the first byte of the pattern, but the bytes of the pattern are
3070 * in a little-endian-like format, i.e. the 9th byte of the pattern 3123 * in a little-endian-like format, i.e. the 9th byte of the pattern
@@ -3075,39 +3128,50 @@ enum nl80211_tx_power_setting {
3075 * Note that the pattern matching is done as though frames were not 3128 * Note that the pattern matching is done as though frames were not
3076 * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked 3129 * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
3077 * first (including SNAP header unpacking) and then matched. 3130 * first (including SNAP header unpacking) and then matched.
3078 * @NL80211_WOWLAN_PKTPAT_OFFSET: packet offset, pattern is matched after 3131 * @NL80211_PKTPAT_OFFSET: packet offset, pattern is matched after
3079 * these fixed number of bytes of received packet 3132 * these fixed number of bytes of received packet
3080 * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes 3133 * @NUM_NL80211_PKTPAT: number of attributes
3081 * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number 3134 * @MAX_NL80211_PKTPAT: max attribute number
3082 */ 3135 */
3083enum nl80211_wowlan_packet_pattern_attr { 3136enum nl80211_packet_pattern_attr {
3084 __NL80211_WOWLAN_PKTPAT_INVALID, 3137 __NL80211_PKTPAT_INVALID,
3085 NL80211_WOWLAN_PKTPAT_MASK, 3138 NL80211_PKTPAT_MASK,
3086 NL80211_WOWLAN_PKTPAT_PATTERN, 3139 NL80211_PKTPAT_PATTERN,
3087 NL80211_WOWLAN_PKTPAT_OFFSET, 3140 NL80211_PKTPAT_OFFSET,
3088 3141
3089 NUM_NL80211_WOWLAN_PKTPAT, 3142 NUM_NL80211_PKTPAT,
3090 MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1, 3143 MAX_NL80211_PKTPAT = NUM_NL80211_PKTPAT - 1,
3091}; 3144};
3092 3145
3093/** 3146/**
3094 * struct nl80211_wowlan_pattern_support - pattern support information 3147 * struct nl80211_pattern_support - packet pattern support information
3095 * @max_patterns: maximum number of patterns supported 3148 * @max_patterns: maximum number of patterns supported
3096 * @min_pattern_len: minimum length of each pattern 3149 * @min_pattern_len: minimum length of each pattern
3097 * @max_pattern_len: maximum length of each pattern 3150 * @max_pattern_len: maximum length of each pattern
3098 * @max_pkt_offset: maximum Rx packet offset 3151 * @max_pkt_offset: maximum Rx packet offset
3099 * 3152 *
3100 * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when 3153 * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when
3101 * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the 3154 * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED or in
3102 * capability information given by the kernel to userspace. 3155 * %NL80211_ATTR_COALESCE_RULE_PKT_PATTERN when that is part of
3156 * %NL80211_ATTR_COALESCE_RULE in the capability information given
3157 * by the kernel to userspace.
3103 */ 3158 */
3104struct nl80211_wowlan_pattern_support { 3159struct nl80211_pattern_support {
3105 __u32 max_patterns; 3160 __u32 max_patterns;
3106 __u32 min_pattern_len; 3161 __u32 min_pattern_len;
3107 __u32 max_pattern_len; 3162 __u32 max_pattern_len;
3108 __u32 max_pkt_offset; 3163 __u32 max_pkt_offset;
3109} __attribute__((packed)); 3164} __attribute__((packed));
3110 3165
3166/* only for backward compatibility */
3167#define __NL80211_WOWLAN_PKTPAT_INVALID __NL80211_PKTPAT_INVALID
3168#define NL80211_WOWLAN_PKTPAT_MASK NL80211_PKTPAT_MASK
3169#define NL80211_WOWLAN_PKTPAT_PATTERN NL80211_PKTPAT_PATTERN
3170#define NL80211_WOWLAN_PKTPAT_OFFSET NL80211_PKTPAT_OFFSET
3171#define NUM_NL80211_WOWLAN_PKTPAT NUM_NL80211_PKTPAT
3172#define MAX_NL80211_WOWLAN_PKTPAT MAX_NL80211_PKTPAT
3173#define nl80211_wowlan_pattern_support nl80211_pattern_support
3174
3111/** 3175/**
3112 * enum nl80211_wowlan_triggers - WoWLAN trigger definitions 3176 * enum nl80211_wowlan_triggers - WoWLAN trigger definitions
3113 * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes 3177 * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes
@@ -3127,7 +3191,7 @@ struct nl80211_wowlan_pattern_support {
3127 * pattern matching is done after the packet is converted to the MSDU. 3191 * pattern matching is done after the packet is converted to the MSDU.
3128 * 3192 *
3129 * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute 3193 * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
3130 * carrying a &struct nl80211_wowlan_pattern_support. 3194 * carrying a &struct nl80211_pattern_support.
3131 * 3195 *
3132 * When reporting wakeup. it is a u32 attribute containing the 0-based 3196 * When reporting wakeup. it is a u32 attribute containing the 0-based
3133 * index of the pattern that caused the wakeup, in the patterns passed 3197 * index of the pattern that caused the wakeup, in the patterns passed
@@ -3284,7 +3348,7 @@ struct nl80211_wowlan_tcp_data_token_feature {
3284 * @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a 3348 * @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a
3285 * u32 attribute holding the maximum length 3349 * u32 attribute holding the maximum length
3286 * @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for 3350 * @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for
3287 * feature advertising. The mask works like @NL80211_WOWLAN_PKTPAT_MASK 3351 * feature advertising. The mask works like @NL80211_PKTPAT_MASK
3288 * but on the TCP payload only. 3352 * but on the TCP payload only.
3289 * @NUM_NL80211_WOWLAN_TCP: number of TCP attributes 3353 * @NUM_NL80211_WOWLAN_TCP: number of TCP attributes
3290 * @MAX_NL80211_WOWLAN_TCP: highest attribute number 3354 * @MAX_NL80211_WOWLAN_TCP: highest attribute number
@@ -3309,6 +3373,55 @@ enum nl80211_wowlan_tcp_attrs {
3309}; 3373};
3310 3374
3311/** 3375/**
3376 * struct nl80211_coalesce_rule_support - coalesce rule support information
3377 * @max_rules: maximum number of rules supported
3378 * @pat: packet pattern support information
3379 * @max_delay: maximum supported coalescing delay in msecs
3380 *
3381 * This struct is carried in %NL80211_ATTR_COALESCE_RULE in the
3382 * capability information given by the kernel to userspace.
3383 */
3384struct nl80211_coalesce_rule_support {
3385 __u32 max_rules;
3386 struct nl80211_pattern_support pat;
3387 __u32 max_delay;
3388} __attribute__((packed));
3389
3390/**
3391 * enum nl80211_attr_coalesce_rule - coalesce rule attribute
3392 * @__NL80211_COALESCE_RULE_INVALID: invalid number for nested attribute
3393 * @NL80211_ATTR_COALESCE_RULE_DELAY: delay in msecs used for packet coalescing
3394 * @NL80211_ATTR_COALESCE_RULE_CONDITION: condition for packet coalescence,
3395 * see &enum nl80211_coalesce_condition.
3396 * @NL80211_ATTR_COALESCE_RULE_PKT_PATTERN: packet offset, pattern is matched
3397 * after these fixed number of bytes of received packet
3398 * @NUM_NL80211_ATTR_COALESCE_RULE: number of attributes
3399 * @NL80211_ATTR_COALESCE_RULE_MAX: max attribute number
3400 */
3401enum nl80211_attr_coalesce_rule {
3402 __NL80211_COALESCE_RULE_INVALID,
3403 NL80211_ATTR_COALESCE_RULE_DELAY,
3404 NL80211_ATTR_COALESCE_RULE_CONDITION,
3405 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN,
3406
3407 /* keep last */
3408 NUM_NL80211_ATTR_COALESCE_RULE,
3409 NL80211_ATTR_COALESCE_RULE_MAX = NUM_NL80211_ATTR_COALESCE_RULE - 1
3410};
3411
3412/**
3413 * enum nl80211_coalesce_condition - coalesce rule conditions
3414 * @NL80211_COALESCE_CONDITION_MATCH: coalaesce Rx packets when patterns
3415 * in a rule are matched.
3416 * @NL80211_COALESCE_CONDITION_NO_MATCH: coalesce Rx packets when patterns
3417 * in a rule are not matched.
3418 */
3419enum nl80211_coalesce_condition {
3420 NL80211_COALESCE_CONDITION_MATCH,
3421 NL80211_COALESCE_CONDITION_NO_MATCH
3422};
3423
3424/**
3312 * enum nl80211_iface_limit_attrs - limit attributes 3425 * enum nl80211_iface_limit_attrs - limit attributes
3313 * @NL80211_IFACE_LIMIT_UNSPEC: (reserved) 3426 * @NL80211_IFACE_LIMIT_UNSPEC: (reserved)
3314 * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that 3427 * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 43dd7525bfcb..973594b229f4 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -395,9 +395,13 @@ void sta_set_rate_info_tx(struct sta_info *sta,
395 rinfo->nss = ieee80211_rate_get_vht_nss(rate); 395 rinfo->nss = ieee80211_rate_get_vht_nss(rate);
396 } else { 396 } else {
397 struct ieee80211_supported_band *sband; 397 struct ieee80211_supported_band *sband;
398 int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
399 u16 brate;
400
398 sband = sta->local->hw.wiphy->bands[ 401 sband = sta->local->hw.wiphy->bands[
399 ieee80211_get_sdata_band(sta->sdata)]; 402 ieee80211_get_sdata_band(sta->sdata)];
400 rinfo->legacy = sband->bitrates[rate->idx].bitrate; 403 brate = sband->bitrates[rate->idx].bitrate;
404 rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
401 } 405 }
402 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 406 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
403 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 407 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
@@ -422,11 +426,13 @@ void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
422 rinfo->mcs = sta->last_rx_rate_idx; 426 rinfo->mcs = sta->last_rx_rate_idx;
423 } else { 427 } else {
424 struct ieee80211_supported_band *sband; 428 struct ieee80211_supported_band *sband;
429 int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
430 u16 brate;
425 431
426 sband = sta->local->hw.wiphy->bands[ 432 sband = sta->local->hw.wiphy->bands[
427 ieee80211_get_sdata_band(sta->sdata)]; 433 ieee80211_get_sdata_band(sta->sdata)];
428 rinfo->legacy = 434 brate = sband->bitrates[sta->last_rx_rate_idx].bitrate;
429 sband->bitrates[sta->last_rx_rate_idx].bitrate; 435 rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
430 } 436 }
431 437
432 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) 438 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
@@ -1192,8 +1198,6 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1192 struct station_parameters *params) 1198 struct station_parameters *params)
1193{ 1199{
1194 int ret = 0; 1200 int ret = 0;
1195 u32 rates;
1196 int i, j;
1197 struct ieee80211_supported_band *sband; 1201 struct ieee80211_supported_band *sband;
1198 struct ieee80211_sub_if_data *sdata = sta->sdata; 1202 struct ieee80211_sub_if_data *sdata = sta->sdata;
1199 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 1203 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
@@ -1286,16 +1290,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1286 sta->listen_interval = params->listen_interval; 1290 sta->listen_interval = params->listen_interval;
1287 1291
1288 if (params->supported_rates) { 1292 if (params->supported_rates) {
1289 rates = 0; 1293 ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
1290 1294 sband, params->supported_rates,
1291 for (i = 0; i < params->supported_rates_len; i++) { 1295 params->supported_rates_len,
1292 int rate = (params->supported_rates[i] & 0x7f) * 5; 1296 &sta->sta.supp_rates[band]);
1293 for (j = 0; j < sband->n_bitrates; j++) {
1294 if (sband->bitrates[j].bitrate == rate)
1295 rates |= BIT(j);
1296 }
1297 }
1298 sta->sta.supp_rates[band] = rates;
1299 } 1297 }
1300 1298
1301 if (params->ht_capa) 1299 if (params->ht_capa)
@@ -1958,18 +1956,11 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1958 } 1956 }
1959 1957
1960 if (params->basic_rates) { 1958 if (params->basic_rates) {
1961 int i, j; 1959 ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
1962 u32 rates = 0; 1960 wiphy->bands[band],
1963 struct ieee80211_supported_band *sband = wiphy->bands[band]; 1961 params->basic_rates,
1964 1962 params->basic_rates_len,
1965 for (i = 0; i < params->basic_rates_len; i++) { 1963 &sdata->vif.bss_conf.basic_rates);
1966 int rate = (params->basic_rates[i] & 0x7f) * 5;
1967 for (j = 0; j < sband->n_bitrates; j++) {
1968 if (sband->bitrates[j].bitrate == rate)
1969 rates |= BIT(j);
1970 }
1971 }
1972 sdata->vif.bss_conf.basic_rates = rates;
1973 changed |= BSS_CHANGED_BASIC_RATES; 1964 changed |= BSS_CHANGED_BASIC_RATES;
1974 } 1965 }
1975 1966
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index f83534f6a2ee..529bf58bc145 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -19,13 +19,14 @@
19#include "ieee80211_i.h" 19#include "ieee80211_i.h"
20#include "rate.h" 20#include "rate.h"
21 21
22static void __check_htcap_disable(struct ieee80211_sub_if_data *sdata, 22static void __check_htcap_disable(struct ieee80211_ht_cap *ht_capa,
23 struct ieee80211_ht_cap *ht_capa_mask,
23 struct ieee80211_sta_ht_cap *ht_cap, 24 struct ieee80211_sta_ht_cap *ht_cap,
24 u16 flag) 25 u16 flag)
25{ 26{
26 __le16 le_flag = cpu_to_le16(flag); 27 __le16 le_flag = cpu_to_le16(flag);
27 if (sdata->u.mgd.ht_capa_mask.cap_info & le_flag) { 28 if (ht_capa_mask->cap_info & le_flag) {
28 if (!(sdata->u.mgd.ht_capa.cap_info & le_flag)) 29 if (!(ht_capa->cap_info & le_flag))
29 ht_cap->cap &= ~flag; 30 ht_cap->cap &= ~flag;
30 } 31 }
31} 32}
@@ -33,13 +34,30 @@ static void __check_htcap_disable(struct ieee80211_sub_if_data *sdata,
33void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, 34void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
34 struct ieee80211_sta_ht_cap *ht_cap) 35 struct ieee80211_sta_ht_cap *ht_cap)
35{ 36{
36 u8 *scaps = (u8 *)(&sdata->u.mgd.ht_capa.mcs.rx_mask); 37 struct ieee80211_ht_cap *ht_capa, *ht_capa_mask;
37 u8 *smask = (u8 *)(&sdata->u.mgd.ht_capa_mask.mcs.rx_mask); 38 u8 *scaps, *smask;
38 int i; 39 int i;
39 40
40 if (!ht_cap->ht_supported) 41 if (!ht_cap->ht_supported)
41 return; 42 return;
42 43
44 switch (sdata->vif.type) {
45 case NL80211_IFTYPE_STATION:
46 ht_capa = &sdata->u.mgd.ht_capa;
47 ht_capa_mask = &sdata->u.mgd.ht_capa_mask;
48 break;
49 case NL80211_IFTYPE_ADHOC:
50 ht_capa = &sdata->u.ibss.ht_capa;
51 ht_capa_mask = &sdata->u.ibss.ht_capa_mask;
52 break;
53 default:
54 WARN_ON_ONCE(1);
55 return;
56 }
57
58 scaps = (u8 *)(&ht_capa->mcs.rx_mask);
59 smask = (u8 *)(&ht_capa_mask->mcs.rx_mask);
60
43 /* NOTE: If you add more over-rides here, update register_hw 61 /* NOTE: If you add more over-rides here, update register_hw
44 * ht_capa_mod_msk logic in main.c as well. 62 * ht_capa_mod_msk logic in main.c as well.
45 * And, if this method can ever change ht_cap.ht_supported, fix 63 * And, if this method can ever change ht_cap.ht_supported, fix
@@ -55,28 +73,32 @@ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
55 } 73 }
56 74
57 /* Force removal of HT-40 capabilities? */ 75 /* Force removal of HT-40 capabilities? */
58 __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SUP_WIDTH_20_40); 76 __check_htcap_disable(ht_capa, ht_capa_mask, ht_cap,
59 __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SGI_40); 77 IEEE80211_HT_CAP_SUP_WIDTH_20_40);
78 __check_htcap_disable(ht_capa, ht_capa_mask, ht_cap,
79 IEEE80211_HT_CAP_SGI_40);
60 80
61 /* Allow user to disable SGI-20 (SGI-40 is handled above) */ 81 /* Allow user to disable SGI-20 (SGI-40 is handled above) */
62 __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SGI_20); 82 __check_htcap_disable(ht_capa, ht_capa_mask, ht_cap,
83 IEEE80211_HT_CAP_SGI_20);
63 84
64 /* Allow user to disable the max-AMSDU bit. */ 85 /* Allow user to disable the max-AMSDU bit. */
65 __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_MAX_AMSDU); 86 __check_htcap_disable(ht_capa, ht_capa_mask, ht_cap,
87 IEEE80211_HT_CAP_MAX_AMSDU);
66 88
67 /* Allow user to decrease AMPDU factor */ 89 /* Allow user to decrease AMPDU factor */
68 if (sdata->u.mgd.ht_capa_mask.ampdu_params_info & 90 if (ht_capa_mask->ampdu_params_info &
69 IEEE80211_HT_AMPDU_PARM_FACTOR) { 91 IEEE80211_HT_AMPDU_PARM_FACTOR) {
70 u8 n = sdata->u.mgd.ht_capa.ampdu_params_info 92 u8 n = ht_capa->ampdu_params_info &
71 & IEEE80211_HT_AMPDU_PARM_FACTOR; 93 IEEE80211_HT_AMPDU_PARM_FACTOR;
72 if (n < ht_cap->ampdu_factor) 94 if (n < ht_cap->ampdu_factor)
73 ht_cap->ampdu_factor = n; 95 ht_cap->ampdu_factor = n;
74 } 96 }
75 97
76 /* Allow the user to increase AMPDU density. */ 98 /* Allow the user to increase AMPDU density. */
77 if (sdata->u.mgd.ht_capa_mask.ampdu_params_info & 99 if (ht_capa_mask->ampdu_params_info &
78 IEEE80211_HT_AMPDU_PARM_DENSITY) { 100 IEEE80211_HT_AMPDU_PARM_DENSITY) {
79 u8 n = (sdata->u.mgd.ht_capa.ampdu_params_info & 101 u8 n = (ht_capa->ampdu_params_info &
80 IEEE80211_HT_AMPDU_PARM_DENSITY) 102 IEEE80211_HT_AMPDU_PARM_DENSITY)
81 >> IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT; 103 >> IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT;
82 if (n > ht_cap->ampdu_density) 104 if (n > ht_cap->ampdu_density)
@@ -112,7 +134,8 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
112 * we advertised a restricted capability set to. Override 134 * we advertised a restricted capability set to. Override
113 * our own capabilities and then use those below. 135 * our own capabilities and then use those below.
114 */ 136 */
115 if (sdata->vif.type == NL80211_IFTYPE_STATION && 137 if ((sdata->vif.type == NL80211_IFTYPE_STATION ||
138 sdata->vif.type == NL80211_IFTYPE_ADHOC) &&
116 !test_sta_flag(sta, WLAN_STA_TDLS_PEER)) 139 !test_sta_flag(sta, WLAN_STA_TDLS_PEER))
117 ieee80211_apply_htcap_overrides(sdata, &own_cap); 140 ieee80211_apply_htcap_overrides(sdata, &own_cap);
118 141
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index ea7b9c2c7e66..5e6836c3aa4c 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -43,16 +43,18 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
43{ 43{
44 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 44 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
45 struct ieee80211_local *local = sdata->local; 45 struct ieee80211_local *local = sdata->local;
46 int rates, i; 46 int rates_n = 0, i, ri;
47 struct ieee80211_mgmt *mgmt; 47 struct ieee80211_mgmt *mgmt;
48 u8 *pos; 48 u8 *pos;
49 struct ieee80211_supported_band *sband; 49 struct ieee80211_supported_band *sband;
50 struct cfg80211_bss *bss; 50 struct cfg80211_bss *bss;
51 u32 bss_change; 51 u32 bss_change, rate_flags, rates = 0, rates_added = 0;
52 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
53 struct cfg80211_chan_def chandef; 52 struct cfg80211_chan_def chandef;
53 enum nl80211_bss_scan_width scan_width;
54 bool have_higher_than_11mbit = false;
54 struct beacon_data *presp; 55 struct beacon_data *presp;
55 int frame_len; 56 int frame_len;
57 int shift;
56 58
57 sdata_assert_lock(sdata); 59 sdata_assert_lock(sdata);
58 60
@@ -83,6 +85,14 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
83 85
84 chandef = ifibss->chandef; 86 chandef = ifibss->chandef;
85 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { 87 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
88 if (chandef.width == NL80211_CHAN_WIDTH_5 ||
89 chandef.width == NL80211_CHAN_WIDTH_10 ||
90 chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
91 chandef.width == NL80211_CHAN_WIDTH_20) {
92 sdata_info(sdata,
93 "Failed to join IBSS, beacons forbidden\n");
94 return;
95 }
86 chandef.width = NL80211_CHAN_WIDTH_20; 96 chandef.width = NL80211_CHAN_WIDTH_20;
87 chandef.center_freq1 = chan->center_freq; 97 chandef.center_freq1 = chan->center_freq;
88 } 98 }
@@ -99,6 +109,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
99 memcpy(ifibss->bssid, bssid, ETH_ALEN); 109 memcpy(ifibss->bssid, bssid, ETH_ALEN);
100 110
101 sband = local->hw.wiphy->bands[chan->band]; 111 sband = local->hw.wiphy->bands[chan->band];
112 shift = ieee80211_vif_get_shift(&sdata->vif);
102 113
103 /* Build IBSS probe response */ 114 /* Build IBSS probe response */
104 frame_len = sizeof(struct ieee80211_hdr_3addr) + 115 frame_len = sizeof(struct ieee80211_hdr_3addr) +
@@ -134,15 +145,33 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
134 memcpy(pos, ifibss->ssid, ifibss->ssid_len); 145 memcpy(pos, ifibss->ssid, ifibss->ssid_len);
135 pos += ifibss->ssid_len; 146 pos += ifibss->ssid_len;
136 147
137 rates = min_t(int, 8, sband->n_bitrates); 148 rate_flags = ieee80211_chandef_rate_flags(&chandef);
149 for (i = 0; i < sband->n_bitrates; i++) {
150 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
151 continue;
152 if (sband->bitrates[i].bitrate > 110)
153 have_higher_than_11mbit = true;
154
155 rates |= BIT(i);
156 rates_n++;
157 }
158
138 *pos++ = WLAN_EID_SUPP_RATES; 159 *pos++ = WLAN_EID_SUPP_RATES;
139 *pos++ = rates; 160 *pos++ = min_t(int, 8, rates_n);
140 for (i = 0; i < rates; i++) { 161 for (ri = 0; ri < sband->n_bitrates; ri++) {
141 int rate = sband->bitrates[i].bitrate; 162 int rate = DIV_ROUND_UP(sband->bitrates[ri].bitrate,
163 5 * (1 << shift));
142 u8 basic = 0; 164 u8 basic = 0;
143 if (basic_rates & BIT(i)) 165 if (!(rates & BIT(ri)))
166 continue;
167
168 if (basic_rates & BIT(ri))
144 basic = 0x80; 169 basic = 0x80;
145 *pos++ = basic | (u8) (rate / 5); 170 *pos++ = basic | (u8) rate;
171 if (++rates_added == 8) {
172 ri++; /* continue at next rate for EXT_SUPP_RATES */
173 break;
174 }
146 } 175 }
147 176
148 if (sband->band == IEEE80211_BAND_2GHZ) { 177 if (sband->band == IEEE80211_BAND_2GHZ) {
@@ -157,15 +186,20 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
157 *pos++ = 0; 186 *pos++ = 0;
158 *pos++ = 0; 187 *pos++ = 0;
159 188
160 if (sband->n_bitrates > 8) { 189 /* put the remaining rates in WLAN_EID_EXT_SUPP_RATES */
190 if (rates_n > 8) {
161 *pos++ = WLAN_EID_EXT_SUPP_RATES; 191 *pos++ = WLAN_EID_EXT_SUPP_RATES;
162 *pos++ = sband->n_bitrates - 8; 192 *pos++ = rates_n - 8;
163 for (i = 8; i < sband->n_bitrates; i++) { 193 for (; ri < sband->n_bitrates; ri++) {
164 int rate = sband->bitrates[i].bitrate; 194 int rate = DIV_ROUND_UP(sband->bitrates[ri].bitrate,
195 5 * (1 << shift));
165 u8 basic = 0; 196 u8 basic = 0;
166 if (basic_rates & BIT(i)) 197 if (!(rates & BIT(ri)))
198 continue;
199
200 if (basic_rates & BIT(ri))
167 basic = 0x80; 201 basic = 0x80;
168 *pos++ = basic | (u8) (rate / 5); 202 *pos++ = basic | (u8) rate;
169 } 203 }
170 } 204 }
171 205
@@ -179,8 +213,12 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
179 chandef.width != NL80211_CHAN_WIDTH_5 && 213 chandef.width != NL80211_CHAN_WIDTH_5 &&
180 chandef.width != NL80211_CHAN_WIDTH_10 && 214 chandef.width != NL80211_CHAN_WIDTH_10 &&
181 sband->ht_cap.ht_supported) { 215 sband->ht_cap.ht_supported) {
182 pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, 216 struct ieee80211_sta_ht_cap ht_cap;
183 sband->ht_cap.cap); 217
218 memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
219 ieee80211_apply_htcap_overrides(sdata, &ht_cap);
220
221 pos = ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap);
184 /* 222 /*
185 * Note: According to 802.11n-2009 9.13.3.1, HT Protection 223 * Note: According to 802.11n-2009 9.13.3.1, HT Protection
186 * field and RIFS Mode are reserved in IBSS mode, therefore 224 * field and RIFS Mode are reserved in IBSS mode, therefore
@@ -236,18 +274,26 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
236 sdata->vif.bss_conf.use_short_slot = chan->band == IEEE80211_BAND_5GHZ; 274 sdata->vif.bss_conf.use_short_slot = chan->band == IEEE80211_BAND_5GHZ;
237 bss_change |= BSS_CHANGED_ERP_SLOT; 275 bss_change |= BSS_CHANGED_ERP_SLOT;
238 276
277 /* cf. IEEE 802.11 9.2.12 */
278 if (chan->band == IEEE80211_BAND_2GHZ && have_higher_than_11mbit)
279 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
280 else
281 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
282
239 sdata->vif.bss_conf.ibss_joined = true; 283 sdata->vif.bss_conf.ibss_joined = true;
240 sdata->vif.bss_conf.ibss_creator = creator; 284 sdata->vif.bss_conf.ibss_creator = creator;
241 ieee80211_bss_info_change_notify(sdata, bss_change); 285 ieee80211_bss_info_change_notify(sdata, bss_change);
242 286
243 ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); 287 ieee80211_set_wmm_default(sdata, true);
244 288
245 ifibss->state = IEEE80211_IBSS_MLME_JOINED; 289 ifibss->state = IEEE80211_IBSS_MLME_JOINED;
246 mod_timer(&ifibss->timer, 290 mod_timer(&ifibss->timer,
247 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); 291 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
248 292
249 bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan, 293 scan_width = cfg80211_chandef_to_scan_width(&chandef);
250 mgmt, presp->head_len, 0, GFP_KERNEL); 294 bss = cfg80211_inform_bss_width_frame(local->hw.wiphy, chan,
295 scan_width, mgmt,
296 presp->head_len, 0, GFP_KERNEL);
251 cfg80211_put_bss(local->hw.wiphy, bss); 297 cfg80211_put_bss(local->hw.wiphy, bss);
252 netif_carrier_on(sdata->dev); 298 netif_carrier_on(sdata->dev);
253 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); 299 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
@@ -264,6 +310,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
264 u16 beacon_int = cbss->beacon_interval; 310 u16 beacon_int = cbss->beacon_interval;
265 const struct cfg80211_bss_ies *ies; 311 const struct cfg80211_bss_ies *ies;
266 u64 tsf; 312 u64 tsf;
313 u32 rate_flags;
314 int shift;
267 315
268 sdata_assert_lock(sdata); 316 sdata_assert_lock(sdata);
269 317
@@ -271,15 +319,24 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
271 beacon_int = 10; 319 beacon_int = 10;
272 320
273 sband = sdata->local->hw.wiphy->bands[cbss->channel->band]; 321 sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
322 rate_flags = ieee80211_chandef_rate_flags(&sdata->u.ibss.chandef);
323 shift = ieee80211_vif_get_shift(&sdata->vif);
274 324
275 basic_rates = 0; 325 basic_rates = 0;
276 326
277 for (i = 0; i < bss->supp_rates_len; i++) { 327 for (i = 0; i < bss->supp_rates_len; i++) {
278 int rate = (bss->supp_rates[i] & 0x7f) * 5; 328 int rate = bss->supp_rates[i] & 0x7f;
279 bool is_basic = !!(bss->supp_rates[i] & 0x80); 329 bool is_basic = !!(bss->supp_rates[i] & 0x80);
280 330
281 for (j = 0; j < sband->n_bitrates; j++) { 331 for (j = 0; j < sband->n_bitrates; j++) {
282 if (sband->bitrates[j].bitrate == rate) { 332 int brate;
333 if ((rate_flags & sband->bitrates[j].flags)
334 != rate_flags)
335 continue;
336
337 brate = DIV_ROUND_UP(sband->bitrates[j].bitrate,
338 5 * (1 << shift));
339 if (brate == rate) {
283 if (is_basic) 340 if (is_basic)
284 basic_rates |= BIT(j); 341 basic_rates |= BIT(j);
285 break; 342 break;
@@ -335,6 +392,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
335 struct sta_info *sta; 392 struct sta_info *sta;
336 struct ieee80211_chanctx_conf *chanctx_conf; 393 struct ieee80211_chanctx_conf *chanctx_conf;
337 struct ieee80211_supported_band *sband; 394 struct ieee80211_supported_band *sband;
395 enum nl80211_bss_scan_width scan_width;
338 int band; 396 int band;
339 397
340 /* 398 /*
@@ -363,6 +421,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
363 if (WARN_ON_ONCE(!chanctx_conf)) 421 if (WARN_ON_ONCE(!chanctx_conf))
364 return NULL; 422 return NULL;
365 band = chanctx_conf->def.chan->band; 423 band = chanctx_conf->def.chan->band;
424 scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
366 rcu_read_unlock(); 425 rcu_read_unlock();
367 426
368 sta = sta_info_alloc(sdata, addr, GFP_KERNEL); 427 sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
@@ -376,7 +435,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
376 /* make sure mandatory rates are always added */ 435 /* make sure mandatory rates are always added */
377 sband = local->hw.wiphy->bands[band]; 436 sband = local->hw.wiphy->bands[band];
378 sta->sta.supp_rates[band] = supp_rates | 437 sta->sta.supp_rates[band] = supp_rates |
379 ieee80211_mandatory_rates(sband); 438 ieee80211_mandatory_rates(sband, scan_width);
380 439
381 return ieee80211_ibss_finish_sta(sta); 440 return ieee80211_ibss_finish_sta(sta);
382} 441}
@@ -440,6 +499,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
440 u64 beacon_timestamp, rx_timestamp; 499 u64 beacon_timestamp, rx_timestamp;
441 u32 supp_rates = 0; 500 u32 supp_rates = 0;
442 enum ieee80211_band band = rx_status->band; 501 enum ieee80211_band band = rx_status->band;
502 enum nl80211_bss_scan_width scan_width;
443 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; 503 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
444 bool rates_updated = false; 504 bool rates_updated = false;
445 505
@@ -461,16 +521,22 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
461 sta = sta_info_get(sdata, mgmt->sa); 521 sta = sta_info_get(sdata, mgmt->sa);
462 522
463 if (elems->supp_rates) { 523 if (elems->supp_rates) {
464 supp_rates = ieee80211_sta_get_rates(local, elems, 524 supp_rates = ieee80211_sta_get_rates(sdata, elems,
465 band, NULL); 525 band, NULL);
466 if (sta) { 526 if (sta) {
467 u32 prev_rates; 527 u32 prev_rates;
468 528
469 prev_rates = sta->sta.supp_rates[band]; 529 prev_rates = sta->sta.supp_rates[band];
470 /* make sure mandatory rates are always added */ 530 /* make sure mandatory rates are always added */
471 sta->sta.supp_rates[band] = supp_rates | 531 scan_width = NL80211_BSS_CHAN_WIDTH_20;
472 ieee80211_mandatory_rates(sband); 532 if (rx_status->flag & RX_FLAG_5MHZ)
533 scan_width = NL80211_BSS_CHAN_WIDTH_5;
534 if (rx_status->flag & RX_FLAG_10MHZ)
535 scan_width = NL80211_BSS_CHAN_WIDTH_10;
473 536
537 sta->sta.supp_rates[band] = supp_rates |
538 ieee80211_mandatory_rates(sband,
539 scan_width);
474 if (sta->sta.supp_rates[band] != prev_rates) { 540 if (sta->sta.supp_rates[band] != prev_rates) {
475 ibss_dbg(sdata, 541 ibss_dbg(sdata,
476 "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", 542 "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n",
@@ -585,7 +651,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
585 "beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", 651 "beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n",
586 mgmt->bssid); 652 mgmt->bssid);
587 ieee80211_sta_join_ibss(sdata, bss); 653 ieee80211_sta_join_ibss(sdata, bss);
588 supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); 654 supp_rates = ieee80211_sta_get_rates(sdata, elems, band, NULL);
589 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 655 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
590 supp_rates); 656 supp_rates);
591 rcu_read_unlock(); 657 rcu_read_unlock();
@@ -604,6 +670,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
604 struct sta_info *sta; 670 struct sta_info *sta;
605 struct ieee80211_chanctx_conf *chanctx_conf; 671 struct ieee80211_chanctx_conf *chanctx_conf;
606 struct ieee80211_supported_band *sband; 672 struct ieee80211_supported_band *sband;
673 enum nl80211_bss_scan_width scan_width;
607 int band; 674 int band;
608 675
609 /* 676 /*
@@ -629,6 +696,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
629 return; 696 return;
630 } 697 }
631 band = chanctx_conf->def.chan->band; 698 band = chanctx_conf->def.chan->band;
699 scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
632 rcu_read_unlock(); 700 rcu_read_unlock();
633 701
634 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); 702 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
@@ -640,7 +708,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
640 /* make sure mandatory rates are always added */ 708 /* make sure mandatory rates are always added */
641 sband = local->hw.wiphy->bands[band]; 709 sband = local->hw.wiphy->bands[band];
642 sta->sta.supp_rates[band] = supp_rates | 710 sta->sta.supp_rates[band] = supp_rates |
643 ieee80211_mandatory_rates(sband); 711 ieee80211_mandatory_rates(sband, scan_width);
644 712
645 spin_lock(&ifibss->incomplete_lock); 713 spin_lock(&ifibss->incomplete_lock);
646 list_add(&sta->list, &ifibss->incomplete_stations); 714 list_add(&sta->list, &ifibss->incomplete_stations);
@@ -679,6 +747,7 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
679static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) 747static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
680{ 748{
681 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 749 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
750 enum nl80211_bss_scan_width scan_width;
682 751
683 sdata_assert_lock(sdata); 752 sdata_assert_lock(sdata);
684 753
@@ -700,8 +769,9 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
700 sdata_info(sdata, 769 sdata_info(sdata,
701 "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); 770 "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n");
702 771
772 scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
703 ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len, 773 ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
704 NULL); 774 NULL, scan_width);
705} 775}
706 776
707static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) 777static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -751,6 +821,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
751 struct cfg80211_bss *cbss; 821 struct cfg80211_bss *cbss;
752 struct ieee80211_channel *chan = NULL; 822 struct ieee80211_channel *chan = NULL;
753 const u8 *bssid = NULL; 823 const u8 *bssid = NULL;
824 enum nl80211_bss_scan_width scan_width;
754 int active_ibss; 825 int active_ibss;
755 u16 capability; 826 u16 capability;
756 827
@@ -799,8 +870,10 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
799 IEEE80211_SCAN_INTERVAL)) { 870 IEEE80211_SCAN_INTERVAL)) {
800 sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); 871 sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
801 872
873 scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
802 ieee80211_request_ibss_scan(sdata, ifibss->ssid, 874 ieee80211_request_ibss_scan(sdata, ifibss->ssid,
803 ifibss->ssid_len, chan); 875 ifibss->ssid_len, chan,
876 scan_width);
804 } else { 877 } else {
805 int interval = IEEE80211_SCAN_INTERVAL; 878 int interval = IEEE80211_SCAN_INTERVAL;
806 879
@@ -1020,6 +1093,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1020 struct cfg80211_ibss_params *params) 1093 struct cfg80211_ibss_params *params)
1021{ 1094{
1022 u32 changed = 0; 1095 u32 changed = 0;
1096 u32 rate_flags;
1097 struct ieee80211_supported_band *sband;
1098 int i;
1023 1099
1024 if (params->bssid) { 1100 if (params->bssid) {
1025 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN); 1101 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
@@ -1030,6 +1106,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1030 sdata->u.ibss.privacy = params->privacy; 1106 sdata->u.ibss.privacy = params->privacy;
1031 sdata->u.ibss.control_port = params->control_port; 1107 sdata->u.ibss.control_port = params->control_port;
1032 sdata->u.ibss.basic_rates = params->basic_rates; 1108 sdata->u.ibss.basic_rates = params->basic_rates;
1109
1110 /* fix basic_rates if channel does not support these rates */
1111 rate_flags = ieee80211_chandef_rate_flags(&params->chandef);
1112 sband = sdata->local->hw.wiphy->bands[params->chandef.chan->band];
1113 for (i = 0; i < sband->n_bitrates; i++) {
1114 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
1115 sdata->u.ibss.basic_rates &= ~BIT(i);
1116 }
1033 memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate, 1117 memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
1034 sizeof(params->mcast_rate)); 1118 sizeof(params->mcast_rate));
1035 1119
@@ -1051,6 +1135,11 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1051 memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); 1135 memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
1052 sdata->u.ibss.ssid_len = params->ssid_len; 1136 sdata->u.ibss.ssid_len = params->ssid_len;
1053 1137
1138 memcpy(&sdata->u.ibss.ht_capa, &params->ht_capa,
1139 sizeof(sdata->u.ibss.ht_capa));
1140 memcpy(&sdata->u.ibss.ht_capa_mask, &params->ht_capa_mask,
1141 sizeof(sdata->u.ibss.ht_capa_mask));
1142
1054 /* 1143 /*
1055 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is 1144 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is
1056 * reserved, but an HT STA shall protect HT transmissions as though 1145 * reserved, but an HT STA shall protect HT transmissions as though
@@ -1131,6 +1220,11 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1131 presp = rcu_dereference_protected(ifibss->presp, 1220 presp = rcu_dereference_protected(ifibss->presp,
1132 lockdep_is_held(&sdata->wdev.mtx)); 1221 lockdep_is_held(&sdata->wdev.mtx));
1133 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); 1222 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
1223
1224 /* on the next join, re-program HT parameters */
1225 memset(&ifibss->ht_capa, 0, sizeof(ifibss->ht_capa));
1226 memset(&ifibss->ht_capa_mask, 0, sizeof(ifibss->ht_capa_mask));
1227
1134 sdata->vif.bss_conf.ibss_joined = false; 1228 sdata->vif.bss_conf.ibss_joined = false;
1135 sdata->vif.bss_conf.ibss_creator = false; 1229 sdata->vif.bss_conf.ibss_creator = false;
1136 sdata->vif.bss_conf.enable_beacon = false; 1230 sdata->vif.bss_conf.enable_beacon = false;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8412a303993a..3d32df1fbc6d 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -509,6 +509,9 @@ struct ieee80211_if_ibss {
509 /* probe response/beacon for IBSS */ 509 /* probe response/beacon for IBSS */
510 struct beacon_data __rcu *presp; 510 struct beacon_data __rcu *presp;
511 511
512 struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */
513 struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */
514
512 spinlock_t incomplete_lock; 515 spinlock_t incomplete_lock;
513 struct list_head incomplete_stations; 516 struct list_head incomplete_stations;
514 517
@@ -809,6 +812,34 @@ ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
809 return band; 812 return band;
810} 813}
811 814
815static inline int
816ieee80211_chandef_get_shift(struct cfg80211_chan_def *chandef)
817{
818 switch (chandef->width) {
819 case NL80211_CHAN_WIDTH_5:
820 return 2;
821 case NL80211_CHAN_WIDTH_10:
822 return 1;
823 default:
824 return 0;
825 }
826}
827
828static inline int
829ieee80211_vif_get_shift(struct ieee80211_vif *vif)
830{
831 struct ieee80211_chanctx_conf *chanctx_conf;
832 int shift = 0;
833
834 rcu_read_lock();
835 chanctx_conf = rcu_dereference(vif->chanctx_conf);
836 if (chanctx_conf)
837 shift = ieee80211_chandef_get_shift(&chanctx_conf->def);
838 rcu_read_unlock();
839
840 return shift;
841}
842
812enum sdata_queue_type { 843enum sdata_queue_type {
813 IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, 844 IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0,
814 IEEE80211_SDATA_QUEUE_AGG_START = 1, 845 IEEE80211_SDATA_QUEUE_AGG_START = 1,
@@ -1026,7 +1057,7 @@ struct ieee80211_local {
1026 struct cfg80211_ssid scan_ssid; 1057 struct cfg80211_ssid scan_ssid;
1027 struct cfg80211_scan_request *int_scan_req; 1058 struct cfg80211_scan_request *int_scan_req;
1028 struct cfg80211_scan_request *scan_req, *hw_scan_req; 1059 struct cfg80211_scan_request *scan_req, *hw_scan_req;
1029 struct ieee80211_channel *scan_channel; 1060 struct cfg80211_chan_def scan_chandef;
1030 enum ieee80211_band hw_scan_band; 1061 enum ieee80211_band hw_scan_band;
1031 int scan_channel_idx; 1062 int scan_channel_idx;
1032 int scan_ies_len; 1063 int scan_ies_len;
@@ -1306,7 +1337,8 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1306void ieee80211_scan_work(struct work_struct *work); 1337void ieee80211_scan_work(struct work_struct *work);
1307int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, 1338int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
1308 const u8 *ssid, u8 ssid_len, 1339 const u8 *ssid, u8 ssid_len,
1309 struct ieee80211_channel *chan); 1340 struct ieee80211_channel *chan,
1341 enum nl80211_bss_scan_width scan_width);
1310int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 1342int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
1311 struct cfg80211_scan_request *req); 1343 struct cfg80211_scan_request *req);
1312void ieee80211_scan_cancel(struct ieee80211_local *local); 1344void ieee80211_scan_cancel(struct ieee80211_local *local);
@@ -1465,7 +1497,8 @@ extern void *mac80211_wiphy_privid; /* for wiphy privid */
1465u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, 1497u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
1466 enum nl80211_iftype type); 1498 enum nl80211_iftype type);
1467int ieee80211_frame_duration(enum ieee80211_band band, size_t len, 1499int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
1468 int rate, int erp, int short_preamble); 1500 int rate, int erp, int short_preamble,
1501 int shift);
1469void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, 1502void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
1470 struct ieee80211_hdr *hdr, const u8 *tsc, 1503 struct ieee80211_hdr *hdr, const u8 *tsc,
1471 gfp_t gfp); 1504 gfp_t gfp);
@@ -1569,7 +1602,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1569int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1602int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1570 size_t buffer_len, const u8 *ie, size_t ie_len, 1603 size_t buffer_len, const u8 *ie, size_t ie_len,
1571 enum ieee80211_band band, u32 rate_mask, 1604 enum ieee80211_band band, u32 rate_mask,
1572 u8 channel); 1605 struct cfg80211_chan_def *chandef);
1573struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1606struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1574 u8 *dst, u32 ratemask, 1607 u8 *dst, u32 ratemask,
1575 struct ieee80211_channel *chan, 1608 struct ieee80211_channel *chan,
@@ -1582,10 +1615,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1582 u32 ratemask, bool directed, u32 tx_flags, 1615 u32 ratemask, bool directed, u32 tx_flags,
1583 struct ieee80211_channel *channel, bool scan); 1616 struct ieee80211_channel *channel, bool scan);
1584 1617
1585void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 1618u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
1586 const size_t supp_rates_len,
1587 const u8 *supp_rates);
1588u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
1589 struct ieee802_11_elems *elems, 1619 struct ieee802_11_elems *elems,
1590 enum ieee80211_band band, u32 *basic_rates); 1620 enum ieee80211_band band, u32 *basic_rates);
1591int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, 1621int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
@@ -1602,6 +1632,9 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1602 u16 prot_mode); 1632 u16 prot_mode);
1603u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, 1633u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1604 u32 cap); 1634 u32 cap);
1635int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
1636 const struct ieee80211_supported_band *sband,
1637 const u8 *srates, int srates_len, u32 *rates);
1605int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, 1638int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1606 struct sk_buff *skb, bool need_basic, 1639 struct sk_buff *skb, bool need_basic,
1607 enum ieee80211_band band); 1640 enum ieee80211_band band);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index cc117591f678..4c41c11958c8 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -54,7 +54,7 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
54 return false; 54 return false;
55 } 55 }
56 56
57 power = chanctx_conf->def.chan->max_power; 57 power = ieee80211_chandef_max_power(&chanctx_conf->def);
58 rcu_read_unlock(); 58 rcu_read_unlock();
59 59
60 if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL) 60 if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 091088ac7890..25eb35b01938 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -102,17 +102,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
102 102
103 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 103 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
104 104
105 if (local->scan_channel) { 105 if (local->scan_chandef.chan) {
106 chandef.chan = local->scan_channel; 106 chandef = local->scan_chandef;
107 /* If scanning on oper channel, use whatever channel-type
108 * is currently in use.
109 */
110 if (chandef.chan == local->_oper_chandef.chan) {
111 chandef = local->_oper_chandef;
112 } else {
113 chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
114 chandef.center_freq1 = chandef.chan->center_freq;
115 }
116 } else if (local->tmp_channel) { 107 } else if (local->tmp_channel) {
117 chandef.chan = local->tmp_channel; 108 chandef.chan = local->tmp_channel;
118 chandef.width = NL80211_CHAN_WIDTH_20_NOHT; 109 chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
@@ -151,7 +142,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
151 changed |= IEEE80211_CONF_CHANGE_SMPS; 142 changed |= IEEE80211_CONF_CHANGE_SMPS;
152 } 143 }
153 144
154 power = chandef.chan->max_power; 145 power = ieee80211_chandef_max_power(&chandef);
155 146
156 rcu_read_lock(); 147 rcu_read_lock();
157 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 148 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 447f41bbe744..885a5f6e2c21 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -62,7 +62,6 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
62 struct ieee802_11_elems *ie) 62 struct ieee802_11_elems *ie)
63{ 63{
64 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 64 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
65 struct ieee80211_local *local = sdata->local;
66 u32 basic_rates = 0; 65 u32 basic_rates = 0;
67 struct cfg80211_chan_def sta_chan_def; 66 struct cfg80211_chan_def sta_chan_def;
68 67
@@ -85,7 +84,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
85 (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) 84 (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
86 return false; 85 return false;
87 86
88 ieee80211_sta_get_rates(local, ie, ieee80211_get_sdata_band(sdata), 87 ieee80211_sta_get_rates(sdata, ie, ieee80211_get_sdata_band(sdata),
89 &basic_rates); 88 &basic_rates);
90 89
91 if (sdata->vif.bss_conf.basic_rates != basic_rates) 90 if (sdata->vif.bss_conf.basic_rates != basic_rates)
@@ -274,7 +273,9 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
274 neighbors = min_t(int, neighbors, IEEE80211_MAX_MESH_PEERINGS); 273 neighbors = min_t(int, neighbors, IEEE80211_MAX_MESH_PEERINGS);
275 *pos++ = neighbors << 1; 274 *pos++ = neighbors << 1;
276 /* Mesh capability */ 275 /* Mesh capability */
277 *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING; 276 *pos = 0x00;
277 *pos |= ifmsh->mshcfg.dot11MeshForwarding ?
278 IEEE80211_MESHCONF_CAPAB_FORWARDING : 0x00;
278 *pos |= ifmsh->accepting_plinks ? 279 *pos |= ifmsh->accepting_plinks ?
279 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 280 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
280 /* Mesh PS mode. See IEEE802.11-2012 8.4.2.100.8 */ 281 /* Mesh PS mode. See IEEE802.11-2012 8.4.2.100.8 */
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 02c05fa15c20..6b65d5055f5b 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -379,7 +379,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
379 u32 rates, basic_rates = 0, changed = 0; 379 u32 rates, basic_rates = 0, changed = 0;
380 380
381 sband = local->hw.wiphy->bands[band]; 381 sband = local->hw.wiphy->bands[band];
382 rates = ieee80211_sta_get_rates(local, elems, band, &basic_rates); 382 rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates);
383 383
384 spin_lock_bh(&sta->lock); 384 spin_lock_bh(&sta->lock);
385 sta->last_rx = jiffies; 385 sta->last_rx = jiffies;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cc9e02d79b55..21bccd849b3f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -489,27 +489,6 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
489 489
490/* frame sending functions */ 490/* frame sending functions */
491 491
492static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
493 struct ieee80211_supported_band *sband,
494 u32 *rates)
495{
496 int i, j, count;
497 *rates = 0;
498 count = 0;
499 for (i = 0; i < supp_rates_len; i++) {
500 int rate = (supp_rates[i] & 0x7F) * 5;
501
502 for (j = 0; j < sband->n_bitrates; j++)
503 if (sband->bitrates[j].bitrate == rate) {
504 *rates |= BIT(j);
505 count++;
506 break;
507 }
508 }
509
510 return count;
511}
512
513static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, 492static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
514 struct sk_buff *skb, u8 ap_ht_param, 493 struct sk_buff *skb, u8 ap_ht_param,
515 struct ieee80211_supported_band *sband, 494 struct ieee80211_supported_band *sband,
@@ -628,12 +607,12 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
628 struct ieee80211_mgmt *mgmt; 607 struct ieee80211_mgmt *mgmt;
629 u8 *pos, qos_info; 608 u8 *pos, qos_info;
630 size_t offset = 0, noffset; 609 size_t offset = 0, noffset;
631 int i, count, rates_len, supp_rates_len; 610 int i, count, rates_len, supp_rates_len, shift;
632 u16 capab; 611 u16 capab;
633 struct ieee80211_supported_band *sband; 612 struct ieee80211_supported_band *sband;
634 struct ieee80211_chanctx_conf *chanctx_conf; 613 struct ieee80211_chanctx_conf *chanctx_conf;
635 struct ieee80211_channel *chan; 614 struct ieee80211_channel *chan;
636 u32 rates = 0; 615 u32 rate_flags, rates = 0;
637 616
638 sdata_assert_lock(sdata); 617 sdata_assert_lock(sdata);
639 618
@@ -644,8 +623,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
644 return; 623 return;
645 } 624 }
646 chan = chanctx_conf->def.chan; 625 chan = chanctx_conf->def.chan;
626 rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
647 rcu_read_unlock(); 627 rcu_read_unlock();
648 sband = local->hw.wiphy->bands[chan->band]; 628 sband = local->hw.wiphy->bands[chan->band];
629 shift = ieee80211_vif_get_shift(&sdata->vif);
649 630
650 if (assoc_data->supp_rates_len) { 631 if (assoc_data->supp_rates_len) {
651 /* 632 /*
@@ -654,17 +635,24 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
654 * in the association request (e.g. D-Link DAP 1353 in 635 * in the association request (e.g. D-Link DAP 1353 in
655 * b-only mode)... 636 * b-only mode)...
656 */ 637 */
657 rates_len = ieee80211_compatible_rates(assoc_data->supp_rates, 638 rates_len = ieee80211_parse_bitrates(&chanctx_conf->def, sband,
658 assoc_data->supp_rates_len, 639 assoc_data->supp_rates,
659 sband, &rates); 640 assoc_data->supp_rates_len,
641 &rates);
660 } else { 642 } else {
661 /* 643 /*
662 * In case AP not provide any supported rates information 644 * In case AP not provide any supported rates information
663 * before association, we send information element(s) with 645 * before association, we send information element(s) with
664 * all rates that we support. 646 * all rates that we support.
665 */ 647 */
666 rates = ~0; 648 rates_len = 0;
667 rates_len = sband->n_bitrates; 649 for (i = 0; i < sband->n_bitrates; i++) {
650 if ((rate_flags & sband->bitrates[i].flags)
651 != rate_flags)
652 continue;
653 rates |= BIT(i);
654 rates_len++;
655 }
668 } 656 }
669 657
670 skb = alloc_skb(local->hw.extra_tx_headroom + 658 skb = alloc_skb(local->hw.extra_tx_headroom +
@@ -741,8 +729,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
741 count = 0; 729 count = 0;
742 for (i = 0; i < sband->n_bitrates; i++) { 730 for (i = 0; i < sband->n_bitrates; i++) {
743 if (BIT(i) & rates) { 731 if (BIT(i) & rates) {
744 int rate = sband->bitrates[i].bitrate; 732 int rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
745 *pos++ = (u8) (rate / 5); 733 5 * (1 << shift));
734 *pos++ = (u8) rate;
746 if (++count == 8) 735 if (++count == 8)
747 break; 736 break;
748 } 737 }
@@ -755,8 +744,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
755 744
756 for (i++; i < sband->n_bitrates; i++) { 745 for (i++; i < sband->n_bitrates; i++) {
757 if (BIT(i) & rates) { 746 if (BIT(i) & rates) {
758 int rate = sband->bitrates[i].bitrate; 747 int rate;
759 *pos++ = (u8) (rate / 5); 748 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
749 5 * (1 << shift));
750 *pos++ = (u8) rate;
760 } 751 }
761 } 752 }
762 } 753 }
@@ -767,7 +758,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
767 *pos++ = WLAN_EID_PWR_CAPABILITY; 758 *pos++ = WLAN_EID_PWR_CAPABILITY;
768 *pos++ = 2; 759 *pos++ = 2;
769 *pos++ = 0; /* min tx power */ 760 *pos++ = 0; /* min tx power */
770 *pos++ = chan->max_power; /* max tx power */ 761 /* max tx power */
762 *pos++ = ieee80211_chandef_max_power(&chanctx_conf->def);
771 763
772 /* 2. supported channels */ 764 /* 2. supported channels */
773 /* TODO: get this in reg domain format */ 765 /* TODO: get this in reg domain format */
@@ -2443,15 +2435,16 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
2443 u8 *supp_rates, unsigned int supp_rates_len, 2435 u8 *supp_rates, unsigned int supp_rates_len,
2444 u32 *rates, u32 *basic_rates, 2436 u32 *rates, u32 *basic_rates,
2445 bool *have_higher_than_11mbit, 2437 bool *have_higher_than_11mbit,
2446 int *min_rate, int *min_rate_index) 2438 int *min_rate, int *min_rate_index,
2439 int shift, u32 rate_flags)
2447{ 2440{
2448 int i, j; 2441 int i, j;
2449 2442
2450 for (i = 0; i < supp_rates_len; i++) { 2443 for (i = 0; i < supp_rates_len; i++) {
2451 int rate = (supp_rates[i] & 0x7f) * 5; 2444 int rate = supp_rates[i] & 0x7f;
2452 bool is_basic = !!(supp_rates[i] & 0x80); 2445 bool is_basic = !!(supp_rates[i] & 0x80);
2453 2446
2454 if (rate > 110) 2447 if ((rate * 5 * (1 << shift)) > 110)
2455 *have_higher_than_11mbit = true; 2448 *have_higher_than_11mbit = true;
2456 2449
2457 /* 2450 /*
@@ -2467,12 +2460,20 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
2467 continue; 2460 continue;
2468 2461
2469 for (j = 0; j < sband->n_bitrates; j++) { 2462 for (j = 0; j < sband->n_bitrates; j++) {
2470 if (sband->bitrates[j].bitrate == rate) { 2463 struct ieee80211_rate *br;
2464 int brate;
2465
2466 br = &sband->bitrates[j];
2467 if ((rate_flags & br->flags) != rate_flags)
2468 continue;
2469
2470 brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
2471 if (brate == rate) {
2471 *rates |= BIT(j); 2472 *rates |= BIT(j);
2472 if (is_basic) 2473 if (is_basic)
2473 *basic_rates |= BIT(j); 2474 *basic_rates |= BIT(j);
2474 if (rate < *min_rate) { 2475 if ((rate * 5) < *min_rate) {
2475 *min_rate = rate; 2476 *min_rate = rate * 5;
2476 *min_rate_index = j; 2477 *min_rate_index = j;
2477 } 2478 }
2478 break; 2479 break;
@@ -3902,27 +3903,40 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3902 if (!new_sta) 3903 if (!new_sta)
3903 return -ENOMEM; 3904 return -ENOMEM;
3904 } 3905 }
3905
3906 if (new_sta) { 3906 if (new_sta) {
3907 u32 rates = 0, basic_rates = 0; 3907 u32 rates = 0, basic_rates = 0;
3908 bool have_higher_than_11mbit; 3908 bool have_higher_than_11mbit;
3909 int min_rate = INT_MAX, min_rate_index = -1; 3909 int min_rate = INT_MAX, min_rate_index = -1;
3910 struct ieee80211_chanctx_conf *chanctx_conf;
3910 struct ieee80211_supported_band *sband; 3911 struct ieee80211_supported_band *sband;
3911 const struct cfg80211_bss_ies *ies; 3912 const struct cfg80211_bss_ies *ies;
3913 int shift;
3914 u32 rate_flags;
3912 3915
3913 sband = local->hw.wiphy->bands[cbss->channel->band]; 3916 sband = local->hw.wiphy->bands[cbss->channel->band];
3914 3917
3915 err = ieee80211_prep_channel(sdata, cbss); 3918 err = ieee80211_prep_channel(sdata, cbss);
3916 if (err) { 3919 if (err) {
3917 sta_info_free(local, new_sta); 3920 sta_info_free(local, new_sta);
3918 return err; 3921 return -EINVAL;
3919 } 3922 }
3923 shift = ieee80211_vif_get_shift(&sdata->vif);
3924
3925 rcu_read_lock();
3926 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3927 if (WARN_ON(!chanctx_conf)) {
3928 rcu_read_unlock();
3929 return -EINVAL;
3930 }
3931 rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
3932 rcu_read_unlock();
3920 3933
3921 ieee80211_get_rates(sband, bss->supp_rates, 3934 ieee80211_get_rates(sband, bss->supp_rates,
3922 bss->supp_rates_len, 3935 bss->supp_rates_len,
3923 &rates, &basic_rates, 3936 &rates, &basic_rates,
3924 &have_higher_than_11mbit, 3937 &have_higher_than_11mbit,
3925 &min_rate, &min_rate_index); 3938 &min_rate, &min_rate_index,
3939 shift, rate_flags);
3926 3940
3927 /* 3941 /*
3928 * This used to be a workaround for basic rates missing 3942 * This used to be a workaround for basic rates missing
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 30d58d2d13e2..ba63ac851c2b 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -232,37 +232,28 @@ static void rc_send_low_broadcast(s8 *idx, u32 basic_rates,
232 /* could not find a basic rate; use original selection */ 232 /* could not find a basic rate; use original selection */
233} 233}
234 234
235static inline s8 235static void __rate_control_send_low(struct ieee80211_hw *hw,
236rate_lowest_non_cck_index(struct ieee80211_supported_band *sband, 236 struct ieee80211_supported_band *sband,
237 struct ieee80211_sta *sta) 237 struct ieee80211_sta *sta,
238 struct ieee80211_tx_info *info)
238{ 239{
239 int i; 240 int i;
241 u32 rate_flags =
242 ieee80211_chandef_rate_flags(&hw->conf.chandef);
240 243
244 if ((sband->band == IEEE80211_BAND_2GHZ) &&
245 (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE))
246 rate_flags |= IEEE80211_RATE_ERP_G;
247
248 info->control.rates[0].idx = 0;
241 for (i = 0; i < sband->n_bitrates; i++) { 249 for (i = 0; i < sband->n_bitrates; i++) {
242 struct ieee80211_rate *srate = &sband->bitrates[i]; 250 if (!rate_supported(sta, sband->band, i))
243 if ((srate->bitrate == 10) || (srate->bitrate == 20) ||
244 (srate->bitrate == 55) || (srate->bitrate == 110))
245 continue; 251 continue;
246 252
247 if (rate_supported(sta, sband->band, i)) 253 info->control.rates[0].idx = i;
248 return i; 254 break;
249 } 255 }
250 256 WARN_ON_ONCE(i == sband->n_bitrates);
251 /* No matching rate found */
252 return 0;
253}
254
255static void __rate_control_send_low(struct ieee80211_hw *hw,
256 struct ieee80211_supported_band *sband,
257 struct ieee80211_sta *sta,
258 struct ieee80211_tx_info *info)
259{
260 if ((sband->band != IEEE80211_BAND_2GHZ) ||
261 !(info->flags & IEEE80211_TX_CTL_NO_CCK_RATE))
262 info->control.rates[0].idx = rate_lowest_index(sband, sta);
263 else
264 info->control.rates[0].idx =
265 rate_lowest_non_cck_index(sband, sta);
266 257
267 info->control.rates[0].count = 258 info->control.rates[0].count =
268 (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 259 (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
@@ -585,6 +576,7 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
585 u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN]; 576 u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
586 bool has_mcs_mask; 577 bool has_mcs_mask;
587 u32 mask; 578 u32 mask;
579 u32 rate_flags;
588 int i; 580 int i;
589 581
590 /* 582 /*
@@ -594,6 +586,12 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
594 */ 586 */
595 mask = sdata->rc_rateidx_mask[info->band]; 587 mask = sdata->rc_rateidx_mask[info->band];
596 has_mcs_mask = sdata->rc_has_mcs_mask[info->band]; 588 has_mcs_mask = sdata->rc_has_mcs_mask[info->band];
589 rate_flags =
590 ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
591 for (i = 0; i < sband->n_bitrates; i++)
592 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
593 mask &= ~BIT(i);
594
597 if (mask == (1 << sband->n_bitrates) - 1 && !has_mcs_mask) 595 if (mask == (1 << sband->n_bitrates) - 1 && !has_mcs_mask)
598 return; 596 return;
599 597
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index d35a5dd3fb13..5dedc56c94db 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -66,11 +66,12 @@ static inline void rate_control_rate_init(struct sta_info *sta)
66 } 66 }
67 67
68 sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band]; 68 sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
69 rcu_read_unlock();
70 69
71 ieee80211_sta_set_rx_nss(sta); 70 ieee80211_sta_set_rx_nss(sta);
72 71
73 ref->ops->rate_init(ref->priv, sband, ista, priv_sta); 72 ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
73 priv_sta);
74 rcu_read_unlock();
74 set_sta_flag(sta, WLAN_STA_RATE_CONTROL); 75 set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
75} 76}
76 77
@@ -81,10 +82,21 @@ static inline void rate_control_rate_update(struct ieee80211_local *local,
81 struct rate_control_ref *ref = local->rate_ctrl; 82 struct rate_control_ref *ref = local->rate_ctrl;
82 struct ieee80211_sta *ista = &sta->sta; 83 struct ieee80211_sta *ista = &sta->sta;
83 void *priv_sta = sta->rate_ctrl_priv; 84 void *priv_sta = sta->rate_ctrl_priv;
85 struct ieee80211_chanctx_conf *chanctx_conf;
86
87 if (ref && ref->ops->rate_update) {
88 rcu_read_lock();
84 89
85 if (ref && ref->ops->rate_update) 90 chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
86 ref->ops->rate_update(ref->priv, sband, ista, 91 if (WARN_ON(!chanctx_conf)) {
87 priv_sta, changed); 92 rcu_read_unlock();
93 return;
94 }
95
96 ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def,
97 ista, priv_sta, changed);
98 rcu_read_unlock();
99 }
88 drv_sta_rc_update(local, sta->sdata, &sta->sta, changed); 100 drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
89} 101}
90 102
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index e6512e2ffd20..8b5f7ef7c0c9 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -383,14 +383,18 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
383static void 383static void
384calc_rate_durations(enum ieee80211_band band, 384calc_rate_durations(enum ieee80211_band band,
385 struct minstrel_rate *d, 385 struct minstrel_rate *d,
386 struct ieee80211_rate *rate) 386 struct ieee80211_rate *rate,
387 struct cfg80211_chan_def *chandef)
387{ 388{
388 int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); 389 int erp = !!(rate->flags & IEEE80211_RATE_ERP_G);
390 int shift = ieee80211_chandef_get_shift(chandef);
389 391
390 d->perfect_tx_time = ieee80211_frame_duration(band, 1200, 392 d->perfect_tx_time = ieee80211_frame_duration(band, 1200,
391 rate->bitrate, erp, 1); 393 DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1,
394 shift);
392 d->ack_time = ieee80211_frame_duration(band, 10, 395 d->ack_time = ieee80211_frame_duration(band, 10,
393 rate->bitrate, erp, 1); 396 DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1,
397 shift);
394} 398}
395 399
396static void 400static void
@@ -418,21 +422,25 @@ init_sample_table(struct minstrel_sta_info *mi)
418 422
419static void 423static void
420minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, 424minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
421 struct ieee80211_sta *sta, void *priv_sta) 425 struct cfg80211_chan_def *chandef,
426 struct ieee80211_sta *sta, void *priv_sta)
422{ 427{
423 struct minstrel_sta_info *mi = priv_sta; 428 struct minstrel_sta_info *mi = priv_sta;
424 struct minstrel_priv *mp = priv; 429 struct minstrel_priv *mp = priv;
425 struct ieee80211_rate *ctl_rate; 430 struct ieee80211_rate *ctl_rate;
426 unsigned int i, n = 0; 431 unsigned int i, n = 0;
427 unsigned int t_slot = 9; /* FIXME: get real slot time */ 432 unsigned int t_slot = 9; /* FIXME: get real slot time */
433 u32 rate_flags;
428 434
429 mi->sta = sta; 435 mi->sta = sta;
430 mi->lowest_rix = rate_lowest_index(sband, sta); 436 mi->lowest_rix = rate_lowest_index(sband, sta);
431 ctl_rate = &sband->bitrates[mi->lowest_rix]; 437 ctl_rate = &sband->bitrates[mi->lowest_rix];
432 mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, 438 mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10,
433 ctl_rate->bitrate, 439 ctl_rate->bitrate,
434 !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1); 440 !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1,
441 ieee80211_chandef_get_shift(chandef));
435 442
443 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef);
436 memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate)); 444 memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate));
437 mi->max_prob_rate = 0; 445 mi->max_prob_rate = 0;
438 446
@@ -441,15 +449,22 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
441 unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; 449 unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0;
442 unsigned int tx_time_single; 450 unsigned int tx_time_single;
443 unsigned int cw = mp->cw_min; 451 unsigned int cw = mp->cw_min;
452 int shift;
444 453
445 if (!rate_supported(sta, sband->band, i)) 454 if (!rate_supported(sta, sband->band, i))
446 continue; 455 continue;
456 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
457 continue;
458
447 n++; 459 n++;
448 memset(mr, 0, sizeof(*mr)); 460 memset(mr, 0, sizeof(*mr));
449 461
450 mr->rix = i; 462 mr->rix = i;
451 mr->bitrate = sband->bitrates[i].bitrate / 5; 463 shift = ieee80211_chandef_get_shift(chandef);
452 calc_rate_durations(sband->band, mr, &sband->bitrates[i]); 464 mr->bitrate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
465 (1 << shift) * 5);
466 calc_rate_durations(sband->band, mr, &sband->bitrates[i],
467 chandef);
453 468
454 /* calculate maximum number of retransmissions before 469 /* calculate maximum number of retransmissions before
455 * fallback (based on maximum segment size) */ 470 * fallback (based on maximum segment size) */
@@ -547,6 +562,7 @@ minstrel_init_cck_rates(struct minstrel_priv *mp)
547{ 562{
548 static const int bitrates[4] = { 10, 20, 55, 110 }; 563 static const int bitrates[4] = { 10, 20, 55, 110 };
549 struct ieee80211_supported_band *sband; 564 struct ieee80211_supported_band *sband;
565 u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef);
550 int i, j; 566 int i, j;
551 567
552 sband = mp->hw->wiphy->bands[IEEE80211_BAND_2GHZ]; 568 sband = mp->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
@@ -559,6 +575,9 @@ minstrel_init_cck_rates(struct minstrel_priv *mp)
559 if (rate->flags & IEEE80211_RATE_ERP_G) 575 if (rate->flags & IEEE80211_RATE_ERP_G)
560 continue; 576 continue;
561 577
578 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
579 continue;
580
562 for (j = 0; j < ARRAY_SIZE(bitrates); j++) { 581 for (j = 0; j < ARRAY_SIZE(bitrates); j++) {
563 if (rate->bitrate != bitrates[j]) 582 if (rate->bitrate != bitrates[j])
564 continue; 583 continue;
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index f5aed963b22e..61569425b723 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -844,6 +844,7 @@ minstrel_ht_update_cck(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
844 844
845static void 845static void
846minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, 846minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
847 struct cfg80211_chan_def *chandef,
847 struct ieee80211_sta *sta, void *priv_sta) 848 struct ieee80211_sta *sta, void *priv_sta)
848{ 849{
849 struct minstrel_priv *mp = priv; 850 struct minstrel_priv *mp = priv;
@@ -869,8 +870,9 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
869 mi->sta = sta; 870 mi->sta = sta;
870 mi->stats_update = jiffies; 871 mi->stats_update = jiffies;
871 872
872 ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1); 873 ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1, 0);
873 mi->overhead = ieee80211_frame_duration(sband->band, 0, 60, 1, 1) + ack_dur; 874 mi->overhead = ieee80211_frame_duration(sband->band, 0, 60, 1, 1, 0);
875 mi->overhead += ack_dur;
874 mi->overhead_rtscts = mi->overhead + 2 * ack_dur; 876 mi->overhead_rtscts = mi->overhead + 2 * ack_dur;
875 877
876 mi->avg_ampdu_len = MINSTREL_FRAC(1, 1); 878 mi->avg_ampdu_len = MINSTREL_FRAC(1, 1);
@@ -939,22 +941,25 @@ use_legacy:
939 memset(&msp->legacy, 0, sizeof(msp->legacy)); 941 memset(&msp->legacy, 0, sizeof(msp->legacy));
940 msp->legacy.r = msp->ratelist; 942 msp->legacy.r = msp->ratelist;
941 msp->legacy.sample_table = msp->sample_table; 943 msp->legacy.sample_table = msp->sample_table;
942 return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy); 944 return mac80211_minstrel.rate_init(priv, sband, chandef, sta,
945 &msp->legacy);
943} 946}
944 947
945static void 948static void
946minstrel_ht_rate_init(void *priv, struct ieee80211_supported_band *sband, 949minstrel_ht_rate_init(void *priv, struct ieee80211_supported_band *sband,
950 struct cfg80211_chan_def *chandef,
947 struct ieee80211_sta *sta, void *priv_sta) 951 struct ieee80211_sta *sta, void *priv_sta)
948{ 952{
949 minstrel_ht_update_caps(priv, sband, sta, priv_sta); 953 minstrel_ht_update_caps(priv, sband, chandef, sta, priv_sta);
950} 954}
951 955
952static void 956static void
953minstrel_ht_rate_update(void *priv, struct ieee80211_supported_band *sband, 957minstrel_ht_rate_update(void *priv, struct ieee80211_supported_band *sband,
958 struct cfg80211_chan_def *chandef,
954 struct ieee80211_sta *sta, void *priv_sta, 959 struct ieee80211_sta *sta, void *priv_sta,
955 u32 changed) 960 u32 changed)
956{ 961{
957 minstrel_ht_update_caps(priv, sband, sta, priv_sta); 962 minstrel_ht_update_caps(priv, sband, chandef, sta, priv_sta);
958} 963}
959 964
960static void * 965static void *
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 502d3ecc4a79..958fad07b54c 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -293,6 +293,7 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
293 293
294static void 294static void
295rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband, 295rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
296 struct cfg80211_chan_def *chandef,
296 struct ieee80211_sta *sta, void *priv_sta) 297 struct ieee80211_sta *sta, void *priv_sta)
297{ 298{
298 struct rc_pid_sta_info *spinfo = priv_sta; 299 struct rc_pid_sta_info *spinfo = priv_sta;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 2c5a79bd3777..6b85f95b9ba1 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -87,11 +87,13 @@ ieee80211_rx_radiotap_space(struct ieee80211_local *local,
87 int len; 87 int len;
88 88
89 /* always present fields */ 89 /* always present fields */
90 len = sizeof(struct ieee80211_radiotap_header) + 9; 90 len = sizeof(struct ieee80211_radiotap_header) + 8;
91 91
92 /* allocate extra bitmap */ 92 /* allocate extra bitmaps */
93 if (status->vendor_radiotap_len) 93 if (status->vendor_radiotap_len)
94 len += 4; 94 len += 4;
95 if (status->chains)
96 len += 4 * hweight8(status->chains);
95 97
96 if (ieee80211_have_rx_timestamp(status)) { 98 if (ieee80211_have_rx_timestamp(status)) {
97 len = ALIGN(len, 8); 99 len = ALIGN(len, 8);
@@ -100,6 +102,10 @@ ieee80211_rx_radiotap_space(struct ieee80211_local *local,
100 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 102 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
101 len += 1; 103 len += 1;
102 104
105 /* antenna field, if we don't have per-chain info */
106 if (!status->chains)
107 len += 1;
108
103 /* padding for RX_FLAGS if necessary */ 109 /* padding for RX_FLAGS if necessary */
104 len = ALIGN(len, 2); 110 len = ALIGN(len, 2);
105 111
@@ -116,6 +122,11 @@ ieee80211_rx_radiotap_space(struct ieee80211_local *local,
116 len += 12; 122 len += 12;
117 } 123 }
118 124
125 if (status->chains) {
126 /* antenna and antenna signal fields */
127 len += 2 * hweight8(status->chains);
128 }
129
119 if (status->vendor_radiotap_len) { 130 if (status->vendor_radiotap_len) {
120 if (WARN_ON_ONCE(status->vendor_radiotap_align == 0)) 131 if (WARN_ON_ONCE(status->vendor_radiotap_align == 0))
121 status->vendor_radiotap_align = 1; 132 status->vendor_radiotap_align = 1;
@@ -145,8 +156,12 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
145 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 156 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
146 struct ieee80211_radiotap_header *rthdr; 157 struct ieee80211_radiotap_header *rthdr;
147 unsigned char *pos; 158 unsigned char *pos;
159 __le32 *it_present;
160 u32 it_present_val;
148 u16 rx_flags = 0; 161 u16 rx_flags = 0;
149 int mpdulen; 162 u16 channel_flags = 0;
163 int mpdulen, chain;
164 unsigned long chains = status->chains;
150 165
151 mpdulen = skb->len; 166 mpdulen = skb->len;
152 if (!(has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS))) 167 if (!(has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)))
@@ -154,25 +169,39 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
154 169
155 rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); 170 rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len);
156 memset(rthdr, 0, rtap_len); 171 memset(rthdr, 0, rtap_len);
172 it_present = &rthdr->it_present;
157 173
158 /* radiotap header, set always present flags */ 174 /* radiotap header, set always present flags */
159 rthdr->it_present =
160 cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
161 (1 << IEEE80211_RADIOTAP_CHANNEL) |
162 (1 << IEEE80211_RADIOTAP_ANTENNA) |
163 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
164 rthdr->it_len = cpu_to_le16(rtap_len + status->vendor_radiotap_len); 175 rthdr->it_len = cpu_to_le16(rtap_len + status->vendor_radiotap_len);
176 it_present_val = BIT(IEEE80211_RADIOTAP_FLAGS) |
177 BIT(IEEE80211_RADIOTAP_CHANNEL) |
178 BIT(IEEE80211_RADIOTAP_RX_FLAGS);
165 179
166 pos = (unsigned char *)(rthdr + 1); 180 if (!status->chains)
181 it_present_val |= BIT(IEEE80211_RADIOTAP_ANTENNA);
182
183 for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) {
184 it_present_val |=
185 BIT(IEEE80211_RADIOTAP_EXT) |
186 BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE);
187 put_unaligned_le32(it_present_val, it_present);
188 it_present++;
189 it_present_val = BIT(IEEE80211_RADIOTAP_ANTENNA) |
190 BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
191 }
167 192
168 if (status->vendor_radiotap_len) { 193 if (status->vendor_radiotap_len) {
169 rthdr->it_present |= 194 it_present_val |= BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE) |
170 cpu_to_le32(BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE)) | 195 BIT(IEEE80211_RADIOTAP_EXT);
171 cpu_to_le32(BIT(IEEE80211_RADIOTAP_EXT)); 196 put_unaligned_le32(it_present_val, it_present);
172 put_unaligned_le32(status->vendor_radiotap_bitmap, pos); 197 it_present++;
173 pos += 4; 198 it_present_val = status->vendor_radiotap_bitmap;
174 } 199 }
175 200
201 put_unaligned_le32(it_present_val, it_present);
202
203 pos = (void *)(it_present + 1);
204
176 /* the order of the following fields is important */ 205 /* the order of the following fields is important */
177 206
178 /* IEEE80211_RADIOTAP_TSFT */ 207 /* IEEE80211_RADIOTAP_TSFT */
@@ -207,28 +236,35 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
207 */ 236 */
208 *pos = 0; 237 *pos = 0;
209 } else { 238 } else {
239 int shift = 0;
210 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); 240 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
211 *pos = rate->bitrate / 5; 241 if (status->flag & RX_FLAG_10MHZ)
242 shift = 1;
243 else if (status->flag & RX_FLAG_5MHZ)
244 shift = 2;
245 *pos = DIV_ROUND_UP(rate->bitrate, 5 * (1 << shift));
212 } 246 }
213 pos++; 247 pos++;
214 248
215 /* IEEE80211_RADIOTAP_CHANNEL */ 249 /* IEEE80211_RADIOTAP_CHANNEL */
216 put_unaligned_le16(status->freq, pos); 250 put_unaligned_le16(status->freq, pos);
217 pos += 2; 251 pos += 2;
252 if (status->flag & RX_FLAG_10MHZ)
253 channel_flags |= IEEE80211_CHAN_HALF;
254 else if (status->flag & RX_FLAG_5MHZ)
255 channel_flags |= IEEE80211_CHAN_QUARTER;
256
218 if (status->band == IEEE80211_BAND_5GHZ) 257 if (status->band == IEEE80211_BAND_5GHZ)
219 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, 258 channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ;
220 pos);
221 else if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) 259 else if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
222 put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, 260 channel_flags |= IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
223 pos);
224 else if (rate && rate->flags & IEEE80211_RATE_ERP_G) 261 else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
225 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, 262 channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ;
226 pos);
227 else if (rate) 263 else if (rate)
228 put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, 264 channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ;
229 pos);
230 else 265 else
231 put_unaligned_le16(IEEE80211_CHAN_2GHZ, pos); 266 channel_flags |= IEEE80211_CHAN_2GHZ;
267 put_unaligned_le16(channel_flags, pos);
232 pos += 2; 268 pos += 2;
233 269
234 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ 270 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
@@ -242,9 +278,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
242 278
243 /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */ 279 /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */
244 280
245 /* IEEE80211_RADIOTAP_ANTENNA */ 281 if (!status->chains) {
246 *pos = status->antenna; 282 /* IEEE80211_RADIOTAP_ANTENNA */
247 pos++; 283 *pos = status->antenna;
284 pos++;
285 }
248 286
249 /* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */ 287 /* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */
250 288
@@ -341,6 +379,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
341 pos += 2; 379 pos += 2;
342 } 380 }
343 381
382 for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) {
383 *pos++ = status->chain_signal[chain];
384 *pos++ = chain;
385 }
386
344 if (status->vendor_radiotap_len) { 387 if (status->vendor_radiotap_len) {
345 /* ensure 2 byte alignment for the vendor field as required */ 388 /* ensure 2 byte alignment for the vendor field as required */
346 if ((pos - (u8 *)rthdr) & 1) 389 if ((pos - (u8 *)rthdr) & 1)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 1b122a79b0d8..08afe74b98f4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -66,6 +66,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
66 struct cfg80211_bss *cbss; 66 struct cfg80211_bss *cbss;
67 struct ieee80211_bss *bss; 67 struct ieee80211_bss *bss;
68 int clen, srlen; 68 int clen, srlen;
69 enum nl80211_bss_scan_width scan_width;
69 s32 signal = 0; 70 s32 signal = 0;
70 71
71 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 72 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
@@ -73,8 +74,15 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
73 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 74 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
74 signal = (rx_status->signal * 100) / local->hw.max_signal; 75 signal = (rx_status->signal * 100) / local->hw.max_signal;
75 76
76 cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel, 77 scan_width = NL80211_BSS_CHAN_WIDTH_20;
77 mgmt, len, signal, GFP_ATOMIC); 78 if (rx_status->flag & RX_FLAG_5MHZ)
79 scan_width = NL80211_BSS_CHAN_WIDTH_5;
80 if (rx_status->flag & RX_FLAG_10MHZ)
81 scan_width = NL80211_BSS_CHAN_WIDTH_10;
82
83 cbss = cfg80211_inform_bss_width_frame(local->hw.wiphy, channel,
84 scan_width, mgmt, len, signal,
85 GFP_ATOMIC);
78 if (!cbss) 86 if (!cbss)
79 return NULL; 87 return NULL;
80 88
@@ -204,10 +212,29 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
204 ieee80211_rx_bss_put(local, bss); 212 ieee80211_rx_bss_put(local, bss);
205} 213}
206 214
215static void
216ieee80211_prepare_scan_chandef(struct cfg80211_chan_def *chandef,
217 enum nl80211_bss_scan_width scan_width)
218{
219 memset(chandef, 0, sizeof(*chandef));
220 switch (scan_width) {
221 case NL80211_BSS_CHAN_WIDTH_5:
222 chandef->width = NL80211_CHAN_WIDTH_5;
223 break;
224 case NL80211_BSS_CHAN_WIDTH_10:
225 chandef->width = NL80211_CHAN_WIDTH_10;
226 break;
227 default:
228 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
229 break;
230 }
231}
232
207/* return false if no more work */ 233/* return false if no more work */
208static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) 234static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
209{ 235{
210 struct cfg80211_scan_request *req = local->scan_req; 236 struct cfg80211_scan_request *req = local->scan_req;
237 struct cfg80211_chan_def chandef;
211 enum ieee80211_band band; 238 enum ieee80211_band band;
212 int i, ielen, n_chans; 239 int i, ielen, n_chans;
213 240
@@ -229,11 +256,12 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
229 } while (!n_chans); 256 } while (!n_chans);
230 257
231 local->hw_scan_req->n_channels = n_chans; 258 local->hw_scan_req->n_channels = n_chans;
259 ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
232 260
233 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, 261 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
234 local->hw_scan_ies_bufsize, 262 local->hw_scan_ies_bufsize,
235 req->ie, req->ie_len, band, 263 req->ie, req->ie_len, band,
236 req->rates[band], 0); 264 req->rates[band], &chandef);
237 local->hw_scan_req->ie_len = ielen; 265 local->hw_scan_req->ie_len = ielen;
238 local->hw_scan_req->no_cck = req->no_cck; 266 local->hw_scan_req->no_cck = req->no_cck;
239 267
@@ -280,7 +308,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
280 rcu_assign_pointer(local->scan_sdata, NULL); 308 rcu_assign_pointer(local->scan_sdata, NULL);
281 309
282 local->scanning = 0; 310 local->scanning = 0;
283 local->scan_channel = NULL; 311 local->scan_chandef.chan = NULL;
284 312
285 /* Set power back to normal operating levels. */ 313 /* Set power back to normal operating levels. */
286 ieee80211_hw_config(local, 0); 314 ieee80211_hw_config(local, 0);
@@ -615,11 +643,34 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
615{ 643{
616 int skip; 644 int skip;
617 struct ieee80211_channel *chan; 645 struct ieee80211_channel *chan;
646 enum nl80211_bss_scan_width oper_scan_width;
618 647
619 skip = 0; 648 skip = 0;
620 chan = local->scan_req->channels[local->scan_channel_idx]; 649 chan = local->scan_req->channels[local->scan_channel_idx];
621 650
622 local->scan_channel = chan; 651 local->scan_chandef.chan = chan;
652 local->scan_chandef.center_freq1 = chan->center_freq;
653 local->scan_chandef.center_freq2 = 0;
654 switch (local->scan_req->scan_width) {
655 case NL80211_BSS_CHAN_WIDTH_5:
656 local->scan_chandef.width = NL80211_CHAN_WIDTH_5;
657 break;
658 case NL80211_BSS_CHAN_WIDTH_10:
659 local->scan_chandef.width = NL80211_CHAN_WIDTH_10;
660 break;
661 case NL80211_BSS_CHAN_WIDTH_20:
662 /* If scanning on oper channel, use whatever channel-type
663 * is currently in use.
664 */
665 oper_scan_width = cfg80211_chandef_to_scan_width(
666 &local->_oper_chandef);
667 if (chan == local->_oper_chandef.chan &&
668 oper_scan_width == local->scan_req->scan_width)
669 local->scan_chandef = local->_oper_chandef;
670 else
671 local->scan_chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
672 break;
673 }
623 674
624 if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) 675 if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))
625 skip = 1; 676 skip = 1;
@@ -659,7 +710,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
659 unsigned long *next_delay) 710 unsigned long *next_delay)
660{ 711{
661 /* switch back to the operating channel */ 712 /* switch back to the operating channel */
662 local->scan_channel = NULL; 713 local->scan_chandef.chan = NULL;
663 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 714 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
664 715
665 /* disable PS */ 716 /* disable PS */
@@ -801,7 +852,8 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
801 852
802int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, 853int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
803 const u8 *ssid, u8 ssid_len, 854 const u8 *ssid, u8 ssid_len,
804 struct ieee80211_channel *chan) 855 struct ieee80211_channel *chan,
856 enum nl80211_bss_scan_width scan_width)
805{ 857{
806 struct ieee80211_local *local = sdata->local; 858 struct ieee80211_local *local = sdata->local;
807 int ret = -EBUSY; 859 int ret = -EBUSY;
@@ -851,6 +903,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
851 903
852 local->int_scan_req->ssids = &local->scan_ssid; 904 local->int_scan_req->ssids = &local->scan_ssid;
853 local->int_scan_req->n_ssids = 1; 905 local->int_scan_req->n_ssids = 1;
906 local->int_scan_req->scan_width = scan_width;
854 memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); 907 memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
855 local->int_scan_req->ssids[0].ssid_len = ssid_len; 908 local->int_scan_req->ssids[0].ssid_len = ssid_len;
856 909
@@ -912,6 +965,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
912{ 965{
913 struct ieee80211_local *local = sdata->local; 966 struct ieee80211_local *local = sdata->local;
914 struct ieee80211_sched_scan_ies sched_scan_ies = {}; 967 struct ieee80211_sched_scan_ies sched_scan_ies = {};
968 struct cfg80211_chan_def chandef;
915 int ret, i, iebufsz; 969 int ret, i, iebufsz;
916 970
917 iebufsz = 2 + IEEE80211_MAX_SSID_LEN + 971 iebufsz = 2 + IEEE80211_MAX_SSID_LEN +
@@ -939,10 +993,12 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
939 goto out_free; 993 goto out_free;
940 } 994 }
941 995
996 ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
997
942 sched_scan_ies.len[i] = 998 sched_scan_ies.len[i] =
943 ieee80211_build_preq_ies(local, sched_scan_ies.ie[i], 999 ieee80211_build_preq_ies(local, sched_scan_ies.ie[i],
944 iebufsz, req->ie, req->ie_len, 1000 iebufsz, req->ie, req->ie_len,
945 i, (u32) -1, 0); 1001 i, (u32) -1, &chandef);
946 } 1002 }
947 1003
948 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); 1004 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 43439203f4e4..6ad4c14385ef 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -252,9 +252,10 @@ static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info)
252 return len; 252 return len;
253} 253}
254 254
255static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band 255static void
256 *sband, struct sk_buff *skb, 256ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband,
257 int retry_count, int rtap_len) 257 struct sk_buff *skb, int retry_count,
258 int rtap_len, int shift)
258{ 259{
259 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 260 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
260 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 261 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -280,8 +281,11 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
280 /* IEEE80211_RADIOTAP_RATE */ 281 /* IEEE80211_RADIOTAP_RATE */
281 if (info->status.rates[0].idx >= 0 && 282 if (info->status.rates[0].idx >= 0 &&
282 !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) { 283 !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) {
284 u16 rate;
285
283 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); 286 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
284 *pos = sband->bitrates[info->status.rates[0].idx].bitrate / 5; 287 rate = sband->bitrates[info->status.rates[0].idx].bitrate;
288 *pos = DIV_ROUND_UP(rate, 5 * (1 << shift));
285 /* padding for tx flags */ 289 /* padding for tx flags */
286 pos += 2; 290 pos += 2;
287 } 291 }
@@ -424,6 +428,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
424 bool acked; 428 bool acked;
425 struct ieee80211_bar *bar; 429 struct ieee80211_bar *bar;
426 int rtap_len; 430 int rtap_len;
431 int shift = 0;
427 432
428 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 433 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
429 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && 434 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
@@ -458,6 +463,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
458 if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr)) 463 if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr))
459 continue; 464 continue;
460 465
466 shift = ieee80211_vif_get_shift(&sta->sdata->vif);
467
461 if (info->flags & IEEE80211_TX_STATUS_EOSP) 468 if (info->flags & IEEE80211_TX_STATUS_EOSP)
462 clear_sta_flag(sta, WLAN_STA_SP); 469 clear_sta_flag(sta, WLAN_STA_SP);
463 470
@@ -624,7 +631,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
624 dev_kfree_skb(skb); 631 dev_kfree_skb(skb);
625 return; 632 return;
626 } 633 }
627 ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len); 634 ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len,
635 shift);
628 636
629 /* XXX: is this sufficient for BPF? */ 637 /* XXX: is this sufficient for BPF? */
630 skb_set_mac_header(skb, 0); 638 skb_set_mac_header(skb, 0);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 4105d0ca963e..be4d3caf4879 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -40,12 +40,22 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
40 struct sk_buff *skb, int group_addr, 40 struct sk_buff *skb, int group_addr,
41 int next_frag_len) 41 int next_frag_len)
42{ 42{
43 int rate, mrate, erp, dur, i; 43 int rate, mrate, erp, dur, i, shift = 0;
44 struct ieee80211_rate *txrate; 44 struct ieee80211_rate *txrate;
45 struct ieee80211_local *local = tx->local; 45 struct ieee80211_local *local = tx->local;
46 struct ieee80211_supported_band *sband; 46 struct ieee80211_supported_band *sband;
47 struct ieee80211_hdr *hdr; 47 struct ieee80211_hdr *hdr;
48 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 48 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
49 struct ieee80211_chanctx_conf *chanctx_conf;
50 u32 rate_flags = 0;
51
52 rcu_read_lock();
53 chanctx_conf = rcu_dereference(tx->sdata->vif.chanctx_conf);
54 if (chanctx_conf) {
55 shift = ieee80211_chandef_get_shift(&chanctx_conf->def);
56 rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
57 }
58 rcu_read_unlock();
49 59
50 /* assume HW handles this */ 60 /* assume HW handles this */
51 if (tx->rate.flags & IEEE80211_TX_RC_MCS) 61 if (tx->rate.flags & IEEE80211_TX_RC_MCS)
@@ -122,8 +132,11 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
122 if (r->bitrate > txrate->bitrate) 132 if (r->bitrate > txrate->bitrate)
123 break; 133 break;
124 134
135 if ((rate_flags & r->flags) != rate_flags)
136 continue;
137
125 if (tx->sdata->vif.bss_conf.basic_rates & BIT(i)) 138 if (tx->sdata->vif.bss_conf.basic_rates & BIT(i))
126 rate = r->bitrate; 139 rate = DIV_ROUND_UP(r->bitrate, 1 << shift);
127 140
128 switch (sband->band) { 141 switch (sband->band) {
129 case IEEE80211_BAND_2GHZ: { 142 case IEEE80211_BAND_2GHZ: {
@@ -150,7 +163,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
150 if (rate == -1) { 163 if (rate == -1) {
151 /* No matching basic rate found; use highest suitable mandatory 164 /* No matching basic rate found; use highest suitable mandatory
152 * PHY rate */ 165 * PHY rate */
153 rate = mrate; 166 rate = DIV_ROUND_UP(mrate, 1 << shift);
154 } 167 }
155 168
156 /* Don't calculate ACKs for QoS Frames with NoAck Policy set */ 169 /* Don't calculate ACKs for QoS Frames with NoAck Policy set */
@@ -162,7 +175,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
162 * (10 bytes + 4-byte FCS = 112 bits) plus SIFS; rounded up 175 * (10 bytes + 4-byte FCS = 112 bits) plus SIFS; rounded up
163 * to closest integer */ 176 * to closest integer */
164 dur = ieee80211_frame_duration(sband->band, 10, rate, erp, 177 dur = ieee80211_frame_duration(sband->band, 10, rate, erp,
165 tx->sdata->vif.bss_conf.use_short_preamble); 178 tx->sdata->vif.bss_conf.use_short_preamble,
179 shift);
166 180
167 if (next_frag_len) { 181 if (next_frag_len) {
168 /* Frame is fragmented: duration increases with time needed to 182 /* Frame is fragmented: duration increases with time needed to
@@ -171,7 +185,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
171 /* next fragment */ 185 /* next fragment */
172 dur += ieee80211_frame_duration(sband->band, next_frag_len, 186 dur += ieee80211_frame_duration(sband->band, next_frag_len,
173 txrate->bitrate, erp, 187 txrate->bitrate, erp,
174 tx->sdata->vif.bss_conf.use_short_preamble); 188 tx->sdata->vif.bss_conf.use_short_preamble,
189 shift);
175 } 190 }
176 191
177 return cpu_to_le16(dur); 192 return cpu_to_le16(dur);
@@ -1257,6 +1272,10 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
1257 1272
1258 switch (sdata->vif.type) { 1273 switch (sdata->vif.type) {
1259 case NL80211_IFTYPE_MONITOR: 1274 case NL80211_IFTYPE_MONITOR:
1275 if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
1276 vif = &sdata->vif;
1277 break;
1278 }
1260 sdata = rcu_dereference(local->monitor_sdata); 1279 sdata = rcu_dereference(local->monitor_sdata);
1261 if (sdata) { 1280 if (sdata) {
1262 vif = &sdata->vif; 1281 vif = &sdata->vif;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 22654452a561..d23c5a705a68 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -107,7 +107,8 @@ void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
107} 107}
108 108
109int ieee80211_frame_duration(enum ieee80211_band band, size_t len, 109int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
110 int rate, int erp, int short_preamble) 110 int rate, int erp, int short_preamble,
111 int shift)
111{ 112{
112 int dur; 113 int dur;
113 114
@@ -118,6 +119,9 @@ int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
118 * 119 *
119 * rate is in 100 kbps, so divident is multiplied by 10 in the 120 * rate is in 100 kbps, so divident is multiplied by 10 in the
120 * DIV_ROUND_UP() operations. 121 * DIV_ROUND_UP() operations.
122 *
123 * shift may be 2 for 5 MHz channels or 1 for 10 MHz channels, and
124 * is assumed to be 0 otherwise.
121 */ 125 */
122 126
123 if (band == IEEE80211_BAND_5GHZ || erp) { 127 if (band == IEEE80211_BAND_5GHZ || erp) {
@@ -130,13 +134,23 @@ int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
130 * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext 134 * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext
131 * 135 *
132 * T_SYM = 4 usec 136 * T_SYM = 4 usec
133 * 802.11a - 17.5.2: aSIFSTime = 16 usec 137 * 802.11a - 18.5.2: aSIFSTime = 16 usec
134 * 802.11g - 19.8.4: aSIFSTime = 10 usec + 138 * 802.11g - 19.8.4: aSIFSTime = 10 usec +
135 * signal ext = 6 usec 139 * signal ext = 6 usec
136 */ 140 */
137 dur = 16; /* SIFS + signal ext */ 141 dur = 16; /* SIFS + signal ext */
138 dur += 16; /* 17.3.2.3: T_PREAMBLE = 16 usec */ 142 dur += 16; /* IEEE 802.11-2012 18.3.2.4: T_PREAMBLE = 16 usec */
139 dur += 4; /* 17.3.2.3: T_SIGNAL = 4 usec */ 143 dur += 4; /* IEEE 802.11-2012 18.3.2.4: T_SIGNAL = 4 usec */
144
145 /* IEEE 802.11-2012 18.3.2.4: all values above are:
146 * * times 4 for 5 MHz
147 * * times 2 for 10 MHz
148 */
149 dur *= 1 << shift;
150
151 /* rates should already consider the channel bandwidth,
152 * don't apply divisor again.
153 */
140 dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10, 154 dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
141 4 * rate); /* T_SYM x N_SYM */ 155 4 * rate); /* T_SYM x N_SYM */
142 } else { 156 } else {
@@ -168,7 +182,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
168{ 182{
169 struct ieee80211_sub_if_data *sdata; 183 struct ieee80211_sub_if_data *sdata;
170 u16 dur; 184 u16 dur;
171 int erp; 185 int erp, shift = 0;
172 bool short_preamble = false; 186 bool short_preamble = false;
173 187
174 erp = 0; 188 erp = 0;
@@ -177,10 +191,11 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
177 short_preamble = sdata->vif.bss_conf.use_short_preamble; 191 short_preamble = sdata->vif.bss_conf.use_short_preamble;
178 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 192 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
179 erp = rate->flags & IEEE80211_RATE_ERP_G; 193 erp = rate->flags & IEEE80211_RATE_ERP_G;
194 shift = ieee80211_vif_get_shift(vif);
180 } 195 }
181 196
182 dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp, 197 dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp,
183 short_preamble); 198 short_preamble, shift);
184 199
185 return cpu_to_le16(dur); 200 return cpu_to_le16(dur);
186} 201}
@@ -194,7 +209,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
194 struct ieee80211_rate *rate; 209 struct ieee80211_rate *rate;
195 struct ieee80211_sub_if_data *sdata; 210 struct ieee80211_sub_if_data *sdata;
196 bool short_preamble; 211 bool short_preamble;
197 int erp; 212 int erp, shift = 0, bitrate;
198 u16 dur; 213 u16 dur;
199 struct ieee80211_supported_band *sband; 214 struct ieee80211_supported_band *sband;
200 215
@@ -210,17 +225,20 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
210 short_preamble = sdata->vif.bss_conf.use_short_preamble; 225 short_preamble = sdata->vif.bss_conf.use_short_preamble;
211 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 226 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
212 erp = rate->flags & IEEE80211_RATE_ERP_G; 227 erp = rate->flags & IEEE80211_RATE_ERP_G;
228 shift = ieee80211_vif_get_shift(vif);
213 } 229 }
214 230
231 bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
232
215 /* CTS duration */ 233 /* CTS duration */
216 dur = ieee80211_frame_duration(sband->band, 10, rate->bitrate, 234 dur = ieee80211_frame_duration(sband->band, 10, bitrate,
217 erp, short_preamble); 235 erp, short_preamble, shift);
218 /* Data frame duration */ 236 /* Data frame duration */
219 dur += ieee80211_frame_duration(sband->band, frame_len, rate->bitrate, 237 dur += ieee80211_frame_duration(sband->band, frame_len, bitrate,
220 erp, short_preamble); 238 erp, short_preamble, shift);
221 /* ACK duration */ 239 /* ACK duration */
222 dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate, 240 dur += ieee80211_frame_duration(sband->band, 10, bitrate,
223 erp, short_preamble); 241 erp, short_preamble, shift);
224 242
225 return cpu_to_le16(dur); 243 return cpu_to_le16(dur);
226} 244}
@@ -235,7 +253,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
235 struct ieee80211_rate *rate; 253 struct ieee80211_rate *rate;
236 struct ieee80211_sub_if_data *sdata; 254 struct ieee80211_sub_if_data *sdata;
237 bool short_preamble; 255 bool short_preamble;
238 int erp; 256 int erp, shift = 0, bitrate;
239 u16 dur; 257 u16 dur;
240 struct ieee80211_supported_band *sband; 258 struct ieee80211_supported_band *sband;
241 259
@@ -250,15 +268,18 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
250 short_preamble = sdata->vif.bss_conf.use_short_preamble; 268 short_preamble = sdata->vif.bss_conf.use_short_preamble;
251 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 269 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
252 erp = rate->flags & IEEE80211_RATE_ERP_G; 270 erp = rate->flags & IEEE80211_RATE_ERP_G;
271 shift = ieee80211_vif_get_shift(vif);
253 } 272 }
254 273
274 bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
275
255 /* Data frame duration */ 276 /* Data frame duration */
256 dur = ieee80211_frame_duration(sband->band, frame_len, rate->bitrate, 277 dur = ieee80211_frame_duration(sband->band, frame_len, bitrate,
257 erp, short_preamble); 278 erp, short_preamble, shift);
258 if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) { 279 if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
259 /* ACK duration */ 280 /* ACK duration */
260 dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate, 281 dur += ieee80211_frame_duration(sband->band, 10, bitrate,
261 erp, short_preamble); 282 erp, short_preamble, shift);
262 } 283 }
263 284
264 return cpu_to_le16(dur); 285 return cpu_to_le16(dur);
@@ -1052,32 +1073,6 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1052 } 1073 }
1053} 1074}
1054 1075
1055void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
1056 const size_t supp_rates_len,
1057 const u8 *supp_rates)
1058{
1059 struct ieee80211_chanctx_conf *chanctx_conf;
1060 int i, have_higher_than_11mbit = 0;
1061
1062 /* cf. IEEE 802.11 9.2.12 */
1063 for (i = 0; i < supp_rates_len; i++)
1064 if ((supp_rates[i] & 0x7f) * 5 > 110)
1065 have_higher_than_11mbit = 1;
1066
1067 rcu_read_lock();
1068 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1069
1070 if (chanctx_conf &&
1071 chanctx_conf->def.chan->band == IEEE80211_BAND_2GHZ &&
1072 have_higher_than_11mbit)
1073 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
1074 else
1075 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
1076 rcu_read_unlock();
1077
1078 ieee80211_set_wmm_default(sdata, true);
1079}
1080
1081void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1076void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1082 u16 transaction, u16 auth_alg, u16 status, 1077 u16 transaction, u16 auth_alg, u16 status,
1083 const u8 *extra, size_t extra_len, const u8 *da, 1078 const u8 *extra, size_t extra_len, const u8 *da,
@@ -1162,7 +1157,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1162int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1157int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1163 size_t buffer_len, const u8 *ie, size_t ie_len, 1158 size_t buffer_len, const u8 *ie, size_t ie_len,
1164 enum ieee80211_band band, u32 rate_mask, 1159 enum ieee80211_band band, u32 rate_mask,
1165 u8 channel) 1160 struct cfg80211_chan_def *chandef)
1166{ 1161{
1167 struct ieee80211_supported_band *sband; 1162 struct ieee80211_supported_band *sband;
1168 u8 *pos = buffer, *end = buffer + buffer_len; 1163 u8 *pos = buffer, *end = buffer + buffer_len;
@@ -1171,16 +1166,26 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1171 u8 rates[32]; 1166 u8 rates[32];
1172 int num_rates; 1167 int num_rates;
1173 int ext_rates_len; 1168 int ext_rates_len;
1169 int shift;
1170 u32 rate_flags;
1174 1171
1175 sband = local->hw.wiphy->bands[band]; 1172 sband = local->hw.wiphy->bands[band];
1176 if (WARN_ON_ONCE(!sband)) 1173 if (WARN_ON_ONCE(!sband))
1177 return 0; 1174 return 0;
1178 1175
1176 rate_flags = ieee80211_chandef_rate_flags(chandef);
1177 shift = ieee80211_chandef_get_shift(chandef);
1178
1179 num_rates = 0; 1179 num_rates = 0;
1180 for (i = 0; i < sband->n_bitrates; i++) { 1180 for (i = 0; i < sband->n_bitrates; i++) {
1181 if ((BIT(i) & rate_mask) == 0) 1181 if ((BIT(i) & rate_mask) == 0)
1182 continue; /* skip rate */ 1182 continue; /* skip rate */
1183 rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5); 1183 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
1184 continue;
1185
1186 rates[num_rates++] =
1187 (u8) DIV_ROUND_UP(sband->bitrates[i].bitrate,
1188 (1 << shift) * 5);
1184 } 1189 }
1185 1190
1186 supp_rates_len = min_t(int, num_rates, 8); 1191 supp_rates_len = min_t(int, num_rates, 8);
@@ -1220,12 +1225,13 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1220 pos += ext_rates_len; 1225 pos += ext_rates_len;
1221 } 1226 }
1222 1227
1223 if (channel && sband->band == IEEE80211_BAND_2GHZ) { 1228 if (chandef->chan && sband->band == IEEE80211_BAND_2GHZ) {
1224 if (end - pos < 3) 1229 if (end - pos < 3)
1225 goto out_err; 1230 goto out_err;
1226 *pos++ = WLAN_EID_DS_PARAMS; 1231 *pos++ = WLAN_EID_DS_PARAMS;
1227 *pos++ = 1; 1232 *pos++ = 1;
1228 *pos++ = channel; 1233 *pos++ = ieee80211_frequency_to_channel(
1234 chandef->chan->center_freq);
1229 } 1235 }
1230 1236
1231 /* insert custom IEs that go before HT */ 1237 /* insert custom IEs that go before HT */
@@ -1290,9 +1296,9 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1290 bool directed) 1296 bool directed)
1291{ 1297{
1292 struct ieee80211_local *local = sdata->local; 1298 struct ieee80211_local *local = sdata->local;
1299 struct cfg80211_chan_def chandef;
1293 struct sk_buff *skb; 1300 struct sk_buff *skb;
1294 struct ieee80211_mgmt *mgmt; 1301 struct ieee80211_mgmt *mgmt;
1295 u8 chan_no;
1296 int ies_len; 1302 int ies_len;
1297 1303
1298 /* 1304 /*
@@ -1300,10 +1306,11 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1300 * in order to maximize the chance that we get a response. Some 1306 * in order to maximize the chance that we get a response. Some
1301 * badly-behaved APs don't respond when this parameter is included. 1307 * badly-behaved APs don't respond when this parameter is included.
1302 */ 1308 */
1309 chandef.width = sdata->vif.bss_conf.chandef.width;
1303 if (directed) 1310 if (directed)
1304 chan_no = 0; 1311 chandef.chan = NULL;
1305 else 1312 else
1306 chan_no = ieee80211_frequency_to_channel(chan->center_freq); 1313 chandef.chan = chan;
1307 1314
1308 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 1315 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1309 ssid, ssid_len, 100 + ie_len); 1316 ssid, ssid_len, 100 + ie_len);
@@ -1313,7 +1320,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1313 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb), 1320 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb),
1314 skb_tailroom(skb), 1321 skb_tailroom(skb),
1315 ie, ie_len, chan->band, 1322 ie, ie_len, chan->band,
1316 ratemask, chan_no); 1323 ratemask, &chandef);
1317 skb_put(skb, ies_len); 1324 skb_put(skb, ies_len);
1318 1325
1319 if (dst) { 1326 if (dst) {
@@ -1347,16 +1354,19 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1347 } 1354 }
1348} 1355}
1349 1356
1350u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 1357u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
1351 struct ieee802_11_elems *elems, 1358 struct ieee802_11_elems *elems,
1352 enum ieee80211_band band, u32 *basic_rates) 1359 enum ieee80211_band band, u32 *basic_rates)
1353{ 1360{
1354 struct ieee80211_supported_band *sband; 1361 struct ieee80211_supported_band *sband;
1355 struct ieee80211_rate *bitrates; 1362 struct ieee80211_rate *bitrates;
1356 size_t num_rates; 1363 size_t num_rates;
1357 u32 supp_rates; 1364 u32 supp_rates, rate_flags;
1358 int i, j; 1365 int i, j, shift;
1359 sband = local->hw.wiphy->bands[band]; 1366 sband = sdata->local->hw.wiphy->bands[band];
1367
1368 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
1369 shift = ieee80211_vif_get_shift(&sdata->vif);
1360 1370
1361 if (WARN_ON(!sband)) 1371 if (WARN_ON(!sband))
1362 return 1; 1372 return 1;
@@ -1381,7 +1391,15 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
1381 continue; 1391 continue;
1382 1392
1383 for (j = 0; j < num_rates; j++) { 1393 for (j = 0; j < num_rates; j++) {
1384 if (bitrates[j].bitrate == own_rate) { 1394 int brate;
1395 if ((rate_flags & sband->bitrates[j].flags)
1396 != rate_flags)
1397 continue;
1398
1399 brate = DIV_ROUND_UP(sband->bitrates[j].bitrate,
1400 1 << shift);
1401
1402 if (brate == own_rate) {
1385 supp_rates |= BIT(j); 1403 supp_rates |= BIT(j);
1386 if (basic_rates && is_basic) 1404 if (basic_rates && is_basic)
1387 *basic_rates |= BIT(j); 1405 *basic_rates |= BIT(j);
@@ -2004,18 +2022,56 @@ void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
2004 cfg80211_chandef_create(chandef, control_chan, channel_type); 2022 cfg80211_chandef_create(chandef, control_chan, channel_type);
2005} 2023}
2006 2024
2025int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
2026 const struct ieee80211_supported_band *sband,
2027 const u8 *srates, int srates_len, u32 *rates)
2028{
2029 u32 rate_flags = ieee80211_chandef_rate_flags(chandef);
2030 int shift = ieee80211_chandef_get_shift(chandef);
2031 struct ieee80211_rate *br;
2032 int brate, rate, i, j, count = 0;
2033
2034 *rates = 0;
2035
2036 for (i = 0; i < srates_len; i++) {
2037 rate = srates[i] & 0x7f;
2038
2039 for (j = 0; j < sband->n_bitrates; j++) {
2040 br = &sband->bitrates[j];
2041 if ((rate_flags & br->flags) != rate_flags)
2042 continue;
2043
2044 brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
2045 if (brate == rate) {
2046 *rates |= BIT(j);
2047 count++;
2048 break;
2049 }
2050 }
2051 }
2052 return count;
2053}
2054
2007int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, 2055int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
2008 struct sk_buff *skb, bool need_basic, 2056 struct sk_buff *skb, bool need_basic,
2009 enum ieee80211_band band) 2057 enum ieee80211_band band)
2010{ 2058{
2011 struct ieee80211_local *local = sdata->local; 2059 struct ieee80211_local *local = sdata->local;
2012 struct ieee80211_supported_band *sband; 2060 struct ieee80211_supported_band *sband;
2013 int rate; 2061 int rate, shift;
2014 u8 i, rates, *pos; 2062 u8 i, rates, *pos;
2015 u32 basic_rates = sdata->vif.bss_conf.basic_rates; 2063 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
2064 u32 rate_flags;
2016 2065
2066 shift = ieee80211_vif_get_shift(&sdata->vif);
2067 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
2017 sband = local->hw.wiphy->bands[band]; 2068 sband = local->hw.wiphy->bands[band];
2018 rates = sband->n_bitrates; 2069 rates = 0;
2070 for (i = 0; i < sband->n_bitrates; i++) {
2071 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
2072 continue;
2073 rates++;
2074 }
2019 if (rates > 8) 2075 if (rates > 8)
2020 rates = 8; 2076 rates = 8;
2021 2077
@@ -2027,10 +2083,15 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
2027 *pos++ = rates; 2083 *pos++ = rates;
2028 for (i = 0; i < rates; i++) { 2084 for (i = 0; i < rates; i++) {
2029 u8 basic = 0; 2085 u8 basic = 0;
2086 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
2087 continue;
2088
2030 if (need_basic && basic_rates & BIT(i)) 2089 if (need_basic && basic_rates & BIT(i))
2031 basic = 0x80; 2090 basic = 0x80;
2032 rate = sband->bitrates[i].bitrate; 2091 rate = sband->bitrates[i].bitrate;
2033 *pos++ = basic | (u8) (rate / 5); 2092 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
2093 5 * (1 << shift));
2094 *pos++ = basic | (u8) rate;
2034 } 2095 }
2035 2096
2036 return 0; 2097 return 0;
@@ -2042,12 +2103,22 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
2042{ 2103{
2043 struct ieee80211_local *local = sdata->local; 2104 struct ieee80211_local *local = sdata->local;
2044 struct ieee80211_supported_band *sband; 2105 struct ieee80211_supported_band *sband;
2045 int rate; 2106 int rate, skip, shift;
2046 u8 i, exrates, *pos; 2107 u8 i, exrates, *pos;
2047 u32 basic_rates = sdata->vif.bss_conf.basic_rates; 2108 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
2109 u32 rate_flags;
2110
2111 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
2112 shift = ieee80211_vif_get_shift(&sdata->vif);
2048 2113
2049 sband = local->hw.wiphy->bands[band]; 2114 sband = local->hw.wiphy->bands[band];
2050 exrates = sband->n_bitrates; 2115 exrates = 0;
2116 for (i = 0; i < sband->n_bitrates; i++) {
2117 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
2118 continue;
2119 exrates++;
2120 }
2121
2051 if (exrates > 8) 2122 if (exrates > 8)
2052 exrates -= 8; 2123 exrates -= 8;
2053 else 2124 else
@@ -2060,12 +2131,19 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
2060 pos = skb_put(skb, exrates + 2); 2131 pos = skb_put(skb, exrates + 2);
2061 *pos++ = WLAN_EID_EXT_SUPP_RATES; 2132 *pos++ = WLAN_EID_EXT_SUPP_RATES;
2062 *pos++ = exrates; 2133 *pos++ = exrates;
2134 skip = 0;
2063 for (i = 8; i < sband->n_bitrates; i++) { 2135 for (i = 8; i < sband->n_bitrates; i++) {
2064 u8 basic = 0; 2136 u8 basic = 0;
2137 if ((rate_flags & sband->bitrates[i].flags)
2138 != rate_flags)
2139 continue;
2140 if (skip++ < 8)
2141 continue;
2065 if (need_basic && basic_rates & BIT(i)) 2142 if (need_basic && basic_rates & BIT(i))
2066 basic = 0x80; 2143 basic = 0x80;
2067 rate = sband->bitrates[i].bitrate; 2144 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
2068 *pos++ = basic | (u8) (rate / 5); 2145 5 * (1 << shift));
2146 *pos++ = basic | (u8) rate;
2069 } 2147 }
2070 } 2148 }
2071 return 0; 2149 return 0;
@@ -2149,9 +2227,17 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2149 ri.flags |= RATE_INFO_FLAGS_SHORT_GI; 2227 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
2150 } else { 2228 } else {
2151 struct ieee80211_supported_band *sband; 2229 struct ieee80211_supported_band *sband;
2230 int shift = 0;
2231 int bitrate;
2232
2233 if (status->flag & RX_FLAG_10MHZ)
2234 shift = 1;
2235 if (status->flag & RX_FLAG_5MHZ)
2236 shift = 2;
2152 2237
2153 sband = local->hw.wiphy->bands[status->band]; 2238 sband = local->hw.wiphy->bands[status->band];
2154 ri.legacy = sband->bitrates[status->rate_idx].bitrate; 2239 bitrate = sband->bitrates[status->rate_idx].bitrate;
2240 ri.legacy = DIV_ROUND_UP(bitrate, (1 << shift));
2155 } 2241 }
2156 2242
2157 rate = cfg80211_calculate_bitrate(&ri); 2243 rate = cfg80211_calculate_bitrate(&ri);
diff --git a/net/wireless/core.c b/net/wireless/core.c
index a8c29fa4f1b3..67153964aad2 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -462,6 +462,14 @@ int wiphy_register(struct wiphy *wiphy)
462 return -EINVAL; 462 return -EINVAL;
463#endif 463#endif
464 464
465 if (WARN_ON(wiphy->coalesce &&
466 (!wiphy->coalesce->n_rules ||
467 !wiphy->coalesce->n_patterns) &&
468 (!wiphy->coalesce->pattern_min_len ||
469 wiphy->coalesce->pattern_min_len >
470 wiphy->coalesce->pattern_max_len)))
471 return -EINVAL;
472
465 if (WARN_ON(wiphy->ap_sme_capa && 473 if (WARN_ON(wiphy->ap_sme_capa &&
466 !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME))) 474 !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME)))
467 return -EINVAL; 475 return -EINVAL;
@@ -668,6 +676,7 @@ void wiphy_unregister(struct wiphy *wiphy)
668 rdev_set_wakeup(rdev, false); 676 rdev_set_wakeup(rdev, false);
669#endif 677#endif
670 cfg80211_rdev_free_wowlan(rdev); 678 cfg80211_rdev_free_wowlan(rdev);
679 cfg80211_rdev_free_coalesce(rdev);
671} 680}
672EXPORT_SYMBOL(wiphy_unregister); 681EXPORT_SYMBOL(wiphy_unregister);
673 682
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a6b45bf00f33..9ad43c619c54 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -79,6 +79,8 @@ struct cfg80211_registered_device {
79 /* netlink port which started critical protocol (0 means not started) */ 79 /* netlink port which started critical protocol (0 means not started) */
80 u32 crit_proto_nlportid; 80 u32 crit_proto_nlportid;
81 81
82 struct cfg80211_coalesce *coalesce;
83
82 /* must be last because of the way we do wiphy_priv(), 84 /* must be last because of the way we do wiphy_priv(),
83 * and it should at least be aligned to NETDEV_ALIGN */ 85 * and it should at least be aligned to NETDEV_ALIGN */
84 struct wiphy wiphy __aligned(NETDEV_ALIGN); 86 struct wiphy wiphy __aligned(NETDEV_ALIGN);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 30c49202ee4d..0553fd4d85ae 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -167,9 +167,12 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
167 * basic rates 167 * basic rates
168 */ 168 */
169 if (!setup->basic_rates) { 169 if (!setup->basic_rates) {
170 enum nl80211_bss_scan_width scan_width;
170 struct ieee80211_supported_band *sband = 171 struct ieee80211_supported_band *sband =
171 rdev->wiphy.bands[setup->chandef.chan->band]; 172 rdev->wiphy.bands[setup->chandef.chan->band];
172 setup->basic_rates = ieee80211_mandatory_rates(sband); 173 scan_width = cfg80211_chandef_to_scan_width(&setup->chandef);
174 setup->basic_rates = ieee80211_mandatory_rates(sband,
175 scan_width);
173 } 176 }
174 177
175 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef)) 178 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 3fcba69817e5..587ff843cf94 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -403,6 +403,14 @@ nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
403 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 }, 403 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
404}; 404};
405 405
406/* policy for coalesce rule attributes */
407static const struct nla_policy
408nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
409 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
410 [NL80211_ATTR_COALESCE_RULE_CONDITION] = { .type = NLA_U32 },
411 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
412};
413
406/* policy for GTK rekey offload attributes */ 414/* policy for GTK rekey offload attributes */
407static const struct nla_policy 415static const struct nla_policy
408nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { 416nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
@@ -976,7 +984,7 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
976 return -ENOBUFS; 984 return -ENOBUFS;
977 985
978 if (dev->wiphy.wowlan->n_patterns) { 986 if (dev->wiphy.wowlan->n_patterns) {
979 struct nl80211_wowlan_pattern_support pat = { 987 struct nl80211_pattern_support pat = {
980 .max_patterns = dev->wiphy.wowlan->n_patterns, 988 .max_patterns = dev->wiphy.wowlan->n_patterns,
981 .min_pattern_len = dev->wiphy.wowlan->pattern_min_len, 989 .min_pattern_len = dev->wiphy.wowlan->pattern_min_len,
982 .max_pattern_len = dev->wiphy.wowlan->pattern_max_len, 990 .max_pattern_len = dev->wiphy.wowlan->pattern_max_len,
@@ -997,6 +1005,27 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
997} 1005}
998#endif 1006#endif
999 1007
1008static int nl80211_send_coalesce(struct sk_buff *msg,
1009 struct cfg80211_registered_device *dev)
1010{
1011 struct nl80211_coalesce_rule_support rule;
1012
1013 if (!dev->wiphy.coalesce)
1014 return 0;
1015
1016 rule.max_rules = dev->wiphy.coalesce->n_rules;
1017 rule.max_delay = dev->wiphy.coalesce->max_delay;
1018 rule.pat.max_patterns = dev->wiphy.coalesce->n_patterns;
1019 rule.pat.min_pattern_len = dev->wiphy.coalesce->pattern_min_len;
1020 rule.pat.max_pattern_len = dev->wiphy.coalesce->pattern_max_len;
1021 rule.pat.max_pkt_offset = dev->wiphy.coalesce->max_pkt_offset;
1022
1023 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1024 return -ENOBUFS;
1025
1026 return 0;
1027}
1028
1000static int nl80211_send_band_rateinfo(struct sk_buff *msg, 1029static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1001 struct ieee80211_supported_band *sband) 1030 struct ieee80211_supported_band *sband)
1002{ 1031{
@@ -1515,6 +1544,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1515 dev->wiphy.vht_capa_mod_mask)) 1544 dev->wiphy.vht_capa_mod_mask))
1516 goto nla_put_failure; 1545 goto nla_put_failure;
1517 1546
1547 state->split_start++;
1548 break;
1549 case 10:
1550 if (nl80211_send_coalesce(msg, dev))
1551 goto nla_put_failure;
1552
1518 /* done */ 1553 /* done */
1519 state->split_start = 0; 1554 state->split_start = 0;
1520 break; 1555 break;
@@ -5641,6 +5676,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
5641 goto nla_put_failure; 5676 goto nla_put_failure;
5642 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) || 5677 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
5643 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) || 5678 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
5679 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
5644 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO, 5680 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
5645 jiffies_to_msecs(jiffies - intbss->ts))) 5681 jiffies_to_msecs(jiffies - intbss->ts)))
5646 goto nla_put_failure; 5682 goto nla_put_failure;
@@ -6321,6 +6357,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
6321 return -EINVAL; 6357 return -EINVAL;
6322 6358
6323 switch (ibss.chandef.width) { 6359 switch (ibss.chandef.width) {
6360 case NL80211_CHAN_WIDTH_5:
6361 case NL80211_CHAN_WIDTH_10:
6324 case NL80211_CHAN_WIDTH_20_NOHT: 6362 case NL80211_CHAN_WIDTH_20_NOHT:
6325 break; 6363 break;
6326 case NL80211_CHAN_WIDTH_20: 6364 case NL80211_CHAN_WIDTH_20:
@@ -6348,6 +6386,19 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
6348 return err; 6386 return err;
6349 } 6387 }
6350 6388
6389 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
6390 memcpy(&ibss.ht_capa_mask,
6391 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
6392 sizeof(ibss.ht_capa_mask));
6393
6394 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
6395 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
6396 return -EINVAL;
6397 memcpy(&ibss.ht_capa,
6398 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
6399 sizeof(ibss.ht_capa));
6400 }
6401
6351 if (info->attrs[NL80211_ATTR_MCAST_RATE] && 6402 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
6352 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate, 6403 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
6353 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]))) 6404 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
@@ -7595,12 +7646,11 @@ static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
7595 if (!nl_pat) 7646 if (!nl_pat)
7596 return -ENOBUFS; 7647 return -ENOBUFS;
7597 pat_len = wowlan->patterns[i].pattern_len; 7648 pat_len = wowlan->patterns[i].pattern_len;
7598 if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK, 7649 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
7599 DIV_ROUND_UP(pat_len, 8),
7600 wowlan->patterns[i].mask) || 7650 wowlan->patterns[i].mask) ||
7601 nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN, 7651 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
7602 pat_len, wowlan->patterns[i].pattern) || 7652 wowlan->patterns[i].pattern) ||
7603 nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET, 7653 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
7604 wowlan->patterns[i].pkt_offset)) 7654 wowlan->patterns[i].pkt_offset))
7605 return -ENOBUFS; 7655 return -ENOBUFS;
7606 nla_nest_end(msg, nl_pat); 7656 nla_nest_end(msg, nl_pat);
@@ -7941,7 +7991,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7941 struct nlattr *pat; 7991 struct nlattr *pat;
7942 int n_patterns = 0; 7992 int n_patterns = 0;
7943 int rem, pat_len, mask_len, pkt_offset; 7993 int rem, pat_len, mask_len, pkt_offset;
7944 struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT]; 7994 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
7945 7995
7946 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], 7996 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
7947 rem) 7997 rem)
@@ -7960,26 +8010,25 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7960 8010
7961 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], 8011 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
7962 rem) { 8012 rem) {
7963 nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT, 8013 nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
7964 nla_data(pat), nla_len(pat), NULL); 8014 nla_len(pat), NULL);
7965 err = -EINVAL; 8015 err = -EINVAL;
7966 if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] || 8016 if (!pat_tb[NL80211_PKTPAT_MASK] ||
7967 !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]) 8017 !pat_tb[NL80211_PKTPAT_PATTERN])
7968 goto error; 8018 goto error;
7969 pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]); 8019 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
7970 mask_len = DIV_ROUND_UP(pat_len, 8); 8020 mask_len = DIV_ROUND_UP(pat_len, 8);
7971 if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) != 8021 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
7972 mask_len)
7973 goto error; 8022 goto error;
7974 if (pat_len > wowlan->pattern_max_len || 8023 if (pat_len > wowlan->pattern_max_len ||
7975 pat_len < wowlan->pattern_min_len) 8024 pat_len < wowlan->pattern_min_len)
7976 goto error; 8025 goto error;
7977 8026
7978 if (!pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET]) 8027 if (!pat_tb[NL80211_PKTPAT_OFFSET])
7979 pkt_offset = 0; 8028 pkt_offset = 0;
7980 else 8029 else
7981 pkt_offset = nla_get_u32( 8030 pkt_offset = nla_get_u32(
7982 pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET]); 8031 pat_tb[NL80211_PKTPAT_OFFSET]);
7983 if (pkt_offset > wowlan->max_pkt_offset) 8032 if (pkt_offset > wowlan->max_pkt_offset)
7984 goto error; 8033 goto error;
7985 new_triggers.patterns[i].pkt_offset = pkt_offset; 8034 new_triggers.patterns[i].pkt_offset = pkt_offset;
@@ -7993,11 +8042,11 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7993 new_triggers.patterns[i].pattern = 8042 new_triggers.patterns[i].pattern =
7994 new_triggers.patterns[i].mask + mask_len; 8043 new_triggers.patterns[i].mask + mask_len;
7995 memcpy(new_triggers.patterns[i].mask, 8044 memcpy(new_triggers.patterns[i].mask,
7996 nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]), 8045 nla_data(pat_tb[NL80211_PKTPAT_MASK]),
7997 mask_len); 8046 mask_len);
7998 new_triggers.patterns[i].pattern_len = pat_len; 8047 new_triggers.patterns[i].pattern_len = pat_len;
7999 memcpy(new_triggers.patterns[i].pattern, 8048 memcpy(new_triggers.patterns[i].pattern,
8000 nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]), 8049 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
8001 pat_len); 8050 pat_len);
8002 i++; 8051 i++;
8003 } 8052 }
@@ -8036,6 +8085,264 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
8036} 8085}
8037#endif 8086#endif
8038 8087
8088static int nl80211_send_coalesce_rules(struct sk_buff *msg,
8089 struct cfg80211_registered_device *rdev)
8090{
8091 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
8092 int i, j, pat_len;
8093 struct cfg80211_coalesce_rules *rule;
8094
8095 if (!rdev->coalesce->n_rules)
8096 return 0;
8097
8098 nl_rules = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE);
8099 if (!nl_rules)
8100 return -ENOBUFS;
8101
8102 for (i = 0; i < rdev->coalesce->n_rules; i++) {
8103 nl_rule = nla_nest_start(msg, i + 1);
8104 if (!nl_rule)
8105 return -ENOBUFS;
8106
8107 rule = &rdev->coalesce->rules[i];
8108 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
8109 rule->delay))
8110 return -ENOBUFS;
8111
8112 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
8113 rule->condition))
8114 return -ENOBUFS;
8115
8116 nl_pats = nla_nest_start(msg,
8117 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
8118 if (!nl_pats)
8119 return -ENOBUFS;
8120
8121 for (j = 0; j < rule->n_patterns; j++) {
8122 nl_pat = nla_nest_start(msg, j + 1);
8123 if (!nl_pat)
8124 return -ENOBUFS;
8125 pat_len = rule->patterns[j].pattern_len;
8126 if (nla_put(msg, NL80211_PKTPAT_MASK,
8127 DIV_ROUND_UP(pat_len, 8),
8128 rule->patterns[j].mask) ||
8129 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
8130 rule->patterns[j].pattern) ||
8131 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
8132 rule->patterns[j].pkt_offset))
8133 return -ENOBUFS;
8134 nla_nest_end(msg, nl_pat);
8135 }
8136 nla_nest_end(msg, nl_pats);
8137 nla_nest_end(msg, nl_rule);
8138 }
8139 nla_nest_end(msg, nl_rules);
8140
8141 return 0;
8142}
8143
8144static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
8145{
8146 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8147 struct sk_buff *msg;
8148 void *hdr;
8149
8150 if (!rdev->wiphy.coalesce)
8151 return -EOPNOTSUPP;
8152
8153 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8154 if (!msg)
8155 return -ENOMEM;
8156
8157 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
8158 NL80211_CMD_GET_COALESCE);
8159 if (!hdr)
8160 goto nla_put_failure;
8161
8162 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
8163 goto nla_put_failure;
8164
8165 genlmsg_end(msg, hdr);
8166 return genlmsg_reply(msg, info);
8167
8168nla_put_failure:
8169 nlmsg_free(msg);
8170 return -ENOBUFS;
8171}
8172
8173void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
8174{
8175 struct cfg80211_coalesce *coalesce = rdev->coalesce;
8176 int i, j;
8177 struct cfg80211_coalesce_rules *rule;
8178
8179 if (!coalesce)
8180 return;
8181
8182 for (i = 0; i < coalesce->n_rules; i++) {
8183 rule = &coalesce->rules[i];
8184 for (j = 0; j < rule->n_patterns; j++)
8185 kfree(rule->patterns[j].mask);
8186 kfree(rule->patterns);
8187 }
8188 kfree(coalesce->rules);
8189 kfree(coalesce);
8190 rdev->coalesce = NULL;
8191}
8192
8193static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
8194 struct nlattr *rule,
8195 struct cfg80211_coalesce_rules *new_rule)
8196{
8197 int err, i;
8198 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
8199 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
8200 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
8201 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
8202
8203 err = nla_parse(tb, NL80211_ATTR_COALESCE_RULE_MAX, nla_data(rule),
8204 nla_len(rule), nl80211_coalesce_policy);
8205 if (err)
8206 return err;
8207
8208 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
8209 new_rule->delay =
8210 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
8211 if (new_rule->delay > coalesce->max_delay)
8212 return -EINVAL;
8213
8214 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
8215 new_rule->condition =
8216 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
8217 if (new_rule->condition != NL80211_COALESCE_CONDITION_MATCH &&
8218 new_rule->condition != NL80211_COALESCE_CONDITION_NO_MATCH)
8219 return -EINVAL;
8220
8221 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
8222 return -EINVAL;
8223
8224 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
8225 rem)
8226 n_patterns++;
8227 if (n_patterns > coalesce->n_patterns)
8228 return -EINVAL;
8229
8230 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
8231 GFP_KERNEL);
8232 if (!new_rule->patterns)
8233 return -ENOMEM;
8234
8235 new_rule->n_patterns = n_patterns;
8236 i = 0;
8237
8238 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
8239 rem) {
8240 nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
8241 nla_len(pat), NULL);
8242 if (!pat_tb[NL80211_PKTPAT_MASK] ||
8243 !pat_tb[NL80211_PKTPAT_PATTERN])
8244 return -EINVAL;
8245 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
8246 mask_len = DIV_ROUND_UP(pat_len, 8);
8247 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
8248 return -EINVAL;
8249 if (pat_len > coalesce->pattern_max_len ||
8250 pat_len < coalesce->pattern_min_len)
8251 return -EINVAL;
8252
8253 if (!pat_tb[NL80211_PKTPAT_OFFSET])
8254 pkt_offset = 0;
8255 else
8256 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
8257 if (pkt_offset > coalesce->max_pkt_offset)
8258 return -EINVAL;
8259 new_rule->patterns[i].pkt_offset = pkt_offset;
8260
8261 new_rule->patterns[i].mask =
8262 kmalloc(mask_len + pat_len, GFP_KERNEL);
8263 if (!new_rule->patterns[i].mask)
8264 return -ENOMEM;
8265 new_rule->patterns[i].pattern =
8266 new_rule->patterns[i].mask + mask_len;
8267 memcpy(new_rule->patterns[i].mask,
8268 nla_data(pat_tb[NL80211_PKTPAT_MASK]), mask_len);
8269 new_rule->patterns[i].pattern_len = pat_len;
8270 memcpy(new_rule->patterns[i].pattern,
8271 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), pat_len);
8272 i++;
8273 }
8274
8275 return 0;
8276}
8277
8278static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
8279{
8280 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8281 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
8282 struct cfg80211_coalesce new_coalesce = {};
8283 struct cfg80211_coalesce *n_coalesce;
8284 int err, rem_rule, n_rules = 0, i, j;
8285 struct nlattr *rule;
8286 struct cfg80211_coalesce_rules *tmp_rule;
8287
8288 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
8289 return -EOPNOTSUPP;
8290
8291 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
8292 cfg80211_rdev_free_coalesce(rdev);
8293 rdev->ops->set_coalesce(&rdev->wiphy, NULL);
8294 return 0;
8295 }
8296
8297 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
8298 rem_rule)
8299 n_rules++;
8300 if (n_rules > coalesce->n_rules)
8301 return -EINVAL;
8302
8303 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
8304 GFP_KERNEL);
8305 if (!new_coalesce.rules)
8306 return -ENOMEM;
8307
8308 new_coalesce.n_rules = n_rules;
8309 i = 0;
8310
8311 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
8312 rem_rule) {
8313 err = nl80211_parse_coalesce_rule(rdev, rule,
8314 &new_coalesce.rules[i]);
8315 if (err)
8316 goto error;
8317
8318 i++;
8319 }
8320
8321 err = rdev->ops->set_coalesce(&rdev->wiphy, &new_coalesce);
8322 if (err)
8323 goto error;
8324
8325 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
8326 if (!n_coalesce) {
8327 err = -ENOMEM;
8328 goto error;
8329 }
8330 cfg80211_rdev_free_coalesce(rdev);
8331 rdev->coalesce = n_coalesce;
8332
8333 return 0;
8334error:
8335 for (i = 0; i < new_coalesce.n_rules; i++) {
8336 tmp_rule = &new_coalesce.rules[i];
8337 for (j = 0; j < tmp_rule->n_patterns; j++)
8338 kfree(tmp_rule->patterns[j].mask);
8339 kfree(tmp_rule->patterns);
8340 }
8341 kfree(new_coalesce.rules);
8342
8343 return err;
8344}
8345
8039static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) 8346static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
8040{ 8347{
8041 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 8348 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -9043,6 +9350,21 @@ static struct genl_ops nl80211_ops[] = {
9043 .flags = GENL_ADMIN_PERM, 9350 .flags = GENL_ADMIN_PERM,
9044 .internal_flags = NL80211_FLAG_NEED_WDEV_UP | 9351 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
9045 NL80211_FLAG_NEED_RTNL, 9352 NL80211_FLAG_NEED_RTNL,
9353 },
9354 {
9355 .cmd = NL80211_CMD_GET_COALESCE,
9356 .doit = nl80211_get_coalesce,
9357 .policy = nl80211_policy,
9358 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9359 NL80211_FLAG_NEED_RTNL,
9360 },
9361 {
9362 .cmd = NL80211_CMD_SET_COALESCE,
9363 .doit = nl80211_set_coalesce,
9364 .policy = nl80211_policy,
9365 .flags = GENL_ADMIN_PERM,
9366 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9367 NL80211_FLAG_NEED_RTNL,
9046 } 9368 }
9047}; 9369};
9048 9370
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index a4073e808c13..44341bf53cfc 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -74,4 +74,6 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
74 enum nl80211_radar_event event, 74 enum nl80211_radar_event event,
75 struct net_device *netdev, gfp_t gfp); 75 struct net_device *netdev, gfp_t gfp);
76 76
77void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev);
78
77#endif /* __NET_WIRELESS_NL80211_H */ 79#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index ae8c186b50d6..ad1e4068ce06 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -651,6 +651,8 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
651 continue; 651 continue;
652 if (bss->pub.channel != new->pub.channel) 652 if (bss->pub.channel != new->pub.channel)
653 continue; 653 continue;
654 if (bss->pub.scan_width != new->pub.scan_width)
655 continue;
654 if (rcu_access_pointer(bss->pub.beacon_ies)) 656 if (rcu_access_pointer(bss->pub.beacon_ies))
655 continue; 657 continue;
656 ies = rcu_access_pointer(bss->pub.ies); 658 ies = rcu_access_pointer(bss->pub.ies);
@@ -870,11 +872,12 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
870 872
871/* Returned bss is reference counted and must be cleaned up appropriately. */ 873/* Returned bss is reference counted and must be cleaned up appropriately. */
872struct cfg80211_bss* 874struct cfg80211_bss*
873cfg80211_inform_bss(struct wiphy *wiphy, 875cfg80211_inform_bss_width(struct wiphy *wiphy,
874 struct ieee80211_channel *channel, 876 struct ieee80211_channel *channel,
875 const u8 *bssid, u64 tsf, u16 capability, 877 enum nl80211_bss_scan_width scan_width,
876 u16 beacon_interval, const u8 *ie, size_t ielen, 878 const u8 *bssid, u64 tsf, u16 capability,
877 s32 signal, gfp_t gfp) 879 u16 beacon_interval, const u8 *ie, size_t ielen,
880 s32 signal, gfp_t gfp)
878{ 881{
879 struct cfg80211_bss_ies *ies; 882 struct cfg80211_bss_ies *ies;
880 struct cfg80211_internal_bss tmp = {}, *res; 883 struct cfg80211_internal_bss tmp = {}, *res;
@@ -892,6 +895,7 @@ cfg80211_inform_bss(struct wiphy *wiphy,
892 895
893 memcpy(tmp.pub.bssid, bssid, ETH_ALEN); 896 memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
894 tmp.pub.channel = channel; 897 tmp.pub.channel = channel;
898 tmp.pub.scan_width = scan_width;
895 tmp.pub.signal = signal; 899 tmp.pub.signal = signal;
896 tmp.pub.beacon_interval = beacon_interval; 900 tmp.pub.beacon_interval = beacon_interval;
897 tmp.pub.capability = capability; 901 tmp.pub.capability = capability;
@@ -924,14 +928,15 @@ cfg80211_inform_bss(struct wiphy *wiphy,
924 /* cfg80211_bss_update gives us a referenced result */ 928 /* cfg80211_bss_update gives us a referenced result */
925 return &res->pub; 929 return &res->pub;
926} 930}
927EXPORT_SYMBOL(cfg80211_inform_bss); 931EXPORT_SYMBOL(cfg80211_inform_bss_width);
928 932
929/* Returned bss is reference counted and must be cleaned up appropriately. */ 933/* Returned bss is reference counted and must be cleaned up appropriately. */
930struct cfg80211_bss * 934struct cfg80211_bss *
931cfg80211_inform_bss_frame(struct wiphy *wiphy, 935cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
932 struct ieee80211_channel *channel, 936 struct ieee80211_channel *channel,
933 struct ieee80211_mgmt *mgmt, size_t len, 937 enum nl80211_bss_scan_width scan_width,
934 s32 signal, gfp_t gfp) 938 struct ieee80211_mgmt *mgmt, size_t len,
939 s32 signal, gfp_t gfp)
935{ 940{
936 struct cfg80211_internal_bss tmp = {}, *res; 941 struct cfg80211_internal_bss tmp = {}, *res;
937 struct cfg80211_bss_ies *ies; 942 struct cfg80211_bss_ies *ies;
@@ -941,7 +946,8 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
941 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != 946 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
942 offsetof(struct ieee80211_mgmt, u.beacon.variable)); 947 offsetof(struct ieee80211_mgmt, u.beacon.variable));
943 948
944 trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal); 949 trace_cfg80211_inform_bss_width_frame(wiphy, channel, scan_width, mgmt,
950 len, signal);
945 951
946 if (WARN_ON(!mgmt)) 952 if (WARN_ON(!mgmt))
947 return NULL; 953 return NULL;
@@ -976,6 +982,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
976 982
977 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN); 983 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN);
978 tmp.pub.channel = channel; 984 tmp.pub.channel = channel;
985 tmp.pub.scan_width = scan_width;
979 tmp.pub.signal = signal; 986 tmp.pub.signal = signal;
980 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 987 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
981 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); 988 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
@@ -991,7 +998,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
991 /* cfg80211_bss_update gives us a referenced result */ 998 /* cfg80211_bss_update gives us a referenced result */
992 return &res->pub; 999 return &res->pub;
993} 1000}
994EXPORT_SYMBOL(cfg80211_inform_bss_frame); 1001EXPORT_SYMBOL(cfg80211_inform_bss_width_frame);
995 1002
996void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) 1003void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
997{ 1004{
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index e1534baf2ebb..09af6eb426a8 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2391,26 +2391,30 @@ TRACE_EVENT(cfg80211_get_bss,
2391 __entry->capa_mask, __entry->capa_val) 2391 __entry->capa_mask, __entry->capa_val)
2392); 2392);
2393 2393
2394TRACE_EVENT(cfg80211_inform_bss_frame, 2394TRACE_EVENT(cfg80211_inform_bss_width_frame,
2395 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, 2395 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel,
2396 enum nl80211_bss_scan_width scan_width,
2396 struct ieee80211_mgmt *mgmt, size_t len, 2397 struct ieee80211_mgmt *mgmt, size_t len,
2397 s32 signal), 2398 s32 signal),
2398 TP_ARGS(wiphy, channel, mgmt, len, signal), 2399 TP_ARGS(wiphy, channel, scan_width, mgmt, len, signal),
2399 TP_STRUCT__entry( 2400 TP_STRUCT__entry(
2400 WIPHY_ENTRY 2401 WIPHY_ENTRY
2401 CHAN_ENTRY 2402 CHAN_ENTRY
2403 __field(enum nl80211_bss_scan_width, scan_width)
2402 __dynamic_array(u8, mgmt, len) 2404 __dynamic_array(u8, mgmt, len)
2403 __field(s32, signal) 2405 __field(s32, signal)
2404 ), 2406 ),
2405 TP_fast_assign( 2407 TP_fast_assign(
2406 WIPHY_ASSIGN; 2408 WIPHY_ASSIGN;
2407 CHAN_ASSIGN(channel); 2409 CHAN_ASSIGN(channel);
2410 __entry->scan_width = scan_width;
2408 if (mgmt) 2411 if (mgmt)
2409 memcpy(__get_dynamic_array(mgmt), mgmt, len); 2412 memcpy(__get_dynamic_array(mgmt), mgmt, len);
2410 __entry->signal = signal; 2413 __entry->signal = signal;
2411 ), 2414 ),
2412 TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT "signal: %d", 2415 TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT "(scan_width: %d) signal: %d",
2413 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->signal) 2416 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->scan_width,
2417 __entry->signal)
2414); 2418);
2415 2419
2416DECLARE_EVENT_CLASS(cfg80211_bss_evt, 2420DECLARE_EVENT_CLASS(cfg80211_bss_evt,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 74458b7f61eb..ce090c1c5e4f 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -33,7 +33,8 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
33} 33}
34EXPORT_SYMBOL(ieee80211_get_response_rate); 34EXPORT_SYMBOL(ieee80211_get_response_rate);
35 35
36u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband) 36u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband,
37 enum nl80211_bss_scan_width scan_width)
37{ 38{
38 struct ieee80211_rate *bitrates; 39 struct ieee80211_rate *bitrates;
39 u32 mandatory_rates = 0; 40 u32 mandatory_rates = 0;
@@ -43,10 +44,15 @@ u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
43 if (WARN_ON(!sband)) 44 if (WARN_ON(!sband))
44 return 1; 45 return 1;
45 46
46 if (sband->band == IEEE80211_BAND_2GHZ) 47 if (sband->band == IEEE80211_BAND_2GHZ) {
47 mandatory_flag = IEEE80211_RATE_MANDATORY_B; 48 if (scan_width == NL80211_BSS_CHAN_WIDTH_5 ||
48 else 49 scan_width == NL80211_BSS_CHAN_WIDTH_10)
50 mandatory_flag = IEEE80211_RATE_MANDATORY_G;
51 else
52 mandatory_flag = IEEE80211_RATE_MANDATORY_B;
53 } else {
49 mandatory_flag = IEEE80211_RATE_MANDATORY_A; 54 mandatory_flag = IEEE80211_RATE_MANDATORY_A;
55 }
50 56
51 bitrates = sband->bitrates; 57 bitrates = sband->bitrates;
52 for (i = 0; i < sband->n_bitrates; i++) 58 for (i = 0; i < sband->n_bitrates; i++)