aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-02-08 13:16:17 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-02-08 13:16:17 -0500
commitf5237f278f30a92401539a54f87ee0c717b6f818 (patch)
tree209d4fd6fb00e660c76ca8ac5d4caed59dbb9957 /drivers
parentb285109dde7b873b5dc671ef1b3ae3090f4bc72f (diff)
parentb26f5f09ebdeb85ab152344cc1d6d484a3ce967d (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bcma/bcma_private.h1
-rw-r--r--drivers/bcma/driver_chipcommon_nflash.c4
-rw-r--r--drivers/bcma/driver_chipcommon_sflash.c4
-rw-r--r--drivers/bcma/driver_gpio.c11
-rw-r--r--drivers/bcma/driver_mips.c38
-rw-r--r--drivers/bcma/main.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig1
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h17
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c193
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c80
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c9
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c55
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c63
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c31
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c107
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h22
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c107
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c5
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c39
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c57
-rw-r--r--drivers/net/wireless/iwlegacy/4965.c3
-rw-r--r--drivers/net/wireless/iwlegacy/commands.h3
-rw-r--r--drivers/net/wireless/iwlegacy/common.h1
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig14
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.c4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/debugfs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/devices.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c42
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.c7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rxon.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/sta.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/testmode.c4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.c8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-read.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-read.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c93
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-notif-wait.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-notif-wait.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c346
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h80
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-op-mode.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c514
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.h82
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.c21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h52
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/binding.c197
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c841
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c378
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h282
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h369
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h140
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h312
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h561
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h380
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h580
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h949
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c644
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/led.c134
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c951
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c1310
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h500
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c311
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c679
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c292
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c207
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c178
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c3096
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h393
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c355
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c437
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c1211
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h368
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c569
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h214
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c916
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c472
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/2000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/5000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/6000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/7000.c111
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/cfg.h6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c10
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c3
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c95
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n.c39
-rw-r--r--drivers/net/wireless/mwifiex/11n.h2
-rw-r--r--drivers/net/wireless/mwifiex/README1
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c2
-rw-r--r--drivers/net/wireless/mwifiex/init.c1
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h1
-rw-r--r--drivers/net/wireless/mwifiex/join.c6
-rw-r--r--drivers/net/wireless/mwifiex/main.h1
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c6
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c10
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c5
-rw-r--r--drivers/net/wireless/mwifiex/usb.c4
-rw-r--r--drivers/net/wireless/mwifiex/util.c2
-rw-r--r--drivers/net/wireless/mwl8k.c167
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c20
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rc.c15
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/dm.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.c8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/phy.c20
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c4
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h2
-rw-r--r--drivers/net/wireless/ti/wl1251/Kconfig2
-rw-r--r--drivers/net/wireless/ti/wl12xx/Makefile2
-rw-r--r--drivers/net/wireless/ti/wl12xx/cmd.c37
-rw-r--r--drivers/net/wireless/ti/wl12xx/cmd.h20
-rw-r--r--drivers/net/wireless/ti/wl12xx/event.c116
-rw-r--r--drivers/net/wireless/ti/wl12xx/event.h111
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c192
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.c501
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.h140
-rw-r--r--drivers/net/wireless/ti/wl12xx/wl12xx.h40
-rw-r--r--drivers/net/wireless/ti/wl18xx/Makefile2
-rw-r--r--drivers/net/wireless/ti/wl18xx/acx.c87
-rw-r--r--drivers/net/wireless/ti/wl18xx/acx.h55
-rw-r--r--drivers/net/wireless/ti/wl18xx/cmd.c80
-rw-r--r--drivers/net/wireless/ti/wl18xx/cmd.h52
-rw-r--r--drivers/net/wireless/ti/wl18xx/conf.h21
-rw-r--r--drivers/net/wireless/ti/wl18xx/event.c111
-rw-r--r--drivers/net/wireless/ti/wl18xx/event.h77
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c267
-rw-r--r--drivers/net/wireless/ti/wl18xx/scan.c326
-rw-r--r--drivers/net/wireless/ti/wl18xx/scan.h127
-rw-r--r--drivers/net/wireless/ti/wl18xx/tx.c54
-rw-r--r--drivers/net/wireless/ti/wl18xx/wl18xx.h50
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.c15
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.h1
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.c77
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c419
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h81
-rw-r--r--drivers/net/wireless/ti/wlcore/conf.h110
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c10
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c326
-rw-r--r--drivers/net/wireless/ti/wlcore/event.h99
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h41
-rw-r--r--drivers/net/wireless/ti/wlcore/init.c19
-rw-r--r--drivers/net/wireless/ti/wlcore/io.h12
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c1572
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.c11
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.c33
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.c696
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.h144
-rw-r--r--drivers/net/wireless/ti/wlcore/sdio.c3
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c5
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c298
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.h35
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h118
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h49
-rw-r--r--drivers/ssb/driver_gpio.c22
-rw-r--r--drivers/ssb/driver_mipscore.c48
-rw-r--r--drivers/ssb/main.c8
-rw-r--r--drivers/ssb/ssb_private.h4
211 files changed, 25183 insertions, 2782 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 04f7c86ea3d8..6f377bd1a6d6 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -47,6 +47,7 @@ int bcma_sprom_get(struct bcma_bus *bus);
47/* driver_chipcommon.c */ 47/* driver_chipcommon.c */
48#ifdef CONFIG_BCMA_DRIVER_MIPS 48#ifdef CONFIG_BCMA_DRIVER_MIPS
49void bcma_chipco_serial_init(struct bcma_drv_cc *cc); 49void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
50extern struct platform_device bcma_pflash_dev;
50#endif /* CONFIG_BCMA_DRIVER_MIPS */ 51#endif /* CONFIG_BCMA_DRIVER_MIPS */
51 52
52/* driver_chipcommon_pmu.c */ 53/* driver_chipcommon_pmu.c */
diff --git a/drivers/bcma/driver_chipcommon_nflash.c b/drivers/bcma/driver_chipcommon_nflash.c
index 1f0b83e18f68..d4f699aef8c4 100644
--- a/drivers/bcma/driver_chipcommon_nflash.c
+++ b/drivers/bcma/driver_chipcommon_nflash.c
@@ -5,11 +5,11 @@
5 * Licensed under the GNU/GPL. See COPYING for details. 5 * Licensed under the GNU/GPL. See COPYING for details.
6 */ 6 */
7 7
8#include "bcma_private.h"
9
8#include <linux/platform_device.h> 10#include <linux/platform_device.h>
9#include <linux/bcma/bcma.h> 11#include <linux/bcma/bcma.h>
10 12
11#include "bcma_private.h"
12
13struct platform_device bcma_nflash_dev = { 13struct platform_device bcma_nflash_dev = {
14 .name = "bcma_nflash", 14 .name = "bcma_nflash",
15 .num_resources = 0, 15 .num_resources = 0,
diff --git a/drivers/bcma/driver_chipcommon_sflash.c b/drivers/bcma/driver_chipcommon_sflash.c
index 1e694db4532d..e6ed4fe5dced 100644
--- a/drivers/bcma/driver_chipcommon_sflash.c
+++ b/drivers/bcma/driver_chipcommon_sflash.c
@@ -5,11 +5,11 @@
5 * Licensed under the GNU/GPL. See COPYING for details. 5 * Licensed under the GNU/GPL. See COPYING for details.
6 */ 6 */
7 7
8#include "bcma_private.h"
9
8#include <linux/platform_device.h> 10#include <linux/platform_device.h>
9#include <linux/bcma/bcma.h> 11#include <linux/bcma/bcma.h>
10 12
11#include "bcma_private.h"
12
13static struct resource bcma_sflash_resource = { 13static struct resource bcma_sflash_resource = {
14 .name = "bcma_sflash", 14 .name = "bcma_sflash",
15 .start = BCMA_SOC_FLASH2, 15 .start = BCMA_SOC_FLASH2,
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
index 9a6f585da2d9..0b5df538dfd9 100644
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -73,6 +73,16 @@ static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
73 bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); 73 bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
74} 74}
75 75
76static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
77{
78 struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
79
80 if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
81 return bcma_core_irq(cc->core);
82 else
83 return -EINVAL;
84}
85
76int bcma_gpio_init(struct bcma_drv_cc *cc) 86int bcma_gpio_init(struct bcma_drv_cc *cc)
77{ 87{
78 struct gpio_chip *chip = &cc->gpio; 88 struct gpio_chip *chip = &cc->gpio;
@@ -85,6 +95,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
85 chip->set = bcma_gpio_set_value; 95 chip->set = bcma_gpio_set_value;
86 chip->direction_input = bcma_gpio_direction_input; 96 chip->direction_input = bcma_gpio_direction_input;
87 chip->direction_output = bcma_gpio_direction_output; 97 chip->direction_output = bcma_gpio_direction_output;
98 chip->to_irq = bcma_gpio_to_irq;
88 chip->ngpio = 16; 99 chip->ngpio = 16;
89 /* There is just one SoC in one device and its GPIO addresses should be 100 /* There is just one SoC in one device and its GPIO addresses should be
90 * deterministic to address them more easily. The other buses could get 101 * deterministic to address them more easily. The other buses could get
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c
index 9fe86ee16c66..9a7f0e3ab5a3 100644
--- a/drivers/bcma/driver_mips.c
+++ b/drivers/bcma/driver_mips.c
@@ -14,11 +14,33 @@
14 14
15#include <linux/bcma/bcma.h> 15#include <linux/bcma/bcma.h>
16 16
17#include <linux/mtd/physmap.h>
18#include <linux/platform_device.h>
17#include <linux/serial.h> 19#include <linux/serial.h>
18#include <linux/serial_core.h> 20#include <linux/serial_core.h>
19#include <linux/serial_reg.h> 21#include <linux/serial_reg.h>
20#include <linux/time.h> 22#include <linux/time.h>
21 23
24static const char *part_probes[] = { "bcm47xxpart", NULL };
25
26static struct physmap_flash_data bcma_pflash_data = {
27 .part_probe_types = part_probes,
28};
29
30static struct resource bcma_pflash_resource = {
31 .name = "bcma_pflash",
32 .flags = IORESOURCE_MEM,
33};
34
35struct platform_device bcma_pflash_dev = {
36 .name = "physmap-flash",
37 .dev = {
38 .platform_data = &bcma_pflash_data,
39 },
40 .resource = &bcma_pflash_resource,
41 .num_resources = 1,
42};
43
22/* The 47162a0 hangs when reading MIPS DMP registers registers */ 44/* The 47162a0 hangs when reading MIPS DMP registers registers */
23static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev) 45static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
24{ 46{
@@ -211,6 +233,7 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
211{ 233{
212 struct bcma_bus *bus = mcore->core->bus; 234 struct bcma_bus *bus = mcore->core->bus;
213 struct bcma_drv_cc *cc = &bus->drv_cc; 235 struct bcma_drv_cc *cc = &bus->drv_cc;
236 struct bcma_pflash *pflash = &cc->pflash;
214 237
215 switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { 238 switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
216 case BCMA_CC_FLASHT_STSER: 239 case BCMA_CC_FLASHT_STSER:
@@ -220,15 +243,20 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
220 break; 243 break;
221 case BCMA_CC_FLASHT_PARA: 244 case BCMA_CC_FLASHT_PARA:
222 bcma_debug(bus, "Found parallel flash\n"); 245 bcma_debug(bus, "Found parallel flash\n");
223 cc->pflash.present = true; 246 pflash->present = true;
224 cc->pflash.window = BCMA_SOC_FLASH2; 247 pflash->window = BCMA_SOC_FLASH2;
225 cc->pflash.window_size = BCMA_SOC_FLASH2_SZ; 248 pflash->window_size = BCMA_SOC_FLASH2_SZ;
226 249
227 if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) & 250 if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) &
228 BCMA_CC_FLASH_CFG_DS) == 0) 251 BCMA_CC_FLASH_CFG_DS) == 0)
229 cc->pflash.buswidth = 1; 252 pflash->buswidth = 1;
230 else 253 else
231 cc->pflash.buswidth = 2; 254 pflash->buswidth = 2;
255
256 bcma_pflash_data.width = pflash->buswidth;
257 bcma_pflash_resource.start = pflash->window;
258 bcma_pflash_resource.end = pflash->window + pflash->window_size;
259
232 break; 260 break;
233 default: 261 default:
234 bcma_err(bus, "Flash type not supported\n"); 262 bcma_err(bus, "Flash type not supported\n");
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index ff8528925322..6eda7ef0682f 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -149,6 +149,14 @@ static int bcma_register_cores(struct bcma_bus *bus)
149 dev_id++; 149 dev_id++;
150 } 150 }
151 151
152#ifdef CONFIG_BCMA_DRIVER_MIPS
153 if (bus->drv_cc.pflash.present) {
154 err = platform_device_register(&bcma_pflash_dev);
155 if (err)
156 bcma_err(bus, "Error registering parallel flash\n");
157 }
158#endif
159
152#ifdef CONFIG_BCMA_SFLASH 160#ifdef CONFIG_BCMA_SFLASH
153 if (bus->drv_cc.sflash.present) { 161 if (bus->drv_cc.sflash.present) {
154 err = platform_device_register(&bcma_sflash_dev); 162 err = platform_device_register(&bcma_sflash_dev);
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 7647ed6b73d7..17507dc8a1e7 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -58,6 +58,7 @@ config ATH9K_DEBUGFS
58 bool "Atheros ath9k debugging" 58 bool "Atheros ath9k debugging"
59 depends on ATH9K 59 depends on ATH9K
60 select MAC80211_DEBUGFS 60 select MAC80211_DEBUGFS
61 select RELAY
61 ---help--- 62 ---help---
62 Say Y, if you need access to ath9k's statistics for 63 Say Y, if you need access to ath9k's statistics for
63 interrupts, rate control, etc. 64 interrupts, rate control, etc.
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index b2d6c18d1678..97c90b21e1cb 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -319,6 +319,8 @@ struct ath_rx {
319 struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; 319 struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
320 320
321 struct sk_buff *frag; 321 struct sk_buff *frag;
322
323 u32 ampdu_ref;
322}; 324};
323 325
324int ath_startrecv(struct ath_softc *sc); 326int ath_startrecv(struct ath_softc *sc);
@@ -754,6 +756,7 @@ struct ath_softc {
754 /* relay(fs) channel for spectral scan */ 756 /* relay(fs) channel for spectral scan */
755 struct rchan *rfs_chan_spec_scan; 757 struct rchan *rfs_chan_spec_scan;
756 enum spectral_mode spectral_mode; 758 enum spectral_mode spectral_mode;
759 struct ath_spec_scan spec_config;
757 int scanning; 760 int scanning;
758 761
759#ifdef CONFIG_PM_SLEEP 762#ifdef CONFIG_PM_SLEEP
@@ -863,31 +866,31 @@ static inline u8 spectral_bitmap_weight(u8 *bins)
863 * interface. 866 * interface.
864 */ 867 */
865enum ath_fft_sample_type { 868enum ath_fft_sample_type {
866 ATH_FFT_SAMPLE_HT20 = 0, 869 ATH_FFT_SAMPLE_HT20 = 1,
867}; 870};
868 871
869struct fft_sample_tlv { 872struct fft_sample_tlv {
870 u8 type; /* see ath_fft_sample */ 873 u8 type; /* see ath_fft_sample */
871 u16 length; 874 __be16 length;
872 /* type dependent data follows */ 875 /* type dependent data follows */
873} __packed; 876} __packed;
874 877
875struct fft_sample_ht20 { 878struct fft_sample_ht20 {
876 struct fft_sample_tlv tlv; 879 struct fft_sample_tlv tlv;
877 880
878 u8 __alignment; 881 u8 max_exp;
879 882
880 u16 freq; 883 __be16 freq;
881 s8 rssi; 884 s8 rssi;
882 s8 noise; 885 s8 noise;
883 886
884 u16 max_magnitude; 887 __be16 max_magnitude;
885 u8 max_index; 888 u8 max_index;
886 u8 bitmap_weight; 889 u8 bitmap_weight;
887 890
888 u64 tsf; 891 __be64 tsf;
889 892
890 u16 data[SPECTRAL_HT20_NUM_BINS]; 893 u8 data[SPECTRAL_HT20_NUM_BINS];
891} __packed; 894} __packed;
892 895
893void ath9k_tasklet(unsigned long data); 896void ath9k_tasklet(unsigned long data);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 6c5d313ebcb7..3714b971d18e 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -895,6 +895,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
895 RXS_ERR("RX-Bytes-All", rx_bytes_all); 895 RXS_ERR("RX-Bytes-All", rx_bytes_all);
896 RXS_ERR("RX-Beacons", rx_beacons); 896 RXS_ERR("RX-Beacons", rx_beacons);
897 RXS_ERR("RX-Frags", rx_frags); 897 RXS_ERR("RX-Frags", rx_frags);
898 RXS_ERR("RX-Spectral", rx_spectral);
898 899
899 if (len > size) 900 if (len > size)
900 len = size; 901 len = size;
@@ -1035,6 +1036,182 @@ static const struct file_operations fops_spec_scan_ctl = {
1035 .llseek = default_llseek, 1036 .llseek = default_llseek,
1036}; 1037};
1037 1038
1039static ssize_t read_file_spectral_short_repeat(struct file *file,
1040 char __user *user_buf,
1041 size_t count, loff_t *ppos)
1042{
1043 struct ath_softc *sc = file->private_data;
1044 char buf[32];
1045 unsigned int len;
1046
1047 len = sprintf(buf, "%d\n", sc->spec_config.short_repeat);
1048 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1049}
1050
1051static ssize_t write_file_spectral_short_repeat(struct file *file,
1052 const char __user *user_buf,
1053 size_t count, loff_t *ppos)
1054{
1055 struct ath_softc *sc = file->private_data;
1056 unsigned long val;
1057 char buf[32];
1058 ssize_t len;
1059
1060 len = min(count, sizeof(buf) - 1);
1061 if (copy_from_user(buf, user_buf, len))
1062 return -EFAULT;
1063
1064 buf[len] = '\0';
1065 if (kstrtoul(buf, 0, &val))
1066 return -EINVAL;
1067
1068 if (val < 0 || val > 1)
1069 return -EINVAL;
1070
1071 sc->spec_config.short_repeat = val;
1072 return count;
1073}
1074
1075static const struct file_operations fops_spectral_short_repeat = {
1076 .read = read_file_spectral_short_repeat,
1077 .write = write_file_spectral_short_repeat,
1078 .open = simple_open,
1079 .owner = THIS_MODULE,
1080 .llseek = default_llseek,
1081};
1082
1083static ssize_t read_file_spectral_count(struct file *file,
1084 char __user *user_buf,
1085 size_t count, loff_t *ppos)
1086{
1087 struct ath_softc *sc = file->private_data;
1088 char buf[32];
1089 unsigned int len;
1090
1091 len = sprintf(buf, "%d\n", sc->spec_config.count);
1092 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1093}
1094
1095static ssize_t write_file_spectral_count(struct file *file,
1096 const char __user *user_buf,
1097 size_t count, loff_t *ppos)
1098{
1099 struct ath_softc *sc = file->private_data;
1100 unsigned long val;
1101 char buf[32];
1102 ssize_t len;
1103
1104 len = min(count, sizeof(buf) - 1);
1105 if (copy_from_user(buf, user_buf, len))
1106 return -EFAULT;
1107
1108 buf[len] = '\0';
1109 if (kstrtoul(buf, 0, &val))
1110 return -EINVAL;
1111
1112 if (val < 0 || val > 255)
1113 return -EINVAL;
1114
1115 sc->spec_config.count = val;
1116 return count;
1117}
1118
1119static const struct file_operations fops_spectral_count = {
1120 .read = read_file_spectral_count,
1121 .write = write_file_spectral_count,
1122 .open = simple_open,
1123 .owner = THIS_MODULE,
1124 .llseek = default_llseek,
1125};
1126
1127static ssize_t read_file_spectral_period(struct file *file,
1128 char __user *user_buf,
1129 size_t count, loff_t *ppos)
1130{
1131 struct ath_softc *sc = file->private_data;
1132 char buf[32];
1133 unsigned int len;
1134
1135 len = sprintf(buf, "%d\n", sc->spec_config.period);
1136 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1137}
1138
1139static ssize_t write_file_spectral_period(struct file *file,
1140 const char __user *user_buf,
1141 size_t count, loff_t *ppos)
1142{
1143 struct ath_softc *sc = file->private_data;
1144 unsigned long val;
1145 char buf[32];
1146 ssize_t len;
1147
1148 len = min(count, sizeof(buf) - 1);
1149 if (copy_from_user(buf, user_buf, len))
1150 return -EFAULT;
1151
1152 buf[len] = '\0';
1153 if (kstrtoul(buf, 0, &val))
1154 return -EINVAL;
1155
1156 if (val < 0 || val > 255)
1157 return -EINVAL;
1158
1159 sc->spec_config.period = val;
1160 return count;
1161}
1162
1163static const struct file_operations fops_spectral_period = {
1164 .read = read_file_spectral_period,
1165 .write = write_file_spectral_period,
1166 .open = simple_open,
1167 .owner = THIS_MODULE,
1168 .llseek = default_llseek,
1169};
1170
1171static ssize_t read_file_spectral_fft_period(struct file *file,
1172 char __user *user_buf,
1173 size_t count, loff_t *ppos)
1174{
1175 struct ath_softc *sc = file->private_data;
1176 char buf[32];
1177 unsigned int len;
1178
1179 len = sprintf(buf, "%d\n", sc->spec_config.fft_period);
1180 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1181}
1182
1183static ssize_t write_file_spectral_fft_period(struct file *file,
1184 const char __user *user_buf,
1185 size_t count, loff_t *ppos)
1186{
1187 struct ath_softc *sc = file->private_data;
1188 unsigned long val;
1189 char buf[32];
1190 ssize_t len;
1191
1192 len = min(count, sizeof(buf) - 1);
1193 if (copy_from_user(buf, user_buf, len))
1194 return -EFAULT;
1195
1196 buf[len] = '\0';
1197 if (kstrtoul(buf, 0, &val))
1198 return -EINVAL;
1199
1200 if (val < 0 || val > 15)
1201 return -EINVAL;
1202
1203 sc->spec_config.fft_period = val;
1204 return count;
1205}
1206
1207static const struct file_operations fops_spectral_fft_period = {
1208 .read = read_file_spectral_fft_period,
1209 .write = write_file_spectral_fft_period,
1210 .open = simple_open,
1211 .owner = THIS_MODULE,
1212 .llseek = default_llseek,
1213};
1214
1038static struct dentry *create_buf_file_handler(const char *filename, 1215static struct dentry *create_buf_file_handler(const char *filename,
1039 struct dentry *parent, 1216 struct dentry *parent,
1040 umode_t mode, 1217 umode_t mode,
@@ -1059,11 +1236,13 @@ static int remove_buf_file_handler(struct dentry *dentry)
1059void ath_debug_send_fft_sample(struct ath_softc *sc, 1236void ath_debug_send_fft_sample(struct ath_softc *sc,
1060 struct fft_sample_tlv *fft_sample_tlv) 1237 struct fft_sample_tlv *fft_sample_tlv)
1061{ 1238{
1239 int length;
1062 if (!sc->rfs_chan_spec_scan) 1240 if (!sc->rfs_chan_spec_scan)
1063 return; 1241 return;
1064 1242
1065 relay_write(sc->rfs_chan_spec_scan, fft_sample_tlv, 1243 length = __be16_to_cpu(fft_sample_tlv->length) +
1066 fft_sample_tlv->length + sizeof(*fft_sample_tlv)); 1244 sizeof(*fft_sample_tlv);
1245 relay_write(sc->rfs_chan_spec_scan, fft_sample_tlv, length);
1067} 1246}
1068 1247
1069static struct rchan_callbacks rfs_spec_scan_cb = { 1248static struct rchan_callbacks rfs_spec_scan_cb = {
@@ -1893,6 +2072,16 @@ int ath9k_init_debug(struct ath_hw *ah)
1893 debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR, 2072 debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR,
1894 sc->debug.debugfs_phy, sc, 2073 sc->debug.debugfs_phy, sc,
1895 &fops_spec_scan_ctl); 2074 &fops_spec_scan_ctl);
2075 debugfs_create_file("spectral_short_repeat", S_IRUSR | S_IWUSR,
2076 sc->debug.debugfs_phy, sc,
2077 &fops_spectral_short_repeat);
2078 debugfs_create_file("spectral_count", S_IRUSR | S_IWUSR,
2079 sc->debug.debugfs_phy, sc, &fops_spectral_count);
2080 debugfs_create_file("spectral_period", S_IRUSR | S_IWUSR,
2081 sc->debug.debugfs_phy, sc, &fops_spectral_period);
2082 debugfs_create_file("spectral_fft_period", S_IRUSR | S_IWUSR,
2083 sc->debug.debugfs_phy, sc,
2084 &fops_spectral_fft_period);
1896 2085
1897#ifdef CONFIG_ATH9K_MAC_DEBUG 2086#ifdef CONFIG_ATH9K_MAC_DEBUG
1898 debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, 2087 debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index a22c0d780700..410d6d8f1aa7 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -219,6 +219,7 @@ struct ath_tx_stats {
219 * @rx_too_many_frags_err: Frames dropped due to too-many-frags received. 219 * @rx_too_many_frags_err: Frames dropped due to too-many-frags received.
220 * @rx_beacons: No. of beacons received. 220 * @rx_beacons: No. of beacons received.
221 * @rx_frags: No. of rx-fragements received. 221 * @rx_frags: No. of rx-fragements received.
222 * @rx_spectral: No of spectral packets received.
222 */ 223 */
223struct ath_rx_stats { 224struct ath_rx_stats {
224 u32 rx_pkts_all; 225 u32 rx_pkts_all;
@@ -237,6 +238,7 @@ struct ath_rx_stats {
237 u32 rx_too_many_frags_err; 238 u32 rx_too_many_frags_err;
238 u32 rx_beacons; 239 u32 rx_beacons;
239 u32 rx_frags; 240 u32 rx_frags;
241 u32 rx_spectral;
240}; 242};
241 243
242struct ath_stats { 244struct ath_stats {
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 4b1abc7da98c..af932c9444de 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -497,6 +497,13 @@ static void ath9k_init_misc(struct ath_softc *sc)
497 497
498 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) 498 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
499 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; 499 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
500
501 sc->spec_config.enabled = 0;
502 sc->spec_config.short_repeat = true;
503 sc->spec_config.count = 8;
504 sc->spec_config.endless = false;
505 sc->spec_config.period = 0xFF;
506 sc->spec_config.fft_period = 0xF;
500} 507}
501 508
502static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob, 509static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob,
@@ -915,7 +922,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
915 922
916 ath9k_eeprom_release(sc); 923 ath9k_eeprom_release(sc);
917 924
918 if (sc->rfs_chan_spec_scan) { 925 if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) {
919 relay_close(sc->rfs_chan_spec_scan); 926 relay_close(sc->rfs_chan_spec_scan);
920 sc->rfs_chan_spec_scan = NULL; 927 sc->rfs_chan_spec_scan = NULL;
921 } 928 }
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index b42be910a83d..811007ec07a7 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -605,13 +605,13 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
605 * reported, then decryption and MIC errors are irrelevant, 605 * reported, then decryption and MIC errors are irrelevant,
606 * the frame is going to be dropped either way 606 * the frame is going to be dropped either way
607 */ 607 */
608 if (ads.ds_rxstatus8 & AR_CRCErr) 608 if (ads.ds_rxstatus8 & AR_PHYErr) {
609 rs->rs_status |= ATH9K_RXERR_CRC;
610 else if (ads.ds_rxstatus8 & AR_PHYErr) {
611 rs->rs_status |= ATH9K_RXERR_PHY; 609 rs->rs_status |= ATH9K_RXERR_PHY;
612 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); 610 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
613 rs->rs_phyerr = phyerr; 611 rs->rs_phyerr = phyerr;
614 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) 612 } else if (ads.ds_rxstatus8 & AR_CRCErr)
613 rs->rs_status |= ATH9K_RXERR_CRC;
614 else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
615 rs->rs_status |= ATH9K_RXERR_DECRYPT; 615 rs->rs_status |= ATH9K_RXERR_DECRYPT;
616 else if (ads.ds_rxstatus8 & AR_MichaelErr) 616 else if (ads.ds_rxstatus8 & AR_MichaelErr)
617 rs->rs_status |= ATH9K_RXERR_MIC; 617 rs->rs_status |= ATH9K_RXERR_MIC;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4b72b660f180..5432f1247e2e 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1099,45 +1099,34 @@ int ath9k_spectral_scan_config(struct ieee80211_hw *hw,
1099 struct ath_softc *sc = hw->priv; 1099 struct ath_softc *sc = hw->priv;
1100 struct ath_hw *ah = sc->sc_ah; 1100 struct ath_hw *ah = sc->sc_ah;
1101 struct ath_common *common = ath9k_hw_common(ah); 1101 struct ath_common *common = ath9k_hw_common(ah);
1102 struct ath_spec_scan param;
1103 1102
1104 if (!ath9k_hw_ops(ah)->spectral_scan_trigger) { 1103 if (!ath9k_hw_ops(ah)->spectral_scan_trigger) {
1105 ath_err(common, "spectrum analyzer not implemented on this hardware\n"); 1104 ath_err(common, "spectrum analyzer not implemented on this hardware\n");
1106 return -1; 1105 return -1;
1107 } 1106 }
1108 1107
1109 /* NOTE: this will generate a few samples ...
1110 *
1111 * TODO: review default parameters, and/or define an interface to set
1112 * them.
1113 */
1114 param.enabled = 1;
1115 param.short_repeat = true;
1116 param.count = 8;
1117 param.endless = false;
1118 param.period = 0xFF;
1119 param.fft_period = 0xF;
1120
1121 switch (spectral_mode) { 1108 switch (spectral_mode) {
1122 case SPECTRAL_DISABLED: 1109 case SPECTRAL_DISABLED:
1123 param.enabled = 0; 1110 sc->spec_config.enabled = 0;
1124 break; 1111 break;
1125 case SPECTRAL_BACKGROUND: 1112 case SPECTRAL_BACKGROUND:
1126 /* send endless samples. 1113 /* send endless samples.
1127 * TODO: is this really useful for "background"? 1114 * TODO: is this really useful for "background"?
1128 */ 1115 */
1129 param.endless = 1; 1116 sc->spec_config.endless = 1;
1117 sc->spec_config.enabled = 1;
1130 break; 1118 break;
1131 case SPECTRAL_CHANSCAN: 1119 case SPECTRAL_CHANSCAN:
1132 break;
1133 case SPECTRAL_MANUAL: 1120 case SPECTRAL_MANUAL:
1121 sc->spec_config.endless = 0;
1122 sc->spec_config.enabled = 1;
1134 break; 1123 break;
1135 default: 1124 default:
1136 return -1; 1125 return -1;
1137 } 1126 }
1138 1127
1139 ath9k_ps_wakeup(sc); 1128 ath9k_ps_wakeup(sc);
1140 ath9k_hw_ops(ah)->spectral_scan_config(ah, &param); 1129 ath9k_hw_ops(ah)->spectral_scan_config(ah, &sc->spec_config);
1141 ath9k_ps_restore(sc); 1130 ath9k_ps_restore(sc);
1142 1131
1143 sc->spectral_mode = spectral_mode; 1132 sc->spectral_mode = spectral_mode;
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index d2074334ec9b..815bee21c19a 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -474,8 +474,6 @@ void ath_mci_cleanup(struct ath_softc *sc)
474{ 474{
475 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 475 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
476 struct ath_hw *ah = sc->sc_ah; 476 struct ath_hw *ah = sc->sc_ah;
477 struct ath_mci_coex *mci = &sc->mci_coex;
478 struct ath_mci_buf *buf = &mci->sched_buf;
479 477
480 ar9003_mci_cleanup(ah); 478 ar9003_mci_cleanup(ah);
481 479
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index d7c129bb571b..2d0fd17a1917 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1016,18 +1016,20 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common,
1016 rxs->flag &= ~RX_FLAG_DECRYPTED; 1016 rxs->flag &= ~RX_FLAG_DECRYPTED;
1017} 1017}
1018 1018
1019#ifdef CONFIG_ATH9K_DEBUGFS
1019static s8 fix_rssi_inv_only(u8 rssi_val) 1020static s8 fix_rssi_inv_only(u8 rssi_val)
1020{ 1021{
1021 if (rssi_val == 128) 1022 if (rssi_val == 128)
1022 rssi_val = 0; 1023 rssi_val = 0;
1023 return (s8) rssi_val; 1024 return (s8) rssi_val;
1024} 1025}
1026#endif
1025 1027
1026 1028/* returns 1 if this was a spectral frame, even if not handled. */
1027static void ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr, 1029static int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
1028 struct ath_rx_status *rs, u64 tsf) 1030 struct ath_rx_status *rs, u64 tsf)
1029{ 1031{
1030#ifdef CONFIG_ATH_DEBUG 1032#ifdef CONFIG_ATH9K_DEBUGFS
1031 struct ath_hw *ah = sc->sc_ah; 1033 struct ath_hw *ah = sc->sc_ah;
1032 u8 bins[SPECTRAL_HT20_NUM_BINS]; 1034 u8 bins[SPECTRAL_HT20_NUM_BINS];
1033 u8 *vdata = (u8 *)hdr; 1035 u8 *vdata = (u8 *)hdr;
@@ -1035,7 +1037,8 @@ static void ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
1035 struct ath_radar_info *radar_info; 1037 struct ath_radar_info *radar_info;
1036 struct ath_ht20_mag_info *mag_info; 1038 struct ath_ht20_mag_info *mag_info;
1037 int len = rs->rs_datalen; 1039 int len = rs->rs_datalen;
1038 int i, dc_pos; 1040 int dc_pos;
1041 u16 length, max_magnitude;
1039 1042
1040 /* AR9280 and before report via ATH9K_PHYERR_RADAR, AR93xx and newer 1043 /* AR9280 and before report via ATH9K_PHYERR_RADAR, AR93xx and newer
1041 * via ATH9K_PHYERR_SPECTRAL. Haven't seen ATH9K_PHYERR_FALSE_RADAR_EXT 1044 * via ATH9K_PHYERR_SPECTRAL. Haven't seen ATH9K_PHYERR_FALSE_RADAR_EXT
@@ -1044,7 +1047,14 @@ static void ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
1044 if (rs->rs_phyerr != ATH9K_PHYERR_RADAR && 1047 if (rs->rs_phyerr != ATH9K_PHYERR_RADAR &&
1045 rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT && 1048 rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT &&
1046 rs->rs_phyerr != ATH9K_PHYERR_SPECTRAL) 1049 rs->rs_phyerr != ATH9K_PHYERR_SPECTRAL)
1047 return; 1050 return 0;
1051
1052 /* check if spectral scan bit is set. This does not have to be checked
1053 * if received through a SPECTRAL phy error, but shouldn't hurt.
1054 */
1055 radar_info = ((struct ath_radar_info *)&vdata[len]) - 1;
1056 if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
1057 return 0;
1048 1058
1049 /* Variation in the data length is possible and will be fixed later. 1059 /* Variation in the data length is possible and will be fixed later.
1050 * Note that we only support HT20 for now. 1060 * Note that we only support HT20 for now.
@@ -1053,19 +1063,13 @@ static void ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
1053 */ 1063 */
1054 if ((len > SPECTRAL_HT20_TOTAL_DATA_LEN + 2) || 1064 if ((len > SPECTRAL_HT20_TOTAL_DATA_LEN + 2) ||
1055 (len < SPECTRAL_HT20_TOTAL_DATA_LEN - 1)) 1065 (len < SPECTRAL_HT20_TOTAL_DATA_LEN - 1))
1056 return; 1066 return 1;
1057
1058 /* check if spectral scan bit is set. This does not have to be checked
1059 * if received through a SPECTRAL phy error, but shouldn't hurt.
1060 */
1061 radar_info = ((struct ath_radar_info *)&vdata[len]) - 1;
1062 if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
1063 return;
1064 1067
1065 fft_sample.tlv.type = ATH_FFT_SAMPLE_HT20; 1068 fft_sample.tlv.type = ATH_FFT_SAMPLE_HT20;
1066 fft_sample.tlv.length = sizeof(fft_sample) - sizeof(fft_sample.tlv); 1069 length = sizeof(fft_sample) - sizeof(fft_sample.tlv);
1070 fft_sample.tlv.length = __cpu_to_be16(length);
1067 1071
1068 fft_sample.freq = ah->curchan->chan->center_freq; 1072 fft_sample.freq = __cpu_to_be16(ah->curchan->chan->center_freq);
1069 fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0); 1073 fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
1070 fft_sample.noise = ah->noise; 1074 fft_sample.noise = ah->noise;
1071 1075
@@ -1093,7 +1097,7 @@ static void ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
1093 memcpy(&bins[32], &vdata[33], SPECTRAL_HT20_NUM_BINS - 32); 1097 memcpy(&bins[32], &vdata[33], SPECTRAL_HT20_NUM_BINS - 32);
1094 break; 1098 break;
1095 default: 1099 default:
1096 return; 1100 return 1;
1097 } 1101 }
1098 1102
1099 /* DC value (value in the middle) is the blind spot of the spectral 1103 /* DC value (value in the middle) is the blind spot of the spectral
@@ -1105,19 +1109,41 @@ static void ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
1105 /* mag data is at the end of the frame, in front of radar_info */ 1109 /* mag data is at the end of the frame, in front of radar_info */
1106 mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1; 1110 mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1;
1107 1111
1108 /* Apply exponent and grab further auxiliary information. */ 1112 /* copy raw bins without scaling them */
1109 for (i = 0; i < SPECTRAL_HT20_NUM_BINS; i++) 1113 memcpy(fft_sample.data, bins, SPECTRAL_HT20_NUM_BINS);
1110 fft_sample.data[i] = bins[i] << mag_info->max_exp; 1114 fft_sample.max_exp = mag_info->max_exp & 0xf;
1111 1115
1112 fft_sample.max_magnitude = spectral_max_magnitude(mag_info->all_bins); 1116 max_magnitude = spectral_max_magnitude(mag_info->all_bins);
1117 fft_sample.max_magnitude = __cpu_to_be16(max_magnitude);
1113 fft_sample.max_index = spectral_max_index(mag_info->all_bins); 1118 fft_sample.max_index = spectral_max_index(mag_info->all_bins);
1114 fft_sample.bitmap_weight = spectral_bitmap_weight(mag_info->all_bins); 1119 fft_sample.bitmap_weight = spectral_bitmap_weight(mag_info->all_bins);
1115 fft_sample.tsf = tsf; 1120 fft_sample.tsf = __cpu_to_be64(tsf);
1116 1121
1117 ath_debug_send_fft_sample(sc, &fft_sample.tlv); 1122 ath_debug_send_fft_sample(sc, &fft_sample.tlv);
1123 return 1;
1124#else
1125 return 0;
1118#endif 1126#endif
1119} 1127}
1120 1128
1129static void ath9k_apply_ampdu_details(struct ath_softc *sc,
1130 struct ath_rx_status *rs, struct ieee80211_rx_status *rxs)
1131{
1132 if (rs->rs_isaggr) {
1133 rxs->flag |= RX_FLAG_AMPDU_DETAILS | RX_FLAG_AMPDU_LAST_KNOWN;
1134
1135 rxs->ampdu_reference = sc->rx.ampdu_ref;
1136
1137 if (!rs->rs_moreaggr) {
1138 rxs->flag |= RX_FLAG_AMPDU_IS_LAST;
1139 sc->rx.ampdu_ref++;
1140 }
1141
1142 if (rs->rs_flags & ATH9K_RX_DELIM_CRC_PRE)
1143 rxs->flag |= RX_FLAG_AMPDU_DELIM_CRC_ERROR;
1144 }
1145}
1146
1121int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) 1147int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1122{ 1148{
1123 struct ath_buf *bf; 1149 struct ath_buf *bf;
@@ -1202,8 +1228,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1202 unlikely(tsf_lower - rs.rs_tstamp > 0x10000000)) 1228 unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
1203 rxs->mactime += 0x100000000ULL; 1229 rxs->mactime += 0x100000000ULL;
1204 1230
1205 if ((rs.rs_status & ATH9K_RXERR_PHY)) 1231 if (rs.rs_status & ATH9K_RXERR_PHY) {
1206 ath_process_fft(sc, hdr, &rs, rxs->mactime); 1232 if (ath_process_fft(sc, hdr, &rs, rxs->mactime)) {
1233 RX_STAT_INC(rx_spectral);
1234 goto requeue_drop_frag;
1235 }
1236 }
1207 1237
1208 retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, 1238 retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
1209 rxs, &decrypt_error); 1239 rxs, &decrypt_error);
@@ -1320,6 +1350,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1320 if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx == 3) 1350 if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx == 3)
1321 ath_ant_comb_scan(sc, &rs); 1351 ath_ant_comb_scan(sc, &rs);
1322 1352
1353 ath9k_apply_ampdu_details(sc, &rs, rxs);
1354
1323 ieee80211_rx(hw, skb); 1355 ieee80211_rx(hw, skb);
1324 1356
1325requeue_drop_frag: 1357requeue_drop_frag:
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 116f4e807ae1..002851fceb2f 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -204,7 +204,6 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
204 break; 204 break;
205 default: 205 default:
206 return -EOPNOTSUPP; 206 return -EOPNOTSUPP;
207
208 } 207 }
209 208
210 /* FW don't support scan after connection attempt */ 209 /* FW don't support scan after connection attempt */
@@ -228,8 +227,8 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
228 } 227 }
229 /* 0-based channel indexes */ 228 /* 0-based channel indexes */
230 cmd.cmd.channel_list[cmd.cmd.num_channels++].channel = ch - 1; 229 cmd.cmd.channel_list[cmd.cmd.num_channels++].channel = ch - 1;
231 wil_dbg(wil, "Scan for ch %d : %d MHz\n", ch, 230 wil_dbg_misc(wil, "Scan for ch %d : %d MHz\n", ch,
232 request->channels[i]->center_freq); 231 request->channels[i]->center_freq);
233 } 232 }
234 233
235 return wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) + 234 return wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
@@ -425,8 +424,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
425 return -EINVAL; 424 return -EINVAL;
426 } 425 }
427 426
428 wil_dbg(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value, 427 wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
429 channel->center_freq, info->privacy ? "secure" : "open"); 428 channel->center_freq, info->privacy ? "secure" : "open");
430 print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET, 429 print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
431 info->ssid, info->ssid_len); 430 info->ssid, info->ssid_len);
432 431
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 38049da71049..dc97e7b2609c 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -38,7 +38,9 @@
38#define WIL6210_IMC_RX BIT_DMA_EP_RX_ICR_RX_DONE 38#define WIL6210_IMC_RX BIT_DMA_EP_RX_ICR_RX_DONE
39#define WIL6210_IMC_TX (BIT_DMA_EP_TX_ICR_TX_DONE | \ 39#define WIL6210_IMC_TX (BIT_DMA_EP_TX_ICR_TX_DONE | \
40 BIT_DMA_EP_TX_ICR_TX_DONE_N(0)) 40 BIT_DMA_EP_TX_ICR_TX_DONE_N(0))
41#define WIL6210_IMC_MISC (ISR_MISC_FW_READY | ISR_MISC_MBOX_EVT) 41#define WIL6210_IMC_MISC (ISR_MISC_FW_READY | \
42 ISR_MISC_MBOX_EVT | \
43 ISR_MISC_FW_ERROR)
42 44
43#define WIL6210_IRQ_PSEUDO_MASK (u32)(~(BIT_DMA_PSEUDO_CAUSE_RX | \ 45#define WIL6210_IRQ_PSEUDO_MASK (u32)(~(BIT_DMA_PSEUDO_CAUSE_RX | \
44 BIT_DMA_PSEUDO_CAUSE_TX | \ 46 BIT_DMA_PSEUDO_CAUSE_TX | \
@@ -50,7 +52,6 @@
50 52
51static inline void wil_icr_clear(u32 x, void __iomem *addr) 53static inline void wil_icr_clear(u32 x, void __iomem *addr)
52{ 54{
53
54} 55}
55#else /* defined(CONFIG_WIL6210_ISR_COR) */ 56#else /* defined(CONFIG_WIL6210_ISR_COR) */
56/* configure to Write-1-to-Clear mode */ 57/* configure to Write-1-to-Clear mode */
@@ -94,7 +95,7 @@ static void wil6210_mask_irq_misc(struct wil6210_priv *wil)
94 95
95static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil) 96static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil)
96{ 97{
97 wil_dbg_IRQ(wil, "%s()\n", __func__); 98 wil_dbg_irq(wil, "%s()\n", __func__);
98 99
99 iowrite32(WIL6210_IRQ_DISABLE, wil->csr + 100 iowrite32(WIL6210_IRQ_DISABLE, wil->csr +
100 HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); 101 HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW));
@@ -125,7 +126,7 @@ static void wil6210_unmask_irq_misc(struct wil6210_priv *wil)
125 126
126static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil) 127static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
127{ 128{
128 wil_dbg_IRQ(wil, "%s()\n", __func__); 129 wil_dbg_irq(wil, "%s()\n", __func__);
129 130
130 set_bit(wil_status_irqen, &wil->status); 131 set_bit(wil_status_irqen, &wil->status);
131 132
@@ -135,7 +136,7 @@ static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
135 136
136void wil6210_disable_irq(struct wil6210_priv *wil) 137void wil6210_disable_irq(struct wil6210_priv *wil)
137{ 138{
138 wil_dbg_IRQ(wil, "%s()\n", __func__); 139 wil_dbg_irq(wil, "%s()\n", __func__);
139 140
140 wil6210_mask_irq_tx(wil); 141 wil6210_mask_irq_tx(wil);
141 wil6210_mask_irq_rx(wil); 142 wil6210_mask_irq_rx(wil);
@@ -145,7 +146,7 @@ void wil6210_disable_irq(struct wil6210_priv *wil)
145 146
146void wil6210_enable_irq(struct wil6210_priv *wil) 147void wil6210_enable_irq(struct wil6210_priv *wil)
147{ 148{
148 wil_dbg_IRQ(wil, "%s()\n", __func__); 149 wil_dbg_irq(wil, "%s()\n", __func__);
149 150
150 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) + 151 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) +
151 offsetof(struct RGF_ICR, ICC)); 152 offsetof(struct RGF_ICR, ICC));
@@ -167,7 +168,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
167 HOSTADDR(RGF_DMA_EP_RX_ICR) + 168 HOSTADDR(RGF_DMA_EP_RX_ICR) +
168 offsetof(struct RGF_ICR, ICR)); 169 offsetof(struct RGF_ICR, ICR));
169 170
170 wil_dbg_IRQ(wil, "ISR RX 0x%08x\n", isr); 171 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr);
171 172
172 if (!isr) { 173 if (!isr) {
173 wil_err(wil, "spurious IRQ: RX\n"); 174 wil_err(wil, "spurious IRQ: RX\n");
@@ -177,7 +178,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
177 wil6210_mask_irq_rx(wil); 178 wil6210_mask_irq_rx(wil);
178 179
179 if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) { 180 if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) {
180 wil_dbg_IRQ(wil, "RX done\n"); 181 wil_dbg_irq(wil, "RX done\n");
181 isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE; 182 isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE;
182 wil_rx_handle(wil); 183 wil_rx_handle(wil);
183 } 184 }
@@ -197,7 +198,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
197 HOSTADDR(RGF_DMA_EP_TX_ICR) + 198 HOSTADDR(RGF_DMA_EP_TX_ICR) +
198 offsetof(struct RGF_ICR, ICR)); 199 offsetof(struct RGF_ICR, ICR));
199 200
200 wil_dbg_IRQ(wil, "ISR TX 0x%08x\n", isr); 201 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr);
201 202
202 if (!isr) { 203 if (!isr) {
203 wil_err(wil, "spurious IRQ: TX\n"); 204 wil_err(wil, "spurious IRQ: TX\n");
@@ -208,13 +209,13 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
208 209
209 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) { 210 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) {
210 uint i; 211 uint i;
211 wil_dbg_IRQ(wil, "TX done\n"); 212 wil_dbg_irq(wil, "TX done\n");
212 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; 213 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
213 for (i = 0; i < 24; i++) { 214 for (i = 0; i < 24; i++) {
214 u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i); 215 u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i);
215 if (isr & mask) { 216 if (isr & mask) {
216 isr &= ~mask; 217 isr &= ~mask;
217 wil_dbg_IRQ(wil, "TX done(%i)\n", i); 218 wil_dbg_irq(wil, "TX done(%i)\n", i);
218 wil_tx_complete(wil, i); 219 wil_tx_complete(wil, i);
219 } 220 }
220 } 221 }
@@ -228,6 +229,17 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
228 return IRQ_HANDLED; 229 return IRQ_HANDLED;
229} 230}
230 231
232static void wil_notify_fw_error(struct wil6210_priv *wil)
233{
234 struct device *dev = &wil_to_ndev(wil)->dev;
235 char *envp[3] = {
236 [0] = "SOURCE=wil6210",
237 [1] = "EVENT=FW_ERROR",
238 [2] = NULL,
239 };
240 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
241}
242
231static irqreturn_t wil6210_irq_misc(int irq, void *cookie) 243static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
232{ 244{
233 struct wil6210_priv *wil = cookie; 245 struct wil6210_priv *wil = cookie;
@@ -235,7 +247,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
235 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 247 HOSTADDR(RGF_DMA_EP_MISC_ICR) +
236 offsetof(struct RGF_ICR, ICR)); 248 offsetof(struct RGF_ICR, ICR));
237 249
238 wil_dbg_IRQ(wil, "ISR MISC 0x%08x\n", isr); 250 wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr);
239 251
240 if (!isr) { 252 if (!isr) {
241 wil_err(wil, "spurious IRQ: MISC\n"); 253 wil_err(wil, "spurious IRQ: MISC\n");
@@ -244,8 +256,15 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
244 256
245 wil6210_mask_irq_misc(wil); 257 wil6210_mask_irq_misc(wil);
246 258
259 if (isr & ISR_MISC_FW_ERROR) {
260 wil_dbg_irq(wil, "IRQ: Firmware error\n");
261 clear_bit(wil_status_fwready, &wil->status);
262 wil_notify_fw_error(wil);
263 isr &= ~ISR_MISC_FW_ERROR;
264 }
265
247 if (isr & ISR_MISC_FW_READY) { 266 if (isr & ISR_MISC_FW_READY) {
248 wil_dbg_IRQ(wil, "IRQ: FW ready\n"); 267 wil_dbg_irq(wil, "IRQ: FW ready\n");
249 /** 268 /**
250 * Actual FW ready indicated by the 269 * Actual FW ready indicated by the
251 * WMI_FW_READY_EVENTID 270 * WMI_FW_READY_EVENTID
@@ -268,10 +287,10 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
268 struct wil6210_priv *wil = cookie; 287 struct wil6210_priv *wil = cookie;
269 u32 isr = wil->isr_misc; 288 u32 isr = wil->isr_misc;
270 289
271 wil_dbg_IRQ(wil, "Thread ISR MISC 0x%08x\n", isr); 290 wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr);
272 291
273 if (isr & ISR_MISC_MBOX_EVT) { 292 if (isr & ISR_MISC_MBOX_EVT) {
274 wil_dbg_IRQ(wil, "MBOX event\n"); 293 wil_dbg_irq(wil, "MBOX event\n");
275 wmi_recv_cmd(wil); 294 wmi_recv_cmd(wil);
276 isr &= ~ISR_MISC_MBOX_EVT; 295 isr &= ~ISR_MISC_MBOX_EVT;
277 } 296 }
@@ -293,7 +312,7 @@ static irqreturn_t wil6210_thread_irq(int irq, void *cookie)
293{ 312{
294 struct wil6210_priv *wil = cookie; 313 struct wil6210_priv *wil = cookie;
295 314
296 wil_dbg_IRQ(wil, "Thread IRQ\n"); 315 wil_dbg_irq(wil, "Thread IRQ\n");
297 /* Discover real IRQ cause */ 316 /* Discover real IRQ cause */
298 if (wil->isr_misc) 317 if (wil->isr_misc)
299 wil6210_irq_misc_thread(irq, cookie); 318 wil6210_irq_misc_thread(irq, cookie);
@@ -370,6 +389,8 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
370 if (wil6210_debug_irq_mask(wil, pseudo_cause)) 389 if (wil6210_debug_irq_mask(wil, pseudo_cause))
371 return IRQ_NONE; 390 return IRQ_NONE;
372 391
392 wil_dbg_irq(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause);
393
373 wil6210_mask_irq_pseudo(wil); 394 wil6210_mask_irq_pseudo(wil);
374 395
375 /* Discover real IRQ cause 396 /* Discover real IRQ cause
@@ -401,8 +422,6 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
401 if (rc != IRQ_WAKE_THREAD) 422 if (rc != IRQ_WAKE_THREAD)
402 wil6210_unmask_irq_pseudo(wil); 423 wil6210_unmask_irq_pseudo(wil);
403 424
404 wil_dbg_IRQ(wil, "Hard IRQ 0x%08x\n", pseudo_cause);
405
406 return rc; 425 return rc;
407} 426}
408 427
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 95fcd361322b..761c389586d4 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -64,7 +64,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
64 struct net_device *ndev = wil_to_ndev(wil); 64 struct net_device *ndev = wil_to_ndev(wil);
65 struct wireless_dev *wdev = wil->wdev; 65 struct wireless_dev *wdev = wil->wdev;
66 66
67 wil_dbg(wil, "%s()\n", __func__); 67 wil_dbg_misc(wil, "%s()\n", __func__);
68 68
69 wil_link_off(wil); 69 wil_link_off(wil);
70 clear_bit(wil_status_fwconnected, &wil->status); 70 clear_bit(wil_status_fwconnected, &wil->status);
@@ -80,11 +80,13 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
80 GFP_KERNEL); 80 GFP_KERNEL);
81 break; 81 break;
82 default: 82 default:
83 ; 83 break;
84 } 84 }
85 85
86 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) 86 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++)
87 wil_vring_fini_tx(wil, i); 87 wil_vring_fini_tx(wil, i);
88
89 clear_bit(wil_status_dontscan, &wil->status);
88} 90}
89 91
90static void wil_disconnect_worker(struct work_struct *work) 92static void wil_disconnect_worker(struct work_struct *work)
@@ -99,7 +101,7 @@ static void wil_connect_timer_fn(ulong x)
99{ 101{
100 struct wil6210_priv *wil = (void *)x; 102 struct wil6210_priv *wil = (void *)x;
101 103
102 wil_dbg(wil, "Connect timeout\n"); 104 wil_dbg_misc(wil, "Connect timeout\n");
103 105
104 /* reschedule to thread context - disconnect won't 106 /* reschedule to thread context - disconnect won't
105 * run from atomic context 107 * run from atomic context
@@ -107,9 +109,18 @@ static void wil_connect_timer_fn(ulong x)
107 schedule_work(&wil->disconnect_worker); 109 schedule_work(&wil->disconnect_worker);
108} 110}
109 111
112static void wil_cache_mbox_regs(struct wil6210_priv *wil)
113{
114 /* make shadow copy of registers that should not change on run time */
115 wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
116 sizeof(struct wil6210_mbox_ctl));
117 wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
118 wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
119}
120
110int wil_priv_init(struct wil6210_priv *wil) 121int wil_priv_init(struct wil6210_priv *wil)
111{ 122{
112 wil_dbg(wil, "%s()\n", __func__); 123 wil_dbg_misc(wil, "%s()\n", __func__);
113 124
114 mutex_init(&wil->mutex); 125 mutex_init(&wil->mutex);
115 mutex_init(&wil->wmi_mutex); 126 mutex_init(&wil->wmi_mutex);
@@ -136,11 +147,7 @@ int wil_priv_init(struct wil6210_priv *wil)
136 return -EAGAIN; 147 return -EAGAIN;
137 } 148 }
138 149
139 /* make shadow copy of registers that should not change on run time */ 150 wil_cache_mbox_regs(wil);
140 wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
141 sizeof(struct wil6210_mbox_ctl));
142 wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
143 wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
144 151
145 return 0; 152 return 0;
146} 153}
@@ -162,7 +169,7 @@ void wil_priv_deinit(struct wil6210_priv *wil)
162 169
163static void wil_target_reset(struct wil6210_priv *wil) 170static void wil_target_reset(struct wil6210_priv *wil)
164{ 171{
165 wil_dbg(wil, "Resetting...\n"); 172 wil_dbg_misc(wil, "Resetting...\n");
166 173
167 /* register write */ 174 /* register write */
168#define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a)) 175#define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a))
@@ -202,7 +209,7 @@ static void wil_target_reset(struct wil6210_priv *wil)
202 209
203 msleep(2000); 210 msleep(2000);
204 211
205 wil_dbg(wil, "Reset completed\n"); 212 wil_dbg_misc(wil, "Reset completed\n");
206 213
207#undef W 214#undef W
208#undef S 215#undef S
@@ -225,8 +232,8 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
225 wil_err(wil, "Firmware not ready\n"); 232 wil_err(wil, "Firmware not ready\n");
226 return -ETIME; 233 return -ETIME;
227 } else { 234 } else {
228 wil_dbg(wil, "FW ready after %d ms\n", 235 wil_dbg_misc(wil, "FW ready after %d ms\n",
229 jiffies_to_msecs(to-left)); 236 jiffies_to_msecs(to-left));
230 } 237 }
231 return 0; 238 return 0;
232} 239}
@@ -243,13 +250,13 @@ int wil_reset(struct wil6210_priv *wil)
243 cancel_work_sync(&wil->disconnect_worker); 250 cancel_work_sync(&wil->disconnect_worker);
244 wil6210_disconnect(wil, NULL); 251 wil6210_disconnect(wil, NULL);
245 252
253 wil6210_disable_irq(wil);
254 wil->status = 0;
255
246 wmi_event_flush(wil); 256 wmi_event_flush(wil);
247 257
248 flush_workqueue(wil->wmi_wq);
249 flush_workqueue(wil->wmi_wq_conn); 258 flush_workqueue(wil->wmi_wq_conn);
250 259 flush_workqueue(wil->wmi_wq);
251 wil6210_disable_irq(wil);
252 wil->status = 0;
253 260
254 /* TODO: put MAC in reset */ 261 /* TODO: put MAC in reset */
255 wil_target_reset(wil); 262 wil_target_reset(wil);
@@ -258,11 +265,7 @@ int wil_reset(struct wil6210_priv *wil)
258 wil->pending_connect_cid = -1; 265 wil->pending_connect_cid = -1;
259 INIT_COMPLETION(wil->wmi_ready); 266 INIT_COMPLETION(wil->wmi_ready);
260 267
261 /* make shadow copy of registers that should not change on run time */ 268 wil_cache_mbox_regs(wil);
262 wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
263 sizeof(struct wil6210_mbox_ctl));
264 wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
265 wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
266 269
267 /* TODO: release MAC reset */ 270 /* TODO: release MAC reset */
268 wil6210_enable_irq(wil); 271 wil6210_enable_irq(wil);
@@ -278,7 +281,7 @@ void wil_link_on(struct wil6210_priv *wil)
278{ 281{
279 struct net_device *ndev = wil_to_ndev(wil); 282 struct net_device *ndev = wil_to_ndev(wil);
280 283
281 wil_dbg(wil, "%s()\n", __func__); 284 wil_dbg_misc(wil, "%s()\n", __func__);
282 285
283 netif_carrier_on(ndev); 286 netif_carrier_on(ndev);
284 netif_tx_wake_all_queues(ndev); 287 netif_tx_wake_all_queues(ndev);
@@ -288,7 +291,7 @@ void wil_link_off(struct wil6210_priv *wil)
288{ 291{
289 struct net_device *ndev = wil_to_ndev(wil); 292 struct net_device *ndev = wil_to_ndev(wil);
290 293
291 wil_dbg(wil, "%s()\n", __func__); 294 wil_dbg_misc(wil, "%s()\n", __func__);
292 295
293 netif_tx_stop_all_queues(ndev); 296 netif_tx_stop_all_queues(ndev);
294 netif_carrier_off(ndev); 297 netif_carrier_off(ndev);
@@ -311,27 +314,27 @@ static int __wil_up(struct wil6210_priv *wil)
311 wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC); 314 wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
312 switch (wdev->iftype) { 315 switch (wdev->iftype) {
313 case NL80211_IFTYPE_STATION: 316 case NL80211_IFTYPE_STATION:
314 wil_dbg(wil, "type: STATION\n"); 317 wil_dbg_misc(wil, "type: STATION\n");
315 bi = 0; 318 bi = 0;
316 ndev->type = ARPHRD_ETHER; 319 ndev->type = ARPHRD_ETHER;
317 break; 320 break;
318 case NL80211_IFTYPE_AP: 321 case NL80211_IFTYPE_AP:
319 wil_dbg(wil, "type: AP\n"); 322 wil_dbg_misc(wil, "type: AP\n");
320 bi = 100; 323 bi = 100;
321 ndev->type = ARPHRD_ETHER; 324 ndev->type = ARPHRD_ETHER;
322 break; 325 break;
323 case NL80211_IFTYPE_P2P_CLIENT: 326 case NL80211_IFTYPE_P2P_CLIENT:
324 wil_dbg(wil, "type: P2P_CLIENT\n"); 327 wil_dbg_misc(wil, "type: P2P_CLIENT\n");
325 bi = 0; 328 bi = 0;
326 ndev->type = ARPHRD_ETHER; 329 ndev->type = ARPHRD_ETHER;
327 break; 330 break;
328 case NL80211_IFTYPE_P2P_GO: 331 case NL80211_IFTYPE_P2P_GO:
329 wil_dbg(wil, "type: P2P_GO\n"); 332 wil_dbg_misc(wil, "type: P2P_GO\n");
330 bi = 100; 333 bi = 100;
331 ndev->type = ARPHRD_ETHER; 334 ndev->type = ARPHRD_ETHER;
332 break; 335 break;
333 case NL80211_IFTYPE_MONITOR: 336 case NL80211_IFTYPE_MONITOR:
334 wil_dbg(wil, "type: Monitor\n"); 337 wil_dbg_misc(wil, "type: Monitor\n");
335 bi = 0; 338 bi = 0;
336 ndev->type = ARPHRD_IEEE80211_RADIOTAP; 339 ndev->type = ARPHRD_IEEE80211_RADIOTAP;
337 /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */ 340 /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */
@@ -354,7 +357,7 @@ static int __wil_up(struct wil6210_priv *wil)
354 wmi_set_channel(wil, channel->hw_value); 357 wmi_set_channel(wil, channel->hw_value);
355 break; 358 break;
356 default: 359 default:
357 ; 360 break;
358 } 361 }
359 362
360 /* MAC address - pre-requisite for other commands */ 363 /* MAC address - pre-requisite for other commands */
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 3068b5cb53a7..8ce2e33dce20 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -35,37 +35,12 @@ static int wil_stop(struct net_device *ndev)
35 return wil_down(wil); 35 return wil_down(wil);
36} 36}
37 37
38/*
39 * AC to queue mapping
40 *
41 * AC_VO -> queue 3
42 * AC_VI -> queue 2
43 * AC_BE -> queue 1
44 * AC_BK -> queue 0
45 */
46static u16 wil_select_queue(struct net_device *ndev, struct sk_buff *skb)
47{
48 static const u16 wil_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
49 struct wil6210_priv *wil = ndev_to_wil(ndev);
50 u16 rc;
51
52 skb->priority = cfg80211_classify8021d(skb);
53
54 rc = wil_1d_to_queue[skb->priority];
55
56 wil_dbg_TXRX(wil, "%s() %d -> %d\n", __func__, (int)skb->priority,
57 (int)rc);
58
59 return rc;
60}
61
62static const struct net_device_ops wil_netdev_ops = { 38static const struct net_device_ops wil_netdev_ops = {
63 .ndo_open = wil_open, 39 .ndo_open = wil_open,
64 .ndo_stop = wil_stop, 40 .ndo_stop = wil_stop,
65 .ndo_start_xmit = wil_start_xmit, 41 .ndo_start_xmit = wil_start_xmit,
66 .ndo_select_queue = wil_select_queue, 42 .ndo_set_mac_address = eth_mac_addr,
67 .ndo_set_mac_address = eth_mac_addr, 43 .ndo_validate_addr = eth_validate_addr,
68 .ndo_validate_addr = eth_validate_addr,
69}; 44};
70 45
71void *wil_if_alloc(struct device *dev, void __iomem *csr) 46void *wil_if_alloc(struct device *dev, void __iomem *csr)
@@ -97,7 +72,7 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
97 ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels; 72 ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels;
98 cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT); 73 cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT);
99 74
100 ndev = alloc_netdev_mqs(0, "wlan%d", ether_setup, WIL6210_TX_QUEUES, 1); 75 ndev = alloc_netdev(0, "wlan%d", ether_setup);
101 if (!ndev) { 76 if (!ndev) {
102 dev_err(dev, "alloc_netdev_mqs failed\n"); 77 dev_err(dev, "alloc_netdev_mqs failed\n");
103 rc = -ENOMEM; 78 rc = -ENOMEM;
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 0fc83edd6bad..81c35c6e3832 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -53,7 +53,7 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
53 } 53 }
54 wil->n_msi = use_msi; 54 wil->n_msi = use_msi;
55 if (wil->n_msi) { 55 if (wil->n_msi) {
56 wil_dbg(wil, "Setup %d MSI interrupts\n", use_msi); 56 wil_dbg_misc(wil, "Setup %d MSI interrupts\n", use_msi);
57 rc = pci_enable_msi_block(pdev, wil->n_msi); 57 rc = pci_enable_msi_block(pdev, wil->n_msi);
58 if (rc && (wil->n_msi == 3)) { 58 if (rc && (wil->n_msi == 3)) {
59 wil_err(wil, "3 MSI mode failed, try 1 MSI\n"); 59 wil_err(wil, "3 MSI mode failed, try 1 MSI\n");
@@ -65,7 +65,7 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
65 wil->n_msi = 0; 65 wil->n_msi = 0;
66 } 66 }
67 } else { 67 } else {
68 wil_dbg(wil, "MSI interrupts disabled, use INTx\n"); 68 wil_dbg_misc(wil, "MSI interrupts disabled, use INTx\n");
69 } 69 }
70 70
71 rc = wil6210_init_irq(wil, pdev->irq); 71 rc = wil6210_init_irq(wil, pdev->irq);
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index f29c294413cf..64b971fdc3cc 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -100,8 +100,8 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
100 d->dma.status = TX_DMA_STATUS_DU; 100 d->dma.status = TX_DMA_STATUS_DU;
101 } 101 }
102 102
103 wil_dbg(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size, 103 wil_dbg_misc(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,
104 vring->va, (unsigned long long)vring->pa, vring->ctx); 104 vring->va, (unsigned long long)vring->pa, vring->ctx);
105 105
106 return 0; 106 return 0;
107} 107}
@@ -353,8 +353,8 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
353 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) 353 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
354 wil_rx_add_radiotap_header(wil, skb, d); 354 wil_rx_add_radiotap_header(wil, skb, d);
355 355
356 wil_dbg_TXRX(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length); 356 wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
357 wil_hex_dump_TXRX("Rx ", DUMP_PREFIX_NONE, 32, 4, 357 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
358 (const void *)d, sizeof(*d), false); 358 (const void *)d, sizeof(*d), false);
359 359
360 wil_vring_advance_head(vring, 1); 360 wil_vring_advance_head(vring, 1);
@@ -369,7 +369,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
369 */ 369 */
370 ftype = wil_rxdesc_ftype(d) << 2; 370 ftype = wil_rxdesc_ftype(d) << 2;
371 if (ftype != IEEE80211_FTYPE_DATA) { 371 if (ftype != IEEE80211_FTYPE_DATA) {
372 wil_dbg_TXRX(wil, "Non-data frame ftype 0x%08x\n", ftype); 372 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
373 /* TODO: process it */ 373 /* TODO: process it */
374 kfree_skb(skb); 374 kfree_skb(skb);
375 return NULL; 375 return NULL;
@@ -430,6 +430,8 @@ static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
430 int rc; 430 int rc;
431 unsigned int len = skb->len; 431 unsigned int len = skb->len;
432 432
433 skb_orphan(skb);
434
433 if (in_interrupt()) 435 if (in_interrupt())
434 rc = netif_rx(skb); 436 rc = netif_rx(skb);
435 else 437 else
@@ -459,13 +461,11 @@ void wil_rx_handle(struct wil6210_priv *wil)
459 wil_err(wil, "Rx IRQ while Rx not yet initialized\n"); 461 wil_err(wil, "Rx IRQ while Rx not yet initialized\n");
460 return; 462 return;
461 } 463 }
462 wil_dbg_TXRX(wil, "%s()\n", __func__); 464 wil_dbg_txrx(wil, "%s()\n", __func__);
463 while (NULL != (skb = wil_vring_reap_rx(wil, v))) { 465 while (NULL != (skb = wil_vring_reap_rx(wil, v))) {
464 wil_hex_dump_TXRX("Rx ", DUMP_PREFIX_OFFSET, 16, 1, 466 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
465 skb->data, skb_headlen(skb), false); 467 skb->data, skb_headlen(skb), false);
466 468
467 skb_orphan(skb);
468
469 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { 469 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
470 skb->dev = ndev; 470 skb->dev = ndev;
471 skb_reset_mac_header(skb); 471 skb_reset_mac_header(skb);
@@ -484,53 +484,18 @@ void wil_rx_handle(struct wil6210_priv *wil)
484 484
485int wil_rx_init(struct wil6210_priv *wil) 485int wil_rx_init(struct wil6210_priv *wil)
486{ 486{
487 struct net_device *ndev = wil_to_ndev(wil);
488 struct wireless_dev *wdev = wil->wdev;
489 struct vring *vring = &wil->vring_rx; 487 struct vring *vring = &wil->vring_rx;
490 int rc; 488 int rc;
491 struct wmi_cfg_rx_chain_cmd cmd = {
492 .action = WMI_RX_CHAIN_ADD,
493 .rx_sw_ring = {
494 .max_mpdu_size = cpu_to_le16(RX_BUF_LEN),
495 },
496 .mid = 0, /* TODO - what is it? */
497 .decap_trans_type = WMI_DECAP_TYPE_802_3,
498 };
499 struct {
500 struct wil6210_mbox_hdr_wmi wmi;
501 struct wmi_cfg_rx_chain_done_event evt;
502 } __packed evt;
503 489
504 vring->size = WIL6210_RX_RING_SIZE; 490 vring->size = WIL6210_RX_RING_SIZE;
505 rc = wil_vring_alloc(wil, vring); 491 rc = wil_vring_alloc(wil, vring);
506 if (rc) 492 if (rc)
507 return rc; 493 return rc;
508 494
509 cmd.rx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); 495 rc = wmi_rx_chain_add(wil, vring);
510 cmd.rx_sw_ring.ring_size = cpu_to_le16(vring->size);
511 if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
512 struct ieee80211_channel *ch = wdev->preset_chandef.chan;
513
514 cmd.sniffer_cfg.mode = cpu_to_le32(WMI_SNIFFER_ON);
515 if (ch)
516 cmd.sniffer_cfg.channel = ch->hw_value - 1;
517 cmd.sniffer_cfg.phy_info_mode =
518 cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP);
519 cmd.sniffer_cfg.phy_support =
520 cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL)
521 ? WMI_SNIFFER_CP : WMI_SNIFFER_DP);
522 }
523 /* typical time for secure PCP is 840ms */
524 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
525 WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000);
526 if (rc) 496 if (rc)
527 goto err_free; 497 goto err_free;
528 498
529 vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr);
530
531 wil_dbg(wil, "Rx init: status %d tail 0x%08x\n",
532 le32_to_cpu(evt.evt.status), vring->hwtail);
533
534 rc = wil_rx_refill(wil, vring->size); 499 rc = wil_rx_refill(wil, vring->size);
535 if (rc) 500 if (rc)
536 goto err_free; 501 goto err_free;
@@ -546,25 +511,8 @@ void wil_rx_fini(struct wil6210_priv *wil)
546{ 511{
547 struct vring *vring = &wil->vring_rx; 512 struct vring *vring = &wil->vring_rx;
548 513
549 if (vring->va) { 514 if (vring->va)
550 int rc;
551 struct wmi_cfg_rx_chain_cmd cmd = {
552 .action = cpu_to_le32(WMI_RX_CHAIN_DEL),
553 .rx_sw_ring = {
554 .max_mpdu_size = cpu_to_le16(RX_BUF_LEN),
555 },
556 };
557 struct {
558 struct wil6210_mbox_hdr_wmi wmi;
559 struct wmi_cfg_rx_chain_done_event cfg;
560 } __packed wmi_rx_cfg_reply;
561
562 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
563 WMI_CFG_RX_CHAIN_DONE_EVENTID,
564 &wmi_rx_cfg_reply, sizeof(wmi_rx_cfg_reply),
565 100);
566 wil_vring_free(wil, vring, 0); 515 wil_vring_free(wil, vring, 0);
567 }
568} 516}
569 517
570int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, 518int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
@@ -617,6 +565,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
617 if (reply.cmd.status != WMI_VRING_CFG_SUCCESS) { 565 if (reply.cmd.status != WMI_VRING_CFG_SUCCESS) {
618 wil_err(wil, "Tx config failed, status 0x%02x\n", 566 wil_err(wil, "Tx config failed, status 0x%02x\n",
619 reply.cmd.status); 567 reply.cmd.status);
568 rc = -EINVAL;
620 goto out_free; 569 goto out_free;
621 } 570 }
622 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); 571 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
@@ -689,7 +638,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
689 uint i = swhead; 638 uint i = swhead;
690 dma_addr_t pa; 639 dma_addr_t pa;
691 640
692 wil_dbg_TXRX(wil, "%s()\n", __func__); 641 wil_dbg_txrx(wil, "%s()\n", __func__);
693 642
694 if (avail < vring->size/8) 643 if (avail < vring->size/8)
695 netif_tx_stop_all_queues(wil_to_ndev(wil)); 644 netif_tx_stop_all_queues(wil_to_ndev(wil));
@@ -706,9 +655,9 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
706 pa = dma_map_single(dev, skb->data, 655 pa = dma_map_single(dev, skb->data,
707 skb_headlen(skb), DMA_TO_DEVICE); 656 skb_headlen(skb), DMA_TO_DEVICE);
708 657
709 wil_dbg_TXRX(wil, "Tx skb %d bytes %p -> %#08llx\n", skb_headlen(skb), 658 wil_dbg_txrx(wil, "Tx skb %d bytes %p -> %#08llx\n", skb_headlen(skb),
710 skb->data, (unsigned long long)pa); 659 skb->data, (unsigned long long)pa);
711 wil_hex_dump_TXRX("Tx ", DUMP_PREFIX_OFFSET, 16, 1, 660 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_OFFSET, 16, 1,
712 skb->data, skb_headlen(skb), false); 661 skb->data, skb_headlen(skb), false);
713 662
714 if (unlikely(dma_mapping_error(dev, pa))) 663 if (unlikely(dma_mapping_error(dev, pa)))
@@ -737,12 +686,12 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
737 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); 686 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
738 d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS); 687 d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS);
739 688
740 wil_hex_dump_TXRX("Tx ", DUMP_PREFIX_NONE, 32, 4, 689 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
741 (const void *)d, sizeof(*d), false); 690 (const void *)d, sizeof(*d), false);
742 691
743 /* advance swhead */ 692 /* advance swhead */
744 wil_vring_advance_head(vring, nr_frags + 1); 693 wil_vring_advance_head(vring, nr_frags + 1);
745 wil_dbg_TXRX(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead); 694 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
746 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail)); 695 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
747 /* hold reference to skb 696 /* hold reference to skb
748 * to prevent skb release before accounting 697 * to prevent skb release before accounting
@@ -775,7 +724,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
775 struct vring *vring; 724 struct vring *vring;
776 int rc; 725 int rc;
777 726
778 wil_dbg_TXRX(wil, "%s()\n", __func__); 727 wil_dbg_txrx(wil, "%s()\n", __func__);
779 if (!test_bit(wil_status_fwready, &wil->status)) { 728 if (!test_bit(wil_status_fwready, &wil->status)) {
780 wil_err(wil, "FW not ready\n"); 729 wil_err(wil, "FW not ready\n");
781 goto drop; 730 goto drop;
@@ -802,15 +751,13 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
802 } 751 }
803 switch (rc) { 752 switch (rc) {
804 case 0: 753 case 0:
805 ndev->stats.tx_packets++; 754 /* statistics will be updated on the tx_complete */
806 ndev->stats.tx_bytes += skb->len;
807 dev_kfree_skb_any(skb); 755 dev_kfree_skb_any(skb);
808 return NETDEV_TX_OK; 756 return NETDEV_TX_OK;
809 case -ENOMEM: 757 case -ENOMEM:
810 return NETDEV_TX_BUSY; 758 return NETDEV_TX_BUSY;
811 default: 759 default:
812 ; /* goto drop; */ 760 break; /* goto drop; */
813 break;
814 } 761 }
815 drop: 762 drop:
816 netif_tx_stop_all_queues(ndev); 763 netif_tx_stop_all_queues(ndev);
@@ -827,6 +774,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
827 */ 774 */
828void wil_tx_complete(struct wil6210_priv *wil, int ringid) 775void wil_tx_complete(struct wil6210_priv *wil, int ringid)
829{ 776{
777 struct net_device *ndev = wil_to_ndev(wil);
830 struct device *dev = wil_to_dev(wil); 778 struct device *dev = wil_to_dev(wil);
831 struct vring *vring = &wil->vring_tx[ringid]; 779 struct vring *vring = &wil->vring_tx[ringid];
832 780
@@ -835,7 +783,7 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid)
835 return; 783 return;
836 } 784 }
837 785
838 wil_dbg_TXRX(wil, "%s(%d)\n", __func__, ringid); 786 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
839 787
840 while (!wil_vring_is_empty(vring)) { 788 while (!wil_vring_is_empty(vring)) {
841 volatile struct vring_tx_desc *d = &vring->va[vring->swtail].tx; 789 volatile struct vring_tx_desc *d = &vring->va[vring->swtail].tx;
@@ -844,16 +792,23 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid)
844 if (!(d->dma.status & TX_DMA_STATUS_DU)) 792 if (!(d->dma.status & TX_DMA_STATUS_DU))
845 break; 793 break;
846 794
847 wil_dbg_TXRX(wil, 795 wil_dbg_txrx(wil,
848 "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n", 796 "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n",
849 vring->swtail, d->dma.length, d->dma.status, 797 vring->swtail, d->dma.length, d->dma.status,
850 d->dma.error); 798 d->dma.error);
851 wil_hex_dump_TXRX("TxC ", DUMP_PREFIX_NONE, 32, 4, 799 wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4,
852 (const void *)d, sizeof(*d), false); 800 (const void *)d, sizeof(*d), false);
853 801
854 pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32); 802 pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
855 skb = vring->ctx[vring->swtail]; 803 skb = vring->ctx[vring->swtail];
856 if (skb) { 804 if (skb) {
805 if (d->dma.error == 0) {
806 ndev->stats.tx_packets++;
807 ndev->stats.tx_bytes += skb->len;
808 } else {
809 ndev->stats.tx_errors++;
810 }
811
857 dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE); 812 dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE);
858 dev_kfree_skb_any(skb); 813 dev_kfree_skb_any(skb);
859 vring->ctx[vring->swtail] = NULL; 814 vring->ctx[vring->swtail] = NULL;
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 9bcfffa4006c..aea961ff8f08 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -36,8 +36,6 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
36 36
37#define WIL6210_MEM_SIZE (2*1024*1024UL) 37#define WIL6210_MEM_SIZE (2*1024*1024UL)
38 38
39#define WIL6210_TX_QUEUES (4)
40
41#define WIL6210_RX_RING_SIZE (128) 39#define WIL6210_RX_RING_SIZE (128)
42#define WIL6210_TX_RING_SIZE (128) 40#define WIL6210_TX_RING_SIZE (128)
43#define WIL6210_MAX_TX_RINGS (24) 41#define WIL6210_MAX_TX_RINGS (24)
@@ -101,8 +99,7 @@ struct RGF_ICR {
101#define RGF_DMA_EP_MISC_ICR (0x881bec) /* struct RGF_ICR */ 99#define RGF_DMA_EP_MISC_ICR (0x881bec) /* struct RGF_ICR */
102 #define BIT_DMA_EP_MISC_ICR_RX_HTRSH BIT(0) 100 #define BIT_DMA_EP_MISC_ICR_RX_HTRSH BIT(0)
103 #define BIT_DMA_EP_MISC_ICR_TX_NO_ACT BIT(1) 101 #define BIT_DMA_EP_MISC_ICR_TX_NO_ACT BIT(1)
104 #define BIT_DMA_EP_MISC_ICR_FW_INT0 BIT(28) 102 #define BIT_DMA_EP_MISC_ICR_FW_INT(n) BIT(28+n) /* n = [0..3] */
105 #define BIT_DMA_EP_MISC_ICR_FW_INT1 BIT(29)
106 103
107/* Interrupt moderation control */ 104/* Interrupt moderation control */
108#define RGF_DMA_ITR_CNT_TRSH (0x881c5c) 105#define RGF_DMA_ITR_CNT_TRSH (0x881c5c)
@@ -121,8 +118,9 @@ struct RGF_ICR {
121#define SW_INT_MBOX BIT_USER_USER_ICR_SW_INT_2 118#define SW_INT_MBOX BIT_USER_USER_ICR_SW_INT_2
122 119
123/* ISR register bits */ 120/* ISR register bits */
124#define ISR_MISC_FW_READY BIT_DMA_EP_MISC_ICR_FW_INT0 121#define ISR_MISC_FW_READY BIT_DMA_EP_MISC_ICR_FW_INT(0)
125#define ISR_MISC_MBOX_EVT BIT_DMA_EP_MISC_ICR_FW_INT1 122#define ISR_MISC_MBOX_EVT BIT_DMA_EP_MISC_ICR_FW_INT(1)
123#define ISR_MISC_FW_ERROR BIT_DMA_EP_MISC_ICR_FW_INT(3)
126 124
127/* Hardware definitions end */ 125/* Hardware definitions end */
128 126
@@ -272,17 +270,18 @@ struct wil6210_priv {
272#define wil_info(wil, fmt, arg...) netdev_info(wil_to_ndev(wil), fmt, ##arg) 270#define wil_info(wil, fmt, arg...) netdev_info(wil_to_ndev(wil), fmt, ##arg)
273#define wil_err(wil, fmt, arg...) netdev_err(wil_to_ndev(wil), fmt, ##arg) 271#define wil_err(wil, fmt, arg...) netdev_err(wil_to_ndev(wil), fmt, ##arg)
274 272
275#define wil_dbg_IRQ(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg) 273#define wil_dbg_irq(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg)
276#define wil_dbg_TXRX(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg) 274#define wil_dbg_txrx(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg)
277#define wil_dbg_WMI(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg) 275#define wil_dbg_wmi(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg)
276#define wil_dbg_misc(wil, fmt, arg...) wil_dbg(wil, "DBG[MISC]" fmt, ##arg)
278 277
279#define wil_hex_dump_TXRX(prefix_str, prefix_type, rowsize, \ 278#define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \
280 groupsize, buf, len, ascii) \ 279 groupsize, buf, len, ascii) \
281 wil_print_hex_dump_debug("DBG[TXRX]" prefix_str,\ 280 wil_print_hex_dump_debug("DBG[TXRX]" prefix_str,\
282 prefix_type, rowsize, \ 281 prefix_type, rowsize, \
283 groupsize, buf, len, ascii) 282 groupsize, buf, len, ascii)
284 283
285#define wil_hex_dump_WMI(prefix_str, prefix_type, rowsize, \ 284#define wil_hex_dump_wmi(prefix_str, prefix_type, rowsize, \
286 groupsize, buf, len, ascii) \ 285 groupsize, buf, len, ascii) \
287 wil_print_hex_dump_debug("DBG[ WMI]" prefix_str,\ 286 wil_print_hex_dump_debug("DBG[ WMI]" prefix_str,\
288 prefix_type, rowsize, \ 287 prefix_type, rowsize, \
@@ -328,6 +327,7 @@ int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
328 const void *mac_addr, int key_len, const void *key); 327 const void *mac_addr, int key_len, const void *key);
329int wmi_echo(struct wil6210_priv *wil); 328int wmi_echo(struct wil6210_priv *wil);
330int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie); 329int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
330int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
331 331
332int wil6210_init_irq(struct wil6210_priv *wil, int irq); 332int wil6210_init_irq(struct wil6210_priv *wil, int irq);
333void wil6210_fini_irq(struct wil6210_priv *wil, int irq); 333void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 12915f6e7617..0b70e17cd1fb 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -18,8 +18,10 @@
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
21#include <linux/if_arp.h>
21 22
22#include "wil6210.h" 23#include "wil6210.h"
24#include "txrx.h"
23#include "wmi.h" 25#include "wmi.h"
24 26
25/** 27/**
@@ -186,7 +188,6 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
186 wil_err(wil, "WMI size too large: %d bytes, max is %d\n", 188 wil_err(wil, "WMI size too large: %d bytes, max is %d\n",
187 (int)(sizeof(cmd) + len), r->entry_size); 189 (int)(sizeof(cmd) + len), r->entry_size);
188 return -ERANGE; 190 return -ERANGE;
189
190 } 191 }
191 192
192 might_sleep(); 193 might_sleep();
@@ -213,7 +214,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
213 } 214 }
214 /* next head */ 215 /* next head */
215 next_head = r->base + ((r->head - r->base + sizeof(d_head)) % r->size); 216 next_head = r->base + ((r->head - r->base + sizeof(d_head)) % r->size);
216 wil_dbg_WMI(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head); 217 wil_dbg_wmi(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head);
217 /* wait till FW finish with previous command */ 218 /* wait till FW finish with previous command */
218 for (retry = 5; retry > 0; retry--) { 219 for (retry = 5; retry > 0; retry--) {
219 r->tail = ioread32(wil->csr + HOST_MBOX + 220 r->tail = ioread32(wil->csr + HOST_MBOX +
@@ -234,10 +235,10 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
234 } 235 }
235 cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq); 236 cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq);
236 /* set command */ 237 /* set command */
237 wil_dbg_WMI(wil, "WMI command 0x%04x [%d]\n", cmdid, len); 238 wil_dbg_wmi(wil, "WMI command 0x%04x [%d]\n", cmdid, len);
238 wil_hex_dump_WMI("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd, 239 wil_hex_dump_wmi("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd,
239 sizeof(cmd), true); 240 sizeof(cmd), true);
240 wil_hex_dump_WMI("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf, 241 wil_hex_dump_wmi("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf,
241 len, true); 242 len, true);
242 wil_memcpy_toio_32(dst, &cmd, sizeof(cmd)); 243 wil_memcpy_toio_32(dst, &cmd, sizeof(cmd));
243 wil_memcpy_toio_32(dst + sizeof(cmd), buf, len); 244 wil_memcpy_toio_32(dst + sizeof(cmd), buf, len);
@@ -273,7 +274,7 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
273 struct wmi_ready_event *evt = d; 274 struct wmi_ready_event *evt = d;
274 u32 ver = le32_to_cpu(evt->sw_version); 275 u32 ver = le32_to_cpu(evt->sw_version);
275 276
276 wil_dbg_WMI(wil, "FW ver. %d; MAC %pM\n", ver, evt->mac); 277 wil_dbg_wmi(wil, "FW ver. %d; MAC %pM\n", ver, evt->mac);
277 278
278 if (!is_valid_ether_addr(ndev->dev_addr)) { 279 if (!is_valid_ether_addr(ndev->dev_addr)) {
279 memcpy(ndev->dev_addr, evt->mac, ETH_ALEN); 280 memcpy(ndev->dev_addr, evt->mac, ETH_ALEN);
@@ -286,7 +287,7 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
286static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d, 287static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d,
287 int len) 288 int len)
288{ 289{
289 wil_dbg_WMI(wil, "WMI: FW ready\n"); 290 wil_dbg_wmi(wil, "WMI: FW ready\n");
290 291
291 set_bit(wil_status_fwready, &wil->status); 292 set_bit(wil_status_fwready, &wil->status);
292 /* reuse wmi_ready for the firmware ready indication */ 293 /* reuse wmi_ready for the firmware ready indication */
@@ -309,11 +310,11 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
309 u32 d_len = le32_to_cpu(data->info.len); 310 u32 d_len = le32_to_cpu(data->info.len);
310 u16 d_status = le16_to_cpu(data->info.status); 311 u16 d_status = le16_to_cpu(data->info.status);
311 312
312 wil_dbg_WMI(wil, "MGMT: channel %d MCS %d SNR %d\n", 313 wil_dbg_wmi(wil, "MGMT: channel %d MCS %d SNR %d\n",
313 data->info.channel, data->info.mcs, data->info.snr); 314 data->info.channel, data->info.mcs, data->info.snr);
314 wil_dbg_WMI(wil, "status 0x%04x len %d stype %04x\n", d_status, d_len, 315 wil_dbg_wmi(wil, "status 0x%04x len %d stype %04x\n", d_status, d_len,
315 le16_to_cpu(data->info.stype)); 316 le16_to_cpu(data->info.stype));
316 wil_dbg_WMI(wil, "qid %d mid %d cid %d\n", 317 wil_dbg_wmi(wil, "qid %d mid %d cid %d\n",
317 data->info.qid, data->info.mid, data->info.cid); 318 data->info.qid, data->info.mid, data->info.cid);
318 319
319 if (!channel) { 320 if (!channel) {
@@ -329,13 +330,13 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
329 const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable; 330 const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable;
330 size_t ie_len = d_len - offsetof(struct ieee80211_mgmt, 331 size_t ie_len = d_len - offsetof(struct ieee80211_mgmt,
331 u.beacon.variable); 332 u.beacon.variable);
332 wil_dbg_WMI(wil, "Capability info : 0x%04x\n", cap); 333 wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap);
333 334
334 bss = cfg80211_inform_bss(wiphy, channel, rx_mgmt_frame->bssid, 335 bss = cfg80211_inform_bss(wiphy, channel, rx_mgmt_frame->bssid,
335 tsf, cap, bi, ie_buf, ie_len, 336 tsf, cap, bi, ie_buf, ie_len,
336 signal, GFP_KERNEL); 337 signal, GFP_KERNEL);
337 if (bss) { 338 if (bss) {
338 wil_dbg_WMI(wil, "Added BSS %pM\n", 339 wil_dbg_wmi(wil, "Added BSS %pM\n",
339 rx_mgmt_frame->bssid); 340 rx_mgmt_frame->bssid);
340 cfg80211_put_bss(bss); 341 cfg80211_put_bss(bss);
341 } else { 342 } else {
@@ -351,7 +352,7 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
351 struct wmi_scan_complete_event *data = d; 352 struct wmi_scan_complete_event *data = d;
352 bool aborted = (data->status != 0); 353 bool aborted = (data->status != 0);
353 354
354 wil_dbg_WMI(wil, "SCAN_COMPLETE(0x%08x)\n", data->status); 355 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
355 cfg80211_scan_done(wil->scan_request, aborted); 356 cfg80211_scan_done(wil->scan_request, aborted);
356 wil->scan_request = NULL; 357 wil->scan_request = NULL;
357 } else { 358 } else {
@@ -386,9 +387,9 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
386 return; 387 return;
387 } 388 }
388 ch = evt->channel + 1; 389 ch = evt->channel + 1;
389 wil_dbg_WMI(wil, "Connect %pM channel [%d] cid %d\n", 390 wil_dbg_wmi(wil, "Connect %pM channel [%d] cid %d\n",
390 evt->bssid, ch, evt->cid); 391 evt->bssid, ch, evt->cid);
391 wil_hex_dump_WMI("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1, 392 wil_hex_dump_wmi("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1,
392 evt->assoc_info, len - sizeof(*evt), true); 393 evt->assoc_info, len - sizeof(*evt), true);
393 394
394 /* figure out IE's */ 395 /* figure out IE's */
@@ -450,14 +451,13 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
450{ 451{
451 struct wmi_disconnect_event *evt = d; 452 struct wmi_disconnect_event *evt = d;
452 453
453 wil_dbg_WMI(wil, "Disconnect %pM reason %d proto %d wmi\n", 454 wil_dbg_wmi(wil, "Disconnect %pM reason %d proto %d wmi\n",
454 evt->bssid, 455 evt->bssid,
455 evt->protocol_reason_status, evt->disconnect_reason); 456 evt->protocol_reason_status, evt->disconnect_reason);
456 457
457 wil->sinfo_gen++; 458 wil->sinfo_gen++;
458 459
459 wil6210_disconnect(wil, evt->bssid); 460 wil6210_disconnect(wil, evt->bssid);
460 clear_bit(wil_status_dontscan, &wil->status);
461} 461}
462 462
463static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len) 463static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len)
@@ -476,7 +476,7 @@ static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len)
476 wil->stats.my_tx_sector = le16_to_cpu(evt->my_tx_sector); 476 wil->stats.my_tx_sector = le16_to_cpu(evt->my_tx_sector);
477 wil->stats.peer_rx_sector = le16_to_cpu(evt->other_rx_sector); 477 wil->stats.peer_rx_sector = le16_to_cpu(evt->other_rx_sector);
478 wil->stats.peer_tx_sector = le16_to_cpu(evt->other_tx_sector); 478 wil->stats.peer_tx_sector = le16_to_cpu(evt->other_tx_sector);
479 wil_dbg_WMI(wil, "Link status, MCS %d TSF 0x%016llx\n" 479 wil_dbg_wmi(wil, "Link status, MCS %d TSF 0x%016llx\n"
480 "BF status 0x%08x SNR 0x%08x\n" 480 "BF status 0x%08x SNR 0x%08x\n"
481 "Tx Tpt %d goodput %d Rx goodput %d\n" 481 "Tx Tpt %d goodput %d Rx goodput %d\n"
482 "Sectors(rx:tx) my %d:%d peer %d:%d\n", 482 "Sectors(rx:tx) my %d:%d peer %d:%d\n",
@@ -501,7 +501,7 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
501 struct sk_buff *skb; 501 struct sk_buff *skb;
502 struct ethhdr *eth; 502 struct ethhdr *eth;
503 503
504 wil_dbg_WMI(wil, "EAPOL len %d from %pM\n", eapol_len, 504 wil_dbg_wmi(wil, "EAPOL len %d from %pM\n", eapol_len,
505 evt->src_mac); 505 evt->src_mac);
506 506
507 if (eapol_len > 196) { /* TODO: revisit size limit */ 507 if (eapol_len > 196) { /* TODO: revisit size limit */
@@ -599,15 +599,15 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
599 iowrite32(0, wil->csr + HOSTADDR(r->tail) + 599 iowrite32(0, wil->csr + HOSTADDR(r->tail) +
600 offsetof(struct wil6210_mbox_ring_desc, sync)); 600 offsetof(struct wil6210_mbox_ring_desc, sync));
601 /* indicate */ 601 /* indicate */
602 wil_dbg_WMI(wil, "Mbox evt %04x %04x %04x %02x\n", 602 wil_dbg_wmi(wil, "Mbox evt %04x %04x %04x %02x\n",
603 le16_to_cpu(hdr.seq), len, le16_to_cpu(hdr.type), 603 le16_to_cpu(hdr.seq), len, le16_to_cpu(hdr.type),
604 hdr.flags); 604 hdr.flags);
605 if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) && 605 if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) &&
606 (len >= sizeof(struct wil6210_mbox_hdr_wmi))) { 606 (len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
607 wil_dbg_WMI(wil, "WMI event 0x%04x\n", 607 wil_dbg_wmi(wil, "WMI event 0x%04x\n",
608 evt->event.wmi.id); 608 evt->event.wmi.id);
609 } 609 }
610 wil_hex_dump_WMI("evt ", DUMP_PREFIX_OFFSET, 16, 1, 610 wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1,
611 &evt->event.hdr, sizeof(hdr) + len, true); 611 &evt->event.hdr, sizeof(hdr) + len, true);
612 612
613 /* advance tail */ 613 /* advance tail */
@@ -623,7 +623,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
623 { 623 {
624 int q = queue_work(wil->wmi_wq, 624 int q = queue_work(wil->wmi_wq,
625 &wil->wmi_event_worker); 625 &wil->wmi_event_worker);
626 wil_dbg_WMI(wil, "queue_work -> %d\n", q); 626 wil_dbg_wmi(wil, "queue_work -> %d\n", q);
627 } 627 }
628 } 628 }
629} 629}
@@ -650,7 +650,7 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
650 cmdid, reply_id, to_msec); 650 cmdid, reply_id, to_msec);
651 rc = -ETIME; 651 rc = -ETIME;
652 } else { 652 } else {
653 wil_dbg_WMI(wil, 653 wil_dbg_wmi(wil,
654 "wmi_call(0x%04x->0x%04x) completed in %d msec\n", 654 "wmi_call(0x%04x->0x%04x) completed in %d msec\n",
655 cmdid, reply_id, 655 cmdid, reply_id,
656 to_msec - jiffies_to_msecs(remain)); 656 to_msec - jiffies_to_msecs(remain));
@@ -680,7 +680,7 @@ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr)
680 680
681 memcpy(cmd.mac, addr, ETH_ALEN); 681 memcpy(cmd.mac, addr, ETH_ALEN);
682 682
683 wil_dbg_WMI(wil, "Set MAC %pM\n", addr); 683 wil_dbg_wmi(wil, "Set MAC %pM\n", addr);
684 684
685 return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd)); 685 return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd));
686} 686}
@@ -778,7 +778,7 @@ int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb)
778 778
779 skb_set_mac_header(skb, 0); 779 skb_set_mac_header(skb, 0);
780 eth = eth_hdr(skb); 780 eth = eth_hdr(skb);
781 wil_dbg_WMI(wil, "EAPOL %d bytes to %pM\n", eapol_len, eth->h_dest); 781 wil_dbg_wmi(wil, "EAPOL %d bytes to %pM\n", eapol_len, eth->h_dest);
782 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { 782 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
783 if (memcmp(wil->dst_addr[i], eth->h_dest, ETH_ALEN) == 0) 783 if (memcmp(wil->dst_addr[i], eth->h_dest, ETH_ALEN) == 0)
784 goto found_dest; 784 goto found_dest;
@@ -853,11 +853,60 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
853 return rc; 853 return rc;
854} 854}
855 855
856int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
857{
858 struct wireless_dev *wdev = wil->wdev;
859 struct net_device *ndev = wil_to_ndev(wil);
860 struct wmi_cfg_rx_chain_cmd cmd = {
861 .action = WMI_RX_CHAIN_ADD,
862 .rx_sw_ring = {
863 .max_mpdu_size = cpu_to_le16(RX_BUF_LEN),
864 .ring_mem_base = cpu_to_le64(vring->pa),
865 .ring_size = cpu_to_le16(vring->size),
866 },
867 .mid = 0, /* TODO - what is it? */
868 .decap_trans_type = WMI_DECAP_TYPE_802_3,
869 };
870 struct {
871 struct wil6210_mbox_hdr_wmi wmi;
872 struct wmi_cfg_rx_chain_done_event evt;
873 } __packed evt;
874 int rc;
875
876 if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
877 struct ieee80211_channel *ch = wdev->preset_chandef.chan;
878
879 cmd.sniffer_cfg.mode = cpu_to_le32(WMI_SNIFFER_ON);
880 if (ch)
881 cmd.sniffer_cfg.channel = ch->hw_value - 1;
882 cmd.sniffer_cfg.phy_info_mode =
883 cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP);
884 cmd.sniffer_cfg.phy_support =
885 cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL)
886 ? WMI_SNIFFER_CP : WMI_SNIFFER_DP);
887 }
888 /* typical time for secure PCP is 840ms */
889 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
890 WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000);
891 if (rc)
892 return rc;
893
894 vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr);
895
896 wil_dbg_misc(wil, "Rx init: status %d tail 0x%08x\n",
897 le32_to_cpu(evt.evt.status), vring->hwtail);
898
899 if (le32_to_cpu(evt.evt.status) != WMI_CFG_RX_CHAIN_SUCCESS)
900 rc = -EINVAL;
901
902 return rc;
903}
904
856void wmi_event_flush(struct wil6210_priv *wil) 905void wmi_event_flush(struct wil6210_priv *wil)
857{ 906{
858 struct pending_wmi_event *evt, *t; 907 struct pending_wmi_event *evt, *t;
859 908
860 wil_dbg_WMI(wil, "%s()\n", __func__); 909 wil_dbg_wmi(wil, "%s()\n", __func__);
861 910
862 list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) { 911 list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) {
863 list_del(&evt->list); 912 list_del(&evt->list);
@@ -899,7 +948,7 @@ static void wmi_event_handle(struct wil6210_priv *wil,
899 wmi_evt_call_handler(wil, id, evt_data, 948 wmi_evt_call_handler(wil, id, evt_data,
900 len - sizeof(*wmi)); 949 len - sizeof(*wmi));
901 } 950 }
902 wil_dbg_WMI(wil, "Complete WMI 0x%04x\n", id); 951 wil_dbg_wmi(wil, "Complete WMI 0x%04x\n", id);
903 complete(&wil->wmi_ready); 952 complete(&wil->wmi_ready);
904 return; 953 return;
905 } 954 }
@@ -964,7 +1013,7 @@ void wmi_connect_worker(struct work_struct *work)
964 return; 1013 return;
965 } 1014 }
966 1015
967 wil_dbg_WMI(wil, "Configure for connection CID %d\n", 1016 wil_dbg_wmi(wil, "Configure for connection CID %d\n",
968 wil->pending_connect_cid); 1017 wil->pending_connect_cid);
969 1018
970 rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE, 1019 rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE,
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 7fc49ca3f597..b1dd5600fd02 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -542,9 +542,8 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
542 542
543 if (changed & BSS_CHANGED_ARP_FILTER) { 543 if (changed & BSS_CHANGED_ARP_FILTER) {
544 /* Hardware ARP filter address list or state changed */ 544 /* Hardware ARP filter address list or state changed */
545 brcms_err(core, "%s: arp filtering: enabled %s, count %d" 545 brcms_err(core, "%s: arp filtering: %d addresses"
546 " (implement)\n", __func__, info->arp_filter_enabled ? 546 " (implement)\n", __func__, info->arp_addr_cnt);
547 "true" : "false", info->arp_addr_cnt);
548 } 547 }
549 548
550 if (changed & BSS_CHANGED_QOS) { 549 if (changed & BSS_CHANGED_QOS) {
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index 050ce7c70d74..83856d1a6101 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -1001,12 +1001,12 @@ il3945_rx_allocate(struct il_priv *il, gfp_t priority)
1001 struct list_head *element; 1001 struct list_head *element;
1002 struct il_rx_buf *rxb; 1002 struct il_rx_buf *rxb;
1003 struct page *page; 1003 struct page *page;
1004 dma_addr_t page_dma;
1004 unsigned long flags; 1005 unsigned long flags;
1005 gfp_t gfp_mask = priority; 1006 gfp_t gfp_mask = priority;
1006 1007
1007 while (1) { 1008 while (1) {
1008 spin_lock_irqsave(&rxq->lock, flags); 1009 spin_lock_irqsave(&rxq->lock, flags);
1009
1010 if (list_empty(&rxq->rx_used)) { 1010 if (list_empty(&rxq->rx_used)) {
1011 spin_unlock_irqrestore(&rxq->lock, flags); 1011 spin_unlock_irqrestore(&rxq->lock, flags);
1012 return; 1012 return;
@@ -1035,26 +1035,34 @@ il3945_rx_allocate(struct il_priv *il, gfp_t priority)
1035 break; 1035 break;
1036 } 1036 }
1037 1037
1038 /* Get physical address of RB/SKB */
1039 page_dma =
1040 pci_map_page(il->pci_dev, page, 0,
1041 PAGE_SIZE << il->hw_params.rx_page_order,
1042 PCI_DMA_FROMDEVICE);
1043
1044 if (unlikely(pci_dma_mapping_error(il->pci_dev, page_dma))) {
1045 __free_pages(page, il->hw_params.rx_page_order);
1046 break;
1047 }
1048
1038 spin_lock_irqsave(&rxq->lock, flags); 1049 spin_lock_irqsave(&rxq->lock, flags);
1050
1039 if (list_empty(&rxq->rx_used)) { 1051 if (list_empty(&rxq->rx_used)) {
1040 spin_unlock_irqrestore(&rxq->lock, flags); 1052 spin_unlock_irqrestore(&rxq->lock, flags);
1053 pci_unmap_page(il->pci_dev, page_dma,
1054 PAGE_SIZE << il->hw_params.rx_page_order,
1055 PCI_DMA_FROMDEVICE);
1041 __free_pages(page, il->hw_params.rx_page_order); 1056 __free_pages(page, il->hw_params.rx_page_order);
1042 return; 1057 return;
1043 } 1058 }
1059
1044 element = rxq->rx_used.next; 1060 element = rxq->rx_used.next;
1045 rxb = list_entry(element, struct il_rx_buf, list); 1061 rxb = list_entry(element, struct il_rx_buf, list);
1046 list_del(element); 1062 list_del(element);
1047 spin_unlock_irqrestore(&rxq->lock, flags);
1048 1063
1049 rxb->page = page; 1064 rxb->page = page;
1050 /* Get physical address of RB/SKB */ 1065 rxb->page_dma = page_dma;
1051 rxb->page_dma =
1052 pci_map_page(il->pci_dev, page, 0,
1053 PAGE_SIZE << il->hw_params.rx_page_order,
1054 PCI_DMA_FROMDEVICE);
1055
1056 spin_lock_irqsave(&rxq->lock, flags);
1057
1058 list_add_tail(&rxb->list, &rxq->rx_free); 1066 list_add_tail(&rxb->list, &rxq->rx_free);
1059 rxq->free_count++; 1067 rxq->free_count++;
1060 il->alloc_rxb_page++; 1068 il->alloc_rxb_page++;
@@ -1284,8 +1292,15 @@ il3945_rx_handle(struct il_priv *il)
1284 pci_map_page(il->pci_dev, rxb->page, 0, 1292 pci_map_page(il->pci_dev, rxb->page, 0,
1285 PAGE_SIZE << il->hw_params. 1293 PAGE_SIZE << il->hw_params.
1286 rx_page_order, PCI_DMA_FROMDEVICE); 1294 rx_page_order, PCI_DMA_FROMDEVICE);
1287 list_add_tail(&rxb->list, &rxq->rx_free); 1295 if (unlikely(pci_dma_mapping_error(il->pci_dev,
1288 rxq->free_count++; 1296 rxb->page_dma))) {
1297 __il_free_pages(il, rxb->page);
1298 rxb->page = NULL;
1299 list_add_tail(&rxb->list, &rxq->rx_used);
1300 } else {
1301 list_add_tail(&rxb->list, &rxq->rx_free);
1302 rxq->free_count++;
1303 }
1289 } else 1304 } else
1290 list_add_tail(&rxb->list, &rxq->rx_used); 1305 list_add_tail(&rxb->list, &rxq->rx_used);
1291 1306
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index f1dc04006564..9741ac10a334 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -319,6 +319,7 @@ il4965_rx_allocate(struct il_priv *il, gfp_t priority)
319 struct list_head *element; 319 struct list_head *element;
320 struct il_rx_buf *rxb; 320 struct il_rx_buf *rxb;
321 struct page *page; 321 struct page *page;
322 dma_addr_t page_dma;
322 unsigned long flags; 323 unsigned long flags;
323 gfp_t gfp_mask = priority; 324 gfp_t gfp_mask = priority;
324 325
@@ -356,33 +357,35 @@ il4965_rx_allocate(struct il_priv *il, gfp_t priority)
356 return; 357 return;
357 } 358 }
358 359
360 /* Get physical address of the RB */
361 page_dma =
362 pci_map_page(il->pci_dev, page, 0,
363 PAGE_SIZE << il->hw_params.rx_page_order,
364 PCI_DMA_FROMDEVICE);
365 if (unlikely(pci_dma_mapping_error(il->pci_dev, page_dma))) {
366 __free_pages(page, il->hw_params.rx_page_order);
367 break;
368 }
369
359 spin_lock_irqsave(&rxq->lock, flags); 370 spin_lock_irqsave(&rxq->lock, flags);
360 371
361 if (list_empty(&rxq->rx_used)) { 372 if (list_empty(&rxq->rx_used)) {
362 spin_unlock_irqrestore(&rxq->lock, flags); 373 spin_unlock_irqrestore(&rxq->lock, flags);
374 pci_unmap_page(il->pci_dev, page_dma,
375 PAGE_SIZE << il->hw_params.rx_page_order,
376 PCI_DMA_FROMDEVICE);
363 __free_pages(page, il->hw_params.rx_page_order); 377 __free_pages(page, il->hw_params.rx_page_order);
364 return; 378 return;
365 } 379 }
380
366 element = rxq->rx_used.next; 381 element = rxq->rx_used.next;
367 rxb = list_entry(element, struct il_rx_buf, list); 382 rxb = list_entry(element, struct il_rx_buf, list);
368 list_del(element); 383 list_del(element);
369 384
370 spin_unlock_irqrestore(&rxq->lock, flags);
371
372 BUG_ON(rxb->page); 385 BUG_ON(rxb->page);
373 rxb->page = page;
374 /* Get physical address of the RB */
375 rxb->page_dma =
376 pci_map_page(il->pci_dev, page, 0,
377 PAGE_SIZE << il->hw_params.rx_page_order,
378 PCI_DMA_FROMDEVICE);
379 /* dma address must be no more than 36 bits */
380 BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
381 /* and also 256 byte aligned! */
382 BUG_ON(rxb->page_dma & DMA_BIT_MASK(8));
383
384 spin_lock_irqsave(&rxq->lock, flags);
385 386
387 rxb->page = page;
388 rxb->page_dma = page_dma;
386 list_add_tail(&rxb->list, &rxq->rx_free); 389 list_add_tail(&rxb->list, &rxq->rx_free);
387 rxq->free_count++; 390 rxq->free_count++;
388 il->alloc_rxb_page++; 391 il->alloc_rxb_page++;
@@ -725,6 +728,16 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
725 if (rate_n_flags & RATE_MCS_SGI_MSK) 728 if (rate_n_flags & RATE_MCS_SGI_MSK)
726 rx_status.flag |= RX_FLAG_SHORT_GI; 729 rx_status.flag |= RX_FLAG_SHORT_GI;
727 730
731 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_AGG_MSK) {
732 /* We know which subframes of an A-MPDU belong
733 * together since we get a single PHY response
734 * from the firmware for all of them.
735 */
736
737 rx_status.flag |= RX_FLAG_AMPDU_DETAILS;
738 rx_status.ampdu_reference = il->_4965.ampdu_ref;
739 }
740
728 il4965_pass_packet_to_mac80211(il, header, len, ampdu_status, rxb, 741 il4965_pass_packet_to_mac80211(il, header, len, ampdu_status, rxb,
729 &rx_status); 742 &rx_status);
730} 743}
@@ -736,6 +749,7 @@ il4965_hdl_rx_phy(struct il_priv *il, struct il_rx_buf *rxb)
736{ 749{
737 struct il_rx_pkt *pkt = rxb_addr(rxb); 750 struct il_rx_pkt *pkt = rxb_addr(rxb);
738 il->_4965.last_phy_res_valid = true; 751 il->_4965.last_phy_res_valid = true;
752 il->_4965.ampdu_ref++;
739 memcpy(&il->_4965.last_phy_res, pkt->u.raw, 753 memcpy(&il->_4965.last_phy_res, pkt->u.raw,
740 sizeof(struct il_rx_phy_res)); 754 sizeof(struct il_rx_phy_res));
741} 755}
@@ -4281,8 +4295,16 @@ il4965_rx_handle(struct il_priv *il)
4281 pci_map_page(il->pci_dev, rxb->page, 0, 4295 pci_map_page(il->pci_dev, rxb->page, 0,
4282 PAGE_SIZE << il->hw_params. 4296 PAGE_SIZE << il->hw_params.
4283 rx_page_order, PCI_DMA_FROMDEVICE); 4297 rx_page_order, PCI_DMA_FROMDEVICE);
4284 list_add_tail(&rxb->list, &rxq->rx_free); 4298
4285 rxq->free_count++; 4299 if (unlikely(pci_dma_mapping_error(il->pci_dev,
4300 rxb->page_dma))) {
4301 __il_free_pages(il, rxb->page);
4302 rxb->page = NULL;
4303 list_add_tail(&rxb->list, &rxq->rx_used);
4304 } else {
4305 list_add_tail(&rxb->list, &rxq->rx_free);
4306 rxq->free_count++;
4307 }
4286 } else 4308 } else
4287 list_add_tail(&rxb->list, &rxq->rx_used); 4309 list_add_tail(&rxb->list, &rxq->rx_used);
4288 4310
@@ -6573,9 +6595,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
6573 if (err) 6595 if (err)
6574 goto out_free_eeprom; 6596 goto out_free_eeprom;
6575 6597
6576 if (err)
6577 goto out_free_eeprom;
6578
6579 /* extract MAC Address */ 6598 /* extract MAC Address */
6580 il4965_eeprom_get_mac(il, il->addresses[0].addr); 6599 il4965_eeprom_get_mac(il, il->addresses[0].addr);
6581 D_INFO("MAC address: %pM\n", il->addresses[0].addr); 6600 D_INFO("MAC address: %pM\n", il->addresses[0].addr);
diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c
index 5db11714e047..91eb2d07fdb8 100644
--- a/drivers/net/wireless/iwlegacy/4965.c
+++ b/drivers/net/wireless/iwlegacy/4965.c
@@ -1748,7 +1748,6 @@ static void
1748il4965_post_associate(struct il_priv *il) 1748il4965_post_associate(struct il_priv *il)
1749{ 1749{
1750 struct ieee80211_vif *vif = il->vif; 1750 struct ieee80211_vif *vif = il->vif;
1751 struct ieee80211_conf *conf = NULL;
1752 int ret = 0; 1751 int ret = 0;
1753 1752
1754 if (!vif || !il->is_open) 1753 if (!vif || !il->is_open)
@@ -1759,8 +1758,6 @@ il4965_post_associate(struct il_priv *il)
1759 1758
1760 il_scan_cancel_timeout(il, 200); 1759 il_scan_cancel_timeout(il, 200);
1761 1760
1762 conf = &il->hw->conf;
1763
1764 il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1761 il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1765 il_commit_rxon(il); 1762 il_commit_rxon(il);
1766 1763
diff --git a/drivers/net/wireless/iwlegacy/commands.h b/drivers/net/wireless/iwlegacy/commands.h
index 25dd7d28d022..3b6c99400892 100644
--- a/drivers/net/wireless/iwlegacy/commands.h
+++ b/drivers/net/wireless/iwlegacy/commands.h
@@ -1134,8 +1134,9 @@ struct il_wep_cmd {
1134#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1) 1134#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1)
1135#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2) 1135#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
1136#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3) 1136#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
1137#define RX_RES_PHY_FLAGS_ANTENNA_MSK 0xf0 1137#define RX_RES_PHY_FLAGS_ANTENNA_MSK 0x70
1138#define RX_RES_PHY_FLAGS_ANTENNA_POS 4 1138#define RX_RES_PHY_FLAGS_ANTENNA_POS 4
1139#define RX_RES_PHY_FLAGS_AGG_MSK cpu_to_le16(1 << 7)
1139 1140
1140#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) 1141#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
1141#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) 1142#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8)
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index 37fe553b25e0..96f2025d936e 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1356,6 +1356,7 @@ struct il_priv {
1356 struct { 1356 struct {
1357 struct il_rx_phy_res last_phy_res; 1357 struct il_rx_phy_res last_phy_res;
1358 bool last_phy_res_valid; 1358 bool last_phy_res_valid;
1359 u32 ampdu_ref;
1359 1360
1360 struct completion firmware_loading_complete; 1361 struct completion firmware_loading_complete;
1361 1362
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 5cf43236421e..ba319cba3f1e 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -43,8 +43,20 @@ config IWLWIFI
43 module will be called iwlwifi. 43 module will be called iwlwifi.
44 44
45config IWLDVM 45config IWLDVM
46 tristate "Intel Wireless WiFi" 46 tristate "Intel Wireless WiFi DVM Firmware support"
47 depends on IWLWIFI 47 depends on IWLWIFI
48 help
49 This is the driver supporting the DVM firmware which is
50 currently the only firmware available for existing devices.
51
52config IWLMVM
53 tristate "Intel Wireless WiFi MVM Firmware support"
54 depends on IWLWIFI
55 help
56 This is the driver supporting the MVM firmware which is
57 currently only available for 7000 series devices.
58
59 Say yes if you have such a device.
48 60
49menu "Debugging Options" 61menu "Debugging Options"
50 depends on IWLWIFI 62 depends on IWLWIFI
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 170ec330d2a9..6c7800044a04 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -5,8 +5,10 @@ iwlwifi-objs += iwl-drv.o
5iwlwifi-objs += iwl-debug.o 5iwlwifi-objs += iwl-debug.o
6iwlwifi-objs += iwl-notif-wait.o 6iwlwifi-objs += iwl-notif-wait.o
7iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o 7iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o
8iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o
8iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o 9iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
9iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o 10iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o
11iwlwifi-objs += pcie/7000.o
10 12
11iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 13iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
12iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o 14iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o
@@ -15,5 +17,6 @@ ccflags-y += -D__CHECK_ENDIAN__ -I$(src)
15 17
16 18
17obj-$(CONFIG_IWLDVM) += dvm/ 19obj-$(CONFIG_IWLDVM) += dvm/
20obj-$(CONFIG_IWLMVM) += mvm/
18 21
19CFLAGS_iwl-devtrace.o := -I$(src) 22CFLAGS_iwl-devtrace.o := -I$(src)
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 33b3ad2e546b..f41ae79e6bc0 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c
index de54713b680c..6468de8634b0 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h
index 2349f393cc42..65e920cab2b7 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.h
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 0ca99c13f7f2..8bce4b0148e0 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
index 72c74af38138..20806cae11b7 100644
--- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 2653a891cc7e..71ea77576d22 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c
index 8c72be3f37c1..15cca2ef9294 100644
--- a/drivers/net/wireless/iwlwifi/dvm/devices.c
+++ b/drivers/net/wireless/iwlwifi/dvm/devices.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/led.c b/drivers/net/wireless/iwlwifi/dvm/led.c
index 844a17f99a18..33c7e15d24f5 100644
--- a/drivers/net/wireless/iwlwifi/dvm/led.c
+++ b/drivers/net/wireless/iwlwifi/dvm/led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/led.h b/drivers/net/wireless/iwlwifi/dvm/led.h
index b02a853103d3..8749dcfe695f 100644
--- a/drivers/net/wireless/iwlwifi/dvm/led.h
+++ b/drivers/net/wireless/iwlwifi/dvm/led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 6ff46605ad4f..86ea5f4c3939 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 0353e1c0670d..c2f03ecd4bf8 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -459,14 +459,12 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
459 459
460 base = priv->device_pointers.error_event_table; 460 base = priv->device_pointers.error_event_table;
461 if (iwlagn_hw_valid_rtc_data_addr(base)) { 461 if (iwlagn_hw_valid_rtc_data_addr(base)) {
462 spin_lock_irqsave(&priv->trans->reg_lock, flags); 462 if (iwl_trans_grab_nic_access(priv->trans, true, &flags)) {
463 if (iwl_trans_grab_nic_access(priv->trans, true)) {
464 iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base); 463 iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base);
465 status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); 464 status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT);
466 iwl_trans_release_nic_access(priv->trans); 465 iwl_trans_release_nic_access(priv->trans, &flags);
467 ret = 0; 466 ret = 0;
468 } 467 }
469 spin_unlock_irqrestore(&priv->trans->reg_lock, flags);
470 468
471#ifdef CONFIG_IWLWIFI_DEBUGFS 469#ifdef CONFIG_IWLWIFI_DEBUGFS
472 if (ret == 0) { 470 if (ret == 0) {
@@ -1154,6 +1152,7 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
1154} 1152}
1155 1153
1156static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, 1154static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
1155 struct ieee80211_vif *vif,
1157 enum ieee80211_rssi_event rssi_event) 1156 enum ieee80211_rssi_event rssi_event)
1158{ 1157{
1159 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1158 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index a64f361e341c..b9e3517652d6 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -353,11 +353,8 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
353 ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); 353 ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32));
354 354
355 /* Make sure device is powered up for SRAM reads */ 355 /* Make sure device is powered up for SRAM reads */
356 spin_lock_irqsave(&priv->trans->reg_lock, reg_flags); 356 if (!iwl_trans_grab_nic_access(priv->trans, false, &reg_flags))
357 if (!iwl_trans_grab_nic_access(priv->trans, false)) {
358 spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags);
359 return; 357 return;
360 }
361 358
362 /* Set starting address; reads will auto-increment */ 359 /* Set starting address; reads will auto-increment */
363 iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, ptr); 360 iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, ptr);
@@ -388,8 +385,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
388 } 385 }
389 } 386 }
390 /* Allow device to power down */ 387 /* Allow device to power down */
391 iwl_trans_release_nic_access(priv->trans); 388 iwl_trans_release_nic_access(priv->trans, &reg_flags);
392 spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags);
393} 389}
394 390
395static void iwl_continuous_event_trace(struct iwl_priv *priv) 391static void iwl_continuous_event_trace(struct iwl_priv *priv)
@@ -1717,9 +1713,8 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1717 ptr = base + EVENT_START_OFFSET + (start_idx * event_size); 1713 ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
1718 1714
1719 /* Make sure device is powered up for SRAM reads */ 1715 /* Make sure device is powered up for SRAM reads */
1720 spin_lock_irqsave(&trans->reg_lock, reg_flags); 1716 if (!iwl_trans_grab_nic_access(trans, false, &reg_flags))
1721 if (!iwl_trans_grab_nic_access(trans, false)) 1717 return pos;
1722 goto out_unlock;
1723 1718
1724 /* Set starting address; reads will auto-increment */ 1719 /* Set starting address; reads will auto-increment */
1725 iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); 1720 iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr);
@@ -1757,9 +1752,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1757 } 1752 }
1758 1753
1759 /* Allow device to power down */ 1754 /* Allow device to power down */
1760 iwl_trans_release_nic_access(trans); 1755 iwl_trans_release_nic_access(trans, &reg_flags);
1761out_unlock:
1762 spin_unlock_irqrestore(&trans->reg_lock, reg_flags);
1763 return pos; 1756 return pos;
1764} 1757}
1765 1758
@@ -1991,13 +1984,13 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode)
1991 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); 1984 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
1992 1985
1993 /* SKU Control */ 1986 /* SKU Control */
1994 iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, 1987 iwl_trans_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG,
1995 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | 1988 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
1996 CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP, 1989 CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP,
1997 (CSR_HW_REV_STEP(priv->trans->hw_rev) << 1990 (CSR_HW_REV_STEP(priv->trans->hw_rev) <<
1998 CSR_HW_IF_CONFIG_REG_POS_MAC_STEP) | 1991 CSR_HW_IF_CONFIG_REG_POS_MAC_STEP) |
1999 (CSR_HW_REV_DASH(priv->trans->hw_rev) << 1992 (CSR_HW_REV_DASH(priv->trans->hw_rev) <<
2000 CSR_HW_IF_CONFIG_REG_POS_MAC_DASH)); 1993 CSR_HW_IF_CONFIG_REG_POS_MAC_DASH));
2001 1994
2002 /* write radio config values to register */ 1995 /* write radio config values to register */
2003 if (priv->nvm_data->radio_cfg_type <= EEPROM_RF_CONFIG_TYPE_MAX) { 1996 if (priv->nvm_data->radio_cfg_type <= EEPROM_RF_CONFIG_TYPE_MAX) {
@@ -2009,10 +2002,11 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode)
2009 priv->nvm_data->radio_cfg_dash << 2002 priv->nvm_data->radio_cfg_dash <<
2010 CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; 2003 CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;
2011 2004
2012 iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, 2005 iwl_trans_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG,
2013 CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE | 2006 CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE |
2014 CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | 2007 CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP |
2015 CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH, reg_val); 2008 CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH,
2009 reg_val);
2016 2010
2017 IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", 2011 IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n",
2018 priv->nvm_data->radio_cfg_type, 2012 priv->nvm_data->radio_cfg_type,
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c
index 518cf3715809..bd69018d07a9 100644
--- a/drivers/net/wireless/iwlwifi/dvm/power.c
+++ b/drivers/net/wireless/iwlwifi/dvm/power.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.h b/drivers/net/wireless/iwlwifi/dvm/power.h
index a2cee7f04848..7b03e1342d47 100644
--- a/drivers/net/wireless/iwlwifi/dvm/power.h
+++ b/drivers/net/wireless/iwlwifi/dvm/power.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c
index f3dd0da60d8a..a131227c49e9 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -411,8 +411,9 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
411 * BT traffic, as they would just be disrupted by BT. 411 * BT traffic, as they would just be disrupted by BT.
412 */ 412 */
413 if (priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) { 413 if (priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) {
414 IWL_ERR(priv, "BT traffic (%d), no aggregation allowed\n", 414 IWL_DEBUG_COEX(priv,
415 priv->bt_traffic_load); 415 "BT traffic (%d), no aggregation allowed\n",
416 priv->bt_traffic_load);
416 return ret; 417 return ret;
417 } 418 }
418 419
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.h b/drivers/net/wireless/iwlwifi/dvm/rs.h
index ad3aea8f626a..5d83cab22d62 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index cac4f37cc427..e8d5b90abf5c 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portionhelp of the ieee80211 subsystem header files. 6 * as portionhelp of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index 9a891e6e60e8..9fabd26997ca 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c
index 610ed2204e1f..3a4aa5239c45 100644
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c
index bdba9543c351..ab768045696b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/dvm/sta.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c
index 57b918ce3b5f..dc6f965a123a 100644
--- a/drivers/net/wireless/iwlwifi/dvm/testmode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c
index b28cfc8553d7..67e2e1321b40 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tt.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -185,10 +185,8 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
185 priv->thermal_throttle.ct_kill_toggle = true; 185 priv->thermal_throttle.ct_kill_toggle = true;
186 } 186 }
187 iwl_read32(priv->trans, CSR_UCODE_DRV_GP1); 187 iwl_read32(priv->trans, CSR_UCODE_DRV_GP1);
188 spin_lock_irqsave(&priv->trans->reg_lock, flags); 188 if (iwl_trans_grab_nic_access(priv->trans, false, &flags))
189 if (iwl_trans_grab_nic_access(priv->trans, false)) 189 iwl_trans_release_nic_access(priv->trans, &flags);
190 iwl_trans_release_nic_access(priv->trans);
191 spin_unlock_irqrestore(&priv->trans->reg_lock, flags);
192 190
193 /* Reschedule the ct_kill timer to occur in 191 /* Reschedule the ct_kill timer to occur in
194 * CT_KILL_EXIT_DURATION seconds to ensure we get a 192 * CT_KILL_EXIT_DURATION seconds to ensure we get a
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.h b/drivers/net/wireless/iwlwifi/dvm/tt.h
index 44c7c8f30a2d..9356c4b908ca 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tt.h
+++ b/drivers/net/wireless/iwlwifi/dvm/tt.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 191b9d4bee47..f4a013675947 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index ebec13a3329f..736fe9bb140e 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index 7960a52f6ad4..e9975c54c276 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 864219d2136a..743b48343358 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -83,6 +83,7 @@ enum iwl_device_family {
83 IWL_DEVICE_FAMILY_6030, 83 IWL_DEVICE_FAMILY_6030,
84 IWL_DEVICE_FAMILY_6050, 84 IWL_DEVICE_FAMILY_6050,
85 IWL_DEVICE_FAMILY_6150, 85 IWL_DEVICE_FAMILY_6150,
86 IWL_DEVICE_FAMILY_7000,
86}; 87};
87 88
88/* 89/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index b419a1efac0a..df3463a38704 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 42b20b0e83bc..8cf5db7fb5c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
@@ -116,6 +116,7 @@ do { \
116#define IWL_DL_HCMD 0x00000004 116#define IWL_DL_HCMD 0x00000004
117#define IWL_DL_STATE 0x00000008 117#define IWL_DL_STATE 0x00000008
118/* 0x000000F0 - 0x00000010 */ 118/* 0x000000F0 - 0x00000010 */
119#define IWL_DL_TE 0x00000020
119#define IWL_DL_EEPROM 0x00000040 120#define IWL_DL_EEPROM 0x00000040
120#define IWL_DL_RADIO 0x00000080 121#define IWL_DL_RADIO 0x00000080
121/* 0x00000F00 - 0x00000100 */ 122/* 0x00000F00 - 0x00000100 */
@@ -156,6 +157,7 @@ do { \
156#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) 157#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a)
157#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) 158#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
158#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) 159#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
160#define IWL_DEBUG_TE(p, f, a...) IWL_DEBUG(p, IWL_DL_TE, f, ## a)
159#define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a) 161#define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a)
160#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) 162#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
161#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) 163#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 70191ddbd8f6..8f61c717f619 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2009 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index dc7e26b2f383..9a0f45ec9e01 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2009 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index d3549f493a17..6f228bb2b844 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -139,8 +139,10 @@ struct iwl_drv {
139#endif 139#endif
140}; 140};
141 141
142#define DVM_OP_MODE 0 142enum {
143#define MVM_OP_MODE 1 143 DVM_OP_MODE = 0,
144 MVM_OP_MODE = 1,
145};
144 146
145/* Protects the table contents, i.e. the ops pointer & drv list */ 147/* Protects the table contents, i.e. the ops pointer & drv list */
146static struct mutex iwlwifi_opmode_table_mtx; 148static struct mutex iwlwifi_opmode_table_mtx;
@@ -149,8 +151,8 @@ static struct iwlwifi_opmode_table {
149 const struct iwl_op_mode_ops *ops; /* pointer to op_mode ops */ 151 const struct iwl_op_mode_ops *ops; /* pointer to op_mode ops */
150 struct list_head drv; /* list of devices using this op_mode */ 152 struct list_head drv; /* list of devices using this op_mode */
151} iwlwifi_opmode_table[] = { /* ops set when driver is initialized */ 153} iwlwifi_opmode_table[] = { /* ops set when driver is initialized */
152 { .name = "iwldvm", .ops = NULL }, 154 [DVM_OP_MODE] = { .name = "iwldvm", .ops = NULL },
153 { .name = "iwlmvm", .ops = NULL }, 155 [MVM_OP_MODE] = { .name = "iwlmvm", .ops = NULL },
154}; 156};
155 157
156/* 158/*
@@ -268,7 +270,7 @@ struct fw_sec_parsing {
268 */ 270 */
269struct iwl_tlv_calib_data { 271struct iwl_tlv_calib_data {
270 __le32 ucode_type; 272 __le32 ucode_type;
271 __le64 calib; 273 struct iwl_tlv_calib_ctrl calib;
272} __packed; 274} __packed;
273 275
274struct iwl_firmware_pieces { 276struct iwl_firmware_pieces {
@@ -358,7 +360,11 @@ static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data)
358 ucode_type); 360 ucode_type);
359 return -EINVAL; 361 return -EINVAL;
360 } 362 }
361 drv->fw.default_calib[ucode_type] = le64_to_cpu(def_calib->calib); 363 drv->fw.default_calib[ucode_type].flow_trigger =
364 def_calib->calib.flow_trigger;
365 drv->fw.default_calib[ucode_type].event_trigger =
366 def_calib->calib.event_trigger;
367
362 return 0; 368 return 0;
363} 369}
364 370
@@ -959,7 +965,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
959 release_firmware(ucode_raw); 965 release_firmware(ucode_raw);
960 966
961 mutex_lock(&iwlwifi_opmode_table_mtx); 967 mutex_lock(&iwlwifi_opmode_table_mtx);
962 op = &iwlwifi_opmode_table[DVM_OP_MODE]; 968 if (fw->mvm_fw)
969 op = &iwlwifi_opmode_table[MVM_OP_MODE];
970 else
971 op = &iwlwifi_opmode_table[DVM_OP_MODE];
963 972
964 /* add this device to the list of devices using this op_mode */ 973 /* add this device to the list of devices using this op_mode */
965 list_add_tail(&drv->list, &op->drv); 974 list_add_tail(&drv->list, &op->drv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h
index 285de5f68c05..594a5c71b272 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.h
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,7 @@
66/* for all modules */ 66/* for all modules */
67#define DRV_NAME "iwlwifi" 67#define DRV_NAME "iwlwifi"
68#define IWLWIFI_VERSION "in-tree:" 68#define IWLWIFI_VERSION "in-tree:"
69#define DRV_COPYRIGHT "Copyright(c) 2003-2012 Intel Corporation" 69#define DRV_COPYRIGHT "Copyright(c) 2003-2013 Intel Corporation"
70#define DRV_AUTHOR "<ilw@linux.intel.com>" 70#define DRV_AUTHOR "<ilw@linux.intel.com>"
71 71
72 72
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index 471986690cf0..034f2ff4f43d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -703,9 +703,9 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
703 return n_channels; 703 return n_channels;
704} 704}
705 705
706static int iwl_init_sband_channels(struct iwl_nvm_data *data, 706int iwl_init_sband_channels(struct iwl_nvm_data *data,
707 struct ieee80211_supported_band *sband, 707 struct ieee80211_supported_band *sband,
708 int n_channels, enum ieee80211_band band) 708 int n_channels, enum ieee80211_band band)
709{ 709{
710 struct ieee80211_channel *chan = &data->channels[0]; 710 struct ieee80211_channel *chan = &data->channels[0];
711 int n = 0, idx = 0; 711 int n = 0, idx = 0;
@@ -728,10 +728,10 @@ static int iwl_init_sband_channels(struct iwl_nvm_data *data,
728#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ 728#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
729#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ 729#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
730 730
731static void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, 731void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
732 struct iwl_nvm_data *data, 732 struct iwl_nvm_data *data,
733 struct ieee80211_sta_ht_cap *ht_info, 733 struct ieee80211_sta_ht_cap *ht_info,
734 enum ieee80211_band band) 734 enum ieee80211_band band)
735{ 735{
736 int max_bit_rate = 0; 736 int max_bit_rate = 0;
737 u8 rx_chains; 737 u8 rx_chains;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index 555f0eb61d48..683fe6a8c58f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -126,4 +126,13 @@ static inline void iwl_free_nvm_data(struct iwl_nvm_data *data)
126int iwl_nvm_check_version(struct iwl_nvm_data *data, 126int iwl_nvm_check_version(struct iwl_nvm_data *data,
127 struct iwl_trans *trans); 127 struct iwl_trans *trans);
128 128
129int iwl_init_sband_channels(struct iwl_nvm_data *data,
130 struct ieee80211_supported_band *sband,
131 int n_channels, enum ieee80211_band band);
132
133void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
134 struct iwl_nvm_data *data,
135 struct ieee80211_sta_ht_cap *ht_info,
136 enum ieee80211_band band);
137
129#endif /* __iwl_eeprom_parse_h__ */ 138#endif /* __iwl_eeprom_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
index 27c7da3c6ed1..ef4806f27cf8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
index 1337c9d36fee..b2588c5cbf93 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index c646a90b725e..f5592fb3b1ed 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -414,6 +414,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
414 * uCode/driver must write "1" in order to clear this flag 414 * uCode/driver must write "1" in order to clear this flag
415 */ 415 */
416#define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018) 416#define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018)
417#define FH_TSSR_TX_MSG_CONFIG_REG (FH_TSSR_LOWER_BOUND + 0x008)
417 418
418#define FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_chnl) ((1 << (_chnl)) << 16) 419#define FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_chnl) ((1 << (_chnl)) << 16)
419 420
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index e71564053e7f..90873eca35f7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 715291eb7f8e..b545178e46e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -139,6 +139,19 @@ struct fw_img {
139#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) 139#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
140#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) 140#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
141 141
142/*
143 * Calibration control struct.
144 * Sent as part of the phy configuration command.
145 * @flow_trigger: bitmap for which calibrations to perform according to
146 * flow triggers.
147 * @event_trigger: bitmap for which calibrations to perform according to
148 * event triggers.
149 */
150struct iwl_tlv_calib_ctrl {
151 __le32 flow_trigger;
152 __le32 event_trigger;
153} __packed;
154
142/** 155/**
143 * struct iwl_fw - variables associated with the firmware 156 * struct iwl_fw - variables associated with the firmware
144 * 157 *
@@ -153,6 +166,7 @@ struct fw_img {
153 * @inst_evtlog_ptr: event log offset for runtime ucode. 166 * @inst_evtlog_ptr: event log offset for runtime ucode.
154 * @inst_evtlog_size: event log size for runtime ucode. 167 * @inst_evtlog_size: event log size for runtime ucode.
155 * @inst_errlog_ptr: error log offfset for runtime ucode. 168 * @inst_errlog_ptr: error log offfset for runtime ucode.
169 * @mvm_fw: indicates this is MVM firmware
156 */ 170 */
157struct iwl_fw { 171struct iwl_fw {
158 u32 ucode_ver; 172 u32 ucode_ver;
@@ -168,7 +182,7 @@ struct iwl_fw {
168 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; 182 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
169 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; 183 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
170 184
171 u64 default_calib[IWL_UCODE_TYPE_MAX]; 185 struct iwl_tlv_calib_ctrl default_calib[IWL_UCODE_TYPE_MAX];
172 u32 phy_config; 186 u32 phy_config;
173 187
174 bool mvm_fw; 188 bool mvm_fw;
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index bff3ac96c00b..276410d82de4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
@@ -35,54 +35,6 @@
35 35
36#define IWL_POLL_INTERVAL 10 /* microseconds */ 36#define IWL_POLL_INTERVAL 10 /* microseconds */
37 37
38void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
39{
40 iwl_write32(trans, reg, iwl_read32(trans, reg) | mask);
41}
42
43void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
44{
45 iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask);
46}
47
48void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
49{
50 unsigned long flags;
51
52 spin_lock_irqsave(&trans->reg_lock, flags);
53 __iwl_set_bit(trans, reg, mask);
54 spin_unlock_irqrestore(&trans->reg_lock, flags);
55}
56EXPORT_SYMBOL_GPL(iwl_set_bit);
57
58void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
59{
60 unsigned long flags;
61
62 spin_lock_irqsave(&trans->reg_lock, flags);
63 __iwl_clear_bit(trans, reg, mask);
64 spin_unlock_irqrestore(&trans->reg_lock, flags);
65}
66EXPORT_SYMBOL_GPL(iwl_clear_bit);
67
68void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value)
69{
70 unsigned long flags;
71 u32 v;
72
73#ifdef CONFIG_IWLWIFI_DEBUG
74 WARN_ON_ONCE(value & ~mask);
75#endif
76
77 spin_lock_irqsave(&trans->reg_lock, flags);
78 v = iwl_read32(trans, reg);
79 v &= ~mask;
80 v |= value;
81 iwl_write32(trans, reg, v);
82 spin_unlock_irqrestore(&trans->reg_lock, flags);
83}
84EXPORT_SYMBOL_GPL(iwl_set_bits_mask);
85
86int iwl_poll_bit(struct iwl_trans *trans, u32 addr, 38int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
87 u32 bits, u32 mask, int timeout) 39 u32 bits, u32 mask, int timeout)
88{ 40{
@@ -103,13 +55,10 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
103{ 55{
104 u32 value = 0x5a5a5a5a; 56 u32 value = 0x5a5a5a5a;
105 unsigned long flags; 57 unsigned long flags;
106 58 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
107 spin_lock_irqsave(&trans->reg_lock, flags);
108 if (iwl_trans_grab_nic_access(trans, false)) {
109 value = iwl_read32(trans, reg); 59 value = iwl_read32(trans, reg);
110 iwl_trans_release_nic_access(trans); 60 iwl_trans_release_nic_access(trans, &flags);
111 } 61 }
112 spin_unlock_irqrestore(&trans->reg_lock, flags);
113 62
114 return value; 63 return value;
115} 64}
@@ -119,12 +68,10 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
119{ 68{
120 unsigned long flags; 69 unsigned long flags;
121 70
122 spin_lock_irqsave(&trans->reg_lock, flags); 71 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
123 if (iwl_trans_grab_nic_access(trans, false)) {
124 iwl_write32(trans, reg, value); 72 iwl_write32(trans, reg, value);
125 iwl_trans_release_nic_access(trans); 73 iwl_trans_release_nic_access(trans, &flags);
126 } 74 }
127 spin_unlock_irqrestore(&trans->reg_lock, flags);
128} 75}
129EXPORT_SYMBOL_GPL(iwl_write_direct32); 76EXPORT_SYMBOL_GPL(iwl_write_direct32);
130 77
@@ -162,12 +109,10 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
162 unsigned long flags; 109 unsigned long flags;
163 u32 val = 0x5a5a5a5a; 110 u32 val = 0x5a5a5a5a;
164 111
165 spin_lock_irqsave(&trans->reg_lock, flags); 112 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
166 if (iwl_trans_grab_nic_access(trans, false)) {
167 val = __iwl_read_prph(trans, ofs); 113 val = __iwl_read_prph(trans, ofs);
168 iwl_trans_release_nic_access(trans); 114 iwl_trans_release_nic_access(trans, &flags);
169 } 115 }
170 spin_unlock_irqrestore(&trans->reg_lock, flags);
171 return val; 116 return val;
172} 117}
173EXPORT_SYMBOL_GPL(iwl_read_prph); 118EXPORT_SYMBOL_GPL(iwl_read_prph);
@@ -176,12 +121,10 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
176{ 121{
177 unsigned long flags; 122 unsigned long flags;
178 123
179 spin_lock_irqsave(&trans->reg_lock, flags); 124 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
180 if (iwl_trans_grab_nic_access(trans, false)) {
181 __iwl_write_prph(trans, ofs, val); 125 __iwl_write_prph(trans, ofs, val);
182 iwl_trans_release_nic_access(trans); 126 iwl_trans_release_nic_access(trans, &flags);
183 } 127 }
184 spin_unlock_irqrestore(&trans->reg_lock, flags);
185} 128}
186EXPORT_SYMBOL_GPL(iwl_write_prph); 129EXPORT_SYMBOL_GPL(iwl_write_prph);
187 130
@@ -189,13 +132,11 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
189{ 132{
190 unsigned long flags; 133 unsigned long flags;
191 134
192 spin_lock_irqsave(&trans->reg_lock, flags); 135 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
193 if (iwl_trans_grab_nic_access(trans, false)) {
194 __iwl_write_prph(trans, ofs, 136 __iwl_write_prph(trans, ofs,
195 __iwl_read_prph(trans, ofs) | mask); 137 __iwl_read_prph(trans, ofs) | mask);
196 iwl_trans_release_nic_access(trans); 138 iwl_trans_release_nic_access(trans, &flags);
197 } 139 }
198 spin_unlock_irqrestore(&trans->reg_lock, flags);
199} 140}
200EXPORT_SYMBOL_GPL(iwl_set_bits_prph); 141EXPORT_SYMBOL_GPL(iwl_set_bits_prph);
201 142
@@ -204,13 +145,11 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
204{ 145{
205 unsigned long flags; 146 unsigned long flags;
206 147
207 spin_lock_irqsave(&trans->reg_lock, flags); 148 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
208 if (iwl_trans_grab_nic_access(trans, false)) {
209 __iwl_write_prph(trans, ofs, 149 __iwl_write_prph(trans, ofs,
210 (__iwl_read_prph(trans, ofs) & mask) | bits); 150 (__iwl_read_prph(trans, ofs) & mask) | bits);
211 iwl_trans_release_nic_access(trans); 151 iwl_trans_release_nic_access(trans, &flags);
212 } 152 }
213 spin_unlock_irqrestore(&trans->reg_lock, flags);
214} 153}
215EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph); 154EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph);
216 155
@@ -219,12 +158,10 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
219 unsigned long flags; 158 unsigned long flags;
220 u32 val; 159 u32 val;
221 160
222 spin_lock_irqsave(&trans->reg_lock, flags); 161 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
223 if (iwl_trans_grab_nic_access(trans, false)) {
224 val = __iwl_read_prph(trans, ofs); 162 val = __iwl_read_prph(trans, ofs);
225 __iwl_write_prph(trans, ofs, (val & ~mask)); 163 __iwl_write_prph(trans, ofs, (val & ~mask));
226 iwl_trans_release_nic_access(trans); 164 iwl_trans_release_nic_access(trans, &flags);
227 } 165 }
228 spin_unlock_irqrestore(&trans->reg_lock, flags);
229} 166}
230EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); 167EXPORT_SYMBOL_GPL(iwl_clear_bits_prph);
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index dc478068596b..fd9f5b97fff3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
@@ -51,12 +51,15 @@ static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs)
51 return val; 51 return val;
52} 52}
53 53
54void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); 54static inline void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
55void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); 55{
56void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); 56 iwl_trans_set_bits_mask(trans, reg, mask, mask);
57void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); 57}
58 58
59void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value); 59static inline void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
60{
61 iwl_trans_set_bits_mask(trans, reg, mask, 0);
62}
60 63
61int iwl_poll_bit(struct iwl_trans *trans, u32 addr, 64int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
62 u32 bits, u32 mask, int timeout); 65 u32 bits, u32 mask, int timeout);
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index d9a86d6b2bd7..e5e3a79eae2f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
index c61f2070f15a..c3affbc62cdf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
+++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
index 821523100cf1..c2ce764463a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
+++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
new file mode 100644
index 000000000000..a70213bdb83c
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -0,0 +1,346 @@
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) 2008 - 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 LICENSE.GPL.
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) 2005 - 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#include <linux/types.h>
63#include <linux/slab.h>
64#include <linux/export.h>
65#include "iwl-modparams.h"
66#include "iwl-nvm-parse.h"
67
68/* NVM offsets (in words) definitions */
69enum wkp_nvm_offsets {
70 /* NVM HW-Section offset (in words) definitions */
71 HW_ADDR = 0x15,
72
73/* NVM SW-Section offset (in words) definitions */
74 NVM_SW_SECTION = 0x1C0,
75 NVM_VERSION = 0,
76 RADIO_CFG = 1,
77 SKU = 2,
78 N_HW_ADDRS = 3,
79 NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION,
80
81/* NVM calibration section offset (in words) definitions */
82 NVM_CALIB_SECTION = 0x2B8,
83 XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
84};
85
86/* SKU Capabilities (actual values from NVM definition) */
87enum nvm_sku_bits {
88 NVM_SKU_CAP_BAND_24GHZ = BIT(0),
89 NVM_SKU_CAP_BAND_52GHZ = BIT(1),
90 NVM_SKU_CAP_11N_ENABLE = BIT(2),
91};
92
93/* radio config bits (actual values from NVM definition) */
94#define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
95#define NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
96#define NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
97#define NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
98#define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
99#define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
100
101/*
102 * These are the channel numbers in the order that they are stored in the NVM
103 */
104static const u8 iwl_nvm_channels[] = {
105 /* 2.4 GHz */
106 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
107 /* 5 GHz */
108 36, 40, 44 , 48, 52, 56, 60, 64,
109 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
110 149, 153, 157, 161, 165
111};
112
113#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
114#define NUM_2GHZ_CHANNELS 14
115#define FIRST_2GHZ_HT_MINUS 5
116#define LAST_2GHZ_HT_PLUS 9
117#define LAST_5GHZ_HT 161
118
119
120/* rate data (static) */
121static struct ieee80211_rate iwl_cfg80211_rates[] = {
122 { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, },
123 { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1,
124 .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
125 { .bitrate = 5.5 * 10, .hw_value = 2, .hw_value_short = 2,
126 .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
127 { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3,
128 .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
129 { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, },
130 { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, },
131 { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, },
132 { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, },
133 { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, },
134 { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, },
135 { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, },
136 { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, },
137};
138#define RATES_24_OFFS 0
139#define N_RATES_24 ARRAY_SIZE(iwl_cfg80211_rates)
140#define RATES_52_OFFS 4
141#define N_RATES_52 (N_RATES_24 - RATES_52_OFFS)
142
143/**
144 * enum iwl_nvm_channel_flags - channel flags in NVM
145 * @NVM_CHANNEL_VALID: channel is usable for this SKU/geo
146 * @NVM_CHANNEL_IBSS: usable as an IBSS channel
147 * @NVM_CHANNEL_ACTIVE: active scanning allowed
148 * @NVM_CHANNEL_RADAR: radar detection required
149 * @NVM_CHANNEL_DFS: dynamic freq selection candidate
150 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
151 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
152 */
153enum iwl_nvm_channel_flags {
154 NVM_CHANNEL_VALID = BIT(0),
155 NVM_CHANNEL_IBSS = BIT(1),
156 NVM_CHANNEL_ACTIVE = BIT(3),
157 NVM_CHANNEL_RADAR = BIT(4),
158 NVM_CHANNEL_DFS = BIT(7),
159 NVM_CHANNEL_WIDE = BIT(8),
160 NVM_CHANNEL_40MHZ = BIT(9),
161};
162
163#define CHECK_AND_PRINT_I(x) \
164 ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
165
166static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
167 struct iwl_nvm_data *data,
168 const __le16 * const nvm_ch_flags)
169{
170 int ch_idx;
171 int n_channels = 0;
172 struct ieee80211_channel *channel;
173 u16 ch_flags;
174 bool is_5ghz;
175
176 for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) {
177 ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
178 if (!(ch_flags & NVM_CHANNEL_VALID)) {
179 IWL_DEBUG_EEPROM(dev,
180 "Ch. %d Flags %x [%sGHz] - No traffic\n",
181 iwl_nvm_channels[ch_idx],
182 ch_flags,
183 (ch_idx >= NUM_2GHZ_CHANNELS) ?
184 "5.2" : "2.4");
185 continue;
186 }
187
188 channel = &data->channels[n_channels];
189 n_channels++;
190
191 channel->hw_value = iwl_nvm_channels[ch_idx];
192 channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
193 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
194 channel->center_freq =
195 ieee80211_channel_to_frequency(
196 channel->hw_value, channel->band);
197
198 /* TODO: Need to be dependent to the NVM */
199 channel->flags = IEEE80211_CHAN_NO_HT40;
200 if (ch_idx < NUM_2GHZ_CHANNELS &&
201 (ch_flags & NVM_CHANNEL_40MHZ)) {
202 if (iwl_nvm_channels[ch_idx] <= LAST_2GHZ_HT_PLUS)
203 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
204 if (iwl_nvm_channels[ch_idx] >= FIRST_2GHZ_HT_MINUS)
205 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
206 } else if (iwl_nvm_channels[ch_idx] <= LAST_5GHZ_HT &&
207 (ch_flags & NVM_CHANNEL_40MHZ)) {
208 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
209 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
210 else
211 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
212 }
213
214 if (!(ch_flags & NVM_CHANNEL_IBSS))
215 channel->flags |= IEEE80211_CHAN_NO_IBSS;
216
217 if (!(ch_flags & NVM_CHANNEL_ACTIVE))
218 channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
219
220 if (ch_flags & NVM_CHANNEL_RADAR)
221 channel->flags |= IEEE80211_CHAN_RADAR;
222
223 /* Initialize regulatory-based run-time data */
224
225 /* TODO: read the real value from the NVM */
226 channel->max_power = 0;
227 is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
228 IWL_DEBUG_EEPROM(dev,
229 "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
230 channel->hw_value,
231 is_5ghz ? "5.2" : "2.4",
232 CHECK_AND_PRINT_I(VALID),
233 CHECK_AND_PRINT_I(IBSS),
234 CHECK_AND_PRINT_I(ACTIVE),
235 CHECK_AND_PRINT_I(RADAR),
236 CHECK_AND_PRINT_I(WIDE),
237 CHECK_AND_PRINT_I(DFS),
238 ch_flags,
239 channel->max_power,
240 ((ch_flags & NVM_CHANNEL_IBSS) &&
241 !(ch_flags & NVM_CHANNEL_RADAR))
242 ? "" : "not ");
243 }
244
245 return n_channels;
246}
247
248static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
249 struct iwl_nvm_data *data, const __le16 *nvm_sw)
250{
251 int n_channels = iwl_init_channel_map(dev, cfg, data,
252 &nvm_sw[NVM_CHANNELS]);
253 int n_used = 0;
254 struct ieee80211_supported_band *sband;
255
256 sband = &data->bands[IEEE80211_BAND_2GHZ];
257 sband->band = IEEE80211_BAND_2GHZ;
258 sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
259 sband->n_bitrates = N_RATES_24;
260 n_used += iwl_init_sband_channels(data, sband, n_channels,
261 IEEE80211_BAND_2GHZ);
262 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ);
263
264 sband = &data->bands[IEEE80211_BAND_5GHZ];
265 sband->band = IEEE80211_BAND_5GHZ;
266 sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS];
267 sband->n_bitrates = N_RATES_52;
268 n_used += iwl_init_sband_channels(data, sband, n_channels,
269 IEEE80211_BAND_5GHZ);
270 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ);
271
272 if (n_channels != n_used)
273 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
274 n_used, n_channels);
275}
276
277struct iwl_nvm_data *
278iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
279 const __le16 *nvm_hw, const __le16 *nvm_sw,
280 const __le16 *nvm_calib)
281{
282 struct iwl_nvm_data *data;
283 u8 hw_addr[ETH_ALEN];
284 u16 radio_cfg, sku;
285
286 data = kzalloc(sizeof(*data) +
287 sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
288 GFP_KERNEL);
289 if (!data)
290 return NULL;
291
292 data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION);
293
294 radio_cfg = le16_to_cpup(nvm_sw + RADIO_CFG);
295 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
296 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
297 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
298 data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
299 data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
300 data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
301
302 sku = le16_to_cpup(nvm_sw + SKU);
303 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
304 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
305 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
306 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
307 data->sku_cap_11n_enable = false;
308
309 /* check overrides (some devices have wrong NVM) */
310 if (cfg->valid_tx_ant)
311 data->valid_tx_ant = cfg->valid_tx_ant;
312 if (cfg->valid_rx_ant)
313 data->valid_rx_ant = cfg->valid_rx_ant;
314
315 if (!data->valid_tx_ant || !data->valid_rx_ant) {
316 IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n",
317 data->valid_tx_ant, data->valid_rx_ant);
318 kfree(data);
319 return NULL;
320 }
321
322 data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS);
323
324 data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
325 data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
326
327 /* The byte order is little endian 16 bit, meaning 214365 */
328 memcpy(hw_addr, nvm_hw + HW_ADDR, ETH_ALEN);
329 data->hw_addr[0] = hw_addr[1];
330 data->hw_addr[1] = hw_addr[0];
331 data->hw_addr[2] = hw_addr[3];
332 data->hw_addr[3] = hw_addr[2];
333 data->hw_addr[4] = hw_addr[5];
334 data->hw_addr[5] = hw_addr[4];
335
336 iwl_init_sbands(dev, cfg, data, nvm_sw);
337
338 data->calib_version = 255; /* TODO:
339 this value will prevent some checks from
340 failing, we need to check if this
341 field is still needed, and if it does,
342 where is it in the NVM*/
343
344 return data;
345}
346EXPORT_SYMBOL_GPL(iwl_parse_nvm_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
new file mode 100644
index 000000000000..b2692bd287fa
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -0,0 +1,80 @@
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) 2008 - 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 LICENSE.GPL.
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) 2005 - 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#ifndef __iwl_nvm_parse_h__
63#define __iwl_nvm_parse_h__
64
65#include "iwl-eeprom-parse.h"
66
67/**
68 * iwl_parse_nvm_data - parse NVM data and return values
69 *
70 * This function parses all NVM values we need and then
71 * returns a (newly allocated) struct containing all the
72 * relevant values for driver use. The struct must be freed
73 * later with iwl_free_nvm_data().
74 */
75struct iwl_nvm_data *
76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
77 const __le16 *nvm_hw, const __le16 *nvm_sw,
78 const __le16 *nvm_calib);
79
80#endif /* __iwl_nvm_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
index c8d9b9517468..dc792584f401 100644
--- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -63,6 +63,8 @@
63#ifndef __iwl_op_mode_h__ 63#ifndef __iwl_op_mode_h__
64#define __iwl_op_mode_h__ 64#define __iwl_op_mode_h__
65 65
66#include <linux/debugfs.h>
67
66struct iwl_op_mode; 68struct iwl_op_mode;
67struct iwl_trans; 69struct iwl_trans;
68struct sk_buff; 70struct sk_buff;
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
new file mode 100644
index 000000000000..14fc8d39fc28
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
@@ -0,0 +1,514 @@
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) 2007 - 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 LICENSE.GPL.
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) 2005 - 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/slab.h>
65#include <linux/string.h>
66#include <linux/export.h>
67
68#include "iwl-phy-db.h"
69#include "iwl-debug.h"
70#include "iwl-op-mode.h"
71#include "iwl-trans.h"
72
73#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */
74#define IWL_NUM_PAPD_CH_GROUPS 4
75#define IWL_NUM_TXP_CH_GROUPS 9
76
77struct iwl_phy_db_entry {
78 u16 size;
79 u8 *data;
80};
81
82/**
83 * struct iwl_phy_db - stores phy configuration and calibration data.
84 *
85 * @cfg: phy configuration.
86 * @calib_nch: non channel specific calibration data.
87 * @calib_ch: channel specific calibration data.
88 * @calib_ch_group_papd: calibration data related to papd channel group.
89 * @calib_ch_group_txp: calibration data related to tx power chanel group.
90 */
91struct iwl_phy_db {
92 struct iwl_phy_db_entry cfg;
93 struct iwl_phy_db_entry calib_nch;
94 struct iwl_phy_db_entry calib_ch;
95 struct iwl_phy_db_entry calib_ch_group_papd[IWL_NUM_PAPD_CH_GROUPS];
96 struct iwl_phy_db_entry calib_ch_group_txp[IWL_NUM_TXP_CH_GROUPS];
97
98 u32 channel_num;
99 u32 channel_size;
100
101 struct iwl_trans *trans;
102};
103
104enum iwl_phy_db_section_type {
105 IWL_PHY_DB_CFG = 1,
106 IWL_PHY_DB_CALIB_NCH,
107 IWL_PHY_DB_CALIB_CH,
108 IWL_PHY_DB_CALIB_CHG_PAPD,
109 IWL_PHY_DB_CALIB_CHG_TXP,
110 IWL_PHY_DB_MAX
111};
112
113#define PHY_DB_CMD 0x6c /* TEMP API - The actual is 0x8c */
114
115/*
116 * phy db - configure operational ucode
117 */
118struct iwl_phy_db_cmd {
119 __le16 type;
120 __le16 length;
121 u8 data[];
122} __packed;
123
124/* for parsing of tx power channel group data that comes from the firmware*/
125struct iwl_phy_db_chg_txp {
126 __le32 space;
127 __le16 max_channel_idx;
128} __packed;
129
130/*
131 * phy db - Receieve phy db chunk after calibrations
132 */
133struct iwl_calib_res_notif_phy_db {
134 __le16 type;
135 __le16 length;
136 u8 data[];
137} __packed;
138
139#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587)
140static inline void iwl_phy_db_test_pic(__le32 pic)
141{
142 WARN_ON(IWL_PHY_DB_STATIC_PIC != pic);
143}
144
145struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans)
146{
147 struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),
148 GFP_KERNEL);
149
150 if (!phy_db)
151 return phy_db;
152
153 phy_db->trans = trans;
154
155 /* TODO: add default values of the phy db. */
156 return phy_db;
157}
158EXPORT_SYMBOL(iwl_phy_db_init);
159
160/*
161 * get phy db section: returns a pointer to a phy db section specified by
162 * type and channel group id.
163 */
164static struct iwl_phy_db_entry *
165iwl_phy_db_get_section(struct iwl_phy_db *phy_db,
166 enum iwl_phy_db_section_type type,
167 u16 chg_id)
168{
169 if (!phy_db || type >= IWL_PHY_DB_MAX)
170 return NULL;
171
172 switch (type) {
173 case IWL_PHY_DB_CFG:
174 return &phy_db->cfg;
175 case IWL_PHY_DB_CALIB_NCH:
176 return &phy_db->calib_nch;
177 case IWL_PHY_DB_CALIB_CH:
178 return &phy_db->calib_ch;
179 case IWL_PHY_DB_CALIB_CHG_PAPD:
180 if (chg_id >= IWL_NUM_PAPD_CH_GROUPS)
181 return NULL;
182 return &phy_db->calib_ch_group_papd[chg_id];
183 case IWL_PHY_DB_CALIB_CHG_TXP:
184 if (chg_id >= IWL_NUM_TXP_CH_GROUPS)
185 return NULL;
186 return &phy_db->calib_ch_group_txp[chg_id];
187 default:
188 return NULL;
189 }
190 return NULL;
191}
192
193static void iwl_phy_db_free_section(struct iwl_phy_db *phy_db,
194 enum iwl_phy_db_section_type type,
195 u16 chg_id)
196{
197 struct iwl_phy_db_entry *entry =
198 iwl_phy_db_get_section(phy_db, type, chg_id);
199 if (!entry)
200 return;
201
202 kfree(entry->data);
203 entry->data = NULL;
204 entry->size = 0;
205}
206
207void iwl_phy_db_free(struct iwl_phy_db *phy_db)
208{
209 int i;
210
211 if (!phy_db)
212 return;
213
214 iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CFG, 0);
215 iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_NCH, 0);
216 iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CH, 0);
217 for (i = 0; i < IWL_NUM_PAPD_CH_GROUPS; i++)
218 iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_PAPD, i);
219 for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++)
220 iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_TXP, i);
221
222 kfree(phy_db);
223}
224EXPORT_SYMBOL(iwl_phy_db_free);
225
226int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
227 gfp_t alloc_ctx)
228{
229 struct iwl_calib_res_notif_phy_db *phy_db_notif =
230 (struct iwl_calib_res_notif_phy_db *)pkt->data;
231 enum iwl_phy_db_section_type type = le16_to_cpu(phy_db_notif->type);
232 u16 size = le16_to_cpu(phy_db_notif->length);
233 struct iwl_phy_db_entry *entry;
234 u16 chg_id = 0;
235
236 if (!phy_db)
237 return -EINVAL;
238
239 if (type == IWL_PHY_DB_CALIB_CHG_PAPD ||
240 type == IWL_PHY_DB_CALIB_CHG_TXP)
241 chg_id = le16_to_cpup((__le16 *)phy_db_notif->data);
242
243 entry = iwl_phy_db_get_section(phy_db, type, chg_id);
244 if (!entry)
245 return -EINVAL;
246
247 kfree(entry->data);
248 entry->data = kmemdup(phy_db_notif->data, size, alloc_ctx);
249 if (!entry->data) {
250 entry->size = 0;
251 return -ENOMEM;
252 }
253
254 entry->size = size;
255
256 if (type == IWL_PHY_DB_CALIB_CH) {
257 phy_db->channel_num =
258 le32_to_cpup((__le32 *)phy_db_notif->data);
259 phy_db->channel_size =
260 (size - CHANNEL_NUM_SIZE) / phy_db->channel_num;
261 }
262
263 /* Test PIC */
264 if (type != IWL_PHY_DB_CFG)
265 iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) +
266 (size / sizeof(__le32)) - 1));
267
268 IWL_DEBUG_INFO(phy_db->trans,
269 "%s(%d): [PHYDB]SET: Type %d , Size: %d\n",
270 __func__, __LINE__, type, size);
271
272 return 0;
273}
274EXPORT_SYMBOL(iwl_phy_db_set_section);
275
276static int is_valid_channel(u16 ch_id)
277{
278 if (ch_id <= 14 ||
279 (36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) ||
280 (100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) ||
281 (145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1))
282 return 1;
283 return 0;
284}
285
286static u8 ch_id_to_ch_index(u16 ch_id)
287{
288 if (WARN_ON(!is_valid_channel(ch_id)))
289 return 0xff;
290
291 if (ch_id <= 14)
292 return ch_id - 1;
293 if (ch_id <= 64)
294 return (ch_id + 20) / 4;
295 if (ch_id <= 140)
296 return (ch_id - 12) / 4;
297 return (ch_id - 13) / 4;
298}
299
300
301static u16 channel_id_to_papd(u16 ch_id)
302{
303 if (WARN_ON(!is_valid_channel(ch_id)))
304 return 0xff;
305
306 if (1 <= ch_id && ch_id <= 14)
307 return 0;
308 if (36 <= ch_id && ch_id <= 64)
309 return 1;
310 if (100 <= ch_id && ch_id <= 140)
311 return 2;
312 return 3;
313}
314
315static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id)
316{
317 struct iwl_phy_db_chg_txp *txp_chg;
318 int i;
319 u8 ch_index = ch_id_to_ch_index(ch_id);
320 if (ch_index == 0xff)
321 return 0xff;
322
323 for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) {
324 txp_chg = (void *)phy_db->calib_ch_group_txp[i].data;
325 if (!txp_chg)
326 return 0xff;
327 /*
328 * Looking for the first channel group that its max channel is
329 * higher then wanted channel.
330 */
331 if (le16_to_cpu(txp_chg->max_channel_idx) >= ch_index)
332 return i;
333 }
334 return 0xff;
335}
336static
337int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
338 u32 type, u8 **data, u16 *size, u16 ch_id)
339{
340 struct iwl_phy_db_entry *entry;
341 u32 channel_num;
342 u32 channel_size;
343 u16 ch_group_id = 0;
344 u16 index;
345
346 if (!phy_db)
347 return -EINVAL;
348
349 /* find wanted channel group */
350 if (type == IWL_PHY_DB_CALIB_CHG_PAPD)
351 ch_group_id = channel_id_to_papd(ch_id);
352 else if (type == IWL_PHY_DB_CALIB_CHG_TXP)
353 ch_group_id = channel_id_to_txp(phy_db, ch_id);
354
355 entry = iwl_phy_db_get_section(phy_db, type, ch_group_id);
356 if (!entry)
357 return -EINVAL;
358
359 if (type == IWL_PHY_DB_CALIB_CH) {
360 index = ch_id_to_ch_index(ch_id);
361 channel_num = phy_db->channel_num;
362 channel_size = phy_db->channel_size;
363 if (index >= channel_num) {
364 IWL_ERR(phy_db->trans, "Wrong channel number %d\n",
365 ch_id);
366 return -EINVAL;
367 }
368 *data = entry->data + CHANNEL_NUM_SIZE + index * channel_size;
369 *size = channel_size;
370 } else {
371 *data = entry->data;
372 *size = entry->size;
373 }
374
375 /* Test PIC */
376 if (type != IWL_PHY_DB_CFG)
377 iwl_phy_db_test_pic(*(((__le32 *)*data) +
378 (*size / sizeof(__le32)) - 1));
379
380 IWL_DEBUG_INFO(phy_db->trans,
381 "%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
382 __func__, __LINE__, type, *size);
383
384 return 0;
385}
386
387static int iwl_send_phy_db_cmd(struct iwl_phy_db *phy_db, u16 type,
388 u16 length, void *data)
389{
390 struct iwl_phy_db_cmd phy_db_cmd;
391 struct iwl_host_cmd cmd = {
392 .id = PHY_DB_CMD,
393 .flags = CMD_SYNC,
394 };
395
396 IWL_DEBUG_INFO(phy_db->trans,
397 "Sending PHY-DB hcmd of type %d, of length %d\n",
398 type, length);
399
400 /* Set phy db cmd variables */
401 phy_db_cmd.type = cpu_to_le16(type);
402 phy_db_cmd.length = cpu_to_le16(length);
403
404 /* Set hcmd variables */
405 cmd.data[0] = &phy_db_cmd;
406 cmd.len[0] = sizeof(struct iwl_phy_db_cmd);
407 cmd.data[1] = data;
408 cmd.len[1] = length;
409 cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY;
410
411 return iwl_trans_send_cmd(phy_db->trans, &cmd);
412}
413
414static int iwl_phy_db_send_all_channel_groups(
415 struct iwl_phy_db *phy_db,
416 enum iwl_phy_db_section_type type,
417 u8 max_ch_groups)
418{
419 u16 i;
420 int err;
421 struct iwl_phy_db_entry *entry;
422
423 /* Send all the channel specific groups to operational fw */
424 for (i = 0; i < max_ch_groups; i++) {
425 entry = iwl_phy_db_get_section(phy_db,
426 type,
427 i);
428 if (!entry)
429 return -EINVAL;
430
431 /* Send the requested PHY DB section */
432 err = iwl_send_phy_db_cmd(phy_db,
433 type,
434 entry->size,
435 entry->data);
436 if (err) {
437 IWL_ERR(phy_db->trans,
438 "Can't SEND phy_db section %d (%d), err %d",
439 type, i, err);
440 return err;
441 }
442
443 IWL_DEBUG_INFO(phy_db->trans,
444 "Sent PHY_DB HCMD, type = %d num = %d",
445 type, i);
446 }
447
448 return 0;
449}
450
451int iwl_send_phy_db_data(struct iwl_phy_db *phy_db)
452{
453 u8 *data = NULL;
454 u16 size = 0;
455 int err;
456
457 IWL_DEBUG_INFO(phy_db->trans,
458 "Sending phy db data and configuration to runtime image\n");
459
460 /* Send PHY DB CFG section */
461 err = iwl_phy_db_get_section_data(phy_db, IWL_PHY_DB_CFG,
462 &data, &size, 0);
463 if (err) {
464 IWL_ERR(phy_db->trans, "Cannot get Phy DB cfg section\n");
465 return err;
466 }
467
468 err = iwl_send_phy_db_cmd(phy_db, IWL_PHY_DB_CFG, size, data);
469 if (err) {
470 IWL_ERR(phy_db->trans,
471 "Cannot send HCMD of Phy DB cfg section\n");
472 return err;
473 }
474
475 err = iwl_phy_db_get_section_data(phy_db, IWL_PHY_DB_CALIB_NCH,
476 &data, &size, 0);
477 if (err) {
478 IWL_ERR(phy_db->trans,
479 "Cannot get Phy DB non specific channel section\n");
480 return err;
481 }
482
483 err = iwl_send_phy_db_cmd(phy_db, IWL_PHY_DB_CALIB_NCH, size, data);
484 if (err) {
485 IWL_ERR(phy_db->trans,
486 "Cannot send HCMD of Phy DB non specific channel section\n");
487 return err;
488 }
489
490 /* Send all the TXP channel specific data */
491 err = iwl_phy_db_send_all_channel_groups(phy_db,
492 IWL_PHY_DB_CALIB_CHG_PAPD,
493 IWL_NUM_PAPD_CH_GROUPS);
494 if (err) {
495 IWL_ERR(phy_db->trans,
496 "Cannot send channel specific PAPD groups");
497 return err;
498 }
499
500 /* Send all the TXP channel specific data */
501 err = iwl_phy_db_send_all_channel_groups(phy_db,
502 IWL_PHY_DB_CALIB_CHG_TXP,
503 IWL_NUM_TXP_CH_GROUPS);
504 if (err) {
505 IWL_ERR(phy_db->trans,
506 "Cannot send channel specific TX power groups");
507 return err;
508 }
509
510 IWL_DEBUG_INFO(phy_db->trans,
511 "Finished sending phy db non channel data\n");
512 return 0;
513}
514EXPORT_SYMBOL(iwl_send_phy_db_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
new file mode 100644
index 000000000000..d0e43d96ab38
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
@@ -0,0 +1,82 @@
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) 2007 - 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 LICENSE.GPL.
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) 2005 - 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#ifndef __IWL_PHYDB_H__
65#define __IWL_PHYDB_H__
66
67#include <linux/types.h>
68
69#include "iwl-op-mode.h"
70#include "iwl-trans.h"
71
72struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans);
73
74void iwl_phy_db_free(struct iwl_phy_db *phy_db);
75
76int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
77 gfp_t alloc_ctx);
78
79
80int iwl_send_phy_db_data(struct iwl_phy_db *phy_db);
81
82#endif /* __IWL_PHYDB_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index c3a4bb41e533..f76e9cad7757 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -97,6 +97,9 @@
97 97
98#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) 98#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
99 99
100/* Device system time */
101#define DEVICE_SYSTEM_TIME_REG 0xA0206C
102
100/** 103/**
101 * Tx Scheduler 104 * Tx Scheduler
102 * 105 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c
index 1a226114fe73..ce0c67b425ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-test.c
+++ b/drivers/net/wireless/iwlwifi/iwl-test.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -466,9 +466,7 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size)
466 /* Hard-coded periphery absolute address */ 466 /* Hard-coded periphery absolute address */
467 if (IWL_ABS_PRPH_START <= addr && 467 if (IWL_ABS_PRPH_START <= addr &&
468 addr < IWL_ABS_PRPH_START + PRPH_END) { 468 addr < IWL_ABS_PRPH_START + PRPH_END) {
469 spin_lock_irqsave(&trans->reg_lock, flags); 469 if (!iwl_trans_grab_nic_access(trans, false, &flags)) {
470 if (!iwl_trans_grab_nic_access(trans, false)) {
471 spin_unlock_irqrestore(&trans->reg_lock, flags);
472 return -EIO; 470 return -EIO;
473 } 471 }
474 iwl_write32(trans, HBUS_TARG_PRPH_RADDR, 472 iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
@@ -476,8 +474,7 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size)
476 for (i = 0; i < size; i += 4) 474 for (i = 0; i < size; i += 4)
477 *(u32 *)(tst->mem.addr + i) = 475 *(u32 *)(tst->mem.addr + i) =
478 iwl_read32(trans, HBUS_TARG_PRPH_RDAT); 476 iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
479 iwl_trans_release_nic_access(trans); 477 iwl_trans_release_nic_access(trans, &flags);
480 spin_unlock_irqrestore(&trans->reg_lock, flags);
481 } else { /* target memory (SRAM) */ 478 } else { /* target memory (SRAM) */
482 iwl_trans_read_mem(trans, addr, tst->mem.addr, 479 iwl_trans_read_mem(trans, addr, tst->mem.addr,
483 tst->mem.size / 4); 480 tst->mem.size / 4);
@@ -506,19 +503,13 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr,
506 /* Periphery writes can be 1-3 bytes long, or DWORDs */ 503 /* Periphery writes can be 1-3 bytes long, or DWORDs */
507 if (size < 4) { 504 if (size < 4) {
508 memcpy(&val, buf, size); 505 memcpy(&val, buf, size);
509 spin_lock_irqsave(&trans->reg_lock, flags); 506 if (!iwl_trans_grab_nic_access(trans, false, &flags))
510 if (!iwl_trans_grab_nic_access(trans, false)) {
511 spin_unlock_irqrestore(&trans->reg_lock, flags);
512 return -EIO; 507 return -EIO;
513 }
514 iwl_write32(trans, HBUS_TARG_PRPH_WADDR, 508 iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
515 (addr & 0x0000FFFF) | 509 (addr & 0x0000FFFF) |
516 ((size - 1) << 24)); 510 ((size - 1) << 24));
517 iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); 511 iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
518 iwl_trans_release_nic_access(trans); 512 iwl_trans_release_nic_access(trans, &flags);
519 /* needed after consecutive writes w/o read */
520 mmiowb();
521 spin_unlock_irqrestore(&trans->reg_lock, flags);
522 } else { 513 } else {
523 if (size % 4) 514 if (size % 4)
524 return -EINVAL; 515 return -EINVAL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h
index e13ffa8acc02..7fbf4d717caa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-test.h
+++ b/drivers/net/wireless/iwlwifi/iwl-test.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
index 6ba211b09426..a963f45c6849 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 0f85eb305878..0a3d4df5f434 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -193,11 +193,11 @@ struct iwl_rx_packet {
193 * @CMD_ON_DEMAND: This command is sent by the test mode pipe. 193 * @CMD_ON_DEMAND: This command is sent by the test mode pipe.
194 */ 194 */
195enum CMD_MODE { 195enum CMD_MODE {
196 CMD_SYNC = 0, 196 CMD_SYNC = 0,
197 CMD_ASYNC = BIT(0), 197 CMD_ASYNC = BIT(0),
198 CMD_WANT_SKB = BIT(1), 198 CMD_WANT_SKB = BIT(1),
199 CMD_WANT_HCMD = BIT(2), 199 CMD_WANT_HCMD = BIT(2),
200 CMD_ON_DEMAND = BIT(3), 200 CMD_ON_DEMAND = BIT(3),
201}; 201};
202 202
203#define DEF_CMD_PAYLOAD_SIZE 320 203#define DEF_CMD_PAYLOAD_SIZE 320
@@ -274,6 +274,7 @@ struct iwl_rx_cmd_buffer {
274 struct page *_page; 274 struct page *_page;
275 int _offset; 275 int _offset;
276 bool _page_stolen; 276 bool _page_stolen;
277 u32 _rx_page_order;
277 unsigned int truesize; 278 unsigned int truesize;
278}; 279};
279 280
@@ -294,6 +295,11 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
294 return r->_page; 295 return r->_page;
295} 296}
296 297
298static inline void iwl_free_rxb(struct iwl_rx_cmd_buffer *r)
299{
300 __free_pages(r->_page, r->_rx_page_order);
301}
302
297#define MAX_NO_RECLAIM_CMDS 6 303#define MAX_NO_RECLAIM_CMDS 6
298 304
299#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) 305#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
@@ -410,8 +416,12 @@ struct iwl_trans;
410 * the op_mode. May be called several times before start_fw, can't be 416 * the op_mode. May be called several times before start_fw, can't be
411 * called after that. 417 * called after that.
412 * @set_pmi: set the power pmi state 418 * @set_pmi: set the power pmi state
413 * @grab_nic_access: wake the NIC to be able to access non-HBUS regs 419 * @grab_nic_access: wake the NIC to be able to access non-HBUS regs.
414 * @release_nic_access: let the NIC go to sleep 420 * Sleeping is not allowed between grab_nic_access and
421 * release_nic_access.
422 * @release_nic_access: let the NIC go to sleep. The "flags" parameter
423 * must be the same one that was sent before to the grab_nic_access.
424 * @set_bits_mask - set SRAM register according to value and mask.
415 */ 425 */
416struct iwl_trans_ops { 426struct iwl_trans_ops {
417 427
@@ -454,8 +464,12 @@ struct iwl_trans_ops {
454 void (*configure)(struct iwl_trans *trans, 464 void (*configure)(struct iwl_trans *trans,
455 const struct iwl_trans_config *trans_cfg); 465 const struct iwl_trans_config *trans_cfg);
456 void (*set_pmi)(struct iwl_trans *trans, bool state); 466 void (*set_pmi)(struct iwl_trans *trans, bool state);
457 bool (*grab_nic_access)(struct iwl_trans *trans, bool silent); 467 bool (*grab_nic_access)(struct iwl_trans *trans, bool silent,
458 void (*release_nic_access)(struct iwl_trans *trans); 468 unsigned long *flags);
469 void (*release_nic_access)(struct iwl_trans *trans,
470 unsigned long *flags);
471 void (*set_bits_mask)(struct iwl_trans *trans, u32 reg, u32 mask,
472 u32 value);
459}; 473};
460 474
461/** 475/**
@@ -475,7 +489,6 @@ enum iwl_trans_state {
475 * @ops - pointer to iwl_trans_ops 489 * @ops - pointer to iwl_trans_ops
476 * @op_mode - pointer to the op_mode 490 * @op_mode - pointer to the op_mode
477 * @cfg - pointer to the configuration 491 * @cfg - pointer to the configuration
478 * @reg_lock - protect hw register access
479 * @dev - pointer to struct device * that represents the device 492 * @dev - pointer to struct device * that represents the device
480 * @hw_id: a u32 with the ID of the device / subdevice. 493 * @hw_id: a u32 with the ID of the device / subdevice.
481 * Set during transport allocation. 494 * Set during transport allocation.
@@ -496,7 +509,6 @@ struct iwl_trans {
496 struct iwl_op_mode *op_mode; 509 struct iwl_op_mode *op_mode;
497 const struct iwl_cfg *cfg; 510 const struct iwl_cfg *cfg;
498 enum iwl_trans_state state; 511 enum iwl_trans_state state;
499 spinlock_t reg_lock;
500 512
501 struct device *dev; 513 struct device *dev;
502 u32 hw_rev; 514 u32 hw_rev;
@@ -756,14 +768,20 @@ static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state)
756 trans->ops->set_pmi(trans, state); 768 trans->ops->set_pmi(trans, state);
757} 769}
758 770
759#define iwl_trans_grab_nic_access(trans, silent) \ 771static inline void
772iwl_trans_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value)
773{
774 trans->ops->set_bits_mask(trans, reg, mask, value);
775}
776
777#define iwl_trans_grab_nic_access(trans, silent, flags) \
760 __cond_lock(nic_access, \ 778 __cond_lock(nic_access, \
761 likely((trans)->ops->grab_nic_access(trans, silent))) 779 likely((trans)->ops->grab_nic_access(trans, silent, flags)))
762 780
763static inline void __releases(nic_access) 781static inline void __releases(nic_access)
764iwl_trans_release_nic_access(struct iwl_trans *trans) 782iwl_trans_release_nic_access(struct iwl_trans *trans, unsigned long *flags)
765{ 783{
766 trans->ops->release_nic_access(trans); 784 trans->ops->release_nic_access(trans, flags);
767 __release(nic_access); 785 __release(nic_access);
768} 786}
769 787
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
new file mode 100644
index 000000000000..807b250ec396
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -0,0 +1,10 @@
1obj-$(CONFIG_IWLMVM) += iwlmvm.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
4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o
6iwlmvm-y += led.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
9
10ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c
new file mode 100644
index 000000000000..73d24aacb90a
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/binding.c
@@ -0,0 +1,197 @@
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 LICENSE.GPL.
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 <net/mac80211.h>
65#include "fw-api.h"
66#include "mvm.h"
67
68struct iwl_mvm_iface_iterator_data {
69 struct ieee80211_vif *ignore_vif;
70 int idx;
71
72 struct iwl_mvm_phy_ctxt *phyctxt;
73
74 u16 ids[MAX_MACS_IN_BINDING];
75 u16 colors[MAX_MACS_IN_BINDING];
76};
77
78static int iwl_mvm_binding_cmd(struct iwl_mvm *mvm, u32 action,
79 struct iwl_mvm_iface_iterator_data *data)
80{
81 struct iwl_binding_cmd cmd;
82 struct iwl_mvm_phy_ctxt *phyctxt = data->phyctxt;
83 int i, ret;
84 u32 status;
85
86 memset(&cmd, 0, sizeof(cmd));
87
88 cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(phyctxt->id,
89 phyctxt->color));
90 cmd.action = cpu_to_le32(action);
91 cmd.phy = cpu_to_le32(FW_CMD_ID_AND_COLOR(phyctxt->id,
92 phyctxt->color));
93
94 for (i = 0; i < MAX_MACS_IN_BINDING; i++)
95 cmd.macs[i] = cpu_to_le32(FW_CTXT_INVALID);
96 for (i = 0; i < data->idx; i++)
97 cmd.macs[i] = cpu_to_le32(FW_CMD_ID_AND_COLOR(data->ids[i],
98 data->colors[i]));
99
100 status = 0;
101 ret = iwl_mvm_send_cmd_pdu_status(mvm, BINDING_CONTEXT_CMD,
102 sizeof(cmd), &cmd, &status);
103 if (ret) {
104 IWL_ERR(mvm, "Failed to send binding (action:%d): %d\n",
105 action, ret);
106 return ret;
107 }
108
109 if (status) {
110 IWL_ERR(mvm, "Binding command failed: %u\n", status);
111 ret = -EIO;
112 }
113
114 return ret;
115}
116
117static void iwl_mvm_iface_iterator(void *_data, u8 *mac,
118 struct ieee80211_vif *vif)
119{
120 struct iwl_mvm_iface_iterator_data *data = _data;
121 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
122
123 if (vif == data->ignore_vif)
124 return;
125
126 if (mvmvif->phy_ctxt != data->phyctxt)
127 return;
128
129 if (WARN_ON_ONCE(data->idx >= MAX_MACS_IN_BINDING))
130 return;
131
132 data->ids[data->idx] = mvmvif->id;
133 data->colors[data->idx] = mvmvif->color;
134 data->idx++;
135}
136
137static int iwl_mvm_binding_update(struct iwl_mvm *mvm,
138 struct ieee80211_vif *vif,
139 struct iwl_mvm_phy_ctxt *phyctxt,
140 bool add)
141{
142 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
143 struct iwl_mvm_iface_iterator_data data = {
144 .ignore_vif = vif,
145 .phyctxt = phyctxt,
146 };
147 u32 action = FW_CTXT_ACTION_MODIFY;
148
149 lockdep_assert_held(&mvm->mutex);
150
151 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
152 IEEE80211_IFACE_ITER_NORMAL,
153 iwl_mvm_iface_iterator,
154 &data);
155
156 /*
157 * If there are no other interfaces yet we
158 * need to create a new binding.
159 */
160 if (data.idx == 0) {
161 if (add)
162 action = FW_CTXT_ACTION_ADD;
163 else
164 action = FW_CTXT_ACTION_REMOVE;
165 }
166
167 if (add) {
168 if (WARN_ON_ONCE(data.idx >= MAX_MACS_IN_BINDING))
169 return -EINVAL;
170
171 data.ids[data.idx] = mvmvif->id;
172 data.colors[data.idx] = mvmvif->color;
173 data.idx++;
174 }
175
176 return iwl_mvm_binding_cmd(mvm, action, &data);
177}
178
179int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
180{
181 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
182
183 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
184 return -EINVAL;
185
186 return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, true);
187}
188
189int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
190{
191 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
192
193 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
194 return -EINVAL;
195
196 return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, false);
197}
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
new file mode 100644
index 000000000000..9a95c374990d
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -0,0 +1,841 @@
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 LICENSE.GPL.
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 <net/cfg80211.h>
65#include <net/ipv6.h>
66#include "iwl-modparams.h"
67#include "fw-api.h"
68#include "mvm.h"
69
70void iwl_mvm_set_rekey_data(struct ieee80211_hw *hw,
71 struct ieee80211_vif *vif,
72 struct cfg80211_gtk_rekey_data *data)
73{
74 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
75 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
76
77 if (iwlwifi_mod_params.sw_crypto)
78 return;
79
80 mutex_lock(&mvm->mutex);
81
82 memcpy(mvmvif->rekey_data.kek, data->kek, NL80211_KEK_LEN);
83 memcpy(mvmvif->rekey_data.kck, data->kck, NL80211_KCK_LEN);
84 mvmvif->rekey_data.replay_ctr =
85 cpu_to_le64(be64_to_cpup((__be64 *)&data->replay_ctr));
86 mvmvif->rekey_data.valid = true;
87
88 mutex_unlock(&mvm->mutex);
89}
90
91#if IS_ENABLED(CONFIG_IPV6)
92void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
93 struct ieee80211_vif *vif,
94 struct inet6_dev *idev)
95{
96 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
97 struct inet6_ifaddr *ifa;
98 int idx = 0;
99
100 read_lock(&idev->lock);
101 list_for_each_entry(ifa, &idev->addr_list, if_list) {
102 mvmvif->target_ipv6_addrs[idx] = ifa->addr;
103 idx++;
104 if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS)
105 break;
106 }
107 read_unlock(&idev->lock);
108
109 mvmvif->num_target_ipv6_addrs = idx;
110}
111#endif
112
113void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
114 struct ieee80211_vif *vif, int idx)
115{
116 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
117
118 mvmvif->tx_key_idx = idx;
119}
120
121static void iwl_mvm_convert_p1k(u16 *p1k, __le16 *out)
122{
123 int i;
124
125 for (i = 0; i < IWL_P1K_SIZE; i++)
126 out[i] = cpu_to_le16(p1k[i]);
127}
128
129struct wowlan_key_data {
130 struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc;
131 struct iwl_wowlan_tkip_params_cmd *tkip;
132 bool error, use_rsc_tsc, use_tkip;
133 int gtk_key_idx;
134};
135
136static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
137 struct ieee80211_vif *vif,
138 struct ieee80211_sta *sta,
139 struct ieee80211_key_conf *key,
140 void *_data)
141{
142 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
143 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
144 struct wowlan_key_data *data = _data;
145 struct aes_sc *aes_sc, *aes_tx_sc = NULL;
146 struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
147 struct iwl_p1k_cache *rx_p1ks;
148 u8 *rx_mic_key;
149 struct ieee80211_key_seq seq;
150 u32 cur_rx_iv32 = 0;
151 u16 p1k[IWL_P1K_SIZE];
152 int ret, i;
153
154 mutex_lock(&mvm->mutex);
155
156 switch (key->cipher) {
157 case WLAN_CIPHER_SUITE_WEP40:
158 case WLAN_CIPHER_SUITE_WEP104: { /* hack it for now */
159 struct {
160 struct iwl_mvm_wep_key_cmd wep_key_cmd;
161 struct iwl_mvm_wep_key wep_key;
162 } __packed wkc = {
163 .wep_key_cmd.mac_id_n_color =
164 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
165 mvmvif->color)),
166 .wep_key_cmd.num_keys = 1,
167 /* firmware sets STA_KEY_FLG_WEP_13BYTES */
168 .wep_key_cmd.decryption_type = STA_KEY_FLG_WEP,
169 .wep_key.key_index = key->keyidx,
170 .wep_key.key_size = key->keylen,
171 };
172
173 /*
174 * This will fail -- the key functions don't set support
175 * pairwise WEP keys. However, that's better than silently
176 * failing WoWLAN. Or maybe not?
177 */
178 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
179 break;
180
181 memcpy(&wkc.wep_key.key[3], key->key, key->keylen);
182 if (key->keyidx == mvmvif->tx_key_idx) {
183 /* TX key must be at offset 0 */
184 wkc.wep_key.key_offset = 0;
185 } else {
186 /* others start at 1 */
187 data->gtk_key_idx++;
188 wkc.wep_key.key_offset = data->gtk_key_idx;
189 }
190
191 ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, CMD_SYNC,
192 sizeof(wkc), &wkc);
193 data->error = ret != 0;
194
195 /* don't upload key again */
196 goto out_unlock;
197 }
198 default:
199 data->error = true;
200 goto out_unlock;
201 case WLAN_CIPHER_SUITE_AES_CMAC:
202 /*
203 * Ignore CMAC keys -- the WoWLAN firmware doesn't support them
204 * but we also shouldn't abort suspend due to that. It does have
205 * support for the IGTK key renewal, but doesn't really use the
206 * IGTK for anything. This means we could spuriously wake up or
207 * be deauthenticated, but that was considered acceptable.
208 */
209 goto out_unlock;
210 case WLAN_CIPHER_SUITE_TKIP:
211 if (sta) {
212 tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc;
213 tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc;
214
215 rx_p1ks = data->tkip->rx_uni;
216
217 ieee80211_get_key_tx_seq(key, &seq);
218 tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16);
219 tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32);
220
221 ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k);
222 iwl_mvm_convert_p1k(p1k, data->tkip->tx.p1k);
223
224 memcpy(data->tkip->mic_keys.tx,
225 &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
226 IWL_MIC_KEY_SIZE);
227
228 rx_mic_key = data->tkip->mic_keys.rx_unicast;
229 } else {
230 tkip_sc =
231 data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc;
232 rx_p1ks = data->tkip->rx_multi;
233 rx_mic_key = data->tkip->mic_keys.rx_mcast;
234 }
235
236 /*
237 * For non-QoS this relies on the fact that both the uCode and
238 * mac80211 use TID 0 (as they need to to avoid replay attacks)
239 * for checking the IV in the frames.
240 */
241 for (i = 0; i < IWL_NUM_RSC; i++) {
242 ieee80211_get_key_rx_seq(key, i, &seq);
243 tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16);
244 tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);
245 /* wrapping isn't allowed, AP must rekey */
246 if (seq.tkip.iv32 > cur_rx_iv32)
247 cur_rx_iv32 = seq.tkip.iv32;
248 }
249
250 ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
251 cur_rx_iv32, p1k);
252 iwl_mvm_convert_p1k(p1k, rx_p1ks[0].p1k);
253 ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
254 cur_rx_iv32 + 1, p1k);
255 iwl_mvm_convert_p1k(p1k, rx_p1ks[1].p1k);
256
257 memcpy(rx_mic_key,
258 &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
259 IWL_MIC_KEY_SIZE);
260
261 data->use_tkip = true;
262 data->use_rsc_tsc = true;
263 break;
264 case WLAN_CIPHER_SUITE_CCMP:
265 if (sta) {
266 u8 *pn = seq.ccmp.pn;
267
268 aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;
269 aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc;
270
271 ieee80211_get_key_tx_seq(key, &seq);
272 aes_tx_sc->pn = cpu_to_le64((u64)pn[5] |
273 ((u64)pn[4] << 8) |
274 ((u64)pn[3] << 16) |
275 ((u64)pn[2] << 24) |
276 ((u64)pn[1] << 32) |
277 ((u64)pn[0] << 40));
278 } else {
279 aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;
280 }
281
282 /*
283 * For non-QoS this relies on the fact that both the uCode and
284 * mac80211 use TID 0 for checking the IV in the frames.
285 */
286 for (i = 0; i < IWL_NUM_RSC; i++) {
287 u8 *pn = seq.ccmp.pn;
288
289 ieee80211_get_key_rx_seq(key, i, &seq);
290 aes_sc->pn = cpu_to_le64((u64)pn[5] |
291 ((u64)pn[4] << 8) |
292 ((u64)pn[3] << 16) |
293 ((u64)pn[2] << 24) |
294 ((u64)pn[1] << 32) |
295 ((u64)pn[0] << 40));
296 }
297 data->use_rsc_tsc = true;
298 break;
299 }
300
301 /*
302 * The D3 firmware hardcodes the key offset 0 as the key it uses
303 * to transmit packets to the AP, i.e. the PTK.
304 */
305 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
306 key->hw_key_idx = 0;
307 } else {
308 data->gtk_key_idx++;
309 key->hw_key_idx = data->gtk_key_idx;
310 }
311
312 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true);
313 data->error = ret != 0;
314out_unlock:
315 mutex_unlock(&mvm->mutex);
316}
317
318static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
319 struct cfg80211_wowlan *wowlan)
320{
321 struct iwl_wowlan_patterns_cmd *pattern_cmd;
322 struct iwl_host_cmd cmd = {
323 .id = WOWLAN_PATTERNS,
324 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
325 .flags = CMD_SYNC,
326 };
327 int i, err;
328
329 if (!wowlan->n_patterns)
330 return 0;
331
332 cmd.len[0] = sizeof(*pattern_cmd) +
333 wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern);
334
335 pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);
336 if (!pattern_cmd)
337 return -ENOMEM;
338
339 pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns);
340
341 for (i = 0; i < wowlan->n_patterns; i++) {
342 int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
343
344 memcpy(&pattern_cmd->patterns[i].mask,
345 wowlan->patterns[i].mask, mask_len);
346 memcpy(&pattern_cmd->patterns[i].pattern,
347 wowlan->patterns[i].pattern,
348 wowlan->patterns[i].pattern_len);
349 pattern_cmd->patterns[i].mask_size = mask_len;
350 pattern_cmd->patterns[i].pattern_size =
351 wowlan->patterns[i].pattern_len;
352 }
353
354 cmd.data[0] = pattern_cmd;
355 err = iwl_mvm_send_cmd(mvm, &cmd);
356 kfree(pattern_cmd);
357 return err;
358}
359
360static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
361 struct ieee80211_vif *vif)
362{
363 struct iwl_proto_offload_cmd cmd = {};
364#if IS_ENABLED(CONFIG_IPV6)
365 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
366 int i;
367
368 if (mvmvif->num_target_ipv6_addrs) {
369 cmd.enabled |= cpu_to_le32(IWL_D3_PROTO_OFFLOAD_NS);
370 memcpy(cmd.ndp_mac_addr, vif->addr, ETH_ALEN);
371 }
372
373 BUILD_BUG_ON(sizeof(cmd.target_ipv6_addr[i]) !=
374 sizeof(mvmvif->target_ipv6_addrs[i]));
375
376 for (i = 0; i < mvmvif->num_target_ipv6_addrs; i++)
377 memcpy(cmd.target_ipv6_addr[i],
378 &mvmvif->target_ipv6_addrs[i],
379 sizeof(cmd.target_ipv6_addr[i]));
380#endif
381
382 if (vif->bss_conf.arp_addr_cnt) {
383 cmd.enabled |= cpu_to_le32(IWL_D3_PROTO_OFFLOAD_ARP);
384 cmd.host_ipv4_addr = vif->bss_conf.arp_addr_list[0];
385 memcpy(cmd.arp_mac_addr, vif->addr, ETH_ALEN);
386 }
387
388 if (!cmd.enabled)
389 return 0;
390
391 return iwl_mvm_send_cmd_pdu(mvm, PROT_OFFLOAD_CONFIG_CMD, CMD_SYNC,
392 sizeof(cmd), &cmd);
393}
394
395struct iwl_d3_iter_data {
396 struct iwl_mvm *mvm;
397 struct ieee80211_vif *vif;
398 bool error;
399};
400
401static void iwl_mvm_d3_iface_iterator(void *_data, u8 *mac,
402 struct ieee80211_vif *vif)
403{
404 struct iwl_d3_iter_data *data = _data;
405 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
406
407 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
408 return;
409
410 if (mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
411 return;
412
413 if (data->vif) {
414 IWL_ERR(data->mvm, "More than one managed interface active!\n");
415 data->error = true;
416 return;
417 }
418
419 data->vif = vif;
420}
421
422static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
423 struct ieee80211_sta *ap_sta)
424{
425 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
426 struct ieee80211_chanctx_conf *ctx;
427 u8 chains_static, chains_dynamic;
428 struct cfg80211_chan_def chandef;
429 int ret, i;
430 struct iwl_binding_cmd binding_cmd = {};
431 struct iwl_time_quota_cmd quota_cmd = {};
432 u32 status;
433
434 /* add back the PHY */
435 if (WARN_ON(!mvmvif->phy_ctxt))
436 return -EINVAL;
437
438 rcu_read_lock();
439 ctx = rcu_dereference(vif->chanctx_conf);
440 if (WARN_ON(!ctx)) {
441 rcu_read_unlock();
442 return -EINVAL;
443 }
444 chandef = ctx->def;
445 chains_static = ctx->rx_chains_static;
446 chains_dynamic = ctx->rx_chains_dynamic;
447 rcu_read_unlock();
448
449 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt, &chandef,
450 chains_static, chains_dynamic);
451 if (ret)
452 return ret;
453
454 /* add back the MAC */
455 mvmvif->uploaded = false;
456
457 if (WARN_ON(!vif->bss_conf.assoc))
458 return -EINVAL;
459 /* hack */
460 vif->bss_conf.assoc = false;
461 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
462 vif->bss_conf.assoc = true;
463 if (ret)
464 return ret;
465
466 /* add back binding - XXX refactor? */
467 binding_cmd.id_and_color =
468 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
469 mvmvif->phy_ctxt->color));
470 binding_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
471 binding_cmd.phy =
472 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
473 mvmvif->phy_ctxt->color));
474 binding_cmd.macs[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
475 mvmvif->color));
476 for (i = 1; i < MAX_MACS_IN_BINDING; i++)
477 binding_cmd.macs[i] = cpu_to_le32(FW_CTXT_INVALID);
478
479 status = 0;
480 ret = iwl_mvm_send_cmd_pdu_status(mvm, BINDING_CONTEXT_CMD,
481 sizeof(binding_cmd), &binding_cmd,
482 &status);
483 if (ret) {
484 IWL_ERR(mvm, "Failed to add binding: %d\n", ret);
485 return ret;
486 }
487
488 if (status) {
489 IWL_ERR(mvm, "Binding command failed: %u\n", status);
490 return -EIO;
491 }
492
493 ret = iwl_mvm_sta_add_to_fw(mvm, ap_sta);
494 if (ret)
495 return ret;
496 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);
497
498 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
499 if (ret)
500 return ret;
501
502 /* and some quota */
503 quota_cmd.quotas[0].id_and_color =
504 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
505 mvmvif->phy_ctxt->color));
506 quota_cmd.quotas[0].quota = cpu_to_le32(100);
507 quota_cmd.quotas[0].max_duration = cpu_to_le32(1000);
508
509 for (i = 1; i < MAX_BINDINGS; i++)
510 quota_cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
511
512 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC,
513 sizeof(quota_cmd), &quota_cmd);
514 if (ret)
515 IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
516
517 return 0;
518}
519
520int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
521{
522 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
523 struct iwl_d3_iter_data suspend_iter_data = {
524 .mvm = mvm,
525 };
526 struct ieee80211_vif *vif;
527 struct iwl_mvm_vif *mvmvif;
528 struct ieee80211_sta *ap_sta;
529 struct iwl_mvm_sta *mvm_ap_sta;
530 struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
531 struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
532 struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
533 struct iwl_d3_manager_config d3_cfg_cmd = {};
534 struct wowlan_key_data key_data = {
535 .use_rsc_tsc = false,
536 .tkip = &tkip_cmd,
537 .use_tkip = false,
538 };
539 int ret, i;
540 u16 seq;
541 u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT;
542
543 if (WARN_ON(!wowlan))
544 return -EINVAL;
545
546 key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL);
547 if (!key_data.rsc_tsc)
548 return -ENOMEM;
549
550 mutex_lock(&mvm->mutex);
551
552 old_aux_sta_id = mvm->aux_sta.sta_id;
553
554 /* see if there's only a single BSS vif and it's associated */
555 ieee80211_iterate_active_interfaces_atomic(
556 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
557 iwl_mvm_d3_iface_iterator, &suspend_iter_data);
558
559 if (suspend_iter_data.error || !suspend_iter_data.vif) {
560 ret = 1;
561 goto out_noreset;
562 }
563
564 vif = suspend_iter_data.vif;
565 mvmvif = iwl_mvm_vif_from_mac80211(vif);
566
567 ap_sta = rcu_dereference_protected(
568 mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
569 lockdep_is_held(&mvm->mutex));
570 if (IS_ERR_OR_NULL(ap_sta)) {
571 ret = -EINVAL;
572 goto out_noreset;
573 }
574
575 mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv;
576
577 /*
578 * The D3 firmware still hardcodes the AP station ID for the
579 * BSS we're associated with as 0. Store the real STA ID here
580 * and assign 0. When we leave this function, we'll restore
581 * the original value for the resume code.
582 */
583 old_ap_sta_id = mvm_ap_sta->sta_id;
584 mvm_ap_sta->sta_id = 0;
585 mvmvif->ap_sta_id = 0;
586
587 /* TODO: wowlan_config_cmd.wowlan_ba_teardown_tids */
588
589 wowlan_config_cmd.is_11n_connection = ap_sta->ht_cap.ht_supported;
590
591 /*
592 * We know the last used seqno, and the uCode expects to know that
593 * one, it will increment before TX.
594 */
595 seq = mvm_ap_sta->last_seq_ctl & IEEE80211_SCTL_SEQ;
596 wowlan_config_cmd.non_qos_seq = cpu_to_le16(seq);
597
598 /*
599 * For QoS counters, we store the one to use next, so subtract 0x10
600 * since the uCode will add 0x10 *before* using the value while we
601 * increment after using the value (i.e. store the next value to use).
602 */
603 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
604 seq = mvm_ap_sta->tid_data[i].seq_number;
605 seq -= 0x10;
606 wowlan_config_cmd.qos_seq[i] = cpu_to_le16(seq);
607 }
608
609 if (wowlan->disconnect)
610 wowlan_config_cmd.wakeup_filter |=
611 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
612 IWL_WOWLAN_WAKEUP_LINK_CHANGE);
613 if (wowlan->magic_pkt)
614 wowlan_config_cmd.wakeup_filter |=
615 cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET);
616 if (wowlan->gtk_rekey_failure)
617 wowlan_config_cmd.wakeup_filter |=
618 cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
619 if (wowlan->eap_identity_req)
620 wowlan_config_cmd.wakeup_filter |=
621 cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ);
622 if (wowlan->four_way_handshake)
623 wowlan_config_cmd.wakeup_filter |=
624 cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
625 if (wowlan->n_patterns)
626 wowlan_config_cmd.wakeup_filter |=
627 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
628
629 if (wowlan->rfkill_release)
630 d3_cfg_cmd.wakeup_flags |=
631 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
632
633 iwl_mvm_cancel_scan(mvm);
634
635 iwl_trans_stop_device(mvm->trans);
636
637 /*
638 * Set the HW restart bit -- this is mostly true as we're
639 * going to load new firmware and reprogram that, though
640 * the reprogramming is going to be manual to avoid adding
641 * all the MACs that aren't support.
642 * We don't have to clear up everything though because the
643 * reprogramming is manual. When we resume, we'll actually
644 * go through a proper restart sequence again to switch
645 * back to the runtime firmware image.
646 */
647 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
648
649 /* We reprogram keys and shouldn't allocate new key indices */
650 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
651
652 /*
653 * The D3 firmware still hardcodes the AP station ID for the
654 * BSS we're associated with as 0. As a result, we have to move
655 * the auxiliary station to ID 1 so the ID 0 remains free for
656 * the AP station for later.
657 * We set the sta_id to 1 here, and reset it to its previous
658 * value (that we stored above) later.
659 */
660 mvm->aux_sta.sta_id = 1;
661
662 ret = iwl_mvm_load_d3_fw(mvm);
663 if (ret)
664 goto out;
665
666 ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta);
667 if (ret)
668 goto out;
669
670 if (!iwlwifi_mod_params.sw_crypto) {
671 /*
672 * This needs to be unlocked due to lock ordering
673 * constraints. Since we're in the suspend path
674 * that isn't really a problem though.
675 */
676 mutex_unlock(&mvm->mutex);
677 ieee80211_iter_keys(mvm->hw, vif,
678 iwl_mvm_wowlan_program_keys,
679 &key_data);
680 mutex_lock(&mvm->mutex);
681 if (key_data.error) {
682 ret = -EIO;
683 goto out;
684 }
685
686 if (key_data.use_rsc_tsc) {
687 struct iwl_host_cmd rsc_tsc_cmd = {
688 .id = WOWLAN_TSC_RSC_PARAM,
689 .flags = CMD_SYNC,
690 .data[0] = key_data.rsc_tsc,
691 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
692 .len[0] = sizeof(*key_data.rsc_tsc),
693 };
694
695 ret = iwl_mvm_send_cmd(mvm, &rsc_tsc_cmd);
696 if (ret)
697 goto out;
698 }
699
700 if (key_data.use_tkip) {
701 ret = iwl_mvm_send_cmd_pdu(mvm,
702 WOWLAN_TKIP_PARAM,
703 CMD_SYNC, sizeof(tkip_cmd),
704 &tkip_cmd);
705 if (ret)
706 goto out;
707 }
708
709 if (mvmvif->rekey_data.valid) {
710 memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd));
711 memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck,
712 NL80211_KCK_LEN);
713 kek_kck_cmd.kck_len = cpu_to_le16(NL80211_KCK_LEN);
714 memcpy(kek_kck_cmd.kek, mvmvif->rekey_data.kek,
715 NL80211_KEK_LEN);
716 kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN);
717 kek_kck_cmd.replay_ctr = mvmvif->rekey_data.replay_ctr;
718
719 ret = iwl_mvm_send_cmd_pdu(mvm,
720 WOWLAN_KEK_KCK_MATERIAL,
721 CMD_SYNC,
722 sizeof(kek_kck_cmd),
723 &kek_kck_cmd);
724 if (ret)
725 goto out;
726 }
727 }
728
729 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION,
730 CMD_SYNC, sizeof(wowlan_config_cmd),
731 &wowlan_config_cmd);
732 if (ret)
733 goto out;
734
735 ret = iwl_mvm_send_patterns(mvm, wowlan);
736 if (ret)
737 goto out;
738
739 ret = iwl_mvm_send_proto_offload(mvm, vif);
740 if (ret)
741 goto out;
742
743 /* must be last -- this switches firmware state */
744 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC,
745 sizeof(d3_cfg_cmd), &d3_cfg_cmd);
746 if (ret)
747 goto out;
748
749 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
750
751 iwl_trans_d3_suspend(mvm->trans);
752 out:
753 mvm->aux_sta.sta_id = old_aux_sta_id;
754 mvm_ap_sta->sta_id = old_ap_sta_id;
755 mvmvif->ap_sta_id = old_ap_sta_id;
756 out_noreset:
757 kfree(key_data.rsc_tsc);
758 if (ret < 0)
759 ieee80211_restart_hw(mvm->hw);
760
761 mutex_unlock(&mvm->mutex);
762
763 return ret;
764}
765
766int iwl_mvm_resume(struct ieee80211_hw *hw)
767{
768 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
769 struct iwl_d3_iter_data resume_iter_data = {
770 .mvm = mvm,
771 };
772 struct ieee80211_vif *vif = NULL;
773 u32 base;
774 int ret;
775 enum iwl_d3_status d3_status;
776 struct error_table_start {
777 /* cf. struct iwl_error_event_table */
778 u32 valid;
779 u32 error_id;
780 } err_info;
781
782 mutex_lock(&mvm->mutex);
783
784 /* get the BSS vif pointer again */
785 ieee80211_iterate_active_interfaces_atomic(
786 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
787 iwl_mvm_d3_iface_iterator, &resume_iter_data);
788
789 if (WARN_ON(resume_iter_data.error || !resume_iter_data.vif))
790 goto out_unlock;
791
792 vif = resume_iter_data.vif;
793
794 ret = iwl_trans_d3_resume(mvm->trans, &d3_status);
795 if (ret)
796 goto out_unlock;
797
798 if (d3_status != IWL_D3_STATUS_ALIVE) {
799 IWL_INFO(mvm, "Device was reset during suspend\n");
800 goto out_unlock;
801 }
802
803 base = mvm->error_event_table;
804
805 iwl_trans_read_mem_bytes(mvm->trans, base,
806 &err_info, sizeof(err_info));
807
808 if (err_info.valid) {
809 IWL_INFO(mvm, "error table is valid (%d)\n",
810 err_info.valid);
811 if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN)
812 IWL_ERR(mvm, "this was due to RF-kill\n");
813 goto out_unlock;
814 }
815
816 /* TODO: get status and whatever else ... */
817 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_GET_STATUSES, CMD_SYNC, 0, NULL);
818 if (ret)
819 IWL_ERR(mvm, "failed to query status (%d)\n", ret);
820
821 ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, CMD_SYNC, 0, NULL);
822 if (ret)
823 IWL_ERR(mvm, "failed to query offloads (%d)\n", ret);
824
825 out_unlock:
826 mutex_unlock(&mvm->mutex);
827
828 if (vif)
829 ieee80211_resume_disconnect(vif);
830
831 /* return 1 to reconfigure the device */
832 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
833 return 1;
834}
835
836void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled)
837{
838 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
839
840 device_set_wakeup_enable(mvm->trans->dev, enabled);
841}
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
new file mode 100644
index 000000000000..c1bdb5582126
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -0,0 +1,378 @@
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 LICENSE.GPL.
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#include "mvm.h"
64#include "sta.h"
65#include "iwl-io.h"
66
67struct iwl_dbgfs_mvm_ctx {
68 struct iwl_mvm *mvm;
69 struct ieee80211_vif *vif;
70};
71
72static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
73{
74 file->private_data = inode->i_private;
75 return 0;
76}
77
78static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
79 const char __user *user_buf,
80 size_t count, loff_t *ppos)
81{
82 struct iwl_mvm *mvm = file->private_data;
83
84 char buf[16];
85 int buf_size, ret;
86 u32 scd_q_msk;
87
88 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
89 return -EIO;
90
91 memset(buf, 0, sizeof(buf));
92 buf_size = min(count, sizeof(buf) - 1);
93 if (copy_from_user(buf, user_buf, buf_size))
94 return -EFAULT;
95
96 if (sscanf(buf, "%x", &scd_q_msk) != 1)
97 return -EINVAL;
98
99 IWL_ERR(mvm, "FLUSHING queues: scd_q_msk = 0x%x\n", scd_q_msk);
100
101 mutex_lock(&mvm->mutex);
102 ret = iwl_mvm_flush_tx_path(mvm, scd_q_msk, true) ? : count;
103 mutex_unlock(&mvm->mutex);
104
105 return ret;
106}
107
108static ssize_t iwl_dbgfs_sta_drain_write(struct file *file,
109 const char __user *user_buf,
110 size_t count, loff_t *ppos)
111{
112 struct iwl_mvm *mvm = file->private_data;
113 struct ieee80211_sta *sta;
114
115 char buf[8];
116 int buf_size, sta_id, drain, ret;
117
118 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
119 return -EIO;
120
121 memset(buf, 0, sizeof(buf));
122 buf_size = min(count, sizeof(buf) - 1);
123 if (copy_from_user(buf, user_buf, buf_size))
124 return -EFAULT;
125
126 if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
127 return -EINVAL;
128
129 mutex_lock(&mvm->mutex);
130
131 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
132 lockdep_is_held(&mvm->mutex));
133 if (IS_ERR_OR_NULL(sta))
134 ret = -ENOENT;
135 else
136 ret = iwl_mvm_drain_sta(mvm, (void *)sta->drv_priv, drain) ? :
137 count;
138
139 mutex_unlock(&mvm->mutex);
140
141 return ret;
142}
143
144static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
145 size_t count, loff_t *ppos)
146{
147 struct iwl_mvm *mvm = file->private_data;
148 const struct fw_img *img;
149 int ofs, len, pos = 0;
150 size_t bufsz, ret;
151 char *buf;
152 u8 *ptr;
153
154 /* default is to dump the entire data segment */
155 if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) {
156 mvm->dbgfs_sram_offset = 0x800000;
157 if (!mvm->ucode_loaded)
158 return -EINVAL;
159 img = &mvm->fw->img[mvm->cur_ucode];
160 mvm->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
161 }
162 len = mvm->dbgfs_sram_len;
163
164 bufsz = len * 4 + 256;
165 buf = kzalloc(bufsz, GFP_KERNEL);
166 if (!buf)
167 return -ENOMEM;
168
169 ptr = kzalloc(len, GFP_KERNEL);
170 if (!ptr) {
171 kfree(buf);
172 return -ENOMEM;
173 }
174
175 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len);
176 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
177 mvm->dbgfs_sram_offset);
178
179 iwl_trans_read_mem_bytes(mvm->trans,
180 mvm->dbgfs_sram_offset,
181 ptr, len);
182 for (ofs = 0; ofs < len; ofs += 16) {
183 pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs);
184 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
185 bufsz - pos, false);
186 pos += strlen(buf + pos);
187 if (bufsz - pos > 0)
188 buf[pos++] = '\n';
189 }
190
191 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
192
193 kfree(buf);
194 kfree(ptr);
195
196 return ret;
197}
198
199static ssize_t iwl_dbgfs_sram_write(struct file *file,
200 const char __user *user_buf, size_t count,
201 loff_t *ppos)
202{
203 struct iwl_mvm *mvm = file->private_data;
204 char buf[64];
205 int buf_size;
206 u32 offset, len;
207
208 memset(buf, 0, sizeof(buf));
209 buf_size = min(count, sizeof(buf) - 1);
210 if (copy_from_user(buf, user_buf, buf_size))
211 return -EFAULT;
212
213 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
214 if ((offset & 0x3) || (len & 0x3))
215 return -EINVAL;
216 mvm->dbgfs_sram_offset = offset;
217 mvm->dbgfs_sram_len = len;
218 } else {
219 mvm->dbgfs_sram_offset = 0;
220 mvm->dbgfs_sram_len = 0;
221 }
222
223 return count;
224}
225
226static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
227 size_t count, loff_t *ppos)
228{
229 struct iwl_mvm *mvm = file->private_data;
230 struct ieee80211_sta *sta;
231 char buf[400];
232 int i, pos = 0, bufsz = sizeof(buf);
233
234 mutex_lock(&mvm->mutex);
235
236 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
237 pos += scnprintf(buf + pos, bufsz - pos, "%.2d: ", i);
238 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
239 lockdep_is_held(&mvm->mutex));
240 if (!sta)
241 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
242 else if (IS_ERR(sta))
243 pos += scnprintf(buf + pos, bufsz - pos, "%ld\n",
244 PTR_ERR(sta));
245 else
246 pos += scnprintf(buf + pos, bufsz - pos, "%pM\n",
247 sta->addr);
248 }
249
250 mutex_unlock(&mvm->mutex);
251
252 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
253}
254
255static ssize_t iwl_dbgfs_power_down_allow_write(struct file *file,
256 const char __user *user_buf,
257 size_t count, loff_t *ppos)
258{
259 struct iwl_mvm *mvm = file->private_data;
260 char buf[8] = {};
261 int allow;
262
263 if (!mvm->ucode_loaded)
264 return -EIO;
265
266 if (copy_from_user(buf, user_buf, sizeof(buf)))
267 return -EFAULT;
268
269 if (sscanf(buf, "%d", &allow) != 1)
270 return -EINVAL;
271
272 IWL_DEBUG_POWER(mvm, "%s device power down\n",
273 allow ? "allow" : "prevent");
274
275 /*
276 * TODO: Send REPLY_DEBUG_CMD (0xf0) when FW support it
277 */
278
279 return count;
280}
281
282static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
283 const char __user *user_buf,
284 size_t count, loff_t *ppos)
285{
286 struct iwl_mvm *mvm = file->private_data;
287 char buf[8] = {};
288 int allow;
289
290 if (copy_from_user(buf, user_buf, sizeof(buf)))
291 return -EFAULT;
292
293 if (sscanf(buf, "%d", &allow) != 1)
294 return -EINVAL;
295
296 IWL_DEBUG_POWER(mvm, "%s device power down in d3\n",
297 allow ? "allow" : "prevent");
298
299 /*
300 * TODO: When WoWLAN FW alive notification happens, driver will send
301 * REPLY_DEBUG_CMD setting power_down_allow flag according to
302 * mvm->prevent_power_down_d3
303 */
304 mvm->prevent_power_down_d3 = !allow;
305
306 return count;
307}
308
309#define MVM_DEBUGFS_READ_FILE_OPS(name) \
310static const struct file_operations iwl_dbgfs_##name##_ops = { \
311 .read = iwl_dbgfs_##name##_read, \
312 .open = iwl_dbgfs_open_file_generic, \
313 .llseek = generic_file_llseek, \
314}
315
316#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name) \
317static const struct file_operations iwl_dbgfs_##name##_ops = { \
318 .write = iwl_dbgfs_##name##_write, \
319 .read = iwl_dbgfs_##name##_read, \
320 .open = iwl_dbgfs_open_file_generic, \
321 .llseek = generic_file_llseek, \
322};
323
324#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \
325static const struct file_operations iwl_dbgfs_##name##_ops = { \
326 .write = iwl_dbgfs_##name##_write, \
327 .open = iwl_dbgfs_open_file_generic, \
328 .llseek = generic_file_llseek, \
329};
330
331#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \
332 if (!debugfs_create_file(#name, mode, parent, mvm, \
333 &iwl_dbgfs_##name##_ops)) \
334 goto err; \
335 } while (0)
336
337#define MVM_DEBUGFS_ADD_FILE_VIF(name, parent, mode) do { \
338 if (!debugfs_create_file(#name, mode, parent, vif, \
339 &iwl_dbgfs_##name##_ops)) \
340 goto err; \
341 } while (0)
342
343/* Device wide debugfs entries */
344MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush);
345MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain);
346MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram);
347MVM_DEBUGFS_READ_FILE_OPS(stations);
348MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
349MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
350
351int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
352{
353 char buf[100];
354
355 mvm->debugfs_dir = dbgfs_dir;
356
357 MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR);
358 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR);
359 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
360 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
361 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR);
362 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR);
363
364 /*
365 * Create a symlink with mac80211. It will be removed when mac80211
366 * exists (before the opmode exists which removes the target.)
367 */
368 snprintf(buf, 100, "../../%s/%s",
369 dbgfs_dir->d_parent->d_parent->d_name.name,
370 dbgfs_dir->d_parent->d_name.name);
371 if (!debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf))
372 goto err;
373
374 return 0;
375err:
376 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n");
377 return -ENOMEM;
378}
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
new file mode 100644
index 000000000000..cf6f9a02fb74
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -0,0 +1,282 @@
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 LICENSE.GPL.
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#ifndef __fw_api_d3_h__
64#define __fw_api_d3_h__
65
66/**
67 * enum iwl_d3_wakeup_flags - D3 manager wakeup flags
68 * @IWL_WAKEUP_D3_CONFIG_FW_ERROR: wake up on firmware sysassert
69 */
70enum iwl_d3_wakeup_flags {
71 IWL_WAKEUP_D3_CONFIG_FW_ERROR = BIT(0),
72}; /* D3_MANAGER_WAKEUP_CONFIG_API_E_VER_3 */
73
74/**
75 * struct iwl_d3_manager_config - D3 manager configuration command
76 * @min_sleep_time: minimum sleep time (in usec)
77 * @wakeup_flags: wakeup flags, see &enum iwl_d3_wakeup_flags
78 *
79 * The structure is used for the D3_CONFIG_CMD command.
80 */
81struct iwl_d3_manager_config {
82 __le32 min_sleep_time;
83 __le32 wakeup_flags;
84} __packed; /* D3_MANAGER_CONFIG_CMD_S_VER_3 */
85
86
87/* TODO: OFFLOADS_QUERY_API_S_VER_1 */
88
89/**
90 * enum iwl_d3_proto_offloads - enabled protocol offloads
91 * @IWL_D3_PROTO_OFFLOAD_ARP: ARP data is enabled
92 * @IWL_D3_PROTO_OFFLOAD_NS: NS (Neighbor Solicitation) is enabled
93 */
94enum iwl_proto_offloads {
95 IWL_D3_PROTO_OFFLOAD_ARP = BIT(0),
96 IWL_D3_PROTO_OFFLOAD_NS = BIT(1),
97};
98
99#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS 2
100
101/**
102 * struct iwl_proto_offload_cmd - ARP/NS offload configuration
103 * @enabled: enable flags
104 * @remote_ipv4_addr: remote address to answer to (or zero if all)
105 * @host_ipv4_addr: our IPv4 address to respond to queries for
106 * @arp_mac_addr: our MAC address for ARP responses
107 * @remote_ipv6_addr: remote address to answer to (or zero if all)
108 * @solicited_node_ipv6_addr: broken -- solicited node address exists
109 * for each target address
110 * @target_ipv6_addr: our target addresses
111 * @ndp_mac_addr: neighbor soliciation response MAC address
112 */
113struct iwl_proto_offload_cmd {
114 __le32 enabled;
115 __be32 remote_ipv4_addr;
116 __be32 host_ipv4_addr;
117 u8 arp_mac_addr[ETH_ALEN];
118 __le16 reserved1;
119
120 u8 remote_ipv6_addr[16];
121 u8 solicited_node_ipv6_addr[16];
122 u8 target_ipv6_addr[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS][16];
123 u8 ndp_mac_addr[ETH_ALEN];
124 __le16 reserved2;
125} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_1 */
126
127
128/*
129 * WOWLAN_PATTERNS
130 */
131#define IWL_WOWLAN_MIN_PATTERN_LEN 16
132#define IWL_WOWLAN_MAX_PATTERN_LEN 128
133
134struct iwl_wowlan_pattern {
135 u8 mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];
136 u8 pattern[IWL_WOWLAN_MAX_PATTERN_LEN];
137 u8 mask_size;
138 u8 pattern_size;
139 __le16 reserved;
140} __packed; /* WOWLAN_PATTERN_API_S_VER_1 */
141
142#define IWL_WOWLAN_MAX_PATTERNS 20
143
144struct iwl_wowlan_patterns_cmd {
145 __le32 n_patterns;
146 struct iwl_wowlan_pattern patterns[];
147} __packed; /* WOWLAN_PATTERN_ARRAY_API_S_VER_1 */
148
149enum iwl_wowlan_wakeup_filters {
150 IWL_WOWLAN_WAKEUP_MAGIC_PACKET = BIT(0),
151 IWL_WOWLAN_WAKEUP_PATTERN_MATCH = BIT(1),
152 IWL_WOWLAN_WAKEUP_BEACON_MISS = BIT(2),
153 IWL_WOWLAN_WAKEUP_LINK_CHANGE = BIT(3),
154 IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL = BIT(4),
155 IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(5),
156 IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(6),
157 IWL_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(7),
158 IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT = BIT(8),
159 IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS = BIT(9),
160 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE = BIT(10),
161 /* BIT(11) reserved */
162 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET = BIT(12),
163}; /* WOWLAN_WAKEUP_FILTER_API_E_VER_4 */
164
165struct iwl_wowlan_config_cmd {
166 __le32 wakeup_filter;
167 __le16 non_qos_seq;
168 __le16 qos_seq[8];
169 u8 wowlan_ba_teardown_tids;
170 u8 is_11n_connection;
171} __packed; /* WOWLAN_CONFIG_API_S_VER_2 */
172
173/*
174 * WOWLAN_TSC_RSC_PARAMS
175 */
176#define IWL_NUM_RSC 16
177
178struct tkip_sc {
179 __le16 iv16;
180 __le16 pad;
181 __le32 iv32;
182} __packed; /* TKIP_SC_API_U_VER_1 */
183
184struct iwl_tkip_rsc_tsc {
185 struct tkip_sc unicast_rsc[IWL_NUM_RSC];
186 struct tkip_sc multicast_rsc[IWL_NUM_RSC];
187 struct tkip_sc tsc;
188} __packed; /* TKIP_TSC_RSC_API_S_VER_1 */
189
190struct aes_sc {
191 __le64 pn;
192} __packed; /* TKIP_AES_SC_API_U_VER_1 */
193
194struct iwl_aes_rsc_tsc {
195 struct aes_sc unicast_rsc[IWL_NUM_RSC];
196 struct aes_sc multicast_rsc[IWL_NUM_RSC];
197 struct aes_sc tsc;
198} __packed; /* AES_TSC_RSC_API_S_VER_1 */
199
200union iwl_all_tsc_rsc {
201 struct iwl_tkip_rsc_tsc tkip;
202 struct iwl_aes_rsc_tsc aes;
203}; /* ALL_TSC_RSC_API_S_VER_2 */
204
205struct iwl_wowlan_rsc_tsc_params_cmd {
206 union iwl_all_tsc_rsc all_tsc_rsc;
207} __packed; /* ALL_TSC_RSC_API_S_VER_2 */
208
209#define IWL_MIC_KEY_SIZE 8
210struct iwl_mic_keys {
211 u8 tx[IWL_MIC_KEY_SIZE];
212 u8 rx_unicast[IWL_MIC_KEY_SIZE];
213 u8 rx_mcast[IWL_MIC_KEY_SIZE];
214} __packed; /* MIC_KEYS_API_S_VER_1 */
215
216#define IWL_P1K_SIZE 5
217struct iwl_p1k_cache {
218 __le16 p1k[IWL_P1K_SIZE];
219} __packed;
220
221#define IWL_NUM_RX_P1K_CACHE 2
222
223struct iwl_wowlan_tkip_params_cmd {
224 struct iwl_mic_keys mic_keys;
225 struct iwl_p1k_cache tx;
226 struct iwl_p1k_cache rx_uni[IWL_NUM_RX_P1K_CACHE];
227 struct iwl_p1k_cache rx_multi[IWL_NUM_RX_P1K_CACHE];
228} __packed; /* WOWLAN_TKIP_SETTING_API_S_VER_1 */
229
230#define IWL_KCK_MAX_SIZE 32
231#define IWL_KEK_MAX_SIZE 32
232
233struct iwl_wowlan_kek_kck_material_cmd {
234 u8 kck[IWL_KCK_MAX_SIZE];
235 u8 kek[IWL_KEK_MAX_SIZE];
236 __le16 kck_len;
237 __le16 kek_len;
238 __le64 replay_ctr;
239} __packed; /* KEK_KCK_MATERIAL_API_S_VER_2 */
240
241#define RF_KILL_INDICATOR_FOR_WOWLAN 0x87
242
243enum iwl_wowlan_rekey_status {
244 IWL_WOWLAN_REKEY_POST_REKEY = 0,
245 IWL_WOWLAN_REKEY_WHILE_REKEY = 1,
246}; /* WOWLAN_REKEY_STATUS_API_E_VER_1 */
247
248enum iwl_wowlan_wakeup_reason {
249 IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS = 0,
250 IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET = BIT(0),
251 IWL_WOWLAN_WAKEUP_BY_PATTERN = BIT(1),
252 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON = BIT(2),
253 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH = BIT(3),
254 IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE = BIT(4),
255 IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED = BIT(5),
256 IWL_WOWLAN_WAKEUP_BY_UCODE_ERROR = BIT(6),
257 IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST = BIT(7),
258 IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8),
259 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9),
260 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10),
261 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_TCP_EXTERNAL = BIT(11),
262 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12),
263}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
264
265struct iwl_wowlan_status {
266 __le64 replay_ctr;
267 __le16 pattern_number;
268 __le16 non_qos_seq_ctr;
269 __le16 qos_seq_ctr[8];
270 __le32 wakeup_reasons;
271 __le32 rekey_status;
272 __le32 num_of_gtk_rekeys;
273 __le32 transmitted_ndps;
274 __le32 received_beacons;
275 __le32 wake_packet_length;
276 __le32 wake_packet_bufsize;
277 u8 wake_packet[]; /* can be truncated from _length to _bufsize */
278} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */
279
280/* TODO: NetDetect API */
281
282#endif /* __fw_api_d3_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
new file mode 100644
index 000000000000..ae39b7dfda7b
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -0,0 +1,369 @@
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 LICENSE.GPL.
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#ifndef __fw_api_mac_h__
64#define __fw_api_mac_h__
65
66/*
67 * The first MAC indices (starting from 0)
68 * are available to the driver, AUX follows
69 */
70#define MAC_INDEX_AUX 4
71#define MAC_INDEX_MIN_DRIVER 0
72#define NUM_MAC_INDEX_DRIVER MAC_INDEX_AUX
73
74#define AC_NUM 4 /* Number of access categories */
75
76/**
77 * enum iwl_mac_protection_flags - MAC context flags
78 * @MAC_PROT_FLG_TGG_PROTECT: 11g protection when transmitting OFDM frames,
79 * this will require CCK RTS/CTS2self.
80 * RTS/CTS will protect full burst time.
81 * @MAC_PROT_FLG_HT_PROT: enable HT protection
82 * @MAC_PROT_FLG_FAT_PROT: protect 40 MHz transmissions
83 * @MAC_PROT_FLG_SELF_CTS_EN: allow CTS2self
84 */
85enum iwl_mac_protection_flags {
86 MAC_PROT_FLG_TGG_PROTECT = BIT(3),
87 MAC_PROT_FLG_HT_PROT = BIT(23),
88 MAC_PROT_FLG_FAT_PROT = BIT(24),
89 MAC_PROT_FLG_SELF_CTS_EN = BIT(30),
90};
91
92#define MAC_FLG_SHORT_SLOT BIT(4)
93#define MAC_FLG_SHORT_PREAMBLE BIT(5)
94
95/**
96 * enum iwl_mac_types - Supported MAC types
97 * @FW_MAC_TYPE_FIRST: lowest supported MAC type
98 * @FW_MAC_TYPE_AUX: Auxiliary MAC (internal)
99 * @FW_MAC_TYPE_LISTENER: monitor MAC type (?)
100 * @FW_MAC_TYPE_PIBSS: Pseudo-IBSS
101 * @FW_MAC_TYPE_IBSS: IBSS
102 * @FW_MAC_TYPE_BSS_STA: BSS (managed) station
103 * @FW_MAC_TYPE_P2P_DEVICE: P2P Device
104 * @FW_MAC_TYPE_P2P_STA: P2P client
105 * @FW_MAC_TYPE_GO: P2P GO
106 * @FW_MAC_TYPE_TEST: ?
107 * @FW_MAC_TYPE_MAX: highest support MAC type
108 */
109enum iwl_mac_types {
110 FW_MAC_TYPE_FIRST = 1,
111 FW_MAC_TYPE_AUX = FW_MAC_TYPE_FIRST,
112 FW_MAC_TYPE_LISTENER,
113 FW_MAC_TYPE_PIBSS,
114 FW_MAC_TYPE_IBSS,
115 FW_MAC_TYPE_BSS_STA,
116 FW_MAC_TYPE_P2P_DEVICE,
117 FW_MAC_TYPE_P2P_STA,
118 FW_MAC_TYPE_GO,
119 FW_MAC_TYPE_TEST,
120 FW_MAC_TYPE_MAX = FW_MAC_TYPE_TEST
121}; /* MAC_CONTEXT_TYPE_API_E_VER_1 */
122
123/**
124 * enum iwl_tsf_id - TSF hw timer ID
125 * @TSF_ID_A: use TSF A
126 * @TSF_ID_B: use TSF B
127 * @TSF_ID_C: use TSF C
128 * @TSF_ID_D: use TSF D
129 * @NUM_TSF_IDS: number of TSF timers available
130 */
131enum iwl_tsf_id {
132 TSF_ID_A = 0,
133 TSF_ID_B = 1,
134 TSF_ID_C = 2,
135 TSF_ID_D = 3,
136 NUM_TSF_IDS = 4,
137}; /* TSF_ID_API_E_VER_1 */
138
139/**
140 * struct iwl_mac_data_ap - configuration data for AP MAC context
141 * @beacon_time: beacon transmit time in system time
142 * @beacon_tsf: beacon transmit time in TSF
143 * @bi: beacon interval in TU
144 * @bi_reciprocal: 2^32 / bi
145 * @dtim_interval: dtim transmit time in TU
146 * @dtim_reciprocal: 2^32 / dtim_interval
147 * @mcast_qid: queue ID for multicast traffic
148 * @beacon_template: beacon template ID
149 */
150struct iwl_mac_data_ap {
151 __le32 beacon_time;
152 __le64 beacon_tsf;
153 __le32 bi;
154 __le32 bi_reciprocal;
155 __le32 dtim_interval;
156 __le32 dtim_reciprocal;
157 __le32 mcast_qid;
158 __le32 beacon_template;
159} __packed; /* AP_MAC_DATA_API_S_VER_1 */
160
161/**
162 * struct iwl_mac_data_ibss - configuration data for IBSS MAC context
163 * @beacon_time: beacon transmit time in system time
164 * @beacon_tsf: beacon transmit time in TSF
165 * @bi: beacon interval in TU
166 * @bi_reciprocal: 2^32 / bi
167 */
168struct iwl_mac_data_ibss {
169 __le32 beacon_time;
170 __le64 beacon_tsf;
171 __le32 bi;
172 __le32 bi_reciprocal;
173} __packed; /* IBSS_MAC_DATA_API_S_VER_1 */
174
175/**
176 * struct iwl_mac_data_sta - configuration data for station MAC context
177 * @is_assoc: 1 for associated state, 0 otherwise
178 * @dtim_time: DTIM arrival time in system time
179 * @dtim_tsf: DTIM arrival time in TSF
180 * @bi: beacon interval in TU, applicable only when associated
181 * @bi_reciprocal: 2^32 / bi , applicable only when associated
182 * @dtim_interval: DTIM interval in TU, applicable only when associated
183 * @dtim_reciprocal: 2^32 / dtim_interval , applicable only when associated
184 * @listen_interval: in beacon intervals, applicable only when associated
185 * @assoc_id: unique ID assigned by the AP during association
186 */
187struct iwl_mac_data_sta {
188 __le32 is_assoc;
189 __le32 dtim_time;
190 __le64 dtim_tsf;
191 __le32 bi;
192 __le32 bi_reciprocal;
193 __le32 dtim_interval;
194 __le32 dtim_reciprocal;
195 __le32 listen_interval;
196 __le32 assoc_id;
197 __le32 assoc_beacon_arrive_time;
198} __packed; /* STA_MAC_DATA_API_S_VER_1 */
199
200/**
201 * struct iwl_mac_data_go - configuration data for P2P GO MAC context
202 * @ap: iwl_mac_data_ap struct with most config data
203 * @ctwin: client traffic window in TU (period after TBTT when GO is present).
204 * 0 indicates that there is no CT window.
205 * @opp_ps_enabled: indicate that opportunistic PS allowed
206 */
207struct iwl_mac_data_go {
208 struct iwl_mac_data_ap ap;
209 __le32 ctwin;
210 __le32 opp_ps_enabled;
211} __packed; /* GO_MAC_DATA_API_S_VER_1 */
212
213/**
214 * struct iwl_mac_data_p2p_sta - configuration data for P2P client MAC context
215 * @sta: iwl_mac_data_sta struct with most config data
216 * @ctwin: client traffic window in TU (period after TBTT when GO is present).
217 * 0 indicates that there is no CT window.
218 */
219struct iwl_mac_data_p2p_sta {
220 struct iwl_mac_data_sta sta;
221 __le32 ctwin;
222} __packed; /* P2P_STA_MAC_DATA_API_S_VER_1 */
223
224/**
225 * struct iwl_mac_data_pibss - Pseudo IBSS config data
226 * @stats_interval: interval in TU between statistics notifications to host.
227 */
228struct iwl_mac_data_pibss {
229 __le32 stats_interval;
230} __packed; /* PIBSS_MAC_DATA_API_S_VER_1 */
231
232/*
233 * struct iwl_mac_data_p2p_dev - configuration data for the P2P Device MAC
234 * context.
235 * @is_disc_extended: if set to true, P2P Device discoverability is enabled on
236 * other channels as well. This should be to true only in case that the
237 * device is discoverable and there is an active GO. Note that setting this
238 * field when not needed, will increase the number of interrupts and have
239 * effect on the platform power, as this setting opens the Rx filters on
240 * all macs.
241 */
242struct iwl_mac_data_p2p_dev {
243 __le32 is_disc_extended;
244} __packed; /* _P2P_DEV_MAC_DATA_API_S_VER_1 */
245
246/**
247 * enum iwl_mac_filter_flags - MAC context filter flags
248 * @MAC_FILTER_IN_PROMISC: accept all data frames
249 * @MAC_FILTER_IN_CONTROL_AND_MGMT: pass all mangement and
250 * control frames to the host
251 * @MAC_FILTER_ACCEPT_GRP: accept multicast frames
252 * @MAC_FILTER_DIS_DECRYPT: don't decrypt unicast frames
253 * @MAC_FILTER_DIS_GRP_DECRYPT: don't decrypt multicast frames
254 * @MAC_FILTER_IN_BEACON: transfer foreign BSS's beacons to host
255 * (in station mode when associated)
256 * @MAC_FILTER_OUT_BCAST: filter out all broadcast frames
257 * @MAC_FILTER_IN_CRC32: extract FCS and append it to frames
258 * @MAC_FILTER_IN_PROBE_REQUEST: pass probe requests to host
259 */
260enum iwl_mac_filter_flags {
261 MAC_FILTER_IN_PROMISC = BIT(0),
262 MAC_FILTER_IN_CONTROL_AND_MGMT = BIT(1),
263 MAC_FILTER_ACCEPT_GRP = BIT(2),
264 MAC_FILTER_DIS_DECRYPT = BIT(3),
265 MAC_FILTER_DIS_GRP_DECRYPT = BIT(4),
266 MAC_FILTER_IN_BEACON = BIT(6),
267 MAC_FILTER_OUT_BCAST = BIT(8),
268 MAC_FILTER_IN_CRC32 = BIT(11),
269 MAC_FILTER_IN_PROBE_REQUEST = BIT(12),
270};
271
272/**
273 * enum iwl_mac_qos_flags - QoS flags
274 * @MAC_QOS_FLG_UPDATE_EDCA: ?
275 * @MAC_QOS_FLG_TGN: HT is enabled
276 * @MAC_QOS_FLG_TXOP_TYPE: ?
277 *
278 */
279enum iwl_mac_qos_flags {
280 MAC_QOS_FLG_UPDATE_EDCA = BIT(0),
281 MAC_QOS_FLG_TGN = BIT(1),
282 MAC_QOS_FLG_TXOP_TYPE = BIT(4),
283};
284
285/**
286 * struct iwl_ac_qos - QOS timing params for MAC_CONTEXT_CMD
287 * @cw_min: Contention window, start value in numbers of slots.
288 * Should be a power-of-2, minus 1. Device's default is 0x0f.
289 * @cw_max: Contention window, max value in numbers of slots.
290 * Should be a power-of-2, minus 1. Device's default is 0x3f.
291 * @aifsn: Number of slots in Arbitration Interframe Space (before
292 * performing random backoff timing prior to Tx). Device default 1.
293 * @fifos_mask: FIFOs used by this MAC for this AC
294 * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0.
295 *
296 * One instance of this config struct for each of 4 EDCA access categories
297 * in struct iwl_qosparam_cmd.
298 *
299 * Device will automatically increase contention window by (2*CW) + 1 for each
300 * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW
301 * value, to cap the CW value.
302 */
303struct iwl_ac_qos {
304 __le16 cw_min;
305 __le16 cw_max;
306 u8 aifsn;
307 u8 fifos_mask;
308 __le16 edca_txop;
309} __packed; /* AC_QOS_API_S_VER_2 */
310
311/**
312 * struct iwl_mac_ctx_cmd - command structure to configure MAC contexts
313 * ( MAC_CONTEXT_CMD = 0x28 )
314 * @id_and_color: ID and color of the MAC
315 * @action: action to perform, one of FW_CTXT_ACTION_*
316 * @mac_type: one of FW_MAC_TYPE_*
317 * @tsd_id: TSF HW timer, one of TSF_ID_*
318 * @node_addr: MAC address
319 * @bssid_addr: BSSID
320 * @cck_rates: basic rates available for CCK
321 * @ofdm_rates: basic rates available for OFDM
322 * @protection_flags: combination of MAC_PROT_FLG_FLAG_*
323 * @cck_short_preamble: 0x20 for enabling short preamble, 0 otherwise
324 * @short_slot: 0x10 for enabling short slots, 0 otherwise
325 * @filter_flags: combination of MAC_FILTER_*
326 * @qos_flags: from MAC_QOS_FLG_*
327 * @ac: one iwl_mac_qos configuration for each AC
328 * @mac_specific: one of struct iwl_mac_data_*, according to mac_type
329 */
330struct iwl_mac_ctx_cmd {
331 /* COMMON_INDEX_HDR_API_S_VER_1 */
332 __le32 id_and_color;
333 __le32 action;
334 /* MAC_CONTEXT_COMMON_DATA_API_S_VER_1 */
335 __le32 mac_type;
336 __le32 tsf_id;
337 u8 node_addr[6];
338 __le16 reserved_for_node_addr;
339 u8 bssid_addr[6];
340 __le16 reserved_for_bssid_addr;
341 __le32 cck_rates;
342 __le32 ofdm_rates;
343 __le32 protection_flags;
344 __le32 cck_short_preamble;
345 __le32 short_slot;
346 __le32 filter_flags;
347 /* MAC_QOS_PARAM_API_S_VER_1 */
348 __le32 qos_flags;
349 struct iwl_ac_qos ac[AC_NUM+1];
350 /* MAC_CONTEXT_COMMON_DATA_API_S */
351 union {
352 struct iwl_mac_data_ap ap;
353 struct iwl_mac_data_go go;
354 struct iwl_mac_data_sta sta;
355 struct iwl_mac_data_p2p_sta p2p_sta;
356 struct iwl_mac_data_p2p_dev p2p_dev;
357 struct iwl_mac_data_pibss pibss;
358 struct iwl_mac_data_ibss ibss;
359 };
360} __packed; /* MAC_CONTEXT_CMD_API_S_VER_1 */
361
362static inline u32 iwl_mvm_reciprocal(u32 v)
363{
364 if (!v)
365 return 0;
366 return 0xFFFFFFFF / v;
367}
368
369#endif /* __fw_api_mac_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
new file mode 100644
index 000000000000..be36b7604b7f
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -0,0 +1,140 @@
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 LICENSE.GPL.
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#ifndef __fw_api_power_h__
65#define __fw_api_power_h__
66
67/* Power Management Commands, Responses, Notifications */
68
69/**
70 * enum iwl_scan_flags - masks for power table command flags
71 * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management,
72 * '1' Driver enables PM (use rest of parameters)
73 * @POWER_FLAGS_SLEEP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM,
74 * '1' PM could sleep over DTIM till listen Interval.
75 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
76 * @POWER_FLAGS_SNOOZE_ENA_MSK: Enable snoozing only if uAPSD is enabled and all
77 * access categories are both delivery and trigger enabled.
78 * @POWER_FLAGS_BT_SCO_ENA: Enable BT SCO coex only if uAPSD and
79 * PBW Snoozing enabled
80 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask
81*/
82enum iwl_power_flags {
83 POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(0),
84 POWER_FLAGS_SLEEP_OVER_DTIM_MSK = BIT(1),
85 POWER_FLAGS_LPRX_ENA_MSK = BIT(2),
86 POWER_FLAGS_SNOOZE_ENA_MSK = BIT(3),
87 POWER_FLAGS_BT_SCO_ENA = BIT(4),
88 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(5)
89};
90
91/**
92 * struct iwl_powertable_cmd - Power Table Command
93 * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
94 *
95 * @id_and_color: MAC contex identifier
96 * @action: Action on context - no action, add new,
97 * modify existent, remove
98 * @flags: Power table command flags from POWER_FLAGS_*
99 * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec.
100 * Minimum allowed:- 3 * DTIM
101 * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to
102 * PSM transition - legacy PM
103 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to
104 * PSM transition - legacy PM
105 * @rx_data_timeout_uapsd: Minimum time (usec) from last Rx packet for AM to
106 * PSM transition - uAPSD
107 * @tx_data_timeout_uapsd: Minimum time (usec) from last Tx packet for AM to
108 * PSM transition - uAPSD
109 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
110 * Default: 80dbm
111 * @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set
112 * @snooze_interval: TBD
113 * @snooze_window: TBD
114 * @snooze_step: TBD
115 * @qndp_tid: TBD
116 * @uapsd_ac_flags: TBD
117 * @uapsd_max_sp: TBD
118 */
119struct iwl_powertable_cmd {
120 /* COMMON_INDEX_HDR_API_S_VER_1 */
121 __le32 id_and_color;
122 __le32 action;
123 __le16 flags;
124 u8 reserved;
125 __le16 keep_alive_seconds;
126 __le32 rx_data_timeout;
127 __le32 tx_data_timeout;
128 __le32 rx_data_timeout_uapsd;
129 __le32 tx_data_timeout_uapsd;
130 u8 lprx_rssi_threshold;
131 u8 num_skip_dtim;
132 __le16 snooze_interval;
133 __le16 snooze_window;
134 u8 snooze_step;
135 u8 qndp_tid;
136 u8 uapsd_ac_flags;
137 u8 uapsd_max_sp;
138} __packed;
139
140#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
new file mode 100644
index 000000000000..aa3474d08231
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -0,0 +1,312 @@
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 LICENSE.GPL.
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#ifndef __fw_api_rs_h__
64#define __fw_api_rs_h__
65
66#include "fw-api-mac.h"
67
68/*
69 * These serve as indexes into
70 * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT];
71 */
72enum {
73 IWL_RATE_1M_INDEX = 0,
74 IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
75 IWL_RATE_2M_INDEX,
76 IWL_RATE_5M_INDEX,
77 IWL_RATE_11M_INDEX,
78 IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
79 IWL_RATE_6M_INDEX,
80 IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
81 IWL_RATE_9M_INDEX,
82 IWL_RATE_12M_INDEX,
83 IWL_RATE_18M_INDEX,
84 IWL_RATE_24M_INDEX,
85 IWL_RATE_36M_INDEX,
86 IWL_RATE_48M_INDEX,
87 IWL_RATE_54M_INDEX,
88 IWL_LAST_NON_HT_RATE = IWL_RATE_54M_INDEX,
89 IWL_RATE_60M_INDEX,
90 IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX,
91 IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1,
92 IWL_RATE_COUNT,
93};
94
95#define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX)
96
97/* fw API values for legacy bit rates, both OFDM and CCK */
98enum {
99 IWL_RATE_6M_PLCP = 13,
100 IWL_RATE_9M_PLCP = 15,
101 IWL_RATE_12M_PLCP = 5,
102 IWL_RATE_18M_PLCP = 7,
103 IWL_RATE_24M_PLCP = 9,
104 IWL_RATE_36M_PLCP = 11,
105 IWL_RATE_48M_PLCP = 1,
106 IWL_RATE_54M_PLCP = 3,
107 IWL_RATE_1M_PLCP = 10,
108 IWL_RATE_2M_PLCP = 20,
109 IWL_RATE_5M_PLCP = 55,
110 IWL_RATE_11M_PLCP = 110,
111};
112
113/*
114 * rate_n_flags bit fields
115 *
116 * The 32-bit value has different layouts in the low 8 bites depending on the
117 * format. There are three formats, HT, VHT and legacy (11abg, with subformats
118 * for CCK and OFDM).
119 *
120 * High-throughput (HT) rate format
121 * bit 8 is 1, bit 26 is 0, bit 9 is 0 (OFDM)
122 * Very High-throughput (VHT) rate format
123 * bit 8 is 0, bit 26 is 1, bit 9 is 0 (OFDM)
124 * Legacy OFDM rate format for bits 7:0
125 * bit 8 is 0, bit 26 is 0, bit 9 is 0 (OFDM)
126 * Legacy CCK rate format for bits 7:0:
127 * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK)
128 */
129
130/* Bit 8: (1) HT format, (0) legacy or VHT format */
131#define RATE_MCS_HT_POS 8
132#define RATE_MCS_HT_MSK (1 << RATE_MCS_HT_POS)
133
134/* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */
135#define RATE_MCS_CCK_POS 9
136#define RATE_MCS_CCK_MSK (1 << RATE_MCS_CCK_POS)
137
138/* Bit 26: (1) VHT format, (0) legacy format in bits 8:0 */
139#define RATE_MCS_VHT_POS 26
140#define RATE_MCS_VHT_MSK (1 << RATE_MCS_VHT_POS)
141
142
143/*
144 * High-throughput (HT) rate format for bits 7:0
145 *
146 * 2-0: MCS rate base
147 * 0) 6 Mbps
148 * 1) 12 Mbps
149 * 2) 18 Mbps
150 * 3) 24 Mbps
151 * 4) 36 Mbps
152 * 5) 48 Mbps
153 * 6) 54 Mbps
154 * 7) 60 Mbps
155 * 4-3: 0) Single stream (SISO)
156 * 1) Dual stream (MIMO)
157 * 2) Triple stream (MIMO)
158 * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data
159 * (bits 7-6 are zero)
160 *
161 * Together the low 5 bits work out to the MCS index because we don't
162 * support MCSes above 15/23, and 0-7 have one stream, 8-15 have two
163 * streams and 16-23 have three streams. We could also support MCS 32
164 * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.)
165 */
166#define RATE_HT_MCS_RATE_CODE_MSK 0x7
167
168/* Bit 10: (1) Use Green Field preamble */
169#define RATE_HT_MCS_GF_POS 10
170#define RATE_HT_MCS_GF_MSK (1 << RATE_HT_MCS_GF_POS)
171
172#define RATE_HT_MCS_INDEX_MSK 0x3f
173
174/*
175 * Very High-throughput (VHT) rate format for bits 7:0
176 *
177 * 3-0: VHT MCS (0-9)
178 * 5-4: number of streams - 1:
179 * 0) Single stream (SISO)
180 * 1) Dual stream (MIMO)
181 * 2) Triple stream (MIMO)
182 */
183
184/* Bit 4-5: (0) SISO, (1) MIMO2 (2) MIMO3 */
185#define RATE_VHT_MCS_RATE_CODE_MSK 0xf
186#define RATE_VHT_MCS_NSS_POS 4
187#define RATE_VHT_MCS_NSS_MSK (3 << RATE_VHT_MCS_NSS_POS)
188
189/*
190 * Legacy OFDM rate format for bits 7:0
191 *
192 * 3-0: 0xD) 6 Mbps
193 * 0xF) 9 Mbps
194 * 0x5) 12 Mbps
195 * 0x7) 18 Mbps
196 * 0x9) 24 Mbps
197 * 0xB) 36 Mbps
198 * 0x1) 48 Mbps
199 * 0x3) 54 Mbps
200 * (bits 7-4 are 0)
201 *
202 * Legacy CCK rate format for bits 7:0:
203 * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK):
204 *
205 * 6-0: 10) 1 Mbps
206 * 20) 2 Mbps
207 * 55) 5.5 Mbps
208 * 110) 11 Mbps
209 * (bit 7 is 0)
210 */
211#define RATE_LEGACY_RATE_MSK 0xff
212
213
214/*
215 * Bit 11-12: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz
216 * 0 and 1 are valid for HT and VHT, 2 and 3 only for VHT
217 */
218#define RATE_MCS_CHAN_WIDTH_POS 11
219#define RATE_MCS_CHAN_WIDTH_MSK (3 << RATE_MCS_CHAN_WIDTH_POS)
220#define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS)
221#define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS)
222#define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS)
223#define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS)
224
225/* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */
226#define RATE_MCS_SGI_POS 13
227#define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS)
228
229/* Bit 14-16: Antenna selection (1) Ant A, (2) Ant B, (4) Ant C */
230#define RATE_MCS_ANT_POS 14
231#define RATE_MCS_ANT_A_MSK (1 << RATE_MCS_ANT_POS)
232#define RATE_MCS_ANT_B_MSK (2 << RATE_MCS_ANT_POS)
233#define RATE_MCS_ANT_C_MSK (4 << RATE_MCS_ANT_POS)
234#define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | \
235 RATE_MCS_ANT_B_MSK)
236#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | \
237 RATE_MCS_ANT_C_MSK)
238#define RATE_MCS_ANT_MSK RATE_MCS_ANT_ABC_MSK
239#define RATE_MCS_ANT_NUM 3
240
241/* Bit 17-18: (0) SS, (1) SS*2 */
242#define RATE_MCS_STBC_POS 17
243#define RATE_MCS_STBC_MSK (1 << RATE_MCS_STBC_POS)
244
245/* Bit 19: (0) Beamforming is off, (1) Beamforming is on */
246#define RATE_MCS_BF_POS 19
247#define RATE_MCS_BF_MSK (1 << RATE_MCS_BF_POS)
248
249/* Bit 20: (0) ZLF is off, (1) ZLF is on */
250#define RATE_MCS_ZLF_POS 20
251#define RATE_MCS_ZLF_MSK (1 << RATE_MCS_ZLF_POS)
252
253/* Bit 24-25: (0) 20MHz (no dup), (1) 2x20MHz, (2) 4x20MHz, 3 8x20MHz */
254#define RATE_MCS_DUP_POS 24
255#define RATE_MCS_DUP_MSK (3 << RATE_MCS_DUP_POS)
256
257/* Bit 27: (1) LDPC enabled, (0) LDPC disabled */
258#define RATE_MCS_LDPC_POS 27
259#define RATE_MCS_LDPC_MSK (1 << RATE_MCS_LDPC_POS)
260
261
262/* Link Quality definitions */
263
264/* # entries in rate scale table to support Tx retries */
265#define LQ_MAX_RETRY_NUM 16
266
267/* Link quality command flags, only this one is available */
268#define LQ_FLAG_SET_STA_TLC_RTS_MSK BIT(0)
269
270/**
271 * struct iwl_lq_cmd - link quality command
272 * @sta_id: station to update
273 * @control: not used
274 * @flags: combination of LQ_FLAG_*
275 * @mimo_delim: the first SISO index in rs_table, which separates MIMO
276 * and SISO rates
277 * @single_stream_ant_msk: best antenna for SISO (can be dual in CDD).
278 * Should be ANT_[ABC]
279 * @dual_stream_ant_msk: best antennas for MIMO, combination of ANT_[ABC]
280 * @initial_rate_index: first index from rs_table per AC category
281 * @agg_time_limit: aggregation max time threshold in usec/100, meaning
282 * value of 100 is one usec. Range is 100 to 8000
283 * @agg_disable_start_th: try-count threshold for starting aggregation.
284 * If a frame has higher try-count, it should not be selected for
285 * starting an aggregation sequence.
286 * @agg_frame_cnt_limit: max frame count in an aggregation.
287 * 0: no limit
288 * 1: no aggregation (one frame per aggregation)
289 * 2 - 0x3f: maximal number of frames (up to 3f == 63)
290 * @rs_table: array of rates for each TX try, each is rate_n_flags,
291 * meaning it is a combination of RATE_MCS_* and IWL_RATE_*_PLCP
292 * @bf_params: beam forming params, currently not used
293 */
294struct iwl_lq_cmd {
295 u8 sta_id;
296 u8 reserved1;
297 u16 control;
298 /* LINK_QUAL_GENERAL_PARAMS_API_S_VER_1 */
299 u8 flags;
300 u8 mimo_delim;
301 u8 single_stream_ant_msk;
302 u8 dual_stream_ant_msk;
303 u8 initial_rate_index[AC_NUM];
304 /* LINK_QUAL_AGG_PARAMS_API_S_VER_1 */
305 __le16 agg_time_limit;
306 u8 agg_disable_start_th;
307 u8 agg_frame_cnt_limit;
308 __le32 reserved2;
309 __le32 rs_table[LQ_MAX_RETRY_NUM];
310 __le32 bf_params;
311}; /* LINK_QUALITY_CMD_API_S_VER_1 */
312#endif /* __fw_api_rs_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
new file mode 100644
index 000000000000..670ac8f95e26
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -0,0 +1,561 @@
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 LICENSE.GPL.
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#ifndef __fw_api_scan_h__
65#define __fw_api_scan_h__
66
67#include "fw-api.h"
68
69/* Scan Commands, Responses, Notifications */
70
71/* Masks for iwl_scan_channel.type flags */
72#define SCAN_CHANNEL_TYPE_PASSIVE 0
73#define SCAN_CHANNEL_TYPE_ACTIVE BIT(0)
74#define SCAN_CHANNEL_NARROW_BAND BIT(22)
75
76/* Max number of IEs for direct SSID scans in a command */
77#define PROBE_OPTION_MAX 20
78
79/**
80 * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table
81 * @channel: band is selected by iwl_scan_cmd "flags" field
82 * @tx_gain: gain for analog radio
83 * @dsp_atten: gain for DSP
84 * @active_dwell: dwell time for active scan in TU, typically 5-50
85 * @passive_dwell: dwell time for passive scan in TU, typically 20-500
86 * @type: type is broken down to these bits:
87 * bit 0: 0 = passive, 1 = active
88 * bits 1-20: SSID direct bit map. If any of these bits is set then
89 * the corresponding SSID IE is transmitted in probe request
90 * (bit i adds IE in position i to the probe request)
91 * bit 22: channel width, 0 = regular, 1 = TGj narrow channel
92 *
93 * @iteration_count:
94 * @iteration_interval:
95 * This struct is used once for each channel in the scan list.
96 * Each channel can independently select:
97 * 1) SSID for directed active scans
98 * 2) Txpower setting (for rate specified within Tx command)
99 * 3) How long to stay on-channel (behavior may be modified by quiet_time,
100 * quiet_plcp_th, good_CRC_th)
101 *
102 * To avoid uCode errors, make sure the following are true (see comments
103 * under struct iwl_scan_cmd about max_out_time and quiet_time):
104 * 1) If using passive_dwell (i.e. passive_dwell != 0):
105 * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
106 * 2) quiet_time <= active_dwell
107 * 3) If restricting off-channel time (i.e. max_out_time !=0):
108 * passive_dwell < max_out_time
109 * active_dwell < max_out_time
110 */
111struct iwl_scan_channel {
112 __le32 type;
113 __le16 channel;
114 __le16 iteration_count;
115 __le32 iteration_interval;
116 __le16 active_dwell;
117 __le16 passive_dwell;
118} __packed; /* SCAN_CHANNEL_CONTROL_API_S_VER_1 */
119
120/**
121 * struct iwl_ssid_ie - directed scan network information element
122 *
123 * Up to 20 of these may appear in REPLY_SCAN_CMD,
124 * selected by "type" bit field in struct iwl_scan_channel;
125 * each channel may select different ssids from among the 20 entries.
126 * SSID IEs get transmitted in reverse order of entry.
127 */
128struct iwl_ssid_ie {
129 u8 id;
130 u8 len;
131 u8 ssid[IEEE80211_MAX_SSID_LEN];
132} __packed; /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */
133
134/**
135 * iwl_scan_flags - masks for scan command flags
136 *@SCAN_FLAGS_PERIODIC_SCAN:
137 *@SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX:
138 *@SCAN_FLAGS_DELAYED_SCAN_LOWBAND:
139 *@SCAN_FLAGS_DELAYED_SCAN_HIGHBAND:
140 *@SCAN_FLAGS_FRAGMENTED_SCAN:
141 */
142enum iwl_scan_flags {
143 SCAN_FLAGS_PERIODIC_SCAN = BIT(0),
144 SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX = BIT(1),
145 SCAN_FLAGS_DELAYED_SCAN_LOWBAND = BIT(2),
146 SCAN_FLAGS_DELAYED_SCAN_HIGHBAND = BIT(3),
147 SCAN_FLAGS_FRAGMENTED_SCAN = BIT(4),
148};
149
150/**
151 * enum iwl_scan_type - Scan types for scan command
152 * @SCAN_TYPE_FORCED:
153 * @SCAN_TYPE_BACKGROUND:
154 * @SCAN_TYPE_OS:
155 * @SCAN_TYPE_ROAMING:
156 * @SCAN_TYPE_ACTION:
157 * @SCAN_TYPE_DISCOVERY:
158 * @SCAN_TYPE_DISCOVERY_FORCED:
159 */
160enum iwl_scan_type {
161 SCAN_TYPE_FORCED = 0,
162 SCAN_TYPE_BACKGROUND = 1,
163 SCAN_TYPE_OS = 2,
164 SCAN_TYPE_ROAMING = 3,
165 SCAN_TYPE_ACTION = 4,
166 SCAN_TYPE_DISCOVERY = 5,
167 SCAN_TYPE_DISCOVERY_FORCED = 6,
168}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */
169
170/* Maximal number of channels to scan */
171#define MAX_NUM_SCAN_CHANNELS 0x24
172
173/**
174 * struct iwl_scan_cmd - scan request command
175 * ( SCAN_REQUEST_CMD = 0x80 )
176 * @len: command length in bytes
177 * @scan_flags: scan flags from SCAN_FLAGS_*
178 * @channel_count: num of channels in channel list (1 - MAX_NUM_SCAN_CHANNELS)
179 * @quiet_time: in msecs, dwell this time for active scan on quiet channels
180 * @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
181 * this number of packets were received (typically 1)
182 * @passive2active: is auto switching from passive to active allowed (0 or 1)
183 * @rxchain_sel_flags: RXON_RX_CHAIN_*
184 * @max_out_time: in usecs, max out of serving channel time
185 * @suspend_time: how long to pause scan when returning to service channel:
186 * bits 0-19: beacon interal in usecs (suspend before executing)
187 * bits 20-23: reserved
188 * bits 24-31: number of beacons (suspend between channels)
189 * @rxon_flags: RXON_FLG_*
190 * @filter_flags: RXON_FILTER_*
191 * @tx_cmd: for active scans (zero for passive), w/o payload,
192 * no RS so specify TX rate
193 * @direct_scan: direct scan SSIDs
194 * @type: one of SCAN_TYPE_*
195 * @repeats: how many time to repeat the scan
196 */
197struct iwl_scan_cmd {
198 __le16 len;
199 u8 scan_flags;
200 u8 channel_count;
201 __le16 quiet_time;
202 __le16 quiet_plcp_th;
203 __le16 passive2active;
204 __le16 rxchain_sel_flags;
205 __le32 max_out_time;
206 __le32 suspend_time;
207 /* RX_ON_FLAGS_API_S_VER_1 */
208 __le32 rxon_flags;
209 __le32 filter_flags;
210 struct iwl_tx_cmd tx_cmd;
211 struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
212 __le32 type;
213 __le32 repeats;
214
215 /*
216 * Probe request frame, followed by channel list.
217 *
218 * Size of probe request frame is specified by byte count in tx_cmd.
219 * Channel list follows immediately after probe request frame.
220 * Number of channels in list is specified by channel_count.
221 * Each channel in list is of type:
222 *
223 * struct iwl_scan_channel channels[0];
224 *
225 * NOTE: Only one band of channels can be scanned per pass. You
226 * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
227 * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
228 * before requesting another scan.
229 */
230 u8 data[0];
231} __packed; /* SCAN_REQUEST_FIXED_PART_API_S_VER_5 */
232
233/* Response to scan request contains only status with one of these values */
234#define SCAN_RESPONSE_OK 0x1
235#define SCAN_RESPONSE_ERROR 0x2
236
237/*
238 * SCAN_ABORT_CMD = 0x81
239 * When scan abort is requested, the command has no fields except the common
240 * header. The response contains only a status with one of these values.
241 */
242#define SCAN_ABORT_POSSIBLE 0x1
243#define SCAN_ABORT_IGNORED 0x2 /* no pending scans */
244
245/* TODO: complete documentation */
246#define SCAN_OWNER_STATUS 0x1
247#define MEASURE_OWNER_STATUS 0x2
248
249/**
250 * struct iwl_scan_start_notif - notifies start of scan in the device
251 * ( SCAN_START_NOTIFICATION = 0x82 )
252 * @tsf_low: TSF timer (lower half) in usecs
253 * @tsf_high: TSF timer (higher half) in usecs
254 * @beacon_timer: structured as follows:
255 * bits 0:19 - beacon interval in usecs
256 * bits 20:23 - reserved (0)
257 * bits 24:31 - number of beacons
258 * @channel: which channel is scanned
259 * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
260 * @status: one of *_OWNER_STATUS
261 */
262struct iwl_scan_start_notif {
263 __le32 tsf_low;
264 __le32 tsf_high;
265 __le32 beacon_timer;
266 u8 channel;
267 u8 band;
268 u8 reserved[2];
269 __le32 status;
270} __packed; /* SCAN_START_NTF_API_S_VER_1 */
271
272/* scan results probe_status first bit indicates success */
273#define SCAN_PROBE_STATUS_OK 0
274#define SCAN_PROBE_STATUS_TX_FAILED BIT(0)
275/* error statuses combined with TX_FAILED */
276#define SCAN_PROBE_STATUS_FAIL_TTL BIT(1)
277#define SCAN_PROBE_STATUS_FAIL_BT BIT(2)
278
279/* How many statistics are gathered for each channel */
280#define SCAN_RESULTS_STATISTICS 1
281
282/**
283 * enum iwl_scan_complete_status - status codes for scan complete notifications
284 * @SCAN_COMP_STATUS_OK: scan completed successfully
285 * @SCAN_COMP_STATUS_ABORT: scan was aborted by user
286 * @SCAN_COMP_STATUS_ERR_SLEEP: sending null sleep packet failed
287 * @SCAN_COMP_STATUS_ERR_CHAN_TIMEOUT: timeout before channel is ready
288 * @SCAN_COMP_STATUS_ERR_PROBE: sending probe request failed
289 * @SCAN_COMP_STATUS_ERR_WAKEUP: sending null wakeup packet failed
290 * @SCAN_COMP_STATUS_ERR_ANTENNAS: invalid antennas chosen at scan command
291 * @SCAN_COMP_STATUS_ERR_INTERNAL: internal error caused scan abort
292 * @SCAN_COMP_STATUS_ERR_COEX: medium was lost ot WiMax
293 * @SCAN_COMP_STATUS_P2P_ACTION_OK: P2P public action frame TX was successful
294 * (not an error!)
295 * @SCAN_COMP_STATUS_ITERATION_END: indicates end of one repeatition the driver
296 * asked for
297 * @SCAN_COMP_STATUS_ERR_ALLOC_TE: scan could not allocate time events
298*/
299enum iwl_scan_complete_status {
300 SCAN_COMP_STATUS_OK = 0x1,
301 SCAN_COMP_STATUS_ABORT = 0x2,
302 SCAN_COMP_STATUS_ERR_SLEEP = 0x3,
303 SCAN_COMP_STATUS_ERR_CHAN_TIMEOUT = 0x4,
304 SCAN_COMP_STATUS_ERR_PROBE = 0x5,
305 SCAN_COMP_STATUS_ERR_WAKEUP = 0x6,
306 SCAN_COMP_STATUS_ERR_ANTENNAS = 0x7,
307 SCAN_COMP_STATUS_ERR_INTERNAL = 0x8,
308 SCAN_COMP_STATUS_ERR_COEX = 0x9,
309 SCAN_COMP_STATUS_P2P_ACTION_OK = 0xA,
310 SCAN_COMP_STATUS_ITERATION_END = 0x0B,
311 SCAN_COMP_STATUS_ERR_ALLOC_TE = 0x0C,
312};
313
314/**
315 * struct iwl_scan_results_notif - scan results for one channel
316 * ( SCAN_RESULTS_NOTIFICATION = 0x83 )
317 * @channel: which channel the results are from
318 * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
319 * @probe_status: SCAN_PROBE_STATUS_*, indicates success of probe request
320 * @num_probe_not_sent: # of request that weren't sent due to not enough time
321 * @duration: duration spent in channel, in usecs
322 * @statistics: statistics gathered for this channel
323 */
324struct iwl_scan_results_notif {
325 u8 channel;
326 u8 band;
327 u8 probe_status;
328 u8 num_probe_not_sent;
329 __le32 duration;
330 __le32 statistics[SCAN_RESULTS_STATISTICS];
331} __packed; /* SCAN_RESULT_NTF_API_S_VER_2 */
332
333/**
334 * struct iwl_scan_complete_notif - notifies end of scanning (all channels)
335 * ( SCAN_COMPLETE_NOTIFICATION = 0x84 )
336 * @scanned_channels: number of channels scanned (and number of valid results)
337 * @status: one of SCAN_COMP_STATUS_*
338 * @bt_status: BT on/off status
339 * @last_channel: last channel that was scanned
340 * @tsf_low: TSF timer (lower half) in usecs
341 * @tsf_high: TSF timer (higher half) in usecs
342 * @results: all scan results, only "scanned_channels" of them are valid
343 */
344struct iwl_scan_complete_notif {
345 u8 scanned_channels;
346 u8 status;
347 u8 bt_status;
348 u8 last_channel;
349 __le32 tsf_low;
350 __le32 tsf_high;
351 struct iwl_scan_results_notif results[MAX_NUM_SCAN_CHANNELS];
352} __packed; /* SCAN_COMPLETE_NTF_API_S_VER_2 */
353
354/* scan offload */
355#define IWL_MAX_SCAN_CHANNELS 40
356#define IWL_SCAN_MAX_BLACKLIST_LEN 64
357#define IWL_SCAN_MAX_PROFILES 11
358#define SCAN_OFFLOAD_PROBE_REQ_SIZE 512
359
360/* Default watchdog (in MS) for scheduled scan iteration */
361#define IWL_SCHED_SCAN_WATCHDOG cpu_to_le16(15000)
362
363#define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1)
364#define CAN_ABORT_STATUS 1
365
366#define IWL_FULL_SCAN_MULTIPLIER 5
367#define IWL_FAST_SCHED_SCAN_ITERATIONS 3
368
369/**
370 * struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6
371 * @scan_flags: see enum iwl_scan_flags
372 * @channel_count: channels in channel list
373 * @quiet_time: dwell time, in milisiconds, on quiet channel
374 * @quiet_plcp_th: quiet channel num of packets threshold
375 * @good_CRC_th: passive to active promotion threshold
376 * @rx_chain: RXON rx chain.
377 * @max_out_time: max uSec to be out of assoceated channel
378 * @suspend_time: pause scan this long when returning to service channel
379 * @flags: RXON flags
380 * @filter_flags: RXONfilter
381 * @tx_cmd: tx command for active scan; for 2GHz and for 5GHz.
382 * @direct_scan: list of SSIDs for directed active scan
383 * @scan_type: see enum iwl_scan_type.
384 * @rep_count: repetition count for each scheduled scan iteration.
385 */
386struct iwl_scan_offload_cmd {
387 __le16 len;
388 u8 scan_flags;
389 u8 channel_count;
390 __le16 quiet_time;
391 __le16 quiet_plcp_th;
392 __le16 good_CRC_th;
393 __le16 rx_chain;
394 __le32 max_out_time;
395 __le32 suspend_time;
396 /* RX_ON_FLAGS_API_S_VER_1 */
397 __le32 flags;
398 __le32 filter_flags;
399 struct iwl_tx_cmd tx_cmd[2];
400 /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */
401 struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
402 __le32 scan_type;
403 __le32 rep_count;
404} __packed;
405
406enum iwl_scan_offload_channel_flags {
407 IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE = BIT(0),
408 IWL_SCAN_OFFLOAD_CHANNEL_NARROW = BIT(22),
409 IWL_SCAN_OFFLOAD_CHANNEL_FULL = BIT(24),
410 IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL = BIT(25),
411};
412
413/**
414 * iwl_scan_channel_cfg - SCAN_CHANNEL_CFG_S
415 * @type: bitmap - see enum iwl_scan_offload_channel_flags.
416 * 0: passive (0) or active (1) scan.
417 * 1-20: directed scan to i'th ssid.
418 * 22: channel width configuation - 1 for narrow.
419 * 24: full scan.
420 * 25: partial scan.
421 * @channel_number: channel number 1-13 etc.
422 * @iter_count: repetition count for the channel.
423 * @iter_interval: interval between two innteration on one channel.
424 * @dwell_time: entry 0 - active scan, entry 1 - passive scan.
425 */
426struct iwl_scan_channel_cfg {
427 __le32 type[IWL_MAX_SCAN_CHANNELS];
428 __le16 channel_number[IWL_MAX_SCAN_CHANNELS];
429 __le16 iter_count[IWL_MAX_SCAN_CHANNELS];
430 __le32 iter_interval[IWL_MAX_SCAN_CHANNELS];
431 u8 dwell_time[IWL_MAX_SCAN_CHANNELS][2];
432} __packed;
433
434/**
435 * iwl_scan_offload_cfg - SCAN_OFFLOAD_CONFIG_API_S
436 * @scan_cmd: scan command fixed part
437 * @channel_cfg: scan channel configuration
438 * @data: probe request frames (one per band)
439 */
440struct iwl_scan_offload_cfg {
441 struct iwl_scan_offload_cmd scan_cmd;
442 struct iwl_scan_channel_cfg channel_cfg;
443 u8 data[0];
444} __packed;
445
446/**
447 * iwl_scan_offload_blacklist - SCAN_OFFLOAD_BLACKLIST_S
448 * @ssid: MAC address to filter out
449 * @reported_rssi: AP rssi reported to the host
450 */
451struct iwl_scan_offload_blacklist {
452 u8 ssid[ETH_ALEN];
453 u8 reported_rssi;
454 u8 reserved;
455} __packed;
456
457enum iwl_scan_offload_network_type {
458 IWL_NETWORK_TYPE_BSS = 1,
459 IWL_NETWORK_TYPE_IBSS = 2,
460 IWL_NETWORK_TYPE_ANY = 3,
461};
462
463enum iwl_scan_offload_band_selection {
464 IWL_SCAN_OFFLOAD_SELECT_2_4 = 0x4,
465 IWL_SCAN_OFFLOAD_SELECT_5_2 = 0x8,
466 IWL_SCAN_OFFLOAD_SELECT_ANY = 0xc,
467};
468
469/**
470 * iwl_scan_offload_profile - SCAN_OFFLOAD_PROFILE_S
471 * @ssid_index: index to ssid list in fixed part
472 * @unicast_cipher: encryption olgorithm to match - bitmap
473 * @aut_alg: authentication olgorithm to match - bitmap
474 * @network_type: enum iwl_scan_offload_network_type
475 * @band_selection: enum iwl_scan_offload_band_selection
476 */
477struct iwl_scan_offload_profile {
478 u8 ssid_index;
479 u8 unicast_cipher;
480 u8 auth_alg;
481 u8 network_type;
482 u8 band_selection;
483 u8 reserved[3];
484} __packed;
485
486/**
487 * iwl_scan_offload_profile_cfg - SCAN_OFFLOAD_PROFILES_CFG_API_S_VER_1
488 * @blaclist: AP list to filter off from scan results
489 * @profiles: profiles to search for match
490 * @blacklist_len: length of blacklist
491 * @num_profiles: num of profiles in the list
492 */
493struct iwl_scan_offload_profile_cfg {
494 struct iwl_scan_offload_blacklist blacklist[IWL_SCAN_MAX_BLACKLIST_LEN];
495 struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES];
496 u8 blacklist_len;
497 u8 num_profiles;
498 u8 reserved[2];
499} __packed;
500
501/**
502 * iwl_scan_offload_schedule - schedule of scan offload
503 * @delay: delay between iterations, in seconds.
504 * @iterations: num of scan iterations
505 * @full_scan_mul: number of partial scans before each full scan
506 */
507struct iwl_scan_offload_schedule {
508 u16 delay;
509 u8 iterations;
510 u8 full_scan_mul;
511} __packed;
512
513/*
514 * iwl_scan_offload_flags
515 *
516 * IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID: filter mode - upload every beacon or match
517 * ssid list.
518 * IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan.
519 * IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN: use energy based scan before partial scan
520 * on A band.
521 */
522enum iwl_scan_offload_flags {
523 IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID = BIT(0),
524 IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL = BIT(2),
525 IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN = BIT(3),
526};
527
528/**
529 * iwl_scan_offload_req - scan offload request command
530 * @flags: bitmap - enum iwl_scan_offload_flags.
531 * @watchdog: maximum scan duration in TU.
532 * @delay: delay in seconds before first iteration.
533 * @schedule_line: scan offload schedule, for fast and regular scan.
534 */
535struct iwl_scan_offload_req {
536 __le16 flags;
537 __le16 watchdog;
538 __le16 delay;
539 __le16 reserved;
540 struct iwl_scan_offload_schedule schedule_line[2];
541} __packed;
542
543enum iwl_scan_offload_compleate_status {
544 IWL_SCAN_OFFLOAD_COMPLETED = 1,
545 IWL_SCAN_OFFLOAD_ABORTED = 2,
546};
547
548/**
549 * iwl_scan_offload_complete - SCAN_OFFLOAD_COMPLETE_NTF_API_S_VER_1
550 * @last_schedule_line: last schedule line executed (fast or regular)
551 * @last_schedule_iteration: last scan iteration executed before scan abort
552 * @status: enum iwl_scan_offload_compleate_status
553 */
554struct iwl_scan_offload_complete {
555 u8 last_schedule_line;
556 u8 last_schedule_iteration;
557 u8 status;
558 u8 reserved;
559} __packed;
560
561#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
new file mode 100644
index 000000000000..0acb53dda22d
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -0,0 +1,380 @@
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 LICENSE.GPL.
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#ifndef __fw_api_sta_h__
64#define __fw_api_sta_h__
65
66/**
67 * enum iwl_sta_flags - flags for the ADD_STA host command
68 * @STA_FLG_REDUCED_TX_PWR_CTRL:
69 * @STA_FLG_REDUCED_TX_PWR_DATA:
70 * @STA_FLG_FLG_ANT_MSK: Antenna selection
71 * @STA_FLG_PS: set if STA is in Power Save
72 * @STA_FLG_INVALID: set if STA is invalid
73 * @STA_FLG_DLP_EN: Direct Link Protocol is enabled
74 * @STA_FLG_SET_ALL_KEYS: the current key applies to all key IDs
75 * @STA_FLG_DRAIN_FLOW: drain flow
76 * @STA_FLG_PAN: STA is for PAN interface
77 * @STA_FLG_CLASS_AUTH:
78 * @STA_FLG_CLASS_ASSOC:
79 * @STA_FLG_CLASS_MIMO_PROT:
80 * @STA_FLG_MAX_AGG_SIZE_MSK: maximal size for A-MPDU
81 * @STA_FLG_AGG_MPDU_DENS_MSK: maximal MPDU density for Tx aggregation
82 * @STA_FLG_FAT_EN_MSK: support for channel width (for Tx). This flag is
83 * initialised by driver and can be updated by fw upon reception of
84 * action frames that can change the channel width. When cleared the fw
85 * will send all the frames in 20MHz even when FAT channel is requested.
86 * @STA_FLG_MIMO_EN_MSK: support for MIMO. This flag is initialised by the
87 * driver and can be updated by fw upon reception of action frames.
88 * @STA_FLG_MFP_EN: Management Frame Protection
89 */
90enum iwl_sta_flags {
91 STA_FLG_REDUCED_TX_PWR_CTRL = BIT(3),
92 STA_FLG_REDUCED_TX_PWR_DATA = BIT(6),
93
94 STA_FLG_FLG_ANT_A = (1 << 4),
95 STA_FLG_FLG_ANT_B = (2 << 4),
96 STA_FLG_FLG_ANT_MSK = (STA_FLG_FLG_ANT_A |
97 STA_FLG_FLG_ANT_B),
98
99 STA_FLG_PS = BIT(8),
100 STA_FLG_INVALID = BIT(9),
101 STA_FLG_DLP_EN = BIT(10),
102 STA_FLG_SET_ALL_KEYS = BIT(11),
103 STA_FLG_DRAIN_FLOW = BIT(12),
104 STA_FLG_PAN = BIT(13),
105 STA_FLG_CLASS_AUTH = BIT(14),
106 STA_FLG_CLASS_ASSOC = BIT(15),
107 STA_FLG_RTS_MIMO_PROT = BIT(17),
108
109 STA_FLG_MAX_AGG_SIZE_SHIFT = 19,
110 STA_FLG_MAX_AGG_SIZE_8K = (0 << STA_FLG_MAX_AGG_SIZE_SHIFT),
111 STA_FLG_MAX_AGG_SIZE_16K = (1 << STA_FLG_MAX_AGG_SIZE_SHIFT),
112 STA_FLG_MAX_AGG_SIZE_32K = (2 << STA_FLG_MAX_AGG_SIZE_SHIFT),
113 STA_FLG_MAX_AGG_SIZE_64K = (3 << STA_FLG_MAX_AGG_SIZE_SHIFT),
114 STA_FLG_MAX_AGG_SIZE_128K = (4 << STA_FLG_MAX_AGG_SIZE_SHIFT),
115 STA_FLG_MAX_AGG_SIZE_256K = (5 << STA_FLG_MAX_AGG_SIZE_SHIFT),
116 STA_FLG_MAX_AGG_SIZE_512K = (6 << STA_FLG_MAX_AGG_SIZE_SHIFT),
117 STA_FLG_MAX_AGG_SIZE_1024K = (7 << STA_FLG_MAX_AGG_SIZE_SHIFT),
118 STA_FLG_MAX_AGG_SIZE_MSK = (7 << STA_FLG_MAX_AGG_SIZE_SHIFT),
119
120 STA_FLG_AGG_MPDU_DENS_SHIFT = 23,
121 STA_FLG_AGG_MPDU_DENS_2US = (4 << STA_FLG_AGG_MPDU_DENS_SHIFT),
122 STA_FLG_AGG_MPDU_DENS_4US = (5 << STA_FLG_AGG_MPDU_DENS_SHIFT),
123 STA_FLG_AGG_MPDU_DENS_8US = (6 << STA_FLG_AGG_MPDU_DENS_SHIFT),
124 STA_FLG_AGG_MPDU_DENS_16US = (7 << STA_FLG_AGG_MPDU_DENS_SHIFT),
125 STA_FLG_AGG_MPDU_DENS_MSK = (7 << STA_FLG_AGG_MPDU_DENS_SHIFT),
126
127 STA_FLG_FAT_EN_20MHZ = (0 << 26),
128 STA_FLG_FAT_EN_40MHZ = (1 << 26),
129 STA_FLG_FAT_EN_80MHZ = (2 << 26),
130 STA_FLG_FAT_EN_160MHZ = (3 << 26),
131 STA_FLG_FAT_EN_MSK = (3 << 26),
132
133 STA_FLG_MIMO_EN_SISO = (0 << 28),
134 STA_FLG_MIMO_EN_MIMO2 = (1 << 28),
135 STA_FLG_MIMO_EN_MIMO3 = (2 << 28),
136 STA_FLG_MIMO_EN_MSK = (3 << 28),
137};
138
139/**
140 * enum iwl_sta_key_flag - key flags for the ADD_STA host command
141 * @STA_KEY_FLG_EN_MSK: mask for encryption algorithm
142 * @STA_KEY_FLG_WEP_KEY_MAP: wep is either a group key (0 - legacy WEP) or from
143 * station info array (1 - n 1X mode)
144 * @STA_KEY_FLG_KEYID_MSK: the index of the key
145 * @STA_KEY_NOT_VALID: key is invalid
146 * @STA_KEY_FLG_WEP_13BYTES: set for 13 bytes WEP key
147 * @STA_KEY_MULTICAST: set for multical key
148 * @STA_KEY_MFP: key is used for Management Frame Protection
149 */
150enum iwl_sta_key_flag {
151 STA_KEY_FLG_NO_ENC = (0 << 0),
152 STA_KEY_FLG_WEP = (1 << 0),
153 STA_KEY_FLG_CCM = (2 << 0),
154 STA_KEY_FLG_TKIP = (3 << 0),
155 STA_KEY_FLG_CMAC = (6 << 0),
156 STA_KEY_FLG_ENC_UNKNOWN = (7 << 0),
157 STA_KEY_FLG_EN_MSK = (7 << 0),
158
159 STA_KEY_FLG_WEP_KEY_MAP = BIT(3),
160 STA_KEY_FLG_KEYID_POS = 8,
161 STA_KEY_FLG_KEYID_MSK = (3 << STA_KEY_FLG_KEYID_POS),
162 STA_KEY_NOT_VALID = BIT(11),
163 STA_KEY_FLG_WEP_13BYTES = BIT(12),
164 STA_KEY_MULTICAST = BIT(14),
165 STA_KEY_MFP = BIT(15),
166};
167
168/**
169 * enum iwl_sta_modify_flag - indicate to the fw what flag are being changed
170 * @STA_MODIFY_KEY: this command modifies %key
171 * @STA_MODIFY_TID_DISABLE_TX: this command modifies %tid_disable_tx
172 * @STA_MODIFY_TX_RATE: unused
173 * @STA_MODIFY_ADD_BA_TID: this command modifies %add_immediate_ba_tid
174 * @STA_MODIFY_REMOVE_BA_TID: this command modifies %remove_immediate_ba_tid
175 * @STA_MODIFY_SLEEPING_STA_TX_COUNT: this command modifies %sleep_tx_count
176 * @STA_MODIFY_PROT_TH:
177 * @STA_MODIFY_QUEUES: modify the queues used by this station
178 */
179enum iwl_sta_modify_flag {
180 STA_MODIFY_KEY = BIT(0),
181 STA_MODIFY_TID_DISABLE_TX = BIT(1),
182 STA_MODIFY_TX_RATE = BIT(2),
183 STA_MODIFY_ADD_BA_TID = BIT(3),
184 STA_MODIFY_REMOVE_BA_TID = BIT(4),
185 STA_MODIFY_SLEEPING_STA_TX_COUNT = BIT(5),
186 STA_MODIFY_PROT_TH = BIT(6),
187 STA_MODIFY_QUEUES = BIT(7),
188};
189
190#define STA_MODE_MODIFY 1
191
192/**
193 * enum iwl_sta_sleep_flag - type of sleep of the station
194 * @STA_SLEEP_STATE_AWAKE:
195 * @STA_SLEEP_STATE_PS_POLL:
196 * @STA_SLEEP_STATE_UAPSD:
197 */
198enum iwl_sta_sleep_flag {
199 STA_SLEEP_STATE_AWAKE = 0,
200 STA_SLEEP_STATE_PS_POLL = BIT(0),
201 STA_SLEEP_STATE_UAPSD = BIT(1),
202};
203
204/* STA ID and color bits definitions */
205#define STA_ID_SEED (0x0f)
206#define STA_ID_POS (0)
207#define STA_ID_MSK (STA_ID_SEED << STA_ID_POS)
208
209#define STA_COLOR_SEED (0x7)
210#define STA_COLOR_POS (4)
211#define STA_COLOR_MSK (STA_COLOR_SEED << STA_COLOR_POS)
212
213#define STA_ID_N_COLOR_GET_COLOR(id_n_color) \
214 (((id_n_color) & STA_COLOR_MSK) >> STA_COLOR_POS)
215#define STA_ID_N_COLOR_GET_ID(id_n_color) \
216 (((id_n_color) & STA_ID_MSK) >> STA_ID_POS)
217
218#define STA_KEY_MAX_NUM (16)
219#define STA_KEY_IDX_INVALID (0xff)
220#define STA_KEY_MAX_DATA_KEY_NUM (4)
221#define IWL_MAX_GLOBAL_KEYS (4)
222#define STA_KEY_LEN_WEP40 (5)
223#define STA_KEY_LEN_WEP104 (13)
224
225/**
226 * struct iwl_mvm_keyinfo - key information
227 * @key_flags: type %iwl_sta_key_flag
228 * @tkip_rx_tsc_byte2: TSC[2] for key mix ph1 detection
229 * @tkip_rx_ttak: 10-byte unicast TKIP TTAK for Rx
230 * @key_offset: key offset in the fw's key table
231 * @key: 16-byte unicast decryption key
232 * @tx_secur_seq_cnt: initial RSC / PN needed for replay check
233 * @hw_tkip_mic_rx_key: byte: MIC Rx Key - used for TKIP only
234 * @hw_tkip_mic_tx_key: byte: MIC Tx Key - used for TKIP only
235 */
236struct iwl_mvm_keyinfo {
237 __le16 key_flags;
238 u8 tkip_rx_tsc_byte2;
239 u8 reserved1;
240 __le16 tkip_rx_ttak[5];
241 u8 key_offset;
242 u8 reserved2;
243 u8 key[16];
244 __le64 tx_secur_seq_cnt;
245 __le64 hw_tkip_mic_rx_key;
246 __le64 hw_tkip_mic_tx_key;
247} __packed;
248
249/**
250 * struct iwl_mvm_add_sta_cmd - Add / modify a station in the fw's station table
251 * ( REPLY_ADD_STA = 0x18 )
252 * @add_modify: 1: modify existing, 0: add new station
253 * @unicast_tx_key_id: unicast tx key id. Relevant only when unicast key sent
254 * @multicast_tx_key_id: multicast tx key id. Relevant only when multicast key
255 * sent
256 * @mac_id_n_color: the Mac context this station belongs to
257 * @addr[ETH_ALEN]: station's MAC address
258 * @sta_id: index of station in uCode's station table
259 * @modify_mask: STA_MODIFY_*, selects which parameters to modify vs. leave
260 * alone. 1 - modify, 0 - don't change.
261 * @key: look at %iwl_mvm_keyinfo
262 * @station_flags: look at %iwl_sta_flags
263 * @station_flags_msk: what of %station_flags have changed
264 * @tid_disable_tx: is tid BIT(tid) enabled for Tx. Clear BIT(x) to enable
265 * AMPDU for tid x. Set %STA_MODIFY_TID_DISABLE_TX to change this field.
266 * @add_immediate_ba_tid: tid for which to add block-ack support (Rx)
267 * Set %STA_MODIFY_ADD_BA_TID to use this field, and also set
268 * add_immediate_ba_ssn.
269 * @remove_immediate_ba_tid: tid for which to remove block-ack support (Rx)
270 * Set %STA_MODIFY_REMOVE_BA_TID to use this field
271 * @add_immediate_ba_ssn: ssn for the Rx block-ack session. Used together with
272 * add_immediate_ba_tid.
273 * @sleep_tx_count: number of packets to transmit to station even though it is
274 * asleep. Used to synchronise PS-poll and u-APSD responses while ucode
275 * keeps track of STA sleep state.
276 * @sleep_state_flags: Look at %iwl_sta_sleep_flag.
277 * @assoc_id: assoc_id to be sent in VHT PLCP (9-bit), for grp use 0, for AP
278 * mac-addr.
279 * @beamform_flags: beam forming controls
280 * @tfd_queue_msk: tfd queues used by this station
281 *
282 * The device contains an internal table of per-station information, with info
283 * on security keys, aggregation parameters, and Tx rates for initial Tx
284 * attempt and any retries (set by REPLY_TX_LINK_QUALITY_CMD).
285 *
286 * ADD_STA sets up the table entry for one station, either creating a new
287 * entry, or modifying a pre-existing one.
288 */
289struct iwl_mvm_add_sta_cmd {
290 u8 add_modify;
291 u8 unicast_tx_key_id;
292 u8 multicast_tx_key_id;
293 u8 reserved1;
294 __le32 mac_id_n_color;
295 u8 addr[ETH_ALEN];
296 __le16 reserved2;
297 u8 sta_id;
298 u8 modify_mask;
299 __le16 reserved3;
300 struct iwl_mvm_keyinfo key;
301 __le32 station_flags;
302 __le32 station_flags_msk;
303 __le16 tid_disable_tx;
304 __le16 reserved4;
305 u8 add_immediate_ba_tid;
306 u8 remove_immediate_ba_tid;
307 __le16 add_immediate_ba_ssn;
308 __le16 sleep_tx_count;
309 __le16 sleep_state_flags;
310 __le16 assoc_id;
311 __le16 beamform_flags;
312 __le32 tfd_queue_msk;
313} __packed; /* ADD_STA_CMD_API_S_VER_5 */
314
315/**
316 * enum iwl_mvm_add_sta_rsp_status - status in the response to ADD_STA command
317 * @ADD_STA_SUCCESS: operation was executed successfully
318 * @ADD_STA_STATIONS_OVERLOAD: no room left in the fw's station table
319 * @ADD_STA_IMMEDIATE_BA_FAILURE: can't add Rx block ack session
320 * @ADD_STA_MODIFY_NON_EXISTING_STA: driver requested to modify a station that
321 * doesn't exist.
322 */
323enum iwl_mvm_add_sta_rsp_status {
324 ADD_STA_SUCCESS = 0x1,
325 ADD_STA_STATIONS_OVERLOAD = 0x2,
326 ADD_STA_IMMEDIATE_BA_FAILURE = 0x4,
327 ADD_STA_MODIFY_NON_EXISTING_STA = 0x8,
328};
329
330/**
331 * struct iwl_mvm_rm_sta_cmd - Add / modify a station in the fw's station table
332 * ( REMOVE_STA = 0x19 )
333 * @sta_id: the station id of the station to be removed
334 */
335struct iwl_mvm_rm_sta_cmd {
336 u8 sta_id;
337 u8 reserved[3];
338} __packed; /* REMOVE_STA_CMD_API_S_VER_2 */
339
340/**
341 * struct iwl_mvm_mgmt_mcast_key_cmd
342 * ( MGMT_MCAST_KEY = 0x1f )
343 * @ctrl_flags: %iwl_sta_key_flag
344 * @IGTK:
345 * @K1: IGTK master key
346 * @K2: IGTK sub key
347 * @sta_id: station ID that support IGTK
348 * @key_id:
349 * @receive_seq_cnt: initial RSC/PN needed for replay check
350 */
351struct iwl_mvm_mgmt_mcast_key_cmd {
352 __le32 ctrl_flags;
353 u8 IGTK[16];
354 u8 K1[16];
355 u8 K2[16];
356 __le32 key_id;
357 __le32 sta_id;
358 __le64 receive_seq_cnt;
359} __packed; /* SEC_MGMT_MULTICAST_KEY_CMD_API_S_VER_1 */
360
361struct iwl_mvm_wep_key {
362 u8 key_index;
363 u8 key_offset;
364 __le16 reserved1;
365 u8 key_size;
366 u8 reserved2[3];
367 u8 key[16];
368} __packed;
369
370struct iwl_mvm_wep_key_cmd {
371 __le32 mac_id_n_color;
372 u8 num_keys;
373 u8 decryption_type;
374 u8 flags;
375 u8 reserved;
376 struct iwl_mvm_wep_key wep_key[0];
377} __packed; /* SEC_CURR_WEP_KEY_CMD_API_S_VER_2 */
378
379
380#endif /* __fw_api_sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
new file mode 100644
index 000000000000..2677914bf0a6
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -0,0 +1,580 @@
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 LICENSE.GPL.
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#ifndef __fw_api_tx_h__
64#define __fw_api_tx_h__
65
66/**
67 * enum iwl_tx_flags - bitmasks for tx_flags in TX command
68 * @TX_CMD_FLG_PROT_REQUIRE: use RTS or CTS-to-self to protect the frame
69 * @TX_CMD_FLG_ACK: expect ACK from receiving station
70 * @TX_CMD_FLG_STA_RATE: use RS table with initial index from the TX command.
71 * Otherwise, use rate_n_flags from the TX command
72 * @TX_CMD_FLG_BA: this frame is a block ack
73 * @TX_CMD_FLG_BAR: this frame is a BA request, immediate BAR is expected
74 * Must set TX_CMD_FLG_ACK with this flag.
75 * @TX_CMD_FLG_TXOP_PROT: protect frame with full TXOP protection
76 * @TX_CMD_FLG_VHT_NDPA: mark frame is NDPA for VHT beamformer sequence
77 * @TX_CMD_FLG_HT_NDPA: mark frame is NDPA for HT beamformer sequence
78 * @TX_CMD_FLG_CSI_FDBK2HOST: mark to send feedback to host (only if good CRC)
79 * @TX_CMD_FLG_BT_DIS: disable BT priority for this frame
80 * @TX_CMD_FLG_SEQ_CTL: set if FW should override the sequence control.
81 * Should be set for mgmt, non-QOS data, mcast, bcast and in scan command
82 * @TX_CMD_FLG_MORE_FRAG: this frame is non-last MPDU
83 * @TX_CMD_FLG_NEXT_FRAME: this frame includes information of the next frame
84 * @TX_CMD_FLG_TSF: FW should calculate and insert TSF in the frame
85 * Should be set for beacons and probe responses
86 * @TX_CMD_FLG_CALIB: activate PA TX power calibrations
87 * @TX_CMD_FLG_KEEP_SEQ_CTL: if seq_ctl is set, don't increase inner seq count
88 * @TX_CMD_FLG_AGG_START: allow this frame to start aggregation
89 * @TX_CMD_FLG_MH_PAD: driver inserted 2 byte padding after MAC header.
90 * Should be set for 26/30 length MAC headers
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
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
96 * @TX_CMD_FLG_FW_DROP: FW should mark frame to be dropped
97 * @TX_CMD_FLG_EXEC_PAPD: execute PAPD
98 * @TX_CMD_FLG_PAPD_TYPE: 0 for reference power, 1 for nominal power
99 * @TX_CMD_FLG_HCCA_CHUNK: mark start of TSPEC chunk
100 */
101enum iwl_tx_flags {
102 TX_CMD_FLG_PROT_REQUIRE = BIT(0),
103 TX_CMD_FLG_ACK = BIT(3),
104 TX_CMD_FLG_STA_RATE = BIT(4),
105 TX_CMD_FLG_BA = BIT(5),
106 TX_CMD_FLG_BAR = BIT(6),
107 TX_CMD_FLG_TXOP_PROT = BIT(7),
108 TX_CMD_FLG_VHT_NDPA = BIT(8),
109 TX_CMD_FLG_HT_NDPA = BIT(9),
110 TX_CMD_FLG_CSI_FDBK2HOST = BIT(10),
111 TX_CMD_FLG_BT_DIS = BIT(12),
112 TX_CMD_FLG_SEQ_CTL = BIT(13),
113 TX_CMD_FLG_MORE_FRAG = BIT(14),
114 TX_CMD_FLG_NEXT_FRAME = BIT(15),
115 TX_CMD_FLG_TSF = BIT(16),
116 TX_CMD_FLG_CALIB = BIT(17),
117 TX_CMD_FLG_KEEP_SEQ_CTL = BIT(18),
118 TX_CMD_FLG_AGG_START = BIT(19),
119 TX_CMD_FLG_MH_PAD = BIT(20),
120 TX_CMD_FLG_RESP_TO_DRV = BIT(21),
121 TX_CMD_FLG_CCMP_AGG = BIT(22),
122 TX_CMD_FLG_TKIP_MIC_DONE = BIT(23),
123 TX_CMD_FLG_CTS_ONLY = BIT(24),
124 TX_CMD_FLG_DUR = BIT(25),
125 TX_CMD_FLG_FW_DROP = BIT(26),
126 TX_CMD_FLG_EXEC_PAPD = BIT(27),
127 TX_CMD_FLG_PAPD_TYPE = BIT(28),
128 TX_CMD_FLG_HCCA_CHUNK = BIT(31)
129}; /* TX_FLAGS_BITS_API_S_VER_1 */
130
131/*
132 * TX command security control
133 */
134#define TX_CMD_SEC_WEP 0x01
135#define TX_CMD_SEC_CCM 0x02
136#define TX_CMD_SEC_TKIP 0x03
137#define TX_CMD_SEC_WEP_KEY_IDX_POS 6
138#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0
139#define TX_CMD_SEC_KEY128 0x08
140
141/* TODO: how does these values are OK with only 16 bit variable??? */
142/*
143 * TX command next frame info
144 *
145 * bits 0:2 - security control (TX_CMD_SEC_*)
146 * bit 3 - immediate ACK required
147 * bit 4 - rate is taken from STA table
148 * bit 5 - frame belongs to BA stream
149 * bit 6 - immediate BA response expected
150 * bit 7 - unused
151 * bits 8:15 - Station ID
152 * bits 16:31 - rate
153 */
154#define TX_CMD_NEXT_FRAME_ACK_MSK (0x8)
155#define TX_CMD_NEXT_FRAME_STA_RATE_MSK (0x10)
156#define TX_CMD_NEXT_FRAME_BA_MSK (0x20)
157#define TX_CMD_NEXT_FRAME_IMM_BA_RSP_MSK (0x40)
158#define TX_CMD_NEXT_FRAME_FLAGS_MSK (0xf8)
159#define TX_CMD_NEXT_FRAME_STA_ID_MSK (0xff00)
160#define TX_CMD_NEXT_FRAME_STA_ID_POS (8)
161#define TX_CMD_NEXT_FRAME_RATE_MSK (0xffff0000)
162#define TX_CMD_NEXT_FRAME_RATE_POS (16)
163
164/*
165 * TX command Frame life time in us - to be written in pm_frame_timeout
166 */
167#define TX_CMD_LIFE_TIME_INFINITE 0xFFFFFFFF
168#define TX_CMD_LIFE_TIME_DEFAULT 2000000 /* 2000 ms*/
169#define TX_CMD_LIFE_TIME_PROBE_RESP 40000 /* 40 ms */
170#define TX_CMD_LIFE_TIME_EXPIRED_FRAME 0
171
172/*
173 * TID for non QoS frames - to be written in tid_tspec
174 */
175#define IWL_TID_NON_QOS IWL_MAX_TID_COUNT
176
177/*
178 * Limits on the retransmissions - to be written in {data,rts}_retry_limit
179 */
180#define IWL_DEFAULT_TX_RETRY 15
181#define IWL_MGMT_DFAULT_RETRY_LIMIT 3
182#define IWL_RTS_DFAULT_RETRY_LIMIT 60
183#define IWL_BAR_DFAULT_RETRY_LIMIT 60
184#define IWL_LOW_RETRY_LIMIT 7
185
186/* TODO: complete documentation for try_cnt and btkill_cnt */
187/**
188 * struct iwl_tx_cmd - TX command struct to FW
189 * ( TX_CMD = 0x1c )
190 * @len: in bytes of the payload, see below for details
191 * @next_frame_len: same as len, but for next frame (0 if not applicable)
192 * Used for fragmentation and bursting, but not in 11n aggregation.
193 * @tx_flags: combination of TX_CMD_FLG_*
194 * @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is
195 * cleared. Combination of RATE_MCS_*
196 * @sta_id: index of destination station in FW station table
197 * @sec_ctl: security control, TX_CMD_SEC_*
198 * @initial_rate_index: index into the the rate table for initial TX attempt.
199 * Applied if TX_CMD_FLG_STA_RATE_MSK is set, normally 0 for data frames.
200 * @key: security key
201 * @next_frame_flags: TX_CMD_SEC_* and TX_CMD_NEXT_FRAME_*
202 * @life_time: frame life time (usecs??)
203 * @dram_lsb_ptr: Physical address of scratch area in the command (try_cnt +
204 * btkill_cnd + reserved), first 32 bits. "0" disables usage.
205 * @dram_msb_ptr: upper bits of the scratch physical address
206 * @rts_retry_limit: max attempts for RTS
207 * @data_retry_limit: max attempts to send the data packet
208 * @tid_spec: TID/tspec
209 * @pm_frame_timeout: PM TX frame timeout
210 * @driver_txop: duration od EDCA TXOP, in 32-usec units. Set this if not
211 * specified by HCCA protocol
212 *
213 * The byte count (both len and next_frame_len) includes MAC header
214 * (24/26/30/32 bytes)
215 * + 2 bytes pad if 26/30 header size
216 * + 8 byte IV for CCM or TKIP (not used for WEP)
217 * + Data payload
218 * + 8-byte MIC (not used for CCM/WEP)
219 * It does not include post-MAC padding, i.e.,
220 * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.
221 * Range of len: 14-2342 bytes.
222 *
223 * After the struct fields the MAC header is placed, plus any padding,
224 * and then the actial payload.
225 */
226struct iwl_tx_cmd {
227 __le16 len;
228 __le16 next_frame_len;
229 __le32 tx_flags;
230 /* DRAM_SCRATCH_API_U_VER_1 */
231 u8 try_cnt;
232 u8 btkill_cnt;
233 __le16 reserved;
234 __le32 rate_n_flags;
235 u8 sta_id;
236 u8 sec_ctl;
237 u8 initial_rate_index;
238 u8 reserved2;
239 u8 key[16];
240 __le16 next_frame_flags;
241 __le16 reserved3;
242 __le32 life_time;
243 __le32 dram_lsb_ptr;
244 u8 dram_msb_ptr;
245 u8 rts_retry_limit;
246 u8 data_retry_limit;
247 u8 tid_tspec;
248 __le16 pm_frame_timeout;
249 __le16 driver_txop;
250 u8 payload[0];
251 struct ieee80211_hdr hdr[0];
252} __packed; /* TX_CMD_API_S_VER_3 */
253
254/*
255 * TX response related data
256 */
257
258/*
259 * enum iwl_tx_status - status that is returned by the fw after attempts to Tx
260 * @TX_STATUS_SUCCESS:
261 * @TX_STATUS_DIRECT_DONE:
262 * @TX_STATUS_POSTPONE_DELAY:
263 * @TX_STATUS_POSTPONE_FEW_BYTES:
264 * @TX_STATUS_POSTPONE_BT_PRIO:
265 * @TX_STATUS_POSTPONE_QUIET_PERIOD:
266 * @TX_STATUS_POSTPONE_CALC_TTAK:
267 * @TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY:
268 * @TX_STATUS_FAIL_SHORT_LIMIT:
269 * @TX_STATUS_FAIL_LONG_LIMIT:
270 * @TX_STATUS_FAIL_UNDERRUN:
271 * @TX_STATUS_FAIL_DRAIN_FLOW:
272 * @TX_STATUS_FAIL_RFKILL_FLUSH:
273 * @TX_STATUS_FAIL_LIFE_EXPIRE:
274 * @TX_STATUS_FAIL_DEST_PS:
275 * @TX_STATUS_FAIL_HOST_ABORTED:
276 * @TX_STATUS_FAIL_BT_RETRY:
277 * @TX_STATUS_FAIL_STA_INVALID:
278 * @TX_TATUS_FAIL_FRAG_DROPPED:
279 * @TX_STATUS_FAIL_TID_DISABLE:
280 * @TX_STATUS_FAIL_FIFO_FLUSHED:
281 * @TX_STATUS_FAIL_SMALL_CF_POLL:
282 * @TX_STATUS_FAIL_FW_DROP:
283 * @TX_STATUS_FAIL_STA_COLOR_MISMATCH: mismatch between color of Tx cmd and
284 * STA table
285 * @TX_FRAME_STATUS_INTERNAL_ABORT:
286 * @TX_MODE_MSK:
287 * @TX_MODE_NO_BURST:
288 * @TX_MODE_IN_BURST_SEQ:
289 * @TX_MODE_FIRST_IN_BURST:
290 * @TX_QUEUE_NUM_MSK:
291 *
292 * Valid only if frame_count =1
293 * TODO: complete documentation
294 */
295enum iwl_tx_status {
296 TX_STATUS_MSK = 0x000000ff,
297 TX_STATUS_SUCCESS = 0x01,
298 TX_STATUS_DIRECT_DONE = 0x02,
299 /* postpone TX */
300 TX_STATUS_POSTPONE_DELAY = 0x40,
301 TX_STATUS_POSTPONE_FEW_BYTES = 0x41,
302 TX_STATUS_POSTPONE_BT_PRIO = 0x42,
303 TX_STATUS_POSTPONE_QUIET_PERIOD = 0x43,
304 TX_STATUS_POSTPONE_CALC_TTAK = 0x44,
305 /* abort TX */
306 TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY = 0x81,
307 TX_STATUS_FAIL_SHORT_LIMIT = 0x82,
308 TX_STATUS_FAIL_LONG_LIMIT = 0x83,
309 TX_STATUS_FAIL_UNDERRUN = 0x84,
310 TX_STATUS_FAIL_DRAIN_FLOW = 0x85,
311 TX_STATUS_FAIL_RFKILL_FLUSH = 0x86,
312 TX_STATUS_FAIL_LIFE_EXPIRE = 0x87,
313 TX_STATUS_FAIL_DEST_PS = 0x88,
314 TX_STATUS_FAIL_HOST_ABORTED = 0x89,
315 TX_STATUS_FAIL_BT_RETRY = 0x8a,
316 TX_STATUS_FAIL_STA_INVALID = 0x8b,
317 TX_STATUS_FAIL_FRAG_DROPPED = 0x8c,
318 TX_STATUS_FAIL_TID_DISABLE = 0x8d,
319 TX_STATUS_FAIL_FIFO_FLUSHED = 0x8e,
320 TX_STATUS_FAIL_SMALL_CF_POLL = 0x8f,
321 TX_STATUS_FAIL_FW_DROP = 0x90,
322 TX_STATUS_FAIL_STA_COLOR_MISMATCH = 0x91,
323 TX_STATUS_INTERNAL_ABORT = 0x92,
324 TX_MODE_MSK = 0x00000f00,
325 TX_MODE_NO_BURST = 0x00000000,
326 TX_MODE_IN_BURST_SEQ = 0x00000100,
327 TX_MODE_FIRST_IN_BURST = 0x00000200,
328 TX_QUEUE_NUM_MSK = 0x0001f000,
329 TX_NARROW_BW_MSK = 0x00060000,
330 TX_NARROW_BW_1DIV2 = 0x00020000,
331 TX_NARROW_BW_1DIV4 = 0x00040000,
332 TX_NARROW_BW_1DIV8 = 0x00060000,
333};
334
335/*
336 * enum iwl_tx_agg_status - TX aggregation status
337 * @AGG_TX_STATE_STATUS_MSK:
338 * @AGG_TX_STATE_TRANSMITTED:
339 * @AGG_TX_STATE_UNDERRUN:
340 * @AGG_TX_STATE_BT_PRIO:
341 * @AGG_TX_STATE_FEW_BYTES:
342 * @AGG_TX_STATE_ABORT:
343 * @AGG_TX_STATE_LAST_SENT_TTL:
344 * @AGG_TX_STATE_LAST_SENT_TRY_CNT:
345 * @AGG_TX_STATE_LAST_SENT_BT_KILL:
346 * @AGG_TX_STATE_SCD_QUERY:
347 * @AGG_TX_STATE_TEST_BAD_CRC32:
348 * @AGG_TX_STATE_RESPONSE:
349 * @AGG_TX_STATE_DUMP_TX:
350 * @AGG_TX_STATE_DELAY_TX:
351 * @AGG_TX_STATE_TRY_CNT_MSK: Retry count for 1st frame in aggregation (retries
352 * occur if tx failed for this frame when it was a member of a previous
353 * aggregation block). If rate scaling is used, retry count indicates the
354 * rate table entry used for all frames in the new agg.
355 *@ AGG_TX_STATE_SEQ_NUM_MSK: Command ID and sequence number of Tx command for
356 * this frame
357 *
358 * TODO: complete documentation
359 */
360enum iwl_tx_agg_status {
361 AGG_TX_STATE_STATUS_MSK = 0x00fff,
362 AGG_TX_STATE_TRANSMITTED = 0x000,
363 AGG_TX_STATE_UNDERRUN = 0x001,
364 AGG_TX_STATE_BT_PRIO = 0x002,
365 AGG_TX_STATE_FEW_BYTES = 0x004,
366 AGG_TX_STATE_ABORT = 0x008,
367 AGG_TX_STATE_LAST_SENT_TTL = 0x010,
368 AGG_TX_STATE_LAST_SENT_TRY_CNT = 0x020,
369 AGG_TX_STATE_LAST_SENT_BT_KILL = 0x040,
370 AGG_TX_STATE_SCD_QUERY = 0x080,
371 AGG_TX_STATE_TEST_BAD_CRC32 = 0x0100,
372 AGG_TX_STATE_RESPONSE = 0x1ff,
373 AGG_TX_STATE_DUMP_TX = 0x200,
374 AGG_TX_STATE_DELAY_TX = 0x400,
375 AGG_TX_STATE_TRY_CNT_POS = 12,
376 AGG_TX_STATE_TRY_CNT_MSK = 0xf << AGG_TX_STATE_TRY_CNT_POS,
377};
378
379#define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL| \
380 AGG_TX_STATE_LAST_SENT_TRY_CNT| \
381 AGG_TX_STATE_LAST_SENT_BT_KILL)
382
383/*
384 * The mask below describes a status where we are absolutely sure that the MPDU
385 * wasn't sent. For BA/Underrun we cannot be that sure. All we know that we've
386 * written the bytes to the TXE, but we know nothing about what the DSP did.
387 */
388#define AGG_TX_STAT_FRAME_NOT_SENT (AGG_TX_STATE_FEW_BYTES | \
389 AGG_TX_STATE_ABORT | \
390 AGG_TX_STATE_SCD_QUERY)
391
392/*
393 * REPLY_TX = 0x1c (response)
394 *
395 * This response may be in one of two slightly different formats, indicated
396 * by the frame_count field:
397 *
398 * 1) No aggregation (frame_count == 1). This reports Tx results for a single
399 * frame. Multiple attempts, at various bit rates, may have been made for
400 * this frame.
401 *
402 * 2) Aggregation (frame_count > 1). This reports Tx results for two or more
403 * frames that used block-acknowledge. All frames were transmitted at
404 * same rate. Rate scaling may have been used if first frame in this new
405 * agg block failed in previous agg block(s).
406 *
407 * Note that, for aggregation, ACK (block-ack) status is not delivered
408 * here; block-ack has not been received by the time the device records
409 * this status.
410 * This status relates to reasons the tx might have been blocked or aborted
411 * within the device, rather than whether it was received successfully by
412 * the destination station.
413 */
414
415/**
416 * struct agg_tx_status - per packet TX aggregation status
417 * @status: enum iwl_tx_agg_status
418 * @sequence: Sequence # for this frame's Tx cmd (not SSN!)
419 */
420struct agg_tx_status {
421 __le16 status;
422 __le16 sequence;
423} __packed;
424
425/*
426 * definitions for initial rate index field
427 * bits [3:0] initial rate index
428 * bits [6:4] rate table color, used for the initial rate
429 * bit-7 invalid rate indication
430 */
431#define TX_RES_INIT_RATE_INDEX_MSK 0x0f
432#define TX_RES_RATE_TABLE_COLOR_MSK 0x70
433#define TX_RES_INV_RATE_INDEX_MSK 0x80
434
435#define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f)
436#define IWL_MVM_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4)
437
438/**
439 * struct iwl_mvm_tx_resp - notifies that fw is TXing a packet
440 * ( REPLY_TX = 0x1c )
441 * @frame_count: 1 no aggregation, >1 aggregation
442 * @bt_kill_count: num of times blocked by bluetooth (unused for agg)
443 * @failure_rts: num of failures due to unsuccessful RTS
444 * @failure_frame: num failures due to no ACK (unused for agg)
445 * @initial_rate: for non-agg: rate of the successful Tx. For agg: rate of the
446 * Tx of all the batch. RATE_MCS_*
447 * @wireless_media_time: for non-agg: RTS + CTS + frame tx attempts time + ACK.
448 * for agg: RTS + CTS + aggregation tx time + block-ack time.
449 * in usec.
450 * @pa_status: tx power info
451 * @pa_integ_res_a: tx power info
452 * @pa_integ_res_b: tx power info
453 * @pa_integ_res_c: tx power info
454 * @measurement_req_id: tx power info
455 * @tfd_info: TFD information set by the FH
456 * @seq_ctl: sequence control from the Tx cmd
457 * @byte_cnt: byte count from the Tx cmd
458 * @tlc_info: TLC rate info
459 * @ra_tid: bits [3:0] = ra, bits [7:4] = tid
460 * @frame_ctrl: frame control
461 * @status: for non-agg: frame status TX_STATUS_*
462 * for agg: status of 1st frame, AGG_TX_STATE_*; other frame status fields
463 * follow this one, up to frame_count.
464 *
465 * After the array of statuses comes the SSN of the SCD. Look at
466 * %iwl_mvm_get_scd_ssn for more details.
467 */
468struct iwl_mvm_tx_resp {
469 u8 frame_count;
470 u8 bt_kill_count;
471 u8 failure_rts;
472 u8 failure_frame;
473 __le32 initial_rate;
474 __le16 wireless_media_time;
475
476 u8 pa_status;
477 u8 pa_integ_res_a[3];
478 u8 pa_integ_res_b[3];
479 u8 pa_integ_res_c[3];
480 __le16 measurement_req_id;
481 __le16 reserved;
482
483 __le32 tfd_info;
484 __le16 seq_ctl;
485 __le16 byte_cnt;
486 u8 tlc_info;
487 u8 ra_tid;
488 __le16 frame_ctrl;
489
490 struct agg_tx_status status;
491} __packed; /* TX_RSP_API_S_VER_3 */
492
493/**
494 * struct iwl_mvm_ba_notif - notifies about reception of BA
495 * ( BA_NOTIF = 0xc5 )
496 * @sta_addr_lo32: lower 32 bits of the MAC address
497 * @sta_addr_hi16: upper 16 bits of the MAC address
498 * @sta_id: Index of recipient (BA-sending) station in fw's station table
499 * @tid: tid of the session
500 * @seq_ctl:
501 * @bitmap: the bitmap of the BA notification as seen in the air
502 * @scd_flow: the tx queue this BA relates to
503 * @scd_ssn: the index of the last contiguously sent packet
504 * @txed: number of Txed frames in this batch
505 * @txed_2_done: number of Acked frames in this batch
506 */
507struct iwl_mvm_ba_notif {
508 __le32 sta_addr_lo32;
509 __le16 sta_addr_hi16;
510 __le16 reserved;
511
512 u8 sta_id;
513 u8 tid;
514 __le16 seq_ctl;
515 __le64 bitmap;
516 __le16 scd_flow;
517 __le16 scd_ssn;
518 u8 txed;
519 u8 txed_2_done;
520 __le16 reserved1;
521} __packed;
522
523/*
524 * struct iwl_mac_beacon_cmd - beacon template command
525 * @tx: the tx commands associated with the beacon frame
526 * @template_id: currently equal to the mac context id of the coresponding
527 * mac.
528 * @tim_idx: the offset of the tim IE in the beacon
529 * @tim_size: the length of the tim IE
530 * @frame: the template of the beacon frame
531 */
532struct iwl_mac_beacon_cmd {
533 struct iwl_tx_cmd tx;
534 __le32 template_id;
535 __le32 tim_idx;
536 __le32 tim_size;
537 struct ieee80211_hdr frame[0];
538} __packed;
539
540/**
541 * enum iwl_dump_control - dump (flush) control flags
542 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
543 * and the TFD queues are empty.
544 */
545enum iwl_dump_control {
546 DUMP_TX_FIFO_FLUSH = BIT(1),
547};
548
549/**
550 * struct iwl_tx_path_flush_cmd -- queue/FIFO flush command
551 * @queues_ctl: bitmap of queues to flush
552 * @flush_ctl: control flags
553 * @reserved: reserved
554 */
555struct iwl_tx_path_flush_cmd {
556 __le32 queues_ctl;
557 __le16 flush_ctl;
558 __le16 reserved;
559} __packed; /* TX_PATH_FLUSH_CMD_API_S_VER_1 */
560
561/**
562 * iwl_mvm_get_scd_ssn - returns the SSN of the SCD
563 * @tx_resp: the Tx response from the fw (agg or non-agg)
564 *
565 * When the fw sends an AMPDU, it fetches the MPDUs one after the other. Since
566 * it can't know that everything will go well until the end of the AMPDU, it
567 * can't know in advance the number of MPDUs that will be sent in the current
568 * batch. This is why it writes the agg Tx response while it fetches the MPDUs.
569 * Hence, it can't know in advance what the SSN of the SCD will be at the end
570 * of the batch. This is why the SSN of the SCD is written at the end of the
571 * whole struct at a variable offset. This function knows how to cope with the
572 * variable offset and returns the SSN of the SCD.
573 */
574static inline u32 iwl_mvm_get_scd_ssn(struct iwl_mvm_tx_resp *tx_resp)
575{
576 return le32_to_cpup((__le32 *)&tx_resp->status +
577 tx_resp->frame_count) & 0xfff;
578}
579
580#endif /* __fw_api_tx_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
new file mode 100644
index 000000000000..9fd49db32a32
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -0,0 +1,949 @@
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 LICENSE.GPL.
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#ifndef __fw_api_h__
65#define __fw_api_h__
66
67#include "fw-api-rs.h"
68#include "fw-api-tx.h"
69#include "fw-api-sta.h"
70#include "fw-api-mac.h"
71#include "fw-api-power.h"
72#include "fw-api-d3.h"
73
74/* queue and FIFO numbers by usage */
75enum {
76 IWL_MVM_OFFCHANNEL_QUEUE = 8,
77 IWL_MVM_CMD_QUEUE = 9,
78 IWL_MVM_AUX_QUEUE = 15,
79 IWL_MVM_FIRST_AGG_QUEUE = 16,
80 IWL_MVM_NUM_QUEUES = 20,
81 IWL_MVM_LAST_AGG_QUEUE = IWL_MVM_NUM_QUEUES - 1,
82 IWL_MVM_CMD_FIFO = 7
83};
84
85#define IWL_MVM_STATION_COUNT 16
86
87/* commands */
88enum {
89 MVM_ALIVE = 0x1,
90 REPLY_ERROR = 0x2,
91
92 INIT_COMPLETE_NOTIF = 0x4,
93
94 /* PHY context commands */
95 PHY_CONTEXT_CMD = 0x8,
96 DBG_CFG = 0x9,
97
98 /* station table */
99 ADD_STA = 0x18,
100 REMOVE_STA = 0x19,
101
102 /* TX */
103 TX_CMD = 0x1c,
104 TXPATH_FLUSH = 0x1e,
105 MGMT_MCAST_KEY = 0x1f,
106
107 /* global key */
108 WEP_KEY = 0x20,
109
110 /* MAC and Binding commands */
111 MAC_CONTEXT_CMD = 0x28,
112 TIME_EVENT_CMD = 0x29, /* both CMD and response */
113 TIME_EVENT_NOTIFICATION = 0x2a,
114 BINDING_CONTEXT_CMD = 0x2b,
115 TIME_QUOTA_CMD = 0x2c,
116
117 LQ_CMD = 0x4e,
118
119 /* Calibration */
120 TEMPERATURE_NOTIFICATION = 0x62,
121 CALIBRATION_CFG_CMD = 0x65,
122 CALIBRATION_RES_NOTIFICATION = 0x66,
123 CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
124 RADIO_VERSION_NOTIFICATION = 0x68,
125
126 /* Scan offload */
127 SCAN_OFFLOAD_REQUEST_CMD = 0x51,
128 SCAN_OFFLOAD_ABORT_CMD = 0x52,
129 SCAN_OFFLOAD_COMPLETE = 0x6D,
130 SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E,
131 SCAN_OFFLOAD_CONFIG_CMD = 0x6f,
132
133 /* Phy */
134 PHY_CONFIGURATION_CMD = 0x6a,
135 CALIB_RES_NOTIF_PHY_DB = 0x6b,
136 /* PHY_DB_CMD = 0x6c, */
137
138 /* Power */
139 POWER_TABLE_CMD = 0x77,
140
141 /* Scanning */
142 SCAN_REQUEST_CMD = 0x80,
143 SCAN_ABORT_CMD = 0x81,
144 SCAN_START_NOTIFICATION = 0x82,
145 SCAN_RESULTS_NOTIFICATION = 0x83,
146 SCAN_COMPLETE_NOTIFICATION = 0x84,
147
148 /* NVM */
149 NVM_ACCESS_CMD = 0x88,
150
151 SET_CALIB_DEFAULT_CMD = 0x8e,
152
153 BEACON_TEMPLATE_CMD = 0x91,
154 TX_ANT_CONFIGURATION_CMD = 0x98,
155 STATISTICS_NOTIFICATION = 0x9d,
156
157 /* RF-KILL commands and notifications */
158 CARD_STATE_CMD = 0xa0,
159 CARD_STATE_NOTIFICATION = 0xa1,
160
161 REPLY_RX_PHY_CMD = 0xc0,
162 REPLY_RX_MPDU_CMD = 0xc1,
163 BA_NOTIF = 0xc5,
164
165 REPLY_DEBUG_CMD = 0xf0,
166 DEBUG_LOG_MSG = 0xf7,
167
168 /* D3 commands/notifications */
169 D3_CONFIG_CMD = 0xd3,
170 PROT_OFFLOAD_CONFIG_CMD = 0xd4,
171 OFFLOADS_QUERY_CMD = 0xd5,
172 REMOTE_WAKE_CONFIG_CMD = 0xd6,
173
174 /* for WoWLAN in particular */
175 WOWLAN_PATTERNS = 0xe0,
176 WOWLAN_CONFIGURATION = 0xe1,
177 WOWLAN_TSC_RSC_PARAM = 0xe2,
178 WOWLAN_TKIP_PARAM = 0xe3,
179 WOWLAN_KEK_KCK_MATERIAL = 0xe4,
180 WOWLAN_GET_STATUSES = 0xe5,
181 WOWLAN_TX_POWER_PER_DB = 0xe6,
182
183 /* and for NetDetect */
184 NET_DETECT_CONFIG_CMD = 0x54,
185 NET_DETECT_PROFILES_QUERY_CMD = 0x56,
186 NET_DETECT_PROFILES_CMD = 0x57,
187 NET_DETECT_HOTSPOTS_CMD = 0x58,
188 NET_DETECT_HOTSPOTS_QUERY_CMD = 0x59,
189
190 REPLY_MAX = 0xff,
191};
192
193/**
194 * struct iwl_cmd_response - generic response struct for most commands
195 * @status: status of the command asked, changes for each one
196 */
197struct iwl_cmd_response {
198 __le32 status;
199};
200
201/*
202 * struct iwl_tx_ant_cfg_cmd
203 * @valid: valid antenna configuration
204 */
205struct iwl_tx_ant_cfg_cmd {
206 __le32 valid;
207} __packed;
208
209/*
210 * Calibration control struct.
211 * Sent as part of the phy configuration command.
212 * @flow_trigger: bitmap for which calibrations to perform according to
213 * flow triggers.
214 * @event_trigger: bitmap for which calibrations to perform according to
215 * event triggers.
216 */
217struct iwl_calib_ctrl {
218 __le32 flow_trigger;
219 __le32 event_trigger;
220} __packed;
221
222/* This enum defines the bitmap of various calibrations to enable in both
223 * init ucode and runtime ucode through CALIBRATION_CFG_CMD.
224 */
225enum iwl_calib_cfg {
226 IWL_CALIB_CFG_XTAL_IDX = BIT(0),
227 IWL_CALIB_CFG_TEMPERATURE_IDX = BIT(1),
228 IWL_CALIB_CFG_VOLTAGE_READ_IDX = BIT(2),
229 IWL_CALIB_CFG_PAPD_IDX = BIT(3),
230 IWL_CALIB_CFG_TX_PWR_IDX = BIT(4),
231 IWL_CALIB_CFG_DC_IDX = BIT(5),
232 IWL_CALIB_CFG_BB_FILTER_IDX = BIT(6),
233 IWL_CALIB_CFG_LO_LEAKAGE_IDX = BIT(7),
234 IWL_CALIB_CFG_TX_IQ_IDX = BIT(8),
235 IWL_CALIB_CFG_TX_IQ_SKEW_IDX = BIT(9),
236 IWL_CALIB_CFG_RX_IQ_IDX = BIT(10),
237 IWL_CALIB_CFG_RX_IQ_SKEW_IDX = BIT(11),
238 IWL_CALIB_CFG_SENSITIVITY_IDX = BIT(12),
239 IWL_CALIB_CFG_CHAIN_NOISE_IDX = BIT(13),
240 IWL_CALIB_CFG_DISCONNECTED_ANT_IDX = BIT(14),
241 IWL_CALIB_CFG_ANT_COUPLING_IDX = BIT(15),
242 IWL_CALIB_CFG_DAC_IDX = BIT(16),
243 IWL_CALIB_CFG_ABS_IDX = BIT(17),
244 IWL_CALIB_CFG_AGC_IDX = BIT(18),
245};
246
247/*
248 * Phy configuration command.
249 */
250struct iwl_phy_cfg_cmd {
251 __le32 phy_cfg;
252 struct iwl_calib_ctrl calib_control;
253} __packed;
254
255#define PHY_CFG_RADIO_TYPE (BIT(0) | BIT(1))
256#define PHY_CFG_RADIO_STEP (BIT(2) | BIT(3))
257#define PHY_CFG_RADIO_DASH (BIT(4) | BIT(5))
258#define PHY_CFG_PRODUCT_NUMBER (BIT(6) | BIT(7))
259#define PHY_CFG_TX_CHAIN_A BIT(8)
260#define PHY_CFG_TX_CHAIN_B BIT(9)
261#define PHY_CFG_TX_CHAIN_C BIT(10)
262#define PHY_CFG_RX_CHAIN_A BIT(12)
263#define PHY_CFG_RX_CHAIN_B BIT(13)
264#define PHY_CFG_RX_CHAIN_C BIT(14)
265
266
267/* Target of the NVM_ACCESS_CMD */
268enum {
269 NVM_ACCESS_TARGET_CACHE = 0,
270 NVM_ACCESS_TARGET_OTP = 1,
271 NVM_ACCESS_TARGET_EEPROM = 2,
272};
273
274/**
275 * struct iwl_nvm_access_cmd_ver1 - Request the device to send the NVM.
276 * @op_code: 0 - read, 1 - write.
277 * @target: NVM_ACCESS_TARGET_*. should be 0 for read.
278 * @cache_refresh: 0 - None, 1- NVM.
279 * @offset: offset in the nvm data.
280 * @length: of the chunk.
281 * @data: empty on read, the NVM chunk on write
282 */
283struct iwl_nvm_access_cmd_ver1 {
284 u8 op_code;
285 u8 target;
286 u8 cache_refresh;
287 u8 reserved;
288 __le16 offset;
289 __le16 length;
290 u8 data[];
291} __packed; /* NVM_ACCESS_CMD_API_S_VER_1 */
292
293/**
294 * struct iwl_nvm_access_resp_ver1 - response to NVM_ACCESS_CMD
295 * @offset: the offset in the nvm data
296 * @length: of the chunk
297 * @data: the nvm chunk on when NVM_ACCESS_CMD was read, nothing on write
298 */
299struct iwl_nvm_access_resp_ver1 {
300 __le16 offset;
301 __le16 length;
302 u8 data[];
303} __packed; /* NVM_ACCESS_CMD_RESP_API_S_VER_1 */
304
305/* Section types for NVM_ACCESS_CMD version 2 */
306enum {
307 NVM_SECTION_TYPE_HW = 0,
308 NVM_SECTION_TYPE_SW,
309 NVM_SECTION_TYPE_PAPD,
310 NVM_SECTION_TYPE_BT,
311 NVM_SECTION_TYPE_CALIBRATION,
312 NVM_SECTION_TYPE_PRODUCTION,
313 NVM_SECTION_TYPE_POST_FCS_CALIB,
314 NVM_NUM_OF_SECTIONS,
315};
316
317/**
318 * struct iwl_nvm_access_cmd_ver2 - Request the device to send an NVM section
319 * @op_code: 0 - read, 1 - write
320 * @target: NVM_ACCESS_TARGET_*
321 * @type: NVM_SECTION_TYPE_*
322 * @offset: offset in bytes into the section
323 * @length: in bytes, to read/write
324 * @data: if write operation, the data to write. On read its empty
325 */
326struct iwl_nvm_access_cmd_ver2 {
327 u8 op_code;
328 u8 target;
329 __le16 type;
330 __le16 offset;
331 __le16 length;
332 u8 data[];
333} __packed; /* NVM_ACCESS_CMD_API_S_VER_2 */
334
335/**
336 * struct iwl_nvm_access_resp_ver2 - response to NVM_ACCESS_CMD
337 * @offset: offset in bytes into the section
338 * @length: in bytes, either how much was written or read
339 * @type: NVM_SECTION_TYPE_*
340 * @status: 0 for success, fail otherwise
341 * @data: if read operation, the data returned. Empty on write.
342 */
343struct iwl_nvm_access_resp_ver2 {
344 __le16 offset;
345 __le16 length;
346 __le16 type;
347 __le16 status;
348 u8 data[];
349} __packed; /* NVM_ACCESS_CMD_RESP_API_S_VER_2 */
350
351/* MVM_ALIVE 0x1 */
352
353/* alive response is_valid values */
354#define ALIVE_RESP_UCODE_OK BIT(0)
355#define ALIVE_RESP_RFKILL BIT(1)
356
357/* alive response ver_type values */
358enum {
359 FW_TYPE_HW = 0,
360 FW_TYPE_PROT = 1,
361 FW_TYPE_AP = 2,
362 FW_TYPE_WOWLAN = 3,
363 FW_TYPE_TIMING = 4,
364 FW_TYPE_WIPAN = 5
365};
366
367/* alive response ver_subtype values */
368enum {
369 FW_SUBTYPE_FULL_FEATURE = 0,
370 FW_SUBTYPE_BOOTSRAP = 1, /* Not valid */
371 FW_SUBTYPE_REDUCED = 2,
372 FW_SUBTYPE_ALIVE_ONLY = 3,
373 FW_SUBTYPE_WOWLAN = 4,
374 FW_SUBTYPE_AP_SUBTYPE = 5,
375 FW_SUBTYPE_WIPAN = 6,
376 FW_SUBTYPE_INITIALIZE = 9
377};
378
379#define IWL_ALIVE_STATUS_ERR 0xDEAD
380#define IWL_ALIVE_STATUS_OK 0xCAFE
381
382#define IWL_ALIVE_FLG_RFKILL BIT(0)
383
384struct mvm_alive_resp {
385 __le16 status;
386 __le16 flags;
387 u8 ucode_minor;
388 u8 ucode_major;
389 __le16 id;
390 u8 api_minor;
391 u8 api_major;
392 u8 ver_subtype;
393 u8 ver_type;
394 u8 mac;
395 u8 opt;
396 __le16 reserved2;
397 __le32 timestamp;
398 __le32 error_event_table_ptr; /* SRAM address for error log */
399 __le32 log_event_table_ptr; /* SRAM address for event log */
400 __le32 cpu_register_ptr;
401 __le32 dbgm_config_ptr;
402 __le32 alive_counter_ptr;
403 __le32 scd_base_ptr; /* SRAM address for SCD */
404} __packed; /* ALIVE_RES_API_S_VER_1 */
405
406/* Error response/notification */
407enum {
408 FW_ERR_UNKNOWN_CMD = 0x0,
409 FW_ERR_INVALID_CMD_PARAM = 0x1,
410 FW_ERR_SERVICE = 0x2,
411 FW_ERR_ARC_MEMORY = 0x3,
412 FW_ERR_ARC_CODE = 0x4,
413 FW_ERR_WATCH_DOG = 0x5,
414 FW_ERR_WEP_GRP_KEY_INDX = 0x10,
415 FW_ERR_WEP_KEY_SIZE = 0x11,
416 FW_ERR_OBSOLETE_FUNC = 0x12,
417 FW_ERR_UNEXPECTED = 0xFE,
418 FW_ERR_FATAL = 0xFF
419};
420
421/**
422 * struct iwl_error_resp - FW error indication
423 * ( REPLY_ERROR = 0x2 )
424 * @error_type: one of FW_ERR_*
425 * @cmd_id: the command ID for which the error occured
426 * @bad_cmd_seq_num: sequence number of the erroneous command
427 * @error_service: which service created the error, applicable only if
428 * error_type = 2, otherwise 0
429 * @timestamp: TSF in usecs.
430 */
431struct iwl_error_resp {
432 __le32 error_type;
433 u8 cmd_id;
434 u8 reserved1;
435 __le16 bad_cmd_seq_num;
436 __le32 error_service;
437 __le64 timestamp;
438} __packed;
439
440
441/* Common PHY, MAC and Bindings definitions */
442
443#define MAX_MACS_IN_BINDING (3)
444#define MAX_BINDINGS (4)
445#define AUX_BINDING_INDEX (3)
446#define MAX_PHYS (4)
447
448/* Used to extract ID and color from the context dword */
449#define FW_CTXT_ID_POS (0)
450#define FW_CTXT_ID_MSK (0xff << FW_CTXT_ID_POS)
451#define FW_CTXT_COLOR_POS (8)
452#define FW_CTXT_COLOR_MSK (0xff << FW_CTXT_COLOR_POS)
453#define FW_CTXT_INVALID (0xffffffff)
454
455#define FW_CMD_ID_AND_COLOR(_id, _color) ((_id << FW_CTXT_ID_POS) |\
456 (_color << FW_CTXT_COLOR_POS))
457
458/* Possible actions on PHYs, MACs and Bindings */
459enum {
460 FW_CTXT_ACTION_STUB = 0,
461 FW_CTXT_ACTION_ADD,
462 FW_CTXT_ACTION_MODIFY,
463 FW_CTXT_ACTION_REMOVE,
464 FW_CTXT_ACTION_NUM
465}; /* COMMON_CONTEXT_ACTION_API_E_VER_1 */
466
467/* Time Events */
468
469/* Time Event types, according to MAC type */
470enum iwl_time_event_type {
471 /* BSS Station Events */
472 TE_BSS_STA_AGGRESSIVE_ASSOC,
473 TE_BSS_STA_ASSOC,
474 TE_BSS_EAP_DHCP_PROT,
475 TE_BSS_QUIET_PERIOD,
476
477 /* P2P Device Events */
478 TE_P2P_DEVICE_DISCOVERABLE,
479 TE_P2P_DEVICE_LISTEN,
480 TE_P2P_DEVICE_ACTION_SCAN,
481 TE_P2P_DEVICE_FULL_SCAN,
482
483 /* P2P Client Events */
484 TE_P2P_CLIENT_AGGRESSIVE_ASSOC,
485 TE_P2P_CLIENT_ASSOC,
486 TE_P2P_CLIENT_QUIET_PERIOD,
487
488 /* P2P GO Events */
489 TE_P2P_GO_ASSOC_PROT,
490 TE_P2P_GO_REPETITIVE_NOA,
491 TE_P2P_GO_CT_WINDOW,
492
493 /* WiDi Sync Events */
494 TE_WIDI_TX_SYNC,
495
496 TE_MAX
497}; /* MAC_EVENT_TYPE_API_E_VER_1 */
498
499/* Time Event dependencies: none, on another TE, or in a specific time */
500enum {
501 TE_INDEPENDENT = 0,
502 TE_DEP_OTHER = 1,
503 TE_DEP_TSF = 2,
504 TE_EVENT_SOCIOPATHIC = 4,
505}; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */
506
507/* When to send Time Event notifications and to whom (internal = FW) */
508enum {
509 TE_NOTIF_NONE = 0,
510 TE_NOTIF_HOST_START = 0x1,
511 TE_NOTIF_HOST_END = 0x2,
512 TE_NOTIF_INTERNAL_START = 0x4,
513 TE_NOTIF_INTERNAL_END = 0x8
514}; /* MAC_EVENT_ACTION_API_E_VER_1 */
515
516/*
517 * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed.
518 * @TE_FRAG_SINGLE: fragmentation of the time event is allowed, but only
519 * the first fragment is scheduled.
520 * @TE_FRAG_DUAL: fragmentation of the time event is allowed, but only
521 * the first 2 fragments are scheduled.
522 * @TE_FRAG_ENDLESS: fragmentation of the time event is allowed, and any number
523 * of fragments are valid.
524 *
525 * Other than the constant defined above, specifying a fragmentation value 'x'
526 * means that the event can be fragmented but only the first 'x' will be
527 * scheduled.
528 */
529enum {
530 TE_FRAG_NONE = 0,
531 TE_FRAG_SINGLE = 1,
532 TE_FRAG_DUAL = 2,
533 TE_FRAG_ENDLESS = 0xffffffff
534};
535
536/* Repeat the time event endlessly (until removed) */
537#define TE_REPEAT_ENDLESS (0xffffffff)
538/* If a Time Event has bounded repetitions, this is the maximal value */
539#define TE_REPEAT_MAX_MSK (0x0fffffff)
540/* If a Time Event can be fragmented, this is the max number of fragments */
541#define TE_FRAG_MAX_MSK (0x0fffffff)
542
543/**
544 * struct iwl_time_event_cmd - configuring Time Events
545 * ( TIME_EVENT_CMD = 0x29 )
546 * @id_and_color: ID and color of the relevant MAC
547 * @action: action to perform, one of FW_CTXT_ACTION_*
548 * @id: this field has two meanings, depending on the action:
549 * If the action is ADD, then it means the type of event to add.
550 * For all other actions it is the unique event ID assigned when the
551 * event was added by the FW.
552 * @apply_time: When to start the Time Event (in GP2)
553 * @max_delay: maximum delay to event's start (apply time), in TU
554 * @depends_on: the unique ID of the event we depend on (if any)
555 * @interval: interval between repetitions, in TU
556 * @interval_reciprocal: 2^32 / interval
557 * @duration: duration of event in TU
558 * @repeat: how many repetitions to do, can be TE_REPEAT_ENDLESS
559 * @dep_policy: one of TE_INDEPENDENT, TE_DEP_OTHER, TE_DEP_TSF
560 * @is_present: 0 or 1, are we present or absent during the Time Event
561 * @max_frags: maximal number of fragments the Time Event can be divided to
562 * @notify: notifications using TE_NOTIF_* (whom to notify when)
563 */
564struct iwl_time_event_cmd {
565 /* COMMON_INDEX_HDR_API_S_VER_1 */
566 __le32 id_and_color;
567 __le32 action;
568 __le32 id;
569 /* MAC_TIME_EVENT_DATA_API_S_VER_1 */
570 __le32 apply_time;
571 __le32 max_delay;
572 __le32 dep_policy;
573 __le32 depends_on;
574 __le32 is_present;
575 __le32 max_frags;
576 __le32 interval;
577 __le32 interval_reciprocal;
578 __le32 duration;
579 __le32 repeat;
580 __le32 notify;
581} __packed; /* MAC_TIME_EVENT_CMD_API_S_VER_1 */
582
583/**
584 * struct iwl_time_event_resp - response structure to iwl_time_event_cmd
585 * @status: bit 0 indicates success, all others specify errors
586 * @id: the Time Event type
587 * @unique_id: the unique ID assigned (in ADD) or given (others) to the TE
588 * @id_and_color: ID and color of the relevant MAC
589 */
590struct iwl_time_event_resp {
591 __le32 status;
592 __le32 id;
593 __le32 unique_id;
594 __le32 id_and_color;
595} __packed; /* MAC_TIME_EVENT_RSP_API_S_VER_1 */
596
597/**
598 * struct iwl_time_event_notif - notifications of time event start/stop
599 * ( TIME_EVENT_NOTIFICATION = 0x2a )
600 * @timestamp: action timestamp in GP2
601 * @session_id: session's unique id
602 * @unique_id: unique id of the Time Event itself
603 * @id_and_color: ID and color of the relevant MAC
604 * @action: one of TE_NOTIF_START or TE_NOTIF_END
605 * @status: true if scheduled, false otherwise (not executed)
606 */
607struct iwl_time_event_notif {
608 __le32 timestamp;
609 __le32 session_id;
610 __le32 unique_id;
611 __le32 id_and_color;
612 __le32 action;
613 __le32 status;
614} __packed; /* MAC_TIME_EVENT_NTFY_API_S_VER_1 */
615
616
617/* Bindings and Time Quota */
618
619/**
620 * struct iwl_binding_cmd - configuring bindings
621 * ( BINDING_CONTEXT_CMD = 0x2b )
622 * @id_and_color: ID and color of the relevant Binding
623 * @action: action to perform, one of FW_CTXT_ACTION_*
624 * @macs: array of MAC id and colors which belong to the binding
625 * @phy: PHY id and color which belongs to the binding
626 */
627struct iwl_binding_cmd {
628 /* COMMON_INDEX_HDR_API_S_VER_1 */
629 __le32 id_and_color;
630 __le32 action;
631 /* BINDING_DATA_API_S_VER_1 */
632 __le32 macs[MAX_MACS_IN_BINDING];
633 __le32 phy;
634} __packed; /* BINDING_CMD_API_S_VER_1 */
635
636/**
637 * struct iwl_time_quota_data - configuration of time quota per binding
638 * @id_and_color: ID and color of the relevant Binding
639 * @quota: absolute time quota in TU. The scheduler will try to divide the
640 * remainig quota (after Time Events) according to this quota.
641 * @max_duration: max uninterrupted context duration in TU
642 */
643struct iwl_time_quota_data {
644 __le32 id_and_color;
645 __le32 quota;
646 __le32 max_duration;
647} __packed; /* TIME_QUOTA_DATA_API_S_VER_1 */
648
649/**
650 * struct iwl_time_quota_cmd - configuration of time quota between bindings
651 * ( TIME_QUOTA_CMD = 0x2c )
652 * @quotas: allocations per binding
653 */
654struct iwl_time_quota_cmd {
655 struct iwl_time_quota_data quotas[MAX_BINDINGS];
656} __packed; /* TIME_QUOTA_ALLOCATION_CMD_API_S_VER_1 */
657
658
659/* PHY context */
660
661/* Supported bands */
662#define PHY_BAND_5 (0)
663#define PHY_BAND_24 (1)
664
665/* Supported channel width, vary if there is VHT support */
666#define PHY_VHT_CHANNEL_MODE20 (0x0)
667#define PHY_VHT_CHANNEL_MODE40 (0x1)
668#define PHY_VHT_CHANNEL_MODE80 (0x2)
669#define PHY_VHT_CHANNEL_MODE160 (0x3)
670
671/*
672 * Control channel position:
673 * For legacy set bit means upper channel, otherwise lower.
674 * For VHT - bit-2 marks if the control is lower/upper relative to center-freq
675 * bits-1:0 mark the distance from the center freq. for 20Mhz, offset is 0.
676 * center_freq
677 * |
678 * 40Mhz |_______|_______|
679 * 80Mhz |_______|_______|_______|_______|
680 * 160Mhz |_______|_______|_______|_______|_______|_______|_______|_______|
681 * code 011 010 001 000 | 100 101 110 111
682 */
683#define PHY_VHT_CTRL_POS_1_BELOW (0x0)
684#define PHY_VHT_CTRL_POS_2_BELOW (0x1)
685#define PHY_VHT_CTRL_POS_3_BELOW (0x2)
686#define PHY_VHT_CTRL_POS_4_BELOW (0x3)
687#define PHY_VHT_CTRL_POS_1_ABOVE (0x4)
688#define PHY_VHT_CTRL_POS_2_ABOVE (0x5)
689#define PHY_VHT_CTRL_POS_3_ABOVE (0x6)
690#define PHY_VHT_CTRL_POS_4_ABOVE (0x7)
691
692/*
693 * @band: PHY_BAND_*
694 * @channel: channel number
695 * @width: PHY_[VHT|LEGACY]_CHANNEL_*
696 * @ctrl channel: PHY_[VHT|LEGACY]_CTRL_*
697 */
698struct iwl_fw_channel_info {
699 u8 band;
700 u8 channel;
701 u8 width;
702 u8 ctrl_pos;
703} __packed;
704
705#define PHY_RX_CHAIN_DRIVER_FORCE_POS (0)
706#define PHY_RX_CHAIN_DRIVER_FORCE_MSK \
707 (0x1 << PHY_RX_CHAIN_DRIVER_FORCE_POS)
708#define PHY_RX_CHAIN_VALID_POS (1)
709#define PHY_RX_CHAIN_VALID_MSK \
710 (0x7 << PHY_RX_CHAIN_VALID_POS)
711#define PHY_RX_CHAIN_FORCE_SEL_POS (4)
712#define PHY_RX_CHAIN_FORCE_SEL_MSK \
713 (0x7 << PHY_RX_CHAIN_FORCE_SEL_POS)
714#define PHY_RX_CHAIN_FORCE_MIMO_SEL_POS (7)
715#define PHY_RX_CHAIN_FORCE_MIMO_SEL_MSK \
716 (0x7 << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS)
717#define PHY_RX_CHAIN_CNT_POS (10)
718#define PHY_RX_CHAIN_CNT_MSK \
719 (0x3 << PHY_RX_CHAIN_CNT_POS)
720#define PHY_RX_CHAIN_MIMO_CNT_POS (12)
721#define PHY_RX_CHAIN_MIMO_CNT_MSK \
722 (0x3 << PHY_RX_CHAIN_MIMO_CNT_POS)
723#define PHY_RX_CHAIN_MIMO_FORCE_POS (14)
724#define PHY_RX_CHAIN_MIMO_FORCE_MSK \
725 (0x1 << PHY_RX_CHAIN_MIMO_FORCE_POS)
726
727/* TODO: fix the value, make it depend on firmware at runtime? */
728#define NUM_PHY_CTX 3
729
730/* TODO: complete missing documentation */
731/**
732 * struct iwl_phy_context_cmd - config of the PHY context
733 * ( PHY_CONTEXT_CMD = 0x8 )
734 * @id_and_color: ID and color of the relevant Binding
735 * @action: action to perform, one of FW_CTXT_ACTION_*
736 * @apply_time: 0 means immediate apply and context switch.
737 * other value means apply new params after X usecs
738 * @tx_param_color: ???
739 * @channel_info:
740 * @txchain_info: ???
741 * @rxchain_info: ???
742 * @acquisition_data: ???
743 * @dsp_cfg_flags: set to 0
744 */
745struct iwl_phy_context_cmd {
746 /* COMMON_INDEX_HDR_API_S_VER_1 */
747 __le32 id_and_color;
748 __le32 action;
749 /* PHY_CONTEXT_DATA_API_S_VER_1 */
750 __le32 apply_time;
751 __le32 tx_param_color;
752 struct iwl_fw_channel_info ci;
753 __le32 txchain_info;
754 __le32 rxchain_info;
755 __le32 acquisition_data;
756 __le32 dsp_cfg_flags;
757} __packed; /* PHY_CONTEXT_CMD_API_VER_1 */
758
759#define IWL_RX_INFO_PHY_CNT 8
760#define IWL_RX_INFO_AGC_IDX 1
761#define IWL_RX_INFO_RSSI_AB_IDX 2
762#define IWL_RX_INFO_RSSI_C_IDX 3
763#define IWL_OFDM_AGC_DB_MSK 0xfe00
764#define IWL_OFDM_AGC_DB_POS 9
765#define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff
766#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
767#define IWL_OFDM_RSSI_A_POS 0
768#define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000
769#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
770#define IWL_OFDM_RSSI_B_POS 16
771#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff
772#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00
773#define IWL_OFDM_RSSI_C_POS 0
774
775/**
776 * struct iwl_rx_phy_info - phy info
777 * (REPLY_RX_PHY_CMD = 0xc0)
778 * @non_cfg_phy_cnt: non configurable DSP phy data byte count
779 * @cfg_phy_cnt: configurable DSP phy data byte count
780 * @stat_id: configurable DSP phy data set ID
781 * @reserved1:
782 * @system_timestamp: GP2 at on air rise
783 * @timestamp: TSF at on air rise
784 * @beacon_time_stamp: beacon at on-air rise
785 * @phy_flags: general phy flags: band, modulation, ...
786 * @channel: channel number
787 * @non_cfg_phy_buf: for various implementations of non_cfg_phy
788 * @rate_n_flags: RATE_MCS_*
789 * @byte_count: frame's byte-count
790 * @frame_time: frame's time on the air, based on byte count and frame rate
791 * calculation
792 *
793 * Before each Rx, the device sends this data. It contains PHY information
794 * about the reception of the packet.
795 */
796struct iwl_rx_phy_info {
797 u8 non_cfg_phy_cnt;
798 u8 cfg_phy_cnt;
799 u8 stat_id;
800 u8 reserved1;
801 __le32 system_timestamp;
802 __le64 timestamp;
803 __le32 beacon_time_stamp;
804 __le16 phy_flags;
805 __le16 channel;
806 __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT];
807 __le32 rate_n_flags;
808 __le32 byte_count;
809 __le16 reserved2;
810 __le16 frame_time;
811} __packed;
812
813struct iwl_rx_mpdu_res_start {
814 __le16 byte_count;
815 __le16 reserved;
816} __packed;
817
818/**
819 * enum iwl_rx_phy_flags - to parse %iwl_rx_phy_info phy_flags
820 * @RX_RES_PHY_FLAGS_BAND_24: true if the packet was received on 2.4 band
821 * @RX_RES_PHY_FLAGS_MOD_CCK:
822 * @RX_RES_PHY_FLAGS_SHORT_PREAMBLE: true if packet's preamble was short
823 * @RX_RES_PHY_FLAGS_NARROW_BAND:
824 * @RX_RES_PHY_FLAGS_ANTENNA: antenna on which the packet was received
825 * @RX_RES_PHY_FLAGS_AGG: set if the packet was part of an A-MPDU
826 * @RX_RES_PHY_FLAGS_OFDM_HT: The frame was an HT frame
827 * @RX_RES_PHY_FLAGS_OFDM_GF: The frame used GF preamble
828 * @RX_RES_PHY_FLAGS_OFDM_VHT: The frame was a VHT frame
829 */
830enum iwl_rx_phy_flags {
831 RX_RES_PHY_FLAGS_BAND_24 = BIT(0),
832 RX_RES_PHY_FLAGS_MOD_CCK = BIT(1),
833 RX_RES_PHY_FLAGS_SHORT_PREAMBLE = BIT(2),
834 RX_RES_PHY_FLAGS_NARROW_BAND = BIT(3),
835 RX_RES_PHY_FLAGS_ANTENNA = (0x7 << 4),
836 RX_RES_PHY_FLAGS_ANTENNA_POS = 4,
837 RX_RES_PHY_FLAGS_AGG = BIT(7),
838 RX_RES_PHY_FLAGS_OFDM_HT = BIT(8),
839 RX_RES_PHY_FLAGS_OFDM_GF = BIT(9),
840 RX_RES_PHY_FLAGS_OFDM_VHT = BIT(10),
841};
842
843/**
844 * enum iwl_mvm_rx_status - written by fw for each Rx packet
845 * @RX_MPDU_RES_STATUS_CRC_OK: CRC is fine
846 * @RX_MPDU_RES_STATUS_OVERRUN_OK: there was no RXE overflow
847 * @RX_MPDU_RES_STATUS_SRC_STA_FOUND:
848 * @RX_MPDU_RES_STATUS_KEY_VALID:
849 * @RX_MPDU_RES_STATUS_KEY_PARAM_OK:
850 * @RX_MPDU_RES_STATUS_ICV_OK: ICV is fine, if not, the packet is destroyed
851 * @RX_MPDU_RES_STATUS_MIC_OK: used for CCM alg only. TKIP MIC is checked
852 * in the driver.
853 * @RX_MPDU_RES_STATUS_TTAK_OK: TTAK is fine
854 * @RX_MPDU_RES_STATUS_MNG_FRAME_REPLAY_ERR: valid for alg = CCM_CMAC or
855 * alg = CCM only. Checks replay attack for 11w frames. Relevant only if
856 * %RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME is set.
857 * @RX_MPDU_RES_STATUS_SEC_NO_ENC: this frame is not encrypted
858 * @RX_MPDU_RES_STATUS_SEC_WEP_ENC: this frame is encrypted using WEP
859 * @RX_MPDU_RES_STATUS_SEC_CCM_ENC: this frame is encrypted using CCM
860 * @RX_MPDU_RES_STATUS_SEC_TKIP_ENC: this frame is encrypted using TKIP
861 * @RX_MPDU_RES_STATUS_SEC_CCM_CMAC_ENC: this frame is encrypted using CCM_CMAC
862 * @RX_MPDU_RES_STATUS_SEC_ENC_ERR: this frame couldn't be decrypted
863 * @RX_MPDU_RES_STATUS_SEC_ENC_MSK: bitmask of the encryption algorithm
864 * @RX_MPDU_RES_STATUS_DEC_DONE: this frame has been successfully decrypted
865 * @RX_MPDU_RES_STATUS_PROTECT_FRAME_BIT_CMP:
866 * @RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP:
867 * @RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT:
868 * @RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME: this frame is an 11w management frame
869 * @RX_MPDU_RES_STATUS_HASH_INDEX_MSK:
870 * @RX_MPDU_RES_STATUS_STA_ID_MSK:
871 * @RX_MPDU_RES_STATUS_RRF_KILL:
872 * @RX_MPDU_RES_STATUS_FILTERING_MSK:
873 * @RX_MPDU_RES_STATUS2_FILTERING_MSK:
874 */
875enum iwl_mvm_rx_status {
876 RX_MPDU_RES_STATUS_CRC_OK = BIT(0),
877 RX_MPDU_RES_STATUS_OVERRUN_OK = BIT(1),
878 RX_MPDU_RES_STATUS_SRC_STA_FOUND = BIT(2),
879 RX_MPDU_RES_STATUS_KEY_VALID = BIT(3),
880 RX_MPDU_RES_STATUS_KEY_PARAM_OK = BIT(4),
881 RX_MPDU_RES_STATUS_ICV_OK = BIT(5),
882 RX_MPDU_RES_STATUS_MIC_OK = BIT(6),
883 RX_MPDU_RES_STATUS_TTAK_OK = BIT(7),
884 RX_MPDU_RES_STATUS_MNG_FRAME_REPLAY_ERR = BIT(7),
885 RX_MPDU_RES_STATUS_SEC_NO_ENC = (0 << 8),
886 RX_MPDU_RES_STATUS_SEC_WEP_ENC = (1 << 8),
887 RX_MPDU_RES_STATUS_SEC_CCM_ENC = (2 << 8),
888 RX_MPDU_RES_STATUS_SEC_TKIP_ENC = (3 << 8),
889 RX_MPDU_RES_STATUS_SEC_CCM_CMAC_ENC = (6 << 8),
890 RX_MPDU_RES_STATUS_SEC_ENC_ERR = (7 << 8),
891 RX_MPDU_RES_STATUS_SEC_ENC_MSK = (7 << 8),
892 RX_MPDU_RES_STATUS_DEC_DONE = BIT(11),
893 RX_MPDU_RES_STATUS_PROTECT_FRAME_BIT_CMP = BIT(12),
894 RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP = BIT(13),
895 RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT = BIT(14),
896 RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME = BIT(15),
897 RX_MPDU_RES_STATUS_HASH_INDEX_MSK = (0x3F0000),
898 RX_MPDU_RES_STATUS_STA_ID_MSK = (0x1f000000),
899 RX_MPDU_RES_STATUS_RRF_KILL = BIT(29),
900 RX_MPDU_RES_STATUS_FILTERING_MSK = (0xc00000),
901 RX_MPDU_RES_STATUS2_FILTERING_MSK = (0xc0000000),
902};
903
904/**
905 * struct iwl_radio_version_notif - information on the radio version
906 * ( RADIO_VERSION_NOTIFICATION = 0x68 )
907 * @radio_flavor:
908 * @radio_step:
909 * @radio_dash:
910 */
911struct iwl_radio_version_notif {
912 __le32 radio_flavor;
913 __le32 radio_step;
914 __le32 radio_dash;
915} __packed; /* RADIO_VERSION_NOTOFICATION_S_VER_1 */
916
917enum iwl_card_state_flags {
918 CARD_ENABLED = 0x00,
919 HW_CARD_DISABLED = 0x01,
920 SW_CARD_DISABLED = 0x02,
921 CT_KILL_CARD_DISABLED = 0x04,
922 HALT_CARD_DISABLED = 0x08,
923 CARD_DISABLED_MSK = 0x0f,
924 CARD_IS_RX_ON = 0x10,
925};
926
927/**
928 * struct iwl_radio_version_notif - information on the radio version
929 * ( CARD_STATE_NOTIFICATION = 0xa1 )
930 * @flags: %iwl_card_state_flags
931 */
932struct iwl_card_state_notif {
933 __le32 flags;
934} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */
935
936/**
937 * struct iwl_set_calib_default_cmd - set default value for calibration.
938 * ( SET_CALIB_DEFAULT_CMD = 0x8e )
939 * @calib_index: the calibration to set value for
940 * @length: of data
941 * @data: the value to set for the calibration result
942 */
943struct iwl_set_calib_default_cmd {
944 __le16 calib_index;
945 __le16 length;
946 u8 data[0];
947} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */
948
949#endif /* __fw_api_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
new file mode 100644
index 000000000000..90473c2ba1c7
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -0,0 +1,644 @@
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 LICENSE.GPL.
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#include <net/mac80211.h>
64
65#include "iwl-trans.h"
66#include "iwl-op-mode.h"
67#include "iwl-fw.h"
68#include "iwl-debug.h"
69#include "iwl-csr.h" /* for iwl_mvm_rx_card_state_notif */
70#include "iwl-io.h" /* for iwl_mvm_rx_card_state_notif */
71#include "iwl-eeprom-parse.h"
72
73#include "mvm.h"
74#include "iwl-phy-db.h"
75
76#define MVM_UCODE_ALIVE_TIMEOUT HZ
77#define MVM_UCODE_CALIB_TIMEOUT (2*HZ)
78
79#define UCODE_VALID_OK cpu_to_le32(0x1)
80
81/* Default calibration values for WkP - set to INIT image w/o running */
82static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f,
83 0x00, 0x18, 0x00 };
84static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
85 0x7f, 0x7f, 0x7f };
86static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 };
87static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00,
88 0x00 };
89static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 };
90static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 };
91static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 };
92static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 };
93
94struct iwl_calib_default_data {
95 u16 size;
96 void *data;
97};
98
99#define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf}
100
101static const struct iwl_calib_default_data wkp_calib_default_data[12] = {
102 [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc),
103 [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter),
104 [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo),
105 [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq),
106 [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew),
107 [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq),
108 [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew),
109};
110
111struct iwl_mvm_alive_data {
112 bool valid;
113 u32 scd_base_addr;
114};
115
116static inline const struct fw_img *
117iwl_get_ucode_image(struct iwl_mvm *mvm, enum iwl_ucode_type ucode_type)
118{
119 if (ucode_type >= IWL_UCODE_TYPE_MAX)
120 return NULL;
121
122 return &mvm->fw->img[ucode_type];
123}
124
125static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant)
126{
127 struct iwl_tx_ant_cfg_cmd tx_ant_cmd = {
128 .valid = cpu_to_le32(valid_tx_ant),
129 };
130
131 IWL_DEBUG_HC(mvm, "select valid tx ant: %u\n", valid_tx_ant);
132 return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC,
133 sizeof(tx_ant_cmd), &tx_ant_cmd);
134}
135
136static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
137 struct iwl_rx_packet *pkt, void *data)
138{
139 struct iwl_mvm *mvm =
140 container_of(notif_wait, struct iwl_mvm, notif_wait);
141 struct iwl_mvm_alive_data *alive_data = data;
142 struct mvm_alive_resp *palive;
143
144 palive = (void *)pkt->data;
145
146 mvm->error_event_table = le32_to_cpu(palive->error_event_table_ptr);
147 mvm->log_event_table = le32_to_cpu(palive->log_event_table_ptr);
148 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr);
149
150 alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK;
151 IWL_DEBUG_FW(mvm, "Alive ucode status 0x%04x revision 0x%01X 0x%01X\n",
152 le16_to_cpu(palive->status), palive->ver_type,
153 palive->ver_subtype);
154
155 return true;
156}
157
158static bool iwl_wait_phy_db_entry(struct iwl_notif_wait_data *notif_wait,
159 struct iwl_rx_packet *pkt, void *data)
160{
161 struct iwl_phy_db *phy_db = data;
162
163 if (pkt->hdr.cmd != CALIB_RES_NOTIF_PHY_DB) {
164 WARN_ON(pkt->hdr.cmd != INIT_COMPLETE_NOTIF);
165 return true;
166 }
167
168 WARN_ON(iwl_phy_db_set_section(phy_db, pkt, GFP_ATOMIC));
169
170 return false;
171}
172
173static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
174 enum iwl_ucode_type ucode_type)
175{
176 struct iwl_notification_wait alive_wait;
177 struct iwl_mvm_alive_data alive_data;
178 const struct fw_img *fw;
179 int ret, i;
180 enum iwl_ucode_type old_type = mvm->cur_ucode;
181 static const u8 alive_cmd[] = { MVM_ALIVE };
182
183 mvm->cur_ucode = ucode_type;
184 fw = iwl_get_ucode_image(mvm, ucode_type);
185
186 mvm->ucode_loaded = false;
187
188 if (!fw)
189 return -EINVAL;
190
191 iwl_init_notification_wait(&mvm->notif_wait, &alive_wait,
192 alive_cmd, ARRAY_SIZE(alive_cmd),
193 iwl_alive_fn, &alive_data);
194
195 ret = iwl_trans_start_fw(mvm->trans, fw, ucode_type == IWL_UCODE_INIT);
196 if (ret) {
197 mvm->cur_ucode = old_type;
198 iwl_remove_notification(&mvm->notif_wait, &alive_wait);
199 return ret;
200 }
201
202 /*
203 * Some things may run in the background now, but we
204 * just wait for the ALIVE notification here.
205 */
206 ret = iwl_wait_notification(&mvm->notif_wait, &alive_wait,
207 MVM_UCODE_ALIVE_TIMEOUT);
208 if (ret) {
209 mvm->cur_ucode = old_type;
210 return ret;
211 }
212
213 if (!alive_data.valid) {
214 IWL_ERR(mvm, "Loaded ucode is not valid!\n");
215 mvm->cur_ucode = old_type;
216 return -EIO;
217 }
218
219 iwl_trans_fw_alive(mvm->trans, alive_data.scd_base_addr);
220
221 /*
222 * Note: all the queues are enabled as part of the interface
223 * initialization, but in firmware restart scenarios they
224 * could be stopped, so wake them up. In firmware restart,
225 * mac80211 will have the queues stopped as well until the
226 * reconfiguration completes. During normal startup, they
227 * will be empty.
228 */
229
230 for (i = 0; i < IWL_MAX_HW_QUEUES; i++) {
231 if (i < IWL_MVM_FIRST_AGG_QUEUE && i != IWL_MVM_CMD_QUEUE)
232 mvm->queue_to_mac80211[i] = i;
233 else
234 mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE;
235 atomic_set(&mvm->queue_stop_count[i], 0);
236 }
237
238 mvm->transport_queue_stop = 0;
239
240 mvm->ucode_loaded = true;
241
242 return 0;
243}
244#define IWL_HW_REV_ID_RAINBOW 0x2
245#define IWL_PROJ_TYPE_LHP 0x5
246
247static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm)
248{
249 struct iwl_nvm_data *data = mvm->nvm_data;
250 /* Temp calls to static definitions, will be changed to CSR calls */
251 u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW;
252 u8 project_type = IWL_PROJ_TYPE_LHP;
253
254 return data->radio_cfg_dash | (data->radio_cfg_step << 2) |
255 (hw_rev_id << 4) | ((project_type & 0x7f) << 6) |
256 (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20);
257}
258
259static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
260{
261 struct iwl_phy_cfg_cmd phy_cfg_cmd;
262 enum iwl_ucode_type ucode_type = mvm->cur_ucode;
263
264 /* Set parameters */
265 phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm));
266 phy_cfg_cmd.calib_control.event_trigger =
267 mvm->fw->default_calib[ucode_type].event_trigger;
268 phy_cfg_cmd.calib_control.flow_trigger =
269 mvm->fw->default_calib[ucode_type].flow_trigger;
270
271 IWL_DEBUG_INFO(mvm, "Sending Phy CFG command: 0x%x\n",
272 phy_cfg_cmd.phy_cfg);
273
274 return iwl_mvm_send_cmd_pdu(mvm, PHY_CONFIGURATION_CMD, CMD_SYNC,
275 sizeof(phy_cfg_cmd), &phy_cfg_cmd);
276}
277
278/* Starting with the new PHY DB implementation - New calibs are enabled */
279/* Value - 0x405e7 */
280#define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\
281 IWL_CALIB_CFG_TEMPERATURE_IDX |\
282 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
283 IWL_CALIB_CFG_DC_IDX |\
284 IWL_CALIB_CFG_BB_FILTER_IDX |\
285 IWL_CALIB_CFG_LO_LEAKAGE_IDX |\
286 IWL_CALIB_CFG_TX_IQ_IDX |\
287 IWL_CALIB_CFG_RX_IQ_IDX |\
288 IWL_CALIB_CFG_AGC_IDX)
289
290#define IWL_CALIB_DEFAULT_EVENT_INIT 0x0
291
292/* Value 0x41567 */
293#define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\
294 IWL_CALIB_CFG_TEMPERATURE_IDX |\
295 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
296 IWL_CALIB_CFG_BB_FILTER_IDX |\
297 IWL_CALIB_CFG_DC_IDX |\
298 IWL_CALIB_CFG_TX_IQ_IDX |\
299 IWL_CALIB_CFG_RX_IQ_IDX |\
300 IWL_CALIB_CFG_SENSITIVITY_IDX |\
301 IWL_CALIB_CFG_AGC_IDX)
302
303#define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\
304 IWL_CALIB_CFG_TEMPERATURE_IDX |\
305 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
306 IWL_CALIB_CFG_TX_PWR_IDX |\
307 IWL_CALIB_CFG_DC_IDX |\
308 IWL_CALIB_CFG_TX_IQ_IDX |\
309 IWL_CALIB_CFG_SENSITIVITY_IDX)
310
311/*
312 * Sets the calibrations trigger values that will be sent to the FW for runtime
313 * and init calibrations.
314 * The ones given in the FW TLV are not correct.
315 */
316static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm)
317{
318 struct iwl_tlv_calib_ctrl default_calib;
319
320 /*
321 * WkP FW TLV calib bits are wrong, overwrite them.
322 * This defines the dynamic calibrations which are implemented in the
323 * uCode both for init(flow) calculation and event driven calibs.
324 */
325
326 /* Init Image */
327 default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT);
328 default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT);
329
330 if (default_calib.event_trigger !=
331 mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger)
332 IWL_ERR(mvm,
333 "Updating the event calib for INIT image: 0x%x -> 0x%x\n",
334 mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger,
335 default_calib.event_trigger);
336 if (default_calib.flow_trigger !=
337 mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger)
338 IWL_ERR(mvm,
339 "Updating the flow calib for INIT image: 0x%x -> 0x%x\n",
340 mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger,
341 default_calib.flow_trigger);
342
343 memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT],
344 &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
345 IWL_ERR(mvm,
346 "Setting uCode init calibrations event 0x%x, trigger 0x%x\n",
347 default_calib.event_trigger,
348 default_calib.flow_trigger);
349
350 /* Run time image */
351 default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN);
352 default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN);
353
354 if (default_calib.event_trigger !=
355 mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger)
356 IWL_ERR(mvm,
357 "Updating the event calib for RT image: 0x%x -> 0x%x\n",
358 mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger,
359 default_calib.event_trigger);
360 if (default_calib.flow_trigger !=
361 mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger)
362 IWL_ERR(mvm,
363 "Updating the flow calib for RT image: 0x%x -> 0x%x\n",
364 mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger,
365 default_calib.flow_trigger);
366
367 memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR],
368 &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
369 IWL_ERR(mvm,
370 "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n",
371 default_calib.event_trigger,
372 default_calib.flow_trigger);
373}
374
375static int iwl_set_default_calibrations(struct iwl_mvm *mvm)
376{
377 u8 cmd_raw[16]; /* holds the variable size commands */
378 struct iwl_set_calib_default_cmd *cmd =
379 (struct iwl_set_calib_default_cmd *)cmd_raw;
380 int ret, i;
381
382 /* Setting default values for calibrations we don't run */
383 for (i = 0; i < ARRAY_SIZE(wkp_calib_default_data); i++) {
384 u16 cmd_len;
385
386 if (wkp_calib_default_data[i].size == 0)
387 continue;
388
389 memset(cmd_raw, 0, sizeof(cmd_raw));
390 cmd_len = wkp_calib_default_data[i].size + sizeof(cmd);
391 cmd->calib_index = cpu_to_le16(i);
392 cmd->length = cpu_to_le16(wkp_calib_default_data[i].size);
393 if (WARN_ONCE(cmd_len > sizeof(cmd_raw),
394 "Need to enlarge cmd_raw to %d\n", cmd_len))
395 break;
396 memcpy(cmd->data, wkp_calib_default_data[i].data,
397 wkp_calib_default_data[i].size);
398 ret = iwl_mvm_send_cmd_pdu(mvm, SET_CALIB_DEFAULT_CMD, 0,
399 sizeof(*cmd) +
400 wkp_calib_default_data[i].size,
401 cmd);
402 if (ret)
403 return ret;
404 }
405
406 return 0;
407}
408
409int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
410{
411 struct iwl_notification_wait calib_wait;
412 static const u8 init_complete[] = {
413 INIT_COMPLETE_NOTIF,
414 CALIB_RES_NOTIF_PHY_DB
415 };
416 int ret;
417
418 lockdep_assert_held(&mvm->mutex);
419
420 if (mvm->init_ucode_run)
421 return 0;
422
423 iwl_init_notification_wait(&mvm->notif_wait,
424 &calib_wait,
425 init_complete,
426 ARRAY_SIZE(init_complete),
427 iwl_wait_phy_db_entry,
428 mvm->phy_db);
429
430 /* Will also start the device */
431 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_INIT);
432 if (ret) {
433 IWL_ERR(mvm, "Failed to start INIT ucode: %d\n", ret);
434 goto error;
435 }
436
437 if (read_nvm) {
438 /* Read nvm */
439 ret = iwl_nvm_init(mvm);
440 if (ret) {
441 IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
442 goto error;
443 }
444 }
445
446 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
447 WARN_ON(ret);
448
449 /* Override the calibrations from TLV and the const of fw */
450 iwl_set_default_calib_trigger(mvm);
451
452 /* WkP doesn't have all calibrations, need to set default values */
453 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
454 ret = iwl_set_default_calibrations(mvm);
455 if (ret)
456 goto error;
457 }
458
459 /*
460 * Send phy configurations command to init uCode
461 * to start the 16.0 uCode init image internal calibrations.
462 */
463 ret = iwl_send_phy_cfg_cmd(mvm);
464 if (ret) {
465 IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
466 ret);
467 goto error;
468 }
469
470 /*
471 * Some things may run in the background now, but we
472 * just wait for the calibration complete notification.
473 */
474 ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
475 MVM_UCODE_CALIB_TIMEOUT);
476 if (!ret)
477 mvm->init_ucode_run = true;
478 goto out;
479
480error:
481 iwl_remove_notification(&mvm->notif_wait, &calib_wait);
482out:
483 if (!iwlmvm_mod_params.init_dbg) {
484 iwl_trans_stop_device(mvm->trans);
485 } else if (!mvm->nvm_data) {
486 /* we want to debug INIT and we have no NVM - fake */
487 mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) +
488 sizeof(struct ieee80211_channel) +
489 sizeof(struct ieee80211_rate),
490 GFP_KERNEL);
491 if (!mvm->nvm_data)
492 return -ENOMEM;
493 mvm->nvm_data->valid_rx_ant = 1;
494 mvm->nvm_data->valid_tx_ant = 1;
495 mvm->nvm_data->bands[0].channels = mvm->nvm_data->channels;
496 mvm->nvm_data->bands[0].n_channels = 1;
497 mvm->nvm_data->bands[0].n_bitrates = 1;
498 mvm->nvm_data->bands[0].bitrates =
499 (void *)mvm->nvm_data->channels + 1;
500 mvm->nvm_data->bands[0].bitrates->hw_value = 10;
501 }
502
503 return ret;
504}
505
506#define UCODE_CALIB_TIMEOUT (2*HZ)
507
508int iwl_mvm_up(struct iwl_mvm *mvm)
509{
510 int ret, i;
511
512 lockdep_assert_held(&mvm->mutex);
513
514 ret = iwl_trans_start_hw(mvm->trans);
515 if (ret)
516 return ret;
517
518 /* If we were in RFKILL during module loading, load init ucode now */
519 if (!mvm->init_ucode_run) {
520 ret = iwl_run_init_mvm_ucode(mvm, false);
521 if (ret && !iwlmvm_mod_params.init_dbg) {
522 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
523 goto error;
524 }
525 }
526
527 if (iwlmvm_mod_params.init_dbg)
528 return 0;
529
530 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
531 if (ret) {
532 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
533 goto error;
534 }
535
536 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
537 if (ret)
538 goto error;
539
540 /* Send phy db control command and then phy db calibration*/
541 ret = iwl_send_phy_db_data(mvm->phy_db);
542 if (ret)
543 goto error;
544
545 ret = iwl_send_phy_cfg_cmd(mvm);
546 if (ret)
547 goto error;
548
549 /* init the fw <-> mac80211 STA mapping */
550 for (i = 0; i < IWL_MVM_STATION_COUNT; i++)
551 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
552
553 /* Add auxiliary station for scanning */
554 ret = iwl_mvm_add_aux_sta(mvm);
555 if (ret)
556 goto error;
557
558 IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
559
560 return 0;
561 error:
562 iwl_trans_stop_device(mvm->trans);
563 return ret;
564}
565
566int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
567{
568 int ret, i;
569
570 lockdep_assert_held(&mvm->mutex);
571
572 ret = iwl_trans_start_hw(mvm->trans);
573 if (ret)
574 return ret;
575
576 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_WOWLAN);
577 if (ret) {
578 IWL_ERR(mvm, "Failed to start WoWLAN firmware: %d\n", ret);
579 goto error;
580 }
581
582 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
583 if (ret)
584 goto error;
585
586 /* Send phy db control command and then phy db calibration*/
587 ret = iwl_send_phy_db_data(mvm->phy_db);
588 if (ret)
589 goto error;
590
591 ret = iwl_send_phy_cfg_cmd(mvm);
592 if (ret)
593 goto error;
594
595 /* init the fw <-> mac80211 STA mapping */
596 for (i = 0; i < IWL_MVM_STATION_COUNT; i++)
597 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
598
599 /* Add auxiliary station for scanning */
600 ret = iwl_mvm_add_aux_sta(mvm);
601 if (ret)
602 goto error;
603
604 return 0;
605 error:
606 iwl_trans_stop_device(mvm->trans);
607 return ret;
608}
609
610int iwl_mvm_rx_card_state_notif(struct iwl_mvm *mvm,
611 struct iwl_rx_cmd_buffer *rxb,
612 struct iwl_device_cmd *cmd)
613{
614 struct iwl_rx_packet *pkt = rxb_addr(rxb);
615 struct iwl_card_state_notif *card_state_notif = (void *)pkt->data;
616 u32 flags = le32_to_cpu(card_state_notif->flags);
617
618 IWL_DEBUG_RF_KILL(mvm, "Card state received: HW:%s SW:%s CT:%s\n",
619 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
620 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
621 (flags & CT_KILL_CARD_DISABLED) ?
622 "Reached" : "Not reached");
623
624 if (flags & CARD_DISABLED_MSK)
625 iwl_write32(mvm->trans, CSR_UCODE_DRV_GP1_SET,
626 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
627
628 return 0;
629}
630
631int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
632 struct iwl_device_cmd *cmd)
633{
634 struct iwl_rx_packet *pkt = rxb_addr(rxb);
635 struct iwl_radio_version_notif *radio_version = (void *)pkt->data;
636
637 /* TODO: what to do with that? */
638 IWL_DEBUG_INFO(mvm,
639 "Radio version: flavor: 0x%08x, step 0x%08x, dash 0x%08x\n",
640 le32_to_cpu(radio_version->radio_flavor),
641 le32_to_cpu(radio_version->radio_step),
642 le32_to_cpu(radio_version->radio_dash));
643 return 0;
644}
diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c
new file mode 100644
index 000000000000..011906e73a05
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/led.c
@@ -0,0 +1,134 @@
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 LICENSE.GPL.
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/leds.h>
65#include "iwl-io.h"
66#include "iwl-csr.h"
67#include "mvm.h"
68
69/* Set led register on */
70static void iwl_mvm_led_enable(struct iwl_mvm *mvm)
71{
72 iwl_write32(mvm->trans, CSR_LED_REG, CSR_LED_REG_TURN_ON);
73}
74
75/* Set led register off */
76static void iwl_mvm_led_disable(struct iwl_mvm *mvm)
77{
78 iwl_write32(mvm->trans, CSR_LED_REG, CSR_LED_REG_TURN_OFF);
79}
80
81static void iwl_led_brightness_set(struct led_classdev *led_cdev,
82 enum led_brightness brightness)
83{
84 struct iwl_mvm *mvm = container_of(led_cdev, struct iwl_mvm, led);
85 if (brightness > 0)
86 iwl_mvm_led_enable(mvm);
87 else
88 iwl_mvm_led_disable(mvm);
89}
90
91int iwl_mvm_leds_init(struct iwl_mvm *mvm)
92{
93 int mode = iwlwifi_mod_params.led_mode;
94 int ret;
95
96 switch (mode) {
97 case IWL_LED_DEFAULT:
98 case IWL_LED_RF_STATE:
99 mode = IWL_LED_RF_STATE;
100 break;
101 case IWL_LED_DISABLE:
102 IWL_INFO(mvm, "Led disabled\n");
103 return 0;
104 default:
105 return -EINVAL;
106 };
107
108 mvm->led.name = kasprintf(GFP_KERNEL, "%s-led",
109 wiphy_name(mvm->hw->wiphy));
110 mvm->led.brightness_set = iwl_led_brightness_set;
111 mvm->led.max_brightness = 1;
112
113 if (mode == IWL_LED_RF_STATE)
114 mvm->led.default_trigger =
115 ieee80211_get_radio_led_name(mvm->hw);
116
117 ret = led_classdev_register(mvm->trans->dev, &mvm->led);
118 if (ret) {
119 kfree(mvm->led.name);
120 IWL_INFO(mvm, "Failed to enable led\n");
121 return ret;
122 }
123
124 return 0;
125}
126
127void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
128{
129 if (iwlwifi_mod_params.led_mode == IWL_LED_DISABLE)
130 return;
131
132 led_classdev_unregister(&mvm->led);
133 kfree(mvm->led.name);
134}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
new file mode 100644
index 000000000000..c08a17a3cab9
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -0,0 +1,951 @@
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 LICENSE.GPL.
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/etherdevice.h>
65#include <net/mac80211.h>
66#include "iwl-io.h"
67#include "iwl-prph.h"
68#include "fw-api.h"
69#include "mvm.h"
70
71const u8 iwl_mvm_ac_to_tx_fifo[] = {
72 IWL_MVM_TX_FIFO_BK,
73 IWL_MVM_TX_FIFO_BE,
74 IWL_MVM_TX_FIFO_VI,
75 IWL_MVM_TX_FIFO_VO,
76};
77
78struct iwl_mvm_mac_iface_iterator_data {
79 struct iwl_mvm *mvm;
80 struct ieee80211_vif *vif;
81 unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)];
82 unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)];
83 unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_FIRST_AGG_QUEUE)];
84 enum iwl_tsf_id preferred_tsf;
85 bool found_vif;
86};
87
88static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
89 struct ieee80211_vif *vif)
90{
91 struct iwl_mvm_mac_iface_iterator_data *data = _data;
92 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
93 u32 ac;
94
95 /* Iterator may already find the interface being added -- skip it */
96 if (vif == data->vif) {
97 data->found_vif = true;
98 return;
99 }
100
101 /* Mark the queues used by the vif */
102 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
103 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
104 __set_bit(vif->hw_queue[ac], data->used_hw_queues);
105
106 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
107 __set_bit(vif->cab_queue, data->used_hw_queues);
108
109 /*
110 * Mark MAC IDs as used by clearing the available bit, and
111 * (below) mark TSFs as used if their existing use is not
112 * compatible with the new interface type.
113 * No locking or atomic bit operations are needed since the
114 * data is on the stack of the caller function.
115 */
116 __clear_bit(mvmvif->id, data->available_mac_ids);
117
118 /*
119 * The TSF is a hardware/firmware resource, there are 4 and
120 * the driver should assign and free them as needed. However,
121 * there are cases where 2 MACs should share the same TSF ID
122 * for the purpose of clock sync, an optimization to avoid
123 * clock drift causing overlapping TBTTs/DTIMs for a GO and
124 * client in the system.
125 *
126 * The firmware will decide according to the MAC type which
127 * will be the master and slave. Clients that need to sync
128 * with a remote station will be the master, and an AP or GO
129 * will be the slave.
130 *
131 * Depending on the new interface type it can be slaved to
132 * or become the master of an existing interface.
133 */
134 switch (data->vif->type) {
135 case NL80211_IFTYPE_STATION:
136 /*
137 * The new interface is client, so if the existing one
138 * we're iterating is an AP, the TSF should be used to
139 * avoid drift between the new client and existing AP,
140 * the existing AP will get drift updates from the new
141 * client context in this case
142 */
143 if (vif->type == NL80211_IFTYPE_AP) {
144 if (data->preferred_tsf == NUM_TSF_IDS &&
145 test_bit(mvmvif->tsf_id, data->available_tsf_ids))
146 data->preferred_tsf = mvmvif->tsf_id;
147 return;
148 }
149 break;
150 case NL80211_IFTYPE_AP:
151 /*
152 * The new interface is AP/GO, so should get drift
153 * updates from an existing client or use the same
154 * TSF as an existing GO. There's no drift between
155 * TSFs internally but if they used different TSFs
156 * then a new client MAC could update one of them
157 * and cause drift that way.
158 */
159 if (vif->type == NL80211_IFTYPE_STATION ||
160 vif->type == NL80211_IFTYPE_AP) {
161 if (data->preferred_tsf == NUM_TSF_IDS &&
162 test_bit(mvmvif->tsf_id, data->available_tsf_ids))
163 data->preferred_tsf = mvmvif->tsf_id;
164 return;
165 }
166 break;
167 default:
168 /*
169 * For all other interface types there's no need to
170 * take drift into account. Either they're exclusive
171 * like IBSS and monitor, or we don't care much about
172 * their TSF (like P2P Device), but we won't be able
173 * to share the TSF resource.
174 */
175 break;
176 }
177
178 /*
179 * Unless we exited above, we can't share the TSF resource
180 * that the virtual interface we're iterating over is using
181 * with the new one, so clear the available bit and if this
182 * was the preferred one, reset that as well.
183 */
184 __clear_bit(mvmvif->tsf_id, data->available_tsf_ids);
185
186 if (data->preferred_tsf == mvmvif->tsf_id)
187 data->preferred_tsf = NUM_TSF_IDS;
188}
189
190/*
191 * Get the mask of the queus used by the vif
192 */
193u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
194 struct ieee80211_vif *vif)
195{
196 u32 qmask, ac;
197
198 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
199 return BIT(IWL_OFFCHANNEL_QUEUE);
200
201 qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ?
202 BIT(vif->cab_queue) : 0;
203
204 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
205 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
206 qmask |= BIT(vif->hw_queue[ac]);
207
208 return qmask;
209}
210
211static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
212 struct ieee80211_vif *vif)
213{
214 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
215 struct iwl_mvm_mac_iface_iterator_data data = {
216 .mvm = mvm,
217 .vif = vif,
218 .available_mac_ids = { (1 << NUM_MAC_INDEX_DRIVER) - 1 },
219 .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 },
220 /* no preference yet */
221 .preferred_tsf = NUM_TSF_IDS,
222 .used_hw_queues = {
223 BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
224 BIT(IWL_MVM_AUX_QUEUE) |
225 BIT(IWL_MVM_CMD_QUEUE)
226 },
227 .found_vif = false,
228 };
229 u32 ac;
230 int ret;
231
232 /*
233 * Allocate a MAC ID and a TSF for this MAC, along with the queues
234 * and other resources.
235 */
236
237 /*
238 * Before the iterator, we start with all MAC IDs and TSFs available.
239 *
240 * During iteration, all MAC IDs are cleared that are in use by other
241 * virtual interfaces, and all TSF IDs are cleared that can't be used
242 * by this new virtual interface because they're used by an interface
243 * that can't share it with the new one.
244 * At the same time, we check if there's a preferred TSF in the case
245 * that we should share it with another interface.
246 */
247
248 ieee80211_iterate_active_interfaces_atomic(
249 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
250 iwl_mvm_mac_iface_iterator, &data);
251
252 /*
253 * In the case we're getting here during resume, it's similar to
254 * firmware restart, and with RESUME_ALL the iterator will find
255 * the vif being added already.
256 * We don't want to reassign any IDs in either case since doing
257 * so would probably assign different IDs (as interfaces aren't
258 * necessarily added in the same order), but the old IDs were
259 * preserved anyway, so skip ID assignment for both resume and
260 * recovery.
261 */
262 if (data.found_vif)
263 return 0;
264
265 /* Therefore, in recovery, we can't get here */
266 WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status));
267
268 mvmvif->id = find_first_bit(data.available_mac_ids,
269 NUM_MAC_INDEX_DRIVER);
270 if (mvmvif->id == NUM_MAC_INDEX_DRIVER) {
271 IWL_ERR(mvm, "Failed to init MAC context - no free ID!\n");
272 ret = -EIO;
273 goto exit_fail;
274 }
275
276 if (data.preferred_tsf != NUM_TSF_IDS)
277 mvmvif->tsf_id = data.preferred_tsf;
278 else
279 mvmvif->tsf_id = find_first_bit(data.available_tsf_ids,
280 NUM_TSF_IDS);
281 if (mvmvif->tsf_id == NUM_TSF_IDS) {
282 IWL_ERR(mvm, "Failed to init MAC context - no free TSF!\n");
283 ret = -EIO;
284 goto exit_fail;
285 }
286
287 mvmvif->color = 0;
288
289 /* No need to allocate data queues to P2P Device MAC.*/
290 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
291 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
292 vif->hw_queue[ac] = IEEE80211_INVAL_HW_QUEUE;
293
294 return 0;
295 }
296
297 /* Find available queues, and allocate them to the ACs */
298 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
299 u8 queue = find_first_zero_bit(data.used_hw_queues,
300 IWL_MVM_FIRST_AGG_QUEUE);
301
302 if (queue >= IWL_MVM_FIRST_AGG_QUEUE) {
303 IWL_ERR(mvm, "Failed to allocate queue\n");
304 ret = -EIO;
305 goto exit_fail;
306 }
307
308 __set_bit(queue, data.used_hw_queues);
309 vif->hw_queue[ac] = queue;
310 }
311
312 /* Allocate the CAB queue for softAP and GO interfaces */
313 if (vif->type == NL80211_IFTYPE_AP) {
314 u8 queue = find_first_zero_bit(data.used_hw_queues,
315 IWL_MVM_FIRST_AGG_QUEUE);
316
317 if (queue >= IWL_MVM_FIRST_AGG_QUEUE) {
318 IWL_ERR(mvm, "Failed to allocate cab queue\n");
319 ret = -EIO;
320 goto exit_fail;
321 }
322
323 vif->cab_queue = queue;
324 } else {
325 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
326 }
327
328 mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT;
329 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
330
331 INIT_LIST_HEAD(&mvmvif->time_event_data.list);
332 mvmvif->time_event_data.id = TE_MAX;
333
334 return 0;
335
336exit_fail:
337 memset(mvmvif, 0, sizeof(struct iwl_mvm_vif));
338 memset(vif->hw_queue, IEEE80211_INVAL_HW_QUEUE, sizeof(vif->hw_queue));
339 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
340 return ret;
341}
342
343int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
344{
345 u32 ac;
346 int ret;
347
348 lockdep_assert_held(&mvm->mutex);
349
350 ret = iwl_mvm_mac_ctxt_allocate_resources(mvm, vif);
351 if (ret)
352 return ret;
353
354 switch (vif->type) {
355 case NL80211_IFTYPE_P2P_DEVICE:
356 iwl_trans_ac_txq_enable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE,
357 IWL_MVM_TX_FIFO_VO);
358 break;
359 case NL80211_IFTYPE_AP:
360 iwl_trans_ac_txq_enable(mvm->trans, vif->cab_queue,
361 IWL_MVM_TX_FIFO_VO);
362 /* fall through */
363 default:
364 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
365 iwl_trans_ac_txq_enable(mvm->trans, vif->hw_queue[ac],
366 iwl_mvm_ac_to_tx_fifo[ac]);
367 break;
368 }
369
370 return 0;
371}
372
373void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
374{
375 int ac;
376
377 lockdep_assert_held(&mvm->mutex);
378
379 switch (vif->type) {
380 case NL80211_IFTYPE_P2P_DEVICE:
381 iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE);
382 break;
383 case NL80211_IFTYPE_AP:
384 iwl_trans_txq_disable(mvm->trans, vif->cab_queue);
385 /* fall through */
386 default:
387 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
388 iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac]);
389 }
390}
391
392static void iwl_mvm_ack_rates(struct iwl_mvm *mvm,
393 struct ieee80211_vif *vif,
394 enum ieee80211_band band,
395 u8 *cck_rates, u8 *ofdm_rates)
396{
397 struct ieee80211_supported_band *sband;
398 unsigned long basic = vif->bss_conf.basic_rates;
399 int lowest_present_ofdm = 100;
400 int lowest_present_cck = 100;
401 u8 cck = 0;
402 u8 ofdm = 0;
403 int i;
404
405 sband = mvm->hw->wiphy->bands[band];
406
407 for_each_set_bit(i, &basic, BITS_PER_LONG) {
408 int hw = sband->bitrates[i].hw_value;
409 if (hw >= IWL_FIRST_OFDM_RATE) {
410 ofdm |= BIT(hw - IWL_FIRST_OFDM_RATE);
411 if (lowest_present_ofdm > hw)
412 lowest_present_ofdm = hw;
413 } else {
414 BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
415
416 cck |= BIT(hw);
417 if (lowest_present_cck > hw)
418 lowest_present_cck = hw;
419 }
420 }
421
422 /*
423 * Now we've got the basic rates as bitmaps in the ofdm and cck
424 * variables. This isn't sufficient though, as there might not
425 * be all the right rates in the bitmap. E.g. if the only basic
426 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
427 * and 6 Mbps because the 802.11-2007 standard says in 9.6:
428 *
429 * [...] a STA responding to a received frame shall transmit
430 * its Control Response frame [...] at the highest rate in the
431 * BSSBasicRateSet parameter that is less than or equal to the
432 * rate of the immediately previous frame in the frame exchange
433 * sequence ([...]) and that is of the same modulation class
434 * ([...]) as the received frame. If no rate contained in the
435 * BSSBasicRateSet parameter meets these conditions, then the
436 * control frame sent in response to a received frame shall be
437 * transmitted at the highest mandatory rate of the PHY that is
438 * less than or equal to the rate of the received frame, and
439 * that is of the same modulation class as the received frame.
440 *
441 * As a consequence, we need to add all mandatory rates that are
442 * lower than all of the basic rates to these bitmaps.
443 */
444
445 if (IWL_RATE_24M_INDEX < lowest_present_ofdm)
446 ofdm |= IWL_RATE_BIT_MSK(24) >> IWL_FIRST_OFDM_RATE;
447 if (IWL_RATE_12M_INDEX < lowest_present_ofdm)
448 ofdm |= IWL_RATE_BIT_MSK(12) >> IWL_FIRST_OFDM_RATE;
449 /* 6M already there or needed so always add */
450 ofdm |= IWL_RATE_BIT_MSK(6) >> IWL_FIRST_OFDM_RATE;
451
452 /*
453 * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
454 * Note, however:
455 * - if no CCK rates are basic, it must be ERP since there must
456 * be some basic rates at all, so they're OFDM => ERP PHY
457 * (or we're in 5 GHz, and the cck bitmap will never be used)
458 * - if 11M is a basic rate, it must be ERP as well, so add 5.5M
459 * - if 5.5M is basic, 1M and 2M are mandatory
460 * - if 2M is basic, 1M is mandatory
461 * - if 1M is basic, that's the only valid ACK rate.
462 * As a consequence, it's not as complicated as it sounds, just add
463 * any lower rates to the ACK rate bitmap.
464 */
465 if (IWL_RATE_11M_INDEX < lowest_present_cck)
466 cck |= IWL_RATE_BIT_MSK(11) >> IWL_FIRST_CCK_RATE;
467 if (IWL_RATE_5M_INDEX < lowest_present_cck)
468 cck |= IWL_RATE_BIT_MSK(5) >> IWL_FIRST_CCK_RATE;
469 if (IWL_RATE_2M_INDEX < lowest_present_cck)
470 cck |= IWL_RATE_BIT_MSK(2) >> IWL_FIRST_CCK_RATE;
471 /* 1M already there or needed so always add */
472 cck |= IWL_RATE_BIT_MSK(1) >> IWL_FIRST_CCK_RATE;
473
474 *cck_rates = cck;
475 *ofdm_rates = ofdm;
476}
477
478static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
479 struct ieee80211_vif *vif,
480 struct iwl_mac_ctx_cmd *cmd,
481 u32 action)
482{
483 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
484 struct ieee80211_chanctx_conf *chanctx;
485 u8 cck_ack_rates, ofdm_ack_rates;
486 int i;
487
488 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
489 mvmvif->color));
490 cmd->action = cpu_to_le32(action);
491
492 switch (vif->type) {
493 case NL80211_IFTYPE_STATION:
494 if (vif->p2p)
495 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_P2P_STA);
496 else
497 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_BSS_STA);
498 break;
499 case NL80211_IFTYPE_AP:
500 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_GO);
501 break;
502 case NL80211_IFTYPE_MONITOR:
503 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_LISTENER);
504 break;
505 case NL80211_IFTYPE_P2P_DEVICE:
506 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_P2P_DEVICE);
507 break;
508 case NL80211_IFTYPE_ADHOC:
509 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_IBSS);
510 break;
511 default:
512 WARN_ON_ONCE(1);
513 }
514
515 cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id);
516
517 memcpy(cmd->node_addr, vif->addr, ETH_ALEN);
518 if (vif->bss_conf.bssid)
519 memcpy(cmd->bssid_addr, vif->bss_conf.bssid, ETH_ALEN);
520 else
521 eth_broadcast_addr(cmd->bssid_addr);
522
523 rcu_read_lock();
524 chanctx = rcu_dereference(vif->chanctx_conf);
525 iwl_mvm_ack_rates(mvm, vif, chanctx ? chanctx->def.chan->band
526 : IEEE80211_BAND_2GHZ,
527 &cck_ack_rates, &ofdm_ack_rates);
528 rcu_read_unlock();
529
530 cmd->cck_rates = cpu_to_le32((u32)cck_ack_rates);
531 cmd->ofdm_rates = cpu_to_le32((u32)ofdm_ack_rates);
532
533 cmd->cck_short_preamble =
534 cpu_to_le32(vif->bss_conf.use_short_preamble ?
535 MAC_FLG_SHORT_PREAMBLE : 0);
536 cmd->short_slot =
537 cpu_to_le32(vif->bss_conf.use_short_slot ?
538 MAC_FLG_SHORT_SLOT : 0);
539
540 for (i = 0; i < AC_NUM; i++) {
541 cmd->ac[i].cw_min = cpu_to_le16(mvmvif->queue_params[i].cw_min);
542 cmd->ac[i].cw_max = cpu_to_le16(mvmvif->queue_params[i].cw_max);
543 cmd->ac[i].aifsn = mvmvif->queue_params[i].aifs;
544 cmd->ac[i].edca_txop =
545 cpu_to_le16(mvmvif->queue_params[i].txop * 32);
546 cmd->ac[i].fifos_mask = BIT(iwl_mvm_ac_to_tx_fifo[i]);
547 }
548
549 if (vif->bss_conf.qos)
550 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
551
552 if (vif->bss_conf.use_cts_prot)
553 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT |
554 MAC_PROT_FLG_SELF_CTS_EN);
555
556 /*
557 * I think that we should enable these 2 flags regardless the HT PROT
558 * fields in the HT IE, but I am not sure. Someone knows whom to ask?...
559 */
560 if (vif->bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
561 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_TGN);
562 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_HT_PROT |
563 MAC_PROT_FLG_FAT_PROT);
564 }
565
566 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
567}
568
569static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm,
570 struct iwl_mac_ctx_cmd *cmd)
571{
572 int ret = iwl_mvm_send_cmd_pdu(mvm, MAC_CONTEXT_CMD, CMD_SYNC,
573 sizeof(*cmd), cmd);
574 if (ret)
575 IWL_ERR(mvm, "Failed to send MAC context (action:%d): %d\n",
576 le32_to_cpu(cmd->action), ret);
577 return ret;
578}
579
580/*
581 * Fill the specific data for mac context of type station or p2p client
582 */
583static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm,
584 struct ieee80211_vif *vif,
585 struct iwl_mac_data_sta *ctxt_sta)
586{
587 ctxt_sta->is_assoc = cpu_to_le32(vif->bss_conf.assoc ? 1 : 0);
588
589 ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int);
590 ctxt_sta->bi_reciprocal =
591 cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
592 ctxt_sta->dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int *
593 vif->bss_conf.dtim_period);
594 ctxt_sta->dtim_reciprocal =
595 cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int *
596 vif->bss_conf.dtim_period));
597
598 ctxt_sta->listen_interval = cpu_to_le32(mvm->hw->conf.listen_interval);
599 ctxt_sta->assoc_id = cpu_to_le32(vif->bss_conf.aid);
600}
601
602static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm,
603 struct ieee80211_vif *vif,
604 u32 action)
605{
606 struct iwl_mac_ctx_cmd cmd = {};
607
608 WARN_ON(vif->type != NL80211_IFTYPE_STATION || vif->p2p);
609
610 /* Fill the common data for all mac context types */
611 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
612
613 /* Fill the data specific for station mode */
614 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta);
615
616 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
617}
618
619static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
620 struct ieee80211_vif *vif,
621 u32 action)
622{
623 struct iwl_mac_ctx_cmd cmd = {};
624
625 WARN_ON(vif->type != NL80211_IFTYPE_STATION || !vif->p2p);
626
627 /* Fill the common data for all mac context types */
628 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
629
630 /* Fill the data specific for station mode */
631 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta);
632
633 cmd.p2p_sta.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);
634
635 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
636}
637
638static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
639 struct ieee80211_vif *vif,
640 u32 action)
641{
642 struct iwl_mac_ctx_cmd cmd = {};
643
644 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
645
646 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
647 /* No other data to be filled */
648 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
649}
650
651struct iwl_mvm_go_iterator_data {
652 bool go_active;
653};
654
655static void iwl_mvm_go_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif)
656{
657 struct iwl_mvm_go_iterator_data *data = _data;
658 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
659
660 if (vif->type == NL80211_IFTYPE_AP && vif->p2p && mvmvif->ap_active)
661 data->go_active = true;
662}
663
664static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,
665 struct ieee80211_vif *vif,
666 u32 action)
667{
668 struct iwl_mac_ctx_cmd cmd = {};
669 struct iwl_mvm_go_iterator_data data = {};
670
671 WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE);
672
673 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
674
675 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
676 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROMISC);
677
678 /*
679 * This flag should be set to true when the P2P Device is
680 * discoverable and there is at least another active P2P GO. Settings
681 * this flag will allow the P2P Device to be discoverable on other
682 * channels in addition to its listen channel.
683 * Note that this flag should not be set in other cases as it opens the
684 * Rx filters on all MAC and increases the number of interrupts.
685 */
686 ieee80211_iterate_active_interfaces_atomic(
687 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
688 iwl_mvm_go_iterator, &data);
689
690 cmd.p2p_dev.is_disc_extended = cpu_to_le32(data.go_active ? 1 : 0);
691 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
692}
693
694static void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm,
695 struct iwl_mac_beacon_cmd *beacon_cmd,
696 u8 *beacon, u32 frame_size)
697{
698 u32 tim_idx;
699 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
700
701 /* The index is relative to frame start but we start looking at the
702 * variable-length part of the beacon. */
703 tim_idx = mgmt->u.beacon.variable - beacon;
704
705 /* Parse variable-length elements of beacon to find WLAN_EID_TIM */
706 while ((tim_idx < (frame_size - 2)) &&
707 (beacon[tim_idx] != WLAN_EID_TIM))
708 tim_idx += beacon[tim_idx+1] + 2;
709
710 /* If TIM field was found, set variables */
711 if ((tim_idx < (frame_size - 1)) && (beacon[tim_idx] == WLAN_EID_TIM)) {
712 beacon_cmd->tim_idx = cpu_to_le32(tim_idx);
713 beacon_cmd->tim_size = cpu_to_le32((u32)beacon[tim_idx+1]);
714 } else {
715 IWL_WARN(mvm, "Unable to find TIM Element in beacon\n");
716 }
717}
718
719static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
720 struct ieee80211_vif *vif,
721 struct sk_buff *beacon)
722{
723 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
724 struct iwl_host_cmd cmd = {
725 .id = BEACON_TEMPLATE_CMD,
726 .flags = CMD_ASYNC,
727 };
728 struct iwl_mac_beacon_cmd beacon_cmd = {};
729 struct ieee80211_tx_info *info;
730 u32 beacon_skb_len;
731 u32 rate;
732
733 if (WARN_ON(!beacon))
734 return -EINVAL;
735
736 beacon_skb_len = beacon->len;
737
738 /* TODO: for now the beacon template id is set to be the mac context id.
739 * Might be better to handle it as another resource ... */
740 beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
741
742 /* Set up TX command fields */
743 beacon_cmd.tx.len = cpu_to_le16((u16)beacon_skb_len);
744 beacon_cmd.tx.sta_id = mvmvif->bcast_sta.sta_id;
745 beacon_cmd.tx.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
746 beacon_cmd.tx.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
747 TX_CMD_FLG_BT_DIS |
748 TX_CMD_FLG_TSF);
749
750 mvm->mgmt_last_antenna_idx =
751 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant,
752 mvm->mgmt_last_antenna_idx);
753
754 beacon_cmd.tx.rate_n_flags =
755 cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
756 RATE_MCS_ANT_POS);
757
758 info = IEEE80211_SKB_CB(beacon);
759
760 if (info->band == IEEE80211_BAND_5GHZ || vif->p2p) {
761 rate = IWL_FIRST_OFDM_RATE;
762 } else {
763 rate = IWL_FIRST_CCK_RATE;
764 beacon_cmd.tx.rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
765 }
766 beacon_cmd.tx.rate_n_flags |=
767 cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate));
768
769 /* Set up TX beacon command fields */
770 iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd,
771 beacon->data,
772 beacon_skb_len);
773
774 /* Submit command */
775 cmd.len[0] = sizeof(beacon_cmd);
776 cmd.data[0] = &beacon_cmd;
777 cmd.dataflags[0] = 0;
778 cmd.len[1] = beacon_skb_len;
779 cmd.data[1] = beacon->data;
780 cmd.dataflags[1] = IWL_HCMD_DFL_DUP;
781
782 return iwl_mvm_send_cmd(mvm, &cmd);
783}
784
785/* The beacon template for the AP/GO context has changed and needs update */
786int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
787 struct ieee80211_vif *vif)
788{
789 struct sk_buff *beacon;
790 int ret;
791
792 WARN_ON(vif->type != NL80211_IFTYPE_AP);
793
794 beacon = ieee80211_beacon_get(mvm->hw, vif);
795 if (!beacon)
796 return -ENOMEM;
797
798 ret = iwl_mvm_mac_ctxt_send_beacon(mvm, vif, beacon);
799 dev_kfree_skb(beacon);
800 return ret;
801}
802
803/*
804 * Fill the specific data for mac context of type AP of P2P GO
805 */
806static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
807 struct ieee80211_vif *vif,
808 struct iwl_mac_data_ap *ctxt_ap)
809{
810 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
811 u32 curr_dev_time;
812
813 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
814 ctxt_ap->bi_reciprocal =
815 cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
816 ctxt_ap->dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int *
817 vif->bss_conf.dtim_period);
818 ctxt_ap->dtim_reciprocal =
819 cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int *
820 vif->bss_conf.dtim_period));
821
822 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);
823 curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
824 ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time);
825
826 ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time);
827
828 /* TODO: Assume that the beacon id == mac context id */
829 ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id);
830}
831
832static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm,
833 struct ieee80211_vif *vif,
834 u32 action)
835{
836 struct iwl_mac_ctx_cmd cmd = {};
837
838 WARN_ON(vif->type != NL80211_IFTYPE_AP || vif->p2p);
839
840 /* Fill the common data for all mac context types */
841 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
842
843 /* Fill the data specific for ap mode */
844 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap);
845
846 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
847}
848
849static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
850 struct ieee80211_vif *vif,
851 u32 action)
852{
853 struct iwl_mac_ctx_cmd cmd = {};
854
855 WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p);
856
857 /* Fill the common data for all mac context types */
858 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
859
860 /* Fill the data specific for GO mode */
861 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap);
862
863 cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);
864 cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps);
865
866 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
867}
868
869static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
870 u32 action)
871{
872 switch (vif->type) {
873 case NL80211_IFTYPE_STATION:
874 if (!vif->p2p)
875 return iwl_mvm_mac_ctxt_cmd_station(mvm, vif,
876 action);
877 else
878 return iwl_mvm_mac_ctxt_cmd_p2p_client(mvm, vif,
879 action);
880 break;
881 case NL80211_IFTYPE_AP:
882 if (!vif->p2p)
883 return iwl_mvm_mac_ctxt_cmd_ap(mvm, vif, action);
884 else
885 return iwl_mvm_mac_ctxt_cmd_go(mvm, vif, action);
886 break;
887 case NL80211_IFTYPE_MONITOR:
888 return iwl_mvm_mac_ctxt_cmd_listener(mvm, vif, action);
889 case NL80211_IFTYPE_P2P_DEVICE:
890 return iwl_mvm_mac_ctxt_cmd_p2p_device(mvm, vif, action);
891 default:
892 break;
893 }
894
895 return -EOPNOTSUPP;
896}
897
898int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
899{
900 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
901 int ret;
902
903 if (WARN_ONCE(mvmvif->uploaded, "Adding active MAC %pM/%d\n",
904 vif->addr, ieee80211_vif_type_p2p(vif)))
905 return -EIO;
906
907 ret = iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD);
908 if (ret)
909 return ret;
910
911 mvmvif->uploaded = true;
912 return 0;
913}
914
915int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
916{
917 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
918
919 if (WARN_ONCE(!mvmvif->uploaded, "Changing inactive MAC %pM/%d\n",
920 vif->addr, ieee80211_vif_type_p2p(vif)))
921 return -EIO;
922
923 return iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY);
924}
925
926int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
927{
928 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
929 struct iwl_mac_ctx_cmd cmd;
930 int ret;
931
932 if (WARN_ONCE(!mvmvif->uploaded, "Removing inactive MAC %pM/%d\n",
933 vif->addr, ieee80211_vif_type_p2p(vif)))
934 return -EIO;
935
936 memset(&cmd, 0, sizeof(cmd));
937
938 cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
939 mvmvif->color));
940 cmd.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE);
941
942 ret = iwl_mvm_send_cmd_pdu(mvm, MAC_CONTEXT_CMD, CMD_SYNC,
943 sizeof(cmd), &cmd);
944 if (ret) {
945 IWL_ERR(mvm, "Failed to remove MAC context: %d\n", ret);
946 return ret;
947 }
948
949 mvmvif->uploaded = false;
950 return 0;
951}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
new file mode 100644
index 000000000000..a6b05a02cfd4
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -0,0 +1,1310 @@
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 LICENSE.GPL.
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#include <linux/kernel.h>
64#include <linux/slab.h>
65#include <linux/skbuff.h>
66#include <linux/netdevice.h>
67#include <linux/etherdevice.h>
68#include <net/mac80211.h>
69
70#include "iwl-op-mode.h"
71#include "iwl-io.h"
72#include "mvm.h"
73#include "sta.h"
74#include "time-event.h"
75#include "iwl-eeprom-parse.h"
76#include "fw-api-scan.h"
77#include "iwl-phy-db.h"
78
79static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
80 {
81 .max = 1,
82 .types = BIT(NL80211_IFTYPE_STATION) |
83 BIT(NL80211_IFTYPE_AP),
84 },
85 {
86 .max = 1,
87 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
88 BIT(NL80211_IFTYPE_P2P_GO),
89 },
90 {
91 .max = 1,
92 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
93 },
94};
95
96static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
97 {
98 .num_different_channels = 1,
99 .max_interfaces = 3,
100 .limits = iwl_mvm_limits,
101 .n_limits = ARRAY_SIZE(iwl_mvm_limits),
102 },
103};
104
105int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
106{
107 struct ieee80211_hw *hw = mvm->hw;
108 int num_mac, ret;
109
110 /* Tell mac80211 our characteristics */
111 hw->flags = IEEE80211_HW_SIGNAL_DBM |
112 IEEE80211_HW_SPECTRUM_MGMT |
113 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
114 IEEE80211_HW_QUEUE_CONTROL |
115 IEEE80211_HW_WANT_MONITOR_VIF |
116 IEEE80211_HW_SCAN_WHILE_IDLE |
117 IEEE80211_HW_NEED_DTIM_PERIOD |
118 IEEE80211_HW_SUPPORTS_PS |
119 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
120 IEEE80211_HW_AMPDU_AGGREGATION;
121
122 hw->queues = IWL_FIRST_AMPDU_QUEUE;
123 hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE;
124 hw->rate_control_algorithm = "iwl-mvm-rs";
125
126 /*
127 * Enable 11w if advertised by firmware and software crypto
128 * is not enabled (as the firmware will interpret some mgmt
129 * packets, so enabling it with software crypto isn't safe)
130 */
131 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP &&
132 !iwlwifi_mod_params.sw_crypto)
133 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
134
135 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
136 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
137 hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt);
138
139 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
140 BIT(NL80211_IFTYPE_P2P_CLIENT) |
141 BIT(NL80211_IFTYPE_AP) |
142 BIT(NL80211_IFTYPE_P2P_GO) |
143 BIT(NL80211_IFTYPE_P2P_DEVICE);
144
145 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
146 WIPHY_FLAG_DISABLE_BEACON_HINTS |
147 WIPHY_FLAG_IBSS_RSN;
148
149 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
150 hw->wiphy->n_iface_combinations =
151 ARRAY_SIZE(iwl_mvm_iface_combinations);
152
153 hw->wiphy->max_remain_on_channel_duration = 500;
154 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
155
156 /* Extract MAC address */
157 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
158 hw->wiphy->addresses = mvm->addresses;
159 hw->wiphy->n_addresses = 1;
160 num_mac = mvm->nvm_data->n_hw_addrs;
161 if (num_mac > 1) {
162 memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr,
163 ETH_ALEN);
164 mvm->addresses[1].addr[5]++;
165 hw->wiphy->n_addresses++;
166 }
167
168 /* we create the 802.11 header and a max-length SSID element */
169 hw->wiphy->max_scan_ie_len =
170 mvm->fw->ucode_capa.max_probe_length - 24 - 34;
171 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
172
173 if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
174 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
175 &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
176 if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels)
177 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
178 &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
179
180 hw->wiphy->hw_version = mvm->trans->hw_id;
181
182 if (iwlwifi_mod_params.power_save)
183 hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
184 else
185 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
186
187 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
188 NL80211_FEATURE_P2P_GO_OPPPS;
189
190 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
191
192#ifdef CONFIG_PM_SLEEP
193 if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
194 mvm->trans->ops->d3_suspend &&
195 mvm->trans->ops->d3_resume &&
196 device_can_wakeup(mvm->trans->dev)) {
197 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
198 WIPHY_WOWLAN_DISCONNECT |
199 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
200 WIPHY_WOWLAN_RFKILL_RELEASE;
201 if (!iwlwifi_mod_params.sw_crypto)
202 hw->wiphy->wowlan.flags |=
203 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
204 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
205 WIPHY_WOWLAN_4WAY_HANDSHAKE;
206
207 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
208 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
209 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
210 }
211#endif
212
213 ret = iwl_mvm_leds_init(mvm);
214 if (ret)
215 return ret;
216
217 return ieee80211_register_hw(mvm->hw);
218}
219
220static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
221 struct ieee80211_tx_control *control,
222 struct sk_buff *skb)
223{
224 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
225
226 if (test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status)) {
227 IWL_DEBUG_DROP(mvm, "Dropping - RF KILL\n");
228 goto drop;
229 }
230
231 if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_OFFCHANNEL_QUEUE &&
232 !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
233 goto drop;
234
235 if (control->sta) {
236 if (iwl_mvm_tx_skb(mvm, skb, control->sta))
237 goto drop;
238 return;
239 }
240
241 if (iwl_mvm_tx_skb_non_sta(mvm, skb))
242 goto drop;
243 return;
244 drop:
245 ieee80211_free_txskb(hw, skb);
246}
247
248static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
249 struct ieee80211_vif *vif,
250 enum ieee80211_ampdu_mlme_action action,
251 struct ieee80211_sta *sta, u16 tid,
252 u16 *ssn, u8 buf_size)
253{
254 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
255 int ret;
256
257 IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
258 sta->addr, tid, action);
259
260 if (!(mvm->nvm_data->sku_cap_11n_enable))
261 return -EACCES;
262
263 mutex_lock(&mvm->mutex);
264
265 switch (action) {
266 case IEEE80211_AMPDU_RX_START:
267 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) {
268 ret = -EINVAL;
269 break;
270 }
271 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, *ssn, true);
272 break;
273 case IEEE80211_AMPDU_RX_STOP:
274 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
275 break;
276 case IEEE80211_AMPDU_TX_START:
277 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
278 break;
279 case IEEE80211_AMPDU_TX_STOP_CONT:
280 case IEEE80211_AMPDU_TX_STOP_FLUSH:
281 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
282 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
283 break;
284 case IEEE80211_AMPDU_TX_OPERATIONAL:
285 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size);
286 break;
287 default:
288 WARN_ON_ONCE(1);
289 ret = -EINVAL;
290 break;
291 }
292 mutex_unlock(&mvm->mutex);
293
294 return ret;
295}
296
297static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
298 struct ieee80211_vif *vif)
299{
300 struct iwl_mvm *mvm = data;
301 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
302
303 mvmvif->uploaded = false;
304 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
305
306 /* does this make sense at all? */
307 mvmvif->color++;
308
309 spin_lock_bh(&mvm->time_event_lock);
310 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
311 spin_unlock_bh(&mvm->time_event_lock);
312
313 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
314 mvmvif->phy_ctxt = NULL;
315}
316
317static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
318{
319 iwl_trans_stop_device(mvm->trans);
320 iwl_trans_stop_hw(mvm->trans, false);
321
322 mvm->scan_status = IWL_MVM_SCAN_NONE;
323
324 /* just in case one was running */
325 ieee80211_remain_on_channel_expired(mvm->hw);
326
327 ieee80211_iterate_active_interfaces_atomic(
328 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
329 iwl_mvm_cleanup_iterator, mvm);
330
331 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
332 memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
333
334 ieee80211_wake_queues(mvm->hw);
335
336 mvm->vif_count = 0;
337}
338
339static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
340{
341 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
342 int ret;
343
344 mutex_lock(&mvm->mutex);
345
346 /* Clean up some internal and mac80211 state on restart */
347 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
348 iwl_mvm_restart_cleanup(mvm);
349
350 ret = iwl_mvm_up(mvm);
351 mutex_unlock(&mvm->mutex);
352
353 return ret;
354}
355
356static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
357{
358 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
359 int ret;
360
361 mutex_lock(&mvm->mutex);
362
363 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
364 ret = iwl_mvm_update_quotas(mvm, NULL);
365 if (ret)
366 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
367 ret);
368
369 mutex_unlock(&mvm->mutex);
370}
371
372static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
373{
374 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
375
376 flush_work(&mvm->async_handlers_wk);
377
378 mutex_lock(&mvm->mutex);
379 /* async_handlers_wk is now blocked */
380
381 /*
382 * The work item could be running or queued if the
383 * ROC time event stops just as we get here.
384 */
385 cancel_work_sync(&mvm->roc_done_wk);
386
387 iwl_trans_stop_device(mvm->trans);
388 iwl_trans_stop_hw(mvm->trans, false);
389
390 iwl_mvm_async_handlers_purge(mvm);
391 /* async_handlers_list is empty and will stay empty: HW is stopped */
392
393 /* the fw is stopped, the aux sta is dead: clean up driver state */
394 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
395
396 mutex_unlock(&mvm->mutex);
397
398 /*
399 * The worker might have been waiting for the mutex, let it run and
400 * discover that its list is now empty.
401 */
402 cancel_work_sync(&mvm->async_handlers_wk);
403}
404
405static void iwl_mvm_pm_disable_iterator(void *data, u8 *mac,
406 struct ieee80211_vif *vif)
407{
408 struct iwl_mvm *mvm = data;
409 int ret;
410
411 ret = iwl_mvm_power_disable(mvm, vif);
412 if (ret)
413 IWL_ERR(mvm, "failed to disable power management\n");
414}
415
416static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
417 struct ieee80211_vif *vif)
418{
419 struct iwl_mvm *mvm = data;
420
421 iwl_mvm_power_update_mode(mvm, vif);
422}
423
424static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
425 struct ieee80211_vif *vif)
426{
427 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
428 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
429 int ret;
430
431 /*
432 * Not much to do here. The stack will not allow interface
433 * types or combinations that we didn't advertise, so we
434 * don't really have to check the types.
435 */
436
437 mutex_lock(&mvm->mutex);
438
439 /* Allocate resources for the MAC context, and add it the the fw */
440 ret = iwl_mvm_mac_ctxt_init(mvm, vif);
441 if (ret)
442 goto out_unlock;
443
444 /*
445 * The AP binding flow can be done only after the beacon
446 * template is configured (which happens only in the mac80211
447 * start_ap() flow), and adding the broadcast station can happen
448 * only after the binding.
449 * In addition, since modifying the MAC before adding a bcast
450 * station is not allowed by the FW, delay the adding of MAC context to
451 * the point where we can also add the bcast station.
452 * In short: there's not much we can do at this point, other than
453 * allocating resources :)
454 */
455 if (vif->type == NL80211_IFTYPE_AP) {
456 u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
457 ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
458 qmask);
459 if (ret) {
460 IWL_ERR(mvm, "Failed to allocate bcast sta\n");
461 goto out_release;
462 }
463
464 goto out_unlock;
465 }
466
467 /*
468 * TODO: remove this temporary code.
469 * Currently MVM FW supports power management only on single MAC.
470 * Iterate and disable PM on all active interfaces.
471 * Note: the method below does not count the new interface being added
472 * at this moment.
473 */
474 mvm->vif_count++;
475 if (mvm->vif_count > 1) {
476 IWL_DEBUG_MAC80211(mvm,
477 "Disable power on existing interfaces\n");
478 ieee80211_iterate_active_interfaces(
479 mvm->hw,
480 IEEE80211_IFACE_ITER_NORMAL,
481 iwl_mvm_pm_disable_iterator, mvm);
482 }
483
484 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
485 if (ret)
486 goto out_release;
487
488 /*
489 * Update power state on the new interface. Admittedly, based on
490 * mac80211 logics this power update will disable power management
491 */
492 iwl_mvm_power_update_mode(mvm, vif);
493
494 /*
495 * P2P_DEVICE interface does not have a channel context assigned to it,
496 * so a dedicated PHY context is allocated to it and the corresponding
497 * MAC context is bound to it at this stage.
498 */
499 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
500 struct ieee80211_channel *chan;
501 struct cfg80211_chan_def chandef;
502
503 mvmvif->phy_ctxt = &mvm->phy_ctxt_roc;
504
505 /*
506 * The channel used here isn't relevant as it's
507 * going to be overwritten as part of the ROC flow.
508 * For now use the first channel we have.
509 */
510 chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
511 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
512 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt,
513 &chandef, 1, 1);
514 if (ret)
515 goto out_remove_mac;
516
517 ret = iwl_mvm_binding_add_vif(mvm, vif);
518 if (ret)
519 goto out_remove_phy;
520
521 ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
522 if (ret)
523 goto out_unbind;
524
525 /* Save a pointer to p2p device vif, so it can later be used to
526 * update the p2p device MAC when a GO is started/stopped */
527 mvm->p2p_device_vif = vif;
528 }
529
530 goto out_unlock;
531
532 out_unbind:
533 iwl_mvm_binding_remove_vif(mvm, vif);
534 out_remove_phy:
535 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt);
536 out_remove_mac:
537 mvmvif->phy_ctxt = NULL;
538 iwl_mvm_mac_ctxt_remove(mvm, vif);
539 out_release:
540 /*
541 * TODO: remove this temporary code.
542 * Currently MVM FW supports power management only on single MAC.
543 * Check if only one additional interface remains after rereasing
544 * current one. Update power mode on the remaining interface.
545 */
546 mvm->vif_count--;
547 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
548 mvm->vif_count);
549 if (mvm->vif_count == 1) {
550 ieee80211_iterate_active_interfaces(
551 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
552 iwl_mvm_power_update_iterator, mvm);
553 }
554 iwl_mvm_mac_ctxt_release(mvm, vif);
555 out_unlock:
556 mutex_unlock(&mvm->mutex);
557
558 return ret;
559}
560
561static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
562 struct ieee80211_vif *vif)
563{
564 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
565 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
566 u32 tfd_msk = 0, ac;
567
568 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
569 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
570 tfd_msk |= BIT(vif->hw_queue[ac]);
571
572 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
573 tfd_msk |= BIT(vif->cab_queue);
574
575 if (tfd_msk) {
576 mutex_lock(&mvm->mutex);
577 iwl_mvm_flush_tx_path(mvm, tfd_msk, true);
578 mutex_unlock(&mvm->mutex);
579 }
580
581 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
582 /*
583 * Flush the ROC worker which will flush the OFFCHANNEL queue.
584 * We assume here that all the packets sent to the OFFCHANNEL
585 * queue are sent in ROC session.
586 */
587 flush_work(&mvm->roc_done_wk);
588 } else {
589 /*
590 * By now, all the AC queues are empty. The AGG queues are
591 * empty too. We already got all the Tx responses for all the
592 * packets in the queues. The drain work can have been
593 * triggered. Flush it. This work item takes the mutex, so kill
594 * it before we take it.
595 */
596 flush_work(&mvm->sta_drained_wk);
597 }
598
599 mutex_lock(&mvm->mutex);
600
601 /*
602 * For AP/GO interface, the tear down of the resources allocated to the
603 * interface should be handled as part of the bss_info_changed flow.
604 */
605 if (vif->type == NL80211_IFTYPE_AP) {
606 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
607 goto out_release;
608 }
609
610 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
611 mvm->p2p_device_vif = NULL;
612 iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
613 iwl_mvm_binding_remove_vif(mvm, vif);
614 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt);
615 mvmvif->phy_ctxt = NULL;
616 }
617
618 /*
619 * TODO: remove this temporary code.
620 * Currently MVM FW supports power management only on single MAC.
621 * Check if only one additional interface remains after removing
622 * current one. Update power mode on the remaining interface.
623 */
624 if (mvm->vif_count)
625 mvm->vif_count--;
626 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
627 mvm->vif_count);
628 if (mvm->vif_count == 1) {
629 ieee80211_iterate_active_interfaces(
630 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
631 iwl_mvm_power_update_iterator, mvm);
632 }
633
634 iwl_mvm_mac_ctxt_remove(mvm, vif);
635
636out_release:
637 iwl_mvm_mac_ctxt_release(mvm, vif);
638 mutex_unlock(&mvm->mutex);
639}
640
641static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed)
642{
643 return 0;
644}
645
646static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
647 unsigned int changed_flags,
648 unsigned int *total_flags,
649 u64 multicast)
650{
651 *total_flags = 0;
652}
653
654static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
655 struct ieee80211_vif *vif,
656 struct ieee80211_bss_conf *bss_conf,
657 u32 changes)
658{
659 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
660 int ret;
661
662 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
663 if (ret)
664 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
665
666 if (changes & BSS_CHANGED_ASSOC) {
667 if (bss_conf->assoc) {
668 /* add quota for this interface */
669 ret = iwl_mvm_update_quotas(mvm, vif);
670 if (ret) {
671 IWL_ERR(mvm, "failed to update quotas\n");
672 return;
673 }
674 iwl_mvm_remove_time_event(mvm, mvmvif,
675 &mvmvif->time_event_data);
676 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
677 /* remove AP station now that the MAC is unassoc */
678 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
679 if (ret)
680 IWL_ERR(mvm, "failed to remove AP station\n");
681 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
682 /* remove quota for this interface */
683 ret = iwl_mvm_update_quotas(mvm, NULL);
684 if (ret)
685 IWL_ERR(mvm, "failed to update quotas\n");
686 }
687 } else if (changes & BSS_CHANGED_PS) {
688 /*
689 * TODO: remove this temporary code.
690 * Currently MVM FW supports power management only on single
691 * MAC. Avoid power mode update if more than one interface
692 * is active.
693 */
694 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
695 mvm->vif_count);
696 if (mvm->vif_count == 1) {
697 ret = iwl_mvm_power_update_mode(mvm, vif);
698 if (ret)
699 IWL_ERR(mvm, "failed to update power mode\n");
700 }
701 }
702}
703
704static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
705{
706 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
707 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
708 int ret;
709
710 mutex_lock(&mvm->mutex);
711
712 /* Send the beacon template */
713 ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif);
714 if (ret)
715 goto out_unlock;
716
717 /* Add the mac context */
718 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
719 if (ret)
720 goto out_unlock;
721
722 /* Perform the binding */
723 ret = iwl_mvm_binding_add_vif(mvm, vif);
724 if (ret)
725 goto out_remove;
726
727 mvmvif->ap_active = true;
728
729 /* Send the bcast station. At this stage the TBTT and DTIM time events
730 * are added and applied to the scheduler */
731 ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
732 if (ret)
733 goto out_unbind;
734
735 ret = iwl_mvm_update_quotas(mvm, vif);
736 if (ret)
737 goto out_rm_bcast;
738
739 /* Need to update the P2P Device MAC */
740 if (vif->p2p && mvm->p2p_device_vif)
741 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
742
743 mutex_unlock(&mvm->mutex);
744 return 0;
745
746out_rm_bcast:
747 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
748out_unbind:
749 iwl_mvm_binding_remove_vif(mvm, vif);
750out_remove:
751 iwl_mvm_mac_ctxt_remove(mvm, vif);
752out_unlock:
753 mutex_unlock(&mvm->mutex);
754 return ret;
755}
756
757static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
758{
759 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
760 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
761
762 mutex_lock(&mvm->mutex);
763
764 mvmvif->ap_active = false;
765
766 /* Need to update the P2P Device MAC */
767 if (vif->p2p && mvm->p2p_device_vif)
768 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
769
770 iwl_mvm_update_quotas(mvm, NULL);
771 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
772 iwl_mvm_binding_remove_vif(mvm, vif);
773 iwl_mvm_mac_ctxt_remove(mvm, vif);
774
775 mutex_unlock(&mvm->mutex);
776}
777
778static void iwl_mvm_bss_info_changed_ap(struct iwl_mvm *mvm,
779 struct ieee80211_vif *vif,
780 struct ieee80211_bss_conf *bss_conf,
781 u32 changes)
782{
783 /* Need to send a new beacon template to the FW */
784 if (changes & BSS_CHANGED_BEACON) {
785 if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
786 IWL_WARN(mvm, "Failed updating beacon data\n");
787 }
788}
789
790static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
791 struct ieee80211_vif *vif,
792 struct ieee80211_bss_conf *bss_conf,
793 u32 changes)
794{
795 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
796
797 mutex_lock(&mvm->mutex);
798
799 switch (vif->type) {
800 case NL80211_IFTYPE_STATION:
801 iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes);
802 break;
803 case NL80211_IFTYPE_AP:
804 iwl_mvm_bss_info_changed_ap(mvm, vif, bss_conf, changes);
805 break;
806 default:
807 /* shouldn't happen */
808 WARN_ON_ONCE(1);
809 }
810
811 mutex_unlock(&mvm->mutex);
812}
813
814static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
815 struct ieee80211_vif *vif,
816 struct cfg80211_scan_request *req)
817{
818 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
819 int ret;
820
821 if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS)
822 return -EINVAL;
823
824 mutex_lock(&mvm->mutex);
825
826 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
827 ret = iwl_mvm_scan_request(mvm, vif, req);
828 else
829 ret = -EBUSY;
830
831 mutex_unlock(&mvm->mutex);
832
833 return ret;
834}
835
836static void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw,
837 struct ieee80211_vif *vif)
838{
839 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
840
841 mutex_lock(&mvm->mutex);
842
843 iwl_mvm_cancel_scan(mvm);
844
845 mutex_unlock(&mvm->mutex);
846}
847
848static void
849iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
850 struct ieee80211_sta *sta, u16 tid,
851 int num_frames,
852 enum ieee80211_frame_release_type reason,
853 bool more_data)
854{
855 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
856 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
857
858 /* TODO: how do we tell the fw to send frames for a specific TID */
859
860 /*
861 * The fw will send EOSP notification when the last frame will be
862 * transmitted.
863 */
864 iwl_mvm_sta_modify_sleep_tx_count(mvm, mvmsta->sta_id, reason,
865 num_frames);
866}
867
868static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
869 struct ieee80211_vif *vif,
870 enum sta_notify_cmd cmd,
871 struct ieee80211_sta *sta)
872{
873 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
874 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
875
876 switch (cmd) {
877 case STA_NOTIFY_SLEEP:
878 if (atomic_read(&mvmsta->pending_frames) > 0)
879 ieee80211_sta_block_awake(hw, sta, true);
880 /*
881 * The fw updates the STA to be asleep. Tx packets on the Tx
882 * queues to this station will not be transmitted. The fw will
883 * send a Tx response with TX_STATUS_FAIL_DEST_PS.
884 */
885 break;
886 case STA_NOTIFY_AWAKE:
887 if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION))
888 break;
889 iwl_mvm_sta_modify_ps_wake(mvm, mvmsta->sta_id);
890 break;
891 default:
892 break;
893 }
894}
895
896static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
897 struct ieee80211_vif *vif,
898 struct ieee80211_sta *sta,
899 enum ieee80211_sta_state old_state,
900 enum ieee80211_sta_state new_state)
901{
902 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
903 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
904 int ret;
905
906 IWL_DEBUG_MAC80211(mvm, "station %pM state change %d->%d\n",
907 sta->addr, old_state, new_state);
908
909 /* this would be a mac80211 bug ... but don't crash */
910 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
911 return -EINVAL;
912
913 /* if a STA is being removed, reuse its ID */
914 flush_work(&mvm->sta_drained_wk);
915
916 mutex_lock(&mvm->mutex);
917 if (old_state == IEEE80211_STA_NOTEXIST &&
918 new_state == IEEE80211_STA_NONE) {
919 ret = iwl_mvm_add_sta(mvm, vif, sta);
920 } else if (old_state == IEEE80211_STA_NONE &&
921 new_state == IEEE80211_STA_AUTH) {
922 ret = 0;
923 } else if (old_state == IEEE80211_STA_AUTH &&
924 new_state == IEEE80211_STA_ASSOC) {
925 iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band);
926 ret = 0;
927 } else if (old_state == IEEE80211_STA_ASSOC &&
928 new_state == IEEE80211_STA_AUTHORIZED) {
929 ret = 0;
930 } else if (old_state == IEEE80211_STA_AUTHORIZED &&
931 new_state == IEEE80211_STA_ASSOC) {
932 ret = 0;
933 } else if (old_state == IEEE80211_STA_ASSOC &&
934 new_state == IEEE80211_STA_AUTH) {
935 ret = 0;
936 } else if (old_state == IEEE80211_STA_AUTH &&
937 new_state == IEEE80211_STA_NONE) {
938 ret = 0;
939 } else if (old_state == IEEE80211_STA_NONE &&
940 new_state == IEEE80211_STA_NOTEXIST) {
941 ret = iwl_mvm_rm_sta(mvm, vif, sta);
942 } else {
943 ret = -EIO;
944 }
945 mutex_unlock(&mvm->mutex);
946
947 return ret;
948}
949
950static int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
951{
952 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
953
954 mvm->rts_threshold = value;
955
956 return 0;
957}
958
959static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
960 struct ieee80211_vif *vif, u16 ac,
961 const struct ieee80211_tx_queue_params *params)
962{
963 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
964 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
965
966 mvmvif->queue_params[ac] = *params;
967
968 /*
969 * No need to update right away, we'll get BSS_CHANGED_QOS
970 * The exception is P2P_DEVICE interface which needs immediate update.
971 */
972 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
973 int ret;
974
975 mutex_lock(&mvm->mutex);
976 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
977 mutex_unlock(&mvm->mutex);
978 return ret;
979 }
980 return 0;
981}
982
983static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
984 struct ieee80211_vif *vif)
985{
986 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
987 u32 duration = min(IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS,
988 200 + vif->bss_conf.beacon_int);
989 u32 min_duration = min(IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS,
990 100 + vif->bss_conf.beacon_int);
991
992 if (WARN_ON_ONCE(vif->bss_conf.assoc))
993 return;
994
995 mutex_lock(&mvm->mutex);
996 /* Try really hard to protect the session and hear a beacon */
997 iwl_mvm_protect_session(mvm, vif, duration, min_duration);
998 mutex_unlock(&mvm->mutex);
999}
1000
1001static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1002 enum set_key_cmd cmd,
1003 struct ieee80211_vif *vif,
1004 struct ieee80211_sta *sta,
1005 struct ieee80211_key_conf *key)
1006{
1007 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1008 int ret;
1009
1010 if (iwlwifi_mod_params.sw_crypto) {
1011 IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n");
1012 return -EOPNOTSUPP;
1013 }
1014
1015 switch (key->cipher) {
1016 case WLAN_CIPHER_SUITE_TKIP:
1017 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1018 /* fall-through */
1019 case WLAN_CIPHER_SUITE_CCMP:
1020 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1021 break;
1022 case WLAN_CIPHER_SUITE_AES_CMAC:
1023 WARN_ON_ONCE(!(hw->flags & IEEE80211_HW_MFP_CAPABLE));
1024 break;
1025 case WLAN_CIPHER_SUITE_WEP40:
1026 case WLAN_CIPHER_SUITE_WEP104:
1027 /*
1028 * Support for TX only, at least for now, so accept
1029 * the key and do nothing else. Then mac80211 will
1030 * pass it for TX but we don't have to use it for RX.
1031 */
1032 return 0;
1033 default:
1034 return -EOPNOTSUPP;
1035 }
1036
1037 mutex_lock(&mvm->mutex);
1038
1039 switch (cmd) {
1040 case SET_KEY:
1041 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
1042 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
1043 if (ret) {
1044 IWL_WARN(mvm, "set key failed\n");
1045 /*
1046 * can't add key for RX, but we don't need it
1047 * in the device for TX so still return 0
1048 */
1049 ret = 0;
1050 }
1051
1052 break;
1053 case DISABLE_KEY:
1054 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
1055 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
1056 break;
1057 default:
1058 ret = -EINVAL;
1059 }
1060
1061 mutex_unlock(&mvm->mutex);
1062 return ret;
1063}
1064
1065static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
1066 struct ieee80211_vif *vif,
1067 struct ieee80211_key_conf *keyconf,
1068 struct ieee80211_sta *sta,
1069 u32 iv32, u16 *phase1key)
1070{
1071 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1072
1073 iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key);
1074}
1075
1076
1077static int iwl_mvm_roc(struct ieee80211_hw *hw,
1078 struct ieee80211_vif *vif,
1079 struct ieee80211_channel *channel,
1080 int duration)
1081{
1082 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1083 struct cfg80211_chan_def chandef;
1084 int ret;
1085
1086 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
1087 IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
1088 return -EINVAL;
1089 }
1090
1091 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d)\n", channel->hw_value,
1092 duration);
1093
1094 mutex_lock(&mvm->mutex);
1095
1096 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
1097 ret = iwl_mvm_phy_ctxt_changed(mvm, &mvm->phy_ctxt_roc,
1098 &chandef, 1, 1);
1099
1100 /* Schedule the time events */
1101 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration);
1102
1103 mutex_unlock(&mvm->mutex);
1104 IWL_DEBUG_MAC80211(mvm, "leave\n");
1105
1106 return ret;
1107}
1108
1109static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
1110{
1111 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1112
1113 IWL_DEBUG_MAC80211(mvm, "enter\n");
1114
1115 mutex_lock(&mvm->mutex);
1116 iwl_mvm_stop_p2p_roc(mvm);
1117 mutex_unlock(&mvm->mutex);
1118
1119 IWL_DEBUG_MAC80211(mvm, "leave\n");
1120 return 0;
1121}
1122
1123static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1124 struct ieee80211_chanctx_conf *ctx)
1125{
1126 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1127 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1128 int ret;
1129
1130 mutex_lock(&mvm->mutex);
1131
1132 IWL_DEBUG_MAC80211(mvm, "Add PHY context\n");
1133 ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, &ctx->def,
1134 ctx->rx_chains_static,
1135 ctx->rx_chains_dynamic);
1136 mutex_unlock(&mvm->mutex);
1137 return ret;
1138}
1139
1140static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
1141 struct ieee80211_chanctx_conf *ctx)
1142{
1143 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1144 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1145
1146 mutex_lock(&mvm->mutex);
1147 iwl_mvm_phy_ctxt_remove(mvm, phy_ctxt);
1148 mutex_unlock(&mvm->mutex);
1149}
1150
1151static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1152 struct ieee80211_chanctx_conf *ctx,
1153 u32 changed)
1154{
1155 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1156 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1157
1158 mutex_lock(&mvm->mutex);
1159 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
1160 ctx->rx_chains_static,
1161 ctx->rx_chains_dynamic);
1162 mutex_unlock(&mvm->mutex);
1163}
1164
1165static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1166 struct ieee80211_vif *vif,
1167 struct ieee80211_chanctx_conf *ctx)
1168{
1169 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1170 struct iwl_mvm_phy_ctxt *phyctx = (void *)ctx->drv_priv;
1171 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1172 int ret;
1173
1174 mutex_lock(&mvm->mutex);
1175
1176 mvmvif->phy_ctxt = phyctx;
1177
1178 switch (vif->type) {
1179 case NL80211_IFTYPE_AP:
1180 /*
1181 * The AP binding flow is handled as part of the start_ap flow
1182 * (in bss_info_changed).
1183 */
1184 ret = 0;
1185 goto out_unlock;
1186 case NL80211_IFTYPE_STATION:
1187 case NL80211_IFTYPE_ADHOC:
1188 case NL80211_IFTYPE_MONITOR:
1189 break;
1190 default:
1191 ret = -EINVAL;
1192 goto out_unlock;
1193 }
1194
1195 ret = iwl_mvm_binding_add_vif(mvm, vif);
1196 if (ret)
1197 goto out_unlock;
1198
1199 /*
1200 * Setting the quota at this stage is only required for monitor
1201 * interfaces. For the other types, the bss_info changed flow
1202 * will handle quota settings.
1203 */
1204 if (vif->type == NL80211_IFTYPE_MONITOR) {
1205 ret = iwl_mvm_update_quotas(mvm, vif);
1206 if (ret)
1207 goto out_remove_binding;
1208 }
1209
1210 goto out_unlock;
1211
1212 out_remove_binding:
1213 iwl_mvm_binding_remove_vif(mvm, vif);
1214 out_unlock:
1215 mutex_unlock(&mvm->mutex);
1216 if (ret)
1217 mvmvif->phy_ctxt = NULL;
1218 return ret;
1219}
1220
1221static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1222 struct ieee80211_vif *vif,
1223 struct ieee80211_chanctx_conf *ctx)
1224{
1225 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1226 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1227
1228 mutex_lock(&mvm->mutex);
1229
1230 iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
1231
1232 if (vif->type == NL80211_IFTYPE_AP)
1233 goto out_unlock;
1234
1235 iwl_mvm_binding_remove_vif(mvm, vif);
1236 switch (vif->type) {
1237 case NL80211_IFTYPE_MONITOR:
1238 iwl_mvm_update_quotas(mvm, vif);
1239 break;
1240 default:
1241 break;
1242 }
1243
1244out_unlock:
1245 mvmvif->phy_ctxt = NULL;
1246 mutex_unlock(&mvm->mutex);
1247}
1248
1249static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
1250 struct ieee80211_sta *sta,
1251 bool set)
1252{
1253 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1254 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1255
1256 if (!mvm_sta || !mvm_sta->vif) {
1257 IWL_ERR(mvm, "Station is not associated to a vif\n");
1258 return -EINVAL;
1259 }
1260
1261 return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif);
1262}
1263
1264struct ieee80211_ops iwl_mvm_hw_ops = {
1265 .tx = iwl_mvm_mac_tx,
1266 .ampdu_action = iwl_mvm_mac_ampdu_action,
1267 .start = iwl_mvm_mac_start,
1268 .restart_complete = iwl_mvm_mac_restart_complete,
1269 .stop = iwl_mvm_mac_stop,
1270 .add_interface = iwl_mvm_mac_add_interface,
1271 .remove_interface = iwl_mvm_mac_remove_interface,
1272 .config = iwl_mvm_mac_config,
1273 .configure_filter = iwl_mvm_configure_filter,
1274 .bss_info_changed = iwl_mvm_bss_info_changed,
1275 .hw_scan = iwl_mvm_mac_hw_scan,
1276 .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan,
1277 .sta_state = iwl_mvm_mac_sta_state,
1278 .sta_notify = iwl_mvm_mac_sta_notify,
1279 .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
1280 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
1281 .conf_tx = iwl_mvm_mac_conf_tx,
1282 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
1283 .set_key = iwl_mvm_mac_set_key,
1284 .update_tkip_key = iwl_mvm_mac_update_tkip_key,
1285 .remain_on_channel = iwl_mvm_roc,
1286 .cancel_remain_on_channel = iwl_mvm_cancel_roc,
1287
1288 .add_chanctx = iwl_mvm_add_chanctx,
1289 .remove_chanctx = iwl_mvm_remove_chanctx,
1290 .change_chanctx = iwl_mvm_change_chanctx,
1291 .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
1292 .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
1293
1294 .start_ap = iwl_mvm_start_ap,
1295 .stop_ap = iwl_mvm_stop_ap,
1296
1297 .set_tim = iwl_mvm_set_tim,
1298
1299#ifdef CONFIG_PM_SLEEP
1300 /* look at d3.c */
1301 .suspend = iwl_mvm_suspend,
1302 .resume = iwl_mvm_resume,
1303 .set_wakeup = iwl_mvm_set_wakeup,
1304 .set_rekey_data = iwl_mvm_set_rekey_data,
1305#if IS_ENABLED(CONFIG_IPV6)
1306 .ipv6_addr_change = iwl_mvm_ipv6_addr_change,
1307#endif
1308 .set_default_unicast_key = iwl_mvm_set_default_unicast_key,
1309#endif
1310};
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
new file mode 100644
index 000000000000..4e339ccfa800
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -0,0 +1,500 @@
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 LICENSE.GPL.
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#ifndef __IWL_MVM_H__
65#define __IWL_MVM_H__
66
67#include <linux/list.h>
68#include <linux/spinlock.h>
69#include <linux/leds.h>
70#include <linux/in6.h>
71
72#include "iwl-op-mode.h"
73#include "iwl-trans.h"
74#include "iwl-notif-wait.h"
75#include "iwl-eeprom-parse.h"
76#include "iwl-test.h"
77#include "iwl-trans.h"
78#include "sta.h"
79#include "fw-api.h"
80
81#define IWL_INVALID_MAC80211_QUEUE 0xff
82#define IWL_MVM_MAX_ADDRESSES 2
83#define IWL_RSSI_OFFSET 44
84
85enum iwl_mvm_tx_fifo {
86 IWL_MVM_TX_FIFO_BK = 0,
87 IWL_MVM_TX_FIFO_BE,
88 IWL_MVM_TX_FIFO_VI,
89 IWL_MVM_TX_FIFO_VO,
90};
91
92/* Placeholder */
93#define IWL_OFFCHANNEL_QUEUE 8
94#define IWL_FIRST_AMPDU_QUEUE 11
95
96extern struct ieee80211_ops iwl_mvm_hw_ops;
97/**
98 * struct iwl_mvm_mod_params - module parameters for iwlmvm
99 * @init_dbg: if true, then the NIC won't be stopped if the INIT fw asserted.
100 * We will register to mac80211 to have testmode working. The NIC must not
101 * be up'ed after the INIT fw asserted. This is useful to be able to use
102 * proprietary tools over testmode to debug the INIT fw.
103 * @power_scheme: CAM(Continuous Active Mode)-1, BPS(Balanced Power
104 * Save)-2(default), LP(Low Power)-3
105 */
106struct iwl_mvm_mod_params {
107 bool init_dbg;
108 int power_scheme;
109};
110extern struct iwl_mvm_mod_params iwlmvm_mod_params;
111
112struct iwl_mvm_phy_ctxt {
113 u16 id;
114 u16 color;
115
116 /*
117 * TODO: This should probably be removed. Currently here only for rate
118 * scaling algorithm
119 */
120 struct ieee80211_channel *channel;
121};
122
123struct iwl_mvm_time_event_data {
124 struct ieee80211_vif *vif;
125 struct list_head list;
126 unsigned long end_jiffies;
127 u32 duration;
128 bool running;
129 u32 uid;
130
131 /*
132 * The access to the 'id' field must be done when the
133 * mvm->time_event_lock is held, as it value is used to indicate
134 * if the te is in the time event list or not (when id == TE_MAX)
135 */
136 u32 id;
137};
138
139 /* Power management */
140
141/**
142 * enum iwl_power_scheme
143 * @IWL_POWER_LEVEL_CAM - Continuously Active Mode
144 * @IWL_POWER_LEVEL_BPS - Balanced Power Save (default)
145 * @IWL_POWER_LEVEL_LP - Low Power
146 */
147enum iwl_power_scheme {
148 IWL_POWER_SCHEME_CAM = 1,
149 IWL_POWER_SCHEME_BPS,
150 IWL_POWER_SCHEME_LP
151};
152
153#define IWL_CONN_MAX_LISTEN_INTERVAL 70
154
155/**
156 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context
157 * @id: between 0 and 3
158 * @color: to solve races upon MAC addition and removal
159 * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA
160 * @uploaded: indicates the MAC context has been added to the device
161 * @ap_active: indicates that ap context is configured, and that the interface
162 * should get quota etc.
163 * @queue_params: QoS params for this MAC
164 * @bcast_sta: station used for broadcast packets. Used by the following
165 * vifs: P2P_DEVICE, GO and AP.
166 * @beacon_skb: the skb used to hold the AP/GO beacon template
167 */
168struct iwl_mvm_vif {
169 u16 id;
170 u16 color;
171 u8 ap_sta_id;
172
173 bool uploaded;
174 bool ap_active;
175
176 enum iwl_tsf_id tsf_id;
177
178 /*
179 * QoS data from mac80211, need to store this here
180 * as mac80211 has a separate callback but we need
181 * to have the data for the MAC context
182 */
183 struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
184 struct iwl_mvm_time_event_data time_event_data;
185
186 struct iwl_mvm_int_sta bcast_sta;
187
188 /*
189 * Assigned while mac80211 has the interface in a channel context,
190 * or, for P2P Device, while it exists.
191 */
192 struct iwl_mvm_phy_ctxt *phy_ctxt;
193
194#ifdef CONFIG_PM_SLEEP
195 /* WoWLAN GTK rekey data */
196 struct {
197 u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN];
198 __le64 replay_ctr;
199 bool valid;
200 } rekey_data;
201
202 int tx_key_idx;
203
204#if IS_ENABLED(CONFIG_IPV6)
205 /* IPv6 addresses for WoWLAN */
206 struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS];
207 int num_target_ipv6_addrs;
208#endif
209#endif
210
211#ifdef CONFIG_IWLWIFI_DEBUGFS
212 struct dentry *dbgfs_dir;
213 void *dbgfs_data;
214#endif
215};
216
217static inline struct iwl_mvm_vif *
218iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
219{
220 return (void *)vif->drv_priv;
221}
222
223enum iwl_mvm_status {
224 IWL_MVM_STATUS_HW_RFKILL,
225 IWL_MVM_STATUS_ROC_RUNNING,
226 IWL_MVM_STATUS_IN_HW_RESTART,
227};
228
229enum iwl_scan_status {
230 IWL_MVM_SCAN_NONE,
231 IWL_MVM_SCAN_OS,
232};
233
234/**
235 * struct iwl_nvm_section - describes an NVM section in memory.
236 *
237 * This struct holds an NVM section read from the NIC using NVM_ACCESS_CMD,
238 * and saved for later use by the driver. Not all NVM sections are saved
239 * this way, only the needed ones.
240 */
241struct iwl_nvm_section {
242 u16 length;
243 const u8 *data;
244};
245
246struct iwl_mvm {
247 /* for logger access */
248 struct device *dev;
249
250 struct iwl_trans *trans;
251 const struct iwl_fw *fw;
252 const struct iwl_cfg *cfg;
253 struct iwl_phy_db *phy_db;
254 struct ieee80211_hw *hw;
255
256 /* for protecting access to iwl_mvm */
257 struct mutex mutex;
258 struct list_head async_handlers_list;
259 spinlock_t async_handlers_lock;
260 struct work_struct async_handlers_wk;
261
262 struct work_struct roc_done_wk;
263
264 unsigned long status;
265
266 enum iwl_ucode_type cur_ucode;
267 bool ucode_loaded;
268 bool init_ucode_run;
269 u32 error_event_table;
270 u32 log_event_table;
271
272 u32 ampdu_ref;
273
274 struct iwl_notif_wait_data notif_wait;
275
276 unsigned long transport_queue_stop;
277 u8 queue_to_mac80211[IWL_MAX_HW_QUEUES];
278 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES];
279
280 struct iwl_nvm_data *nvm_data;
281 /* eeprom blob for debugfs/testmode */
282 u8 *eeprom_blob;
283 size_t eeprom_blob_size;
284 /* NVM sections for 7000 family */
285 struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS];
286
287 /* EEPROM MAC addresses */
288 struct mac_address addresses[IWL_MVM_MAX_ADDRESSES];
289
290 /* data related to data path */
291 struct iwl_rx_phy_info last_phy_info;
292 struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT];
293 struct work_struct sta_drained_wk;
294 unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
295
296 /* configured by mac80211 */
297 u32 rts_threshold;
298
299 /* Scan status, cmd (pre-allocated) and auxiliary station */
300 enum iwl_scan_status scan_status;
301 struct iwl_scan_cmd *scan_cmd;
302
303 /* Internal station */
304 struct iwl_mvm_int_sta aux_sta;
305
306 u8 scan_last_antenna_idx; /* to toggle TX between antennas */
307 u8 mgmt_last_antenna_idx;
308
309#ifdef CONFIG_IWLWIFI_DEBUGFS
310 struct dentry *debugfs_dir;
311 u32 dbgfs_sram_offset, dbgfs_sram_len;
312 bool prevent_power_down_d3;
313#endif
314
315 struct iwl_mvm_phy_ctxt phy_ctxt_roc;
316
317 struct list_head time_event_list;
318 spinlock_t time_event_lock;
319
320 /*
321 * A bitmap indicating the index of the key in use. The firmware
322 * can hold 16 keys at most. Reflect this fact.
323 */
324 unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)];
325 u8 vif_count;
326
327 struct led_classdev led;
328
329 struct ieee80211_vif *p2p_device_vif;
330};
331
332/* Extract MVM priv from op_mode and _hw */
333#define IWL_OP_MODE_GET_MVM(_iwl_op_mode) \
334 ((struct iwl_mvm *)(_iwl_op_mode)->op_mode_specific)
335
336#define IWL_MAC80211_GET_MVM(_hw) \
337 IWL_OP_MODE_GET_MVM((struct iwl_op_mode *)((_hw)->priv))
338
339extern const u8 iwl_mvm_ac_to_tx_fifo[];
340
341struct iwl_rate_info {
342 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
343 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
344 u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
345 u8 plcp_mimo3; /* uCode API: IWL_RATE_MIMO3_6M_PLCP, etc. */
346 u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
347};
348
349/******************
350 * MVM Methods
351 ******************/
352/* uCode */
353int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm);
354
355/* Utils */
356int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
357 enum ieee80211_band band);
358u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
359void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm);
360u8 first_antenna(u8 mask);
361u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx);
362
363/* Tx / Host Commands */
364int __must_check iwl_mvm_send_cmd(struct iwl_mvm *mvm,
365 struct iwl_host_cmd *cmd);
366int __must_check iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u8 id,
367 u32 flags, u16 len, const void *data);
368int __must_check iwl_mvm_send_cmd_status(struct iwl_mvm *mvm,
369 struct iwl_host_cmd *cmd,
370 u32 *status);
371int __must_check iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u8 id,
372 u16 len, const void *data,
373 u32 *status);
374int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
375 struct ieee80211_sta *sta);
376int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb);
377#ifdef CONFIG_IWLWIFI_DEBUG
378const char *iwl_mvm_get_tx_fail_reason(u32 status);
379#else
380static inline const char *iwl_mvm_get_tx_fail_reason(u32 status) { return ""; }
381#endif
382int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, bool sync);
383void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm);
384
385/* Statistics */
386int iwl_mvm_rx_reply_statistics(struct iwl_mvm *mvm,
387 struct iwl_rx_cmd_buffer *rxb,
388 struct iwl_device_cmd *cmd);
389int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
390 struct iwl_rx_cmd_buffer *rxb,
391 struct iwl_device_cmd *cmd);
392
393/* NVM */
394int iwl_nvm_init(struct iwl_mvm *mvm);
395
396int iwl_mvm_up(struct iwl_mvm *mvm);
397int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm);
398
399int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm);
400
401/*
402 * FW notifications / CMD responses handlers
403 * Convention: iwl_mvm_rx_<NAME OF THE CMD>
404 */
405int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
406 struct iwl_device_cmd *cmd);
407int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
408 struct iwl_device_cmd *cmd);
409int iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
410 struct iwl_device_cmd *cmd);
411int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
412 struct iwl_device_cmd *cmd);
413int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
414 struct iwl_device_cmd *cmd);
415int iwl_mvm_rx_fw_error(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
416 struct iwl_device_cmd *cmd);
417int iwl_mvm_rx_card_state_notif(struct iwl_mvm *mvm,
418 struct iwl_rx_cmd_buffer *rxb,
419 struct iwl_device_cmd *cmd);
420int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
421 struct iwl_device_cmd *cmd);
422
423/* MVM PHY */
424int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
425 struct cfg80211_chan_def *chandef,
426 u8 chains_static, u8 chains_dynamic);
427int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
428 struct cfg80211_chan_def *chandef,
429 u8 chains_static, u8 chains_dynamic);
430void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm,
431 struct iwl_mvm_phy_ctxt *ctxt);
432
433/* MAC (virtual interface) programming */
434int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
435void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
436int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
437int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
438int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
439u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
440 struct ieee80211_vif *vif);
441int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
442 struct ieee80211_vif *vif);
443
444/* Bindings */
445int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
446int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
447
448/* Quota management */
449int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif);
450
451/* Scanning */
452int iwl_mvm_scan_request(struct iwl_mvm *mvm,
453 struct ieee80211_vif *vif,
454 struct cfg80211_scan_request *req);
455int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
456 struct iwl_device_cmd *cmd);
457int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
458 struct iwl_device_cmd *cmd);
459void iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
460
461/* MVM debugfs */
462#ifdef CONFIG_IWLWIFI_DEBUGFS
463int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir);
464int iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
465 struct dentry *dbgfs_dir);
466void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
467 struct iwl_powertable_cmd *cmd);
468#else
469static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm,
470 struct dentry *dbgfs_dir)
471{
472 return 0;
473}
474#endif /* CONFIG_IWLWIFI_DEBUGFS */
475
476/* rate scaling */
477int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
478 u8 flags, bool init);
479
480/* power managment */
481int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
482int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
483
484int iwl_mvm_leds_init(struct iwl_mvm *mvm);
485void iwl_mvm_leds_exit(struct iwl_mvm *mvm);
486
487/* D3 (WoWLAN, NetDetect) */
488int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
489int iwl_mvm_resume(struct ieee80211_hw *hw);
490void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled);
491void iwl_mvm_set_rekey_data(struct ieee80211_hw *hw,
492 struct ieee80211_vif *vif,
493 struct cfg80211_gtk_rekey_data *data);
494void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
495 struct ieee80211_vif *vif,
496 struct inet6_dev *idev);
497void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
498 struct ieee80211_vif *vif, int idx);
499
500#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
new file mode 100644
index 000000000000..20016bcbdeab
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -0,0 +1,311 @@
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 LICENSE.GPL.
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#include "iwl-trans.h"
64#include "mvm.h"
65#include "iwl-eeprom-parse.h"
66#include "iwl-eeprom-read.h"
67#include "iwl-nvm-parse.h"
68
69/* list of NVM sections we are allowed/need to read */
70static const int nvm_to_read[] = {
71 NVM_SECTION_TYPE_HW,
72 NVM_SECTION_TYPE_SW,
73 NVM_SECTION_TYPE_CALIBRATION,
74 NVM_SECTION_TYPE_PRODUCTION,
75};
76
77/* used to simplify the shared operations on NCM_ACCESS_CMD versions */
78union iwl_nvm_access_cmd {
79 struct iwl_nvm_access_cmd_ver1 ver1;
80 struct iwl_nvm_access_cmd_ver2 ver2;
81};
82union iwl_nvm_access_resp {
83 struct iwl_nvm_access_resp_ver1 ver1;
84 struct iwl_nvm_access_resp_ver2 ver2;
85};
86
87static inline void iwl_nvm_fill_read_ver1(struct iwl_nvm_access_cmd_ver1 *cmd,
88 u16 offset, u16 length)
89{
90 cmd->offset = cpu_to_le16(offset);
91 cmd->length = cpu_to_le16(length);
92 cmd->cache_refresh = 1;
93}
94
95static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd,
96 u16 offset, u16 length, u16 section)
97{
98 cmd->offset = cpu_to_le16(offset);
99 cmd->length = cpu_to_le16(length);
100 cmd->type = cpu_to_le16(section);
101}
102
103static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
104 u16 offset, u16 length, u8 *data)
105{
106 union iwl_nvm_access_cmd nvm_access_cmd;
107 union iwl_nvm_access_resp *nvm_resp;
108 struct iwl_rx_packet *pkt;
109 struct iwl_host_cmd cmd = {
110 .id = NVM_ACCESS_CMD,
111 .flags = CMD_SYNC | CMD_WANT_SKB,
112 .data = { &nvm_access_cmd, },
113 };
114 int ret, bytes_read, offset_read;
115 u8 *resp_data;
116
117 memset(&nvm_access_cmd, 0, sizeof(nvm_access_cmd));
118
119 /* TODO: not sure family should be the decider, maybe FW version? */
120 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
121 iwl_nvm_fill_read_ver2(&(nvm_access_cmd.ver2),
122 offset, length, section);
123 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver2);
124 } else {
125 iwl_nvm_fill_read_ver1(&(nvm_access_cmd.ver1),
126 offset, length);
127 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver1);
128 }
129
130 ret = iwl_mvm_send_cmd(mvm, &cmd);
131 if (ret)
132 return ret;
133
134 pkt = cmd.resp_pkt;
135 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
136 IWL_ERR(mvm, "Bad return from NVM_ACCES_COMMAND (0x%08X)\n",
137 pkt->hdr.flags);
138 ret = -EIO;
139 goto exit;
140 }
141
142 /* Extract NVM response */
143 nvm_resp = (void *)pkt->data;
144 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
145 ret = le16_to_cpu(nvm_resp->ver2.status);
146 bytes_read = le16_to_cpu(nvm_resp->ver2.length);
147 offset_read = le16_to_cpu(nvm_resp->ver2.offset);
148 resp_data = nvm_resp->ver2.data;
149 } else {
150 ret = le16_to_cpu(nvm_resp->ver1.length) <= 0;
151 bytes_read = le16_to_cpu(nvm_resp->ver1.length);
152 offset_read = le16_to_cpu(nvm_resp->ver1.offset);
153 resp_data = nvm_resp->ver1.data;
154 }
155 if (ret) {
156 IWL_ERR(mvm,
157 "NVM access command failed with status %d (device: %s)\n",
158 ret, mvm->cfg->name);
159 ret = -EINVAL;
160 goto exit;
161 }
162
163 if (offset_read != offset) {
164 IWL_ERR(mvm, "NVM ACCESS response with invalid offset %d\n",
165 offset_read);
166 ret = -EINVAL;
167 goto exit;
168 }
169
170 /* Write data to NVM */
171 memcpy(data + offset, resp_data, bytes_read);
172 ret = bytes_read;
173
174exit:
175 iwl_free_resp(&cmd);
176 return ret;
177}
178
179/*
180 * Reads an NVM section completely.
181 * NICs prior to 7000 family doesn't have a real NVM, but just read
182 * section 0 which is the EEPROM. Because the EEPROM reading is unlimited
183 * by uCode, we need to manually check in this case that we don't
184 * overflow and try to read more than the EEPROM size.
185 * For 7000 family NICs, we supply the maximal size we can read, and
186 * the uCode fills the response with as much data as we can,
187 * without overflowing, so no check is needed.
188 */
189static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
190 u8 *data)
191{
192 u16 length, offset = 0;
193 int ret;
194 bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000;
195
196 length = (iwlwifi_mod_params.amsdu_size_8K ? (8 * 1024) : (4 * 1024))
197 - sizeof(union iwl_nvm_access_cmd)
198 - sizeof(struct iwl_rx_packet);
199 /*
200 * if length is greater than EEPROM size, truncate it because uCode
201 * doesn't check it by itself, and exit the loop when reached.
202 */
203 if (old_eeprom && length > mvm->cfg->base_params->eeprom_size)
204 length = mvm->cfg->base_params->eeprom_size;
205 ret = length;
206
207 /* Read the NVM until exhausted (reading less than requested) */
208 while (ret == length) {
209 ret = iwl_nvm_read_chunk(mvm, section, offset, length, data);
210 if (ret < 0) {
211 IWL_ERR(mvm,
212 "Cannot read NVM from section %d offset %d, length %d\n",
213 section, offset, length);
214 return ret;
215 }
216 offset += ret;
217 if (old_eeprom && offset == mvm->cfg->base_params->eeprom_size)
218 break;
219 }
220
221 IWL_INFO(mvm, "NVM section %d read completed\n", section);
222 return offset;
223}
224
225static struct iwl_nvm_data *
226iwl_parse_nvm_sections(struct iwl_mvm *mvm)
227{
228 struct iwl_nvm_section *sections = mvm->nvm_sections;
229 const __le16 *hw, *sw, *calib;
230
231 /* Checking for required sections */
232 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
233 !mvm->nvm_sections[NVM_SECTION_TYPE_HW].data) {
234 IWL_ERR(mvm, "Can't parse empty NVM sections\n");
235 return NULL;
236 }
237
238 if (WARN_ON(!mvm->cfg))
239 return NULL;
240
241 hw = (const __le16 *)sections[NVM_SECTION_TYPE_HW].data;
242 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
243 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
244 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib);
245}
246
247int iwl_nvm_init(struct iwl_mvm *mvm)
248{
249 int ret, i, section;
250 u8 *nvm_buffer, *temp;
251
252 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
253 /* TODO: find correct NVM max size for a section */
254 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
255 GFP_KERNEL);
256 if (!nvm_buffer)
257 return -ENOMEM;
258 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
259 section = nvm_to_read[i];
260 /* we override the constness for initial read */
261 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
262 if (ret < 0)
263 break;
264 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
265 if (!temp) {
266 ret = -ENOMEM;
267 break;
268 }
269 mvm->nvm_sections[section].data = temp;
270 mvm->nvm_sections[section].length = ret;
271 }
272 kfree(nvm_buffer);
273 if (ret < 0)
274 return ret;
275 } else {
276 /* allocate eeprom */
277 mvm->eeprom_blob_size = mvm->cfg->base_params->eeprom_size;
278 IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM size = %zd\n",
279 mvm->eeprom_blob_size);
280 mvm->eeprom_blob = kzalloc(mvm->eeprom_blob_size, GFP_KERNEL);
281 if (!mvm->eeprom_blob)
282 return -ENOMEM;
283
284 ret = iwl_nvm_read_section(mvm, 0, mvm->eeprom_blob);
285 if (ret != mvm->eeprom_blob_size) {
286 IWL_ERR(mvm, "Read partial NVM %d/%zd\n",
287 ret, mvm->eeprom_blob_size);
288 kfree(mvm->eeprom_blob);
289 mvm->eeprom_blob = NULL;
290 return -EINVAL;
291 }
292 }
293
294 ret = 0;
295 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000)
296 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
297 else
298 mvm->nvm_data =
299 iwl_parse_eeprom_data(mvm->trans->dev,
300 mvm->cfg,
301 mvm->eeprom_blob,
302 mvm->eeprom_blob_size);
303
304 if (!mvm->nvm_data) {
305 kfree(mvm->eeprom_blob);
306 mvm->eeprom_blob = NULL;
307 ret = -ENOMEM;
308 }
309
310 return ret;
311}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
new file mode 100644
index 000000000000..983dca3f888a
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -0,0 +1,679 @@
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 LICENSE.GPL.
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#include <linux/module.h>
64#include <net/mac80211.h>
65
66#include "iwl-notif-wait.h"
67#include "iwl-trans.h"
68#include "iwl-op-mode.h"
69#include "iwl-fw.h"
70#include "iwl-debug.h"
71#include "iwl-drv.h"
72#include "iwl-modparams.h"
73#include "mvm.h"
74#include "iwl-phy-db.h"
75#include "iwl-eeprom-parse.h"
76#include "iwl-csr.h"
77#include "iwl-io.h"
78#include "iwl-prph.h"
79#include "rs.h"
80#include "fw-api-scan.h"
81#include "time-event.h"
82
83/*
84 * module name, copyright, version, etc.
85 */
86#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux"
87
88#define DRV_VERSION IWLWIFI_VERSION
89
90MODULE_DESCRIPTION(DRV_DESCRIPTION);
91MODULE_VERSION(DRV_VERSION);
92MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
93MODULE_LICENSE("GPL");
94
95static const struct iwl_op_mode_ops iwl_mvm_ops;
96
97struct iwl_mvm_mod_params iwlmvm_mod_params = {
98 .power_scheme = IWL_POWER_SCHEME_BPS,
99 /* rest of fields are 0 by default */
100};
101
102module_param_named(init_dbg, iwlmvm_mod_params.init_dbg, bool, S_IRUGO);
103MODULE_PARM_DESC(init_dbg,
104 "set to true to debug an ASSERT in INIT fw (default: false");
105module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO);
106MODULE_PARM_DESC(power_scheme,
107 "power management scheme: 1-active, 2-balanced, 3-low power, default: 2");
108
109/*
110 * module init and exit functions
111 */
112static int __init iwl_mvm_init(void)
113{
114 int ret;
115
116 ret = iwl_mvm_rate_control_register();
117 if (ret) {
118 pr_err("Unable to register rate control algorithm: %d\n", ret);
119 return ret;
120 }
121
122 ret = iwl_opmode_register("iwlmvm", &iwl_mvm_ops);
123
124 if (ret) {
125 pr_err("Unable to register MVM op_mode: %d\n", ret);
126 iwl_mvm_rate_control_unregister();
127 }
128
129 return ret;
130}
131module_init(iwl_mvm_init);
132
133static void __exit iwl_mvm_exit(void)
134{
135 iwl_opmode_deregister("iwlmvm");
136 iwl_mvm_rate_control_unregister();
137}
138module_exit(iwl_mvm_exit);
139
140static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
141{
142 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
143 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
144 u32 reg_val = 0;
145
146 /*
147 * We can't upload the correct value to the INIT image
148 * as we don't have nvm_data by that time.
149 *
150 * TODO: Figure out what we should do here
151 */
152 if (mvm->nvm_data) {
153 radio_cfg_type = mvm->nvm_data->radio_cfg_type;
154 radio_cfg_step = mvm->nvm_data->radio_cfg_step;
155 radio_cfg_dash = mvm->nvm_data->radio_cfg_dash;
156 } else {
157 radio_cfg_type = 0;
158 radio_cfg_step = 0;
159 radio_cfg_dash = 0;
160 }
161
162 /* SKU control */
163 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
164 CSR_HW_IF_CONFIG_REG_POS_MAC_STEP;
165 reg_val |= CSR_HW_REV_DASH(mvm->trans->hw_rev) <<
166 CSR_HW_IF_CONFIG_REG_POS_MAC_DASH;
167
168 /* radio configuration */
169 reg_val |= radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE;
170 reg_val |= radio_cfg_step << CSR_HW_IF_CONFIG_REG_POS_PHY_STEP;
171 reg_val |= radio_cfg_dash << CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;
172
173 WARN_ON((radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE) &
174 ~CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE);
175
176 /* silicon bits */
177 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
178 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_MAC_SI;
179
180 iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
181 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
182 CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP |
183 CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE |
184 CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP |
185 CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH |
186 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
187 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI,
188 reg_val);
189
190 IWL_DEBUG_INFO(mvm, "Radio type=0x%x-0x%x-0x%x\n", radio_cfg_type,
191 radio_cfg_step, radio_cfg_dash);
192
193 /*
194 * W/A : NIC is stuck in a reset state after Early PCIe power off
195 * (PCIe power is lost before PERST# is asserted), causing ME FW
196 * to lose ownership and not being able to obtain it back.
197 */
198 iwl_set_bits_mask_prph(mvm->trans, APMG_PS_CTRL_REG,
199 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
200 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
201}
202
203struct iwl_rx_handlers {
204 u8 cmd_id;
205 bool async;
206 int (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
207 struct iwl_device_cmd *cmd);
208};
209
210#define RX_HANDLER(_cmd_id, _fn, _async) \
211 { .cmd_id = _cmd_id , .fn = _fn , .async = _async }
212
213/*
214 * Handlers for fw notifications
215 * Convention: RX_HANDLER(CMD_NAME, iwl_mvm_rx_CMD_NAME
216 * This list should be in order of frequency for performance purposes.
217 *
218 * The handler can be SYNC - this means that it will be called in the Rx path
219 * which can't acquire mvm->mutex. If the handler needs to hold mvm->mutex (and
220 * only in this case!), it should be set as ASYNC. In that case, it will be
221 * called from a worker with mvm->mutex held.
222 */
223static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
224 RX_HANDLER(REPLY_RX_MPDU_CMD, iwl_mvm_rx_rx_mpdu, false),
225 RX_HANDLER(REPLY_RX_PHY_CMD, iwl_mvm_rx_rx_phy_cmd, false),
226 RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, false),
227 RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, false),
228 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false),
229
230 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
231 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
232
233 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
234 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
235
236 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
237};
238#undef RX_HANDLER
239#define CMD(x) [x] = #x
240
241static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
242 CMD(MVM_ALIVE),
243 CMD(REPLY_ERROR),
244 CMD(INIT_COMPLETE_NOTIF),
245 CMD(PHY_CONTEXT_CMD),
246 CMD(MGMT_MCAST_KEY),
247 CMD(TX_CMD),
248 CMD(TXPATH_FLUSH),
249 CMD(MAC_CONTEXT_CMD),
250 CMD(TIME_EVENT_CMD),
251 CMD(TIME_EVENT_NOTIFICATION),
252 CMD(BINDING_CONTEXT_CMD),
253 CMD(TIME_QUOTA_CMD),
254 CMD(RADIO_VERSION_NOTIFICATION),
255 CMD(SCAN_REQUEST_CMD),
256 CMD(SCAN_ABORT_CMD),
257 CMD(SCAN_START_NOTIFICATION),
258 CMD(SCAN_RESULTS_NOTIFICATION),
259 CMD(SCAN_COMPLETE_NOTIFICATION),
260 CMD(NVM_ACCESS_CMD),
261 CMD(PHY_CONFIGURATION_CMD),
262 CMD(CALIB_RES_NOTIF_PHY_DB),
263 CMD(SET_CALIB_DEFAULT_CMD),
264 CMD(CALIBRATION_COMPLETE_NOTIFICATION),
265 CMD(ADD_STA),
266 CMD(REMOVE_STA),
267 CMD(LQ_CMD),
268 CMD(SCAN_OFFLOAD_CONFIG_CMD),
269 CMD(SCAN_OFFLOAD_REQUEST_CMD),
270 CMD(SCAN_OFFLOAD_ABORT_CMD),
271 CMD(SCAN_OFFLOAD_COMPLETE),
272 CMD(SCAN_OFFLOAD_UPDATE_PROFILES_CMD),
273 CMD(POWER_TABLE_CMD),
274 CMD(WEP_KEY),
275 CMD(REPLY_RX_PHY_CMD),
276 CMD(REPLY_RX_MPDU_CMD),
277 CMD(BEACON_TEMPLATE_CMD),
278 CMD(STATISTICS_NOTIFICATION),
279 CMD(TX_ANT_CONFIGURATION_CMD),
280 CMD(D3_CONFIG_CMD),
281 CMD(PROT_OFFLOAD_CONFIG_CMD),
282 CMD(OFFLOADS_QUERY_CMD),
283 CMD(REMOTE_WAKE_CONFIG_CMD),
284 CMD(WOWLAN_PATTERNS),
285 CMD(WOWLAN_CONFIGURATION),
286 CMD(WOWLAN_TSC_RSC_PARAM),
287 CMD(WOWLAN_TKIP_PARAM),
288 CMD(WOWLAN_KEK_KCK_MATERIAL),
289 CMD(WOWLAN_GET_STATUSES),
290 CMD(WOWLAN_TX_POWER_PER_DB),
291 CMD(NET_DETECT_CONFIG_CMD),
292 CMD(NET_DETECT_PROFILES_QUERY_CMD),
293 CMD(NET_DETECT_PROFILES_CMD),
294 CMD(NET_DETECT_HOTSPOTS_CMD),
295 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
296};
297#undef CMD
298
299/* this forward declaration can avoid to export the function */
300static void iwl_mvm_async_handlers_wk(struct work_struct *wk);
301
302static struct iwl_op_mode *
303iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
304 const struct iwl_fw *fw, struct dentry *dbgfs_dir)
305{
306 struct ieee80211_hw *hw;
307 struct iwl_op_mode *op_mode;
308 struct iwl_mvm *mvm;
309 struct iwl_trans_config trans_cfg = {};
310 static const u8 no_reclaim_cmds[] = {
311 TX_CMD,
312 };
313 int err, scan_size;
314
315 switch (cfg->device_family) {
316 case IWL_DEVICE_FAMILY_6030:
317 case IWL_DEVICE_FAMILY_6005:
318 case IWL_DEVICE_FAMILY_7000:
319 break;
320 default:
321 IWL_ERR(trans, "Trying to load mvm on an unsupported device\n");
322 return NULL;
323 }
324
325 /********************************
326 * 1. Allocating and configuring HW data
327 ********************************/
328 hw = ieee80211_alloc_hw(sizeof(struct iwl_op_mode) +
329 sizeof(struct iwl_mvm),
330 &iwl_mvm_hw_ops);
331 if (!hw)
332 return NULL;
333
334 op_mode = hw->priv;
335 op_mode->ops = &iwl_mvm_ops;
336 op_mode->trans = trans;
337
338 mvm = IWL_OP_MODE_GET_MVM(op_mode);
339 mvm->dev = trans->dev;
340 mvm->trans = trans;
341 mvm->cfg = cfg;
342 mvm->fw = fw;
343 mvm->hw = hw;
344
345 mutex_init(&mvm->mutex);
346 spin_lock_init(&mvm->async_handlers_lock);
347 INIT_LIST_HEAD(&mvm->time_event_list);
348 INIT_LIST_HEAD(&mvm->async_handlers_list);
349 spin_lock_init(&mvm->time_event_lock);
350
351 INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk);
352 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk);
353 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk);
354
355 SET_IEEE80211_DEV(mvm->hw, mvm->trans->dev);
356
357 /*
358 * Populate the state variables that the transport layer needs
359 * to know about.
360 */
361 trans_cfg.op_mode = op_mode;
362 trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
363 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
364 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
365
366 /* TODO: this should really be a TLV */
367 if (cfg->device_family == IWL_DEVICE_FAMILY_7000)
368 trans_cfg.bc_table_dword = true;
369
370 if (!iwlwifi_mod_params.wd_disable)
371 trans_cfg.queue_watchdog_timeout = cfg->base_params->wd_timeout;
372 else
373 trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
374
375 trans_cfg.command_names = iwl_mvm_cmd_strings;
376
377 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
378 trans_cfg.cmd_fifo = IWL_MVM_CMD_FIFO;
379
380 snprintf(mvm->hw->wiphy->fw_version,
381 sizeof(mvm->hw->wiphy->fw_version),
382 "%s", fw->fw_version);
383
384 /* Configure transport layer */
385 iwl_trans_configure(mvm->trans, &trans_cfg);
386
387 trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
388 trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
389
390 /* set up notification wait support */
391 iwl_notification_wait_init(&mvm->notif_wait);
392
393 /* Init phy db */
394 mvm->phy_db = iwl_phy_db_init(trans);
395 if (!mvm->phy_db) {
396 IWL_ERR(mvm, "Cannot init phy_db\n");
397 goto out_free;
398 }
399
400 IWL_INFO(mvm, "Detected %s, REV=0x%X\n",
401 mvm->cfg->name, mvm->trans->hw_rev);
402
403 err = iwl_trans_start_hw(mvm->trans);
404 if (err)
405 goto out_free;
406
407 mutex_lock(&mvm->mutex);
408 err = iwl_run_init_mvm_ucode(mvm, true);
409 mutex_unlock(&mvm->mutex);
410 if (err && !iwlmvm_mod_params.init_dbg) {
411 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
412 goto out_free;
413 }
414
415 /* Stop the hw after the ALIVE and NVM has been read */
416 if (!iwlmvm_mod_params.init_dbg)
417 iwl_trans_stop_hw(mvm->trans, false);
418
419 scan_size = sizeof(struct iwl_scan_cmd) +
420 mvm->fw->ucode_capa.max_probe_length +
421 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel));
422 mvm->scan_cmd = kmalloc(scan_size, GFP_KERNEL);
423 if (!mvm->scan_cmd)
424 goto out_free;
425
426 err = iwl_mvm_mac_setup_register(mvm);
427 if (err)
428 goto out_free;
429
430 err = iwl_mvm_dbgfs_register(mvm, dbgfs_dir);
431 if (err)
432 goto out_unregister;
433
434 return op_mode;
435
436 out_unregister:
437 ieee80211_unregister_hw(mvm->hw);
438 out_free:
439 iwl_phy_db_free(mvm->phy_db);
440 kfree(mvm->scan_cmd);
441 kfree(mvm->eeprom_blob);
442 iwl_trans_stop_hw(trans, true);
443 ieee80211_free_hw(mvm->hw);
444 return NULL;
445}
446
447static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
448{
449 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
450 int i;
451
452 iwl_mvm_leds_exit(mvm);
453
454 ieee80211_unregister_hw(mvm->hw);
455
456 kfree(mvm->scan_cmd);
457
458 iwl_trans_stop_hw(mvm->trans, true);
459
460 iwl_phy_db_free(mvm->phy_db);
461 mvm->phy_db = NULL;
462
463 kfree(mvm->eeprom_blob);
464 iwl_free_nvm_data(mvm->nvm_data);
465 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++)
466 kfree(mvm->nvm_sections[i].data);
467
468 ieee80211_free_hw(mvm->hw);
469}
470
471struct iwl_async_handler_entry {
472 struct list_head list;
473 struct iwl_rx_cmd_buffer rxb;
474 int (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
475 struct iwl_device_cmd *cmd);
476};
477
478void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm)
479{
480 struct iwl_async_handler_entry *entry, *tmp;
481
482 spin_lock_bh(&mvm->async_handlers_lock);
483 list_for_each_entry_safe(entry, tmp, &mvm->async_handlers_list, list) {
484 iwl_free_rxb(&entry->rxb);
485 list_del(&entry->list);
486 kfree(entry);
487 }
488 spin_unlock_bh(&mvm->async_handlers_lock);
489}
490
491static void iwl_mvm_async_handlers_wk(struct work_struct *wk)
492{
493 struct iwl_mvm *mvm =
494 container_of(wk, struct iwl_mvm, async_handlers_wk);
495 struct iwl_async_handler_entry *entry, *tmp;
496 struct list_head local_list;
497
498 INIT_LIST_HEAD(&local_list);
499
500 /* Ensure that we are not in stop flow (check iwl_mvm_mac_stop) */
501 mutex_lock(&mvm->mutex);
502
503 /*
504 * Sync with Rx path with a lock. Remove all the entries from this list,
505 * add them to a local one (lock free), and then handle them.
506 */
507 spin_lock_bh(&mvm->async_handlers_lock);
508 list_splice_init(&mvm->async_handlers_list, &local_list);
509 spin_unlock_bh(&mvm->async_handlers_lock);
510
511 list_for_each_entry_safe(entry, tmp, &local_list, list) {
512 if (entry->fn(mvm, &entry->rxb, NULL))
513 IWL_WARN(mvm,
514 "returned value from ASYNC handlers are ignored\n");
515 iwl_free_rxb(&entry->rxb);
516 list_del(&entry->list);
517 kfree(entry);
518 }
519 mutex_unlock(&mvm->mutex);
520}
521
522static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
523 struct iwl_rx_cmd_buffer *rxb,
524 struct iwl_device_cmd *cmd)
525{
526 struct iwl_rx_packet *pkt = rxb_addr(rxb);
527 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
528 u8 i;
529
530 /*
531 * Do the notification wait before RX handlers so
532 * even if the RX handler consumes the RXB we have
533 * access to it in the notification wait entry.
534 */
535 iwl_notification_wait_notify(&mvm->notif_wait, pkt);
536
537 for (i = 0; i < ARRAY_SIZE(iwl_mvm_rx_handlers); i++) {
538 const struct iwl_rx_handlers *rx_h = &iwl_mvm_rx_handlers[i];
539 if (rx_h->cmd_id == pkt->hdr.cmd) {
540 struct iwl_async_handler_entry *entry;
541 if (!rx_h->async)
542 return rx_h->fn(mvm, rxb, cmd);
543
544 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
545 /* we can't do much... */
546 if (!entry)
547 return 0;
548
549 entry->rxb._page = rxb_steal_page(rxb);
550 entry->rxb._offset = rxb->_offset;
551 entry->rxb._rx_page_order = rxb->_rx_page_order;
552 entry->fn = rx_h->fn;
553 spin_lock(&mvm->async_handlers_lock);
554 list_add_tail(&entry->list, &mvm->async_handlers_list);
555 spin_unlock(&mvm->async_handlers_lock);
556 schedule_work(&mvm->async_handlers_wk);
557 }
558 }
559
560 return 0;
561}
562
563static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
564{
565 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
566 int mq = mvm->queue_to_mac80211[queue];
567
568 if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
569 return;
570
571 if (atomic_inc_return(&mvm->queue_stop_count[mq]) > 1) {
572 IWL_DEBUG_TX_QUEUES(mvm,
573 "queue %d (mac80211 %d) already stopped\n",
574 queue, mq);
575 return;
576 }
577
578 set_bit(mq, &mvm->transport_queue_stop);
579 ieee80211_stop_queue(mvm->hw, mq);
580}
581
582static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
583{
584 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
585 int mq = mvm->queue_to_mac80211[queue];
586
587 if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
588 return;
589
590 if (atomic_dec_return(&mvm->queue_stop_count[mq]) > 0) {
591 IWL_DEBUG_TX_QUEUES(mvm,
592 "queue %d (mac80211 %d) already awake\n",
593 queue, mq);
594 return;
595 }
596
597 clear_bit(mq, &mvm->transport_queue_stop);
598
599 ieee80211_wake_queue(mvm->hw, mq);
600}
601
602static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
603{
604 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
605
606 if (state)
607 set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
608 else
609 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
610
611 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, state);
612}
613
614static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
615{
616 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
617 struct ieee80211_tx_info *info;
618
619 info = IEEE80211_SKB_CB(skb);
620 iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]);
621 ieee80211_free_txskb(mvm->hw, skb);
622}
623
624static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
625{
626 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
627
628 iwl_mvm_dump_nic_error_log(mvm);
629
630 iwl_abort_notification_waits(&mvm->notif_wait);
631
632 /*
633 * If we're restarting already, don't cycle restarts.
634 * If INIT fw asserted, it will likely fail again.
635 * If WoWLAN fw asserted, don't restart either, mac80211
636 * can't recover this since we're already half suspended.
637 */
638 if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
639 IWL_ERR(mvm, "Firmware error during reconfiguration! Abort.\n");
640 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR &&
641 iwlwifi_mod_params.restart_fw) {
642 /*
643 * This is a bit racy, but worst case we tell mac80211 about
644 * a stopped/aborted (sched) scan when that was already done
645 * which is not a problem. It is necessary to abort any scan
646 * here because mac80211 requires having the scan cleared
647 * before restarting.
648 * We'll reset the scan_status to NONE in restart cleanup in
649 * the next start() call from mac80211.
650 */
651 switch (mvm->scan_status) {
652 case IWL_MVM_SCAN_NONE:
653 break;
654 case IWL_MVM_SCAN_OS:
655 ieee80211_scan_completed(mvm->hw, true);
656 break;
657 }
658
659 ieee80211_restart_hw(mvm->hw);
660 }
661}
662
663static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
664{
665 WARN_ON(1);
666}
667
668static const struct iwl_op_mode_ops iwl_mvm_ops = {
669 .start = iwl_op_mode_mvm_start,
670 .stop = iwl_op_mode_mvm_stop,
671 .rx = iwl_mvm_rx_dispatch,
672 .queue_full = iwl_mvm_stop_sw_queue,
673 .queue_not_full = iwl_mvm_wake_sw_queue,
674 .hw_rf_kill = iwl_mvm_set_hw_rfkill_state,
675 .free_skb = iwl_mvm_free_skb,
676 .nic_error = iwl_mvm_nic_error,
677 .cmd_queue_full = iwl_mvm_cmd_queue_full,
678 .nic_config = iwl_mvm_nic_config,
679};
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
new file mode 100644
index 000000000000..b428448f8ddf
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -0,0 +1,292 @@
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 LICENSE.GPL.
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 <net/mac80211.h>
65#include "fw-api.h"
66#include "mvm.h"
67
68/* Maps the driver specific channel width definition to the the fw values */
69static inline u8 iwl_mvm_get_channel_width(struct cfg80211_chan_def *chandef)
70{
71 switch (chandef->width) {
72 case NL80211_CHAN_WIDTH_20_NOHT:
73 case NL80211_CHAN_WIDTH_20:
74 return PHY_VHT_CHANNEL_MODE20;
75 case NL80211_CHAN_WIDTH_40:
76 return PHY_VHT_CHANNEL_MODE40;
77 case NL80211_CHAN_WIDTH_80:
78 return PHY_VHT_CHANNEL_MODE80;
79 case NL80211_CHAN_WIDTH_160:
80 return PHY_VHT_CHANNEL_MODE160;
81 default:
82 WARN(1, "Invalid channel width=%u", chandef->width);
83 return PHY_VHT_CHANNEL_MODE20;
84 }
85}
86
87/*
88 * Maps the driver specific control channel position (relative to the center
89 * freq) definitions to the the fw values
90 */
91static inline u8 iwl_mvm_get_ctrl_pos(struct cfg80211_chan_def *chandef)
92{
93 switch (chandef->chan->center_freq - chandef->center_freq1) {
94 case -70:
95 return PHY_VHT_CTRL_POS_4_BELOW;
96 case -50:
97 return PHY_VHT_CTRL_POS_3_BELOW;
98 case -30:
99 return PHY_VHT_CTRL_POS_2_BELOW;
100 case -10:
101 return PHY_VHT_CTRL_POS_1_BELOW;
102 case 10:
103 return PHY_VHT_CTRL_POS_1_ABOVE;
104 case 30:
105 return PHY_VHT_CTRL_POS_2_ABOVE;
106 case 50:
107 return PHY_VHT_CTRL_POS_3_ABOVE;
108 case 70:
109 return PHY_VHT_CTRL_POS_4_ABOVE;
110 default:
111 WARN(1, "Invalid channel definition");
112 case 0:
113 /*
114 * The FW is expected to check the control channel position only
115 * when in HT/VHT and the channel width is not 20MHz. Return
116 * this value as the default one.
117 */
118 return PHY_VHT_CTRL_POS_1_BELOW;
119 }
120}
121
122/*
123 * Construct the generic fields of the PHY context command
124 */
125static void iwl_mvm_phy_ctxt_cmd_hdr(struct iwl_mvm_phy_ctxt *ctxt,
126 struct iwl_phy_context_cmd *cmd,
127 u32 action, u32 apply_time)
128{
129 memset(cmd, 0, sizeof(struct iwl_phy_context_cmd));
130
131 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(ctxt->id,
132 ctxt->color));
133 cmd->action = cpu_to_le32(action);
134 cmd->apply_time = cpu_to_le32(apply_time);
135}
136
137/*
138 * Add the phy configuration to the PHY context command
139 */
140static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
141 struct iwl_phy_context_cmd *cmd,
142 struct cfg80211_chan_def *chandef,
143 u8 chains_static, u8 chains_dynamic)
144{
145 u8 valid_rx_chains, active_cnt, idle_cnt;
146
147 /* Set the channel info data */
148 cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ?
149 PHY_BAND_24 : PHY_BAND_5);
150
151 cmd->ci.channel = chandef->chan->hw_value;
152 cmd->ci.width = iwl_mvm_get_channel_width(chandef);
153 cmd->ci.ctrl_pos = iwl_mvm_get_ctrl_pos(chandef);
154
155 /* Set rx the chains */
156
157 /* TODO:
158 * Need to add on chain noise calibration limitations, and
159 * BT coex considerations.
160 */
161 valid_rx_chains = mvm->nvm_data->valid_rx_ant;
162 idle_cnt = chains_static;
163 active_cnt = chains_dynamic;
164
165 cmd->rxchain_info = cpu_to_le32(valid_rx_chains <<
166 PHY_RX_CHAIN_VALID_POS);
167 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
168 cmd->rxchain_info |= cpu_to_le32(active_cnt <<
169 PHY_RX_CHAIN_MIMO_CNT_POS);
170
171 cmd->txchain_info = cpu_to_le32(mvm->nvm_data->valid_tx_ant);
172}
173
174/*
175 * Send a command to apply the current phy configuration. The command is send
176 * only if something in the configuration changed: in case that this is the
177 * first time that the phy configuration is applied or in case that the phy
178 * configuration changed from the previous apply.
179 */
180static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
181 struct iwl_mvm_phy_ctxt *ctxt,
182 struct cfg80211_chan_def *chandef,
183 u8 chains_static, u8 chains_dynamic,
184 u32 action, u32 apply_time)
185{
186 struct iwl_phy_context_cmd cmd;
187 int ret;
188
189 /* Set the command header fields */
190 iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, action, apply_time);
191
192 /* Set the command data */
193 iwl_mvm_phy_ctxt_cmd_data(mvm, &cmd, chandef,
194 chains_static, chains_dynamic);
195
196 ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, CMD_SYNC,
197 sizeof(struct iwl_phy_context_cmd),
198 &cmd);
199 if (ret)
200 IWL_ERR(mvm, "PHY ctxt cmd error. ret=%d\n", ret);
201 return ret;
202}
203
204
205struct phy_ctx_used_data {
206 unsigned long used[BITS_TO_LONGS(NUM_PHY_CTX)];
207};
208
209static void iwl_mvm_phy_ctx_used_iter(struct ieee80211_hw *hw,
210 struct ieee80211_chanctx_conf *ctx,
211 void *_data)
212{
213 struct phy_ctx_used_data *data = _data;
214 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
215
216 __set_bit(phy_ctxt->id, data->used);
217}
218
219/*
220 * Send a command to add a PHY context based on the current HW configuration.
221 */
222int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
223 struct cfg80211_chan_def *chandef,
224 u8 chains_static, u8 chains_dynamic)
225{
226 struct phy_ctx_used_data data = {
227 .used = { },
228 };
229
230 /*
231 * If this is a regular PHY context (not the ROC one)
232 * skip the ROC PHY context's ID.
233 */
234 if (ctxt != &mvm->phy_ctxt_roc)
235 __set_bit(mvm->phy_ctxt_roc.id, data.used);
236
237 lockdep_assert_held(&mvm->mutex);
238 ctxt->color++;
239
240 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
241 ieee80211_iter_chan_contexts_atomic(
242 mvm->hw, iwl_mvm_phy_ctx_used_iter, &data);
243
244 ctxt->id = find_first_zero_bit(data.used, NUM_PHY_CTX);
245 if (WARN_ONCE(ctxt->id == NUM_PHY_CTX,
246 "Failed to init PHY context - no free ID!\n"))
247 return -EIO;
248 }
249
250 ctxt->channel = chandef->chan;
251 return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
252 chains_static, chains_dynamic,
253 FW_CTXT_ACTION_ADD, 0);
254}
255
256/*
257 * Send a command to modify the PHY context based on the current HW
258 * configuration. Note that the function does not check that the configuration
259 * changed.
260 */
261int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
262 struct cfg80211_chan_def *chandef,
263 u8 chains_static, u8 chains_dynamic)
264{
265 lockdep_assert_held(&mvm->mutex);
266
267 ctxt->channel = chandef->chan;
268 return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
269 chains_static, chains_dynamic,
270 FW_CTXT_ACTION_MODIFY, 0);
271}
272
273/*
274 * Send a command to the FW to remove the given phy context.
275 * Once the command is sent, regardless of success or failure, the context is
276 * marked as invalid
277 */
278void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
279{
280 struct iwl_phy_context_cmd cmd;
281 int ret;
282
283 lockdep_assert_held(&mvm->mutex);
284
285 iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, FW_CTXT_ACTION_REMOVE, 0);
286 ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, CMD_SYNC,
287 sizeof(struct iwl_phy_context_cmd),
288 &cmd);
289 if (ret)
290 IWL_ERR(mvm, "Failed to send PHY remove: ctxt id=%d\n",
291 ctxt->id);
292}
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
new file mode 100644
index 000000000000..63628739cf4a
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -0,0 +1,207 @@
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 LICENSE.GPL.
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_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
79 struct iwl_powertable_cmd *cmd)
80{
81 struct ieee80211_hw *hw = mvm->hw;
82 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
83 struct ieee80211_chanctx_conf *chanctx_conf;
84 struct ieee80211_channel *chan;
85 int dtimper, dtimper_msec;
86 int keep_alive;
87 bool radar_detect = false;
88
89 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
90 mvmvif->color));
91 cmd->action = cpu_to_le32(FW_CTXT_ACTION_MODIFY);
92
93 if ((!vif->bss_conf.ps) ||
94 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM))
95 return;
96
97 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
98
99 dtimper = hw->conf.ps_dtim_period ?: 1;
100
101 /* Check if radar detection is required on current channel */
102 rcu_read_lock();
103 chanctx_conf = rcu_dereference(vif->chanctx_conf);
104 WARN_ON(!chanctx_conf);
105 if (chanctx_conf) {
106 chan = chanctx_conf->def.chan;
107 radar_detect = chan->flags & IEEE80211_CHAN_RADAR;
108 }
109 rcu_read_unlock();
110
111 /* Check skip over DTIM conditions */
112 if (!radar_detect && (dtimper <= 10) &&
113 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) {
114 cmd->flags |= cpu_to_le16(POWER_FLAGS_SLEEP_OVER_DTIM_MSK);
115 cmd->num_skip_dtim = 2;
116 }
117
118 /* Check that keep alive period is at least 3 * DTIM */
119 dtimper_msec = dtimper * vif->bss_conf.beacon_int;
120 keep_alive = max_t(int, 3 * dtimper_msec,
121 MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC);
122 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
123
124 cmd->keep_alive_seconds = cpu_to_le16(keep_alive);
125
126 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) {
127 /* TODO: Also for D3 (device sleep / WoWLAN) */
128 cmd->rx_data_timeout = cpu_to_le32(10);
129 cmd->tx_data_timeout = cpu_to_le32(10);
130 } else {
131 cmd->rx_data_timeout = cpu_to_le32(50);
132 cmd->tx_data_timeout = cpu_to_le32(50);
133 }
134}
135
136int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
137{
138 struct iwl_powertable_cmd cmd = {};
139
140 if (!iwlwifi_mod_params.power_save) {
141 IWL_DEBUG_POWER(mvm, "Power management is not allowed\n");
142 return 0;
143 }
144
145 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
146 return 0;
147
148 iwl_power_build_cmd(mvm, vif, &cmd);
149
150 IWL_DEBUG_POWER(mvm,
151 "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
152 cmd.id_and_color, iwlmvm_mod_params.power_scheme,
153 le16_to_cpu(cmd.flags));
154
155 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
156 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n",
157 le16_to_cpu(cmd.keep_alive_seconds));
158 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n",
159 le32_to_cpu(cmd.rx_data_timeout));
160 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
161 le32_to_cpu(cmd.tx_data_timeout));
162 IWL_DEBUG_POWER(mvm, "Rx timeout (uAPSD) = %u usec\n",
163 le32_to_cpu(cmd.rx_data_timeout_uapsd));
164 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
165 le32_to_cpu(cmd.tx_data_timeout_uapsd));
166 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
167 cmd.lprx_rssi_threshold);
168 IWL_DEBUG_POWER(mvm, "DTIMs to skip = %u\n", cmd.num_skip_dtim);
169 }
170
171 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
172 sizeof(cmd), &cmd);
173}
174
175int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
176{
177 struct iwl_powertable_cmd cmd = {};
178 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
179
180 if (!iwlwifi_mod_params.power_save) {
181 IWL_DEBUG_POWER(mvm, "Power management is not allowed\n");
182 return 0;
183 }
184
185 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
186 return 0;
187
188 cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
189 mvmvif->color));
190 cmd.action = cpu_to_le32(FW_CTXT_ACTION_MODIFY);
191
192 IWL_DEBUG_POWER(mvm,
193 "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
194 cmd.id_and_color, iwlmvm_mod_params.power_scheme,
195 le16_to_cpu(cmd.flags));
196
197 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
198 sizeof(cmd), &cmd);
199}
200
201#ifdef CONFIG_IWLWIFI_DEBUGFS
202void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
203 struct iwl_powertable_cmd *cmd)
204{
205 iwl_power_build_cmd(mvm, vif, cmd);
206}
207#endif /* CONFIG_IWLWIFI_DEBUGFS */
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
new file mode 100644
index 000000000000..2d4611a563c5
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -0,0 +1,178 @@
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 LICENSE.GPL.
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 <net/mac80211.h>
65#include "fw-api.h"
66#include "mvm.h"
67
68struct iwl_mvm_quota_iterator_data {
69 int n_interfaces[MAX_BINDINGS];
70 int colors[MAX_BINDINGS];
71 struct ieee80211_vif *new_vif;
72};
73
74static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
75 struct ieee80211_vif *vif)
76{
77 struct iwl_mvm_quota_iterator_data *data = _data;
78 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
79 u16 id;
80
81 /*
82 * We'll account for the new interface (if any) below,
83 * skip it here in case we're not called from within
84 * the add_interface callback (otherwise it won't show
85 * up in iteration)
86 */
87 if (vif == data->new_vif)
88 return;
89
90 if (!mvmvif->phy_ctxt)
91 return;
92
93 /* currently, PHY ID == binding ID */
94 id = mvmvif->phy_ctxt->id;
95
96 /* need at least one binding per PHY */
97 BUILD_BUG_ON(NUM_PHY_CTX > MAX_BINDINGS);
98
99 if (WARN_ON_ONCE(id >= MAX_BINDINGS))
100 return;
101
102 if (data->colors[id] < 0)
103 data->colors[id] = mvmvif->phy_ctxt->color;
104 else
105 WARN_ON_ONCE(data->colors[id] != mvmvif->phy_ctxt->color);
106
107 switch (vif->type) {
108 case NL80211_IFTYPE_STATION:
109 if (vif->bss_conf.assoc)
110 data->n_interfaces[id]++;
111 break;
112 case NL80211_IFTYPE_AP:
113 if (mvmvif->ap_active)
114 data->n_interfaces[id]++;
115 break;
116 case NL80211_IFTYPE_MONITOR:
117 data->n_interfaces[id]++;
118 break;
119 case NL80211_IFTYPE_P2P_DEVICE:
120 break;
121 case NL80211_IFTYPE_ADHOC:
122 if (vif->bss_conf.ibss_joined)
123 data->n_interfaces[id]++;
124 break;
125 default:
126 WARN_ON_ONCE(1);
127 break;
128 }
129}
130
131int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
132{
133 struct iwl_time_quota_cmd cmd;
134 int i, idx, ret;
135 struct iwl_mvm_quota_iterator_data data = {
136 .n_interfaces = {},
137 .colors = { -1, -1, -1, -1 },
138 .new_vif = newvif,
139 };
140
141 /* update all upon completion */
142 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
143 return 0;
144
145 BUILD_BUG_ON(data.colors[MAX_BINDINGS - 1] != -1);
146
147 lockdep_assert_held(&mvm->mutex);
148
149 memset(&cmd, 0, sizeof(cmd));
150
151 ieee80211_iterate_active_interfaces_atomic(
152 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
153 iwl_mvm_quota_iterator, &data);
154 if (newvif) {
155 data.new_vif = NULL;
156 iwl_mvm_quota_iterator(&data, newvif->addr, newvif);
157 }
158
159 for (idx = 0, i = 0; i < MAX_BINDINGS; i++) {
160 if (data.n_interfaces[i] <= 0)
161 continue;
162
163 cmd.quotas[idx].id_and_color =
164 cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i]));
165 cmd.quotas[idx].quota = cpu_to_le32(100);
166 cmd.quotas[idx].max_duration = cpu_to_le32(1000);
167 idx++;
168 }
169
170 for (i = idx; i < MAX_BINDINGS; i++)
171 cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
172
173 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC,
174 sizeof(cmd), &cmd);
175 if (ret)
176 IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
177 return ret;
178}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
new file mode 100644
index 000000000000..60a4291ca221
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -0,0 +1,3096 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/skbuff.h>
29#include <linux/slab.h>
30#include <net/mac80211.h>
31
32#include <linux/netdevice.h>
33#include <linux/etherdevice.h>
34#include <linux/delay.h>
35
36#include <linux/workqueue.h>
37#include "rs.h"
38#include "fw-api.h"
39#include "sta.h"
40#include "iwl-op-mode.h"
41#include "mvm.h"
42
43#define RS_NAME "iwl-mvm-rs"
44
45#define NUM_TRY_BEFORE_ANT_TOGGLE 1
46#define IWL_NUMBER_TRY 1
47#define IWL_HT_NUMBER_TRY 3
48
49#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */
50#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */
51#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
52
53/* max allowed rate miss before sync LQ cmd */
54#define IWL_MISSED_RATE_MAX 15
55/* max time to accum history 2 seconds */
56#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ)
57
58static u8 rs_ht_to_legacy[] = {
59 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
60 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
61 IWL_RATE_6M_INDEX,
62 IWL_RATE_6M_INDEX, IWL_RATE_9M_INDEX,
63 IWL_RATE_12M_INDEX, IWL_RATE_18M_INDEX,
64 IWL_RATE_24M_INDEX, IWL_RATE_36M_INDEX,
65 IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX
66};
67
68static const u8 ant_toggle_lookup[] = {
69 /*ANT_NONE -> */ ANT_NONE,
70 /*ANT_A -> */ ANT_B,
71 /*ANT_B -> */ ANT_C,
72 /*ANT_AB -> */ ANT_BC,
73 /*ANT_C -> */ ANT_A,
74 /*ANT_AC -> */ ANT_AB,
75 /*ANT_BC -> */ ANT_AC,
76 /*ANT_ABC -> */ ANT_ABC,
77};
78
79#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
80 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
81 IWL_RATE_SISO_##s##M_PLCP, \
82 IWL_RATE_MIMO2_##s##M_PLCP,\
83 IWL_RATE_MIMO3_##s##M_PLCP,\
84 IWL_RATE_##r##M_IEEE, \
85 IWL_RATE_##ip##M_INDEX, \
86 IWL_RATE_##in##M_INDEX, \
87 IWL_RATE_##rp##M_INDEX, \
88 IWL_RATE_##rn##M_INDEX, \
89 IWL_RATE_##pp##M_INDEX, \
90 IWL_RATE_##np##M_INDEX }
91
92/*
93 * Parameter order:
94 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
95 *
96 * If there isn't a valid next or previous rate then INV is used which
97 * maps to IWL_RATE_INVALID
98 *
99 */
100static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = {
101 IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */
102 IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */
103 IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */
104 IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */
105 IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */
106 IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */
107 IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */
108 IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */
109 IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */
110 IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */
111 IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */
112 IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
113 IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
114 /* FIXME:RS: ^^ should be INV (legacy) */
115};
116
117static inline u8 rs_extract_rate(u32 rate_n_flags)
118{
119 /* also works for HT because bits 7:6 are zero there */
120 return (u8)(rate_n_flags & RATE_LEGACY_RATE_MSK);
121}
122
123static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
124{
125 int idx = 0;
126
127 /* HT rate format */
128 if (rate_n_flags & RATE_MCS_HT_MSK) {
129 idx = rs_extract_rate(rate_n_flags);
130
131 if (idx >= IWL_RATE_MIMO3_6M_PLCP)
132 idx = idx - IWL_RATE_MIMO3_6M_PLCP;
133 else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
134 idx = idx - IWL_RATE_MIMO2_6M_PLCP;
135
136 idx += IWL_FIRST_OFDM_RATE;
137 /* skip 9M not supported in ht*/
138 if (idx >= IWL_RATE_9M_INDEX)
139 idx += 1;
140 if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
141 return idx;
142
143 /* legacy rate format, search for match in table */
144 } else {
145 for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
146 if (iwl_rates[idx].plcp ==
147 rs_extract_rate(rate_n_flags))
148 return idx;
149 }
150
151 return -1;
152}
153
154static void rs_rate_scale_perform(struct iwl_mvm *mvm,
155 struct sk_buff *skb,
156 struct ieee80211_sta *sta,
157 struct iwl_lq_sta *lq_sta);
158static void rs_fill_link_cmd(struct iwl_mvm *mvm,
159 struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
160static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
161
162
163#ifdef CONFIG_MAC80211_DEBUGFS
164static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
165 u32 *rate_n_flags, int index);
166#else
167static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
168 u32 *rate_n_flags, int index)
169{}
170#endif
171
172/**
173 * The following tables contain the expected throughput metrics for all rates
174 *
175 * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
176 *
177 * where invalid entries are zeros.
178 *
179 * CCK rates are only valid in legacy table and will only be used in G
180 * (2.4 GHz) band.
181 */
182
183static s32 expected_tpt_legacy[IWL_RATE_COUNT] = {
184 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0
185};
186
187static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = {
188 {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202}, /* Norm */
189 {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210}, /* SGI */
190 {0, 0, 0, 0, 47, 0, 91, 133, 171, 242, 305, 334, 362}, /* AGG */
191 {0, 0, 0, 0, 52, 0, 101, 145, 187, 264, 330, 361, 390}, /* AGG+SGI */
192};
193
194static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = {
195 {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */
196 {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */
197 {0, 0, 0, 0, 94, 0, 177, 249, 313, 423, 512, 550, 586}, /* AGG */
198 {0, 0, 0, 0, 104, 0, 193, 270, 338, 454, 545, 584, 620}, /* AGG+SGI */
199};
200
201static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = {
202 {0, 0, 0, 0, 74, 0, 123, 155, 179, 214, 236, 244, 251}, /* Norm */
203 {0, 0, 0, 0, 81, 0, 131, 164, 188, 223, 243, 251, 257}, /* SGI */
204 {0, 0, 0, 0, 89, 0, 167, 235, 296, 402, 488, 526, 560}, /* AGG */
205 {0, 0, 0, 0, 97, 0, 182, 255, 320, 431, 520, 558, 593}, /* AGG+SGI*/
206};
207
208static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = {
209 {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */
210 {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */
211 {0, 0, 0, 0, 171, 0, 305, 410, 496, 634, 731, 771, 805}, /* AGG */
212 {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838}, /* AGG+SGI */
213};
214
215static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = {
216 {0, 0, 0, 0, 99, 0, 153, 186, 208, 239, 256, 263, 268}, /* Norm */
217 {0, 0, 0, 0, 106, 0, 162, 194, 215, 246, 262, 268, 273}, /* SGI */
218 {0, 0, 0, 0, 134, 0, 249, 346, 431, 574, 685, 732, 775}, /* AGG */
219 {0, 0, 0, 0, 148, 0, 272, 376, 465, 614, 727, 775, 818}, /* AGG+SGI */
220};
221
222static s32 expected_tpt_mimo3_40MHz[4][IWL_RATE_COUNT] = {
223 {0, 0, 0, 0, 152, 0, 211, 239, 255, 279, 290, 294, 297}, /* Norm */
224 {0, 0, 0, 0, 160, 0, 219, 245, 261, 284, 294, 297, 300}, /* SGI */
225 {0, 0, 0, 0, 254, 0, 443, 584, 695, 868, 984, 1030, 1070}, /* AGG */
226 {0, 0, 0, 0, 277, 0, 478, 624, 737, 911, 1026, 1070, 1109}, /* AGG+SGI */
227};
228
229/* mbps, mcs */
230static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
231 { "1", "BPSK DSSS"},
232 { "2", "QPSK DSSS"},
233 {"5.5", "BPSK CCK"},
234 { "11", "QPSK CCK"},
235 { "6", "BPSK 1/2"},
236 { "9", "BPSK 1/2"},
237 { "12", "QPSK 1/2"},
238 { "18", "QPSK 3/4"},
239 { "24", "16QAM 1/2"},
240 { "36", "16QAM 3/4"},
241 { "48", "64QAM 2/3"},
242 { "54", "64QAM 3/4"},
243 { "60", "64QAM 5/6"},
244};
245
246#define MCS_INDEX_PER_STREAM (8)
247
248static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
249{
250 window->data = 0;
251 window->success_counter = 0;
252 window->success_ratio = IWL_INVALID_VALUE;
253 window->counter = 0;
254 window->average_tpt = IWL_INVALID_VALUE;
255 window->stamp = 0;
256}
257
258static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
259{
260 return (ant_type & valid_antenna) == ant_type;
261}
262
263/*
264 * removes the old data from the statistics. All data that is older than
265 * TID_MAX_TIME_DIFF, will be deleted.
266 */
267static void rs_tl_rm_old_stats(struct iwl_traffic_load *tl, u32 curr_time)
268{
269 /* The oldest age we want to keep */
270 u32 oldest_time = curr_time - TID_MAX_TIME_DIFF;
271
272 while (tl->queue_count &&
273 (tl->time_stamp < oldest_time)) {
274 tl->total -= tl->packet_count[tl->head];
275 tl->packet_count[tl->head] = 0;
276 tl->time_stamp += TID_QUEUE_CELL_SPACING;
277 tl->queue_count--;
278 tl->head++;
279 if (tl->head >= TID_QUEUE_MAX_SIZE)
280 tl->head = 0;
281 }
282}
283
284/*
285 * increment traffic load value for tid and also remove
286 * any old values if passed the certain time period
287 */
288static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
289 struct ieee80211_hdr *hdr)
290{
291 u32 curr_time = jiffies_to_msecs(jiffies);
292 u32 time_diff;
293 s32 index;
294 struct iwl_traffic_load *tl = NULL;
295 u8 tid;
296
297 if (ieee80211_is_data_qos(hdr->frame_control)) {
298 u8 *qc = ieee80211_get_qos_ctl(hdr);
299 tid = qc[0] & 0xf;
300 } else {
301 return IWL_MAX_TID_COUNT;
302 }
303
304 if (unlikely(tid >= IWL_MAX_TID_COUNT))
305 return IWL_MAX_TID_COUNT;
306
307 tl = &lq_data->load[tid];
308
309 curr_time -= curr_time % TID_ROUND_VALUE;
310
311 /* Happens only for the first packet. Initialize the data */
312 if (!(tl->queue_count)) {
313 tl->total = 1;
314 tl->time_stamp = curr_time;
315 tl->queue_count = 1;
316 tl->head = 0;
317 tl->packet_count[0] = 1;
318 return IWL_MAX_TID_COUNT;
319 }
320
321 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
322 index = time_diff / TID_QUEUE_CELL_SPACING;
323
324 /* The history is too long: remove data that is older than */
325 /* TID_MAX_TIME_DIFF */
326 if (index >= TID_QUEUE_MAX_SIZE)
327 rs_tl_rm_old_stats(tl, curr_time);
328
329 index = (tl->head + index) % TID_QUEUE_MAX_SIZE;
330 tl->packet_count[index] = tl->packet_count[index] + 1;
331 tl->total = tl->total + 1;
332
333 if ((index + 1) > tl->queue_count)
334 tl->queue_count = index + 1;
335
336 return tid;
337}
338
339#ifdef CONFIG_MAC80211_DEBUGFS
340/**
341 * Program the device to use fixed rate for frame transmit
342 * This is for debugging/testing only
343 * once the device start use fixed rate, we need to reload the module
344 * to being back the normal operation.
345 */
346static void rs_program_fix_rate(struct iwl_mvm *mvm,
347 struct iwl_lq_sta *lq_sta)
348{
349 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
350 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
351 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
352 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
353
354 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n",
355 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
356
357 if (lq_sta->dbg_fixed_rate) {
358 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
359 iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
360 }
361}
362#endif
363
364/*
365 get the traffic load value for tid
366*/
367static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
368{
369 u32 curr_time = jiffies_to_msecs(jiffies);
370 u32 time_diff;
371 s32 index;
372 struct iwl_traffic_load *tl = NULL;
373
374 if (tid >= IWL_MAX_TID_COUNT)
375 return 0;
376
377 tl = &(lq_data->load[tid]);
378
379 curr_time -= curr_time % TID_ROUND_VALUE;
380
381 if (!(tl->queue_count))
382 return 0;
383
384 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
385 index = time_diff / TID_QUEUE_CELL_SPACING;
386
387 /* The history is too long: remove data that is older than */
388 /* TID_MAX_TIME_DIFF */
389 if (index >= TID_QUEUE_MAX_SIZE)
390 rs_tl_rm_old_stats(tl, curr_time);
391
392 return tl->total;
393}
394
395static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
396 struct iwl_lq_sta *lq_data, u8 tid,
397 struct ieee80211_sta *sta)
398{
399 int ret = -EAGAIN;
400 u32 load;
401
402 load = rs_tl_get_load(lq_data, tid);
403
404 if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) {
405 IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
406 sta->addr, tid);
407 ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
408 if (ret == -EAGAIN) {
409 /*
410 * driver and mac80211 is out of sync
411 * this might be cause by reloading firmware
412 * stop the tx ba session here
413 */
414 IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n",
415 tid);
416 ieee80211_stop_tx_ba_session(sta, tid);
417 }
418 } else {
419 IWL_DEBUG_HT(mvm,
420 "Aggregation not enabled for tid %d because load = %u\n",
421 tid, load);
422 }
423 return ret;
424}
425
426static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, u8 tid,
427 struct iwl_lq_sta *lq_data,
428 struct ieee80211_sta *sta)
429{
430 if (tid < IWL_MAX_TID_COUNT)
431 rs_tl_turn_on_agg_for_tid(mvm, lq_data, tid, sta);
432 else
433 IWL_ERR(mvm, "tid exceeds max TID count: %d/%d\n",
434 tid, IWL_MAX_TID_COUNT);
435}
436
437static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
438{
439 return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
440 !!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
441 !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
442}
443
444/*
445 * Static function to get the expected throughput from an iwl_scale_tbl_info
446 * that wraps a NULL pointer check
447 */
448static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
449{
450 if (tbl->expected_tpt)
451 return tbl->expected_tpt[rs_index];
452 return 0;
453}
454
455/**
456 * rs_collect_tx_data - Update the success/failure sliding window
457 *
458 * We keep a sliding window of the last 62 packets transmitted
459 * at this rate. window->data contains the bitmask of successful
460 * packets.
461 */
462static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
463 int scale_index, int attempts, int successes)
464{
465 struct iwl_rate_scale_data *window = NULL;
466 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
467 s32 fail_count, tpt;
468
469 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
470 return -EINVAL;
471
472 /* Select window for current tx bit rate */
473 window = &(tbl->win[scale_index]);
474
475 /* Get expected throughput */
476 tpt = get_expected_tpt(tbl, scale_index);
477
478 /*
479 * Keep track of only the latest 62 tx frame attempts in this rate's
480 * history window; anything older isn't really relevant any more.
481 * If we have filled up the sliding window, drop the oldest attempt;
482 * if the oldest attempt (highest bit in bitmap) shows "success",
483 * subtract "1" from the success counter (this is the main reason
484 * we keep these bitmaps!).
485 */
486 while (attempts > 0) {
487 if (window->counter >= IWL_RATE_MAX_WINDOW) {
488 /* remove earliest */
489 window->counter = IWL_RATE_MAX_WINDOW - 1;
490
491 if (window->data & mask) {
492 window->data &= ~mask;
493 window->success_counter--;
494 }
495 }
496
497 /* Increment frames-attempted counter */
498 window->counter++;
499
500 /* Shift bitmap by one frame to throw away oldest history */
501 window->data <<= 1;
502
503 /* Mark the most recent #successes attempts as successful */
504 if (successes > 0) {
505 window->success_counter++;
506 window->data |= 0x1;
507 successes--;
508 }
509
510 attempts--;
511 }
512
513 /* Calculate current success ratio, avoid divide-by-0! */
514 if (window->counter > 0)
515 window->success_ratio = 128 * (100 * window->success_counter)
516 / window->counter;
517 else
518 window->success_ratio = IWL_INVALID_VALUE;
519
520 fail_count = window->counter - window->success_counter;
521
522 /* Calculate average throughput, if we have enough history. */
523 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
524 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
525 window->average_tpt = (window->success_ratio * tpt + 64) / 128;
526 else
527 window->average_tpt = IWL_INVALID_VALUE;
528
529 /* Tag this window as having been updated */
530 window->stamp = jiffies;
531
532 return 0;
533}
534
535/*
536 * Fill uCode API rate_n_flags field, based on "search" or "active" table.
537 */
538/* FIXME:RS:remove this function and put the flags statically in the table */
539static u32 rate_n_flags_from_tbl(struct iwl_mvm *mvm,
540 struct iwl_scale_tbl_info *tbl,
541 int index, u8 use_green)
542{
543 u32 rate_n_flags = 0;
544
545 if (is_legacy(tbl->lq_type)) {
546 rate_n_flags = iwl_rates[index].plcp;
547 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
548 rate_n_flags |= RATE_MCS_CCK_MSK;
549 } else if (is_Ht(tbl->lq_type)) {
550 if (index > IWL_LAST_OFDM_RATE) {
551 IWL_ERR(mvm, "Invalid HT rate index %d\n", index);
552 index = IWL_LAST_OFDM_RATE;
553 }
554 rate_n_flags = RATE_MCS_HT_MSK;
555
556 if (is_siso(tbl->lq_type))
557 rate_n_flags |= iwl_rates[index].plcp_siso;
558 else if (is_mimo2(tbl->lq_type))
559 rate_n_flags |= iwl_rates[index].plcp_mimo2;
560 else
561 rate_n_flags |= iwl_rates[index].plcp_mimo3;
562 } else {
563 IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type);
564 }
565
566 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
567 RATE_MCS_ANT_ABC_MSK);
568
569 if (is_Ht(tbl->lq_type)) {
570 if (tbl->is_ht40)
571 rate_n_flags |= RATE_MCS_CHAN_WIDTH_40;
572 if (tbl->is_SGI)
573 rate_n_flags |= RATE_MCS_SGI_MSK;
574
575 if (use_green) {
576 rate_n_flags |= RATE_HT_MCS_GF_MSK;
577 if (is_siso(tbl->lq_type) && tbl->is_SGI) {
578 rate_n_flags &= ~RATE_MCS_SGI_MSK;
579 IWL_ERR(mvm, "GF was set with SGI:SISO\n");
580 }
581 }
582 }
583 return rate_n_flags;
584}
585
586/*
587 * Interpret uCode API's rate_n_flags format,
588 * fill "search" or "active" tx mode table.
589 */
590static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
591 enum ieee80211_band band,
592 struct iwl_scale_tbl_info *tbl,
593 int *rate_idx)
594{
595 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK);
596 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
597 u8 mcs;
598
599 memset(tbl, 0, sizeof(struct iwl_scale_tbl_info));
600 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
601
602 if (*rate_idx == IWL_RATE_INVALID) {
603 *rate_idx = -1;
604 return -EINVAL;
605 }
606 tbl->is_SGI = 0; /* default legacy setup */
607 tbl->is_ht40 = 0;
608 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
609 tbl->lq_type = LQ_NONE;
610 tbl->max_search = IWL_MAX_SEARCH;
611
612 /* legacy rate format */
613 if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
614 if (num_of_ant == 1) {
615 if (band == IEEE80211_BAND_5GHZ)
616 tbl->lq_type = LQ_A;
617 else
618 tbl->lq_type = LQ_G;
619 }
620 /* HT rate format */
621 } else {
622 if (rate_n_flags & RATE_MCS_SGI_MSK)
623 tbl->is_SGI = 1;
624
625 if (rate_n_flags & RATE_MCS_CHAN_WIDTH_40) /* TODO */
626 tbl->is_ht40 = 1;
627
628 mcs = rs_extract_rate(rate_n_flags);
629
630 /* SISO */
631 if (mcs <= IWL_RATE_SISO_60M_PLCP) {
632 if (num_of_ant == 1)
633 tbl->lq_type = LQ_SISO; /*else NONE*/
634 /* MIMO2 */
635 } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) {
636 if (num_of_ant == 2)
637 tbl->lq_type = LQ_MIMO2;
638 /* MIMO3 */
639 } else {
640 if (num_of_ant == 3) {
641 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
642 tbl->lq_type = LQ_MIMO3;
643 }
644 }
645 }
646 return 0;
647}
648
649/* switch to another antenna/antennas and return 1 */
650/* if no other valid antenna found, return 0 */
651static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
652 struct iwl_scale_tbl_info *tbl)
653{
654 u8 new_ant_type;
655
656 if (!tbl->ant_type || tbl->ant_type > ANT_ABC)
657 return 0;
658
659 if (!rs_is_valid_ant(valid_ant, tbl->ant_type))
660 return 0;
661
662 new_ant_type = ant_toggle_lookup[tbl->ant_type];
663
664 while ((new_ant_type != tbl->ant_type) &&
665 !rs_is_valid_ant(valid_ant, new_ant_type))
666 new_ant_type = ant_toggle_lookup[new_ant_type];
667
668 if (new_ant_type == tbl->ant_type)
669 return 0;
670
671 tbl->ant_type = new_ant_type;
672 *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK;
673 *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS;
674 return 1;
675}
676
677/**
678 * Green-field mode is valid if the station supports it and
679 * there are no non-GF stations present in the BSS.
680 */
681static bool rs_use_green(struct ieee80211_sta *sta)
682{
683 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;
684
685 bool use_green = !(sta_priv->vif->bss_conf.ht_operation_mode &
686 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
687
688 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && use_green;
689}
690
691/**
692 * rs_get_supported_rates - get the available rates
693 *
694 * if management frame or broadcast frame only return
695 * basic available rates.
696 *
697 */
698static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
699 struct ieee80211_hdr *hdr,
700 enum iwl_table_type rate_type)
701{
702 if (is_legacy(rate_type)) {
703 return lq_sta->active_legacy_rate;
704 } else {
705 if (is_siso(rate_type))
706 return lq_sta->active_siso_rate;
707 else if (is_mimo2(rate_type))
708 return lq_sta->active_mimo2_rate;
709 else
710 return lq_sta->active_mimo3_rate;
711 }
712}
713
714static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
715 int rate_type)
716{
717 u8 high = IWL_RATE_INVALID;
718 u8 low = IWL_RATE_INVALID;
719
720 /* 802.11A or ht walks to the next literal adjacent rate in
721 * the rate table */
722 if (is_a_band(rate_type) || !is_legacy(rate_type)) {
723 int i;
724 u32 mask;
725
726 /* Find the previous rate that is in the rate mask */
727 i = index - 1;
728 for (mask = (1 << i); i >= 0; i--, mask >>= 1) {
729 if (rate_mask & mask) {
730 low = i;
731 break;
732 }
733 }
734
735 /* Find the next rate that is in the rate mask */
736 i = index + 1;
737 for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {
738 if (rate_mask & mask) {
739 high = i;
740 break;
741 }
742 }
743
744 return (high << 8) | low;
745 }
746
747 low = index;
748 while (low != IWL_RATE_INVALID) {
749 low = iwl_rates[low].prev_rs;
750 if (low == IWL_RATE_INVALID)
751 break;
752 if (rate_mask & (1 << low))
753 break;
754 IWL_DEBUG_RATE(mvm, "Skipping masked lower rate: %d\n", low);
755 }
756
757 high = index;
758 while (high != IWL_RATE_INVALID) {
759 high = iwl_rates[high].next_rs;
760 if (high == IWL_RATE_INVALID)
761 break;
762 if (rate_mask & (1 << high))
763 break;
764 IWL_DEBUG_RATE(mvm, "Skipping masked higher rate: %d\n", high);
765 }
766
767 return (high << 8) | low;
768}
769
770static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
771 struct iwl_scale_tbl_info *tbl,
772 u8 scale_index, u8 ht_possible)
773{
774 s32 low;
775 u16 rate_mask;
776 u16 high_low;
777 u8 switch_to_legacy = 0;
778 u8 is_green = lq_sta->is_green;
779 struct iwl_mvm *mvm = lq_sta->drv;
780
781 /* check if we need to switch from HT to legacy rates.
782 * assumption is that mandatory rates (1Mbps or 6Mbps)
783 * are always supported (spec demand) */
784 if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) {
785 switch_to_legacy = 1;
786 scale_index = rs_ht_to_legacy[scale_index];
787 if (lq_sta->band == IEEE80211_BAND_5GHZ)
788 tbl->lq_type = LQ_A;
789 else
790 tbl->lq_type = LQ_G;
791
792 if (num_of_ant(tbl->ant_type) > 1)
793 tbl->ant_type =
794 first_antenna(mvm->nvm_data->valid_tx_ant);
795
796 tbl->is_ht40 = 0;
797 tbl->is_SGI = 0;
798 tbl->max_search = IWL_MAX_SEARCH;
799 }
800
801 rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type);
802
803 /* Mask with station rate restriction */
804 if (is_legacy(tbl->lq_type)) {
805 /* supp_rates has no CCK bits in A mode */
806 if (lq_sta->band == IEEE80211_BAND_5GHZ)
807 rate_mask = (u16)(rate_mask &
808 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
809 else
810 rate_mask = (u16)(rate_mask & lq_sta->supp_rates);
811 }
812
813 /* If we switched from HT to legacy, check current rate */
814 if (switch_to_legacy && (rate_mask & (1 << scale_index))) {
815 low = scale_index;
816 goto out;
817 }
818
819 high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask,
820 tbl->lq_type);
821 low = high_low & 0xff;
822
823 if (low == IWL_RATE_INVALID)
824 low = scale_index;
825
826out:
827 return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green);
828}
829
830/*
831 * Simple function to compare two rate scale table types
832 */
833static bool table_type_matches(struct iwl_scale_tbl_info *a,
834 struct iwl_scale_tbl_info *b)
835{
836 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
837 (a->is_SGI == b->is_SGI);
838}
839
840/*
841 * mac80211 sends us Tx status
842 */
843static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
844 struct ieee80211_sta *sta, void *priv_sta,
845 struct sk_buff *skb)
846{
847 int legacy_success;
848 int retries;
849 int rs_index, mac_index, i;
850 struct iwl_lq_sta *lq_sta = priv_sta;
851 struct iwl_lq_cmd *table;
852 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
853 struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_r;
854 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
855 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
856 enum mac80211_rate_control_flags mac_flags;
857 u32 tx_rate;
858 struct iwl_scale_tbl_info tbl_type;
859 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
860
861 IWL_DEBUG_RATE_LIMIT(mvm,
862 "get frame ack response, update rate scale window\n");
863
864 /* Treat uninitialized rate scaling data same as non-existing. */
865 if (!lq_sta) {
866 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
867 return;
868 } else if (!lq_sta->drv) {
869 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
870 return;
871 }
872
873 if (!ieee80211_is_data(hdr->frame_control) ||
874 info->flags & IEEE80211_TX_CTL_NO_ACK)
875 return;
876
877 /* This packet was aggregated but doesn't carry status info */
878 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
879 !(info->flags & IEEE80211_TX_STAT_AMPDU))
880 return;
881
882 /*
883 * Ignore this Tx frame response if its initial rate doesn't match
884 * that of latest Link Quality command. There may be stragglers
885 * from a previous Link Quality command, but we're no longer interested
886 * in those; they're either from the "active" mode while we're trying
887 * to check "search" mode, or a prior "search" mode after we've moved
888 * to a new "search" mode (which might become the new "active" mode).
889 */
890 table = &lq_sta->lq;
891 tx_rate = le32_to_cpu(table->rs_table[0]);
892 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type, &rs_index);
893 if (info->band == IEEE80211_BAND_5GHZ)
894 rs_index -= IWL_FIRST_OFDM_RATE;
895 mac_flags = info->status.rates[0].flags;
896 mac_index = info->status.rates[0].idx;
897 /* For HT packets, map MCS to PLCP */
898 if (mac_flags & IEEE80211_TX_RC_MCS) {
899 /* Remove # of streams */
900 mac_index &= RATE_HT_MCS_RATE_CODE_MSK;
901 if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
902 mac_index++;
903 /*
904 * mac80211 HT index is always zero-indexed; we need to move
905 * HT OFDM rates after CCK rates in 2.4 GHz band
906 */
907 if (info->band == IEEE80211_BAND_2GHZ)
908 mac_index += IWL_FIRST_OFDM_RATE;
909 }
910 /* Here we actually compare this rate to the latest LQ command */
911 if ((mac_index < 0) ||
912 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
913 (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) ||
914 (tbl_type.ant_type != info->status.antenna) ||
915 (!!(tx_rate & RATE_MCS_HT_MSK) !=
916 !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
917 (!!(tx_rate & RATE_HT_MCS_GF_MSK) !=
918 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
919 (rs_index != mac_index)) {
920 IWL_DEBUG_RATE(mvm,
921 "initial rate %d does not match %d (0x%x)\n",
922 mac_index, rs_index, tx_rate);
923 /*
924 * Since rates mis-match, the last LQ command may have failed.
925 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
926 * ... driver.
927 */
928 lq_sta->missed_rate_counter++;
929 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
930 lq_sta->missed_rate_counter = 0;
931 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
932 }
933 /* Regardless, ignore this status info for outdated rate */
934 return;
935 } else
936 /* Rate did match, so reset the missed_rate_counter */
937 lq_sta->missed_rate_counter = 0;
938
939 /* Figure out if rate scale algorithm is in active or search table */
940 if (table_type_matches(&tbl_type,
941 &(lq_sta->lq_info[lq_sta->active_tbl]))) {
942 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
943 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
944 } else if (table_type_matches(
945 &tbl_type, &lq_sta->lq_info[1 - lq_sta->active_tbl])) {
946 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
947 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
948 } else {
949 IWL_DEBUG_RATE(mvm,
950 "Neither active nor search matches tx rate\n");
951 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
952 IWL_DEBUG_RATE(mvm, "active- lq:%x, ant:%x, SGI:%d\n",
953 tmp_tbl->lq_type, tmp_tbl->ant_type,
954 tmp_tbl->is_SGI);
955 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
956 IWL_DEBUG_RATE(mvm, "search- lq:%x, ant:%x, SGI:%d\n",
957 tmp_tbl->lq_type, tmp_tbl->ant_type,
958 tmp_tbl->is_SGI);
959 IWL_DEBUG_RATE(mvm, "actual- lq:%x, ant:%x, SGI:%d\n",
960 tbl_type.lq_type, tbl_type.ant_type,
961 tbl_type.is_SGI);
962 /*
963 * no matching table found, let's by-pass the data collection
964 * and continue to perform rate scale to find the rate table
965 */
966 rs_stay_in_table(lq_sta, true);
967 goto done;
968 }
969
970 /*
971 * Updating the frame history depends on whether packets were
972 * aggregated.
973 *
974 * For aggregation, all packets were transmitted at the same rate, the
975 * first index into rate scale table.
976 */
977 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
978 tx_rate = le32_to_cpu(table->rs_table[0]);
979 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type,
980 &rs_index);
981 rs_collect_tx_data(curr_tbl, rs_index,
982 info->status.ampdu_len,
983 info->status.ampdu_ack_len);
984
985 /* Update success/fail counts if not searching for new mode */
986 if (lq_sta->stay_in_tbl) {
987 lq_sta->total_success += info->status.ampdu_ack_len;
988 lq_sta->total_failed += (info->status.ampdu_len -
989 info->status.ampdu_ack_len);
990 }
991 } else {
992 /*
993 * For legacy, update frame history with for each Tx retry.
994 */
995 retries = info->status.rates[0].count - 1;
996 /* HW doesn't send more than 15 retries */
997 retries = min(retries, 15);
998
999 /* The last transmission may have been successful */
1000 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
1001 /* Collect data for each rate used during failed TX attempts */
1002 for (i = 0; i <= retries; ++i) {
1003 tx_rate = le32_to_cpu(table->rs_table[i]);
1004 rs_get_tbl_info_from_mcs(tx_rate, info->band,
1005 &tbl_type, &rs_index);
1006 /*
1007 * Only collect stats if retried rate is in the same RS
1008 * table as active/search.
1009 */
1010 if (table_type_matches(&tbl_type, curr_tbl))
1011 tmp_tbl = curr_tbl;
1012 else if (table_type_matches(&tbl_type, other_tbl))
1013 tmp_tbl = other_tbl;
1014 else
1015 continue;
1016 rs_collect_tx_data(tmp_tbl, rs_index, 1,
1017 i < retries ? 0 : legacy_success);
1018 }
1019
1020 /* Update success/fail counts if not searching for new mode */
1021 if (lq_sta->stay_in_tbl) {
1022 lq_sta->total_success += legacy_success;
1023 lq_sta->total_failed += retries + (1 - legacy_success);
1024 }
1025 }
1026 /* The last TX rate is cached in lq_sta; it's set in if/else above */
1027 lq_sta->last_rate_n_flags = tx_rate;
1028done:
1029 /* See if there's a better rate or modulation mode to try. */
1030 if (sta && sta->supp_rates[sband->band])
1031 rs_rate_scale_perform(mvm, skb, sta, lq_sta);
1032}
1033
1034/*
1035 * Begin a period of staying with a selected modulation mode.
1036 * Set "stay_in_tbl" flag to prevent any mode switches.
1037 * Set frame tx success limits according to legacy vs. high-throughput,
1038 * and reset overall (spanning all rates) tx success history statistics.
1039 * These control how long we stay using same modulation mode before
1040 * searching for a new mode.
1041 */
1042static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
1043 struct iwl_lq_sta *lq_sta)
1044{
1045 IWL_DEBUG_RATE(mvm, "we are staying in the same table\n");
1046 lq_sta->stay_in_tbl = 1; /* only place this gets set */
1047 if (is_legacy) {
1048 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
1049 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
1050 lq_sta->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT;
1051 } else {
1052 lq_sta->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT;
1053 lq_sta->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT;
1054 lq_sta->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT;
1055 }
1056 lq_sta->table_count = 0;
1057 lq_sta->total_failed = 0;
1058 lq_sta->total_success = 0;
1059 lq_sta->flush_timer = jiffies;
1060 lq_sta->action_counter = 0;
1061}
1062
1063/*
1064 * Find correct throughput table for given mode of modulation
1065 */
1066static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1067 struct iwl_scale_tbl_info *tbl)
1068{
1069 /* Used to choose among HT tables */
1070 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT];
1071
1072 /* Check for invalid LQ type */
1073 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_Ht(tbl->lq_type))) {
1074 tbl->expected_tpt = expected_tpt_legacy;
1075 return;
1076 }
1077
1078 /* Legacy rates have only one table */
1079 if (is_legacy(tbl->lq_type)) {
1080 tbl->expected_tpt = expected_tpt_legacy;
1081 return;
1082 }
1083
1084 /* Choose among many HT tables depending on number of streams
1085 * (SISO/MIMO2/MIMO3), channel width (20/40), SGI, and aggregation
1086 * status */
1087 if (is_siso(tbl->lq_type) && !tbl->is_ht40)
1088 ht_tbl_pointer = expected_tpt_siso20MHz;
1089 else if (is_siso(tbl->lq_type))
1090 ht_tbl_pointer = expected_tpt_siso40MHz;
1091 else if (is_mimo2(tbl->lq_type) && !tbl->is_ht40)
1092 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1093 else if (is_mimo2(tbl->lq_type))
1094 ht_tbl_pointer = expected_tpt_mimo2_40MHz;
1095 else if (is_mimo3(tbl->lq_type) && !tbl->is_ht40)
1096 ht_tbl_pointer = expected_tpt_mimo3_20MHz;
1097 else /* if (is_mimo3(tbl->lq_type)) <-- must be true */
1098 ht_tbl_pointer = expected_tpt_mimo3_40MHz;
1099
1100 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */
1101 tbl->expected_tpt = ht_tbl_pointer[0];
1102 else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */
1103 tbl->expected_tpt = ht_tbl_pointer[1];
1104 else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */
1105 tbl->expected_tpt = ht_tbl_pointer[2];
1106 else /* AGG+SGI */
1107 tbl->expected_tpt = ht_tbl_pointer[3];
1108}
1109
1110/*
1111 * Find starting rate for new "search" high-throughput mode of modulation.
1112 * Goal is to find lowest expected rate (under perfect conditions) that is
1113 * above the current measured throughput of "active" mode, to give new mode
1114 * a fair chance to prove itself without too many challenges.
1115 *
1116 * This gets called when transitioning to more aggressive modulation
1117 * (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive
1118 * (i.e. MIMO to SISO). When moving to MIMO, bit rate will typically need
1119 * to decrease to match "active" throughput. When moving from MIMO to SISO,
1120 * bit rate will typically need to increase, but not if performance was bad.
1121 */
1122static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1123 struct iwl_lq_sta *lq_sta,
1124 struct iwl_scale_tbl_info *tbl, /* "search" */
1125 u16 rate_mask, s8 index)
1126{
1127 /* "active" values */
1128 struct iwl_scale_tbl_info *active_tbl =
1129 &(lq_sta->lq_info[lq_sta->active_tbl]);
1130 s32 active_sr = active_tbl->win[index].success_ratio;
1131 s32 active_tpt = active_tbl->expected_tpt[index];
1132
1133 /* expected "search" throughput */
1134 s32 *tpt_tbl = tbl->expected_tpt;
1135
1136 s32 new_rate, high, low, start_hi;
1137 u16 high_low;
1138 s8 rate = index;
1139
1140 new_rate = high = low = start_hi = IWL_RATE_INVALID;
1141
1142 while (1) {
1143 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask,
1144 tbl->lq_type);
1145
1146 low = high_low & 0xff;
1147 high = (high_low >> 8) & 0xff;
1148
1149 /*
1150 * Lower the "search" bit rate, to give new "search" mode
1151 * approximately the same throughput as "active" if:
1152 *
1153 * 1) "Active" mode has been working modestly well (but not
1154 * great), and expected "search" throughput (under perfect
1155 * conditions) at candidate rate is above the actual
1156 * measured "active" throughput (but less than expected
1157 * "active" throughput under perfect conditions).
1158 * OR
1159 * 2) "Active" mode has been working perfectly or very well
1160 * and expected "search" throughput (under perfect
1161 * conditions) at candidate rate is above expected
1162 * "active" throughput (under perfect conditions).
1163 */
1164 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) &&
1165 ((active_sr > IWL_RATE_DECREASE_TH) &&
1166 (active_sr <= IWL_RATE_HIGH_TH) &&
1167 (tpt_tbl[rate] <= active_tpt))) ||
1168 ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
1169 (tpt_tbl[rate] > active_tpt))) {
1170 /* (2nd or later pass)
1171 * If we've already tried to raise the rate, and are
1172 * now trying to lower it, use the higher rate. */
1173 if (start_hi != IWL_RATE_INVALID) {
1174 new_rate = start_hi;
1175 break;
1176 }
1177
1178 new_rate = rate;
1179
1180 /* Loop again with lower rate */
1181 if (low != IWL_RATE_INVALID)
1182 rate = low;
1183
1184 /* Lower rate not available, use the original */
1185 else
1186 break;
1187
1188 /* Else try to raise the "search" rate to match "active" */
1189 } else {
1190 /* (2nd or later pass)
1191 * If we've already tried to lower the rate, and are
1192 * now trying to raise it, use the lower rate. */
1193 if (new_rate != IWL_RATE_INVALID)
1194 break;
1195
1196 /* Loop again with higher rate */
1197 else if (high != IWL_RATE_INVALID) {
1198 start_hi = high;
1199 rate = high;
1200
1201 /* Higher rate not available, use the original */
1202 } else {
1203 new_rate = rate;
1204 break;
1205 }
1206 }
1207 }
1208
1209 return new_rate;
1210}
1211
1212static bool iwl_is_ht40_tx_allowed(struct iwl_mvm *mvm,
1213 struct ieee80211_sta_ht_cap *ht_cap)
1214{
1215 /*
1216 * Remainder of this function checks ht_cap, but if it's
1217 * NULL then we can do HT40 (special case for RXON)
1218 */
1219 if (!ht_cap)
1220 return true;
1221
1222 if (!ht_cap->ht_supported)
1223 return false;
1224
1225 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
1226 return false;
1227
1228 return true;
1229}
1230
1231/*
1232 * Set up search table for MIMO2
1233 */
1234static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1235 struct iwl_lq_sta *lq_sta,
1236 struct ieee80211_sta *sta,
1237 struct iwl_scale_tbl_info *tbl, int index)
1238{
1239 u16 rate_mask;
1240 s32 rate;
1241 s8 is_green = lq_sta->is_green;
1242
1243 if (!sta->ht_cap.ht_supported)
1244 return -1;
1245
1246 if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
1247 == WLAN_HT_CAP_SM_PS_STATIC)
1248 return -1;
1249
1250 /* Need both Tx chains/antennas to support MIMO */
1251 if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 2)
1252 return -1;
1253
1254 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n");
1255
1256 tbl->lq_type = LQ_MIMO2;
1257 tbl->action = 0;
1258 tbl->max_search = IWL_MAX_SEARCH;
1259 rate_mask = lq_sta->active_mimo2_rate;
1260
1261 if (iwl_is_ht40_tx_allowed(mvm, &sta->ht_cap))
1262 tbl->is_ht40 = 1;
1263 else
1264 tbl->is_ht40 = 0;
1265
1266 rs_set_expected_tpt_table(lq_sta, tbl);
1267
1268 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1269
1270 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 best rate %d mask %X\n",
1271 rate, rate_mask);
1272 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1273 IWL_DEBUG_RATE(mvm, "Can't switch with index %d rate mask %x\n",
1274 rate, rate_mask);
1275 return -1;
1276 }
1277 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green);
1278
1279 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n",
1280 tbl->current_rate, is_green);
1281 return 0;
1282}
1283
1284/*
1285 * Set up search table for MIMO3
1286 */
1287static int rs_switch_to_mimo3(struct iwl_mvm *mvm,
1288 struct iwl_lq_sta *lq_sta,
1289 struct ieee80211_sta *sta,
1290 struct iwl_scale_tbl_info *tbl, int index)
1291{
1292 u16 rate_mask;
1293 s32 rate;
1294 s8 is_green = lq_sta->is_green;
1295
1296 if (!sta->ht_cap.ht_supported)
1297 return -1;
1298
1299 if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
1300 == WLAN_HT_CAP_SM_PS_STATIC)
1301 return -1;
1302
1303 /* Need both Tx chains/antennas to support MIMO */
1304 if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 3)
1305 return -1;
1306
1307 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n");
1308
1309 tbl->lq_type = LQ_MIMO3;
1310 tbl->action = 0;
1311 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
1312 rate_mask = lq_sta->active_mimo3_rate;
1313
1314 if (iwl_is_ht40_tx_allowed(mvm, &sta->ht_cap))
1315 tbl->is_ht40 = 1;
1316 else
1317 tbl->is_ht40 = 0;
1318
1319 rs_set_expected_tpt_table(lq_sta, tbl);
1320
1321 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1322
1323 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 best rate %d mask %X\n",
1324 rate, rate_mask);
1325 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1326 IWL_DEBUG_RATE(mvm, "Can't switch with index %d rate mask %x\n",
1327 rate, rate_mask);
1328 return -1;
1329 }
1330 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green);
1331
1332 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n",
1333 tbl->current_rate, is_green);
1334 return 0;
1335}
1336
1337/*
1338 * Set up search table for SISO
1339 */
1340static int rs_switch_to_siso(struct iwl_mvm *mvm,
1341 struct iwl_lq_sta *lq_sta,
1342 struct ieee80211_sta *sta,
1343 struct iwl_scale_tbl_info *tbl, int index)
1344{
1345 u16 rate_mask;
1346 u8 is_green = lq_sta->is_green;
1347 s32 rate;
1348
1349 if (!sta->ht_cap.ht_supported)
1350 return -1;
1351
1352 IWL_DEBUG_RATE(mvm, "LQ: try to switch to SISO\n");
1353
1354 tbl->lq_type = LQ_SISO;
1355 tbl->action = 0;
1356 tbl->max_search = IWL_MAX_SEARCH;
1357 rate_mask = lq_sta->active_siso_rate;
1358
1359 if (iwl_is_ht40_tx_allowed(mvm, &sta->ht_cap))
1360 tbl->is_ht40 = 1;
1361 else
1362 tbl->is_ht40 = 0;
1363
1364 if (is_green)
1365 tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/
1366
1367 rs_set_expected_tpt_table(lq_sta, tbl);
1368 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1369
1370 IWL_DEBUG_RATE(mvm, "LQ: get best rate %d mask %X\n", rate, rate_mask);
1371 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1372 IWL_DEBUG_RATE(mvm,
1373 "can not switch with index %d rate mask %x\n",
1374 rate, rate_mask);
1375 return -1;
1376 }
1377 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green);
1378 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n",
1379 tbl->current_rate, is_green);
1380 return 0;
1381}
1382
1383/*
1384 * Try to switch to new modulation mode from legacy
1385 */
1386static int rs_move_legacy_other(struct iwl_mvm *mvm,
1387 struct iwl_lq_sta *lq_sta,
1388 struct ieee80211_sta *sta,
1389 int index)
1390{
1391 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1392 struct iwl_scale_tbl_info *search_tbl =
1393 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1394 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1395 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1396 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1397 u8 start_action;
1398 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
1399 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1400 int ret;
1401 u8 update_search_tbl_counter = 0;
1402
1403 start_action = tbl->action;
1404 while (1) {
1405 lq_sta->action_counter++;
1406 switch (tbl->action) {
1407 case IWL_LEGACY_SWITCH_ANTENNA1:
1408 case IWL_LEGACY_SWITCH_ANTENNA2:
1409 IWL_DEBUG_RATE(mvm, "LQ: Legacy toggle Antenna\n");
1410
1411 if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
1412 tx_chains_num <= 1) ||
1413 (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
1414 tx_chains_num <= 2))
1415 break;
1416
1417 /* Don't change antenna if success has been great */
1418 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1419 break;
1420
1421 /* Set up search table to try other antenna */
1422 memcpy(search_tbl, tbl, sz);
1423
1424 if (rs_toggle_antenna(valid_tx_ant,
1425 &search_tbl->current_rate,
1426 search_tbl)) {
1427 update_search_tbl_counter = 1;
1428 rs_set_expected_tpt_table(lq_sta, search_tbl);
1429 goto out;
1430 }
1431 break;
1432 case IWL_LEGACY_SWITCH_SISO:
1433 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to SISO\n");
1434
1435 /* Set up search table to try SISO */
1436 memcpy(search_tbl, tbl, sz);
1437 search_tbl->is_SGI = 0;
1438 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1439 search_tbl, index);
1440 if (!ret) {
1441 lq_sta->action_counter = 0;
1442 goto out;
1443 }
1444
1445 break;
1446 case IWL_LEGACY_SWITCH_MIMO2_AB:
1447 case IWL_LEGACY_SWITCH_MIMO2_AC:
1448 case IWL_LEGACY_SWITCH_MIMO2_BC:
1449 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to MIMO2\n");
1450
1451 /* Set up search table to try MIMO */
1452 memcpy(search_tbl, tbl, sz);
1453 search_tbl->is_SGI = 0;
1454
1455 if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AB)
1456 search_tbl->ant_type = ANT_AB;
1457 else if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AC)
1458 search_tbl->ant_type = ANT_AC;
1459 else
1460 search_tbl->ant_type = ANT_BC;
1461
1462 if (!rs_is_valid_ant(valid_tx_ant,
1463 search_tbl->ant_type))
1464 break;
1465
1466 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1467 search_tbl, index);
1468 if (!ret) {
1469 lq_sta->action_counter = 0;
1470 goto out;
1471 }
1472 break;
1473
1474 case IWL_LEGACY_SWITCH_MIMO3_ABC:
1475 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to MIMO3\n");
1476
1477 /* Set up search table to try MIMO3 */
1478 memcpy(search_tbl, tbl, sz);
1479 search_tbl->is_SGI = 0;
1480
1481 search_tbl->ant_type = ANT_ABC;
1482
1483 if (!rs_is_valid_ant(valid_tx_ant,
1484 search_tbl->ant_type))
1485 break;
1486
1487 ret = rs_switch_to_mimo3(mvm, lq_sta, sta,
1488 search_tbl, index);
1489 if (!ret) {
1490 lq_sta->action_counter = 0;
1491 goto out;
1492 }
1493 break;
1494 }
1495 tbl->action++;
1496 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
1497 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1498
1499 if (tbl->action == start_action)
1500 break;
1501 }
1502 search_tbl->lq_type = LQ_NONE;
1503 return 0;
1504
1505out:
1506 lq_sta->search_better_tbl = 1;
1507 tbl->action++;
1508 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
1509 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1510 if (update_search_tbl_counter)
1511 search_tbl->action = tbl->action;
1512 return 0;
1513}
1514
1515/*
1516 * Try to switch to new modulation mode from SISO
1517 */
1518static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1519 struct iwl_lq_sta *lq_sta,
1520 struct ieee80211_sta *sta, int index)
1521{
1522 u8 is_green = lq_sta->is_green;
1523 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1524 struct iwl_scale_tbl_info *search_tbl =
1525 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1526 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1527 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1528 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1529 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1530 u8 start_action;
1531 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
1532 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1533 u8 update_search_tbl_counter = 0;
1534 int ret;
1535
1536 start_action = tbl->action;
1537 while (1) {
1538 lq_sta->action_counter++;
1539 switch (tbl->action) {
1540 case IWL_SISO_SWITCH_ANTENNA1:
1541 case IWL_SISO_SWITCH_ANTENNA2:
1542 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle Antenna\n");
1543 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
1544 tx_chains_num <= 1) ||
1545 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
1546 tx_chains_num <= 2))
1547 break;
1548
1549 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1550 break;
1551
1552 memcpy(search_tbl, tbl, sz);
1553 if (rs_toggle_antenna(valid_tx_ant,
1554 &search_tbl->current_rate,
1555 search_tbl)) {
1556 update_search_tbl_counter = 1;
1557 goto out;
1558 }
1559 break;
1560 case IWL_SISO_SWITCH_MIMO2_AB:
1561 case IWL_SISO_SWITCH_MIMO2_AC:
1562 case IWL_SISO_SWITCH_MIMO2_BC:
1563 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO2\n");
1564 memcpy(search_tbl, tbl, sz);
1565 search_tbl->is_SGI = 0;
1566
1567 if (tbl->action == IWL_SISO_SWITCH_MIMO2_AB)
1568 search_tbl->ant_type = ANT_AB;
1569 else if (tbl->action == IWL_SISO_SWITCH_MIMO2_AC)
1570 search_tbl->ant_type = ANT_AC;
1571 else
1572 search_tbl->ant_type = ANT_BC;
1573
1574 if (!rs_is_valid_ant(valid_tx_ant,
1575 search_tbl->ant_type))
1576 break;
1577
1578 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1579 search_tbl, index);
1580 if (!ret)
1581 goto out;
1582 break;
1583 case IWL_SISO_SWITCH_GI:
1584 if (!tbl->is_ht40 && !(ht_cap->cap &
1585 IEEE80211_HT_CAP_SGI_20))
1586 break;
1587 if (tbl->is_ht40 && !(ht_cap->cap &
1588 IEEE80211_HT_CAP_SGI_40))
1589 break;
1590
1591 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle SGI/NGI\n");
1592
1593 memcpy(search_tbl, tbl, sz);
1594 if (is_green) {
1595 if (!tbl->is_SGI)
1596 break;
1597 else
1598 IWL_ERR(mvm,
1599 "SGI was set in GF+SISO\n");
1600 }
1601 search_tbl->is_SGI = !tbl->is_SGI;
1602 rs_set_expected_tpt_table(lq_sta, search_tbl);
1603 if (tbl->is_SGI) {
1604 s32 tpt = lq_sta->last_tpt / 100;
1605 if (tpt >= search_tbl->expected_tpt[index])
1606 break;
1607 }
1608 search_tbl->current_rate =
1609 rate_n_flags_from_tbl(mvm, search_tbl,
1610 index, is_green);
1611 update_search_tbl_counter = 1;
1612 goto out;
1613 case IWL_SISO_SWITCH_MIMO3_ABC:
1614 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO3\n");
1615 memcpy(search_tbl, tbl, sz);
1616 search_tbl->is_SGI = 0;
1617 search_tbl->ant_type = ANT_ABC;
1618
1619 if (!rs_is_valid_ant(valid_tx_ant,
1620 search_tbl->ant_type))
1621 break;
1622
1623 ret = rs_switch_to_mimo3(mvm, lq_sta, sta,
1624 search_tbl, index);
1625 if (!ret)
1626 goto out;
1627 break;
1628 }
1629 tbl->action++;
1630 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
1631 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1632
1633 if (tbl->action == start_action)
1634 break;
1635 }
1636 search_tbl->lq_type = LQ_NONE;
1637 return 0;
1638
1639 out:
1640 lq_sta->search_better_tbl = 1;
1641 tbl->action++;
1642 if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC)
1643 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1644 if (update_search_tbl_counter)
1645 search_tbl->action = tbl->action;
1646
1647 return 0;
1648}
1649
1650/*
1651 * Try to switch to new modulation mode from MIMO2
1652 */
1653static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1654 struct iwl_lq_sta *lq_sta,
1655 struct ieee80211_sta *sta, int index)
1656{
1657 s8 is_green = lq_sta->is_green;
1658 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1659 struct iwl_scale_tbl_info *search_tbl =
1660 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1661 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1662 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1663 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1664 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1665 u8 start_action;
1666 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
1667 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1668 u8 update_search_tbl_counter = 0;
1669 int ret;
1670
1671 start_action = tbl->action;
1672 while (1) {
1673 lq_sta->action_counter++;
1674 switch (tbl->action) {
1675 case IWL_MIMO2_SWITCH_ANTENNA1:
1676 case IWL_MIMO2_SWITCH_ANTENNA2:
1677 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle Antennas\n");
1678
1679 if (tx_chains_num <= 2)
1680 break;
1681
1682 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1683 break;
1684
1685 memcpy(search_tbl, tbl, sz);
1686 if (rs_toggle_antenna(valid_tx_ant,
1687 &search_tbl->current_rate,
1688 search_tbl)) {
1689 update_search_tbl_counter = 1;
1690 goto out;
1691 }
1692 break;
1693 case IWL_MIMO2_SWITCH_SISO_A:
1694 case IWL_MIMO2_SWITCH_SISO_B:
1695 case IWL_MIMO2_SWITCH_SISO_C:
1696 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to SISO\n");
1697
1698 /* Set up new search table for SISO */
1699 memcpy(search_tbl, tbl, sz);
1700
1701 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)
1702 search_tbl->ant_type = ANT_A;
1703 else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)
1704 search_tbl->ant_type = ANT_B;
1705 else
1706 search_tbl->ant_type = ANT_C;
1707
1708 if (!rs_is_valid_ant(valid_tx_ant,
1709 search_tbl->ant_type))
1710 break;
1711
1712 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1713 search_tbl, index);
1714 if (!ret)
1715 goto out;
1716
1717 break;
1718
1719 case IWL_MIMO2_SWITCH_GI:
1720 if (!tbl->is_ht40 && !(ht_cap->cap &
1721 IEEE80211_HT_CAP_SGI_20))
1722 break;
1723 if (tbl->is_ht40 && !(ht_cap->cap &
1724 IEEE80211_HT_CAP_SGI_40))
1725 break;
1726
1727 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle SGI/NGI\n");
1728
1729 /* Set up new search table for MIMO2 */
1730 memcpy(search_tbl, tbl, sz);
1731 search_tbl->is_SGI = !tbl->is_SGI;
1732 rs_set_expected_tpt_table(lq_sta, search_tbl);
1733 /*
1734 * If active table already uses the fastest possible
1735 * modulation (dual stream with short guard interval),
1736 * and it's working well, there's no need to look
1737 * for a better type of modulation!
1738 */
1739 if (tbl->is_SGI) {
1740 s32 tpt = lq_sta->last_tpt / 100;
1741 if (tpt >= search_tbl->expected_tpt[index])
1742 break;
1743 }
1744 search_tbl->current_rate =
1745 rate_n_flags_from_tbl(mvm, search_tbl,
1746 index, is_green);
1747 update_search_tbl_counter = 1;
1748 goto out;
1749
1750 case IWL_MIMO2_SWITCH_MIMO3_ABC:
1751 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to MIMO3\n");
1752 memcpy(search_tbl, tbl, sz);
1753 search_tbl->is_SGI = 0;
1754 search_tbl->ant_type = ANT_ABC;
1755
1756 if (!rs_is_valid_ant(valid_tx_ant,
1757 search_tbl->ant_type))
1758 break;
1759
1760 ret = rs_switch_to_mimo3(mvm, lq_sta, sta,
1761 search_tbl, index);
1762 if (!ret)
1763 goto out;
1764
1765 break;
1766 }
1767 tbl->action++;
1768 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
1769 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1770
1771 if (tbl->action == start_action)
1772 break;
1773 }
1774 search_tbl->lq_type = LQ_NONE;
1775 return 0;
1776 out:
1777 lq_sta->search_better_tbl = 1;
1778 tbl->action++;
1779 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
1780 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1781 if (update_search_tbl_counter)
1782 search_tbl->action = tbl->action;
1783
1784 return 0;
1785}
1786
1787/*
1788 * Try to switch to new modulation mode from MIMO3
1789 */
1790static int rs_move_mimo3_to_other(struct iwl_mvm *mvm,
1791 struct iwl_lq_sta *lq_sta,
1792 struct ieee80211_sta *sta, int index)
1793{
1794 s8 is_green = lq_sta->is_green;
1795 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1796 struct iwl_scale_tbl_info *search_tbl =
1797 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1798 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1799 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1800 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1801 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1802 u8 start_action;
1803 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
1804 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1805 int ret;
1806 u8 update_search_tbl_counter = 0;
1807
1808 start_action = tbl->action;
1809 while (1) {
1810 lq_sta->action_counter++;
1811 switch (tbl->action) {
1812 case IWL_MIMO3_SWITCH_ANTENNA1:
1813 case IWL_MIMO3_SWITCH_ANTENNA2:
1814 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 toggle Antennas\n");
1815
1816 if (tx_chains_num <= 3)
1817 break;
1818
1819 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1820 break;
1821
1822 memcpy(search_tbl, tbl, sz);
1823 if (rs_toggle_antenna(valid_tx_ant,
1824 &search_tbl->current_rate,
1825 search_tbl))
1826 goto out;
1827 break;
1828 case IWL_MIMO3_SWITCH_SISO_A:
1829 case IWL_MIMO3_SWITCH_SISO_B:
1830 case IWL_MIMO3_SWITCH_SISO_C:
1831 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 switch to SISO\n");
1832
1833 /* Set up new search table for SISO */
1834 memcpy(search_tbl, tbl, sz);
1835
1836 if (tbl->action == IWL_MIMO3_SWITCH_SISO_A)
1837 search_tbl->ant_type = ANT_A;
1838 else if (tbl->action == IWL_MIMO3_SWITCH_SISO_B)
1839 search_tbl->ant_type = ANT_B;
1840 else
1841 search_tbl->ant_type = ANT_C;
1842
1843 if (!rs_is_valid_ant(valid_tx_ant,
1844 search_tbl->ant_type))
1845 break;
1846
1847 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1848 search_tbl, index);
1849 if (!ret)
1850 goto out;
1851
1852 break;
1853
1854 case IWL_MIMO3_SWITCH_MIMO2_AB:
1855 case IWL_MIMO3_SWITCH_MIMO2_AC:
1856 case IWL_MIMO3_SWITCH_MIMO2_BC:
1857 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 switch to MIMO2\n");
1858
1859 memcpy(search_tbl, tbl, sz);
1860 search_tbl->is_SGI = 0;
1861 if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB)
1862 search_tbl->ant_type = ANT_AB;
1863 else if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC)
1864 search_tbl->ant_type = ANT_AC;
1865 else
1866 search_tbl->ant_type = ANT_BC;
1867
1868 if (!rs_is_valid_ant(valid_tx_ant,
1869 search_tbl->ant_type))
1870 break;
1871
1872 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1873 search_tbl, index);
1874 if (!ret)
1875 goto out;
1876
1877 break;
1878
1879 case IWL_MIMO3_SWITCH_GI:
1880 if (!tbl->is_ht40 && !(ht_cap->cap &
1881 IEEE80211_HT_CAP_SGI_20))
1882 break;
1883 if (tbl->is_ht40 && !(ht_cap->cap &
1884 IEEE80211_HT_CAP_SGI_40))
1885 break;
1886
1887 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 toggle SGI/NGI\n");
1888
1889 /* Set up new search table for MIMO */
1890 memcpy(search_tbl, tbl, sz);
1891 search_tbl->is_SGI = !tbl->is_SGI;
1892 rs_set_expected_tpt_table(lq_sta, search_tbl);
1893 /*
1894 * If active table already uses the fastest possible
1895 * modulation (dual stream with short guard interval),
1896 * and it's working well, there's no need to look
1897 * for a better type of modulation!
1898 */
1899 if (tbl->is_SGI) {
1900 s32 tpt = lq_sta->last_tpt / 100;
1901 if (tpt >= search_tbl->expected_tpt[index])
1902 break;
1903 }
1904 search_tbl->current_rate =
1905 rate_n_flags_from_tbl(mvm, search_tbl,
1906 index, is_green);
1907 update_search_tbl_counter = 1;
1908 goto out;
1909 }
1910 tbl->action++;
1911 if (tbl->action > IWL_MIMO3_SWITCH_GI)
1912 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
1913
1914 if (tbl->action == start_action)
1915 break;
1916 }
1917 search_tbl->lq_type = LQ_NONE;
1918 return 0;
1919 out:
1920 lq_sta->search_better_tbl = 1;
1921 tbl->action++;
1922 if (tbl->action > IWL_MIMO3_SWITCH_GI)
1923 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
1924 if (update_search_tbl_counter)
1925 search_tbl->action = tbl->action;
1926
1927 return 0;
1928}
1929
1930/*
1931 * Check whether we should continue using same modulation mode, or
1932 * begin search for a new mode, based on:
1933 * 1) # tx successes or failures while using this mode
1934 * 2) # times calling this function
1935 * 3) elapsed time in this mode (not used, for now)
1936 */
1937static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1938{
1939 struct iwl_scale_tbl_info *tbl;
1940 int i;
1941 int active_tbl;
1942 int flush_interval_passed = 0;
1943 struct iwl_mvm *mvm;
1944
1945 mvm = lq_sta->drv;
1946 active_tbl = lq_sta->active_tbl;
1947
1948 tbl = &(lq_sta->lq_info[active_tbl]);
1949
1950 /* If we've been disallowing search, see if we should now allow it */
1951 if (lq_sta->stay_in_tbl) {
1952 /* Elapsed time using current modulation mode */
1953 if (lq_sta->flush_timer)
1954 flush_interval_passed =
1955 time_after(jiffies,
1956 (unsigned long)(lq_sta->flush_timer +
1957 IWL_RATE_SCALE_FLUSH_INTVL));
1958
1959 /*
1960 * Check if we should allow search for new modulation mode.
1961 * If many frames have failed or succeeded, or we've used
1962 * this same modulation for a long time, allow search, and
1963 * reset history stats that keep track of whether we should
1964 * allow a new search. Also (below) reset all bitmaps and
1965 * stats in active history.
1966 */
1967 if (force_search ||
1968 (lq_sta->total_failed > lq_sta->max_failure_limit) ||
1969 (lq_sta->total_success > lq_sta->max_success_limit) ||
1970 ((!lq_sta->search_better_tbl) &&
1971 (lq_sta->flush_timer) && (flush_interval_passed))) {
1972 IWL_DEBUG_RATE(mvm,
1973 "LQ: stay is expired %d %d %d\n",
1974 lq_sta->total_failed,
1975 lq_sta->total_success,
1976 flush_interval_passed);
1977
1978 /* Allow search for new mode */
1979 lq_sta->stay_in_tbl = 0; /* only place reset */
1980 lq_sta->total_failed = 0;
1981 lq_sta->total_success = 0;
1982 lq_sta->flush_timer = 0;
1983 /*
1984 * Else if we've used this modulation mode enough repetitions
1985 * (regardless of elapsed time or success/failure), reset
1986 * history bitmaps and rate-specific stats for all rates in
1987 * active table.
1988 */
1989 } else {
1990 lq_sta->table_count++;
1991 if (lq_sta->table_count >=
1992 lq_sta->table_count_limit) {
1993 lq_sta->table_count = 0;
1994
1995 IWL_DEBUG_RATE(mvm,
1996 "LQ: stay in table clear win\n");
1997 for (i = 0; i < IWL_RATE_COUNT; i++)
1998 rs_rate_scale_clear_window(
1999 &(tbl->win[i]));
2000 }
2001 }
2002
2003 /* If transitioning to allow "search", reset all history
2004 * bitmaps and stats in active table (this will become the new
2005 * "search" table). */
2006 if (!lq_sta->stay_in_tbl) {
2007 for (i = 0; i < IWL_RATE_COUNT; i++)
2008 rs_rate_scale_clear_window(&(tbl->win[i]));
2009 }
2010 }
2011}
2012
2013/*
2014 * setup rate table in uCode
2015 */
2016static void rs_update_rate_tbl(struct iwl_mvm *mvm,
2017 struct iwl_lq_sta *lq_sta,
2018 struct iwl_scale_tbl_info *tbl,
2019 int index, u8 is_green)
2020{
2021 u32 rate;
2022
2023 /* Update uCode's rate table. */
2024 rate = rate_n_flags_from_tbl(mvm, tbl, index, is_green);
2025 rs_fill_link_cmd(mvm, lq_sta, rate);
2026 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
2027}
2028
2029/*
2030 * Do rate scaling and search for new modulation mode.
2031 */
2032static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2033 struct sk_buff *skb,
2034 struct ieee80211_sta *sta,
2035 struct iwl_lq_sta *lq_sta)
2036{
2037 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2038 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2039 int low = IWL_RATE_INVALID;
2040 int high = IWL_RATE_INVALID;
2041 int index;
2042 int i;
2043 struct iwl_rate_scale_data *window = NULL;
2044 int current_tpt = IWL_INVALID_VALUE;
2045 int low_tpt = IWL_INVALID_VALUE;
2046 int high_tpt = IWL_INVALID_VALUE;
2047 u32 fail_count;
2048 s8 scale_action = 0;
2049 u16 rate_mask;
2050 u8 update_lq = 0;
2051 struct iwl_scale_tbl_info *tbl, *tbl1;
2052 u16 rate_scale_index_msk = 0;
2053 u8 is_green = 0;
2054 u8 active_tbl = 0;
2055 u8 done_search = 0;
2056 u16 high_low;
2057 s32 sr;
2058 u8 tid = IWL_MAX_TID_COUNT;
2059 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;
2060 struct iwl_mvm_tid_data *tid_data;
2061
2062 IWL_DEBUG_RATE(mvm, "rate scale calculate new rate for skb\n");
2063
2064 /* Send management frames and NO_ACK data using lowest rate. */
2065 /* TODO: this could probably be improved.. */
2066 if (!ieee80211_is_data(hdr->frame_control) ||
2067 info->flags & IEEE80211_TX_CTL_NO_ACK)
2068 return;
2069
2070 lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
2071
2072 tid = rs_tl_add_packet(lq_sta, hdr);
2073 if ((tid != IWL_MAX_TID_COUNT) &&
2074 (lq_sta->tx_agg_tid_en & (1 << tid))) {
2075 tid_data = &sta_priv->tid_data[tid];
2076 if (tid_data->state == IWL_AGG_OFF)
2077 lq_sta->is_agg = 0;
2078 else
2079 lq_sta->is_agg = 1;
2080 } else {
2081 lq_sta->is_agg = 0;
2082 }
2083
2084 /*
2085 * Select rate-scale / modulation-mode table to work with in
2086 * the rest of this function: "search" if searching for better
2087 * modulation mode, or "active" if doing rate scaling within a mode.
2088 */
2089 if (!lq_sta->search_better_tbl)
2090 active_tbl = lq_sta->active_tbl;
2091 else
2092 active_tbl = 1 - lq_sta->active_tbl;
2093
2094 tbl = &(lq_sta->lq_info[active_tbl]);
2095 if (is_legacy(tbl->lq_type))
2096 lq_sta->is_green = 0;
2097 else
2098 lq_sta->is_green = rs_use_green(sta);
2099 is_green = lq_sta->is_green;
2100
2101 /* current tx rate */
2102 index = lq_sta->last_txrate_idx;
2103
2104 IWL_DEBUG_RATE(mvm, "Rate scale index %d for type %d\n", index,
2105 tbl->lq_type);
2106
2107 /* rates available for this association, and for modulation mode */
2108 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type);
2109
2110 IWL_DEBUG_RATE(mvm, "mask 0x%04X\n", rate_mask);
2111
2112 /* mask with station rate restriction */
2113 if (is_legacy(tbl->lq_type)) {
2114 if (lq_sta->band == IEEE80211_BAND_5GHZ)
2115 /* supp_rates has no CCK bits in A mode */
2116 rate_scale_index_msk = (u16) (rate_mask &
2117 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
2118 else
2119 rate_scale_index_msk = (u16) (rate_mask &
2120 lq_sta->supp_rates);
2121
2122 } else {
2123 rate_scale_index_msk = rate_mask;
2124 }
2125
2126 if (!rate_scale_index_msk)
2127 rate_scale_index_msk = rate_mask;
2128
2129 if (!((1 << index) & rate_scale_index_msk)) {
2130 IWL_ERR(mvm, "Current Rate is not valid\n");
2131 if (lq_sta->search_better_tbl) {
2132 /* revert to active table if search table is not valid*/
2133 tbl->lq_type = LQ_NONE;
2134 lq_sta->search_better_tbl = 0;
2135 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2136 /* get "active" rate info */
2137 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2138 rs_update_rate_tbl(mvm, lq_sta, tbl, index, is_green);
2139 }
2140 return;
2141 }
2142
2143 /* Get expected throughput table and history window for current rate */
2144 if (!tbl->expected_tpt) {
2145 IWL_ERR(mvm, "tbl->expected_tpt is NULL\n");
2146 return;
2147 }
2148
2149 /* force user max rate if set by user */
2150 if ((lq_sta->max_rate_idx != -1) &&
2151 (lq_sta->max_rate_idx < index)) {
2152 index = lq_sta->max_rate_idx;
2153 update_lq = 1;
2154 window = &(tbl->win[index]);
2155 goto lq_update;
2156 }
2157
2158 window = &(tbl->win[index]);
2159
2160 /*
2161 * If there is not enough history to calculate actual average
2162 * throughput, keep analyzing results of more tx frames, without
2163 * changing rate or mode (bypass most of the rest of this function).
2164 * Set up new rate table in uCode only if old rate is not supported
2165 * in current association (use new rate found above).
2166 */
2167 fail_count = window->counter - window->success_counter;
2168 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
2169 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
2170 IWL_DEBUG_RATE(mvm,
2171 "LQ: still below TH. succ=%d total=%d for index %d\n",
2172 window->success_counter, window->counter, index);
2173
2174 /* Can't calculate this yet; not enough history */
2175 window->average_tpt = IWL_INVALID_VALUE;
2176
2177 /* Should we stay with this modulation mode,
2178 * or search for a new one? */
2179 rs_stay_in_table(lq_sta, false);
2180
2181 goto out;
2182 }
2183 /* Else we have enough samples; calculate estimate of
2184 * actual average throughput */
2185 if (window->average_tpt != ((window->success_ratio *
2186 tbl->expected_tpt[index] + 64) / 128)) {
2187 IWL_ERR(mvm,
2188 "expected_tpt should have been calculated by now\n");
2189 window->average_tpt = ((window->success_ratio *
2190 tbl->expected_tpt[index] + 64) / 128);
2191 }
2192
2193 /* If we are searching for better modulation mode, check success. */
2194 if (lq_sta->search_better_tbl) {
2195 /* If good success, continue using the "search" mode;
2196 * no need to send new link quality command, since we're
2197 * continuing to use the setup that we've been trying. */
2198 if (window->average_tpt > lq_sta->last_tpt) {
2199 IWL_DEBUG_RATE(mvm,
2200 "LQ: SWITCHING TO NEW TABLE suc=%d cur-tpt=%d old-tpt=%d\n",
2201 window->success_ratio,
2202 window->average_tpt,
2203 lq_sta->last_tpt);
2204
2205 if (!is_legacy(tbl->lq_type))
2206 lq_sta->enable_counter = 1;
2207
2208 /* Swap tables; "search" becomes "active" */
2209 lq_sta->active_tbl = active_tbl;
2210 current_tpt = window->average_tpt;
2211 /* Else poor success; go back to mode in "active" table */
2212 } else {
2213 IWL_DEBUG_RATE(mvm,
2214 "LQ: GOING BACK TO THE OLD TABLE suc=%d cur-tpt=%d old-tpt=%d\n",
2215 window->success_ratio,
2216 window->average_tpt,
2217 lq_sta->last_tpt);
2218
2219 /* Nullify "search" table */
2220 tbl->lq_type = LQ_NONE;
2221
2222 /* Revert to "active" table */
2223 active_tbl = lq_sta->active_tbl;
2224 tbl = &(lq_sta->lq_info[active_tbl]);
2225
2226 /* Revert to "active" rate and throughput info */
2227 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2228 current_tpt = lq_sta->last_tpt;
2229
2230 /* Need to set up a new rate table in uCode */
2231 update_lq = 1;
2232 }
2233
2234 /* Either way, we've made a decision; modulation mode
2235 * search is done, allow rate adjustment next time. */
2236 lq_sta->search_better_tbl = 0;
2237 done_search = 1; /* Don't switch modes below! */
2238 goto lq_update;
2239 }
2240
2241 /* (Else) not in search of better modulation mode, try for better
2242 * starting rate, while staying in this mode. */
2243 high_low = rs_get_adjacent_rate(mvm, index, rate_scale_index_msk,
2244 tbl->lq_type);
2245 low = high_low & 0xff;
2246 high = (high_low >> 8) & 0xff;
2247
2248 /* If user set max rate, dont allow higher than user constrain */
2249 if ((lq_sta->max_rate_idx != -1) &&
2250 (lq_sta->max_rate_idx < high))
2251 high = IWL_RATE_INVALID;
2252
2253 sr = window->success_ratio;
2254
2255 /* Collect measured throughputs for current and adjacent rates */
2256 current_tpt = window->average_tpt;
2257 if (low != IWL_RATE_INVALID)
2258 low_tpt = tbl->win[low].average_tpt;
2259 if (high != IWL_RATE_INVALID)
2260 high_tpt = tbl->win[high].average_tpt;
2261
2262 scale_action = 0;
2263
2264 /* Too many failures, decrease rate */
2265 if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) {
2266 IWL_DEBUG_RATE(mvm,
2267 "decrease rate because of low success_ratio\n");
2268 scale_action = -1;
2269 /* No throughput measured yet for adjacent rates; try increase. */
2270 } else if ((low_tpt == IWL_INVALID_VALUE) &&
2271 (high_tpt == IWL_INVALID_VALUE)) {
2272 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
2273 scale_action = 1;
2274 else if (low != IWL_RATE_INVALID)
2275 scale_action = 0;
2276 }
2277
2278 /* Both adjacent throughputs are measured, but neither one has better
2279 * throughput; we're using the best rate, don't change it! */
2280 else if ((low_tpt != IWL_INVALID_VALUE) &&
2281 (high_tpt != IWL_INVALID_VALUE) &&
2282 (low_tpt < current_tpt) &&
2283 (high_tpt < current_tpt))
2284 scale_action = 0;
2285
2286 /* At least one adjacent rate's throughput is measured,
2287 * and may have better performance. */
2288 else {
2289 /* Higher adjacent rate's throughput is measured */
2290 if (high_tpt != IWL_INVALID_VALUE) {
2291 /* Higher rate has better throughput */
2292 if (high_tpt > current_tpt &&
2293 sr >= IWL_RATE_INCREASE_TH) {
2294 scale_action = 1;
2295 } else {
2296 scale_action = 0;
2297 }
2298
2299 /* Lower adjacent rate's throughput is measured */
2300 } else if (low_tpt != IWL_INVALID_VALUE) {
2301 /* Lower rate has better throughput */
2302 if (low_tpt > current_tpt) {
2303 IWL_DEBUG_RATE(mvm,
2304 "decrease rate because of low tpt\n");
2305 scale_action = -1;
2306 } else if (sr >= IWL_RATE_INCREASE_TH) {
2307 scale_action = 1;
2308 }
2309 }
2310 }
2311
2312 /* Sanity check; asked for decrease, but success rate or throughput
2313 * has been good at old rate. Don't change it. */
2314 if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
2315 ((sr > IWL_RATE_HIGH_TH) ||
2316 (current_tpt > (100 * tbl->expected_tpt[low]))))
2317 scale_action = 0;
2318
2319 switch (scale_action) {
2320 case -1:
2321 /* Decrease starting rate, update uCode's rate table */
2322 if (low != IWL_RATE_INVALID) {
2323 update_lq = 1;
2324 index = low;
2325 }
2326
2327 break;
2328 case 1:
2329 /* Increase starting rate, update uCode's rate table */
2330 if (high != IWL_RATE_INVALID) {
2331 update_lq = 1;
2332 index = high;
2333 }
2334
2335 break;
2336 case 0:
2337 /* No change */
2338 default:
2339 break;
2340 }
2341
2342 IWL_DEBUG_RATE(mvm,
2343 "choose rate scale index %d action %d low %d high %d type %d\n",
2344 index, scale_action, low, high, tbl->lq_type);
2345
2346lq_update:
2347 /* Replace uCode's rate table for the destination station. */
2348 if (update_lq)
2349 rs_update_rate_tbl(mvm, lq_sta, tbl, index, is_green);
2350
2351 rs_stay_in_table(lq_sta, false);
2352
2353 /*
2354 * Search for new modulation mode if we're:
2355 * 1) Not changing rates right now
2356 * 2) Not just finishing up a search
2357 * 3) Allowing a new search
2358 */
2359 if (!update_lq && !done_search &&
2360 !lq_sta->stay_in_tbl && window->counter) {
2361 /* Save current throughput to compare with "search" throughput*/
2362 lq_sta->last_tpt = current_tpt;
2363
2364 /* Select a new "search" modulation mode to try.
2365 * If one is found, set up the new "search" table. */
2366 if (is_legacy(tbl->lq_type))
2367 rs_move_legacy_other(mvm, lq_sta, sta, index);
2368 else if (is_siso(tbl->lq_type))
2369 rs_move_siso_to_other(mvm, lq_sta, sta, index);
2370 else if (is_mimo2(tbl->lq_type))
2371 rs_move_mimo2_to_other(mvm, lq_sta, sta, index);
2372 else
2373 rs_move_mimo3_to_other(mvm, lq_sta, sta, index);
2374
2375 /* If new "search" mode was selected, set up in uCode table */
2376 if (lq_sta->search_better_tbl) {
2377 /* Access the "search" table, clear its history. */
2378 tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
2379 for (i = 0; i < IWL_RATE_COUNT; i++)
2380 rs_rate_scale_clear_window(&(tbl->win[i]));
2381
2382 /* Use new "search" start rate */
2383 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2384
2385 IWL_DEBUG_RATE(mvm,
2386 "Switch current mcs: %X index: %d\n",
2387 tbl->current_rate, index);
2388 rs_fill_link_cmd(mvm, lq_sta, tbl->current_rate);
2389 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
2390 } else {
2391 done_search = 1;
2392 }
2393 }
2394
2395 if (done_search && !lq_sta->stay_in_tbl) {
2396 /* If the "active" (non-search) mode was legacy,
2397 * and we've tried switching antennas,
2398 * but we haven't been able to try HT modes (not available),
2399 * stay with best antenna legacy modulation for a while
2400 * before next round of mode comparisons. */
2401 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
2402 if (is_legacy(tbl1->lq_type) && !sta->ht_cap.ht_supported &&
2403 lq_sta->action_counter > tbl1->max_search) {
2404 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
2405 rs_set_stay_in_table(mvm, 1, lq_sta);
2406 }
2407
2408 /* If we're in an HT mode, and all 3 mode switch actions
2409 * have been tried and compared, stay in this best modulation
2410 * mode for a while before next round of mode comparisons. */
2411 if (lq_sta->enable_counter &&
2412 (lq_sta->action_counter >= tbl1->max_search)) {
2413 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
2414 (lq_sta->tx_agg_tid_en & (1 << tid)) &&
2415 (tid != IWL_MAX_TID_COUNT)) {
2416 tid_data = &sta_priv->tid_data[tid];
2417 if (tid_data->state == IWL_AGG_OFF) {
2418 IWL_DEBUG_RATE(mvm,
2419 "try to aggregate tid %d\n",
2420 tid);
2421 rs_tl_turn_on_agg(mvm, tid,
2422 lq_sta, sta);
2423 }
2424 }
2425 rs_set_stay_in_table(mvm, 0, lq_sta);
2426 }
2427 }
2428
2429out:
2430 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, index, is_green);
2431 lq_sta->last_txrate_idx = index;
2432}
2433
2434/**
2435 * rs_initialize_lq - Initialize a station's hardware rate table
2436 *
2437 * The uCode's station table contains a table of fallback rates
2438 * for automatic fallback during transmission.
2439 *
2440 * NOTE: This sets up a default set of values. These will be replaced later
2441 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
2442 * rc80211_simple.
2443 *
2444 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
2445 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
2446 * which requires station table entry to exist).
2447 */
2448static void rs_initialize_lq(struct iwl_mvm *mvm,
2449 struct ieee80211_sta *sta,
2450 struct iwl_lq_sta *lq_sta,
2451 enum ieee80211_band band)
2452{
2453 struct iwl_scale_tbl_info *tbl;
2454 int rate_idx;
2455 int i;
2456 u32 rate;
2457 u8 use_green = rs_use_green(sta);
2458 u8 active_tbl = 0;
2459 u8 valid_tx_ant;
2460
2461 if (!sta || !lq_sta)
2462 return;
2463
2464 i = lq_sta->last_txrate_idx;
2465
2466 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
2467
2468 if (!lq_sta->search_better_tbl)
2469 active_tbl = lq_sta->active_tbl;
2470 else
2471 active_tbl = 1 - lq_sta->active_tbl;
2472
2473 tbl = &(lq_sta->lq_info[active_tbl]);
2474
2475 if ((i < 0) || (i >= IWL_RATE_COUNT))
2476 i = 0;
2477
2478 rate = iwl_rates[i].plcp;
2479 tbl->ant_type = first_antenna(valid_tx_ant);
2480 rate |= tbl->ant_type << RATE_MCS_ANT_POS;
2481
2482 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)
2483 rate |= RATE_MCS_CCK_MSK;
2484
2485 rs_get_tbl_info_from_mcs(rate, band, tbl, &rate_idx);
2486 if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))
2487 rs_toggle_antenna(valid_tx_ant, &rate, tbl);
2488
2489 rate = rate_n_flags_from_tbl(mvm, tbl, rate_idx, use_green);
2490 tbl->current_rate = rate;
2491 rs_set_expected_tpt_table(lq_sta, tbl);
2492 rs_fill_link_cmd(NULL, lq_sta, rate);
2493 /* TODO restore station should remember the lq cmd */
2494 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_SYNC, true);
2495}
2496
2497static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
2498 struct ieee80211_tx_rate_control *txrc)
2499{
2500 struct sk_buff *skb = txrc->skb;
2501 struct ieee80211_supported_band *sband = txrc->sband;
2502 struct iwl_op_mode *op_mode __maybe_unused =
2503 (struct iwl_op_mode *)mvm_r;
2504 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
2505 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2506 struct iwl_lq_sta *lq_sta = mvm_sta;
2507 int rate_idx;
2508
2509 IWL_DEBUG_RATE_LIMIT(mvm, "rate scale calculate new rate for skb\n");
2510
2511 /* Get max rate if user set max rate */
2512 if (lq_sta) {
2513 lq_sta->max_rate_idx = txrc->max_rate_idx;
2514 if ((sband->band == IEEE80211_BAND_5GHZ) &&
2515 (lq_sta->max_rate_idx != -1))
2516 lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;
2517 if ((lq_sta->max_rate_idx < 0) ||
2518 (lq_sta->max_rate_idx >= IWL_RATE_COUNT))
2519 lq_sta->max_rate_idx = -1;
2520 }
2521
2522 /* Treat uninitialized rate scaling data same as non-existing. */
2523 if (lq_sta && !lq_sta->drv) {
2524 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
2525 mvm_sta = NULL;
2526 }
2527
2528 /* Send management frames and NO_ACK data using lowest rate. */
2529 if (rate_control_send_low(sta, mvm_sta, txrc))
2530 return;
2531
2532 rate_idx = lq_sta->last_txrate_idx;
2533
2534 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
2535 rate_idx -= IWL_FIRST_OFDM_RATE;
2536 /* 6M and 9M shared same MCS index */
2537 rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0;
2538 if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2539 IWL_RATE_MIMO3_6M_PLCP)
2540 rate_idx = rate_idx + (2 * MCS_INDEX_PER_STREAM);
2541 else if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2542 IWL_RATE_MIMO2_6M_PLCP)
2543 rate_idx = rate_idx + MCS_INDEX_PER_STREAM;
2544 info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
2545 if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK)
2546 info->control.rates[0].flags |= IEEE80211_TX_RC_SHORT_GI;
2547 if (lq_sta->last_rate_n_flags & RATE_MCS_CHAN_WIDTH_40) /* TODO */
2548 info->control.rates[0].flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
2549 if (lq_sta->last_rate_n_flags & RATE_HT_MCS_GF_MSK)
2550 info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD;
2551 } else {
2552 /* Check for invalid rates */
2553 if ((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT_LEGACY) ||
2554 ((sband->band == IEEE80211_BAND_5GHZ) &&
2555 (rate_idx < IWL_FIRST_OFDM_RATE)))
2556 rate_idx = rate_lowest_index(sband, sta);
2557 /* On valid 5 GHz rate, adjust index */
2558 else if (sband->band == IEEE80211_BAND_5GHZ)
2559 rate_idx -= IWL_FIRST_OFDM_RATE;
2560 info->control.rates[0].flags = 0;
2561 }
2562 info->control.rates[0].idx = rate_idx;
2563}
2564
2565static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
2566 gfp_t gfp)
2567{
2568 struct iwl_mvm_sta *sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
2569 struct iwl_op_mode *op_mode __maybe_unused =
2570 (struct iwl_op_mode *)mvm_rate;
2571 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
2572
2573 IWL_DEBUG_RATE(mvm, "create station rate scale window\n");
2574
2575 return &sta_priv->lq_sta;
2576}
2577
2578/*
2579 * Called after adding a new station to initialize rate scaling
2580 */
2581void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2582 enum ieee80211_band band)
2583{
2584 int i, j;
2585 struct ieee80211_hw *hw = mvm->hw;
2586 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2587 struct iwl_mvm_sta *sta_priv;
2588 struct iwl_lq_sta *lq_sta;
2589 struct ieee80211_supported_band *sband;
2590 unsigned long supp; /* must be unsigned long for for_each_set_bit */
2591
2592 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
2593 lq_sta = &sta_priv->lq_sta;
2594 sband = hw->wiphy->bands[band];
2595
2596 lq_sta->lq.sta_id = sta_priv->sta_id;
2597
2598 for (j = 0; j < LQ_SIZE; j++)
2599 for (i = 0; i < IWL_RATE_COUNT; i++)
2600 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2601
2602 lq_sta->flush_timer = 0;
2603 lq_sta->supp_rates = sta->supp_rates[sband->band];
2604 for (j = 0; j < LQ_SIZE; j++)
2605 for (i = 0; i < IWL_RATE_COUNT; i++)
2606 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2607
2608 IWL_DEBUG_RATE(mvm,
2609 "LQ: *** rate scale station global init for station %d ***\n",
2610 sta_priv->sta_id);
2611 /* TODO: what is a good starting rate for STA? About middle? Maybe not
2612 * the lowest or the highest rate.. Could consider using RSSI from
2613 * previous packets? Need to have IEEE 802.1X auth succeed immediately
2614 * after assoc.. */
2615
2616 lq_sta->max_rate_idx = -1;
2617 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2618 lq_sta->is_green = rs_use_green(sta);
2619 lq_sta->band = sband->band;
2620 /*
2621 * active legacy rates as per supported rates bitmap
2622 */
2623 supp = sta->supp_rates[sband->band];
2624 lq_sta->active_legacy_rate = 0;
2625 for_each_set_bit(i, &supp, BITS_PER_LONG)
2626 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value);
2627
2628 /*
2629 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
2630 * supp_rates[] does not; shift to convert format, force 9 MBits off.
2631 */
2632 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
2633 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
2634 lq_sta->active_siso_rate &= ~((u16)0x2);
2635 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
2636
2637 /* Same here */
2638 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
2639 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
2640 lq_sta->active_mimo2_rate &= ~((u16)0x2);
2641 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2642
2643 lq_sta->active_mimo3_rate = ht_cap->mcs.rx_mask[2] << 1;
2644 lq_sta->active_mimo3_rate |= ht_cap->mcs.rx_mask[2] & 0x1;
2645 lq_sta->active_mimo3_rate &= ~((u16)0x2);
2646 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
2647
2648 IWL_DEBUG_RATE(mvm,
2649 "SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
2650 lq_sta->active_siso_rate,
2651 lq_sta->active_mimo2_rate,
2652 lq_sta->active_mimo3_rate);
2653
2654 /* These values will be overridden later */
2655 lq_sta->lq.single_stream_ant_msk =
2656 first_antenna(mvm->nvm_data->valid_tx_ant);
2657 lq_sta->lq.dual_stream_ant_msk =
2658 mvm->nvm_data->valid_tx_ant &
2659 ~first_antenna(mvm->nvm_data->valid_tx_ant);
2660 if (!lq_sta->lq.dual_stream_ant_msk) {
2661 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2662 } else if (num_of_ant(mvm->nvm_data->valid_tx_ant) == 2) {
2663 lq_sta->lq.dual_stream_ant_msk =
2664 mvm->nvm_data->valid_tx_ant;
2665 }
2666
2667 /* as default allow aggregation for all tids */
2668 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
2669 lq_sta->drv = mvm;
2670
2671 /* Set last_txrate_idx to lowest rate */
2672 lq_sta->last_txrate_idx = rate_lowest_index(sband, sta);
2673 if (sband->band == IEEE80211_BAND_5GHZ)
2674 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2675 lq_sta->is_agg = 0;
2676#ifdef CONFIG_MAC80211_DEBUGFS
2677 lq_sta->dbg_fixed_rate = 0;
2678#endif
2679
2680 rs_initialize_lq(mvm, sta, lq_sta, band);
2681}
2682
2683static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2684 struct iwl_lq_sta *lq_sta, u32 new_rate)
2685{
2686 struct iwl_scale_tbl_info tbl_type;
2687 int index = 0;
2688 int rate_idx;
2689 int repeat_rate = 0;
2690 u8 ant_toggle_cnt = 0;
2691 u8 use_ht_possible = 1;
2692 u8 valid_tx_ant = 0;
2693 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
2694
2695 /* Override starting rate (index 0) if needed for debug purposes */
2696 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
2697
2698 /* Interpret new_rate (rate_n_flags) */
2699 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
2700 &tbl_type, &rate_idx);
2701
2702 /* How many times should we repeat the initial rate? */
2703 if (is_legacy(tbl_type.lq_type)) {
2704 ant_toggle_cnt = 1;
2705 repeat_rate = IWL_NUMBER_TRY;
2706 } else {
2707 repeat_rate = min(IWL_HT_NUMBER_TRY,
2708 LINK_QUAL_AGG_DISABLE_START_DEF - 1);
2709 }
2710
2711 lq_cmd->mimo_delim = is_mimo(tbl_type.lq_type) ? 1 : 0;
2712
2713 /* Fill 1st table entry (index 0) */
2714 lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
2715
2716 if (num_of_ant(tbl_type.ant_type) == 1)
2717 lq_cmd->single_stream_ant_msk = tbl_type.ant_type;
2718 else if (num_of_ant(tbl_type.ant_type) == 2)
2719 lq_cmd->dual_stream_ant_msk = tbl_type.ant_type;
2720 /* otherwise we don't modify the existing value */
2721
2722 index++;
2723 repeat_rate--;
2724 if (mvm)
2725 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
2726
2727 /* Fill rest of rate table */
2728 while (index < LINK_QUAL_MAX_RETRY_NUM) {
2729 /* Repeat initial/next rate.
2730 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
2731 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
2732 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
2733 if (is_legacy(tbl_type.lq_type)) {
2734 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2735 ant_toggle_cnt++;
2736 else if (mvm &&
2737 rs_toggle_antenna(valid_tx_ant,
2738 &new_rate, &tbl_type))
2739 ant_toggle_cnt = 1;
2740 }
2741
2742 /* Override next rate if needed for debug purposes */
2743 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
2744
2745 /* Fill next table entry */
2746 lq_cmd->rs_table[index] =
2747 cpu_to_le32(new_rate);
2748 repeat_rate--;
2749 index++;
2750 }
2751
2752 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
2753 &rate_idx);
2754
2755
2756 /* Indicate to uCode which entries might be MIMO.
2757 * If initial rate was MIMO, this will finally end up
2758 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
2759 if (is_mimo(tbl_type.lq_type))
2760 lq_cmd->mimo_delim = index;
2761
2762 /* Get next rate */
2763 new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
2764 use_ht_possible);
2765
2766 /* How many times should we repeat the next rate? */
2767 if (is_legacy(tbl_type.lq_type)) {
2768 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2769 ant_toggle_cnt++;
2770 else if (mvm &&
2771 rs_toggle_antenna(valid_tx_ant,
2772 &new_rate, &tbl_type))
2773 ant_toggle_cnt = 1;
2774
2775 repeat_rate = IWL_NUMBER_TRY;
2776 } else {
2777 repeat_rate = IWL_HT_NUMBER_TRY;
2778 }
2779
2780 /* Don't allow HT rates after next pass.
2781 * rs_get_lower_rate() will change type to LQ_A or LQ_G. */
2782 use_ht_possible = 0;
2783
2784 /* Override next rate if needed for debug purposes */
2785 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
2786
2787 /* Fill next table entry */
2788 lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
2789
2790 index++;
2791 repeat_rate--;
2792 }
2793
2794 lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
2795 lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
2796
2797 lq_cmd->agg_time_limit =
2798 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
2799}
2800
2801static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
2802{
2803 return hw->priv;
2804}
2805/* rate scale requires free function to be implemented */
2806static void rs_free(void *mvm_rate)
2807{
2808 return;
2809}
2810
2811static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta,
2812 void *mvm_sta)
2813{
2814 struct iwl_op_mode *op_mode __maybe_unused = mvm_r;
2815 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
2816
2817 IWL_DEBUG_RATE(mvm, "enter\n");
2818 IWL_DEBUG_RATE(mvm, "leave\n");
2819}
2820
2821#ifdef CONFIG_MAC80211_DEBUGFS
2822static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
2823 u32 *rate_n_flags, int index)
2824{
2825 struct iwl_mvm *mvm;
2826 u8 valid_tx_ant;
2827 u8 ant_sel_tx;
2828
2829 mvm = lq_sta->drv;
2830 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
2831 if (lq_sta->dbg_fixed_rate) {
2832 ant_sel_tx =
2833 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
2834 >> RATE_MCS_ANT_POS);
2835 if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
2836 *rate_n_flags = lq_sta->dbg_fixed_rate;
2837 IWL_DEBUG_RATE(mvm, "Fixed rate ON\n");
2838 } else {
2839 lq_sta->dbg_fixed_rate = 0;
2840 IWL_ERR(mvm,
2841 "Invalid antenna selection 0x%X, Valid is 0x%X\n",
2842 ant_sel_tx, valid_tx_ant);
2843 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n");
2844 }
2845 } else {
2846 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n");
2847 }
2848}
2849
2850static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2851 const char __user *user_buf, size_t count, loff_t *ppos)
2852{
2853 struct iwl_lq_sta *lq_sta = file->private_data;
2854 struct iwl_mvm *mvm;
2855 char buf[64];
2856 size_t buf_size;
2857 u32 parsed_rate;
2858
2859
2860 mvm = lq_sta->drv;
2861 memset(buf, 0, sizeof(buf));
2862 buf_size = min(count, sizeof(buf) - 1);
2863 if (copy_from_user(buf, user_buf, buf_size))
2864 return -EFAULT;
2865
2866 if (sscanf(buf, "%x", &parsed_rate) == 1)
2867 lq_sta->dbg_fixed_rate = parsed_rate;
2868 else
2869 lq_sta->dbg_fixed_rate = 0;
2870
2871 rs_program_fix_rate(mvm, lq_sta);
2872
2873 return count;
2874}
2875
2876static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2877 char __user *user_buf, size_t count, loff_t *ppos)
2878{
2879 char *buff;
2880 int desc = 0;
2881 int i = 0;
2882 int index = 0;
2883 ssize_t ret;
2884
2885 struct iwl_lq_sta *lq_sta = file->private_data;
2886 struct iwl_mvm *mvm;
2887 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2888
2889 mvm = lq_sta->drv;
2890 buff = kmalloc(1024, GFP_KERNEL);
2891 if (!buff)
2892 return -ENOMEM;
2893
2894 desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
2895 desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
2896 lq_sta->total_failed, lq_sta->total_success,
2897 lq_sta->active_legacy_rate);
2898 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
2899 lq_sta->dbg_fixed_rate);
2900 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
2901 (mvm->nvm_data->valid_tx_ant & ANT_A) ? "ANT_A," : "",
2902 (mvm->nvm_data->valid_tx_ant & ANT_B) ? "ANT_B," : "",
2903 (mvm->nvm_data->valid_tx_ant & ANT_C) ? "ANT_C" : "");
2904 desc += sprintf(buff+desc, "lq type %s\n",
2905 (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
2906 if (is_Ht(tbl->lq_type)) {
2907 desc += sprintf(buff+desc, " %s",
2908 (is_siso(tbl->lq_type)) ? "SISO" :
2909 ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
2910 desc += sprintf(buff+desc, " %s",
2911 (tbl->is_ht40) ? "40MHz" : "20MHz");
2912 desc += sprintf(buff+desc, " %s %s %s\n",
2913 (tbl->is_SGI) ? "SGI" : "",
2914 (lq_sta->is_green) ? "GF enabled" : "",
2915 (lq_sta->is_agg) ? "AGG on" : "");
2916 }
2917 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
2918 lq_sta->last_rate_n_flags);
2919 desc += sprintf(buff+desc,
2920 "general: flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
2921 lq_sta->lq.flags,
2922 lq_sta->lq.mimo_delim,
2923 lq_sta->lq.single_stream_ant_msk,
2924 lq_sta->lq.dual_stream_ant_msk);
2925
2926 desc += sprintf(buff+desc,
2927 "agg: time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",
2928 le16_to_cpu(lq_sta->lq.agg_time_limit),
2929 lq_sta->lq.agg_disable_start_th,
2930 lq_sta->lq.agg_frame_cnt_limit);
2931
2932 desc += sprintf(buff+desc,
2933 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
2934 lq_sta->lq.initial_rate_index[0],
2935 lq_sta->lq.initial_rate_index[1],
2936 lq_sta->lq.initial_rate_index[2],
2937 lq_sta->lq.initial_rate_index[3]);
2938
2939 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
2940 index = iwl_hwrate_to_plcp_idx(
2941 le32_to_cpu(lq_sta->lq.rs_table[i]));
2942 if (is_legacy(tbl->lq_type)) {
2943 desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n",
2944 i, le32_to_cpu(lq_sta->lq.rs_table[i]),
2945 iwl_rate_mcs[index].mbps);
2946 } else {
2947 desc += sprintf(buff+desc,
2948 " rate[%d] 0x%X %smbps (%s)\n",
2949 i, le32_to_cpu(lq_sta->lq.rs_table[i]),
2950 iwl_rate_mcs[index].mbps,
2951 iwl_rate_mcs[index].mcs);
2952 }
2953 }
2954
2955 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2956 kfree(buff);
2957 return ret;
2958}
2959
2960static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
2961 .write = rs_sta_dbgfs_scale_table_write,
2962 .read = rs_sta_dbgfs_scale_table_read,
2963 .open = simple_open,
2964 .llseek = default_llseek,
2965};
2966static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2967 char __user *user_buf, size_t count, loff_t *ppos)
2968{
2969 char *buff;
2970 int desc = 0;
2971 int i, j;
2972 ssize_t ret;
2973
2974 struct iwl_lq_sta *lq_sta = file->private_data;
2975
2976 buff = kmalloc(1024, GFP_KERNEL);
2977 if (!buff)
2978 return -ENOMEM;
2979
2980 for (i = 0; i < LQ_SIZE; i++) {
2981 desc += sprintf(buff+desc,
2982 "%s type=%d SGI=%d HT40=%d DUP=0 GF=%d\n"
2983 "rate=0x%X\n",
2984 lq_sta->active_tbl == i ? "*" : "x",
2985 lq_sta->lq_info[i].lq_type,
2986 lq_sta->lq_info[i].is_SGI,
2987 lq_sta->lq_info[i].is_ht40,
2988 lq_sta->is_green,
2989 lq_sta->lq_info[i].current_rate);
2990 for (j = 0; j < IWL_RATE_COUNT; j++) {
2991 desc += sprintf(buff+desc,
2992 "counter=%d success=%d %%=%d\n",
2993 lq_sta->lq_info[i].win[j].counter,
2994 lq_sta->lq_info[i].win[j].success_counter,
2995 lq_sta->lq_info[i].win[j].success_ratio);
2996 }
2997 }
2998 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2999 kfree(buff);
3000 return ret;
3001}
3002
3003static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
3004 .read = rs_sta_dbgfs_stats_table_read,
3005 .open = simple_open,
3006 .llseek = default_llseek,
3007};
3008
3009static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
3010 char __user *user_buf, size_t count, loff_t *ppos)
3011{
3012 struct iwl_lq_sta *lq_sta = file->private_data;
3013 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
3014 char buff[120];
3015 int desc = 0;
3016
3017 if (is_Ht(tbl->lq_type))
3018 desc += sprintf(buff+desc,
3019 "Bit Rate= %d Mb/s\n",
3020 tbl->expected_tpt[lq_sta->last_txrate_idx]);
3021 else
3022 desc += sprintf(buff+desc,
3023 "Bit Rate= %d Mb/s\n",
3024 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
3025
3026 return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
3027}
3028
3029static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
3030 .read = rs_sta_dbgfs_rate_scale_data_read,
3031 .open = simple_open,
3032 .llseek = default_llseek,
3033};
3034
3035static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
3036{
3037 struct iwl_lq_sta *lq_sta = mvm_sta;
3038 lq_sta->rs_sta_dbgfs_scale_table_file =
3039 debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir,
3040 lq_sta, &rs_sta_dbgfs_scale_table_ops);
3041 lq_sta->rs_sta_dbgfs_stats_table_file =
3042 debugfs_create_file("rate_stats_table", S_IRUSR, dir,
3043 lq_sta, &rs_sta_dbgfs_stats_table_ops);
3044 lq_sta->rs_sta_dbgfs_rate_scale_data_file =
3045 debugfs_create_file("rate_scale_data", S_IRUSR, dir,
3046 lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
3047 lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
3048 debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir,
3049 &lq_sta->tx_agg_tid_en);
3050}
3051
3052static void rs_remove_debugfs(void *mvm, void *mvm_sta)
3053{
3054 struct iwl_lq_sta *lq_sta = mvm_sta;
3055 debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
3056 debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
3057 debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file);
3058 debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
3059}
3060#endif
3061
3062/*
3063 * Initialization of rate scaling information is done by driver after
3064 * the station is added. Since mac80211 calls this function before a
3065 * station is added we ignore it.
3066 */
3067static void rs_rate_init_stub(void *mvm_r,
3068 struct ieee80211_supported_band *sband,
3069 struct ieee80211_sta *sta, void *mvm_sta)
3070{
3071}
3072static struct rate_control_ops rs_mvm_ops = {
3073 .module = NULL,
3074 .name = RS_NAME,
3075 .tx_status = rs_tx_status,
3076 .get_rate = rs_get_rate,
3077 .rate_init = rs_rate_init_stub,
3078 .alloc = rs_alloc,
3079 .free = rs_free,
3080 .alloc_sta = rs_alloc_sta,
3081 .free_sta = rs_free_sta,
3082#ifdef CONFIG_MAC80211_DEBUGFS
3083 .add_sta_debugfs = rs_add_debugfs,
3084 .remove_sta_debugfs = rs_remove_debugfs,
3085#endif
3086};
3087
3088int iwl_mvm_rate_control_register(void)
3089{
3090 return ieee80211_rate_control_register(&rs_mvm_ops);
3091}
3092
3093void iwl_mvm_rate_control_unregister(void)
3094{
3095 ieee80211_rate_control_unregister(&rs_mvm_ops);
3096}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
new file mode 100644
index 000000000000..219c6857cc0f
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -0,0 +1,393 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#ifndef __rs_h__
28#define __rs_h__
29
30#include <net/mac80211.h>
31
32#include "iwl-config.h"
33
34#include "fw-api.h"
35#include "iwl-trans.h"
36
37struct iwl_rs_rate_info {
38 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
39 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
40 u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
41 u8 plcp_mimo3; /* uCode API: IWL_RATE_MIMO3_6M_PLCP, etc. */
42 u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
43 u8 prev_ieee; /* previous rate in IEEE speeds */
44 u8 next_ieee; /* next rate in IEEE speeds */
45 u8 prev_rs; /* previous rate used in rs algo */
46 u8 next_rs; /* next rate used in rs algo */
47 u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
48 u8 next_rs_tgg; /* next rate used in TGG rs algo */
49};
50
51#define IWL_RATE_60M_PLCP 3
52
53enum {
54 IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
55 IWL_RATE_INVALID = IWL_RATE_COUNT,
56};
57
58#define LINK_QUAL_MAX_RETRY_NUM 16
59
60enum {
61 IWL_RATE_6M_INDEX_TABLE = 0,
62 IWL_RATE_9M_INDEX_TABLE,
63 IWL_RATE_12M_INDEX_TABLE,
64 IWL_RATE_18M_INDEX_TABLE,
65 IWL_RATE_24M_INDEX_TABLE,
66 IWL_RATE_36M_INDEX_TABLE,
67 IWL_RATE_48M_INDEX_TABLE,
68 IWL_RATE_54M_INDEX_TABLE,
69 IWL_RATE_1M_INDEX_TABLE,
70 IWL_RATE_2M_INDEX_TABLE,
71 IWL_RATE_5M_INDEX_TABLE,
72 IWL_RATE_11M_INDEX_TABLE,
73 IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1,
74};
75
76/* #define vs. enum to keep from defaulting to 'large integer' */
77#define IWL_RATE_6M_MASK (1 << IWL_RATE_6M_INDEX)
78#define IWL_RATE_9M_MASK (1 << IWL_RATE_9M_INDEX)
79#define IWL_RATE_12M_MASK (1 << IWL_RATE_12M_INDEX)
80#define IWL_RATE_18M_MASK (1 << IWL_RATE_18M_INDEX)
81#define IWL_RATE_24M_MASK (1 << IWL_RATE_24M_INDEX)
82#define IWL_RATE_36M_MASK (1 << IWL_RATE_36M_INDEX)
83#define IWL_RATE_48M_MASK (1 << IWL_RATE_48M_INDEX)
84#define IWL_RATE_54M_MASK (1 << IWL_RATE_54M_INDEX)
85#define IWL_RATE_60M_MASK (1 << IWL_RATE_60M_INDEX)
86#define IWL_RATE_1M_MASK (1 << IWL_RATE_1M_INDEX)
87#define IWL_RATE_2M_MASK (1 << IWL_RATE_2M_INDEX)
88#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX)
89#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
90
91
92/* uCode API values for OFDM high-throughput (HT) bit rates */
93enum {
94 IWL_RATE_SISO_6M_PLCP = 0,
95 IWL_RATE_SISO_12M_PLCP = 1,
96 IWL_RATE_SISO_18M_PLCP = 2,
97 IWL_RATE_SISO_24M_PLCP = 3,
98 IWL_RATE_SISO_36M_PLCP = 4,
99 IWL_RATE_SISO_48M_PLCP = 5,
100 IWL_RATE_SISO_54M_PLCP = 6,
101 IWL_RATE_SISO_60M_PLCP = 7,
102 IWL_RATE_MIMO2_6M_PLCP = 0x8,
103 IWL_RATE_MIMO2_12M_PLCP = 0x9,
104 IWL_RATE_MIMO2_18M_PLCP = 0xa,
105 IWL_RATE_MIMO2_24M_PLCP = 0xb,
106 IWL_RATE_MIMO2_36M_PLCP = 0xc,
107 IWL_RATE_MIMO2_48M_PLCP = 0xd,
108 IWL_RATE_MIMO2_54M_PLCP = 0xe,
109 IWL_RATE_MIMO2_60M_PLCP = 0xf,
110 IWL_RATE_MIMO3_6M_PLCP = 0x10,
111 IWL_RATE_MIMO3_12M_PLCP = 0x11,
112 IWL_RATE_MIMO3_18M_PLCP = 0x12,
113 IWL_RATE_MIMO3_24M_PLCP = 0x13,
114 IWL_RATE_MIMO3_36M_PLCP = 0x14,
115 IWL_RATE_MIMO3_48M_PLCP = 0x15,
116 IWL_RATE_MIMO3_54M_PLCP = 0x16,
117 IWL_RATE_MIMO3_60M_PLCP = 0x17,
118 IWL_RATE_SISO_INVM_PLCP,
119 IWL_RATE_MIMO2_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
120 IWL_RATE_MIMO3_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
121};
122
123/* MAC header values for bit rates */
124enum {
125 IWL_RATE_6M_IEEE = 12,
126 IWL_RATE_9M_IEEE = 18,
127 IWL_RATE_12M_IEEE = 24,
128 IWL_RATE_18M_IEEE = 36,
129 IWL_RATE_24M_IEEE = 48,
130 IWL_RATE_36M_IEEE = 72,
131 IWL_RATE_48M_IEEE = 96,
132 IWL_RATE_54M_IEEE = 108,
133 IWL_RATE_60M_IEEE = 120,
134 IWL_RATE_1M_IEEE = 2,
135 IWL_RATE_2M_IEEE = 4,
136 IWL_RATE_5M_IEEE = 11,
137 IWL_RATE_11M_IEEE = 22,
138};
139
140#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
141
142#define IWL_INVALID_VALUE -1
143
144#define IWL_MIN_RSSI_VAL -100
145#define IWL_MAX_RSSI_VAL 0
146
147/* These values specify how many Tx frame attempts before
148 * searching for a new modulation mode */
149#define IWL_LEGACY_FAILURE_LIMIT 160
150#define IWL_LEGACY_SUCCESS_LIMIT 480
151#define IWL_LEGACY_TABLE_COUNT 160
152
153#define IWL_NONE_LEGACY_FAILURE_LIMIT 400
154#define IWL_NONE_LEGACY_SUCCESS_LIMIT 4500
155#define IWL_NONE_LEGACY_TABLE_COUNT 1500
156
157/* Success ratio (ACKed / attempted tx frames) values (perfect is 128 * 100) */
158#define IWL_RS_GOOD_RATIO 12800 /* 100% */
159#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */
160#define IWL_RATE_HIGH_TH 10880 /* 85% */
161#define IWL_RATE_INCREASE_TH 6400 /* 50% */
162#define IWL_RATE_DECREASE_TH 1920 /* 15% */
163
164/* possible actions when in legacy mode */
165#define IWL_LEGACY_SWITCH_ANTENNA1 0
166#define IWL_LEGACY_SWITCH_ANTENNA2 1
167#define IWL_LEGACY_SWITCH_SISO 2
168#define IWL_LEGACY_SWITCH_MIMO2_AB 3
169#define IWL_LEGACY_SWITCH_MIMO2_AC 4
170#define IWL_LEGACY_SWITCH_MIMO2_BC 5
171#define IWL_LEGACY_SWITCH_MIMO3_ABC 6
172
173/* possible actions when in siso mode */
174#define IWL_SISO_SWITCH_ANTENNA1 0
175#define IWL_SISO_SWITCH_ANTENNA2 1
176#define IWL_SISO_SWITCH_MIMO2_AB 2
177#define IWL_SISO_SWITCH_MIMO2_AC 3
178#define IWL_SISO_SWITCH_MIMO2_BC 4
179#define IWL_SISO_SWITCH_GI 5
180#define IWL_SISO_SWITCH_MIMO3_ABC 6
181
182
183/* possible actions when in mimo mode */
184#define IWL_MIMO2_SWITCH_ANTENNA1 0
185#define IWL_MIMO2_SWITCH_ANTENNA2 1
186#define IWL_MIMO2_SWITCH_SISO_A 2
187#define IWL_MIMO2_SWITCH_SISO_B 3
188#define IWL_MIMO2_SWITCH_SISO_C 4
189#define IWL_MIMO2_SWITCH_GI 5
190#define IWL_MIMO2_SWITCH_MIMO3_ABC 6
191
192
193/* possible actions when in mimo3 mode */
194#define IWL_MIMO3_SWITCH_ANTENNA1 0
195#define IWL_MIMO3_SWITCH_ANTENNA2 1
196#define IWL_MIMO3_SWITCH_SISO_A 2
197#define IWL_MIMO3_SWITCH_SISO_B 3
198#define IWL_MIMO3_SWITCH_SISO_C 4
199#define IWL_MIMO3_SWITCH_MIMO2_AB 5
200#define IWL_MIMO3_SWITCH_MIMO2_AC 6
201#define IWL_MIMO3_SWITCH_MIMO2_BC 7
202#define IWL_MIMO3_SWITCH_GI 8
203
204
205#define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI
206#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC
207
208/*FIXME:RS:add possible actions for MIMO3*/
209
210#define IWL_ACTION_LIMIT 3 /* # possible actions */
211
212#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
213#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
214#define LINK_QUAL_AGG_TIME_LIMIT_MIN (100)
215
216#define LINK_QUAL_AGG_DISABLE_START_DEF (3)
217#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
218#define LINK_QUAL_AGG_DISABLE_START_MIN (0)
219
220#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63)
221#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63)
222#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)
223
224#define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */
225
226/* load per tid defines for A-MPDU activation */
227#define IWL_AGG_TPT_THREHOLD 0
228#define IWL_AGG_LOAD_THRESHOLD 10
229#define IWL_AGG_ALL_TID 0xff
230#define TID_QUEUE_CELL_SPACING 50 /*mS */
231#define TID_QUEUE_MAX_SIZE 20
232#define TID_ROUND_VALUE 5 /* mS */
233
234#define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING)
235#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
236
237enum iwl_table_type {
238 LQ_NONE,
239 LQ_G, /* legacy types */
240 LQ_A,
241 LQ_SISO, /* high-throughput types */
242 LQ_MIMO2,
243 LQ_MIMO3,
244 LQ_MAX,
245};
246
247#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A))
248#define is_siso(tbl) ((tbl) == LQ_SISO)
249#define is_mimo2(tbl) ((tbl) == LQ_MIMO2)
250#define is_mimo3(tbl) ((tbl) == LQ_MIMO3)
251#define is_mimo(tbl) (is_mimo2(tbl) || is_mimo3(tbl))
252#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl))
253#define is_a_band(tbl) ((tbl) == LQ_A)
254#define is_g_and(tbl) ((tbl) == LQ_G)
255
256#define IWL_MAX_MCS_DISPLAY_SIZE 12
257
258struct iwl_rate_mcs_info {
259 char mbps[IWL_MAX_MCS_DISPLAY_SIZE];
260 char mcs[IWL_MAX_MCS_DISPLAY_SIZE];
261};
262
263/**
264 * struct iwl_rate_scale_data -- tx success history for one rate
265 */
266struct iwl_rate_scale_data {
267 u64 data; /* bitmap of successful frames */
268 s32 success_counter; /* number of frames successful */
269 s32 success_ratio; /* per-cent * 128 */
270 s32 counter; /* number of frames attempted */
271 s32 average_tpt; /* success ratio * expected throughput */
272 unsigned long stamp;
273};
274
275/**
276 * struct iwl_scale_tbl_info -- tx params and success history for all rates
277 *
278 * There are two of these in struct iwl_lq_sta,
279 * one for "active", and one for "search".
280 */
281struct iwl_scale_tbl_info {
282 enum iwl_table_type lq_type;
283 u8 ant_type;
284 u8 is_SGI; /* 1 = short guard interval */
285 u8 is_ht40; /* 1 = 40 MHz channel width */
286 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
287 u8 max_search; /* maximun number of tables we can search */
288 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
289 u32 current_rate; /* rate_n_flags, uCode API format */
290 struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
291};
292
293struct iwl_traffic_load {
294 unsigned long time_stamp; /* age of the oldest statistics */
295 u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time
296 * slice */
297 u32 total; /* total num of packets during the
298 * last TID_MAX_TIME_DIFF */
299 u8 queue_count; /* number of queues that has
300 * been used since the last cleanup */
301 u8 head; /* start of the circular buffer */
302};
303
304/**
305 * struct iwl_lq_sta -- driver's rate scaling private structure
306 *
307 * Pointer to this gets passed back and forth between driver and mac80211.
308 */
309struct iwl_lq_sta {
310 u8 active_tbl; /* index of active table, range 0-1 */
311 u8 enable_counter; /* indicates HT mode */
312 u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */
313 u8 search_better_tbl; /* 1: currently trying alternate mode */
314 s32 last_tpt;
315
316 /* The following determine when to search for a new mode */
317 u32 table_count_limit;
318 u32 max_failure_limit; /* # failed frames before new search */
319 u32 max_success_limit; /* # successful frames before new search */
320 u32 table_count;
321 u32 total_failed; /* total failed frames, any/all rates */
322 u32 total_success; /* total successful frames, any/all rates */
323 u64 flush_timer; /* time staying in mode before new search */
324
325 u8 action_counter; /* # mode-switch actions tried */
326 u8 is_green;
327 enum ieee80211_band band;
328
329 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
330 u32 supp_rates;
331 u16 active_legacy_rate;
332 u16 active_siso_rate;
333 u16 active_mimo2_rate;
334 u16 active_mimo3_rate;
335 s8 max_rate_idx; /* Max rate set by user */
336 u8 missed_rate_counter;
337
338 struct iwl_lq_cmd lq;
339 struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
340 struct iwl_traffic_load load[IWL_MAX_TID_COUNT];
341 u8 tx_agg_tid_en;
342#ifdef CONFIG_MAC80211_DEBUGFS
343 struct dentry *rs_sta_dbgfs_scale_table_file;
344 struct dentry *rs_sta_dbgfs_stats_table_file;
345 struct dentry *rs_sta_dbgfs_rate_scale_data_file;
346 struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
347 u32 dbg_fixed_rate;
348#endif
349 struct iwl_mvm *drv;
350
351 /* used to be in sta_info */
352 int last_txrate_idx;
353 /* last tx rate_n_flags */
354 u32 last_rate_n_flags;
355 /* packets destined for this STA are aggregated */
356 u8 is_agg;
357 /* BT traffic this sta was last updated in */
358 u8 last_bt_traffic;
359};
360
361static inline u8 num_of_ant(u8 mask)
362{
363 return !!((mask) & ANT_A) +
364 !!((mask) & ANT_B) +
365 !!((mask) & ANT_C);
366}
367
368/* Initialize station's rate scaling information after adding station */
369extern void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm,
370 struct ieee80211_sta *sta,
371 enum ieee80211_band band);
372
373/**
374 * iwl_rate_control_register - Register the rate control algorithm callbacks
375 *
376 * Since the rate control algorithm is hardware specific, there is no need
377 * or reason to place it as a stand alone module. The driver can call
378 * iwl_rate_control_register in order to register the rate control callbacks
379 * with the mac80211 subsystem. This should be performed prior to calling
380 * ieee80211_register_hw
381 *
382 */
383extern int iwl_mvm_rate_control_register(void);
384
385/**
386 * iwl_rate_control_unregister - Unregister the rate control callbacks
387 *
388 * This should be called after calling ieee80211_unregister_hw, but before
389 * the driver is unloaded.
390 */
391extern void iwl_mvm_rate_control_unregister(void);
392
393#endif /* __rs__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
new file mode 100644
index 000000000000..52da375e5740
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -0,0 +1,355 @@
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 LICENSE.GPL.
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#include "iwl-trans.h"
63
64#include "mvm.h"
65#include "fw-api.h"
66
67/*
68 * iwl_mvm_rx_rx_phy_cmd - REPLY_RX_PHY_CMD handler
69 *
70 * Copies the phy information in mvm->last_phy_info, it will be used when the
71 * actual data will come from the fw in the next packet.
72 */
73int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
74 struct iwl_device_cmd *cmd)
75{
76 struct iwl_rx_packet *pkt = rxb_addr(rxb);
77
78 memcpy(&mvm->last_phy_info, pkt->data, sizeof(mvm->last_phy_info));
79 mvm->ampdu_ref++;
80 return 0;
81}
82
83/*
84 * iwl_mvm_pass_packet_to_mac80211 - builds the packet for mac80211
85 *
86 * Adds the rxb to a new skb and give it to mac80211
87 */
88static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
89 struct ieee80211_hdr *hdr, u16 len,
90 u32 ampdu_status,
91 struct iwl_rx_cmd_buffer *rxb,
92 struct ieee80211_rx_status *stats)
93{
94 struct sk_buff *skb;
95 unsigned int hdrlen, fraglen;
96
97 /* Dont use dev_alloc_skb(), we'll have enough headroom once
98 * ieee80211_hdr pulled.
99 */
100 skb = alloc_skb(128, GFP_ATOMIC);
101 if (!skb) {
102 IWL_ERR(mvm, "alloc_skb failed\n");
103 return;
104 }
105 /* If frame is small enough to fit in skb->head, pull it completely.
106 * If not, only pull ieee80211_hdr so that splice() or TCP coalesce
107 * are more efficient.
108 */
109 hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr);
110
111 memcpy(skb_put(skb, hdrlen), hdr, hdrlen);
112 fraglen = len - hdrlen;
113
114 if (fraglen) {
115 int offset = (void *)hdr + hdrlen -
116 rxb_addr(rxb) + rxb_offset(rxb);
117
118 skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset,
119 fraglen, rxb->truesize);
120 }
121
122 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
123
124 ieee80211_rx(mvm->hw, skb);
125}
126
127/*
128 * iwl_mvm_calc_rssi - calculate the rssi in dBm
129 * @phy_info: the phy information for the coming packet
130 */
131static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
132 struct iwl_rx_phy_info *phy_info)
133{
134 u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db;
135 u32 val;
136
137 /* Find max rssi among 3 possible receivers.
138 * These values are measured by the Digital Signal Processor (DSP).
139 * They should stay fairly constant even as the signal strength varies,
140 * if the radio's Automatic Gain Control (AGC) is working right.
141 * AGC value (see below) will provide the "interesting" info.
142 */
143 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);
144 rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;
145 rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;
146 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]);
147 rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS;
148
149 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
150 agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS;
151
152 max_rssi = max_t(u32, rssi_a, rssi_b);
153 max_rssi = max_t(u32, max_rssi, rssi_c);
154
155 IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
156 rssi_a, rssi_b, rssi_c, max_rssi, agc_db);
157
158 /* dBm = max_rssi dB - agc dB - constant.
159 * Higher AGC (higher radio gain) means lower signal. */
160 return max_rssi - agc_db - IWL_RSSI_OFFSET;
161}
162
163/*
164 * iwl_mvm_set_mac80211_rx_flag - translate fw status to mac80211 format
165 * @mvm: the mvm object
166 * @hdr: 80211 header
167 * @stats: status in mac80211's format
168 * @rx_pkt_status: status coming from fw
169 *
170 * returns non 0 value if the packet should be dropped
171 */
172static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
173 struct ieee80211_hdr *hdr,
174 struct ieee80211_rx_status *stats,
175 u32 rx_pkt_status)
176{
177 if (!ieee80211_has_protected(hdr->frame_control) ||
178 (rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) ==
179 RX_MPDU_RES_STATUS_SEC_NO_ENC)
180 return 0;
181
182 /* packet was encrypted with unknown alg */
183 if ((rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) ==
184 RX_MPDU_RES_STATUS_SEC_ENC_ERR)
185 return 0;
186
187 switch (rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) {
188 case RX_MPDU_RES_STATUS_SEC_CCM_ENC:
189 /* alg is CCM: check MIC only */
190 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_MIC_OK))
191 return -1;
192
193 stats->flag |= RX_FLAG_DECRYPTED;
194 IWL_DEBUG_WEP(mvm, "hw decrypted CCMP successfully\n");
195 return 0;
196
197 case RX_MPDU_RES_STATUS_SEC_TKIP_ENC:
198 /* Don't drop the frame and decrypt it in SW */
199 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_TTAK_OK))
200 return 0;
201 /* fall through if TTAK OK */
202
203 case RX_MPDU_RES_STATUS_SEC_WEP_ENC:
204 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_ICV_OK))
205 return -1;
206
207 stats->flag |= RX_FLAG_DECRYPTED;
208 return 0;
209
210 default:
211 IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status);
212 }
213
214 return 0;
215}
216
217/*
218 * iwl_mvm_rx_rx_mpdu - REPLY_RX_MPDU_CMD handler
219 *
220 * Handles the actual data of the Rx packet from the fw
221 */
222int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
223 struct iwl_device_cmd *cmd)
224{
225 struct ieee80211_hdr *hdr;
226 struct ieee80211_rx_status rx_status = {};
227 struct iwl_rx_packet *pkt = rxb_addr(rxb);
228 struct iwl_rx_phy_info *phy_info;
229 struct iwl_rx_mpdu_res_start *rx_res;
230 u32 len;
231 u32 ampdu_status;
232 u32 rate_n_flags;
233 u32 rx_pkt_status;
234
235 phy_info = &mvm->last_phy_info;
236 rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data;
237 hdr = (struct ieee80211_hdr *)(pkt->data + sizeof(*rx_res));
238 len = le16_to_cpu(rx_res->byte_count);
239 rx_pkt_status = le32_to_cpup((__le32 *)
240 (pkt->data + sizeof(*rx_res) + len));
241
242 memset(&rx_status, 0, sizeof(rx_status));
243
244 /*
245 * drop the packet if it has failed being decrypted by HW
246 */
247 if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, &rx_status, rx_pkt_status)) {
248 IWL_DEBUG_DROP(mvm, "Bad decryption results 0x%08x\n",
249 rx_pkt_status);
250 return 0;
251 }
252
253 if ((unlikely(phy_info->cfg_phy_cnt > 20))) {
254 IWL_DEBUG_DROP(mvm, "dsp size out of range [0,20]: %d\n",
255 phy_info->cfg_phy_cnt);
256 return 0;
257 }
258
259 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_CRC_OK) ||
260 !(rx_pkt_status & RX_MPDU_RES_STATUS_OVERRUN_OK)) {
261 IWL_DEBUG_RX(mvm, "Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status);
262 return 0;
263 }
264
265 /* This will be used in several places later */
266 rate_n_flags = le32_to_cpu(phy_info->rate_n_flags);
267
268 /* rx_status carries information about the packet to mac80211 */
269 rx_status.mactime = le64_to_cpu(phy_info->timestamp);
270 rx_status.band =
271 (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
272 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
273 rx_status.freq =
274 ieee80211_channel_to_frequency(le16_to_cpu(phy_info->channel),
275 rx_status.band);
276 /*
277 * TSF as indicated by the fw is at INA time, but mac80211 expects the
278 * TSF at the beginning of the MPDU.
279 */
280 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
281
282 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
283 rx_status.signal = iwl_mvm_calc_rssi(mvm, phy_info);
284
285 IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal,
286 (unsigned long long)rx_status.mactime);
287
288 /*
289 * "antenna number"
290 *
291 * It seems that the antenna field in the phy flags value
292 * is actually a bit field. This is undefined by radiotap,
293 * it wants an actual antenna number but I always get "7"
294 * for most legacy frames I receive indicating that the
295 * same frame was received on all three RX chains.
296 *
297 * I think this field should be removed in favor of a
298 * new 802.11n radiotap field "RX chains" that is defined
299 * as a bitmask.
300 */
301 rx_status.antenna = (le16_to_cpu(phy_info->phy_flags) &
302 RX_RES_PHY_FLAGS_ANTENNA)
303 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
304
305 /* set the preamble flag if appropriate */
306 if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE))
307 rx_status.flag |= RX_FLAG_SHORTPRE;
308
309 if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_AGG)) {
310 /*
311 * We know which subframes of an A-MPDU belong
312 * together since we get a single PHY response
313 * from the firmware for all of them
314 */
315 rx_status.flag |= RX_FLAG_AMPDU_DETAILS;
316 rx_status.ampdu_reference = mvm->ampdu_ref;
317 }
318
319 /* Set up the HT phy flags */
320 switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
321 case RATE_MCS_CHAN_WIDTH_20:
322 break;
323 case RATE_MCS_CHAN_WIDTH_40:
324 rx_status.flag |= RX_FLAG_40MHZ;
325 break;
326 case RATE_MCS_CHAN_WIDTH_80:
327 rx_status.flag |= RX_FLAG_80MHZ;
328 break;
329 case RATE_MCS_CHAN_WIDTH_160:
330 rx_status.flag |= RX_FLAG_160MHZ;
331 break;
332 }
333 if (rate_n_flags & RATE_MCS_SGI_MSK)
334 rx_status.flag |= RX_FLAG_SHORT_GI;
335 if (rate_n_flags & RATE_HT_MCS_GF_MSK)
336 rx_status.flag |= RX_FLAG_HT_GF;
337 if (rate_n_flags & RATE_MCS_HT_MSK) {
338 rx_status.flag |= RX_FLAG_HT;
339 rx_status.rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
340 } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
341 rx_status.vht_nss =
342 ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
343 RATE_VHT_MCS_NSS_POS) + 1;
344 rx_status.rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
345 rx_status.flag |= RX_FLAG_VHT;
346 } else {
347 rx_status.rate_idx =
348 iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
349 rx_status.band);
350 }
351
352 iwl_mvm_pass_packet_to_mac80211(mvm, hdr, len, ampdu_status,
353 rxb, &rx_status);
354 return 0;
355}
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
new file mode 100644
index 000000000000..406c53ad0a49
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -0,0 +1,437 @@
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 LICENSE.GPL.
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/etherdevice.h>
65#include <net/mac80211.h>
66
67#include "mvm.h"
68#include "iwl-eeprom-parse.h"
69#include "fw-api-scan.h"
70
71#define IWL_PLCP_QUIET_THRESH 1
72#define IWL_ACTIVE_QUIET_TIME 10
73
74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
75{
76 u16 rx_chain;
77 u8 rx_ant = mvm->nvm_data->valid_rx_ant;
78
79 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
80 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
81 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS;
82 rx_chain |= 0x1 << PHY_RX_CHAIN_DRIVER_FORCE_POS;
83 return cpu_to_le16(rx_chain);
84}
85
86static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif)
87{
88 if (vif->bss_conf.assoc)
89 return cpu_to_le32(200 * 1024);
90 else
91 return 0;
92}
93
94static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif)
95{
96 if (vif->bss_conf.assoc)
97 return cpu_to_le32(vif->bss_conf.beacon_int);
98 else
99 return 0;
100}
101
102static inline __le32
103iwl_mvm_scan_rxon_flags(struct cfg80211_scan_request *req)
104{
105 if (req->channels[0]->band == IEEE80211_BAND_2GHZ)
106 return cpu_to_le32(PHY_BAND_24);
107 else
108 return cpu_to_le32(PHY_BAND_5);
109}
110
111static inline __le32
112iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
113 bool no_cck)
114{
115 u32 tx_ant;
116
117 mvm->scan_last_antenna_idx =
118 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant,
119 mvm->scan_last_antenna_idx);
120 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
121
122 if (band == IEEE80211_BAND_2GHZ && !no_cck)
123 return cpu_to_le32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK |
124 tx_ant);
125 else
126 return cpu_to_le32(IWL_RATE_6M_PLCP | tx_ant);
127}
128
129/*
130 * We insert the SSIDs in an inverted order, because the FW will
131 * invert it back. The most prioritized SSID, which is first in the
132 * request list, is not copied here, but inserted directly to the probe
133 * request.
134 */
135static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
136 struct cfg80211_scan_request *req)
137{
138 int fw_idx, req_idx;
139
140 fw_idx = 0;
141 for (req_idx = req->n_ssids - 1; req_idx > 0; req_idx--) {
142 cmd->direct_scan[fw_idx].id = WLAN_EID_SSID;
143 cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len;
144 memcpy(cmd->direct_scan[fw_idx].ssid,
145 req->ssids[req_idx].ssid,
146 req->ssids[req_idx].ssid_len);
147 }
148}
149
150/*
151 * If req->n_ssids > 0, it means we should do an active scan.
152 * In case of active scan w/o directed scan, we receive a zero-length SSID
153 * just to notify that this scan is active and not passive.
154 * In order to notify the FW of the number of SSIDs we wish to scan (including
155 * the zero-length one), we need to set the corresponding bits in chan->type,
156 * one for each SSID, and set the active bit (first).
157 */
158static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids)
159{
160 if (band == IEEE80211_BAND_2GHZ)
161 return 30 + 3 * (n_ssids + 1);
162 return 20 + 2 * (n_ssids + 1);
163}
164
165static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
166{
167 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10;
168}
169
170static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
171 struct cfg80211_scan_request *req)
172{
173 u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band);
174 u16 active_dwell = iwl_mvm_get_active_dwell(req->channels[0]->band,
175 req->n_ssids);
176 struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
177 (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
178 int i;
179 __le32 chan_type_value;
180
181 if (req->n_ssids > 0)
182 chan_type_value = cpu_to_le32(BIT(req->n_ssids + 1) - 1);
183 else
184 chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE;
185
186 for (i = 0; i < cmd->channel_count; i++) {
187 chan->channel = cpu_to_le16(req->channels[i]->hw_value);
188 if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN)
189 chan->type = SCAN_CHANNEL_TYPE_PASSIVE;
190 else
191 chan->type = chan_type_value;
192 chan->active_dwell = cpu_to_le16(active_dwell);
193 chan->passive_dwell = cpu_to_le16(passive_dwell);
194 chan->iteration_count = cpu_to_le16(1);
195 chan++;
196 }
197}
198
199/*
200 * Fill in probe request with the following parameters:
201 * TA is our vif HW address, which mac80211 ensures we have.
202 * Packet is broadcasted, so this is both SA and DA.
203 * The probe request IE is made out of two: first comes the most prioritized
204 * SSID if a directed scan is requested. Second comes whatever extra
205 * information was given to us as the scan request IE.
206 */
207static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
208 int n_ssids, const u8 *ssid, int ssid_len,
209 const u8 *ie, int ie_len,
210 int left)
211{
212 int len = 0;
213 u8 *pos = NULL;
214
215 /* Make sure there is enough space for the probe request,
216 * two mandatory IEs and the data */
217 left -= 24;
218 if (left < 0)
219 return 0;
220
221 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
222 eth_broadcast_addr(frame->da);
223 memcpy(frame->sa, ta, ETH_ALEN);
224 eth_broadcast_addr(frame->bssid);
225 frame->seq_ctrl = 0;
226
227 len += 24;
228
229 /* for passive scans, no need to fill anything */
230 if (n_ssids == 0)
231 return (u16)len;
232
233 /* points to the payload of the request */
234 pos = &frame->u.probe_req.variable[0];
235
236 /* fill in our SSID IE */
237 left -= ssid_len + 2;
238 if (left < 0)
239 return 0;
240 *pos++ = WLAN_EID_SSID;
241 *pos++ = ssid_len;
242 if (ssid && ssid_len) { /* ssid_len may be == 0 even if ssid is valid */
243 memcpy(pos, ssid, ssid_len);
244 pos += ssid_len;
245 }
246
247 len += ssid_len + 2;
248
249 if (WARN_ON(left < ie_len))
250 return len;
251
252 if (ie && ie_len) {
253 memcpy(pos, ie, ie_len);
254 len += ie_len;
255 }
256
257 return (u16)len;
258}
259
260int iwl_mvm_scan_request(struct iwl_mvm *mvm,
261 struct ieee80211_vif *vif,
262 struct cfg80211_scan_request *req)
263{
264 struct iwl_host_cmd hcmd = {
265 .id = SCAN_REQUEST_CMD,
266 .len = { 0, },
267 .data = { mvm->scan_cmd, },
268 .flags = CMD_SYNC,
269 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
270 };
271 struct iwl_scan_cmd *cmd = mvm->scan_cmd;
272 int ret;
273 u32 status;
274 int ssid_len = 0;
275 u8 *ssid = NULL;
276
277 lockdep_assert_held(&mvm->mutex);
278 BUG_ON(mvm->scan_cmd == NULL);
279
280 IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n");
281 mvm->scan_status = IWL_MVM_SCAN_OS;
282 memset(cmd, 0, sizeof(struct iwl_scan_cmd) +
283 mvm->fw->ucode_capa.max_probe_length +
284 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)));
285
286 cmd->channel_count = (u8)req->n_channels;
287 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
288 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
289 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
290 cmd->max_out_time = iwl_mvm_scan_max_out_time(vif);
291 cmd->suspend_time = iwl_mvm_scan_suspend_time(vif);
292 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
293 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
294 MAC_FILTER_IN_BEACON);
295 cmd->type = SCAN_TYPE_FORCED;
296 cmd->repeats = cpu_to_le32(1);
297
298 /*
299 * If the user asked for passive scan, don't change to active scan if
300 * you see any activity on the channel - remain passive.
301 */
302 if (req->n_ssids > 0) {
303 cmd->passive2active = cpu_to_le16(1);
304 ssid = req->ssids[0].ssid;
305 ssid_len = req->ssids[0].ssid_len;
306 } else {
307 cmd->passive2active = 0;
308 }
309
310 iwl_mvm_scan_fill_ssids(cmd, req);
311
312 cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL);
313 cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id;
314 cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
315 cmd->tx_cmd.rate_n_flags =
316 iwl_mvm_scan_rate_n_flags(mvm, req->channels[0]->band,
317 req->no_cck);
318
319 cmd->tx_cmd.len =
320 cpu_to_le16(iwl_mvm_fill_probe_req(
321 (struct ieee80211_mgmt *)cmd->data,
322 vif->addr,
323 req->n_ssids, ssid, ssid_len,
324 req->ie, req->ie_len,
325 mvm->fw->ucode_capa.max_probe_length));
326
327 iwl_mvm_scan_fill_channels(cmd, req);
328
329 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) +
330 le16_to_cpu(cmd->tx_cmd.len) +
331 (cmd->channel_count * sizeof(struct iwl_scan_channel)));
332 hcmd.len[0] = le16_to_cpu(cmd->len);
333
334 status = SCAN_RESPONSE_OK;
335 ret = iwl_mvm_send_cmd_status(mvm, &hcmd, &status);
336 if (!ret && status == SCAN_RESPONSE_OK) {
337 IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
338 } else {
339 /*
340 * If the scan failed, it usually means that the FW was unable
341 * to allocate the time events. Warn on it, but maybe we
342 * should try to send the command again with different params.
343 */
344 IWL_ERR(mvm, "Scan failed! status 0x%x ret %d\n",
345 status, ret);
346 mvm->scan_status = IWL_MVM_SCAN_NONE;
347 ret = -EIO;
348 }
349 return ret;
350}
351
352int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
353 struct iwl_device_cmd *cmd)
354{
355 struct iwl_rx_packet *pkt = rxb_addr(rxb);
356 struct iwl_cmd_response *resp = (void *)pkt->data;
357
358 IWL_DEBUG_SCAN(mvm, "Scan response received. status 0x%x\n",
359 le32_to_cpu(resp->status));
360 return 0;
361}
362
363int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
364 struct iwl_device_cmd *cmd)
365{
366 struct iwl_rx_packet *pkt = rxb_addr(rxb);
367 struct iwl_scan_complete_notif *notif = (void *)pkt->data;
368
369 IWL_DEBUG_SCAN(mvm, "Scan complete: status=0x%x scanned channels=%d\n",
370 notif->status, notif->scanned_channels);
371
372 mvm->scan_status = IWL_MVM_SCAN_NONE;
373 ieee80211_scan_completed(mvm->hw, notif->status != SCAN_COMP_STATUS_OK);
374
375 return 0;
376}
377
378static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
379 struct iwl_rx_packet *pkt, void *data)
380{
381 struct iwl_mvm *mvm =
382 container_of(notif_wait, struct iwl_mvm, notif_wait);
383 struct iwl_scan_complete_notif *notif;
384 u32 *resp;
385
386 switch (pkt->hdr.cmd) {
387 case SCAN_ABORT_CMD:
388 resp = (void *)pkt->data;
389 if (*resp == CAN_ABORT_STATUS) {
390 IWL_DEBUG_SCAN(mvm,
391 "Scan can be aborted, wait until completion\n");
392 return false;
393 }
394
395 IWL_DEBUG_SCAN(mvm, "Scan cannot be aborted, exit now: %d\n",
396 *resp);
397 return true;
398
399 case SCAN_COMPLETE_NOTIFICATION:
400 notif = (void *)pkt->data;
401 IWL_DEBUG_SCAN(mvm, "Scan aborted: status 0x%x\n",
402 notif->status);
403 return true;
404
405 default:
406 WARN_ON(1);
407 return false;
408 };
409}
410
411void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
412{
413 struct iwl_notification_wait wait_scan_abort;
414 static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD,
415 SCAN_COMPLETE_NOTIFICATION };
416 int ret;
417
418 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
419 scan_abort_notif,
420 ARRAY_SIZE(scan_abort_notif),
421 iwl_mvm_scan_abort_notif, NULL);
422
423 ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, CMD_SYNC, 0, NULL);
424 if (ret) {
425 IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret);
426 goto out_remove_notif;
427 }
428
429 ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_abort, 1 * HZ);
430 if (ret)
431 IWL_ERR(mvm, "%s - failed on timeout\n", __func__);
432
433 return;
434
435out_remove_notif:
436 iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort);
437}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
new file mode 100644
index 000000000000..69603c3b2b39
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -0,0 +1,1211 @@
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 LICENSE.GPL.
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#include <net/mac80211.h>
64
65#include "mvm.h"
66#include "sta.h"
67
68static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm)
69{
70 int sta_id;
71
72 WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status));
73
74 lockdep_assert_held(&mvm->mutex);
75
76 /* Don't take rcu_read_lock() since we are protected by mvm->mutex */
77 for (sta_id = 0; sta_id < IWL_MVM_STATION_COUNT; sta_id++)
78 if (!rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
79 lockdep_is_held(&mvm->mutex)))
80 return sta_id;
81 return IWL_MVM_STATION_COUNT;
82}
83
84/* add a NEW station to fw */
85int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta)
86{
87 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
88 struct iwl_mvm_add_sta_cmd add_sta_cmd;
89 int ret;
90 u32 status;
91 u32 agg_size = 0, mpdu_dens = 0;
92
93 memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
94
95 add_sta_cmd.sta_id = mvm_sta->sta_id;
96 add_sta_cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
97 add_sta_cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk);
98 memcpy(&add_sta_cmd.addr, sta->addr, ETH_ALEN);
99
100 /* STA_FLG_FAT_EN_MSK ? */
101 /* STA_FLG_MIMO_EN_MSK ? */
102
103 if (sta->ht_cap.ht_supported) {
104 add_sta_cmd.station_flags_msk |=
105 cpu_to_le32(STA_FLG_MAX_AGG_SIZE_MSK |
106 STA_FLG_AGG_MPDU_DENS_MSK);
107
108 mpdu_dens = sta->ht_cap.ampdu_density;
109 }
110
111 if (sta->vht_cap.vht_supported) {
112 agg_size = sta->vht_cap.cap &
113 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
114 agg_size >>=
115 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
116 } else if (sta->ht_cap.ht_supported) {
117 agg_size = sta->ht_cap.ampdu_factor;
118 }
119
120 add_sta_cmd.station_flags |=
121 cpu_to_le32(agg_size << STA_FLG_MAX_AGG_SIZE_SHIFT);
122 add_sta_cmd.station_flags |=
123 cpu_to_le32(mpdu_dens << STA_FLG_AGG_MPDU_DENS_SHIFT);
124
125 status = ADD_STA_SUCCESS;
126 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(add_sta_cmd),
127 &add_sta_cmd, &status);
128 if (ret)
129 return ret;
130
131 switch (status) {
132 case ADD_STA_SUCCESS:
133 IWL_DEBUG_ASSOC(mvm, "ADD_STA PASSED\n");
134 break;
135 default:
136 ret = -EIO;
137 IWL_ERR(mvm, "ADD_STA failed\n");
138 break;
139 }
140
141 return ret;
142}
143
144int iwl_mvm_add_sta(struct iwl_mvm *mvm,
145 struct ieee80211_vif *vif,
146 struct ieee80211_sta *sta)
147{
148 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
149 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
150 int i, ret, sta_id;
151
152 lockdep_assert_held(&mvm->mutex);
153
154 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
155 sta_id = iwl_mvm_find_free_sta_id(mvm);
156 else
157 sta_id = mvm_sta->sta_id;
158
159 if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT))
160 return -ENOSPC;
161
162 spin_lock_init(&mvm_sta->lock);
163
164 mvm_sta->sta_id = sta_id;
165 mvm_sta->mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id,
166 mvmvif->color);
167 mvm_sta->vif = vif;
168 mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
169
170 /* HW restart, don't assume the memory has been zeroed */
171 atomic_set(&mvm_sta->pending_frames, 0);
172 mvm_sta->tid_disable_agg = 0;
173 mvm_sta->tfd_queue_msk = 0;
174 for (i = 0; i < IEEE80211_NUM_ACS; i++)
175 if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE)
176 mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]);
177
178 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
179 mvm_sta->tfd_queue_msk |= BIT(vif->cab_queue);
180
181 /* for HW restart - need to reset the seq_number etc... */
182 memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data));
183
184 ret = iwl_mvm_sta_add_to_fw(mvm, sta);
185 if (ret)
186 return ret;
187
188 /* The first station added is the AP, the others are TDLS STAs */
189 if (vif->type == NL80211_IFTYPE_STATION &&
190 mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
191 mvmvif->ap_sta_id = sta_id;
192
193 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta);
194
195 return 0;
196}
197
198int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
199 bool drain)
200{
201 struct iwl_mvm_add_sta_cmd cmd = {};
202 int ret;
203 u32 status;
204
205 lockdep_assert_held(&mvm->mutex);
206
207 cmd.mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color);
208 cmd.sta_id = mvmsta->sta_id;
209 cmd.add_modify = STA_MODE_MODIFY;
210 cmd.station_flags = drain ? cpu_to_le32(STA_FLG_DRAIN_FLOW) : 0;
211 cmd.station_flags_msk = cpu_to_le32(STA_FLG_DRAIN_FLOW);
212
213 status = ADD_STA_SUCCESS;
214 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
215 &cmd, &status);
216 if (ret)
217 return ret;
218
219 switch (status) {
220 case ADD_STA_SUCCESS:
221 IWL_DEBUG_INFO(mvm, "Frames for staid %d will drained in fw\n",
222 mvmsta->sta_id);
223 break;
224 default:
225 ret = -EIO;
226 IWL_ERR(mvm, "Couldn't drain frames for staid %d\n",
227 mvmsta->sta_id);
228 break;
229 }
230
231 return ret;
232}
233
234/*
235 * Remove a station from the FW table. Before sending the command to remove
236 * the station validate that the station is indeed known to the driver (sanity
237 * only).
238 */
239static int iwl_mvm_rm_sta_common(struct iwl_mvm *mvm, u8 sta_id)
240{
241 struct ieee80211_sta *sta;
242 struct iwl_mvm_rm_sta_cmd rm_sta_cmd = {
243 .sta_id = sta_id,
244 };
245 int ret;
246
247 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
248 lockdep_is_held(&mvm->mutex));
249
250 /* Note: internal stations are marked as error values */
251 if (!sta) {
252 IWL_ERR(mvm, "Invalid station id\n");
253 return -EINVAL;
254 }
255
256 ret = iwl_mvm_send_cmd_pdu(mvm, REMOVE_STA, CMD_SYNC,
257 sizeof(rm_sta_cmd), &rm_sta_cmd);
258 if (ret) {
259 IWL_ERR(mvm, "Failed to remove station. Id=%d\n", sta_id);
260 return ret;
261 }
262
263 return 0;
264}
265
266void iwl_mvm_sta_drained_wk(struct work_struct *wk)
267{
268 struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, sta_drained_wk);
269 u8 sta_id;
270
271 /*
272 * The mutex is needed because of the SYNC cmd, but not only: if the
273 * work would run concurrently with iwl_mvm_rm_sta, it would run before
274 * iwl_mvm_rm_sta sets the station as busy, and exit. Then
275 * iwl_mvm_rm_sta would set the station as busy, and nobody will clean
276 * that later.
277 */
278 mutex_lock(&mvm->mutex);
279
280 for_each_set_bit(sta_id, mvm->sta_drained, IWL_MVM_STATION_COUNT) {
281 int ret;
282 struct ieee80211_sta *sta =
283 rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
284 lockdep_is_held(&mvm->mutex));
285
286 /* This station is in use */
287 if (!IS_ERR(sta))
288 continue;
289
290 if (PTR_ERR(sta) == -EINVAL) {
291 IWL_ERR(mvm, "Drained sta %d, but it is internal?\n",
292 sta_id);
293 continue;
294 }
295
296 if (!sta) {
297 IWL_ERR(mvm, "Drained sta %d, but it was NULL?\n",
298 sta_id);
299 continue;
300 }
301
302 WARN_ON(PTR_ERR(sta) != -EBUSY);
303 /* This station was removed and we waited until it got drained,
304 * we can now proceed and remove it.
305 */
306 ret = iwl_mvm_rm_sta_common(mvm, sta_id);
307 if (ret) {
308 IWL_ERR(mvm,
309 "Couldn't remove sta %d after it was drained\n",
310 sta_id);
311 continue;
312 }
313 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], NULL);
314 clear_bit(sta_id, mvm->sta_drained);
315 }
316
317 mutex_unlock(&mvm->mutex);
318}
319
320int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
321 struct ieee80211_vif *vif,
322 struct ieee80211_sta *sta)
323{
324 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
325 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
326 int ret;
327
328 lockdep_assert_held(&mvm->mutex);
329
330 if (vif->type == NL80211_IFTYPE_STATION &&
331 mvmvif->ap_sta_id == mvm_sta->sta_id) {
332 /*
333 * Put a non-NULL since the fw station isn't removed.
334 * It will be removed after the MAC will be set as
335 * unassoc.
336 */
337 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
338 ERR_PTR(-EINVAL));
339
340 /* flush its queues here since we are freeing mvm_sta */
341 ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);
342
343 /* if we are associated - we can't remove the AP STA now */
344 if (vif->bss_conf.assoc)
345 return ret;
346
347 /* unassoc - go ahead - remove the AP STA now */
348 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
349 }
350
351 /*
352 * There are frames pending on the AC queues for this station.
353 * We need to wait until all the frames are drained...
354 */
355 if (atomic_read(&mvm_sta->pending_frames)) {
356 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
357 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
358 ERR_PTR(-EBUSY));
359 } else {
360 ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id);
361 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
362 }
363
364 return ret;
365}
366
367int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
368 struct ieee80211_vif *vif,
369 u8 sta_id)
370{
371 int ret = iwl_mvm_rm_sta_common(mvm, sta_id);
372
373 lockdep_assert_held(&mvm->mutex);
374
375 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], NULL);
376 return ret;
377}
378
379int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
380 u32 qmask)
381{
382 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
383 sta->sta_id = iwl_mvm_find_free_sta_id(mvm);
384 if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_STATION_COUNT))
385 return -ENOSPC;
386 }
387
388 sta->tfd_queue_msk = qmask;
389
390 /* put a non-NULL value so iterating over the stations won't stop */
391 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta->sta_id], ERR_PTR(-EINVAL));
392 return 0;
393}
394
395void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
396{
397 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta->sta_id], NULL);
398 memset(sta, 0, sizeof(struct iwl_mvm_int_sta));
399 sta->sta_id = IWL_MVM_STATION_COUNT;
400}
401
402static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
403 struct iwl_mvm_int_sta *sta,
404 const u8 *addr,
405 u16 mac_id, u16 color)
406{
407 struct iwl_mvm_add_sta_cmd cmd;
408 int ret;
409 u32 status;
410
411 lockdep_assert_held(&mvm->mutex);
412
413 memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd));
414 cmd.sta_id = sta->sta_id;
415 cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
416 color));
417
418 cmd.tfd_queue_msk = cpu_to_le32(sta->tfd_queue_msk);
419
420 if (addr)
421 memcpy(cmd.addr, addr, ETH_ALEN);
422
423 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
424 &cmd, &status);
425 if (ret)
426 return ret;
427
428 switch (status) {
429 case ADD_STA_SUCCESS:
430 IWL_DEBUG_INFO(mvm, "Internal station added.\n");
431 return 0;
432 default:
433 ret = -EIO;
434 IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
435 status);
436 break;
437 }
438 return ret;
439}
440
441int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
442{
443 int ret;
444
445 lockdep_assert_held(&mvm->mutex);
446
447 /* Add the aux station, but without any queues */
448 ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, 0);
449 if (ret)
450 return ret;
451
452 ret = iwl_mvm_add_int_sta_common(mvm, &mvm->aux_sta, NULL,
453 MAC_INDEX_AUX, 0);
454
455 if (ret)
456 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
457 return ret;
458}
459
460/*
461 * Send the add station command for the vif's broadcast station.
462 * Assumes that the station was already allocated.
463 *
464 * @mvm: the mvm component
465 * @vif: the interface to which the broadcast station is added
466 * @bsta: the broadcast station to add.
467 */
468int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
469 struct iwl_mvm_int_sta *bsta)
470{
471 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
472 static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
473
474 lockdep_assert_held(&mvm->mutex);
475
476 if (WARN_ON_ONCE(bsta->sta_id == IWL_MVM_STATION_COUNT))
477 return -ENOSPC;
478
479 return iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
480 mvmvif->id, mvmvif->color);
481}
482
483/* Send the FW a request to remove the station from it's internal data
484 * structures, but DO NOT remove the entry from the local data structures. */
485int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
486 struct iwl_mvm_int_sta *bsta)
487{
488 int ret;
489
490 lockdep_assert_held(&mvm->mutex);
491
492 ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
493 if (ret)
494 IWL_WARN(mvm, "Failed sending remove station\n");
495 return ret;
496}
497
498/* Allocate a new station entry for the broadcast station to the given vif,
499 * and send it to the FW.
500 * Note that each P2P mac should have its own broadcast station.
501 *
502 * @mvm: the mvm component
503 * @vif: the interface to which the broadcast station is added
504 * @bsta: the broadcast station to add. */
505int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
506 struct iwl_mvm_int_sta *bsta)
507{
508 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
509 static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
510 u32 qmask;
511 int ret;
512
513 lockdep_assert_held(&mvm->mutex);
514
515 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
516 ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask);
517 if (ret)
518 return ret;
519
520 ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
521 mvmvif->id, mvmvif->color);
522
523 if (ret)
524 iwl_mvm_dealloc_int_sta(mvm, bsta);
525 return ret;
526}
527
528/*
529 * Send the FW a request to remove the station from it's internal data
530 * structures, and in addition remove it from the local data structure.
531 */
532int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta)
533{
534 int ret;
535
536 lockdep_assert_held(&mvm->mutex);
537
538 ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
539 if (ret)
540 return ret;
541
542 iwl_mvm_dealloc_int_sta(mvm, bsta);
543 return ret;
544}
545
546int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
547 int tid, u16 ssn, bool start)
548{
549 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
550 struct iwl_mvm_add_sta_cmd cmd = {};
551 int ret;
552 u32 status;
553
554 lockdep_assert_held(&mvm->mutex);
555
556 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
557 cmd.sta_id = mvm_sta->sta_id;
558 cmd.add_modify = STA_MODE_MODIFY;
559 cmd.add_immediate_ba_tid = (u8) tid;
560 cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
561 cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID :
562 STA_MODIFY_REMOVE_BA_TID;
563
564 status = ADD_STA_SUCCESS;
565 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
566 &cmd, &status);
567 if (ret)
568 return ret;
569
570 switch (status) {
571 case ADD_STA_SUCCESS:
572 IWL_DEBUG_INFO(mvm, "RX BA Session %sed in fw\n",
573 start ? "start" : "stopp");
574 break;
575 case ADD_STA_IMMEDIATE_BA_FAILURE:
576 IWL_WARN(mvm, "RX BA Session refused by fw\n");
577 ret = -ENOSPC;
578 break;
579 default:
580 ret = -EIO;
581 IWL_ERR(mvm, "RX BA Session failed %sing, status 0x%x\n",
582 start ? "start" : "stopp", status);
583 break;
584 }
585
586 return ret;
587}
588
589static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
590 int tid, u8 queue, bool start)
591{
592 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
593 struct iwl_mvm_add_sta_cmd cmd = {};
594 int ret;
595 u32 status;
596
597 lockdep_assert_held(&mvm->mutex);
598
599 if (start) {
600 mvm_sta->tfd_queue_msk |= BIT(queue);
601 mvm_sta->tid_disable_agg &= ~BIT(tid);
602 } else {
603 mvm_sta->tfd_queue_msk &= ~BIT(queue);
604 mvm_sta->tid_disable_agg |= BIT(tid);
605 }
606
607 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
608 cmd.sta_id = mvm_sta->sta_id;
609 cmd.add_modify = STA_MODE_MODIFY;
610 cmd.modify_mask = STA_MODIFY_QUEUES | STA_MODIFY_TID_DISABLE_TX;
611 cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk);
612 cmd.tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg);
613
614 status = ADD_STA_SUCCESS;
615 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
616 &cmd, &status);
617 if (ret)
618 return ret;
619
620 switch (status) {
621 case ADD_STA_SUCCESS:
622 break;
623 default:
624 ret = -EIO;
625 IWL_ERR(mvm, "TX BA Session failed %sing, status 0x%x\n",
626 start ? "start" : "stopp", status);
627 break;
628 }
629
630 return ret;
631}
632
633static const u8 tid_to_ac[] = {
634 IEEE80211_AC_BE,
635 IEEE80211_AC_BK,
636 IEEE80211_AC_BK,
637 IEEE80211_AC_BE,
638 IEEE80211_AC_VI,
639 IEEE80211_AC_VI,
640 IEEE80211_AC_VO,
641 IEEE80211_AC_VO,
642};
643
644int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
645 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
646{
647 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
648 struct iwl_mvm_tid_data *tid_data;
649 int txq_id;
650
651 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
652 return -EINVAL;
653
654 if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) {
655 IWL_ERR(mvm, "Start AGG when state is not IWL_AGG_OFF %d!\n",
656 mvmsta->tid_data[tid].state);
657 return -ENXIO;
658 }
659
660 lockdep_assert_held(&mvm->mutex);
661
662 for (txq_id = IWL_MVM_FIRST_AGG_QUEUE;
663 txq_id <= IWL_MVM_LAST_AGG_QUEUE; txq_id++)
664 if (mvm->queue_to_mac80211[txq_id] ==
665 IWL_INVALID_MAC80211_QUEUE)
666 break;
667
668 if (txq_id > IWL_MVM_LAST_AGG_QUEUE) {
669 IWL_ERR(mvm, "Failed to allocate agg queue\n");
670 return -EIO;
671 }
672
673 /* the new tx queue is still connected to the same mac80211 queue */
674 mvm->queue_to_mac80211[txq_id] = vif->hw_queue[tid_to_ac[tid]];
675
676 spin_lock_bh(&mvmsta->lock);
677 tid_data = &mvmsta->tid_data[tid];
678 tid_data->ssn = SEQ_TO_SN(tid_data->seq_number);
679 tid_data->txq_id = txq_id;
680 *ssn = tid_data->ssn;
681
682 IWL_DEBUG_TX_QUEUES(mvm,
683 "Start AGG: sta %d tid %d queue %d - ssn = %d, next_recl = %d\n",
684 mvmsta->sta_id, tid, txq_id, tid_data->ssn,
685 tid_data->next_reclaimed);
686
687 if (tid_data->ssn == tid_data->next_reclaimed) {
688 tid_data->state = IWL_AGG_STARTING;
689 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
690 } else {
691 tid_data->state = IWL_EMPTYING_HW_QUEUE_ADDBA;
692 }
693
694 spin_unlock_bh(&mvmsta->lock);
695
696 return 0;
697}
698
699int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
700 struct ieee80211_sta *sta, u16 tid, u8 buf_size)
701{
702 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
703 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
704 int queue, fifo, ret;
705 u16 ssn;
706
707 buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
708
709 spin_lock_bh(&mvmsta->lock);
710 ssn = tid_data->ssn;
711 queue = tid_data->txq_id;
712 tid_data->state = IWL_AGG_ON;
713 tid_data->ssn = 0xffff;
714 spin_unlock_bh(&mvmsta->lock);
715
716 fifo = iwl_mvm_ac_to_tx_fifo[tid_to_ac[tid]];
717
718 ret = iwl_mvm_sta_tx_agg(mvm, sta, tid, queue, true);
719 if (ret)
720 return -EIO;
721
722 iwl_trans_txq_enable(mvm->trans, queue, fifo, mvmsta->sta_id, tid,
723 buf_size, ssn);
724
725 /*
726 * Even though in theory the peer could have different
727 * aggregation reorder buffer sizes for different sessions,
728 * our ucode doesn't allow for that and has a global limit
729 * for each station. Therefore, use the minimum of all the
730 * aggregation sessions and our default value.
731 */
732 mvmsta->max_agg_bufsize =
733 min(mvmsta->max_agg_bufsize, buf_size);
734 mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize;
735
736 if (mvm->cfg->ht_params->use_rts_for_aggregation) {
737 /*
738 * switch to RTS/CTS if it is the prefer protection
739 * method for HT traffic
740 */
741 mvmsta->lq_sta.lq.flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK;
742 /*
743 * TODO: remove the TLC_RTS flag when we tear down the last
744 * AGG session (agg_tids_count in DVM)
745 */
746 }
747
748 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
749 sta->addr, tid);
750
751 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
752}
753
754int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
755 struct ieee80211_sta *sta, u16 tid)
756{
757 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
758 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
759 u16 txq_id;
760 int err;
761
762 spin_lock_bh(&mvmsta->lock);
763
764 txq_id = tid_data->txq_id;
765
766 IWL_DEBUG_TX_QUEUES(mvm, "Stop AGG: sta %d tid %d q %d state %d\n",
767 mvmsta->sta_id, tid, txq_id, tid_data->state);
768
769 switch (tid_data->state) {
770 case IWL_AGG_ON:
771 tid_data->ssn = SEQ_TO_SN(tid_data->seq_number);
772
773 IWL_DEBUG_TX_QUEUES(mvm,
774 "ssn = %d, next_recl = %d\n",
775 tid_data->ssn, tid_data->next_reclaimed);
776
777 /* There are still packets for this RA / TID in the HW */
778 if (tid_data->ssn != tid_data->next_reclaimed) {
779 tid_data->state = IWL_EMPTYING_HW_QUEUE_DELBA;
780 err = 0;
781 break;
782 }
783
784 tid_data->ssn = 0xffff;
785 iwl_trans_txq_disable(mvm->trans, txq_id);
786 /* fall through */
787 case IWL_AGG_STARTING:
788 case IWL_EMPTYING_HW_QUEUE_ADDBA:
789 /*
790 * The agg session has been stopped before it was set up. This
791 * can happen when the AddBA timer times out for example.
792 */
793
794 /* No barriers since we are under mutex */
795 lockdep_assert_held(&mvm->mutex);
796 mvm->queue_to_mac80211[txq_id] = IWL_INVALID_MAC80211_QUEUE;
797
798 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
799 tid_data->state = IWL_AGG_OFF;
800 err = 0;
801 break;
802 default:
803 IWL_ERR(mvm,
804 "Stopping AGG while state not ON or starting for %d on %d (%d)\n",
805 mvmsta->sta_id, tid, tid_data->state);
806 IWL_ERR(mvm,
807 "\ttid_data->txq_id = %d\n", tid_data->txq_id);
808 err = -EINVAL;
809 }
810
811 spin_unlock_bh(&mvmsta->lock);
812
813 return err;
814}
815
816static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
817{
818 int i;
819
820 lockdep_assert_held(&mvm->mutex);
821
822 i = find_first_zero_bit(mvm->fw_key_table, STA_KEY_MAX_NUM);
823
824 if (i == STA_KEY_MAX_NUM)
825 return STA_KEY_IDX_INVALID;
826
827 __set_bit(i, mvm->fw_key_table);
828
829 return i;
830}
831
832static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
833 struct ieee80211_sta *sta)
834{
835 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
836
837 if (sta) {
838 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
839
840 return mvm_sta->sta_id;
841 }
842
843 /*
844 * The device expects GTKs for station interfaces to be
845 * installed as GTKs for the AP station. If we have no
846 * station ID, then use AP's station ID.
847 */
848 if (vif->type == NL80211_IFTYPE_STATION &&
849 mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT)
850 return mvmvif->ap_sta_id;
851
852 return IWL_INVALID_STATION;
853}
854
855static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
856 struct iwl_mvm_sta *mvm_sta,
857 struct ieee80211_key_conf *keyconf,
858 u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k,
859 u32 cmd_flags)
860{
861 __le16 key_flags;
862 struct iwl_mvm_add_sta_cmd cmd = {};
863 int ret, status;
864 u16 keyidx;
865 int i;
866
867 keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
868 STA_KEY_FLG_KEYID_MSK;
869 key_flags = cpu_to_le16(keyidx);
870 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_KEY_MAP);
871
872 switch (keyconf->cipher) {
873 case WLAN_CIPHER_SUITE_TKIP:
874 key_flags |= cpu_to_le16(STA_KEY_FLG_TKIP);
875 cmd.key.tkip_rx_tsc_byte2 = tkip_iv32;
876 for (i = 0; i < 5; i++)
877 cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]);
878 memcpy(cmd.key.key, keyconf->key, keyconf->keylen);
879 break;
880 case WLAN_CIPHER_SUITE_CCMP:
881 key_flags |= cpu_to_le16(STA_KEY_FLG_CCM);
882 memcpy(cmd.key.key, keyconf->key, keyconf->keylen);
883 break;
884 default:
885 WARN_ON(1);
886 return -EINVAL;
887 }
888
889 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
890 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
891
892 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
893 cmd.key.key_offset = keyconf->hw_key_idx;
894 cmd.key.key_flags = key_flags;
895 cmd.add_modify = STA_MODE_MODIFY;
896 cmd.modify_mask = STA_MODIFY_KEY;
897 cmd.sta_id = sta_id;
898
899 status = ADD_STA_SUCCESS;
900 if (cmd_flags == CMD_SYNC)
901 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
902 &cmd, &status);
903 else
904 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC,
905 sizeof(cmd), &cmd);
906
907 switch (status) {
908 case ADD_STA_SUCCESS:
909 IWL_DEBUG_WEP(mvm, "MODIFY_STA: set dynamic key passed\n");
910 break;
911 default:
912 ret = -EIO;
913 IWL_ERR(mvm, "MODIFY_STA: set dynamic key failed\n");
914 break;
915 }
916
917 return ret;
918}
919
920static int iwl_mvm_send_sta_igtk(struct iwl_mvm *mvm,
921 struct ieee80211_key_conf *keyconf,
922 u8 sta_id, bool remove_key)
923{
924 struct iwl_mvm_mgmt_mcast_key_cmd igtk_cmd = {};
925
926 /* verify the key details match the required command's expectations */
927 if (WARN_ON((keyconf->cipher != WLAN_CIPHER_SUITE_AES_CMAC) ||
928 (keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE) ||
929 (keyconf->keyidx != 4 && keyconf->keyidx != 5)))
930 return -EINVAL;
931
932 igtk_cmd.key_id = cpu_to_le32(keyconf->keyidx);
933 igtk_cmd.sta_id = cpu_to_le32(sta_id);
934
935 if (remove_key) {
936 igtk_cmd.ctrl_flags |= cpu_to_le32(STA_KEY_NOT_VALID);
937 } else {
938 struct ieee80211_key_seq seq;
939 const u8 *pn;
940
941 memcpy(igtk_cmd.IGTK, keyconf->key, keyconf->keylen);
942 ieee80211_aes_cmac_calculate_k1_k2(keyconf,
943 igtk_cmd.K1, igtk_cmd.K2);
944 ieee80211_get_key_rx_seq(keyconf, 0, &seq);
945 pn = seq.aes_cmac.pn;
946 igtk_cmd.receive_seq_cnt = cpu_to_le64(((u64) pn[5] << 0) |
947 ((u64) pn[4] << 8) |
948 ((u64) pn[3] << 16) |
949 ((u64) pn[2] << 24) |
950 ((u64) pn[1] << 32) |
951 ((u64) pn[0] << 40));
952 }
953
954 IWL_DEBUG_INFO(mvm, "%s igtk for sta %u\n",
955 remove_key ? "removing" : "installing",
956 igtk_cmd.sta_id);
957
958 return iwl_mvm_send_cmd_pdu(mvm, MGMT_MCAST_KEY, CMD_SYNC,
959 sizeof(igtk_cmd), &igtk_cmd);
960}
961
962
963static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
964 struct ieee80211_vif *vif,
965 struct ieee80211_sta *sta)
966{
967 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
968
969 if (sta)
970 return sta->addr;
971
972 if (vif->type == NL80211_IFTYPE_STATION &&
973 mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
974 u8 sta_id = mvmvif->ap_sta_id;
975 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
976 lockdep_is_held(&mvm->mutex));
977 return sta->addr;
978 }
979
980
981 return NULL;
982}
983
984int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
985 struct ieee80211_vif *vif,
986 struct ieee80211_sta *sta,
987 struct ieee80211_key_conf *keyconf,
988 bool have_key_offset)
989{
990 struct iwl_mvm_sta *mvm_sta;
991 int ret;
992 u8 *addr, sta_id;
993 struct ieee80211_key_seq seq;
994 u16 p1k[5];
995
996 lockdep_assert_held(&mvm->mutex);
997
998 /* Get the station id from the mvm local station table */
999 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1000 if (sta_id == IWL_INVALID_STATION) {
1001 IWL_ERR(mvm, "Failed to find station id\n");
1002 return -EINVAL;
1003 }
1004
1005 if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
1006 ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, false);
1007 goto end;
1008 }
1009
1010 /*
1011 * It is possible that the 'sta' parameter is NULL, and thus
1012 * there is a need to retrieve the sta from the local station table.
1013 */
1014 if (!sta) {
1015 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1016 lockdep_is_held(&mvm->mutex));
1017 if (IS_ERR_OR_NULL(sta)) {
1018 IWL_ERR(mvm, "Invalid station id\n");
1019 return -EINVAL;
1020 }
1021 }
1022
1023 mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv;
1024 if (WARN_ON_ONCE(mvm_sta->vif != vif))
1025 return -EINVAL;
1026
1027 if (!have_key_offset) {
1028 /*
1029 * The D3 firmware hardcodes the PTK offset to 0, so we have to
1030 * configure it there. As a result, this workaround exists to
1031 * let the caller set the key offset (hw_key_idx), see d3.c.
1032 */
1033 keyconf->hw_key_idx = iwl_mvm_set_fw_key_idx(mvm);
1034 if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID)
1035 return -ENOSPC;
1036 }
1037
1038 switch (keyconf->cipher) {
1039 case WLAN_CIPHER_SUITE_TKIP:
1040 addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
1041 /* get phase 1 key from mac80211 */
1042 ieee80211_get_key_rx_seq(keyconf, 0, &seq);
1043 ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
1044 ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1045 seq.tkip.iv32, p1k, CMD_SYNC);
1046 break;
1047 case WLAN_CIPHER_SUITE_CCMP:
1048 ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1049 0, NULL, CMD_SYNC);
1050 break;
1051 default:
1052 IWL_ERR(mvm, "Unknown cipher %x\n", keyconf->cipher);
1053 ret = -EINVAL;
1054 }
1055
1056 if (ret)
1057 __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
1058
1059end:
1060 IWL_DEBUG_WEP(mvm, "key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n",
1061 keyconf->cipher, keyconf->keylen, keyconf->keyidx,
1062 sta->addr, ret);
1063 return ret;
1064}
1065
1066int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1067 struct ieee80211_vif *vif,
1068 struct ieee80211_sta *sta,
1069 struct ieee80211_key_conf *keyconf)
1070{
1071 struct iwl_mvm_sta *mvm_sta;
1072 struct iwl_mvm_add_sta_cmd cmd = {};
1073 __le16 key_flags;
1074 int ret, status;
1075 u8 sta_id;
1076
1077 lockdep_assert_held(&mvm->mutex);
1078
1079 /* Get the station id from the mvm local station table */
1080 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1081
1082 IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
1083 keyconf->keyidx, sta_id);
1084
1085 if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
1086 return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
1087
1088 ret = __test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
1089 if (!ret) {
1090 IWL_ERR(mvm, "offset %d not used in fw key table.\n",
1091 keyconf->hw_key_idx);
1092 return -ENOENT;
1093 }
1094
1095 if (sta_id == IWL_INVALID_STATION) {
1096 IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n");
1097 return 0;
1098 }
1099
1100 /*
1101 * It is possible that the 'sta' parameter is NULL, and thus
1102 * there is a need to retrieve the sta from the local station table,
1103 * for example when a GTK is removed (where the sta_id will then be
1104 * the AP ID, and no station was passed by mac80211.)
1105 */
1106 if (!sta) {
1107 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1108 lockdep_is_held(&mvm->mutex));
1109 if (!sta) {
1110 IWL_ERR(mvm, "Invalid station id\n");
1111 return -EINVAL;
1112 }
1113 }
1114
1115 mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv;
1116 if (WARN_ON_ONCE(mvm_sta->vif != vif))
1117 return -EINVAL;
1118
1119 key_flags = cpu_to_le16(keyconf->keyidx & STA_KEY_FLG_KEYID_MSK);
1120 key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP);
1121 key_flags |= cpu_to_le16(STA_KEY_NOT_VALID);
1122
1123 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1124 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
1125
1126 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
1127 cmd.key.key_flags = key_flags;
1128 cmd.key.key_offset = keyconf->hw_key_idx;
1129 cmd.sta_id = sta_id;
1130
1131 cmd.modify_mask = STA_MODIFY_KEY;
1132 cmd.add_modify = STA_MODE_MODIFY;
1133
1134 status = ADD_STA_SUCCESS;
1135 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
1136 &cmd, &status);
1137
1138 switch (status) {
1139 case ADD_STA_SUCCESS:
1140 IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n");
1141 break;
1142 default:
1143 ret = -EIO;
1144 IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n");
1145 break;
1146 }
1147
1148 return ret;
1149}
1150
1151void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1152 struct ieee80211_vif *vif,
1153 struct ieee80211_key_conf *keyconf,
1154 struct ieee80211_sta *sta, u32 iv32,
1155 u16 *phase1key)
1156{
1157 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1158 u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1159
1160 if (sta_id == IWL_INVALID_STATION)
1161 return;
1162
1163 iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1164 iv32, phase1key, CMD_ASYNC);
1165}
1166
1167void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id)
1168{
1169 struct iwl_mvm_add_sta_cmd cmd = {
1170 .add_modify = STA_MODE_MODIFY,
1171 .sta_id = sta_id,
1172 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
1173 .sleep_state_flags = cpu_to_le16(STA_SLEEP_STATE_AWAKE),
1174 };
1175 int ret;
1176
1177 /*
1178 * Same modify mask for sleep_tx_count and sleep_state_flags but this
1179 * should be fine since if we set the STA as "awake", then
1180 * sleep_tx_count is not relevant.
1181 */
1182 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
1183 if (ret)
1184 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1185}
1186
1187void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm, int sta_id,
1188 enum ieee80211_frame_release_type reason,
1189 u16 cnt)
1190{
1191 u16 sleep_state_flags =
1192 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
1193 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
1194 struct iwl_mvm_add_sta_cmd cmd = {
1195 .add_modify = STA_MODE_MODIFY,
1196 .sta_id = sta_id,
1197 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
1198 .sleep_tx_count = cpu_to_le16(cnt),
1199 /*
1200 * Same modify mask for sleep_tx_count and sleep_state_flags so
1201 * we must set the sleep_state_flags too.
1202 */
1203 .sleep_state_flags = cpu_to_le16(sleep_state_flags),
1204 };
1205 int ret;
1206
1207 /* TODO: somehow the fw doesn't seem to take PS_POLL into account */
1208 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
1209 if (ret)
1210 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1211}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
new file mode 100644
index 000000000000..1bf301097984
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -0,0 +1,368 @@
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 LICENSE.GPL.
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#ifndef __sta_h__
65#define __sta_h__
66
67#include <linux/spinlock.h>
68#include <net/mac80211.h>
69#include <linux/wait.h>
70
71#include "iwl-trans.h" /* for IWL_MAX_TID_COUNT */
72#include "fw-api.h" /* IWL_MVM_STATION_COUNT */
73#include "rs.h"
74
75struct iwl_mvm;
76
77/**
78 * DOC: station table - introduction
79 *
80 * The station table is a list of data structure that reprensent the stations.
81 * In STA/P2P client mode, the driver will hold one station for the AP/ GO.
82 * In GO/AP mode, the driver will have as many stations as associated clients.
83 * All these stations are reflected in the fw's station table. The driver
84 * keeps the fw's station table up to date with the ADD_STA command. Stations
85 * can be removed by the REMOVE_STA command.
86 *
87 * All the data related to a station is held in the structure %iwl_mvm_sta
88 * which is embed in the mac80211's %ieee80211_sta (in the drv_priv) area.
89 * This data includes the index of the station in the fw, per tid information
90 * (sequence numbers, Block-ack state machine, etc...). The stations are
91 * created and deleted by the %sta_state callback from %ieee80211_ops.
92 *
93 * The driver holds a map: %fw_id_to_mac_id that allows to fetch a
94 * %ieee80211_sta (and the %iwl_mvm_sta embedded into it) based on a fw
95 * station index. That way, the driver is able to get the tid related data in
96 * O(1) in time sensitive paths (Tx / Tx response / BA notification). These
97 * paths are triggered by the fw, and the driver needs to get a pointer to the
98 * %ieee80211 structure. This map helps to get that pointer quickly.
99 */
100
101/**
102 * DOC: station table - locking
103 *
104 * As stated before, the station is created / deleted by mac80211's %sta_state
105 * callback from %ieee80211_ops which can sleep. The next paragraph explains
106 * the locking of a single stations, the next ones relates to the station
107 * table.
108 *
109 * The station holds the sequence number per tid. So this data needs to be
110 * accessed in the Tx path (which is softIRQ). It also holds the Block-Ack
111 * information (the state machine / and the logic that checks if the queues
112 * were drained), so it also needs to be accessible from the Tx response flow.
113 * In short, the station needs to be access from sleepable context as well as
114 * from tasklets, so the station itself needs a spinlock.
115 *
116 * The writers of %fw_id_to_mac_id map are serialized by the global mutex of
117 * the mvm op_mode. This is possible since %sta_state can sleep.
118 * The pointers in this map are RCU protected, hence we won't replace the
119 * station while we have Tx / Tx response / BA notification running.
120 *
121 * If a station is deleted while it still has packets in its A-MPDU queues,
122 * then the reclaim flow will notice that there is no station in the map for
123 * sta_id and it will dump the responses.
124 */
125
126/**
127 * DOC: station table - internal stations
128 *
129 * The FW needs a few internal stations that are not reflected in
130 * mac80211, such as broadcast station in AP / GO mode, or AUX sta for
131 * scanning and P2P device (during the GO negotiation).
132 * For these kind of stations we have %iwl_mvm_int_sta struct which holds the
133 * data relevant for them from both %iwl_mvm_sta and %ieee80211_sta.
134 * Usually the data for these stations is static, so no locking is required,
135 * and no TID data as this is also not needed.
136 * One thing to note, is that these stations have an ID in the fw, but not
137 * in mac80211. In order to "reserve" them a sta_id in %fw_id_to_mac_id
138 * we fill ERR_PTR(EINVAL) in this mapping and all other dereferencing of
139 * pointers from this mapping need to check that the value is not error
140 * or NULL.
141 *
142 * Currently there is only one auxiliary station for scanning, initialized
143 * on init.
144 */
145
146/**
147 * DOC: station table - AP Station in STA mode
148 *
149 * %iwl_mvm_vif includes the index of the AP station in the fw's STA table:
150 * %ap_sta_id. To get the point to the coresponsding %ieee80211_sta,
151 * &fw_id_to_mac_id can be used. Due to the way the fw works, we must not remove
152 * the AP station from the fw before setting the MAC context as unassociated.
153 * Hence, %fw_id_to_mac_id[%ap_sta_id] will be NULLed when the AP station is
154 * removed by mac80211, but the station won't be removed in the fw until the
155 * VIF is set as unassociated. Then, %ap_sta_id will be invalidated.
156 */
157
158/**
159 * DOC: station table - Drain vs. Flush
160 *
161 * Flush means that all the frames in the SCD queue are dumped regardless the
162 * station to which they were sent. We do that when we disassociate and before
163 * we remove the STA of the AP. The flush can be done synchronously against the
164 * fw.
165 * Drain means that the fw will drop all the frames sent to a specific station.
166 * This is useful when a client (if we are IBSS / GO or AP) disassociates. In
167 * that case, we need to drain all the frames for that client from the AC queues
168 * that are shared with the other clients. Only then, we can remove the STA in
169 * the fw. In order to do so, we track the non-AMPDU packets for each station.
170 * If mac80211 removes a STA and if it still has non-AMPDU packets pending in
171 * the queues, we mark this station as %EBUSY in %fw_id_to_mac_id, and drop all
172 * the frames for this STA (%iwl_mvm_rm_sta). When the last frame is dropped
173 * (we know about it with its Tx response), we remove the station in fw and set
174 * it as %NULL in %fw_id_to_mac_id: this is the purpose of
175 * %iwl_mvm_sta_drained_wk.
176 */
177
178/**
179 * DOC: station table - fw restart
180 *
181 * When the fw asserts, or we have any other issue that requires to reset the
182 * driver, we require mac80211 to reconfigure the driver. Since the private
183 * data of the stations is embed in mac80211's %ieee80211_sta, that data will
184 * not be zeroed and needs to be reinitialized manually.
185 * %IWL_MVM_STATUS_IN_HW_RESTART is set during restart and that will hint us
186 * that we must not allocate a new sta_id but reuse the previous one. This
187 * means that the stations being re-added after the reset will have the same
188 * place in the fw as before the reset. We do need to zero the %fw_id_to_mac_id
189 * map, since the stations aren't in the fw any more. Internal stations that
190 * are not added by mac80211 will be re-added in the init flow that is called
191 * after the restart: mac80211 call's %iwl_mvm_mac_start which calls to
192 * %iwl_mvm_up.
193 */
194
195/**
196 * DOC: AP mode - PS
197 *
198 * When a station is asleep, the fw will set it as "asleep". All the
199 * non-aggregation frames to that station will be dropped by the fw
200 * (%TX_STATUS_FAIL_DEST_PS failure code).
201 * AMPDUs are in a separate queue that is stopped by the fw. We just need to
202 * let mac80211 know how many frames we have in these queues so that it can
203 * properly handle trigger frames.
204 * When the a trigger frame is received, mac80211 tells the driver to send
205 * frames from the AMPDU queues or AC queue depending on which queue are
206 * delivery-enabled and what TID has frames to transmit (Note that mac80211 has
207 * all the knowledege since all the non-agg frames are buffered / filtered, and
208 * the driver tells mac80211 about agg frames). The driver needs to tell the fw
209 * to let frames out even if the station is asleep. This is done by
210 * %iwl_mvm_sta_modify_sleep_tx_count.
211 * When we receive a frame from that station with PM bit unset, the
212 * driver needs to let the fw know that this station isn't alseep any more.
213 * This is done by %iwl_mvm_sta_modify_ps_wake.
214 *
215 * TODO - EOSP handling
216 */
217
218/**
219 * enum iwl_mvm_agg_state
220 *
221 * The state machine of the BA agreement establishment / tear down.
222 * These states relate to a specific RA / TID.
223 *
224 * @IWL_AGG_OFF: aggregation is not used
225 * @IWL_AGG_STARTING: aggregation are starting (between start and oper)
226 * @IWL_AGG_ON: aggregation session is up
227 * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the
228 * HW queue to be empty from packets for this RA /TID.
229 * @IWL_EMPTYING_HW_QUEUE_DELBA: tearing down a BA session - waiting for the
230 * HW queue to be empty from packets for this RA /TID.
231 */
232enum iwl_mvm_agg_state {
233 IWL_AGG_OFF = 0,
234 IWL_AGG_STARTING,
235 IWL_AGG_ON,
236 IWL_EMPTYING_HW_QUEUE_ADDBA,
237 IWL_EMPTYING_HW_QUEUE_DELBA,
238};
239
240/**
241 * struct iwl_mvm_tid_data - holds the states for each RA / TID
242 * @seq_number: the next WiFi sequence number to use
243 * @next_reclaimed: the WiFi sequence number of the next packet to be acked.
244 * This is basically (last acked packet++).
245 * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the
246 * Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA).
247 * @state: state of the BA agreement establishment / tear down.
248 * @txq_id: Tx queue used by the BA session
249 * @ssn: the first packet to be sent in AGG HW queue in Tx AGG start flow, or
250 * the first packet to be sent in legacy HW queue in Tx AGG stop flow.
251 * Basically when next_reclaimed reaches ssn, we can tell mac80211 that
252 * we are ready to finish the Tx AGG stop / start flow.
253 * @wait_for_ba: Expect block-ack before next Tx reply
254 */
255struct iwl_mvm_tid_data {
256 u16 seq_number;
257 u16 next_reclaimed;
258 /* The rest is Tx AGG related */
259 u32 rate_n_flags;
260 enum iwl_mvm_agg_state state;
261 u16 txq_id;
262 u16 ssn;
263 bool wait_for_ba;
264};
265
266/**
267 * struct iwl_mvm_sta - representation of a station in the driver
268 * @sta_id: the index of the station in the fw (will be replaced by id_n_color)
269 * @tfd_queue_msk: the tfd queues used by the station
270 * @mac_id_n_color: the MAC context this station is linked to
271 * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for
272 * tid.
273 * @max_agg_bufsize: the maximal size of the AGG buffer for this station
274 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx
275 * and from Tx response flow, it needs a spinlock.
276 * @pending_frames: number of frames for this STA on the shared Tx queues.
277 * @tid_data: per tid data. Look at %iwl_mvm_tid_data.
278 *
279 * When mac80211 creates a station it reserves some space (hw->sta_data_size)
280 * in the structure for use by driver. This structure is placed in that
281 * space.
282 *
283 */
284struct iwl_mvm_sta {
285 u32 sta_id;
286 u32 tfd_queue_msk;
287 u32 mac_id_n_color;
288 u16 tid_disable_agg;
289 u8 max_agg_bufsize;
290 spinlock_t lock;
291 atomic_t pending_frames;
292 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT];
293 struct iwl_lq_sta lq_sta;
294 struct ieee80211_vif *vif;
295
296#ifdef CONFIG_PM_SLEEP
297 u16 last_seq_ctl;
298#endif
299};
300
301/**
302 * struct iwl_mvm_int_sta - representation of an internal station (auxiliary or
303 * broadcast)
304 * @sta_id: the index of the station in the fw (will be replaced by id_n_color)
305 * @tfd_queue_msk: the tfd queues used by the station
306 */
307struct iwl_mvm_int_sta {
308 u32 sta_id;
309 u32 tfd_queue_msk;
310};
311
312int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta);
313int iwl_mvm_add_sta(struct iwl_mvm *mvm,
314 struct ieee80211_vif *vif,
315 struct ieee80211_sta *sta);
316int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
317 struct ieee80211_vif *vif,
318 struct ieee80211_sta *sta);
319int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
320 struct ieee80211_vif *vif,
321 u8 sta_id);
322int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
323 struct ieee80211_vif *vif,
324 struct ieee80211_sta *sta,
325 struct ieee80211_key_conf *key,
326 bool have_key_offset);
327int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
328 struct ieee80211_vif *vif,
329 struct ieee80211_sta *sta,
330 struct ieee80211_key_conf *keyconf);
331
332void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
333 struct ieee80211_vif *vif,
334 struct ieee80211_key_conf *keyconf,
335 struct ieee80211_sta *sta, u32 iv32,
336 u16 *phase1key);
337
338/* AMPDU */
339int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
340 int tid, u16 ssn, bool start);
341int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
342 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
343int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
344 struct ieee80211_sta *sta, u16 tid, u8 buf_size);
345int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
346 struct ieee80211_sta *sta, u16 tid);
347
348int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
349int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
350 u32 qmask);
351void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm,
352 struct iwl_mvm_int_sta *sta);
353int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
354 struct iwl_mvm_int_sta *bsta);
355int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
356 struct iwl_mvm_int_sta *bsta);
357int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
358 struct iwl_mvm_int_sta *bsta);
359int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta);
360void iwl_mvm_sta_drained_wk(struct work_struct *wk);
361void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id);
362void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm, int sta_id,
363 enum ieee80211_frame_release_type reason,
364 u16 cnt);
365int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
366 bool drain);
367
368#endif /* __sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
new file mode 100644
index 000000000000..b9f076f4f17c
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -0,0 +1,569 @@
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 LICENSE.GPL.
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/jiffies.h>
65#include <net/mac80211.h>
66
67#include "iwl-notif-wait.h"
68#include "iwl-trans.h"
69#include "fw-api.h"
70#include "time-event.h"
71#include "mvm.h"
72#include "iwl-io.h"
73#include "iwl-prph.h"
74
75/* A TimeUnit is 1024 microsecond */
76#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024))
77#define MSEC_TO_TU(_msec) (_msec*1000/1024)
78
79void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
80 struct iwl_mvm_time_event_data *te_data)
81{
82 lockdep_assert_held(&mvm->time_event_lock);
83
84 if (te_data->id == TE_MAX)
85 return;
86
87 list_del(&te_data->list);
88 te_data->running = false;
89 te_data->uid = 0;
90 te_data->id = TE_MAX;
91 te_data->vif = NULL;
92}
93
94void iwl_mvm_roc_done_wk(struct work_struct *wk)
95{
96 struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk);
97
98 synchronize_net();
99
100 /*
101 * Flush the offchannel queue -- this is called when the time
102 * event finishes or is cancelled, so that frames queued for it
103 * won't get stuck on the queue and be transmitted in the next
104 * time event.
105 * We have to send the command asynchronously since this cannot
106 * be under the mutex for locking reasons, but that's not an
107 * issue as it will have to complete before the next command is
108 * executed, and a new time event means a new command.
109 */
110 iwl_mvm_flush_tx_path(mvm, BIT(IWL_OFFCHANNEL_QUEUE), false);
111}
112
113static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
114{
115 /*
116 * First, clear the ROC_RUNNING status bit. This will cause the TX
117 * path to drop offchannel transmissions. That would also be done
118 * by mac80211, but it is racy, in particular in the case that the
119 * time event actually completed in the firmware (which is handled
120 * in iwl_mvm_te_handle_notif).
121 */
122 clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
123
124 /*
125 * Of course, our status bit is just as racy as mac80211, so in
126 * addition, fire off the work struct which will drop all frames
127 * from the hardware queues that made it through the race. First
128 * it will of course synchronize the TX path to make sure that
129 * any *new* TX will be rejected.
130 */
131 schedule_work(&mvm->roc_done_wk);
132}
133
134/*
135 * Handles a FW notification for an event that is known to the driver.
136 *
137 * @mvm: the mvm component
138 * @te_data: the time event data
139 * @notif: the notification data corresponding the time event data.
140 */
141static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
142 struct iwl_mvm_time_event_data *te_data,
143 struct iwl_time_event_notif *notif)
144{
145 lockdep_assert_held(&mvm->time_event_lock);
146
147 IWL_DEBUG_TE(mvm, "Handle time event notif - UID = 0x%x action %d\n",
148 le32_to_cpu(notif->unique_id),
149 le32_to_cpu(notif->action));
150
151 /*
152 * The FW sends the start/end time event notifications even for events
153 * that it fails to schedule. This is indicated in the status field of
154 * the notification. This happens in cases that the scheduler cannot
155 * find a schedule that can handle the event (for example requesting a
156 * P2P Device discoveribility, while there are other higher priority
157 * events in the system).
158 */
159 WARN_ONCE(!le32_to_cpu(notif->status),
160 "Failed to schedule time event\n");
161
162 if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_END) {
163 IWL_DEBUG_TE(mvm,
164 "TE ended - current time %lu, estimated end %lu\n",
165 jiffies, te_data->end_jiffies);
166
167 if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
168 ieee80211_remain_on_channel_expired(mvm->hw);
169 iwl_mvm_roc_finished(mvm);
170 }
171
172 /*
173 * By now, we should have finished association
174 * and know the dtim period.
175 */
176 if (te_data->vif->type == NL80211_IFTYPE_STATION &&
177 (!te_data->vif->bss_conf.assoc ||
178 !te_data->vif->bss_conf.dtim_period))
179 IWL_ERR(mvm,
180 "No assocation and the time event is over already...\n");
181
182 iwl_mvm_te_clear_data(mvm, te_data);
183 } else if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_START) {
184 te_data->running = true;
185 te_data->end_jiffies = jiffies +
186 TU_TO_JIFFIES(te_data->duration);
187
188 if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
189 set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
190 ieee80211_ready_on_channel(mvm->hw);
191 }
192 } else {
193 IWL_WARN(mvm, "Got TE with unknown action\n");
194 }
195}
196
197/*
198 * The Rx handler for time event notifications
199 */
200int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
201 struct iwl_rx_cmd_buffer *rxb,
202 struct iwl_device_cmd *cmd)
203{
204 struct iwl_rx_packet *pkt = rxb_addr(rxb);
205 struct iwl_time_event_notif *notif = (void *)pkt->data;
206 struct iwl_mvm_time_event_data *te_data, *tmp;
207
208 IWL_DEBUG_TE(mvm, "Time event notification - UID = 0x%x action %d\n",
209 le32_to_cpu(notif->unique_id),
210 le32_to_cpu(notif->action));
211
212 spin_lock_bh(&mvm->time_event_lock);
213 list_for_each_entry_safe(te_data, tmp, &mvm->time_event_list, list) {
214 if (le32_to_cpu(notif->unique_id) == te_data->uid)
215 iwl_mvm_te_handle_notif(mvm, te_data, notif);
216 }
217 spin_unlock_bh(&mvm->time_event_lock);
218
219 return 0;
220}
221
222static bool iwl_mvm_time_event_notif(struct iwl_notif_wait_data *notif_wait,
223 struct iwl_rx_packet *pkt, void *data)
224{
225 struct iwl_mvm *mvm =
226 container_of(notif_wait, struct iwl_mvm, notif_wait);
227 struct iwl_mvm_time_event_data *te_data = data;
228 struct ieee80211_vif *vif = te_data->vif;
229 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
230 struct iwl_time_event_notif *notif;
231 struct iwl_time_event_resp *resp;
232
233 u32 mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
234
235 /* until we do something else */
236 WARN_ON(te_data->id != TE_BSS_STA_AGGRESSIVE_ASSOC);
237
238 switch (pkt->hdr.cmd) {
239 case TIME_EVENT_CMD:
240 resp = (void *)pkt->data;
241 /* TODO: I can't check that since the fw is buggy - it doesn't
242 * put the right values when we remove a TE. We can be here
243 * when we remove a TE because the remove TE command is sent in
244 * ASYNC...
245 * WARN_ON(mac_id_n_color != le32_to_cpu(resp->id_and_color));
246 */
247 te_data->uid = le32_to_cpu(resp->unique_id);
248 IWL_DEBUG_TE(mvm, "Got response - UID = 0x%x\n", te_data->uid);
249 return false;
250
251 case TIME_EVENT_NOTIFICATION:
252 notif = (void *)pkt->data;
253 WARN_ON(le32_to_cpu(notif->status) != 1);
254 WARN_ON(mac_id_n_color != le32_to_cpu(notif->id_and_color));
255 /* check if this is our Time Event that is starting */
256 if (le32_to_cpu(notif->unique_id) != te_data->uid)
257 return false;
258 IWL_DEBUG_TE(mvm, "Event %d is starting - time is %d\n",
259 te_data->uid, le32_to_cpu(notif->timestamp));
260
261 WARN_ONCE(!le32_to_cpu(notif->status),
262 "Failed to schedule protected session TE\n");
263
264 te_data->running = true;
265 te_data->end_jiffies = jiffies +
266 TU_TO_JIFFIES(te_data->duration);
267 return true;
268
269 default:
270 WARN_ON(1);
271 return false;
272 };
273}
274
275void iwl_mvm_protect_session(struct iwl_mvm *mvm,
276 struct ieee80211_vif *vif,
277 u32 duration, u32 min_duration)
278{
279 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
280 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
281 static const u8 time_event_notif[] = { TIME_EVENT_CMD,
282 TIME_EVENT_NOTIFICATION };
283 struct iwl_notification_wait wait_time_event;
284 struct iwl_time_event_cmd time_cmd = {};
285 int ret;
286
287 lockdep_assert_held(&mvm->mutex);
288
289 if (te_data->running &&
290 time_after(te_data->end_jiffies,
291 jiffies + TU_TO_JIFFIES(min_duration))) {
292 IWL_DEBUG_TE(mvm, "We have enough time in the current TE: %u\n",
293 jiffies_to_msecs(te_data->end_jiffies - jiffies));
294 return;
295 }
296
297 if (te_data->running) {
298 IWL_DEBUG_TE(mvm, "extend 0x%x: only %u ms left\n",
299 te_data->uid,
300 jiffies_to_msecs(te_data->end_jiffies - jiffies));
301 /*
302 * we don't have enough time
303 * cancel the current TE and issue a new one
304 * Of course it would be better to remove the old one only
305 * when the new one is added, but we don't care if we are off
306 * channel for a bit. All we need to do, is not to return
307 * before we actually begin to be on the channel.
308 */
309 iwl_mvm_stop_session_protection(mvm, vif);
310 }
311
312 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
313 time_event_notif,
314 ARRAY_SIZE(time_event_notif),
315 iwl_mvm_time_event_notif,
316 &mvmvif->time_event_data);
317
318 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
319 time_cmd.id_and_color =
320 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
321 time_cmd.id = cpu_to_le32(TE_BSS_STA_AGGRESSIVE_ASSOC);
322
323 time_cmd.apply_time =
324 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG));
325 time_cmd.dep_policy = TE_INDEPENDENT;
326 time_cmd.is_present = cpu_to_le32(1);
327 time_cmd.max_frags = cpu_to_le32(TE_FRAG_NONE);
328 time_cmd.max_delay = cpu_to_le32(500);
329 /* TODO: why do we need to interval = bi if it is not periodic? */
330 time_cmd.interval = cpu_to_le32(1);
331 time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1));
332 time_cmd.duration = cpu_to_le32(duration);
333 time_cmd.repeat = cpu_to_le32(1);
334 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END);
335
336 te_data->vif = vif;
337 te_data->duration = duration;
338
339 spin_lock_bh(&mvm->time_event_lock);
340 te_data->id = le32_to_cpu(time_cmd.id);
341 list_add_tail(&te_data->list, &mvm->time_event_list);
342 spin_unlock_bh(&mvm->time_event_lock);
343
344 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
345 sizeof(time_cmd), &time_cmd);
346 if (ret) {
347 IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret);
348 goto out_remove_notif;
349 }
350
351 ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1 * HZ);
352 if (ret) {
353 IWL_ERR(mvm, "%s - failed on timeout\n", __func__);
354 spin_lock_bh(&mvm->time_event_lock);
355 iwl_mvm_te_clear_data(mvm, te_data);
356 spin_unlock_bh(&mvm->time_event_lock);
357 }
358
359 return;
360
361out_remove_notif:
362 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
363}
364
365/*
366 * Explicit request to remove a time event. The removal of a time event needs to
367 * be synchronized with the flow of a time event's end notification, which also
368 * removes the time event from the op mode data structures.
369 */
370void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
371 struct iwl_mvm_vif *mvmvif,
372 struct iwl_mvm_time_event_data *te_data)
373{
374 struct iwl_time_event_cmd time_cmd = {};
375 u32 id, uid;
376 int ret;
377
378 /*
379 * It is possible that by the time we got to this point the time
380 * event was already removed.
381 */
382 spin_lock_bh(&mvm->time_event_lock);
383
384 /* Save time event uid before clearing its data */
385 uid = te_data->uid;
386 id = te_data->id;
387
388 /*
389 * The clear_data function handles time events that were already removed
390 */
391 iwl_mvm_te_clear_data(mvm, te_data);
392 spin_unlock_bh(&mvm->time_event_lock);
393
394 /*
395 * It is possible that by the time we try to remove it, the time event
396 * has already ended and removed. In such a case there is no need to
397 * send a removal command.
398 */
399 if (id == TE_MAX) {
400 IWL_DEBUG_TE(mvm, "TE 0x%x has already ended\n", uid);
401 return;
402 }
403
404 /* When we remove a TE, the UID is to be set in the id field */
405 time_cmd.id = cpu_to_le32(uid);
406 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE);
407 time_cmd.id_and_color =
408 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
409
410 IWL_DEBUG_TE(mvm, "Removing TE 0x%x\n", le32_to_cpu(time_cmd.id));
411 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_ASYNC,
412 sizeof(time_cmd), &time_cmd);
413 if (WARN_ON(ret))
414 return;
415}
416
417void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
418 struct ieee80211_vif *vif)
419{
420 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
421 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
422
423 lockdep_assert_held(&mvm->mutex);
424 iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
425}
426
427static bool iwl_mvm_roc_te_notif(struct iwl_notif_wait_data *notif_wait,
428 struct iwl_rx_packet *pkt, void *data)
429{
430 struct iwl_mvm *mvm =
431 container_of(notif_wait, struct iwl_mvm, notif_wait);
432 struct iwl_mvm_time_event_data *te_data = data;
433 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
434 struct iwl_time_event_resp *resp;
435
436 u32 mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
437
438 /* until we do something else */
439 WARN_ON(te_data->id != TE_P2P_DEVICE_DISCOVERABLE);
440
441 switch (pkt->hdr.cmd) {
442 case TIME_EVENT_CMD:
443 resp = (void *)pkt->data;
444 WARN_ON(mac_id_n_color != le32_to_cpu(resp->id_and_color));
445 te_data->uid = le32_to_cpu(resp->unique_id);
446 IWL_DEBUG_TE(mvm, "Got response - UID = 0x%x\n", te_data->uid);
447 return true;
448
449 default:
450 WARN_ON(1);
451 return false;
452 };
453}
454
455int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
456 int duration)
457{
458 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
459 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
460 static const u8 roc_te_notif[] = { TIME_EVENT_CMD };
461 struct iwl_notification_wait wait_time_event;
462 struct iwl_time_event_cmd time_cmd = {};
463 int ret;
464
465 lockdep_assert_held(&mvm->mutex);
466 if (te_data->running) {
467 IWL_WARN(mvm, "P2P_DEVICE remain on channel already running\n");
468 return -EBUSY;
469 }
470
471 /*
472 * Flush the done work, just in case it's still pending, so that
473 * the work it does can complete and we can accept new frames.
474 */
475 flush_work(&mvm->roc_done_wk);
476
477 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
478 roc_te_notif,
479 ARRAY_SIZE(roc_te_notif),
480 iwl_mvm_roc_te_notif,
481 &mvmvif->time_event_data);
482
483 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
484 time_cmd.id_and_color =
485 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
486 time_cmd.id = cpu_to_le32(TE_P2P_DEVICE_DISCOVERABLE);
487
488 time_cmd.apply_time = cpu_to_le32(0);
489 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT);
490 time_cmd.is_present = cpu_to_le32(1);
491
492 time_cmd.interval = cpu_to_le32(1);
493
494 /*
495 * TE_P2P_DEVICE_DISCOVERABLE can have lower priority than other events
496 * that are being scheduled by the driver/fw, and thus it might not be
497 * scheduled. To improve the chances of it being scheduled, allow it to
498 * be fragmented.
499 * In addition, for the same reasons, allow to delay the scheduling of
500 * the time event.
501 */
502 time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20);
503 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2));
504 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration));
505 time_cmd.repeat = cpu_to_le32(1);
506 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END);
507
508 /* Push the te data to the tracked te list */
509 te_data->vif = vif;
510 te_data->duration = MSEC_TO_TU(duration);
511
512 spin_lock_bh(&mvm->time_event_lock);
513 te_data->id = le32_to_cpu(time_cmd.id);
514 list_add_tail(&te_data->list, &mvm->time_event_list);
515 spin_unlock_bh(&mvm->time_event_lock);
516
517 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
518 sizeof(time_cmd), &time_cmd);
519 if (ret) {
520 IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret);
521 goto out_remove_notif;
522 }
523
524 ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1 * HZ);
525 if (ret) {
526 IWL_ERR(mvm, "%s - failed on timeout\n", __func__);
527 iwl_mvm_te_clear_data(mvm, te_data);
528 }
529
530 return ret;
531
532out_remove_notif:
533 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
534 return ret;
535}
536
537void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm)
538{
539 struct iwl_mvm_vif *mvmvif;
540 struct iwl_mvm_time_event_data *te_data;
541
542 lockdep_assert_held(&mvm->mutex);
543
544 /*
545 * Iterate over the list of time events and find the time event that is
546 * associated with a P2P_DEVICE interface.
547 * This assumes that a P2P_DEVICE interface can have only a single time
548 * event at any given time and this time event coresponds to a ROC
549 * request
550 */
551 mvmvif = NULL;
552 spin_lock_bh(&mvm->time_event_lock);
553 list_for_each_entry(te_data, &mvm->time_event_list, list) {
554 if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
555 mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
556 break;
557 }
558 }
559 spin_unlock_bh(&mvm->time_event_lock);
560
561 if (!mvmvif) {
562 IWL_WARN(mvm, "P2P_DEVICE no remain on channel event\n");
563 return;
564 }
565
566 iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
567
568 iwl_mvm_roc_finished(mvm);
569}
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
new file mode 100644
index 000000000000..64fb57a5ab43
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -0,0 +1,214 @@
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 LICENSE.GPL.
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#ifndef __time_event_h__
65#define __time_event_h__
66
67#include "fw-api.h"
68
69#include "mvm.h"
70
71/**
72 * DOC: Time Events - what is it?
73 *
74 * Time Events are a fw feature that allows the driver to control the presence
75 * of the device on the channel. Since the fw supports multiple channels
76 * concurrently, the fw may choose to jump to another channel at any time.
77 * In order to make sure that the fw is on a specific channel at a certain time
78 * and for a certain duration, the driver needs to issue a time event.
79 *
80 * The simplest example is for BSS association. The driver issues a time event,
81 * waits for it to start, and only then tells mac80211 that we can start the
82 * association. This way, we make sure that the association will be done
83 * smoothly and won't be interrupted by channel switch decided within the fw.
84 */
85
86 /**
87 * DOC: The flow against the fw
88 *
89 * When the driver needs to make sure we are in a certain channel, at a certain
90 * time and for a certain duration, it sends a Time Event. The flow against the
91 * fw goes like this:
92 * 1) Driver sends a TIME_EVENT_CMD to the fw
93 * 2) Driver gets the response for that command. This response contains the
94 * Unique ID (UID) of the event.
95 * 3) The fw sends notification when the event starts.
96 *
97 * Of course the API provides various options that allow to cover parameters
98 * of the flow.
99 * What is the duration of the event?
100 * What is the start time of the event?
101 * Is there an end-time for the event?
102 * How much can the event be delayed?
103 * Can the event be split?
104 * If yes what is the maximal number of chunks?
105 * etc...
106 */
107
108/**
109 * DOC: Abstraction to the driver
110 *
111 * In order to simplify the use of time events to the rest of the driver,
112 * we abstract the use of time events. This component provides the functions
113 * needed by the driver.
114 */
115
116#define IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS 500
117#define IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS 400
118
119/**
120 * iwl_mvm_protect_session - start / extend the session protection.
121 * @mvm: the mvm component
122 * @vif: the virtual interface for which the session is issued
123 * @duration: the duration of the session in TU.
124 * @min_duration: will start a new session if the current session will end
125 * in less than min_duration.
126 *
127 * This function can be used to start a session protection which means that the
128 * fw will stay on the channel for %duration_ms milliseconds. This function
129 * will block (sleep) until the session starts. This function can also be used
130 * to extend a currently running session.
131 * This function is meant to be used for BSS association for example, where we
132 * want to make sure that the fw stays on the channel during the association.
133 */
134void iwl_mvm_protect_session(struct iwl_mvm *mvm,
135 struct ieee80211_vif *vif,
136 u32 duration, u32 min_duration);
137
138/**
139 * iwl_mvm_stop_session_protection - cancel the session protection.
140 * @mvm: the mvm component
141 * @vif: the virtual interface for which the session is issued
142 *
143 * This functions cancels the session protection which is an act of good
144 * citizenship. If it is not needed any more it should be cancelled because
145 * the other bindings wait for the medium during that time.
146 * This funtions doesn't sleep.
147 */
148void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
149 struct ieee80211_vif *vif);
150
151/*
152 * iwl_mvm_rx_time_event_notif - handles %TIME_EVENT_NOTIFICATION.
153 */
154int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
155 struct iwl_rx_cmd_buffer *rxb,
156 struct iwl_device_cmd *cmd);
157
158/**
159 * iwl_mvm_start_p2p_roc - start remain on channel for p2p device functionlity
160 * @mvm: the mvm component
161 * @vif: the virtual interface for which the roc is requested. It is assumed
162 * that the vif type is NL80211_IFTYPE_P2P_DEVICE
163 * @duration: the requested duration in millisecond for the fw to be on the
164 * channel that is bound to the vif.
165 *
166 * This function can be used to issue a remain on channel session,
167 * which means that the fw will stay in the channel for the request %duration
168 * milliseconds. The function is async, meaning that it only issues the ROC
169 * request but does not wait for it to start. Once the FW is ready to serve the
170 * ROC request, it will issue a notification to the driver that it is on the
171 * requested channel. Once the FW completes the ROC request it will issue
172 * another notification to the driver.
173 */
174int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
175 int duration);
176
177/**
178 * iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity
179 * @mvm: the mvm component
180 *
181 * This function can be used to cancel an ongoing ROC session.
182 * The function is async, it will instruct the FW to stop serving the ROC
183 * session, but will not wait for the actual stopping of the session.
184 */
185void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm);
186
187/**
188 * iwl_mvm_remove_time_event - general function to clean up of time event
189 * @mvm: the mvm component
190 * @vif: the vif to which the time event belongs
191 * @te_data: the time event data that corresponds to that time event
192 *
193 * This function can be used to cancel a time event regardless its type.
194 * It is useful for cleaning up time events running before removing an
195 * interface.
196 */
197void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
198 struct iwl_mvm_vif *mvmvif,
199 struct iwl_mvm_time_event_data *te_data);
200
201/**
202 * iwl_mvm_te_clear_data - remove time event from list
203 * @mvm: the mvm component
204 * @te_data: the time event data to remove
205 *
206 * This function is mostly internal, it is made available here only
207 * for firmware restart purposes.
208 */
209void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
210 struct iwl_mvm_time_event_data *te_data);
211
212void iwl_mvm_roc_done_wk(struct work_struct *wk);
213
214#endif /* __time_event_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
new file mode 100644
index 000000000000..cada8efe0cca
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -0,0 +1,916 @@
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 LICENSE.GPL.
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#include <linux/ieee80211.h>
64#include <linux/etherdevice.h>
65
66#include "iwl-trans.h"
67#include "iwl-eeprom-parse.h"
68#include "mvm.h"
69#include "sta.h"
70
71/*
72 * Sets most of the Tx cmd's fields
73 */
74static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
75 struct iwl_tx_cmd *tx_cmd,
76 struct ieee80211_tx_info *info, u8 sta_id)
77{
78 struct ieee80211_hdr *hdr = (void *)skb->data;
79 __le16 fc = hdr->frame_control;
80 u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags);
81 u32 len = skb->len + FCS_LEN;
82
83 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
84 tx_flags |= TX_CMD_FLG_ACK;
85 else
86 tx_flags &= ~TX_CMD_FLG_ACK;
87
88 if (ieee80211_is_probe_resp(fc))
89 tx_flags |= TX_CMD_FLG_TSF;
90 else if (ieee80211_is_back_req(fc))
91 tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR;
92
93 /* High prio packet (wrt. BT coex) if it is EAPOL, MCAST or MGMT */
94 if (info->band == IEEE80211_BAND_2GHZ &&
95 (skb->protocol == cpu_to_be16(ETH_P_PAE) ||
96 is_multicast_ether_addr(hdr->addr1) ||
97 ieee80211_is_back_req(fc) ||
98 ieee80211_is_mgmt(fc)))
99 tx_flags |= TX_CMD_FLG_BT_DIS;
100
101 if (ieee80211_has_morefrags(fc))
102 tx_flags |= TX_CMD_FLG_MORE_FRAG;
103
104 if (ieee80211_is_data_qos(fc)) {
105 u8 *qc = ieee80211_get_qos_ctl(hdr);
106 tx_cmd->tid_tspec = qc[0] & 0xf;
107 tx_flags &= ~TX_CMD_FLG_SEQ_CTL;
108 } else {
109 tx_cmd->tid_tspec = IWL_TID_NON_QOS;
110 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
111 tx_flags |= TX_CMD_FLG_SEQ_CTL;
112 else
113 tx_flags &= ~TX_CMD_FLG_SEQ_CTL;
114 }
115
116 if (ieee80211_is_mgmt(fc)) {
117 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
118 tx_cmd->pm_frame_timeout = cpu_to_le16(3);
119 else
120 tx_cmd->pm_frame_timeout = cpu_to_le16(2);
121
122 /* The spec allows Action frames in A-MPDU, we don't support
123 * it
124 */
125 WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU);
126 } else {
127 tx_cmd->pm_frame_timeout = 0;
128 }
129
130 if (info->flags & IEEE80211_TX_CTL_AMPDU)
131 tx_flags |= TX_CMD_FLG_PROT_REQUIRE;
132
133 if (ieee80211_is_data(fc) && len > mvm->rts_threshold &&
134 !is_multicast_ether_addr(ieee80211_get_DA(hdr)))
135 tx_flags |= TX_CMD_FLG_PROT_REQUIRE;
136
137 tx_cmd->driver_txop = 0;
138 tx_cmd->tx_flags = cpu_to_le32(tx_flags);
139 /* Total # bytes to be transmitted */
140 tx_cmd->len = cpu_to_le16((u16)skb->len);
141 tx_cmd->next_frame_len = 0;
142 tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
143 tx_cmd->sta_id = sta_id;
144}
145
146/*
147 * Sets the fields in the Tx cmd that are rate related
148 */
149static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
150 struct iwl_tx_cmd *tx_cmd,
151 struct ieee80211_tx_info *info,
152 struct ieee80211_sta *sta,
153 __le16 fc)
154{
155 u32 rate_flags;
156 int rate_idx;
157 u8 rate_plcp;
158
159 /* Set retry limit on RTS packets */
160 tx_cmd->rts_retry_limit = IWL_RTS_DFAULT_RETRY_LIMIT;
161
162 /* Set retry limit on DATA packets and Probe Responses*/
163 if (ieee80211_is_probe_resp(fc)) {
164 tx_cmd->data_retry_limit = IWL_MGMT_DFAULT_RETRY_LIMIT;
165 tx_cmd->rts_retry_limit =
166 min(tx_cmd->data_retry_limit, tx_cmd->rts_retry_limit);
167 } else if (ieee80211_is_back_req(fc)) {
168 tx_cmd->data_retry_limit = IWL_BAR_DFAULT_RETRY_LIMIT;
169 } else {
170 tx_cmd->data_retry_limit = IWL_DEFAULT_TX_RETRY;
171 }
172
173 /*
174 * for data packets, rate info comes from the table inside he fw. This
175 * table is controlled by LINK_QUALITY commands
176 */
177
178 if (ieee80211_is_data(fc)) {
179 tx_cmd->initial_rate_index = 0;
180 tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
181 return;
182 } else if (ieee80211_is_back_req(fc)) {
183 tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
184 }
185
186 /* HT rate doesn't make sense for a non data frame */
187 WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS,
188 "Got an HT rate for a non data frame 0x%x\n",
189 info->control.rates[0].flags);
190
191 rate_idx = info->control.rates[0].idx;
192 /* if the rate isn't a well known legacy rate, take the lowest one */
193 if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT_LEGACY)
194 rate_idx = rate_lowest_index(
195 &mvm->nvm_data->bands[info->band], sta);
196
197 /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
198 if (info->band == IEEE80211_BAND_5GHZ)
199 rate_idx += IWL_FIRST_OFDM_RATE;
200
201 /* For 2.4 GHZ band, check that there is no need to remap */
202 BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
203
204 /* Get PLCP rate for tx_cmd->rate_n_flags */
205 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
206
207 mvm->mgmt_last_antenna_idx =
208 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant,
209 mvm->mgmt_last_antenna_idx);
210 rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
211
212 /* Set CCK flag as needed */
213 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
214 rate_flags |= RATE_MCS_CCK_MSK;
215
216 /* Set the rate in the TX cmd */
217 tx_cmd->rate_n_flags = cpu_to_le32((u32)rate_plcp | rate_flags);
218}
219
220/*
221 * Sets the fields in the Tx cmd that are crypto related
222 */
223static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
224 struct ieee80211_tx_info *info,
225 struct iwl_tx_cmd *tx_cmd,
226 struct sk_buff *skb_frag)
227{
228 struct ieee80211_key_conf *keyconf = info->control.hw_key;
229
230 switch (keyconf->cipher) {
231 case WLAN_CIPHER_SUITE_CCMP:
232 tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
233 memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
234 if (info->flags & IEEE80211_TX_CTL_AMPDU)
235 tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_CCMP_AGG);
236 break;
237
238 case WLAN_CIPHER_SUITE_TKIP:
239 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
240 ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
241 break;
242
243 case WLAN_CIPHER_SUITE_WEP104:
244 tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
245 /* fall through */
246 case WLAN_CIPHER_SUITE_WEP40:
247 tx_cmd->sec_ctl |= TX_CMD_SEC_WEP |
248 ((keyconf->keyidx << TX_CMD_SEC_WEP_KEY_IDX_POS) &
249 TX_CMD_SEC_WEP_KEY_IDX_MSK);
250
251 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
252 break;
253 default:
254 IWL_ERR(mvm, "Unknown encode cipher %x\n", keyconf->cipher);
255 break;
256 }
257}
258
259/*
260 * Allocates and sets the Tx cmd the driver data pointers in the skb
261 */
262static struct iwl_device_cmd *
263iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
264 struct ieee80211_sta *sta, u8 sta_id)
265{
266 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
267 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
268 struct iwl_device_cmd *dev_cmd;
269 struct iwl_tx_cmd *tx_cmd;
270
271 dev_cmd = iwl_trans_alloc_tx_cmd(mvm->trans);
272
273 if (unlikely(!dev_cmd))
274 return NULL;
275
276 memset(dev_cmd, 0, sizeof(*dev_cmd));
277 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
278
279 if (info->control.hw_key)
280 iwl_mvm_set_tx_cmd_crypto(mvm, info, tx_cmd, skb);
281
282 iwl_mvm_set_tx_cmd(mvm, skb, tx_cmd, info, sta_id);
283
284 iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control);
285
286 memset(&info->status, 0, sizeof(info->status));
287
288 info->driver_data[0] = NULL;
289 info->driver_data[1] = dev_cmd;
290
291 return dev_cmd;
292}
293
294int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
295{
296 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
297 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
298 struct iwl_device_cmd *dev_cmd;
299 struct iwl_tx_cmd *tx_cmd;
300 u8 sta_id;
301
302 if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU))
303 return -1;
304
305 if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
306 (!info->control.vif ||
307 info->hw_queue != info->control.vif->cab_queue)))
308 return -1;
309
310 /*
311 * If the interface on which frame is sent is the P2P_DEVICE
312 * or an AP/GO interface use the broadcast station associated
313 * with it; otherwise use the AUX station.
314 */
315 if (info->control.vif &&
316 (info->control.vif->type == NL80211_IFTYPE_P2P_DEVICE ||
317 info->control.vif->type == NL80211_IFTYPE_AP)) {
318 struct iwl_mvm_vif *mvmvif =
319 iwl_mvm_vif_from_mac80211(info->control.vif);
320 sta_id = mvmvif->bcast_sta.sta_id;
321 } else {
322 sta_id = mvm->aux_sta.sta_id;
323 }
324
325 IWL_DEBUG_TX(mvm, "station Id %d, queue=%d\n", sta_id, info->hw_queue);
326
327 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, NULL, sta_id);
328 if (!dev_cmd)
329 return -1;
330
331 /* From now on, we cannot access info->control */
332 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
333
334 /* Copy MAC header from skb into command buffer */
335 memcpy(tx_cmd->hdr, hdr, ieee80211_hdrlen(hdr->frame_control));
336
337 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, info->hw_queue)) {
338 iwl_trans_free_tx_cmd(mvm->trans, dev_cmd);
339 return -1;
340 }
341
342 return 0;
343}
344
345/*
346 * Sets the fields in the Tx cmd that are crypto related
347 */
348int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
349 struct ieee80211_sta *sta)
350{
351 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
352 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
353 struct iwl_mvm_sta *mvmsta;
354 struct iwl_device_cmd *dev_cmd;
355 struct iwl_tx_cmd *tx_cmd;
356 __le16 fc;
357 u16 seq_number = 0;
358 u8 tid = IWL_MAX_TID_COUNT;
359 u8 txq_id = info->hw_queue;
360 bool is_data_qos = false, is_ampdu = false;
361
362 mvmsta = (void *)sta->drv_priv;
363 fc = hdr->frame_control;
364
365 if (WARN_ON_ONCE(!mvmsta))
366 return -1;
367
368 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_INVALID_STATION))
369 return -1;
370
371 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, sta, mvmsta->sta_id);
372 if (!dev_cmd)
373 goto drop;
374
375 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
376 /* From now on, we cannot access info->control */
377
378 spin_lock(&mvmsta->lock);
379
380 if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) {
381 u8 *qc = NULL;
382 qc = ieee80211_get_qos_ctl(hdr);
383 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
384 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
385 goto drop_unlock_sta;
386
387 seq_number = mvmsta->tid_data[tid].seq_number;
388 seq_number &= IEEE80211_SCTL_SEQ;
389 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
390 hdr->seq_ctrl |= cpu_to_le16(seq_number);
391 seq_number += 0x10;
392 is_data_qos = true;
393 is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU;
394 }
395
396 /* Copy MAC header from skb into command buffer */
397 memcpy(tx_cmd->hdr, hdr, ieee80211_hdrlen(fc));
398
399 WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM);
400
401 if (is_ampdu) {
402 if (WARN_ON_ONCE(mvmsta->tid_data[tid].state != IWL_AGG_ON))
403 goto drop_unlock_sta;
404 txq_id = mvmsta->tid_data[tid].txq_id;
405 }
406
407 IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id,
408 tid, txq_id, seq_number);
409
410 /* NOTE: aggregation will need changes here (for txq id) */
411 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id))
412 goto drop_unlock_sta;
413
414 if (is_data_qos && !ieee80211_has_morefrags(fc))
415 mvmsta->tid_data[tid].seq_number = seq_number;
416
417 spin_unlock(&mvmsta->lock);
418
419 if (mvmsta->vif->type == NL80211_IFTYPE_AP &&
420 txq_id < IWL_FIRST_AMPDU_QUEUE)
421 atomic_inc(&mvmsta->pending_frames);
422
423 return 0;
424
425drop_unlock_sta:
426 iwl_trans_free_tx_cmd(mvm->trans, dev_cmd);
427 spin_unlock(&mvmsta->lock);
428drop:
429 return -1;
430}
431
432static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
433 struct ieee80211_sta *sta, u8 tid)
434{
435 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
436 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
437 struct ieee80211_vif *vif = mvmsta->vif;
438
439 lockdep_assert_held(&mvmsta->lock);
440
441 if (tid_data->ssn != tid_data->next_reclaimed)
442 return;
443
444 switch (tid_data->state) {
445 case IWL_EMPTYING_HW_QUEUE_ADDBA:
446 IWL_DEBUG_TX_QUEUES(mvm,
447 "Can continue addBA flow ssn = next_recl = %d\n",
448 tid_data->next_reclaimed);
449 tid_data->state = IWL_AGG_STARTING;
450 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
451 break;
452
453 case IWL_EMPTYING_HW_QUEUE_DELBA:
454 IWL_DEBUG_TX_QUEUES(mvm,
455 "Can continue DELBA flow ssn = next_recl = %d\n",
456 tid_data->next_reclaimed);
457 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
458 tid_data->state = IWL_AGG_OFF;
459 /*
460 * we can't hold the mutex - but since we are after a sequence
461 * point (call to iwl_trans_txq_disable), so we don't even need
462 * a memory barrier.
463 */
464 mvm->queue_to_mac80211[tid_data->txq_id] =
465 IWL_INVALID_MAC80211_QUEUE;
466 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
467 break;
468
469 default:
470 break;
471 }
472}
473
474#ifdef CONFIG_IWLWIFI_DEBUG
475const char *iwl_mvm_get_tx_fail_reason(u32 status)
476{
477#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
478#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
479
480 switch (status & TX_STATUS_MSK) {
481 case TX_STATUS_SUCCESS:
482 return "SUCCESS";
483 TX_STATUS_POSTPONE(DELAY);
484 TX_STATUS_POSTPONE(FEW_BYTES);
485 TX_STATUS_POSTPONE(BT_PRIO);
486 TX_STATUS_POSTPONE(QUIET_PERIOD);
487 TX_STATUS_POSTPONE(CALC_TTAK);
488 TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
489 TX_STATUS_FAIL(SHORT_LIMIT);
490 TX_STATUS_FAIL(LONG_LIMIT);
491 TX_STATUS_FAIL(UNDERRUN);
492 TX_STATUS_FAIL(DRAIN_FLOW);
493 TX_STATUS_FAIL(RFKILL_FLUSH);
494 TX_STATUS_FAIL(LIFE_EXPIRE);
495 TX_STATUS_FAIL(DEST_PS);
496 TX_STATUS_FAIL(HOST_ABORTED);
497 TX_STATUS_FAIL(BT_RETRY);
498 TX_STATUS_FAIL(STA_INVALID);
499 TX_STATUS_FAIL(FRAG_DROPPED);
500 TX_STATUS_FAIL(TID_DISABLE);
501 TX_STATUS_FAIL(FIFO_FLUSHED);
502 TX_STATUS_FAIL(SMALL_CF_POLL);
503 TX_STATUS_FAIL(FW_DROP);
504 TX_STATUS_FAIL(STA_COLOR_MISMATCH);
505 }
506
507 return "UNKNOWN";
508
509#undef TX_STATUS_FAIL
510#undef TX_STATUS_POSTPONE
511}
512#endif /* CONFIG_IWLWIFI_DEBUG */
513
514/**
515 * translate ucode response to mac80211 tx status control values
516 */
517static void iwl_mvm_hwrate_to_tx_control(u32 rate_n_flags,
518 struct ieee80211_tx_info *info)
519{
520 struct ieee80211_tx_rate *r = &info->status.rates[0];
521
522 info->status.antenna =
523 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
524 if (rate_n_flags & RATE_HT_MCS_GF_MSK)
525 r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
526 switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
527 case RATE_MCS_CHAN_WIDTH_20:
528 break;
529 case RATE_MCS_CHAN_WIDTH_40:
530 r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
531 break;
532 case RATE_MCS_CHAN_WIDTH_80:
533 r->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
534 break;
535 case RATE_MCS_CHAN_WIDTH_160:
536 r->flags |= IEEE80211_TX_RC_160_MHZ_WIDTH;
537 break;
538 }
539 if (rate_n_flags & RATE_MCS_SGI_MSK)
540 r->flags |= IEEE80211_TX_RC_SHORT_GI;
541 if (rate_n_flags & RATE_MCS_HT_MSK) {
542 r->flags |= IEEE80211_TX_RC_MCS;
543 r->idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
544 } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
545 ieee80211_rate_set_vht(
546 r, rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK,
547 ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
548 RATE_VHT_MCS_NSS_POS) + 1);
549 r->flags |= IEEE80211_TX_RC_VHT_MCS;
550 } else {
551 r->idx = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
552 info->band);
553 }
554}
555
556static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
557 struct iwl_rx_packet *pkt)
558{
559 struct ieee80211_sta *sta;
560 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
561 int txq_id = SEQ_TO_QUEUE(sequence);
562 struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
563 int sta_id = IWL_MVM_TX_RES_GET_RA(tx_resp->ra_tid);
564 int tid = IWL_MVM_TX_RES_GET_TID(tx_resp->ra_tid);
565 u32 status = le16_to_cpu(tx_resp->status.status);
566 u16 ssn = iwl_mvm_get_scd_ssn(tx_resp);
567 struct iwl_mvm_sta *mvmsta;
568 struct sk_buff_head skbs;
569 u8 skb_freed = 0;
570 u16 next_reclaimed, seq_ctl;
571
572 __skb_queue_head_init(&skbs);
573
574 seq_ctl = le16_to_cpu(tx_resp->seq_ctl);
575
576 /* we can free until ssn % q.n_bd not inclusive */
577 iwl_trans_reclaim(mvm->trans, txq_id, ssn, &skbs);
578
579 while (!skb_queue_empty(&skbs)) {
580 struct sk_buff *skb = __skb_dequeue(&skbs);
581 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
582
583 skb_freed++;
584
585 iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]);
586
587 memset(&info->status, 0, sizeof(info->status));
588
589 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
590
591 /* inform mac80211 about what happened with the frame */
592 switch (status & TX_STATUS_MSK) {
593 case TX_STATUS_SUCCESS:
594 case TX_STATUS_DIRECT_DONE:
595 info->flags |= IEEE80211_TX_STAT_ACK;
596 break;
597 case TX_STATUS_FAIL_DEST_PS:
598 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
599 break;
600 default:
601 break;
602 }
603
604 info->status.rates[0].count = tx_resp->failure_frame + 1;
605 iwl_mvm_hwrate_to_tx_control(le32_to_cpu(tx_resp->initial_rate),
606 info);
607
608 /* Single frame failure in an AMPDU queue => send BAR */
609 if (txq_id >= IWL_FIRST_AMPDU_QUEUE &&
610 !(info->flags & IEEE80211_TX_STAT_ACK)) {
611 /* there must be only one skb in the skb_list */
612 WARN_ON_ONCE(skb_freed > 1 ||
613 !skb_queue_empty(&skbs));
614 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
615 }
616
617 /* W/A FW bug: seq_ctl is wrong when the queue is flushed */
618 if (status == TX_STATUS_FAIL_FIFO_FLUSHED) {
619 struct ieee80211_hdr *hdr = (void *)skb->data;
620 seq_ctl = le16_to_cpu(hdr->seq_ctrl);
621 }
622
623 ieee80211_tx_status(mvm->hw, skb);
624 }
625
626 if (txq_id >= IWL_FIRST_AMPDU_QUEUE) {
627 /* If this is an aggregation queue, we use the ssn since:
628 * ssn = wifi seq_num % 256.
629 * The seq_ctl is the sequence control of the packet to which
630 * this Tx response relates. But if there is a hole in the
631 * bitmap of the BA we received, this Tx response may allow to
632 * reclaim the hole and all the subsequent packets that were
633 * already acked. In that case, seq_ctl != ssn, and the next
634 * packet to be reclaimed will be ssn and not seq_ctl. In that
635 * case, several packets will be reclaimed even if
636 * frame_count = 1.
637 *
638 * The ssn is the index (% 256) of the latest packet that has
639 * treated (acked / dropped) + 1.
640 */
641 next_reclaimed = ssn;
642 } else {
643 /* The next packet to be reclaimed is the one after this one */
644 next_reclaimed = SEQ_TO_SN(seq_ctl + 0x10);
645 }
646
647 IWL_DEBUG_TX_REPLY(mvm,
648 "TXQ %d status %s (0x%08x)\n\t\t\t\tinitial_rate 0x%x "
649 "retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n",
650 txq_id, iwl_mvm_get_tx_fail_reason(status),
651 status, le32_to_cpu(tx_resp->initial_rate),
652 tx_resp->failure_frame, SEQ_TO_INDEX(sequence),
653 ssn, next_reclaimed, seq_ctl);
654
655 rcu_read_lock();
656
657 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
658
659 if (!IS_ERR_OR_NULL(sta)) {
660 mvmsta = (void *)sta->drv_priv;
661
662 if (tid != IWL_TID_NON_QOS) {
663 struct iwl_mvm_tid_data *tid_data =
664 &mvmsta->tid_data[tid];
665
666 spin_lock(&mvmsta->lock);
667 tid_data->next_reclaimed = next_reclaimed;
668 IWL_DEBUG_TX_REPLY(mvm, "Next reclaimed packet:%d\n",
669 next_reclaimed);
670 iwl_mvm_check_ratid_empty(mvm, sta, tid);
671 spin_unlock(&mvmsta->lock);
672 }
673
674#ifdef CONFIG_PM_SLEEP
675 mvmsta->last_seq_ctl = seq_ctl;
676#endif
677 } else {
678 sta = NULL;
679 mvmsta = NULL;
680 }
681
682 /*
683 * If the txq is not an AMPDU queue, there is no chance we freed
684 * several skbs. Check that out...
685 * If there are no pending frames for this STA, notify mac80211 that
686 * this station can go to sleep in its STA table.
687 */
688 if (txq_id < IWL_FIRST_AMPDU_QUEUE && mvmsta &&
689 !WARN_ON(skb_freed > 1) &&
690 mvmsta->vif->type == NL80211_IFTYPE_AP &&
691 atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) {
692 ieee80211_sta_block_awake(mvm->hw, sta, false);
693 set_bit(sta_id, mvm->sta_drained);
694 schedule_work(&mvm->sta_drained_wk);
695 }
696
697 rcu_read_unlock();
698}
699
700#ifdef CONFIG_IWLWIFI_DEBUG
701#define AGG_TX_STATE_(x) case AGG_TX_STATE_ ## x: return #x
702static const char *iwl_get_agg_tx_status(u16 status)
703{
704 switch (status & AGG_TX_STATE_STATUS_MSK) {
705 AGG_TX_STATE_(TRANSMITTED);
706 AGG_TX_STATE_(UNDERRUN);
707 AGG_TX_STATE_(BT_PRIO);
708 AGG_TX_STATE_(FEW_BYTES);
709 AGG_TX_STATE_(ABORT);
710 AGG_TX_STATE_(LAST_SENT_TTL);
711 AGG_TX_STATE_(LAST_SENT_TRY_CNT);
712 AGG_TX_STATE_(LAST_SENT_BT_KILL);
713 AGG_TX_STATE_(SCD_QUERY);
714 AGG_TX_STATE_(TEST_BAD_CRC32);
715 AGG_TX_STATE_(RESPONSE);
716 AGG_TX_STATE_(DUMP_TX);
717 AGG_TX_STATE_(DELAY_TX);
718 }
719
720 return "UNKNOWN";
721}
722
723static void iwl_mvm_rx_tx_cmd_agg_dbg(struct iwl_mvm *mvm,
724 struct iwl_rx_packet *pkt)
725{
726 struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
727 struct agg_tx_status *frame_status = &tx_resp->status;
728 int i;
729
730 for (i = 0; i < tx_resp->frame_count; i++) {
731 u16 fstatus = le16_to_cpu(frame_status[i].status);
732
733 IWL_DEBUG_TX_REPLY(mvm,
734 "status %s (0x%04x), try-count (%d) seq (0x%x)\n",
735 iwl_get_agg_tx_status(fstatus),
736 fstatus & AGG_TX_STATE_STATUS_MSK,
737 (fstatus & AGG_TX_STATE_TRY_CNT_MSK) >>
738 AGG_TX_STATE_TRY_CNT_POS,
739 le16_to_cpu(frame_status[i].sequence));
740 }
741}
742#else
743static void iwl_mvm_rx_tx_cmd_agg_dbg(struct iwl_mvm *mvm,
744 struct iwl_rx_packet *pkt)
745{}
746#endif /* CONFIG_IWLWIFI_DEBUG */
747
748static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
749 struct iwl_rx_packet *pkt)
750{
751 struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
752 int sta_id = IWL_MVM_TX_RES_GET_RA(tx_resp->ra_tid);
753 int tid = IWL_MVM_TX_RES_GET_TID(tx_resp->ra_tid);
754 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
755 struct ieee80211_sta *sta;
756
757 if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_FIRST_AMPDU_QUEUE))
758 return;
759
760 if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS))
761 return;
762
763 iwl_mvm_rx_tx_cmd_agg_dbg(mvm, pkt);
764
765 rcu_read_lock();
766
767 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
768
769 if (!WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
770 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
771 mvmsta->tid_data[tid].rate_n_flags =
772 le32_to_cpu(tx_resp->initial_rate);
773 }
774
775 rcu_read_unlock();
776}
777
778int iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
779 struct iwl_device_cmd *cmd)
780{
781 struct iwl_rx_packet *pkt = rxb_addr(rxb);
782 struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
783
784 if (tx_resp->frame_count == 1)
785 iwl_mvm_rx_tx_cmd_single(mvm, pkt);
786 else
787 iwl_mvm_rx_tx_cmd_agg(mvm, pkt);
788
789 return 0;
790}
791
792int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
793 struct iwl_device_cmd *cmd)
794{
795 struct iwl_rx_packet *pkt = rxb_addr(rxb);
796 struct iwl_mvm_ba_notif *ba_notif = (void *)pkt->data;
797 struct sk_buff_head reclaimed_skbs;
798 struct iwl_mvm_tid_data *tid_data;
799 struct ieee80211_tx_info *info;
800 struct ieee80211_sta *sta;
801 struct iwl_mvm_sta *mvmsta;
802 struct ieee80211_hdr *hdr;
803 struct sk_buff *skb;
804 int sta_id, tid, freed;
805
806 /* "flow" corresponds to Tx queue */
807 u16 scd_flow = le16_to_cpu(ba_notif->scd_flow);
808
809 /* "ssn" is start of block-ack Tx window, corresponds to index
810 * (in Tx queue's circular buffer) of first TFD/frame in window */
811 u16 ba_resp_scd_ssn = le16_to_cpu(ba_notif->scd_ssn);
812
813 sta_id = ba_notif->sta_id;
814 tid = ba_notif->tid;
815
816 rcu_read_lock();
817
818 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
819
820 /* Reclaiming frames for a station that has been deleted ? */
821 if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
822 rcu_read_unlock();
823 return 0;
824 }
825
826 mvmsta = (void *)sta->drv_priv;
827 tid_data = &mvmsta->tid_data[tid];
828
829 if (WARN_ONCE(tid_data->txq_id != scd_flow, "Q %d, tid %d, flow %d",
830 tid_data->txq_id, tid, scd_flow)) {
831 rcu_read_unlock();
832 return 0;
833 }
834
835 spin_lock(&mvmsta->lock);
836
837 __skb_queue_head_init(&reclaimed_skbs);
838
839 /*
840 * Release all TFDs before the SSN, i.e. all TFDs in front of
841 * block-ack window (we assume that they've been successfully
842 * transmitted ... if not, it's too late anyway).
843 */
844 iwl_trans_reclaim(mvm->trans, scd_flow, ba_resp_scd_ssn,
845 &reclaimed_skbs);
846
847 IWL_DEBUG_TX_REPLY(mvm,
848 "BA_NOTIFICATION Received from %pM, sta_id = %d\n",
849 (u8 *)&ba_notif->sta_addr_lo32,
850 ba_notif->sta_id);
851 IWL_DEBUG_TX_REPLY(mvm,
852 "TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = %d, scd_ssn = %d sent:%d, acked:%d\n",
853 ba_notif->tid, le16_to_cpu(ba_notif->seq_ctl),
854 (unsigned long long)le64_to_cpu(ba_notif->bitmap),
855 scd_flow, ba_resp_scd_ssn, ba_notif->txed,
856 ba_notif->txed_2_done);
857
858 tid_data->next_reclaimed = ba_resp_scd_ssn;
859
860 iwl_mvm_check_ratid_empty(mvm, sta, tid);
861
862 freed = 0;
863
864 skb_queue_walk(&reclaimed_skbs, skb) {
865 hdr = (struct ieee80211_hdr *)skb->data;
866
867 if (ieee80211_is_data_qos(hdr->frame_control))
868 freed++;
869 else
870 WARN_ON_ONCE(1);
871
872 info = IEEE80211_SKB_CB(skb);
873 iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]);
874
875 if (freed == 1) {
876 /* this is the first skb we deliver in this batch */
877 /* put the rate scaling data there */
878 info = IEEE80211_SKB_CB(skb);
879 memset(&info->status, 0, sizeof(info->status));
880 info->flags |= IEEE80211_TX_STAT_ACK;
881 info->flags |= IEEE80211_TX_STAT_AMPDU;
882 info->status.ampdu_ack_len = ba_notif->txed_2_done;
883 info->status.ampdu_len = ba_notif->txed;
884 iwl_mvm_hwrate_to_tx_control(tid_data->rate_n_flags,
885 info);
886 }
887 }
888
889 spin_unlock(&mvmsta->lock);
890
891 rcu_read_unlock();
892
893 while (!skb_queue_empty(&reclaimed_skbs)) {
894 skb = __skb_dequeue(&reclaimed_skbs);
895 ieee80211_tx_status(mvm->hw, skb);
896 }
897
898 return 0;
899}
900
901int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, bool sync)
902{
903 int ret;
904 struct iwl_tx_path_flush_cmd flush_cmd = {
905 .queues_ctl = cpu_to_le32(tfd_msk),
906 .flush_ctl = cpu_to_le16(DUMP_TX_FIFO_FLUSH),
907 };
908
909 u32 flags = sync ? CMD_SYNC : CMD_ASYNC;
910
911 ret = iwl_mvm_send_cmd_pdu(mvm, TXPATH_FLUSH, flags,
912 sizeof(flush_cmd), &flush_cmd);
913 if (ret)
914 IWL_ERR(mvm, "Failed to send flush command (%d)\n", ret);
915 return ret;
916}
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
new file mode 100644
index 000000000000..000e842c2edd
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -0,0 +1,472 @@
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 LICENSE.GPL.
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#include <net/mac80211.h>
64
65#include "iwl-debug.h"
66#include "iwl-io.h"
67
68#include "mvm.h"
69#include "fw-api-rs.h"
70
71/*
72 * Will return 0 even if the cmd failed when RFKILL is asserted unless
73 * CMD_WANT_SKB is set in cmd->flags.
74 */
75int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd)
76{
77 int ret;
78
79 /*
80 * Synchronous commands from this op-mode must hold
81 * the mutex, this ensures we don't try to send two
82 * (or more) synchronous commands at a time.
83 */
84 if (!(cmd->flags & CMD_ASYNC))
85 lockdep_assert_held(&mvm->mutex);
86
87 ret = iwl_trans_send_cmd(mvm->trans, cmd);
88
89 /*
90 * If the caller wants the SKB, then don't hide any problems, the
91 * caller might access the response buffer which will be NULL if
92 * the command failed.
93 */
94 if (cmd->flags & CMD_WANT_SKB)
95 return ret;
96
97 /* Silently ignore failures if RFKILL is asserted */
98 if (!ret || ret == -ERFKILL)
99 return 0;
100 return ret;
101}
102
103int iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u8 id,
104 u32 flags, u16 len, const void *data)
105{
106 struct iwl_host_cmd cmd = {
107 .id = id,
108 .len = { len, },
109 .data = { data, },
110 .flags = flags,
111 };
112
113 return iwl_mvm_send_cmd(mvm, &cmd);
114}
115
116/*
117 * We assume that the caller set the status to the sucess value
118 */
119int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd,
120 u32 *status)
121{
122 struct iwl_rx_packet *pkt;
123 struct iwl_cmd_response *resp;
124 int ret, resp_len;
125
126 lockdep_assert_held(&mvm->mutex);
127
128 /*
129 * Only synchronous commands can wait for status,
130 * we use WANT_SKB so the caller can't.
131 */
132 if (WARN_ONCE(cmd->flags & (CMD_ASYNC | CMD_WANT_SKB),
133 "cmd flags %x", cmd->flags))
134 return -EINVAL;
135
136 cmd->flags |= CMD_SYNC | CMD_WANT_SKB;
137
138 ret = iwl_trans_send_cmd(mvm->trans, cmd);
139 if (ret == -ERFKILL) {
140 /*
141 * The command failed because of RFKILL, don't update
142 * the status, leave it as success and return 0.
143 */
144 return 0;
145 } else if (ret) {
146 return ret;
147 }
148
149 pkt = cmd->resp_pkt;
150 /* Can happen if RFKILL is asserted */
151 if (!pkt) {
152 ret = 0;
153 goto out_free_resp;
154 }
155
156 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
157 ret = -EIO;
158 goto out_free_resp;
159 }
160
161 resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
162 if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) {
163 ret = -EIO;
164 goto out_free_resp;
165 }
166
167 resp = (void *)pkt->data;
168 *status = le32_to_cpu(resp->status);
169 out_free_resp:
170 iwl_free_resp(cmd);
171 return ret;
172}
173
174/*
175 * We assume that the caller set the status to the sucess value
176 */
177int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u8 id, u16 len,
178 const void *data, u32 *status)
179{
180 struct iwl_host_cmd cmd = {
181 .id = id,
182 .len = { len, },
183 .data = { data, },
184 };
185
186 return iwl_mvm_send_cmd_status(mvm, &cmd, status);
187}
188
189#define IWL_DECLARE_RATE_INFO(r) \
190 [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP
191
192/*
193 * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP
194 */
195static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = {
196 IWL_DECLARE_RATE_INFO(1),
197 IWL_DECLARE_RATE_INFO(2),
198 IWL_DECLARE_RATE_INFO(5),
199 IWL_DECLARE_RATE_INFO(11),
200 IWL_DECLARE_RATE_INFO(6),
201 IWL_DECLARE_RATE_INFO(9),
202 IWL_DECLARE_RATE_INFO(12),
203 IWL_DECLARE_RATE_INFO(18),
204 IWL_DECLARE_RATE_INFO(24),
205 IWL_DECLARE_RATE_INFO(36),
206 IWL_DECLARE_RATE_INFO(48),
207 IWL_DECLARE_RATE_INFO(54),
208};
209
210int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
211 enum ieee80211_band band)
212{
213 int rate = rate_n_flags & RATE_LEGACY_RATE_MSK;
214 int idx;
215 int band_offset = 0;
216
217 /* Legacy rate format, search for match in table */
218 if (band == IEEE80211_BAND_5GHZ)
219 band_offset = IWL_FIRST_OFDM_RATE;
220 for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
221 if (fw_rate_idx_to_plcp[idx] == rate)
222 return idx - band_offset;
223
224 return -1;
225}
226
227u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx)
228{
229 /* Get PLCP rate for tx_cmd->rate_n_flags */
230 return fw_rate_idx_to_plcp[rate_idx];
231}
232
233int iwl_mvm_rx_fw_error(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
234 struct iwl_device_cmd *cmd)
235{
236 struct iwl_rx_packet *pkt = rxb_addr(rxb);
237 struct iwl_error_resp *err_resp = (void *)pkt->data;
238
239 IWL_ERR(mvm, "FW Error notification: type 0x%08X cmd_id 0x%02X\n",
240 le32_to_cpu(err_resp->error_type), err_resp->cmd_id);
241 IWL_ERR(mvm, "FW Error notification: seq 0x%04X service 0x%08X\n",
242 le16_to_cpu(err_resp->bad_cmd_seq_num),
243 le32_to_cpu(err_resp->error_service));
244 IWL_ERR(mvm, "FW Error notification: timestamp 0x%16llX\n",
245 le64_to_cpu(err_resp->timestamp));
246 return 0;
247}
248
249/*
250 * Returns the first antenna as ANT_[ABC], as defined in iwl-config.h.
251 * The parameter should also be a combination of ANT_[ABC].
252 */
253u8 first_antenna(u8 mask)
254{
255 BUILD_BUG_ON(ANT_A != BIT(0)); /* using ffs is wrong if not */
256 WARN_ON_ONCE(!mask); /* ffs will return 0 if mask is zeroed */
257 return (u8)(BIT(ffs(mask)));
258}
259
260/*
261 * Toggles between TX antennas to send the probe request on.
262 * Receives the bitmask of valid TX antennas and the *index* used
263 * for the last TX, and returns the next valid *index* to use.
264 * In order to set it in the tx_cmd, must do BIT(idx).
265 */
266u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx)
267{
268 u8 ind = last_idx;
269 int i;
270
271 for (i = 0; i < RATE_MCS_ANT_NUM; i++) {
272 ind = (ind + 1) % RATE_MCS_ANT_NUM;
273 if (valid & BIT(ind))
274 return ind;
275 }
276
277 WARN_ONCE(1, "Failed to toggle between antennas 0x%x", valid);
278 return last_idx;
279}
280
281static struct {
282 char *name;
283 u8 num;
284} advanced_lookup[] = {
285 { "NMI_INTERRUPT_WDG", 0x34 },
286 { "SYSASSERT", 0x35 },
287 { "UCODE_VERSION_MISMATCH", 0x37 },
288 { "BAD_COMMAND", 0x38 },
289 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
290 { "FATAL_ERROR", 0x3D },
291 { "NMI_TRM_HW_ERR", 0x46 },
292 { "NMI_INTERRUPT_TRM", 0x4C },
293 { "NMI_INTERRUPT_BREAK_POINT", 0x54 },
294 { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
295 { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
296 { "NMI_INTERRUPT_HOST", 0x66 },
297 { "NMI_INTERRUPT_ACTION_PT", 0x7C },
298 { "NMI_INTERRUPT_UNKNOWN", 0x84 },
299 { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
300 { "ADVANCED_SYSASSERT", 0 },
301};
302
303static const char *desc_lookup(u32 num)
304{
305 int i;
306
307 for (i = 0; i < ARRAY_SIZE(advanced_lookup) - 1; i++)
308 if (advanced_lookup[i].num == num)
309 return advanced_lookup[i].name;
310
311 /* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
312 return advanced_lookup[i].name;
313}
314
315/*
316 * Note: This structure is read from the device with IO accesses,
317 * and the reading already does the endian conversion. As it is
318 * read with u32-sized accesses, any members with a different size
319 * need to be ordered correctly though!
320 */
321struct iwl_error_event_table {
322 u32 valid; /* (nonzero) valid, (0) log is empty */
323 u32 error_id; /* type of error */
324 u32 pc; /* program counter */
325 u32 blink1; /* branch link */
326 u32 blink2; /* branch link */
327 u32 ilink1; /* interrupt link */
328 u32 ilink2; /* interrupt link */
329 u32 data1; /* error-specific data */
330 u32 data2; /* error-specific data */
331 u32 data3; /* error-specific data */
332 u32 bcon_time; /* beacon timer */
333 u32 tsf_low; /* network timestamp function timer */
334 u32 tsf_hi; /* network timestamp function timer */
335 u32 gp1; /* GP1 timer register */
336 u32 gp2; /* GP2 timer register */
337 u32 gp3; /* GP3 timer register */
338 u32 ucode_ver; /* uCode version */
339 u32 hw_ver; /* HW Silicon version */
340 u32 brd_ver; /* HW board version */
341 u32 log_pc; /* log program counter */
342 u32 frame_ptr; /* frame pointer */
343 u32 stack_ptr; /* stack pointer */
344 u32 hcmd; /* last host command header */
345 u32 isr0; /* isr status register LMPM_NIC_ISR0:
346 * rxtx_flag */
347 u32 isr1; /* isr status register LMPM_NIC_ISR1:
348 * host_flag */
349 u32 isr2; /* isr status register LMPM_NIC_ISR2:
350 * enc_flag */
351 u32 isr3; /* isr status register LMPM_NIC_ISR3:
352 * time_flag */
353 u32 isr4; /* isr status register LMPM_NIC_ISR4:
354 * wico interrupt */
355 u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
356 u32 wait_event; /* wait event() caller address */
357 u32 l2p_control; /* L2pControlField */
358 u32 l2p_duration; /* L2pDurationField */
359 u32 l2p_mhvalid; /* L2pMhValidBits */
360 u32 l2p_addr_match; /* L2pAddrMatchStat */
361 u32 lmpm_pmg_sel; /* indicate which clocks are turned on
362 * (LMPM_PMG_SEL) */
363 u32 u_timestamp; /* indicate when the date and time of the
364 * compilation */
365 u32 flow_handler; /* FH read/write pointers, RX credit */
366} __packed;
367
368#define ERROR_START_OFFSET (1 * sizeof(u32))
369#define ERROR_ELEM_SIZE (7 * sizeof(u32))
370
371void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
372{
373 struct iwl_trans *trans = mvm->trans;
374 struct iwl_error_event_table table;
375 u32 base;
376
377 base = mvm->error_event_table;
378 if (mvm->cur_ucode == IWL_UCODE_INIT) {
379 if (!base)
380 base = mvm->fw->init_errlog_ptr;
381 } else {
382 if (!base)
383 base = mvm->fw->inst_errlog_ptr;
384 }
385
386 if (base < 0x800000 || base >= 0x80C000) {
387 IWL_ERR(mvm,
388 "Not valid error log pointer 0x%08X for %s uCode\n",
389 base,
390 (mvm->cur_ucode == IWL_UCODE_INIT)
391 ? "Init" : "RT");
392 return;
393 }
394
395 iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
396
397 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
398 IWL_ERR(trans, "Start IWL Error Log Dump:\n");
399 IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
400 mvm->status, table.valid);
401 }
402
403 trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
404 table.data1, table.data2, table.data3,
405 table.blink1, table.blink2, table.ilink1,
406 table.ilink2, table.bcon_time, table.gp1,
407 table.gp2, table.gp3, table.ucode_ver,
408 table.hw_ver, table.brd_ver);
409 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
410 desc_lookup(table.error_id));
411 IWL_ERR(mvm, "0x%08X | uPc\n", table.pc);
412 IWL_ERR(mvm, "0x%08X | branchlink1\n", table.blink1);
413 IWL_ERR(mvm, "0x%08X | branchlink2\n", table.blink2);
414 IWL_ERR(mvm, "0x%08X | interruptlink1\n", table.ilink1);
415 IWL_ERR(mvm, "0x%08X | interruptlink2\n", table.ilink2);
416 IWL_ERR(mvm, "0x%08X | data1\n", table.data1);
417 IWL_ERR(mvm, "0x%08X | data2\n", table.data2);
418 IWL_ERR(mvm, "0x%08X | data3\n", table.data3);
419 IWL_ERR(mvm, "0x%08X | beacon time\n", table.bcon_time);
420 IWL_ERR(mvm, "0x%08X | tsf low\n", table.tsf_low);
421 IWL_ERR(mvm, "0x%08X | tsf hi\n", table.tsf_hi);
422 IWL_ERR(mvm, "0x%08X | time gp1\n", table.gp1);
423 IWL_ERR(mvm, "0x%08X | time gp2\n", table.gp2);
424 IWL_ERR(mvm, "0x%08X | time gp3\n", table.gp3);
425 IWL_ERR(mvm, "0x%08X | uCode version\n", table.ucode_ver);
426 IWL_ERR(mvm, "0x%08X | hw version\n", table.hw_ver);
427 IWL_ERR(mvm, "0x%08X | board version\n", table.brd_ver);
428 IWL_ERR(mvm, "0x%08X | hcmd\n", table.hcmd);
429 IWL_ERR(mvm, "0x%08X | isr0\n", table.isr0);
430 IWL_ERR(mvm, "0x%08X | isr1\n", table.isr1);
431 IWL_ERR(mvm, "0x%08X | isr2\n", table.isr2);
432 IWL_ERR(mvm, "0x%08X | isr3\n", table.isr3);
433 IWL_ERR(mvm, "0x%08X | isr4\n", table.isr4);
434 IWL_ERR(mvm, "0x%08X | isr_pref\n", table.isr_pref);
435 IWL_ERR(mvm, "0x%08X | wait_event\n", table.wait_event);
436 IWL_ERR(mvm, "0x%08X | l2p_control\n", table.l2p_control);
437 IWL_ERR(mvm, "0x%08X | l2p_duration\n", table.l2p_duration);
438 IWL_ERR(mvm, "0x%08X | l2p_mhvalid\n", table.l2p_mhvalid);
439 IWL_ERR(mvm, "0x%08X | l2p_addr_match\n", table.l2p_addr_match);
440 IWL_ERR(mvm, "0x%08X | lmpm_pmg_sel\n", table.lmpm_pmg_sel);
441 IWL_ERR(mvm, "0x%08X | timestamp\n", table.u_timestamp);
442 IWL_ERR(mvm, "0x%08X | flow_handler\n", table.flow_handler);
443}
444
445/**
446 * iwl_mvm_send_lq_cmd() - Send link quality command
447 * @init: This command is sent as part of station initialization right
448 * after station has been added.
449 *
450 * The link quality command is sent as the last step of station creation.
451 * This is the special case in which init is set and we call a callback in
452 * this case to clear the state indicating that station creation is in
453 * progress.
454 */
455int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
456 u8 flags, bool init)
457{
458 struct iwl_host_cmd cmd = {
459 .id = LQ_CMD,
460 .len = { sizeof(struct iwl_lq_cmd), },
461 .flags = flags,
462 .data = { lq, },
463 };
464
465 if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
466 return -EINVAL;
467
468 if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
469 return -EINVAL;
470
471 return iwl_mvm_send_cmd(mvm, &cmd);
472}
diff --git a/drivers/net/wireless/iwlwifi/pcie/1000.c b/drivers/net/wireless/iwlwifi/pcie/1000.c
index f8620ecae6b4..ff3389757281 100644
--- a/drivers/net/wireless/iwlwifi/pcie/1000.c
+++ b/drivers/net/wireless/iwlwifi/pcie/1000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c
index 244019cec3e1..e7de33128b16 100644
--- a/drivers/net/wireless/iwlwifi/pcie/2000.c
+++ b/drivers/net/wireless/iwlwifi/pcie/2000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/pcie/5000.c b/drivers/net/wireless/iwlwifi/pcie/5000.c
index 83ca40321ff1..5096f7c96ab6 100644
--- a/drivers/net/wireless/iwlwifi/pcie/5000.c
+++ b/drivers/net/wireless/iwlwifi/pcie/5000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c
index d4df976d4709..801ff49796dd 100644
--- a/drivers/net/wireless/iwlwifi/pcie/6000.c
+++ b/drivers/net/wireless/iwlwifi/pcie/6000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/pcie/7000.c
new file mode 100644
index 000000000000..6e35b2b72332
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/pcie/7000.c
@@ -0,0 +1,111 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#include <linux/module.h>
28#include <linux/stringify.h>
29#include "iwl-config.h"
30#include "iwl-agn-hw.h"
31#include "cfg.h"
32
33/* Highest firmware API version supported */
34#define IWL7260_UCODE_API_MAX 6
35#define IWL3160_UCODE_API_MAX 6
36
37/* Oldest version we won't warn about */
38#define IWL7260_UCODE_API_OK 6
39#define IWL3160_UCODE_API_OK 6
40
41/* Lowest firmware API version supported */
42#define IWL7260_UCODE_API_MIN 6
43#define IWL3160_UCODE_API_MIN 6
44
45/* NVM versions */
46#define IWL7260_NVM_VERSION 0x0a1d
47#define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */
48#define IWL3160_NVM_VERSION 0x709
49#define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */
50
51#define IWL7260_FW_PRE "iwlwifi-7260-"
52#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode"
53
54#define IWL3160_FW_PRE "iwlwifi-3160-"
55#define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode"
56
57static const struct iwl_base_params iwl7000_base_params = {
58 .eeprom_size = OTP_LOW_IMAGE_SIZE,
59 .num_of_queues = IWLAGN_NUM_QUEUES,
60 .pll_cfg_val = 0,
61 .shadow_ram_support = true,
62 .led_compensation = 57,
63 .adv_thermal_throttle = true,
64 .support_ct_kill_exit = true,
65 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
66 .chain_noise_scale = 1000,
67 .wd_timeout = IWL_LONG_WD_TIMEOUT,
68 .max_event_log_size = 512,
69 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
70};
71
72static const struct iwl_ht_params iwl7000_ht_params = {
73 .ht_greenfield_support = true,
74 .use_rts_for_aggregation = true, /* use rts/cts protection */
75 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
76};
77
78#define IWL_DEVICE_7000 \
79 .ucode_api_max = IWL7260_UCODE_API_MAX, \
80 .ucode_api_ok = IWL7260_UCODE_API_OK, \
81 .ucode_api_min = IWL7260_UCODE_API_MIN, \
82 .device_family = IWL_DEVICE_FAMILY_7000, \
83 .max_inst_size = IWL60_RTC_INST_SIZE, \
84 .max_data_size = IWL60_RTC_DATA_SIZE, \
85 .base_params = &iwl7000_base_params, \
86 /* TODO: .bt_params? */ \
87 .need_temp_offset_calib = true, \
88 .led_mode = IWL_LED_RF_STATE, \
89 .adv_pm = true \
90
91
92const struct iwl_cfg iwl7260_2ac_cfg = {
93 .name = "Intel(R) Dual Band Wireless AC7260",
94 .fw_name_pre = IWL7260_FW_PRE,
95 IWL_DEVICE_7000,
96 .ht_params = &iwl7000_ht_params,
97 .nvm_ver = IWL7260_NVM_VERSION,
98 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
99};
100
101const struct iwl_cfg iwl3160_ac_cfg = {
102 .name = "Intel(R) Dual Band Wireless AC3160",
103 .fw_name_pre = IWL3160_FW_PRE,
104 IWL_DEVICE_7000,
105 .ht_params = &iwl7000_ht_params,
106 .nvm_ver = IWL3160_NVM_VERSION,
107 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
108};
109
110MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
111MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
diff --git a/drivers/net/wireless/iwlwifi/pcie/cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h
index 82152311d73b..c6f8e83c3551 100644
--- a/drivers/net/wireless/iwlwifi/pcie/cfg.h
+++ b/drivers/net/wireless/iwlwifi/pcie/cfg.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -109,5 +109,7 @@ extern const struct iwl_cfg iwl6035_2agn_cfg;
109extern const struct iwl_cfg iwl105_bgn_cfg; 109extern const struct iwl_cfg iwl105_bgn_cfg;
110extern const struct iwl_cfg iwl105_bgn_d_cfg; 110extern const struct iwl_cfg iwl105_bgn_d_cfg;
111extern const struct iwl_cfg iwl135_bgn_cfg; 111extern const struct iwl_cfg iwl135_bgn_cfg;
112extern const struct iwl_cfg iwl7260_2ac_cfg;
113extern const struct iwl_cfg iwl3160_ac_cfg;
112 114
113#endif /* __iwl_pci_h__ */ 115#endif /* __iwl_pci_h__ */
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index c2e141af353c..7bc0fb9128dd 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -255,6 +255,12 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
255 {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, 255 {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)},
256 {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, 256 {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)},
257 257
258/* 7000 Series */
259 {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)},
260 {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)},
261 {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_ac_cfg)},
262 {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_ac_cfg)},
263
258 {0} 264 {0}
259}; 265};
260MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); 266MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 20735a008cab..5f6bb4e09d42 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -235,6 +235,7 @@ struct iwl_txq {
235 * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) 235 * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes)
236 * @rx_page_order: page order for receive buffer size 236 * @rx_page_order: page order for receive buffer size
237 * @wd_timeout: queue watchdog timeout (jiffies) 237 * @wd_timeout: queue watchdog timeout (jiffies)
238 * @reg_lock: protect hw register access
238 */ 239 */
239struct iwl_trans_pcie { 240struct iwl_trans_pcie {
240 struct iwl_rxq rxq; 241 struct iwl_rxq rxq;
@@ -283,6 +284,9 @@ struct iwl_trans_pcie {
283 284
284 /* queue watchdog */ 285 /* queue watchdog */
285 unsigned long wd_timeout; 286 unsigned long wd_timeout;
287
288 /*protect hw register */
289 spinlock_t reg_lock;
286}; 290};
287 291
288/** 292/**
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 4e6591d24e61..a9ca1d35fa93 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -594,6 +594,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
594 int index, cmd_index, err, len; 594 int index, cmd_index, err, len;
595 struct iwl_rx_cmd_buffer rxcb = { 595 struct iwl_rx_cmd_buffer rxcb = {
596 ._offset = offset, 596 ._offset = offset,
597 ._rx_page_order = trans_pcie->rx_page_order,
597 ._page = rxb->page, 598 ._page = rxb->page,
598 ._page_stolen = false, 599 ._page_stolen = false,
599 .truesize = max_len, 600 .truesize = max_len,
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index c57641eb83d5..56d4f72500bc 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -75,6 +75,33 @@
75#include "iwl-agn-hw.h" 75#include "iwl-agn-hw.h"
76#include "internal.h" 76#include "internal.h"
77 77
78static void __iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans,
79 u32 reg, u32 mask, u32 value)
80{
81 u32 v;
82
83#ifdef CONFIG_IWLWIFI_DEBUG
84 WARN_ON_ONCE(value & ~mask);
85#endif
86
87 v = iwl_read32(trans, reg);
88 v &= ~mask;
89 v |= value;
90 iwl_write32(trans, reg, v);
91}
92
93static inline void __iwl_trans_pcie_clear_bit(struct iwl_trans *trans,
94 u32 reg, u32 mask)
95{
96 __iwl_trans_pcie_set_bits_mask(trans, reg, mask, 0);
97}
98
99static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
100 u32 reg, u32 mask)
101{
102 __iwl_trans_pcie_set_bits_mask(trans, reg, mask, mask);
103}
104
78static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux) 105static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux)
79{ 106{
80 if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold)) 107 if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold))
@@ -779,15 +806,16 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
779} 806}
780#endif /* CONFIG_PM_SLEEP */ 807#endif /* CONFIG_PM_SLEEP */
781 808
782static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent) 809static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
810 unsigned long *flags)
783{ 811{
784 int ret; 812 int ret;
785 813 struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans);
786 lockdep_assert_held(&trans->reg_lock); 814 spin_lock_irqsave(&pcie_trans->reg_lock, *flags);
787 815
788 /* this bit wakes up the NIC */ 816 /* this bit wakes up the NIC */
789 __iwl_set_bit(trans, CSR_GP_CNTRL, 817 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
790 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 818 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
791 819
792 /* 820 /*
793 * These bits say the device is running, and should keep running for 821 * These bits say the device is running, and should keep running for
@@ -819,18 +847,34 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent)
819 WARN_ONCE(1, 847 WARN_ONCE(1,
820 "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", 848 "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
821 val); 849 val);
850 spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags);
822 return false; 851 return false;
823 } 852 }
824 } 853 }
825 854
855 /*
856 * Fool sparse by faking we release the lock - sparse will
857 * track nic_access anyway.
858 */
859 __release(&pcie_trans->reg_lock);
826 return true; 860 return true;
827} 861}
828 862
829static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) 863static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
864 unsigned long *flags)
830{ 865{
831 lockdep_assert_held(&trans->reg_lock); 866 struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans);
832 __iwl_clear_bit(trans, CSR_GP_CNTRL, 867
833 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 868 lockdep_assert_held(&pcie_trans->reg_lock);
869
870 /*
871 * Fool sparse by faking we acquiring the lock - sparse will
872 * track nic_access anyway.
873 */
874 __acquire(&pcie_trans->reg_lock);
875
876 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
877 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
834 /* 878 /*
835 * Above we read the CSR_GP_CNTRL register, which will flush 879 * Above we read the CSR_GP_CNTRL register, which will flush
836 * any previous writes, but we need the write that clears the 880 * any previous writes, but we need the write that clears the
@@ -838,6 +882,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
838 * scheduled on different CPUs (after we drop reg_lock). 882 * scheduled on different CPUs (after we drop reg_lock).
839 */ 883 */
840 mmiowb(); 884 mmiowb();
885 spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags);
841} 886}
842 887
843static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, 888static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
@@ -847,16 +892,14 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
847 int offs, ret = 0; 892 int offs, ret = 0;
848 u32 *vals = buf; 893 u32 *vals = buf;
849 894
850 spin_lock_irqsave(&trans->reg_lock, flags); 895 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
851 if (iwl_trans_grab_nic_access(trans, false)) {
852 iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); 896 iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
853 for (offs = 0; offs < dwords; offs++) 897 for (offs = 0; offs < dwords; offs++)
854 vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); 898 vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
855 iwl_trans_release_nic_access(trans); 899 iwl_trans_release_nic_access(trans, &flags);
856 } else { 900 } else {
857 ret = -EBUSY; 901 ret = -EBUSY;
858 } 902 }
859 spin_unlock_irqrestore(&trans->reg_lock, flags);
860 return ret; 903 return ret;
861} 904}
862 905
@@ -867,17 +910,15 @@ static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
867 int offs, ret = 0; 910 int offs, ret = 0;
868 u32 *vals = buf; 911 u32 *vals = buf;
869 912
870 spin_lock_irqsave(&trans->reg_lock, flags); 913 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
871 if (iwl_trans_grab_nic_access(trans, false)) {
872 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); 914 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
873 for (offs = 0; offs < dwords; offs++) 915 for (offs = 0; offs < dwords; offs++)
874 iwl_write32(trans, HBUS_TARG_MEM_WDAT, 916 iwl_write32(trans, HBUS_TARG_MEM_WDAT,
875 vals ? vals[offs] : 0); 917 vals ? vals[offs] : 0);
876 iwl_trans_release_nic_access(trans); 918 iwl_trans_release_nic_access(trans, &flags);
877 } else { 919 } else {
878 ret = -EBUSY; 920 ret = -EBUSY;
879 } 921 }
880 spin_unlock_irqrestore(&trans->reg_lock, flags);
881 return ret; 922 return ret;
882} 923}
883 924
@@ -952,6 +993,17 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans)
952 return ret; 993 return ret;
953} 994}
954 995
996static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
997 u32 mask, u32 value)
998{
999 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1000 unsigned long flags;
1001
1002 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1003 __iwl_trans_pcie_set_bits_mask(trans, reg, mask, value);
1004 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1005}
1006
955static const char *get_fh_string(int cmd) 1007static const char *get_fh_string(int cmd)
956{ 1008{
957#define IWL_CMD(x) case x: return #x 1009#define IWL_CMD(x) case x: return #x
@@ -1405,7 +1457,8 @@ static const struct iwl_trans_ops trans_ops_pcie = {
1405 .configure = iwl_trans_pcie_configure, 1457 .configure = iwl_trans_pcie_configure,
1406 .set_pmi = iwl_trans_pcie_set_pmi, 1458 .set_pmi = iwl_trans_pcie_set_pmi,
1407 .grab_nic_access = iwl_trans_pcie_grab_nic_access, 1459 .grab_nic_access = iwl_trans_pcie_grab_nic_access,
1408 .release_nic_access = iwl_trans_pcie_release_nic_access 1460 .release_nic_access = iwl_trans_pcie_release_nic_access,
1461 .set_bits_mask = iwl_trans_pcie_set_bits_mask,
1409}; 1462};
1410 1463
1411struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, 1464struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
@@ -1429,6 +1482,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1429 trans->cfg = cfg; 1482 trans->cfg = cfg;
1430 trans_pcie->trans = trans; 1483 trans_pcie->trans = trans;
1431 spin_lock_init(&trans_pcie->irq_lock); 1484 spin_lock_init(&trans_pcie->irq_lock);
1485 spin_lock_init(&trans_pcie->reg_lock);
1432 init_waitqueue_head(&trans_pcie->ucode_write_waitq); 1486 init_waitqueue_head(&trans_pcie->ucode_write_waitq);
1433 1487
1434 /* W/A - seems to solve weird behavior. We need to remove this if we 1488 /* W/A - seems to solve weird behavior. We need to remove this if we
@@ -1495,7 +1549,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1495 1549
1496 /* Initialize the wait queue for commands */ 1550 /* Initialize the wait queue for commands */
1497 init_waitqueue_head(&trans_pcie->wait_command_queue); 1551 init_waitqueue_head(&trans_pcie->wait_command_queue);
1498 spin_lock_init(&trans->reg_lock);
1499 1552
1500 snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name), 1553 snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name),
1501 "iwl_cmd_pool:%s", dev_name(trans->dev)); 1554 "iwl_cmd_pool:%s", dev_name(trans->dev));
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index a93f06762b96..041127ad372a 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 7b0ae2407083..25596ab0c576 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -400,45 +400,6 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
400} 400}
401 401
402/* 402/*
403 * This function reconfigures the Tx buffer size in firmware.
404 *
405 * This function prepares a firmware command and issues it, if
406 * the current Tx buffer size is different from the one requested.
407 * Maximum configurable Tx buffer size is limited by the HT capability
408 * field value.
409 */
410void
411mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
412 struct mwifiex_bssdescriptor *bss_desc)
413{
414 u16 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_2K;
415 u16 tx_buf, curr_tx_buf_size = 0;
416
417 if (bss_desc->bcn_ht_cap) {
418 if (le16_to_cpu(bss_desc->bcn_ht_cap->cap_info) &
419 IEEE80211_HT_CAP_MAX_AMSDU)
420 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_8K;
421 else
422 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_4K;
423 }
424
425 tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu);
426
427 dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n",
428 max_amsdu, priv->adapter->max_tx_buf_size);
429
430 if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K)
431 curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
432 else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_4K)
433 curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
434 else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K)
435 curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K;
436 if (curr_tx_buf_size != tx_buf)
437 mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
438 HostCmd_ACT_GEN_SET, 0, &tx_buf);
439}
440
441/*
442 * This function checks if the given pointer is valid entry of 403 * This function checks if the given pointer is valid entry of
443 * Tx BA Stream table. 404 * Tx BA Stream table.
444 */ 405 */
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 46006a54a656..29a4c02479d6 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -34,8 +34,6 @@ int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action,
34int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, 34int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
35 struct mwifiex_bssdescriptor *bss_desc, 35 struct mwifiex_bssdescriptor *bss_desc,
36 u8 **buffer); 36 u8 **buffer);
37void mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
38 struct mwifiex_bssdescriptor *bss_desc);
39void mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type, 37void mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type,
40 struct mwifiex_ie_types_htcap *); 38 struct mwifiex_ie_types_htcap *);
41int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv, 39int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README
index b55badef4660..3d64613ebb29 100644
--- a/drivers/net/wireless/mwifiex/README
+++ b/drivers/net/wireless/mwifiex/README
@@ -121,7 +121,6 @@ info
121 wmm_ac_vi = <number of packets sent to device from WMM AcVi queue> 121 wmm_ac_vi = <number of packets sent to device from WMM AcVi queue>
122 wmm_ac_be = <number of packets sent to device from WMM AcBE queue> 122 wmm_ac_be = <number of packets sent to device from WMM AcBE queue>
123 wmm_ac_bk = <number of packets sent to device from WMM AcBK queue> 123 wmm_ac_bk = <number of packets sent to device from WMM AcBK queue>
124 max_tx_buf_size = <maximum Tx buffer size>
125 tx_buf_size = <current Tx buffer size> 124 tx_buf_size = <current Tx buffer size>
126 curr_tx_buf_size = <current Tx buffer size> 125 curr_tx_buf_size = <current Tx buffer size>
127 ps_mode = <0/1, CAM mode/PS mode> 126 ps_mode = <0/1, CAM mode/PS mode>
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 46e34aa65d1c..753b5682d53f 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -58,8 +58,6 @@ static struct mwifiex_debug_data items[] = {
58 item_addr(packets_out[WMM_AC_BE]), 1}, 58 item_addr(packets_out[WMM_AC_BE]), 1},
59 {"wmm_ac_bk", item_size(packets_out[WMM_AC_BK]), 59 {"wmm_ac_bk", item_size(packets_out[WMM_AC_BK]),
60 item_addr(packets_out[WMM_AC_BK]), 1}, 60 item_addr(packets_out[WMM_AC_BK]), 1},
61 {"max_tx_buf_size", item_size(max_tx_buf_size),
62 item_addr(max_tx_buf_size), 1},
63 {"tx_buf_size", item_size(tx_buf_size), 61 {"tx_buf_size", item_size(tx_buf_size),
64 item_addr(tx_buf_size), 1}, 62 item_addr(tx_buf_size), 1},
65 {"curr_tx_buf_size", item_size(curr_tx_buf_size), 63 {"curr_tx_buf_size", item_size(curr_tx_buf_size),
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 84848c33b7f0..e38aa9b3663d 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -314,7 +314,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
314 314
315 adapter->pm_wakeup_fw_try = false; 315 adapter->pm_wakeup_fw_try = false;
316 316
317 adapter->max_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
318 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; 317 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
319 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; 318 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
320 319
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 6095b3e53f4e..f3d9d0445529 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -178,7 +178,6 @@ struct mwifiex_ds_tx_ba_stream_tbl {
178struct mwifiex_debug_info { 178struct mwifiex_debug_info {
179 u32 int_counter; 179 u32 int_counter;
180 u32 packets_out[MAX_NUM_TID]; 180 u32 packets_out[MAX_NUM_TID];
181 u32 max_tx_buf_size;
182 u32 tx_buf_size; 181 u32 tx_buf_size;
183 u32 curr_tx_buf_size; 182 u32 curr_tx_buf_size;
184 u32 tx_tbl_num; 183 u32 tx_tbl_num;
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 893d809ba83c..a537297866c6 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -157,8 +157,8 @@ static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1,
157 157
158 memset(rate1, 0, rate1_size); 158 memset(rate1, 0, rate1_size);
159 159
160 for (i = 0; rate2[i] && i < rate2_size; i++) { 160 for (i = 0; i < rate2_size && rate2[i]; i++) {
161 for (j = 0; tmp[j] && j < rate1_size; j++) { 161 for (j = 0; j < rate1_size && tmp[j]; j++) {
162 /* Check common rate, excluding the bit for 162 /* Check common rate, excluding the bit for
163 basic rate */ 163 basic rate */
164 if ((rate2[i] & 0x7F) == (tmp[j] & 0x7F)) { 164 if ((rate2[i] & 0x7F) == (tmp[j] & 0x7F)) {
@@ -398,8 +398,6 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
398 398
399 pos = (u8 *) assoc; 399 pos = (u8 *) assoc;
400 400
401 mwifiex_cfg_tx_buf(priv, bss_desc);
402
403 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE); 401 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE);
404 402
405 /* Save so we know which BSS Desc to use in the response handler */ 403 /* Save so we know which BSS Desc to use in the response handler */
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 51044e3ea89b..ac799a046eb7 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -631,7 +631,6 @@ struct mwifiex_adapter {
631 /* spin lock for main process */ 631 /* spin lock for main process */
632 spinlock_t main_proc_lock; 632 spinlock_t main_proc_lock;
633 u32 mwifiex_processing; 633 u32 mwifiex_processing;
634 u16 max_tx_buf_size;
635 u16 tx_buf_size; 634 u16 tx_buf_size;
636 u16 curr_tx_buf_size; 635 u16 curr_tx_buf_size;
637 u32 ioport; 636 u32 ioport;
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 237949c070cc..df88e65595c8 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -846,8 +846,8 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
846 846
847 card->tx_buf_list[wrdoneidx] = NULL; 847 card->tx_buf_list[wrdoneidx] = NULL;
848 card->txbd_ring[wrdoneidx]->paddr = 0; 848 card->txbd_ring[wrdoneidx]->paddr = 0;
849 card->rxbd_ring[wrdoneidx]->len = 0; 849 card->txbd_ring[wrdoneidx]->len = 0;
850 card->rxbd_ring[wrdoneidx]->flags = 0; 850 card->txbd_ring[wrdoneidx]->flags = 0;
851 card->txbd_rdptr++; 851 card->txbd_rdptr++;
852 852
853 if ((card->txbd_rdptr & MWIFIEX_TXBD_MASK) == num_tx_buffs) 853 if ((card->txbd_rdptr & MWIFIEX_TXBD_MASK) == num_tx_buffs)
@@ -1985,6 +1985,7 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
1985 card->pci_mmap = pci_iomap(pdev, 0, 0); 1985 card->pci_mmap = pci_iomap(pdev, 0, 0);
1986 if (!card->pci_mmap) { 1986 if (!card->pci_mmap) {
1987 dev_err(adapter->dev, "iomap(0) error\n"); 1987 dev_err(adapter->dev, "iomap(0) error\n");
1988 ret = -EIO;
1988 goto err_iomap0; 1989 goto err_iomap0;
1989 } 1990 }
1990 ret = pci_request_region(pdev, 2, DRV_NAME); 1991 ret = pci_request_region(pdev, 2, DRV_NAME);
@@ -1995,6 +1996,7 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
1995 card->pci_mmap1 = pci_iomap(pdev, 2, 0); 1996 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
1996 if (!card->pci_mmap1) { 1997 if (!card->pci_mmap1) {
1997 dev_err(adapter->dev, "iomap(2) error\n"); 1998 dev_err(adapter->dev, "iomap(2) error\n");
1999 ret = -EIO;
1998 goto err_iomap2; 2000 goto err_iomap2;
1999 } 2001 }
2000 2002
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 31d7b2bdaa31..d3fb9a14580a 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -332,7 +332,7 @@ mwifiex_write_data_sync(struct mwifiex_adapter *adapter,
332 u8 *buffer, u32 pkt_len, u32 port) 332 u8 *buffer, u32 pkt_len, u32 port)
333{ 333{
334 struct sdio_mmc_card *card = adapter->card; 334 struct sdio_mmc_card *card = adapter->card;
335 int ret = -1; 335 int ret;
336 u8 blk_mode = 336 u8 blk_mode =
337 (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; 337 (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
338 u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; 338 u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
@@ -350,8 +350,7 @@ mwifiex_write_data_sync(struct mwifiex_adapter *adapter,
350 350
351 sdio_claim_host(card->func); 351 sdio_claim_host(card->func);
352 352
353 if (!sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size)) 353 ret = sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size);
354 ret = 0;
355 354
356 sdio_release_host(card->func); 355 sdio_release_host(card->func);
357 356
@@ -365,7 +364,7 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer,
365 u32 len, u32 port, u8 claim) 364 u32 len, u32 port, u8 claim)
366{ 365{
367 struct sdio_mmc_card *card = adapter->card; 366 struct sdio_mmc_card *card = adapter->card;
368 int ret = -1; 367 int ret;
369 u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE 368 u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE
370 : BLOCK_MODE; 369 : BLOCK_MODE;
371 u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; 370 u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
@@ -376,8 +375,7 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer,
376 if (claim) 375 if (claim)
377 sdio_claim_host(card->func); 376 sdio_claim_host(card->func);
378 377
379 if (!sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size)) 378 ret = sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size);
380 ret = 0;
381 379
382 if (claim) 380 if (claim)
383 sdio_release_host(card->func); 381 sdio_release_host(card->func);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 65c12eb3e5e7..847056415ac9 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -935,9 +935,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
935 / MWIFIEX_SDIO_BLOCK_SIZE) 935 / MWIFIEX_SDIO_BLOCK_SIZE)
936 * MWIFIEX_SDIO_BLOCK_SIZE; 936 * MWIFIEX_SDIO_BLOCK_SIZE;
937 adapter->curr_tx_buf_size = adapter->tx_buf_size; 937 adapter->curr_tx_buf_size = adapter->tx_buf_size;
938 dev_dbg(adapter->dev, 938 dev_dbg(adapter->dev, "cmd: curr_tx_buf_size=%d\n",
939 "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n", 939 adapter->curr_tx_buf_size);
940 adapter->max_tx_buf_size, adapter->tx_buf_size);
941 940
942 if (adapter->if_ops.update_mp_end_port) 941 if (adapter->if_ops.update_mp_end_port)
943 adapter->if_ops.update_mp_end_port(adapter, 942 adapter->if_ops.update_mp_end_port(adapter,
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 5d4a10a8a005..f90fe21e5bfd 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -672,7 +672,7 @@ static int mwifiex_write_data_sync(struct mwifiex_adapter *adapter, u8 *pbuf,
672 *len, &actual_length, timeout); 672 *len, &actual_length, timeout);
673 if (ret) { 673 if (ret) {
674 dev_err(adapter->dev, "usb_bulk_msg for tx failed: %d\n", ret); 674 dev_err(adapter->dev, "usb_bulk_msg for tx failed: %d\n", ret);
675 ret = -1; 675 return ret;
676 } 676 }
677 677
678 *len = actual_length; 678 *len = actual_length;
@@ -691,7 +691,7 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *pbuf,
691 *len, &actual_length, timeout); 691 *len, &actual_length, timeout);
692 if (ret) { 692 if (ret) {
693 dev_err(adapter->dev, "usb_bulk_msg for rx failed: %d\n", ret); 693 dev_err(adapter->dev, "usb_bulk_msg for rx failed: %d\n", ret);
694 ret = -1; 694 return ret;
695 } 695 }
696 696
697 *len = actual_length; 697 *len = actual_length;
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 0982375ba3b1..21553976b550 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -91,7 +91,7 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
91 memcpy(info->packets_out, 91 memcpy(info->packets_out,
92 priv->wmm.packets_out, 92 priv->wmm.packets_out,
93 sizeof(priv->wmm.packets_out)); 93 sizeof(priv->wmm.packets_out));
94 info->max_tx_buf_size = (u32) adapter->max_tx_buf_size; 94 info->curr_tx_buf_size = (u32) adapter->curr_tx_buf_size;
95 info->tx_buf_size = (u32) adapter->tx_buf_size; 95 info->tx_buf_size = (u32) adapter->tx_buf_size;
96 info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(priv, 96 info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(priv,
97 info->rx_tbl); 97 info->rx_tbl);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 224cf917744a..2031130d860b 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -285,6 +285,9 @@ struct mwl8k_priv {
285 char *fw_pref; 285 char *fw_pref;
286 char *fw_alt; 286 char *fw_alt;
287 struct completion firmware_loading_complete; 287 struct completion firmware_loading_complete;
288
289 /* bitmap of running BSSes */
290 u32 running_bsses;
288}; 291};
289 292
290#define MAX_WEP_KEY_LEN 13 293#define MAX_WEP_KEY_LEN 13
@@ -2156,6 +2159,8 @@ static void mwl8k_fw_unlock(struct ieee80211_hw *hw)
2156 } 2159 }
2157} 2160}
2158 2161
2162static void mwl8k_enable_bsses(struct ieee80211_hw *hw, bool enable,
2163 u32 bitmap);
2159 2164
2160/* 2165/*
2161 * Command processing. 2166 * Command processing.
@@ -2174,6 +2179,34 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
2174 int rc; 2179 int rc;
2175 unsigned long timeout = 0; 2180 unsigned long timeout = 0;
2176 u8 buf[32]; 2181 u8 buf[32];
2182 u32 bitmap = 0;
2183
2184 wiphy_dbg(hw->wiphy, "Posting %s [%d]\n",
2185 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), cmd->macid);
2186
2187 /* Before posting firmware commands that could change the hardware
2188 * characteristics, make sure that all BSSes are stopped temporary.
2189 * Enable these stopped BSSes after completion of the commands
2190 */
2191
2192 rc = mwl8k_fw_lock(hw);
2193 if (rc)
2194 return rc;
2195
2196 if (priv->ap_fw && priv->running_bsses) {
2197 switch (le16_to_cpu(cmd->code)) {
2198 case MWL8K_CMD_SET_RF_CHANNEL:
2199 case MWL8K_CMD_RADIO_CONTROL:
2200 case MWL8K_CMD_RF_TX_POWER:
2201 case MWL8K_CMD_TX_POWER:
2202 case MWL8K_CMD_RF_ANTENNA:
2203 case MWL8K_CMD_RTS_THRESHOLD:
2204 case MWL8K_CMD_MIMO_CONFIG:
2205 bitmap = priv->running_bsses;
2206 mwl8k_enable_bsses(hw, false, bitmap);
2207 break;
2208 }
2209 }
2177 2210
2178 cmd->result = (__force __le16) 0xffff; 2211 cmd->result = (__force __le16) 0xffff;
2179 dma_size = le16_to_cpu(cmd->length); 2212 dma_size = le16_to_cpu(cmd->length);
@@ -2182,13 +2215,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
2182 if (pci_dma_mapping_error(priv->pdev, dma_addr)) 2215 if (pci_dma_mapping_error(priv->pdev, dma_addr))
2183 return -ENOMEM; 2216 return -ENOMEM;
2184 2217
2185 rc = mwl8k_fw_lock(hw);
2186 if (rc) {
2187 pci_unmap_single(priv->pdev, dma_addr, dma_size,
2188 PCI_DMA_BIDIRECTIONAL);
2189 return rc;
2190 }
2191
2192 priv->hostcmd_wait = &cmd_wait; 2218 priv->hostcmd_wait = &cmd_wait;
2193 iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR); 2219 iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
2194 iowrite32(MWL8K_H2A_INT_DOORBELL, 2220 iowrite32(MWL8K_H2A_INT_DOORBELL,
@@ -2201,7 +2227,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
2201 2227
2202 priv->hostcmd_wait = NULL; 2228 priv->hostcmd_wait = NULL;
2203 2229
2204 mwl8k_fw_unlock(hw);
2205 2230
2206 pci_unmap_single(priv->pdev, dma_addr, dma_size, 2231 pci_unmap_single(priv->pdev, dma_addr, dma_size,
2207 PCI_DMA_BIDIRECTIONAL); 2232 PCI_DMA_BIDIRECTIONAL);
@@ -2228,6 +2253,11 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
2228 ms); 2253 ms);
2229 } 2254 }
2230 2255
2256 if (bitmap)
2257 mwl8k_enable_bsses(hw, true, bitmap);
2258
2259 mwl8k_fw_unlock(hw);
2260
2231 return rc; 2261 return rc;
2232} 2262}
2233 2263
@@ -2489,7 +2519,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
2489 priv->hw_rev = cmd->hw_rev; 2519 priv->hw_rev = cmd->hw_rev;
2490 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps)); 2520 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
2491 priv->ap_macids_supported = 0x000000ff; 2521 priv->ap_macids_supported = 0x000000ff;
2492 priv->sta_macids_supported = 0x00000000; 2522 priv->sta_macids_supported = 0x00000100;
2493 priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues); 2523 priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues);
2494 if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) { 2524 if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) {
2495 wiphy_warn(hw->wiphy, "fw reported %d ampdu queues" 2525 wiphy_warn(hw->wiphy, "fw reported %d ampdu queues"
@@ -3508,7 +3538,10 @@ static int mwl8k_cmd_update_mac_addr(struct ieee80211_hw *hw,
3508 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP; 3538 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
3509 if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) { 3539 if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) {
3510 if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported)) 3540 if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported))
3511 mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT; 3541 if (priv->ap_fw)
3542 mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
3543 else
3544 mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT;
3512 else 3545 else
3513 mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT; 3546 mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
3514 } else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) { 3547 } else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) {
@@ -3680,8 +3713,16 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
3680 struct ieee80211_vif *vif, int enable) 3713 struct ieee80211_vif *vif, int enable)
3681{ 3714{
3682 struct mwl8k_cmd_bss_start *cmd; 3715 struct mwl8k_cmd_bss_start *cmd;
3716 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
3717 struct mwl8k_priv *priv = hw->priv;
3683 int rc; 3718 int rc;
3684 3719
3720 if (enable && (priv->running_bsses & (1 << mwl8k_vif->macid)))
3721 return 0;
3722
3723 if (!enable && !(priv->running_bsses & (1 << mwl8k_vif->macid)))
3724 return 0;
3725
3685 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 3726 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3686 if (cmd == NULL) 3727 if (cmd == NULL)
3687 return -ENOMEM; 3728 return -ENOMEM;
@@ -3693,9 +3734,31 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
3693 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); 3734 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
3694 kfree(cmd); 3735 kfree(cmd);
3695 3736
3737 if (!rc) {
3738 if (enable)
3739 priv->running_bsses |= (1 << mwl8k_vif->macid);
3740 else
3741 priv->running_bsses &= ~(1 << mwl8k_vif->macid);
3742 }
3696 return rc; 3743 return rc;
3697} 3744}
3698 3745
3746static void mwl8k_enable_bsses(struct ieee80211_hw *hw, bool enable, u32 bitmap)
3747{
3748 struct mwl8k_priv *priv = hw->priv;
3749 struct mwl8k_vif *mwl8k_vif, *tmp_vif;
3750 struct ieee80211_vif *vif;
3751
3752 list_for_each_entry_safe(mwl8k_vif, tmp_vif, &priv->vif_list, list) {
3753 vif = mwl8k_vif->vif;
3754
3755 if (!(bitmap & (1 << mwl8k_vif->macid)))
3756 continue;
3757
3758 if (vif->type == NL80211_IFTYPE_AP)
3759 mwl8k_cmd_bss_start(hw, vif, enable);
3760 }
3761}
3699/* 3762/*
3700 * CMD_BASTREAM. 3763 * CMD_BASTREAM.
3701 */ 3764 */
@@ -4202,8 +4265,9 @@ static int mwl8k_set_key(struct ieee80211_hw *hw,
4202 u8 encr_type; 4265 u8 encr_type;
4203 u8 *addr; 4266 u8 *addr;
4204 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); 4267 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
4268 struct mwl8k_priv *priv = hw->priv;
4205 4269
4206 if (vif->type == NL80211_IFTYPE_STATION) 4270 if (vif->type == NL80211_IFTYPE_STATION && !priv->ap_fw)
4207 return -EOPNOTSUPP; 4271 return -EOPNOTSUPP;
4208 4272
4209 if (sta == NULL) 4273 if (sta == NULL)
@@ -4609,12 +4673,18 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
4609 break; 4673 break;
4610 case NL80211_IFTYPE_STATION: 4674 case NL80211_IFTYPE_STATION:
4611 if (priv->ap_fw && di->fw_image_sta) { 4675 if (priv->ap_fw && di->fw_image_sta) {
4612 /* we must load the sta fw to meet this request */ 4676 if (!list_empty(&priv->vif_list)) {
4613 if (!list_empty(&priv->vif_list)) 4677 wiphy_warn(hw->wiphy, "AP interface is running.\n"
4614 return -EBUSY; 4678 "Adding STA interface for WDS");
4615 rc = mwl8k_reload_firmware(hw, di->fw_image_sta); 4679 } else {
4616 if (rc) 4680 /* we must load the sta fw to
4617 return rc; 4681 * meet this request.
4682 */
4683 rc = mwl8k_reload_firmware(hw,
4684 di->fw_image_sta);
4685 if (rc)
4686 return rc;
4687 }
4618 } 4688 }
4619 macids_supported = priv->sta_macids_supported; 4689 macids_supported = priv->sta_macids_supported;
4620 break; 4690 break;
@@ -4638,7 +4708,7 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
4638 /* Set the mac address. */ 4708 /* Set the mac address. */
4639 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr); 4709 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr);
4640 4710
4641 if (priv->ap_fw) 4711 if (vif->type == NL80211_IFTYPE_AP)
4642 mwl8k_cmd_set_new_stn_add_self(hw, vif); 4712 mwl8k_cmd_set_new_stn_add_self(hw, vif);
4643 4713
4644 priv->macids_used |= 1 << mwl8k_vif->macid; 4714 priv->macids_used |= 1 << mwl8k_vif->macid;
@@ -4663,7 +4733,7 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw,
4663 struct mwl8k_priv *priv = hw->priv; 4733 struct mwl8k_priv *priv = hw->priv;
4664 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); 4734 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
4665 4735
4666 if (priv->ap_fw) 4736 if (vif->type == NL80211_IFTYPE_AP)
4667 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr); 4737 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr);
4668 4738
4669 mwl8k_cmd_del_mac_addr(hw, vif, vif->addr); 4739 mwl8k_cmd_del_mac_addr(hw, vif, vif->addr);
@@ -4737,9 +4807,11 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
4737 if (rc) 4807 if (rc)
4738 goto out; 4808 goto out;
4739 4809
4740 rc = mwl8k_cmd_set_rf_channel(hw, conf); 4810 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
4741 if (rc) 4811 rc = mwl8k_cmd_set_rf_channel(hw, conf);
4742 goto out; 4812 if (rc)
4813 goto out;
4814 }
4743 4815
4744 if (conf->power_level > 18) 4816 if (conf->power_level > 18)
4745 conf->power_level = 18; 4817 conf->power_level = 18;
@@ -4752,12 +4824,6 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
4752 goto out; 4824 goto out;
4753 } 4825 }
4754 4826
4755 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3);
4756 if (rc)
4757 wiphy_warn(hw->wiphy, "failed to set # of RX antennas");
4758 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7);
4759 if (rc)
4760 wiphy_warn(hw->wiphy, "failed to set # of TX antennas");
4761 4827
4762 } else { 4828 } else {
4763 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); 4829 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
@@ -4815,7 +4881,8 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4815 rcu_read_unlock(); 4881 rcu_read_unlock();
4816 } 4882 }
4817 4883
4818 if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) { 4884 if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc &&
4885 !priv->ap_fw) {
4819 rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates); 4886 rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates);
4820 if (rc) 4887 if (rc)
4821 goto out; 4888 goto out;
@@ -4823,6 +4890,25 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4823 rc = mwl8k_cmd_use_fixed_rate_sta(hw); 4890 rc = mwl8k_cmd_use_fixed_rate_sta(hw);
4824 if (rc) 4891 if (rc)
4825 goto out; 4892 goto out;
4893 } else {
4894 if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc &&
4895 priv->ap_fw) {
4896 int idx;
4897 int rate;
4898
4899 /* Use AP firmware specific rate command.
4900 */
4901 idx = ffs(vif->bss_conf.basic_rates);
4902 if (idx)
4903 idx--;
4904
4905 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
4906 rate = mwl8k_rates_24[idx].hw_value;
4907 else
4908 rate = mwl8k_rates_50[idx].hw_value;
4909
4910 mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate);
4911 }
4826 } 4912 }
4827 4913
4828 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 4914 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
@@ -4832,13 +4918,13 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4832 goto out; 4918 goto out;
4833 } 4919 }
4834 4920
4835 if (changed & BSS_CHANGED_ERP_SLOT) { 4921 if ((changed & BSS_CHANGED_ERP_SLOT) && !priv->ap_fw) {
4836 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot); 4922 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot);
4837 if (rc) 4923 if (rc)
4838 goto out; 4924 goto out;
4839 } 4925 }
4840 4926
4841 if (vif->bss_conf.assoc && 4927 if (vif->bss_conf.assoc && !priv->ap_fw &&
4842 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT | 4928 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT |
4843 BSS_CHANGED_HT))) { 4929 BSS_CHANGED_HT))) {
4844 rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates); 4930 rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates);
@@ -4918,11 +5004,9 @@ static void
4918mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 5004mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4919 struct ieee80211_bss_conf *info, u32 changed) 5005 struct ieee80211_bss_conf *info, u32 changed)
4920{ 5006{
4921 struct mwl8k_priv *priv = hw->priv; 5007 if (vif->type == NL80211_IFTYPE_STATION)
4922
4923 if (!priv->ap_fw)
4924 mwl8k_bss_info_changed_sta(hw, vif, info, changed); 5008 mwl8k_bss_info_changed_sta(hw, vif, info, changed);
4925 else 5009 if (vif->type == NL80211_IFTYPE_AP)
4926 mwl8k_bss_info_changed_ap(hw, vif, info, changed); 5010 mwl8k_bss_info_changed_ap(hw, vif, info, changed);
4927} 5011}
4928 5012
@@ -5647,6 +5731,15 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
5647 goto err_free_irq; 5731 goto err_free_irq;
5648 } 5732 }
5649 5733
5734 /* Configure Antennas */
5735 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3);
5736 if (rc)
5737 wiphy_warn(hw->wiphy, "failed to set # of RX antennas");
5738 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7);
5739 if (rc)
5740 wiphy_warn(hw->wiphy, "failed to set # of TX antennas");
5741
5742
5650 /* Disable interrupts */ 5743 /* Disable interrupts */
5651 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 5744 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
5652 free_irq(priv->pdev->irq, hw); 5745 free_irq(priv->pdev->irq, hw);
@@ -5734,6 +5827,7 @@ fail:
5734 5827
5735static const struct ieee80211_iface_limit ap_if_limits[] = { 5828static const struct ieee80211_iface_limit ap_if_limits[] = {
5736 { .max = 8, .types = BIT(NL80211_IFTYPE_AP) }, 5829 { .max = 8, .types = BIT(NL80211_IFTYPE_AP) },
5830 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION) },
5737}; 5831};
5738 5832
5739static const struct ieee80211_iface_combination ap_if_comb = { 5833static const struct ieee80211_iface_combination ap_if_comb = {
@@ -5826,6 +5920,7 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
5826 5920
5827 if (priv->ap_macids_supported || priv->device_info->fw_image_ap) { 5921 if (priv->ap_macids_supported || priv->device_info->fw_image_ap) {
5828 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); 5922 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
5923 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
5829 hw->wiphy->iface_combinations = &ap_if_comb; 5924 hw->wiphy->iface_combinations = &ap_if_comb;
5830 hw->wiphy->n_iface_combinations = 1; 5925 hw->wiphy->n_iface_combinations = 1;
5831 } 5926 }
@@ -5948,6 +6043,8 @@ static int mwl8k_probe(struct pci_dev *pdev,
5948 6043
5949 priv->hw_restart_in_progress = false; 6044 priv->hw_restart_in_progress = false;
5950 6045
6046 priv->running_bsses = 0;
6047
5951 return rc; 6048 return rc;
5952 6049
5953err_stop_firmware: 6050err_stop_firmware:
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index a5c694f23d33..a658b4bc7da2 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -80,7 +80,7 @@ static inline bool rt2800_is_305x_soc(struct rt2x00_dev *rt2x00dev)
80 rt2x00_rf(rt2x00dev, RF3022)) 80 rt2x00_rf(rt2x00dev, RF3022))
81 return true; 81 return true;
82 82
83 NOTICE(rt2x00dev, "Unknown RF chipset on rt305x\n"); 83 WARNING(rt2x00dev, "Unknown RF chipset on rt305x\n");
84 return false; 84 return false;
85} 85}
86 86
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 0e8d1705e368..48a01aa21f1c 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -1152,6 +1152,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
1152 { PCI_DEVICE(0x1814, 0x3562) }, 1152 { PCI_DEVICE(0x1814, 0x3562) },
1153 { PCI_DEVICE(0x1814, 0x3592) }, 1153 { PCI_DEVICE(0x1814, 0x3592) },
1154 { PCI_DEVICE(0x1814, 0x3593) }, 1154 { PCI_DEVICE(0x1814, 0x3593) },
1155 { PCI_DEVICE(0x1814, 0x359f) },
1155#endif 1156#endif
1156#ifdef CONFIG_RT2800PCI_RT53XX 1157#ifdef CONFIG_RT2800PCI_RT53XX
1157 { PCI_DEVICE(0x1814, 0x5360) }, 1158 { PCI_DEVICE(0x1814, 0x5360) },
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 4721cada1591..42b5b659af16 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -540,9 +540,9 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
540 tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); 540 tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
541 541
542 if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { 542 if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) {
543 WARNING(entry->queue->rt2x00dev, 543 DEBUG(entry->queue->rt2x00dev,
544 "TX status report missed for queue %d entry %d\n", 544 "TX status report missed for queue %d entry %d\n",
545 entry->queue->qid, entry->entry_idx); 545 entry->queue->qid, entry->entry_idx);
546 return TXDONE_UNKNOWN; 546 return TXDONE_UNKNOWN;
547 } 547 }
548 548
@@ -968,6 +968,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
968 { USB_DEVICE(0x07d1, 0x3c13) }, 968 { USB_DEVICE(0x07d1, 0x3c13) },
969 { USB_DEVICE(0x07d1, 0x3c15) }, 969 { USB_DEVICE(0x07d1, 0x3c15) },
970 { USB_DEVICE(0x07d1, 0x3c16) }, 970 { USB_DEVICE(0x07d1, 0x3c16) },
971 { USB_DEVICE(0x07d1, 0x3c17) },
971 { USB_DEVICE(0x2001, 0x3c1b) }, 972 { USB_DEVICE(0x2001, 0x3c1b) },
972 /* Draytek */ 973 /* Draytek */
973 { USB_DEVICE(0x07fa, 0x7712) }, 974 { USB_DEVICE(0x07fa, 0x7712) },
@@ -1115,6 +1116,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
1115 /* Zyxel */ 1116 /* Zyxel */
1116 { USB_DEVICE(0x0586, 0x3416) }, 1117 { USB_DEVICE(0x0586, 0x3416) },
1117 { USB_DEVICE(0x0586, 0x3418) }, 1118 { USB_DEVICE(0x0586, 0x3418) },
1119 { USB_DEVICE(0x0586, 0x341a) },
1118 { USB_DEVICE(0x0586, 0x341e) }, 1120 { USB_DEVICE(0x0586, 0x341e) },
1119 { USB_DEVICE(0x0586, 0x343e) }, 1121 { USB_DEVICE(0x0586, 0x343e) },
1120#ifdef CONFIG_RT2800USB_RT33XX 1122#ifdef CONFIG_RT2800USB_RT33XX
@@ -1166,6 +1168,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
1166#ifdef CONFIG_RT2800USB_RT53XX 1168#ifdef CONFIG_RT2800USB_RT53XX
1167 /* Arcadyan */ 1169 /* Arcadyan */
1168 { USB_DEVICE(0x043e, 0x7a12) }, 1170 { USB_DEVICE(0x043e, 0x7a12) },
1171 { USB_DEVICE(0x043e, 0x7a32) },
1169 /* Azurewave */ 1172 /* Azurewave */
1170 { USB_DEVICE(0x13d3, 0x3329) }, 1173 { USB_DEVICE(0x13d3, 0x3329) },
1171 { USB_DEVICE(0x13d3, 0x3365) }, 1174 { USB_DEVICE(0x13d3, 0x3365) },
@@ -1177,16 +1180,20 @@ static struct usb_device_id rt2800usb_device_table[] = {
1177 { USB_DEVICE(0x2001, 0x3c1e) }, 1180 { USB_DEVICE(0x2001, 0x3c1e) },
1178 /* LG innotek */ 1181 /* LG innotek */
1179 { USB_DEVICE(0x043e, 0x7a22) }, 1182 { USB_DEVICE(0x043e, 0x7a22) },
1183 { USB_DEVICE(0x043e, 0x7a42) },
1180 /* Panasonic */ 1184 /* Panasonic */
1181 { USB_DEVICE(0x04da, 0x1801) }, 1185 { USB_DEVICE(0x04da, 0x1801) },
1182 { USB_DEVICE(0x04da, 0x1800) }, 1186 { USB_DEVICE(0x04da, 0x1800) },
1187 { USB_DEVICE(0x04da, 0x23f6) },
1183 /* Philips */ 1188 /* Philips */
1184 { USB_DEVICE(0x0471, 0x2104) }, 1189 { USB_DEVICE(0x0471, 0x2104) },
1190 { USB_DEVICE(0x0471, 0x2126) },
1191 { USB_DEVICE(0x0471, 0x2180) },
1192 { USB_DEVICE(0x0471, 0x2181) },
1193 { USB_DEVICE(0x0471, 0x2182) },
1185 /* Ralink */ 1194 /* Ralink */
1186 { USB_DEVICE(0x148f, 0x5370) }, 1195 { USB_DEVICE(0x148f, 0x5370) },
1187 { USB_DEVICE(0x148f, 0x5372) }, 1196 { USB_DEVICE(0x148f, 0x5372) },
1188 /* Unknown */
1189 { USB_DEVICE(0x04da, 0x23f6) },
1190#endif 1197#endif
1191#ifdef CONFIG_RT2800USB_UNKNOWN 1198#ifdef CONFIG_RT2800USB_UNKNOWN
1192 /* 1199 /*
@@ -1223,7 +1230,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
1223 { USB_DEVICE(0x18c5, 0x0008) }, 1230 { USB_DEVICE(0x18c5, 0x0008) },
1224 /* D-Link */ 1231 /* D-Link */
1225 { USB_DEVICE(0x07d1, 0x3c0b) }, 1232 { USB_DEVICE(0x07d1, 0x3c0b) },
1226 { USB_DEVICE(0x07d1, 0x3c17) },
1227 /* Encore */ 1233 /* Encore */
1228 { USB_DEVICE(0x203d, 0x14a1) }, 1234 { USB_DEVICE(0x203d, 0x14a1) },
1229 /* Gemtek */ 1235 /* Gemtek */
@@ -1261,8 +1267,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
1261 { USB_DEVICE(0x083a, 0xc522) }, 1267 { USB_DEVICE(0x083a, 0xc522) },
1262 { USB_DEVICE(0x083a, 0xd522) }, 1268 { USB_DEVICE(0x083a, 0xd522) },
1263 { USB_DEVICE(0x083a, 0xf511) }, 1269 { USB_DEVICE(0x083a, 0xf511) },
1264 /* Zyxel */
1265 { USB_DEVICE(0x0586, 0x341a) },
1266#endif 1270#endif
1267 { 0, } 1271 { 0, }
1268}; 1272};
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index b52512b8ac5f..9a3f31a543ce 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -88,11 +88,9 @@
88#define ERROR_PROBE(__msg, __args...) \ 88#define ERROR_PROBE(__msg, __args...) \
89 DEBUG_PRINTK_PROBE(KERN_ERR, "Error", __msg, ##__args) 89 DEBUG_PRINTK_PROBE(KERN_ERR, "Error", __msg, ##__args)
90#define WARNING(__dev, __msg, __args...) \ 90#define WARNING(__dev, __msg, __args...) \
91 DEBUG_PRINTK(__dev, KERN_WARNING, "Warning", __msg, ##__args) 91 DEBUG_PRINTK_MSG(__dev, KERN_WARNING, "Warning", __msg, ##__args)
92#define NOTICE(__dev, __msg, __args...) \
93 DEBUG_PRINTK(__dev, KERN_NOTICE, "Notice", __msg, ##__args)
94#define INFO(__dev, __msg, __args...) \ 92#define INFO(__dev, __msg, __args...) \
95 DEBUG_PRINTK(__dev, KERN_INFO, "Info", __msg, ##__args) 93 DEBUG_PRINTK_MSG(__dev, KERN_INFO, "Info", __msg, ##__args)
96#define DEBUG(__dev, __msg, __args...) \ 94#define DEBUG(__dev, __msg, __args...) \
97 DEBUG_PRINTK(__dev, KERN_DEBUG, "Debug", __msg, ##__args) 95 DEBUG_PRINTK(__dev, KERN_DEBUG, "Debug", __msg, ##__args)
98#define EEPROM(__dev, __msg, __args...) \ 96#define EEPROM(__dev, __msg, __args...) \
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index b40a53857498..1031db66474a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1236,7 +1236,8 @@ static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
1236 */ 1236 */
1237 if_limit = &rt2x00dev->if_limits_ap; 1237 if_limit = &rt2x00dev->if_limits_ap;
1238 if_limit->max = rt2x00dev->ops->max_ap_intf; 1238 if_limit->max = rt2x00dev->ops->max_ap_intf;
1239 if_limit->types = BIT(NL80211_IFTYPE_AP); 1239 if_limit->types = BIT(NL80211_IFTYPE_AP) |
1240 BIT(NL80211_IFTYPE_MESH_POINT);
1240 1241
1241 /* 1242 /*
1242 * Build up AP interface combinations structure. 1243 * Build up AP interface combinations structure.
@@ -1446,7 +1447,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
1446#ifdef CONFIG_PM 1447#ifdef CONFIG_PM
1447int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) 1448int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
1448{ 1449{
1449 NOTICE(rt2x00dev, "Going to sleep.\n"); 1450 DEBUG(rt2x00dev, "Going to sleep.\n");
1450 1451
1451 /* 1452 /*
1452 * Prevent mac80211 from accessing driver while suspended. 1453 * Prevent mac80211 from accessing driver while suspended.
@@ -1486,7 +1487,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_suspend);
1486 1487
1487int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) 1488int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1488{ 1489{
1489 NOTICE(rt2x00dev, "Waking up.\n"); 1490 DEBUG(rt2x00dev, "Waking up.\n");
1490 1491
1491 /* 1492 /*
1492 * Restore/enable extra components. 1493 * Restore/enable extra components.
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index ed7a1bb3f245..20c6eccce5aa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -731,9 +731,9 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw,
731 queue->aifs = params->aifs; 731 queue->aifs = params->aifs;
732 queue->txop = params->txop; 732 queue->txop = params->txop;
733 733
734 INFO(rt2x00dev, 734 DEBUG(rt2x00dev,
735 "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d, TXop: %d.\n", 735 "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d, TXop: %d.\n",
736 queue_idx, queue->cw_min, queue->cw_max, queue->aifs, queue->txop); 736 queue_idx, queue->cw_min, queue->cw_max, queue->aifs, queue->txop);
737 737
738 return 0; 738 return 0;
739} 739}
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c
index c1e065f136ba..204f46c4510d 100644
--- a/drivers/net/wireless/rtlwifi/rc.c
+++ b/drivers/net/wireless/rtlwifi/rc.c
@@ -217,19 +217,6 @@ static void rtl_tx_status(void *ppriv,
217 } 217 }
218} 218}
219 219
220static void rtl_rate_init(void *ppriv,
221 struct ieee80211_supported_band *sband,
222 struct ieee80211_sta *sta, void *priv_sta)
223{
224}
225
226static void rtl_rate_update(void *ppriv,
227 struct ieee80211_supported_band *sband,
228 struct ieee80211_sta *sta, void *priv_sta,
229 u32 changed)
230{
231}
232
233static void *rtl_rate_alloc(struct ieee80211_hw *hw, 220static void *rtl_rate_alloc(struct ieee80211_hw *hw,
234 struct dentry *debugfsdir) 221 struct dentry *debugfsdir)
235{ 222{
@@ -274,8 +261,6 @@ static struct rate_control_ops rtl_rate_ops = {
274 .free = rtl_rate_free, 261 .free = rtl_rate_free,
275 .alloc_sta = rtl_rate_alloc_sta, 262 .alloc_sta = rtl_rate_alloc_sta,
276 .free_sta = rtl_rate_free_sta, 263 .free_sta = rtl_rate_free_sta,
277 .rate_init = rtl_rate_init,
278 .rate_update = rtl_rate_update,
279 .tx_status = rtl_tx_status, 264 .tx_status = rtl_tx_status,
280 .get_rate = rtl_get_rate, 265 .get_rate = rtl_get_rate,
281}; 266};
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
index 1cdf5a271c9f..b793a659a465 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
@@ -669,7 +669,8 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
669 u8 thermalvalue, delta, delta_lck, delta_iqk; 669 u8 thermalvalue, delta, delta_lck, delta_iqk;
670 long ele_a, ele_d, temp_cck, val_x, value32; 670 long ele_a, ele_d, temp_cck, val_x, value32;
671 long val_y, ele_c = 0; 671 long val_y, ele_c = 0;
672 u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; 672 u8 ofdm_index[2], ofdm_index_old[2], cck_index_old = 0;
673 s8 cck_index = 0;
673 int i; 674 int i;
674 bool is2t = IS_92C_SERIAL(rtlhal->version); 675 bool is2t = IS_92C_SERIAL(rtlhal->version);
675 s8 txpwr_level[2] = {0, 0}; 676 s8 txpwr_level[2] = {0, 0};
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index b7e6607e6b6d..d9e659f92767 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -76,7 +76,7 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
76 GFP_KERNEL, hw, rtl_fw_cb); 76 GFP_KERNEL, hw, rtl_fw_cb);
77 77
78 78
79 return 0; 79 return err;
80} 80}
81 81
82static void rtl92cu_deinit_sw_vars(struct ieee80211_hw *hw) 82static void rtl92cu_deinit_sw_vars(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
index fd8df233ff22..5251fb8a111e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
@@ -841,9 +841,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
841 long ele_a = 0, ele_d, temp_cck, val_x, value32; 841 long ele_a = 0, ele_d, temp_cck, val_x, value32;
842 long val_y, ele_c = 0; 842 long val_y, ele_c = 0;
843 u8 ofdm_index[2]; 843 u8 ofdm_index[2];
844 u8 cck_index = 0; 844 s8 cck_index = 0;
845 u8 ofdm_index_old[2]; 845 u8 ofdm_index_old[2];
846 u8 cck_index_old = 0; 846 s8 cck_index_old = 0;
847 u8 index; 847 u8 index;
848 int i; 848 int i;
849 bool is2t = IS_92D_SINGLEPHY(rtlhal->version); 849 bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
index f55b1767ef57..35cb8f83eed4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
@@ -252,7 +252,7 @@ static void _rtl8723ae_fill_h2c_command(struct ieee80211_hw *hw,
252 u16 box_reg = 0, box_extreg = 0; 252 u16 box_reg = 0, box_extreg = 0;
253 u8 u1tmp; 253 u8 u1tmp;
254 bool isfw_rd = false; 254 bool isfw_rd = false;
255 bool bwrite_sucess = false; 255 bool bwrite_success = false;
256 u8 wait_h2c_limmit = 100; 256 u8 wait_h2c_limmit = 100;
257 u8 wait_writeh2c_limmit = 100; 257 u8 wait_writeh2c_limmit = 100;
258 u8 boxcontent[4], boxextcontent[2]; 258 u8 boxcontent[4], boxextcontent[2];
@@ -291,7 +291,7 @@ static void _rtl8723ae_fill_h2c_command(struct ieee80211_hw *hw,
291 } 291 }
292 } 292 }
293 293
294 while (!bwrite_sucess) { 294 while (!bwrite_success) {
295 wait_writeh2c_limmit--; 295 wait_writeh2c_limmit--;
296 if (wait_writeh2c_limmit == 0) { 296 if (wait_writeh2c_limmit == 0) {
297 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 297 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
@@ -429,7 +429,7 @@ static void _rtl8723ae_fill_h2c_command(struct ieee80211_hw *hw,
429 break; 429 break;
430 } 430 }
431 431
432 bwrite_sucess = true; 432 bwrite_success = true;
433 433
434 rtlhal->last_hmeboxnum = boxnum + 1; 434 rtlhal->last_hmeboxnum = boxnum + 1;
435 if (rtlhal->last_hmeboxnum == 4) 435 if (rtlhal->last_hmeboxnum == 4)
@@ -512,7 +512,6 @@ static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw,
512 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 512 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
513 struct rtl8192_tx_ring *ring; 513 struct rtl8192_tx_ring *ring;
514 struct rtl_tx_desc *pdesc; 514 struct rtl_tx_desc *pdesc;
515 u8 own;
516 unsigned long flags; 515 unsigned long flags;
517 struct sk_buff *pskb = NULL; 516 struct sk_buff *pskb = NULL;
518 517
@@ -525,7 +524,6 @@ static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw,
525 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); 524 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
526 525
527 pdesc = &ring->desc[0]; 526 pdesc = &ring->desc[0];
528 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
529 527
530 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); 528 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
531 529
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
index 887d521fe690..68c28340f791 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
@@ -1433,7 +1433,6 @@ static void _rtl8723ae_dm_bt_coexist_2_ant(struct ieee80211_hw *hw)
1433 struct rtl_priv *rtlpriv = rtl_priv(hw); 1433 struct rtl_priv *rtlpriv = rtl_priv(hw);
1434 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 1434 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1435 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); 1435 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1436 u8 bt_retry_cnt;
1437 u8 bt_info_original; 1436 u8 bt_info_original;
1438 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, 1437 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1439 "[BTCoex] Get bt info by fw!!\n"); 1438 "[BTCoex] Get bt info by fw!!\n");
@@ -1445,7 +1444,6 @@ static void _rtl8723ae_dm_bt_coexist_2_ant(struct ieee80211_hw *hw)
1445 "[BTCoex] c2h for btInfo not rcvd yet!!\n"); 1444 "[BTCoex] c2h for btInfo not rcvd yet!!\n");
1446 } 1445 }
1447 1446
1448 bt_retry_cnt = rtlhal->hal_coex_8723.bt_retry_cnt;
1449 bt_info_original = rtlhal->hal_coex_8723.c2h_bt_info_original; 1447 bt_info_original = rtlhal->hal_coex_8723.c2h_bt_info_original;
1450 1448
1451 /* when bt inquiry or page scan, we have to set h2c 0x25 1449 /* when bt inquiry or page scan, we have to set h2c 0x25
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
index 0a8c03863fb2..149804816ac4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -703,11 +703,9 @@ static void _rtl8723ae_hw_configure(struct ieee80211_hw *hw)
703 struct rtl_priv *rtlpriv = rtl_priv(hw); 703 struct rtl_priv *rtlpriv = rtl_priv(hw);
704 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 704 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
705 u8 reg_bw_opmode; 705 u8 reg_bw_opmode;
706 u32 reg_ratr, reg_prsr; 706 u32 reg_prsr;
707 707
708 reg_bw_opmode = BW_OPMODE_20MHZ; 708 reg_bw_opmode = BW_OPMODE_20MHZ;
709 reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
710 RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
711 reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; 709 reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
712 710
713 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); 711 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8);
@@ -2030,7 +2028,7 @@ bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2030 struct rtl_priv *rtlpriv = rtl_priv(hw); 2028 struct rtl_priv *rtlpriv = rtl_priv(hw);
2031 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 2029 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2032 struct rtl_phy *rtlphy = &(rtlpriv->phy); 2030 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2033 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; 2031 enum rf_pwrstate e_rfpowerstate_toset;
2034 u8 u1tmp; 2032 u8 u1tmp;
2035 bool actuallyset = false; 2033 bool actuallyset = false;
2036 2034
@@ -2049,8 +2047,6 @@ bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2049 spin_unlock(&rtlpriv->locks.rf_ps_lock); 2047 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2050 } 2048 }
2051 2049
2052 cur_rfstate = ppsc->rfpwr_state;
2053
2054 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2, 2050 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2055 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2)&~(BIT(1))); 2051 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2)&~(BIT(1)));
2056 2052
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
index 3d8536bb0d2b..eafbb18dd48e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
@@ -614,17 +614,11 @@ bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
614{ 614{
615 struct rtl_priv *rtlpriv = rtl_priv(hw); 615 struct rtl_priv *rtlpriv = rtl_priv(hw);
616 int i; 616 int i;
617 bool rtstatus = true;
618 u32 *radioa_array_table; 617 u32 *radioa_array_table;
619 u32 *radiob_array_table; 618 u16 radioa_arraylen;
620 u16 radioa_arraylen, radiob_arraylen;
621 619
622 radioa_arraylen = Rtl8723ERADIOA_1TARRAYLENGTH; 620 radioa_arraylen = Rtl8723ERADIOA_1TARRAYLENGTH;
623 radioa_array_table = RTL8723E_RADIOA_1TARRAY; 621 radioa_array_table = RTL8723E_RADIOA_1TARRAY;
624 radiob_arraylen = RTL8723E_RADIOB_1TARRAYLENGTH;
625 radiob_array_table = RTL8723E_RADIOB_1TARRAY;
626
627 rtstatus = true;
628 622
629 switch (rfpath) { 623 switch (rfpath) {
630 case RF90_PATH_A: 624 case RF90_PATH_A:
@@ -1531,11 +1525,8 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
1531 0x522, 0x550, 0x551, 0x040 1525 0x522, 0x550, 0x551, 0x040
1532 }; 1526 };
1533 const u32 retrycount = 2; 1527 const u32 retrycount = 2;
1534 u32 bbvalue;
1535 1528
1536 if (t == 0) { 1529 if (t == 0) {
1537 bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD);
1538
1539 phy_save_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); 1530 phy_save_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16);
1540 phy_save_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); 1531 phy_save_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup);
1541 } 1532 }
@@ -1712,8 +1703,7 @@ void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1712 long result[4][8]; 1703 long result[4][8];
1713 u8 i, final_candidate; 1704 u8 i, final_candidate;
1714 bool patha_ok, pathb_ok; 1705 bool patha_ok, pathb_ok;
1715 long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, 1706 long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_tmp = 0;
1716 reg_ecc, reg_tmp = 0;
1717 bool is12simular, is13simular, is23simular; 1707 bool is12simular, is13simular, is23simular;
1718 bool start_conttx = false, singletone = false; 1708 bool start_conttx = false, singletone = false;
1719 u32 iqk_bb_reg[10] = { 1709 u32 iqk_bb_reg[10] = {
@@ -1780,21 +1770,15 @@ void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1780 reg_e94 = result[i][0]; 1770 reg_e94 = result[i][0];
1781 reg_e9c = result[i][1]; 1771 reg_e9c = result[i][1];
1782 reg_ea4 = result[i][2]; 1772 reg_ea4 = result[i][2];
1783 reg_eac = result[i][3];
1784 reg_eb4 = result[i][4]; 1773 reg_eb4 = result[i][4];
1785 reg_ebc = result[i][5]; 1774 reg_ebc = result[i][5];
1786 reg_ec4 = result[i][6];
1787 reg_ecc = result[i][7];
1788 } 1775 }
1789 if (final_candidate != 0xff) { 1776 if (final_candidate != 0xff) {
1790 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; 1777 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1791 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; 1778 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1792 reg_ea4 = result[final_candidate][2]; 1779 reg_ea4 = result[final_candidate][2];
1793 reg_eac = result[final_candidate][3];
1794 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; 1780 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1795 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; 1781 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1796 reg_ec4 = result[final_candidate][6];
1797 reg_ecc = result[final_candidate][7];
1798 patha_ok = pathb_ok = true; 1782 patha_ok = pathb_ok = true;
1799 } else { 1783 } else {
1800 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; 1784 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
index ce8ad12bce5b..b1fd2b328abf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
@@ -244,7 +244,6 @@ static void _rtl8723ae_translate_rx_signal_stuff(struct ieee80211_hw *hw,
244 struct ieee80211_hdr *hdr; 244 struct ieee80211_hdr *hdr;
245 u8 *tmp_buf; 245 u8 *tmp_buf;
246 u8 *praddr; 246 u8 *praddr;
247 u8 *psaddr;
248 __le16 fc; 247 __le16 fc;
249 u16 type; 248 u16 type;
250 bool packet_matchbssid, packet_toself, packet_beacon = false; 249 bool packet_matchbssid, packet_toself, packet_beacon = false;
@@ -255,7 +254,6 @@ static void _rtl8723ae_translate_rx_signal_stuff(struct ieee80211_hw *hw,
255 fc = hdr->frame_control; 254 fc = hdr->frame_control;
256 type = WLAN_FC_GET_TYPE(fc); 255 type = WLAN_FC_GET_TYPE(fc);
257 praddr = hdr->addr1; 256 praddr = hdr->addr1;
258 psaddr = ieee80211_get_SA(hdr);
259 257
260 packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && 258 packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
261 (!compare_ether_addr(mac->bssid, 259 (!compare_ether_addr(mac->bssid,
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 1535efda3d52..d42bbe21ba6e 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -825,8 +825,6 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
825 u32 ep_num; 825 u32 ep_num;
826 struct urb *_urb = NULL; 826 struct urb *_urb = NULL;
827 struct sk_buff *_skb = NULL; 827 struct sk_buff *_skb = NULL;
828 struct sk_buff_head *skb_list;
829 struct usb_anchor *urb_list;
830 828
831 WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); 829 WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl);
832 if (unlikely(IS_USB_STOP(rtlusb))) { 830 if (unlikely(IS_USB_STOP(rtlusb))) {
@@ -836,7 +834,6 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
836 return; 834 return;
837 } 835 }
838 ep_num = rtlusb->ep_map.ep_mapping[qnum]; 836 ep_num = rtlusb->ep_map.ep_mapping[qnum];
839 skb_list = &rtlusb->tx_skb_queue[ep_num];
840 _skb = skb; 837 _skb = skb;
841 _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); 838 _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num);
842 if (unlikely(!_urb)) { 839 if (unlikely(!_urb)) {
@@ -844,7 +841,6 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
844 "Can't allocate urb. Drop skb!\n"); 841 "Can't allocate urb. Drop skb!\n");
845 return; 842 return;
846 } 843 }
847 urb_list = &rtlusb->tx_pending[ep_num];
848 _rtl_submit_tx_urb(hw, _urb); 844 _rtl_submit_tx_urb(hw, _urb);
849} 845}
850 846
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 21a5f4f4a135..f13258a8d995 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -1702,7 +1702,7 @@ struct rtl_works {
1702 1702
1703struct rtl_debug { 1703struct rtl_debug {
1704 u32 dbgp_type[DBGP_TYPE_MAX]; 1704 u32 dbgp_type[DBGP_TYPE_MAX];
1705 u32 global_debuglevel; 1705 int global_debuglevel;
1706 u64 global_debugcomponents; 1706 u64 global_debugcomponents;
1707 1707
1708 /* add for proc debug */ 1708 /* add for proc debug */
diff --git a/drivers/net/wireless/ti/wl1251/Kconfig b/drivers/net/wireless/ti/wl1251/Kconfig
index 1fb65849414f..8fec4ed36ac2 100644
--- a/drivers/net/wireless/ti/wl1251/Kconfig
+++ b/drivers/net/wireless/ti/wl1251/Kconfig
@@ -1,6 +1,6 @@
1menuconfig WL1251 1menuconfig WL1251
2 tristate "TI wl1251 driver support" 2 tristate "TI wl1251 driver support"
3 depends on MAC80211 && EXPERIMENTAL && GENERIC_HARDIRQS 3 depends on MAC80211 && GENERIC_HARDIRQS
4 select FW_LOADER 4 select FW_LOADER
5 select CRC7 5 select CRC7
6 ---help--- 6 ---help---
diff --git a/drivers/net/wireless/ti/wl12xx/Makefile b/drivers/net/wireless/ti/wl12xx/Makefile
index da509aa7d009..e6a24056b3c8 100644
--- a/drivers/net/wireless/ti/wl12xx/Makefile
+++ b/drivers/net/wireless/ti/wl12xx/Makefile
@@ -1,3 +1,3 @@
1wl12xx-objs = main.o cmd.o acx.o debugfs.o 1wl12xx-objs = main.o cmd.o acx.o debugfs.o scan.o event.o
2 2
3obj-$(CONFIG_WL12XX) += wl12xx.o 3obj-$(CONFIG_WL12XX) += wl12xx.o
diff --git a/drivers/net/wireless/ti/wl12xx/cmd.c b/drivers/net/wireless/ti/wl12xx/cmd.c
index 622206241e83..7dc9f965037d 100644
--- a/drivers/net/wireless/ti/wl12xx/cmd.c
+++ b/drivers/net/wireless/ti/wl12xx/cmd.c
@@ -284,3 +284,40 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl)
284 kfree(radio_parms); 284 kfree(radio_parms);
285 return ret; 285 return ret;
286} 286}
287
288int wl12xx_cmd_channel_switch(struct wl1271 *wl,
289 struct wl12xx_vif *wlvif,
290 struct ieee80211_channel_switch *ch_switch)
291{
292 struct wl12xx_cmd_channel_switch *cmd;
293 int ret;
294
295 wl1271_debug(DEBUG_ACX, "cmd channel switch");
296
297 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
298 if (!cmd) {
299 ret = -ENOMEM;
300 goto out;
301 }
302
303 cmd->role_id = wlvif->role_id;
304 cmd->channel = ch_switch->channel->hw_value;
305 cmd->switch_time = ch_switch->count;
306 cmd->stop_tx = ch_switch->block_tx;
307
308 /* FIXME: control from mac80211 in the future */
309 /* Enable TX on the target channel */
310 cmd->post_switch_tx_disable = 0;
311
312 ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
313 if (ret < 0) {
314 wl1271_error("failed to send channel switch command");
315 goto out_free;
316 }
317
318out_free:
319 kfree(cmd);
320
321out:
322 return ret;
323}
diff --git a/drivers/net/wireless/ti/wl12xx/cmd.h b/drivers/net/wireless/ti/wl12xx/cmd.h
index 140a0e8829d5..32cbad54e993 100644
--- a/drivers/net/wireless/ti/wl12xx/cmd.h
+++ b/drivers/net/wireless/ti/wl12xx/cmd.h
@@ -103,10 +103,30 @@ struct wl1271_ext_radio_parms_cmd {
103 u8 padding[3]; 103 u8 padding[3];
104} __packed; 104} __packed;
105 105
106struct wl12xx_cmd_channel_switch {
107 struct wl1271_cmd_header header;
108
109 u8 role_id;
110
111 /* The new serving channel */
112 u8 channel;
113 /* Relative time of the serving channel switch in TBTT units */
114 u8 switch_time;
115 /* Stop the role TX, should expect it after radar detection */
116 u8 stop_tx;
117 /* The target channel tx status 1-stopped 0-open*/
118 u8 post_switch_tx_disable;
119
120 u8 padding[3];
121} __packed;
122
106int wl1271_cmd_general_parms(struct wl1271 *wl); 123int wl1271_cmd_general_parms(struct wl1271 *wl);
107int wl128x_cmd_general_parms(struct wl1271 *wl); 124int wl128x_cmd_general_parms(struct wl1271 *wl);
108int wl1271_cmd_radio_parms(struct wl1271 *wl); 125int wl1271_cmd_radio_parms(struct wl1271 *wl);
109int wl128x_cmd_radio_parms(struct wl1271 *wl); 126int wl128x_cmd_radio_parms(struct wl1271 *wl);
110int wl1271_cmd_ext_radio_parms(struct wl1271 *wl); 127int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
128int wl12xx_cmd_channel_switch(struct wl1271 *wl,
129 struct wl12xx_vif *wlvif,
130 struct ieee80211_channel_switch *ch_switch);
111 131
112#endif /* __WL12XX_CMD_H__ */ 132#endif /* __WL12XX_CMD_H__ */
diff --git a/drivers/net/wireless/ti/wl12xx/event.c b/drivers/net/wireless/ti/wl12xx/event.c
new file mode 100644
index 000000000000..6ac0ed751da8
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/event.c
@@ -0,0 +1,116 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2012 Texas Instruments. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include "event.h"
23#include "scan.h"
24#include "../wlcore/cmd.h"
25#include "../wlcore/debug.h"
26
27int wl12xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
28 bool *timeout)
29{
30 u32 local_event;
31
32 switch (event) {
33 case WLCORE_EVENT_ROLE_STOP_COMPLETE:
34 local_event = ROLE_STOP_COMPLETE_EVENT_ID;
35 break;
36
37 case WLCORE_EVENT_PEER_REMOVE_COMPLETE:
38 local_event = PEER_REMOVE_COMPLETE_EVENT_ID;
39 break;
40
41 default:
42 /* event not implemented */
43 return 0;
44 }
45 return wlcore_cmd_wait_for_event_or_timeout(wl, local_event, timeout);
46}
47
48int wl12xx_process_mailbox_events(struct wl1271 *wl)
49{
50 struct wl12xx_event_mailbox *mbox = wl->mbox;
51 u32 vector;
52
53
54 vector = le32_to_cpu(mbox->events_vector);
55 vector &= ~(le32_to_cpu(mbox->events_mask));
56
57 wl1271_debug(DEBUG_EVENT, "MBOX vector: 0x%x", vector);
58
59 if (vector & SCAN_COMPLETE_EVENT_ID) {
60 wl1271_debug(DEBUG_EVENT, "status: 0x%x",
61 mbox->scheduled_scan_status);
62
63 if (wl->scan_wlvif)
64 wl12xx_scan_completed(wl, wl->scan_wlvif);
65 }
66
67 if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
68 wl1271_debug(DEBUG_EVENT,
69 "PERIODIC_SCAN_REPORT_EVENT (status 0x%0x)",
70 mbox->scheduled_scan_status);
71
72 wlcore_scan_sched_scan_results(wl);
73 }
74
75 if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID)
76 wlcore_event_sched_scan_completed(wl,
77 mbox->scheduled_scan_status);
78 if (vector & SOFT_GEMINI_SENSE_EVENT_ID)
79 wlcore_event_soft_gemini_sense(wl,
80 mbox->soft_gemini_sense_info);
81
82 if (vector & BSS_LOSE_EVENT_ID)
83 wlcore_event_beacon_loss(wl, 0xff);
84
85 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID)
86 wlcore_event_rssi_trigger(wl, mbox->rssi_snr_trigger_metric);
87
88 if (vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID)
89 wlcore_event_ba_rx_constraint(wl,
90 BIT(mbox->role_id),
91 mbox->rx_ba_allowed);
92
93 if (vector & CHANNEL_SWITCH_COMPLETE_EVENT_ID)
94 wlcore_event_channel_switch(wl, 0xff,
95 mbox->channel_switch_status);
96
97 if (vector & DUMMY_PACKET_EVENT_ID)
98 wlcore_event_dummy_packet(wl);
99
100 /*
101 * "TX retries exceeded" has a different meaning according to mode.
102 * In AP mode the offending station is disconnected.
103 */
104 if (vector & MAX_TX_RETRY_EVENT_ID)
105 wlcore_event_max_tx_failure(wl,
106 le16_to_cpu(mbox->sta_tx_retry_exceeded));
107
108 if (vector & INACTIVE_STA_EVENT_ID)
109 wlcore_event_inactive_sta(wl,
110 le16_to_cpu(mbox->sta_aging_status));
111
112 if (vector & REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID)
113 wlcore_event_roc_complete(wl);
114
115 return 0;
116}
diff --git a/drivers/net/wireless/ti/wl12xx/event.h b/drivers/net/wireless/ti/wl12xx/event.h
new file mode 100644
index 000000000000..a5cc3fcd9eea
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/event.h
@@ -0,0 +1,111 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2012 Texas Instruments. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __WL12XX_EVENT_H__
23#define __WL12XX_EVENT_H__
24
25#include "../wlcore/wlcore.h"
26
27enum {
28 MEASUREMENT_START_EVENT_ID = BIT(8),
29 MEASUREMENT_COMPLETE_EVENT_ID = BIT(9),
30 SCAN_COMPLETE_EVENT_ID = BIT(10),
31 WFD_DISCOVERY_COMPLETE_EVENT_ID = BIT(11),
32 AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(12),
33 RESERVED1 = BIT(13),
34 PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(14),
35 ROLE_STOP_COMPLETE_EVENT_ID = BIT(15),
36 RADAR_DETECTED_EVENT_ID = BIT(16),
37 CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17),
38 BSS_LOSE_EVENT_ID = BIT(18),
39 REGAINED_BSS_EVENT_ID = BIT(19),
40 MAX_TX_RETRY_EVENT_ID = BIT(20),
41 DUMMY_PACKET_EVENT_ID = BIT(21),
42 SOFT_GEMINI_SENSE_EVENT_ID = BIT(22),
43 CHANGE_AUTO_MODE_TIMEOUT_EVENT_ID = BIT(23),
44 SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24),
45 PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25),
46 INACTIVE_STA_EVENT_ID = BIT(26),
47 PEER_REMOVE_COMPLETE_EVENT_ID = BIT(27),
48 PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(28),
49 PERIODIC_SCAN_REPORT_EVENT_ID = BIT(29),
50 BA_SESSION_RX_CONSTRAINT_EVENT_ID = BIT(30),
51 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID = BIT(31),
52};
53
54struct wl12xx_event_mailbox {
55 __le32 events_vector;
56 __le32 events_mask;
57 __le32 reserved_1;
58 __le32 reserved_2;
59
60 u8 number_of_scan_results;
61 u8 scan_tag;
62 u8 completed_scan_status;
63 u8 reserved_3;
64
65 u8 soft_gemini_sense_info;
66 u8 soft_gemini_protective_info;
67 s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
68 u8 change_auto_mode_timeout;
69 u8 scheduled_scan_status;
70 u8 reserved4;
71 /* tuned channel (roc) */
72 u8 roc_channel;
73
74 __le16 hlid_removed_bitmap;
75
76 /* bitmap of aged stations (by HLID) */
77 __le16 sta_aging_status;
78
79 /* bitmap of stations (by HLID) which exceeded max tx retries */
80 __le16 sta_tx_retry_exceeded;
81
82 /* discovery completed results */
83 u8 discovery_tag;
84 u8 number_of_preq_results;
85 u8 number_of_prsp_results;
86 u8 reserved_5;
87
88 /* rx ba constraint */
89 u8 role_id; /* 0xFF means any role. */
90 u8 rx_ba_allowed;
91 u8 reserved_6[2];
92
93 /* Channel switch results */
94
95 u8 channel_switch_role_id;
96 u8 channel_switch_status;
97 u8 reserved_7[2];
98
99 u8 ps_poll_delivery_failure_role_ids;
100 u8 stopped_role_ids;
101 u8 started_role_ids;
102
103 u8 reserved_8[9];
104} __packed;
105
106int wl12xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
107 bool *timeout);
108int wl12xx_process_mailbox_events(struct wl1271 *wl);
109
110#endif
111
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index e5f5f8f39144..3254bfc81a2a 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -38,6 +38,8 @@
38#include "reg.h" 38#include "reg.h"
39#include "cmd.h" 39#include "cmd.h"
40#include "acx.h" 40#include "acx.h"
41#include "scan.h"
42#include "event.h"
41#include "debugfs.h" 43#include "debugfs.h"
42 44
43static char *fref_param; 45static char *fref_param;
@@ -208,6 +210,8 @@ static struct wlcore_conf wl12xx_conf = {
208 .tmpl_short_retry_limit = 10, 210 .tmpl_short_retry_limit = 10,
209 .tmpl_long_retry_limit = 10, 211 .tmpl_long_retry_limit = 10,
210 .tx_watchdog_timeout = 5000, 212 .tx_watchdog_timeout = 5000,
213 .slow_link_thold = 3,
214 .fast_link_thold = 10,
211 }, 215 },
212 .conn = { 216 .conn = {
213 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, 217 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
@@ -265,8 +269,10 @@ static struct wlcore_conf wl12xx_conf = {
265 .scan = { 269 .scan = {
266 .min_dwell_time_active = 7500, 270 .min_dwell_time_active = 7500,
267 .max_dwell_time_active = 30000, 271 .max_dwell_time_active = 30000,
268 .min_dwell_time_passive = 100000, 272 .min_dwell_time_active_long = 25000,
269 .max_dwell_time_passive = 100000, 273 .max_dwell_time_active_long = 50000,
274 .dwell_time_passive = 100000,
275 .dwell_time_dfs = 150000,
270 .num_probe_reqs = 2, 276 .num_probe_reqs = 2,
271 .split_scan_timeout = 50000, 277 .split_scan_timeout = 50000,
272 }, 278 },
@@ -368,6 +374,10 @@ static struct wlcore_conf wl12xx_conf = {
368 .increase_time = 1, 374 .increase_time = 1,
369 .window_size = 16, 375 .window_size = 16,
370 }, 376 },
377 .recovery = {
378 .bug_on_recovery = 0,
379 .no_recovery = 0,
380 },
371}; 381};
372 382
373static struct wl12xx_priv_conf wl12xx_default_priv_conf = { 383static struct wl12xx_priv_conf wl12xx_default_priv_conf = {
@@ -601,9 +611,9 @@ static int wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
601{ 611{
602 int ret; 612 int ret;
603 613
604 if (wl->chip.id != CHIP_ID_1283_PG20) { 614 if (wl->chip.id != CHIP_ID_128X_PG20) {
605 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; 615 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
606 struct wl127x_rx_mem_pool_addr rx_mem_addr; 616 struct wl12xx_priv *priv = wl->priv;
607 617
608 /* 618 /*
609 * Choose the block we want to read 619 * Choose the block we want to read
@@ -612,13 +622,13 @@ static int wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
612 */ 622 */
613 u32 mem_block = rx_desc & RX_MEM_BLOCK_MASK; 623 u32 mem_block = rx_desc & RX_MEM_BLOCK_MASK;
614 624
615 rx_mem_addr.addr = (mem_block << 8) + 625 priv->rx_mem_addr->addr = (mem_block << 8) +
616 le32_to_cpu(wl_mem_map->packet_memory_pool_start); 626 le32_to_cpu(wl_mem_map->packet_memory_pool_start);
617 627
618 rx_mem_addr.addr_extra = rx_mem_addr.addr + 4; 628 priv->rx_mem_addr->addr_extra = priv->rx_mem_addr->addr + 4;
619 629
620 ret = wlcore_write(wl, WL1271_SLV_REG_DATA, &rx_mem_addr, 630 ret = wlcore_write(wl, WL1271_SLV_REG_DATA, priv->rx_mem_addr,
621 sizeof(rx_mem_addr), false); 631 sizeof(*priv->rx_mem_addr), false);
622 if (ret < 0) 632 if (ret < 0)
623 return ret; 633 return ret;
624 } 634 }
@@ -631,13 +641,15 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
631 int ret = 0; 641 int ret = 0;
632 642
633 switch (wl->chip.id) { 643 switch (wl->chip.id) {
634 case CHIP_ID_1271_PG10: 644 case CHIP_ID_127X_PG10:
635 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", 645 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
636 wl->chip.id); 646 wl->chip.id);
637 647
638 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | 648 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS |
639 WLCORE_QUIRK_DUAL_PROBE_TMPL | 649 WLCORE_QUIRK_DUAL_PROBE_TMPL |
640 WLCORE_QUIRK_TKIP_HEADER_SPACE; 650 WLCORE_QUIRK_TKIP_HEADER_SPACE |
651 WLCORE_QUIRK_START_STA_FAILS |
652 WLCORE_QUIRK_AP_ZERO_SESSION_ID;
641 wl->sr_fw_name = WL127X_FW_NAME_SINGLE; 653 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
642 wl->mr_fw_name = WL127X_FW_NAME_MULTI; 654 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
643 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x, 655 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
@@ -646,18 +658,22 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
646 /* read data preparation is only needed by wl127x */ 658 /* read data preparation is only needed by wl127x */
647 wl->ops->prepare_read = wl127x_prepare_read; 659 wl->ops->prepare_read = wl127x_prepare_read;
648 660
649 wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, WL127X_IFTYPE_VER, 661 wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER,
650 WL127X_MAJOR_VER, WL127X_SUBTYPE_VER, 662 WL127X_IFTYPE_SR_VER, WL127X_MAJOR_SR_VER,
651 WL127X_MINOR_VER); 663 WL127X_SUBTYPE_SR_VER, WL127X_MINOR_SR_VER,
664 WL127X_IFTYPE_MR_VER, WL127X_MAJOR_MR_VER,
665 WL127X_SUBTYPE_MR_VER, WL127X_MINOR_MR_VER);
652 break; 666 break;
653 667
654 case CHIP_ID_1271_PG20: 668 case CHIP_ID_127X_PG20:
655 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", 669 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
656 wl->chip.id); 670 wl->chip.id);
657 671
658 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | 672 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS |
659 WLCORE_QUIRK_DUAL_PROBE_TMPL | 673 WLCORE_QUIRK_DUAL_PROBE_TMPL |
660 WLCORE_QUIRK_TKIP_HEADER_SPACE; 674 WLCORE_QUIRK_TKIP_HEADER_SPACE |
675 WLCORE_QUIRK_START_STA_FAILS |
676 WLCORE_QUIRK_AP_ZERO_SESSION_ID;
661 wl->plt_fw_name = WL127X_PLT_FW_NAME; 677 wl->plt_fw_name = WL127X_PLT_FW_NAME;
662 wl->sr_fw_name = WL127X_FW_NAME_SINGLE; 678 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
663 wl->mr_fw_name = WL127X_FW_NAME_MULTI; 679 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
@@ -667,12 +683,14 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
667 /* read data preparation is only needed by wl127x */ 683 /* read data preparation is only needed by wl127x */
668 wl->ops->prepare_read = wl127x_prepare_read; 684 wl->ops->prepare_read = wl127x_prepare_read;
669 685
670 wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, WL127X_IFTYPE_VER, 686 wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER,
671 WL127X_MAJOR_VER, WL127X_SUBTYPE_VER, 687 WL127X_IFTYPE_SR_VER, WL127X_MAJOR_SR_VER,
672 WL127X_MINOR_VER); 688 WL127X_SUBTYPE_SR_VER, WL127X_MINOR_SR_VER,
689 WL127X_IFTYPE_MR_VER, WL127X_MAJOR_MR_VER,
690 WL127X_SUBTYPE_MR_VER, WL127X_MINOR_MR_VER);
673 break; 691 break;
674 692
675 case CHIP_ID_1283_PG20: 693 case CHIP_ID_128X_PG20:
676 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)", 694 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
677 wl->chip.id); 695 wl->chip.id);
678 wl->plt_fw_name = WL128X_PLT_FW_NAME; 696 wl->plt_fw_name = WL128X_PLT_FW_NAME;
@@ -682,19 +700,29 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
682 /* wl128x requires TX blocksize alignment */ 700 /* wl128x requires TX blocksize alignment */
683 wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | 701 wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
684 WLCORE_QUIRK_DUAL_PROBE_TMPL | 702 WLCORE_QUIRK_DUAL_PROBE_TMPL |
685 WLCORE_QUIRK_TKIP_HEADER_SPACE; 703 WLCORE_QUIRK_TKIP_HEADER_SPACE |
686 704 WLCORE_QUIRK_START_STA_FAILS |
687 wlcore_set_min_fw_ver(wl, WL128X_CHIP_VER, WL128X_IFTYPE_VER, 705 WLCORE_QUIRK_AP_ZERO_SESSION_ID;
688 WL128X_MAJOR_VER, WL128X_SUBTYPE_VER, 706
689 WL128X_MINOR_VER); 707 wlcore_set_min_fw_ver(wl, WL128X_CHIP_VER,
708 WL128X_IFTYPE_SR_VER, WL128X_MAJOR_SR_VER,
709 WL128X_SUBTYPE_SR_VER, WL128X_MINOR_SR_VER,
710 WL128X_IFTYPE_MR_VER, WL128X_MAJOR_MR_VER,
711 WL128X_SUBTYPE_MR_VER, WL128X_MINOR_MR_VER);
690 break; 712 break;
691 case CHIP_ID_1283_PG10: 713 case CHIP_ID_128X_PG10:
692 default: 714 default:
693 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); 715 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
694 ret = -ENODEV; 716 ret = -ENODEV;
695 goto out; 717 goto out;
696 } 718 }
697 719
720 /* common settings */
721 wl->scan_templ_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4_LEGACY;
722 wl->scan_templ_id_5 = CMD_TEMPL_APP_PROBE_REQ_5_LEGACY;
723 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
724 wl->sched_scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
725 wl->max_channels_5 = WL12XX_MAX_CHANNELS_5GHZ;
698out: 726out:
699 return ret; 727 return ret;
700} 728}
@@ -1067,7 +1095,7 @@ static int wl12xx_pre_boot(struct wl1271 *wl)
1067 u32 clk; 1095 u32 clk;
1068 int selected_clock = -1; 1096 int selected_clock = -1;
1069 1097
1070 if (wl->chip.id == CHIP_ID_1283_PG20) { 1098 if (wl->chip.id == CHIP_ID_128X_PG20) {
1071 ret = wl128x_boot_clk(wl, &selected_clock); 1099 ret = wl128x_boot_clk(wl, &selected_clock);
1072 if (ret < 0) 1100 if (ret < 0)
1073 goto out; 1101 goto out;
@@ -1098,7 +1126,7 @@ static int wl12xx_pre_boot(struct wl1271 *wl)
1098 1126
1099 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); 1127 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
1100 1128
1101 if (wl->chip.id == CHIP_ID_1283_PG20) 1129 if (wl->chip.id == CHIP_ID_128X_PG20)
1102 clk |= ((selected_clock & 0x3) << 1) << 4; 1130 clk |= ((selected_clock & 0x3) << 1) << 4;
1103 else 1131 else
1104 clk |= (priv->ref_clock << 1) << 4; 1132 clk |= (priv->ref_clock << 1) << 4;
@@ -1152,7 +1180,7 @@ static int wl12xx_pre_upload(struct wl1271 *wl)
1152 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly 1180 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
1153 * to upload_fw) */ 1181 * to upload_fw) */
1154 1182
1155 if (wl->chip.id == CHIP_ID_1283_PG20) { 1183 if (wl->chip.id == CHIP_ID_128X_PG20) {
1156 ret = wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA); 1184 ret = wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
1157 if (ret < 0) 1185 if (ret < 0)
1158 goto out; 1186 goto out;
@@ -1219,6 +1247,23 @@ static int wl12xx_boot(struct wl1271 *wl)
1219 if (ret < 0) 1247 if (ret < 0)
1220 goto out; 1248 goto out;
1221 1249
1250 wl->event_mask = BSS_LOSE_EVENT_ID |
1251 REGAINED_BSS_EVENT_ID |
1252 SCAN_COMPLETE_EVENT_ID |
1253 ROLE_STOP_COMPLETE_EVENT_ID |
1254 RSSI_SNR_TRIGGER_0_EVENT_ID |
1255 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
1256 SOFT_GEMINI_SENSE_EVENT_ID |
1257 PERIODIC_SCAN_REPORT_EVENT_ID |
1258 PERIODIC_SCAN_COMPLETE_EVENT_ID |
1259 DUMMY_PACKET_EVENT_ID |
1260 PEER_REMOVE_COMPLETE_EVENT_ID |
1261 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
1262 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
1263 INACTIVE_STA_EVENT_ID |
1264 MAX_TX_RETRY_EVENT_ID |
1265 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
1266
1222 ret = wlcore_boot_run_firmware(wl); 1267 ret = wlcore_boot_run_firmware(wl);
1223 if (ret < 0) 1268 if (ret < 0)
1224 goto out; 1269 goto out;
@@ -1261,7 +1306,7 @@ static void
1261wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, 1306wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1262 u32 blks, u32 spare_blks) 1307 u32 blks, u32 spare_blks)
1263{ 1308{
1264 if (wl->chip.id == CHIP_ID_1283_PG20) { 1309 if (wl->chip.id == CHIP_ID_128X_PG20) {
1265 desc->wl128x_mem.total_mem_blocks = blks; 1310 desc->wl128x_mem.total_mem_blocks = blks;
1266 } else { 1311 } else {
1267 desc->wl127x_mem.extra_blocks = spare_blks; 1312 desc->wl127x_mem.extra_blocks = spare_blks;
@@ -1275,7 +1320,7 @@ wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1275{ 1320{
1276 u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len); 1321 u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len);
1277 1322
1278 if (wl->chip.id == CHIP_ID_1283_PG20) { 1323 if (wl->chip.id == CHIP_ID_128X_PG20) {
1279 desc->wl128x_mem.extra_bytes = aligned_len - skb->len; 1324 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
1280 desc->length = cpu_to_le16(aligned_len >> 2); 1325 desc->length = cpu_to_le16(aligned_len >> 2);
1281 1326
@@ -1339,7 +1384,7 @@ static int wl12xx_hw_init(struct wl1271 *wl)
1339{ 1384{
1340 int ret; 1385 int ret;
1341 1386
1342 if (wl->chip.id == CHIP_ID_1283_PG20) { 1387 if (wl->chip.id == CHIP_ID_128X_PG20) {
1343 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE; 1388 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
1344 1389
1345 ret = wl128x_cmd_general_parms(wl); 1390 ret = wl128x_cmd_general_parms(wl);
@@ -1394,22 +1439,6 @@ static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1394 return wlvif->rate_set; 1439 return wlvif->rate_set;
1395} 1440}
1396 1441
1397static int wl12xx_identify_fw(struct wl1271 *wl)
1398{
1399 unsigned int *fw_ver = wl->chip.fw_ver;
1400
1401 /* Only new station firmwares support routing fw logs to the host */
1402 if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
1403 (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN))
1404 wl->quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
1405
1406 /* This feature is not yet supported for AP mode */
1407 if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP)
1408 wl->quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
1409
1410 return 0;
1411}
1412
1413static void wl12xx_conf_init(struct wl1271 *wl) 1442static void wl12xx_conf_init(struct wl1271 *wl)
1414{ 1443{
1415 struct wl12xx_priv *priv = wl->priv; 1444 struct wl12xx_priv *priv = wl->priv;
@@ -1426,7 +1455,7 @@ static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
1426 bool supported = false; 1455 bool supported = false;
1427 u8 major, minor; 1456 u8 major, minor;
1428 1457
1429 if (wl->chip.id == CHIP_ID_1283_PG20) { 1458 if (wl->chip.id == CHIP_ID_128X_PG20) {
1430 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver); 1459 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
1431 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver); 1460 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
1432 1461
@@ -1482,7 +1511,7 @@ static int wl12xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
1482 u16 die_info; 1511 u16 die_info;
1483 int ret; 1512 int ret;
1484 1513
1485 if (wl->chip.id == CHIP_ID_1283_PG20) 1514 if (wl->chip.id == CHIP_ID_128X_PG20)
1486 ret = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1, 1515 ret = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1,
1487 &die_info); 1516 &die_info);
1488 else 1517 else
@@ -1589,16 +1618,46 @@ static int wl12xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1589 return wlcore_set_key(wl, cmd, vif, sta, key_conf); 1618 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1590} 1619}
1591 1620
1621static int wl12xx_set_peer_cap(struct wl1271 *wl,
1622 struct ieee80211_sta_ht_cap *ht_cap,
1623 bool allow_ht_operation,
1624 u32 rate_set, u8 hlid)
1625{
1626 return wl1271_acx_set_ht_capabilities(wl, ht_cap, allow_ht_operation,
1627 hlid);
1628}
1629
1630static bool wl12xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1631 struct wl1271_link *lnk)
1632{
1633 u8 thold;
1634
1635 if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map))
1636 thold = wl->conf.tx.fast_link_thold;
1637 else
1638 thold = wl->conf.tx.slow_link_thold;
1639
1640 return lnk->allocated_pkts < thold;
1641}
1642
1643static bool wl12xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1644 struct wl1271_link *lnk)
1645{
1646 /* any link is good for low priority */
1647 return true;
1648}
1649
1592static int wl12xx_setup(struct wl1271 *wl); 1650static int wl12xx_setup(struct wl1271 *wl);
1593 1651
1594static struct wlcore_ops wl12xx_ops = { 1652static struct wlcore_ops wl12xx_ops = {
1595 .setup = wl12xx_setup, 1653 .setup = wl12xx_setup,
1596 .identify_chip = wl12xx_identify_chip, 1654 .identify_chip = wl12xx_identify_chip,
1597 .identify_fw = wl12xx_identify_fw,
1598 .boot = wl12xx_boot, 1655 .boot = wl12xx_boot,
1599 .plt_init = wl12xx_plt_init, 1656 .plt_init = wl12xx_plt_init,
1600 .trigger_cmd = wl12xx_trigger_cmd, 1657 .trigger_cmd = wl12xx_trigger_cmd,
1601 .ack_event = wl12xx_ack_event, 1658 .ack_event = wl12xx_ack_event,
1659 .wait_for_event = wl12xx_wait_for_event,
1660 .process_mailbox_events = wl12xx_process_mailbox_events,
1602 .calc_tx_blocks = wl12xx_calc_tx_blocks, 1661 .calc_tx_blocks = wl12xx_calc_tx_blocks,
1603 .set_tx_desc_blocks = wl12xx_set_tx_desc_blocks, 1662 .set_tx_desc_blocks = wl12xx_set_tx_desc_blocks,
1604 .set_tx_desc_data_len = wl12xx_set_tx_desc_data_len, 1663 .set_tx_desc_data_len = wl12xx_set_tx_desc_data_len,
@@ -1615,9 +1674,17 @@ static struct wlcore_ops wl12xx_ops = {
1615 .set_rx_csum = NULL, 1674 .set_rx_csum = NULL,
1616 .ap_get_mimo_wide_rate_mask = NULL, 1675 .ap_get_mimo_wide_rate_mask = NULL,
1617 .debugfs_init = wl12xx_debugfs_add_files, 1676 .debugfs_init = wl12xx_debugfs_add_files,
1677 .scan_start = wl12xx_scan_start,
1678 .scan_stop = wl12xx_scan_stop,
1679 .sched_scan_start = wl12xx_sched_scan_start,
1680 .sched_scan_stop = wl12xx_scan_sched_scan_stop,
1618 .get_spare_blocks = wl12xx_get_spare_blocks, 1681 .get_spare_blocks = wl12xx_get_spare_blocks,
1619 .set_key = wl12xx_set_key, 1682 .set_key = wl12xx_set_key,
1683 .channel_switch = wl12xx_cmd_channel_switch,
1620 .pre_pkt_send = NULL, 1684 .pre_pkt_send = NULL,
1685 .set_peer_cap = wl12xx_set_peer_cap,
1686 .lnk_high_prio = wl12xx_lnk_high_prio,
1687 .lnk_low_prio = wl12xx_lnk_low_prio,
1621}; 1688};
1622 1689
1623static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { 1690static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
@@ -1641,6 +1708,7 @@ static int wl12xx_setup(struct wl1271 *wl)
1641 wl->rtable = wl12xx_rtable; 1708 wl->rtable = wl12xx_rtable;
1642 wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS; 1709 wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
1643 wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS; 1710 wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
1711 wl->num_channels = 1;
1644 wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES; 1712 wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
1645 wl->band_rate_to_idx = wl12xx_band_rate_to_idx; 1713 wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1646 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; 1714 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
@@ -1693,6 +1761,10 @@ static int wl12xx_setup(struct wl1271 *wl)
1693 wl1271_error("Invalid tcxo parameter %s", tcxo_param); 1761 wl1271_error("Invalid tcxo parameter %s", tcxo_param);
1694 } 1762 }
1695 1763
1764 priv->rx_mem_addr = kmalloc(sizeof(*priv->rx_mem_addr), GFP_KERNEL);
1765 if (!priv->rx_mem_addr)
1766 return -ENOMEM;
1767
1696 return 0; 1768 return 0;
1697} 1769}
1698 1770
@@ -1703,7 +1775,8 @@ static int wl12xx_probe(struct platform_device *pdev)
1703 int ret; 1775 int ret;
1704 1776
1705 hw = wlcore_alloc_hw(sizeof(struct wl12xx_priv), 1777 hw = wlcore_alloc_hw(sizeof(struct wl12xx_priv),
1706 WL12XX_AGGR_BUFFER_SIZE); 1778 WL12XX_AGGR_BUFFER_SIZE,
1779 sizeof(struct wl12xx_event_mailbox));
1707 if (IS_ERR(hw)) { 1780 if (IS_ERR(hw)) {
1708 wl1271_error("can't allocate hw"); 1781 wl1271_error("can't allocate hw");
1709 ret = PTR_ERR(hw); 1782 ret = PTR_ERR(hw);
@@ -1725,6 +1798,21 @@ out:
1725 return ret; 1798 return ret;
1726} 1799}
1727 1800
1801static int wl12xx_remove(struct platform_device *pdev)
1802{
1803 struct wl1271 *wl = platform_get_drvdata(pdev);
1804 struct wl12xx_priv *priv;
1805
1806 if (!wl)
1807 goto out;
1808 priv = wl->priv;
1809
1810 kfree(priv->rx_mem_addr);
1811
1812out:
1813 return wlcore_remove(pdev);
1814}
1815
1728static const struct platform_device_id wl12xx_id_table[] = { 1816static const struct platform_device_id wl12xx_id_table[] = {
1729 { "wl12xx", 0 }, 1817 { "wl12xx", 0 },
1730 { } /* Terminating Entry */ 1818 { } /* Terminating Entry */
@@ -1733,7 +1821,7 @@ MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
1733 1821
1734static struct platform_driver wl12xx_driver = { 1822static struct platform_driver wl12xx_driver = {
1735 .probe = wl12xx_probe, 1823 .probe = wl12xx_probe,
1736 .remove = wlcore_remove, 1824 .remove = wl12xx_remove,
1737 .id_table = wl12xx_id_table, 1825 .id_table = wl12xx_id_table,
1738 .driver = { 1826 .driver = {
1739 .name = "wl12xx_driver", 1827 .name = "wl12xx_driver",
diff --git a/drivers/net/wireless/ti/wl12xx/scan.c b/drivers/net/wireless/ti/wl12xx/scan.c
new file mode 100644
index 000000000000..affdb3ec6225
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/scan.c
@@ -0,0 +1,501 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2012 Texas Instruments. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/ieee80211.h>
23#include "scan.h"
24#include "../wlcore/debug.h"
25#include "../wlcore/tx.h"
26
27static int wl1271_get_scan_channels(struct wl1271 *wl,
28 struct cfg80211_scan_request *req,
29 struct basic_scan_channel_params *channels,
30 enum ieee80211_band band, bool passive)
31{
32 struct conf_scan_settings *c = &wl->conf.scan;
33 int i, j;
34 u32 flags;
35
36 for (i = 0, j = 0;
37 i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS;
38 i++) {
39 flags = req->channels[i]->flags;
40
41 if (!test_bit(i, wl->scan.scanned_ch) &&
42 !(flags & IEEE80211_CHAN_DISABLED) &&
43 (req->channels[i]->band == band) &&
44 /*
45 * In passive scans, we scan all remaining
46 * channels, even if not marked as such.
47 * In active scans, we only scan channels not
48 * marked as passive.
49 */
50 (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) {
51 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
52 req->channels[i]->band,
53 req->channels[i]->center_freq);
54 wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
55 req->channels[i]->hw_value,
56 req->channels[i]->flags);
57 wl1271_debug(DEBUG_SCAN,
58 "max_antenna_gain %d, max_power %d",
59 req->channels[i]->max_antenna_gain,
60 req->channels[i]->max_power);
61 wl1271_debug(DEBUG_SCAN, "beacon_found %d",
62 req->channels[i]->beacon_found);
63
64 if (!passive) {
65 channels[j].min_duration =
66 cpu_to_le32(c->min_dwell_time_active);
67 channels[j].max_duration =
68 cpu_to_le32(c->max_dwell_time_active);
69 } else {
70 channels[j].min_duration =
71 cpu_to_le32(c->dwell_time_passive);
72 channels[j].max_duration =
73 cpu_to_le32(c->dwell_time_passive);
74 }
75 channels[j].early_termination = 0;
76 channels[j].tx_power_att = req->channels[i]->max_power;
77 channels[j].channel = req->channels[i]->hw_value;
78
79 memset(&channels[j].bssid_lsb, 0xff, 4);
80 memset(&channels[j].bssid_msb, 0xff, 2);
81
82 /* Mark the channels we already used */
83 set_bit(i, wl->scan.scanned_ch);
84
85 j++;
86 }
87 }
88
89 return j;
90}
91
92#define WL1271_NOTHING_TO_SCAN 1
93
94static int wl1271_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
95 enum ieee80211_band band,
96 bool passive, u32 basic_rate)
97{
98 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
99 struct wl1271_cmd_scan *cmd;
100 struct wl1271_cmd_trigger_scan_to *trigger;
101 int ret;
102 u16 scan_options = 0;
103
104 /* skip active scans if we don't have SSIDs */
105 if (!passive && wl->scan.req->n_ssids == 0)
106 return WL1271_NOTHING_TO_SCAN;
107
108 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
109 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
110 if (!cmd || !trigger) {
111 ret = -ENOMEM;
112 goto out;
113 }
114
115 if (wl->conf.scan.split_scan_timeout)
116 scan_options |= WL1271_SCAN_OPT_SPLIT_SCAN;
117
118 if (passive)
119 scan_options |= WL1271_SCAN_OPT_PASSIVE;
120
121 cmd->params.role_id = wlvif->role_id;
122
123 if (WARN_ON(cmd->params.role_id == WL12XX_INVALID_ROLE_ID)) {
124 ret = -EINVAL;
125 goto out;
126 }
127
128 cmd->params.scan_options = cpu_to_le16(scan_options);
129
130 cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req,
131 cmd->channels,
132 band, passive);
133 if (cmd->params.n_ch == 0) {
134 ret = WL1271_NOTHING_TO_SCAN;
135 goto out;
136 }
137
138 cmd->params.tx_rate = cpu_to_le32(basic_rate);
139 cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs;
140 cmd->params.tid_trigger = CONF_TX_AC_ANY_TID;
141 cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
142
143 if (band == IEEE80211_BAND_2GHZ)
144 cmd->params.band = WL1271_SCAN_BAND_2_4_GHZ;
145 else
146 cmd->params.band = WL1271_SCAN_BAND_5_GHZ;
147
148 if (wl->scan.ssid_len && wl->scan.ssid) {
149 cmd->params.ssid_len = wl->scan.ssid_len;
150 memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len);
151 }
152
153 memcpy(cmd->addr, vif->addr, ETH_ALEN);
154
155 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
156 cmd->params.role_id, band,
157 wl->scan.ssid, wl->scan.ssid_len,
158 wl->scan.req->ie,
159 wl->scan.req->ie_len, false);
160 if (ret < 0) {
161 wl1271_error("PROBE request template failed");
162 goto out;
163 }
164
165 trigger->timeout = cpu_to_le32(wl->conf.scan.split_scan_timeout);
166 ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
167 sizeof(*trigger), 0);
168 if (ret < 0) {
169 wl1271_error("trigger scan to failed for hw scan");
170 goto out;
171 }
172
173 wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd));
174
175 ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0);
176 if (ret < 0) {
177 wl1271_error("SCAN failed");
178 goto out;
179 }
180
181out:
182 kfree(cmd);
183 kfree(trigger);
184 return ret;
185}
186
187int wl12xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif)
188{
189 struct wl1271_cmd_header *cmd = NULL;
190 int ret = 0;
191
192 if (WARN_ON(wl->scan.state == WL1271_SCAN_STATE_IDLE))
193 return -EINVAL;
194
195 wl1271_debug(DEBUG_CMD, "cmd scan stop");
196
197 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
198 if (!cmd) {
199 ret = -ENOMEM;
200 goto out;
201 }
202
203 ret = wl1271_cmd_send(wl, CMD_STOP_SCAN, cmd,
204 sizeof(*cmd), 0);
205 if (ret < 0) {
206 wl1271_error("cmd stop_scan failed");
207 goto out;
208 }
209out:
210 kfree(cmd);
211 return ret;
212}
213
214void wl1271_scan_stm(struct wl1271 *wl, struct wl12xx_vif *wlvif)
215{
216 int ret = 0;
217 enum ieee80211_band band;
218 u32 rate, mask;
219
220 switch (wl->scan.state) {
221 case WL1271_SCAN_STATE_IDLE:
222 break;
223
224 case WL1271_SCAN_STATE_2GHZ_ACTIVE:
225 band = IEEE80211_BAND_2GHZ;
226 mask = wlvif->bitrate_masks[band];
227 if (wl->scan.req->no_cck) {
228 mask &= ~CONF_TX_CCK_RATES;
229 if (!mask)
230 mask = CONF_TX_RATE_MASK_BASIC_P2P;
231 }
232 rate = wl1271_tx_min_rate_get(wl, mask);
233 ret = wl1271_scan_send(wl, wlvif, band, false, rate);
234 if (ret == WL1271_NOTHING_TO_SCAN) {
235 wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
236 wl1271_scan_stm(wl, wlvif);
237 }
238
239 break;
240
241 case WL1271_SCAN_STATE_2GHZ_PASSIVE:
242 band = IEEE80211_BAND_2GHZ;
243 mask = wlvif->bitrate_masks[band];
244 if (wl->scan.req->no_cck) {
245 mask &= ~CONF_TX_CCK_RATES;
246 if (!mask)
247 mask = CONF_TX_RATE_MASK_BASIC_P2P;
248 }
249 rate = wl1271_tx_min_rate_get(wl, mask);
250 ret = wl1271_scan_send(wl, wlvif, band, true, rate);
251 if (ret == WL1271_NOTHING_TO_SCAN) {
252 if (wl->enable_11a)
253 wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
254 else
255 wl->scan.state = WL1271_SCAN_STATE_DONE;
256 wl1271_scan_stm(wl, wlvif);
257 }
258
259 break;
260
261 case WL1271_SCAN_STATE_5GHZ_ACTIVE:
262 band = IEEE80211_BAND_5GHZ;
263 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
264 ret = wl1271_scan_send(wl, wlvif, band, false, rate);
265 if (ret == WL1271_NOTHING_TO_SCAN) {
266 wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
267 wl1271_scan_stm(wl, wlvif);
268 }
269
270 break;
271
272 case WL1271_SCAN_STATE_5GHZ_PASSIVE:
273 band = IEEE80211_BAND_5GHZ;
274 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
275 ret = wl1271_scan_send(wl, wlvif, band, true, rate);
276 if (ret == WL1271_NOTHING_TO_SCAN) {
277 wl->scan.state = WL1271_SCAN_STATE_DONE;
278 wl1271_scan_stm(wl, wlvif);
279 }
280
281 break;
282
283 case WL1271_SCAN_STATE_DONE:
284 wl->scan.failed = false;
285 cancel_delayed_work(&wl->scan_complete_work);
286 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
287 msecs_to_jiffies(0));
288 break;
289
290 default:
291 wl1271_error("invalid scan state");
292 break;
293 }
294
295 if (ret < 0) {
296 cancel_delayed_work(&wl->scan_complete_work);
297 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
298 msecs_to_jiffies(0));
299 }
300}
301
302static void wl12xx_adjust_channels(struct wl1271_cmd_sched_scan_config *cmd,
303 struct wlcore_scan_channels *cmd_channels)
304{
305 memcpy(cmd->passive, cmd_channels->passive, sizeof(cmd->passive));
306 memcpy(cmd->active, cmd_channels->active, sizeof(cmd->active));
307 cmd->dfs = cmd_channels->dfs;
308 cmd->n_pactive_ch = cmd_channels->passive_active;
309
310 memcpy(cmd->channels_2, cmd_channels->channels_2,
311 sizeof(cmd->channels_2));
312 memcpy(cmd->channels_5, cmd_channels->channels_5,
313 sizeof(cmd->channels_2));
314 /* channels_4 are not supported, so no need to copy them */
315}
316
317int wl1271_scan_sched_scan_config(struct wl1271 *wl,
318 struct wl12xx_vif *wlvif,
319 struct cfg80211_sched_scan_request *req,
320 struct ieee80211_sched_scan_ies *ies)
321{
322 struct wl1271_cmd_sched_scan_config *cfg = NULL;
323 struct wlcore_scan_channels *cfg_channels = NULL;
324 struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
325 int i, ret;
326 bool force_passive = !req->n_ssids;
327
328 wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config");
329
330 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
331 if (!cfg)
332 return -ENOMEM;
333
334 cfg->role_id = wlvif->role_id;
335 cfg->rssi_threshold = c->rssi_threshold;
336 cfg->snr_threshold = c->snr_threshold;
337 cfg->n_probe_reqs = c->num_probe_reqs;
338 /* cycles set to 0 it means infinite (until manually stopped) */
339 cfg->cycles = 0;
340 /* report APs when at least 1 is found */
341 cfg->report_after = 1;
342 /* don't stop scanning automatically when something is found */
343 cfg->terminate = 0;
344 cfg->tag = WL1271_SCAN_DEFAULT_TAG;
345 /* don't filter on BSS type */
346 cfg->bss_type = SCAN_BSS_TYPE_ANY;
347 /* currently NL80211 supports only a single interval */
348 for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++)
349 cfg->intervals[i] = cpu_to_le32(req->interval);
350
351 cfg->ssid_len = 0;
352 ret = wlcore_scan_sched_scan_ssid_list(wl, wlvif, req);
353 if (ret < 0)
354 goto out;
355
356 cfg->filter_type = ret;
357
358 wl1271_debug(DEBUG_SCAN, "filter_type = %d", cfg->filter_type);
359
360 cfg_channels = kzalloc(sizeof(*cfg_channels), GFP_KERNEL);
361 if (!cfg_channels) {
362 ret = -ENOMEM;
363 goto out;
364 }
365
366 if (!wlcore_set_scan_chan_params(wl, cfg_channels, req->channels,
367 req->n_channels, req->n_ssids,
368 SCAN_TYPE_PERIODIC)) {
369 wl1271_error("scan channel list is empty");
370 ret = -EINVAL;
371 goto out;
372 }
373 wl12xx_adjust_channels(cfg, cfg_channels);
374
375 if (!force_passive && cfg->active[0]) {
376 u8 band = IEEE80211_BAND_2GHZ;
377 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
378 wlvif->role_id, band,
379 req->ssids[0].ssid,
380 req->ssids[0].ssid_len,
381 ies->ie[band],
382 ies->len[band], true);
383 if (ret < 0) {
384 wl1271_error("2.4GHz PROBE request template failed");
385 goto out;
386 }
387 }
388
389 if (!force_passive && cfg->active[1]) {
390 u8 band = IEEE80211_BAND_5GHZ;
391 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
392 wlvif->role_id, band,
393 req->ssids[0].ssid,
394 req->ssids[0].ssid_len,
395 ies->ie[band],
396 ies->len[band], true);
397 if (ret < 0) {
398 wl1271_error("5GHz PROBE request template failed");
399 goto out;
400 }
401 }
402
403 wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg));
404
405 ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg,
406 sizeof(*cfg), 0);
407 if (ret < 0) {
408 wl1271_error("SCAN configuration failed");
409 goto out;
410 }
411out:
412 kfree(cfg_channels);
413 kfree(cfg);
414 return ret;
415}
416
417int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif)
418{
419 struct wl1271_cmd_sched_scan_start *start;
420 int ret = 0;
421
422 wl1271_debug(DEBUG_CMD, "cmd periodic scan start");
423
424 if (wlvif->bss_type != BSS_TYPE_STA_BSS)
425 return -EOPNOTSUPP;
426
427 if ((wl->quirks & WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN) &&
428 test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
429 return -EBUSY;
430
431 start = kzalloc(sizeof(*start), GFP_KERNEL);
432 if (!start)
433 return -ENOMEM;
434
435 start->role_id = wlvif->role_id;
436 start->tag = WL1271_SCAN_DEFAULT_TAG;
437
438 ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start,
439 sizeof(*start), 0);
440 if (ret < 0) {
441 wl1271_error("failed to send scan start command");
442 goto out_free;
443 }
444
445out_free:
446 kfree(start);
447 return ret;
448}
449
450int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
451 struct cfg80211_sched_scan_request *req,
452 struct ieee80211_sched_scan_ies *ies)
453{
454 int ret;
455
456 ret = wl1271_scan_sched_scan_config(wl, wlvif, req, ies);
457 if (ret < 0)
458 return ret;
459
460 return wl1271_scan_sched_scan_start(wl, wlvif);
461}
462
463void wl12xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif)
464{
465 struct wl1271_cmd_sched_scan_stop *stop;
466 int ret = 0;
467
468 wl1271_debug(DEBUG_CMD, "cmd periodic scan stop");
469
470 /* FIXME: what to do if alloc'ing to stop fails? */
471 stop = kzalloc(sizeof(*stop), GFP_KERNEL);
472 if (!stop) {
473 wl1271_error("failed to alloc memory to send sched scan stop");
474 return;
475 }
476
477 stop->role_id = wlvif->role_id;
478 stop->tag = WL1271_SCAN_DEFAULT_TAG;
479
480 ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop,
481 sizeof(*stop), 0);
482 if (ret < 0) {
483 wl1271_error("failed to send sched scan stop command");
484 goto out_free;
485 }
486
487out_free:
488 kfree(stop);
489}
490
491int wl12xx_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
492 struct cfg80211_scan_request *req)
493{
494 wl1271_scan_stm(wl, wlvif);
495 return 0;
496}
497
498void wl12xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif)
499{
500 wl1271_scan_stm(wl, wlvif);
501}
diff --git a/drivers/net/wireless/ti/wl12xx/scan.h b/drivers/net/wireless/ti/wl12xx/scan.h
new file mode 100644
index 000000000000..264af7ac2785
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/scan.h
@@ -0,0 +1,140 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2012 Texas Instruments. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __WL12XX_SCAN_H__
23#define __WL12XX_SCAN_H__
24
25#include "../wlcore/wlcore.h"
26#include "../wlcore/cmd.h"
27#include "../wlcore/scan.h"
28
29#define WL12XX_MAX_CHANNELS_5GHZ 23
30
31struct basic_scan_params {
32 /* Scan option flags (WL1271_SCAN_OPT_*) */
33 __le16 scan_options;
34 u8 role_id;
35 /* Number of scan channels in the list (maximum 30) */
36 u8 n_ch;
37 /* This field indicates the number of probe requests to send
38 per channel for an active scan */
39 u8 n_probe_reqs;
40 u8 tid_trigger;
41 u8 ssid_len;
42 u8 use_ssid_list;
43
44 /* Rate bit field for sending the probes */
45 __le32 tx_rate;
46
47 u8 ssid[IEEE80211_MAX_SSID_LEN];
48 /* Band to scan */
49 u8 band;
50
51 u8 scan_tag;
52 u8 padding2[2];
53} __packed;
54
55struct basic_scan_channel_params {
56 /* Duration in TU to wait for frames on a channel for active scan */
57 __le32 min_duration;
58 __le32 max_duration;
59 __le32 bssid_lsb;
60 __le16 bssid_msb;
61 u8 early_termination;
62 u8 tx_power_att;
63 u8 channel;
64 /* FW internal use only! */
65 u8 dfs_candidate;
66 u8 activity_detected;
67 u8 pad;
68} __packed;
69
70struct wl1271_cmd_scan {
71 struct wl1271_cmd_header header;
72
73 struct basic_scan_params params;
74 struct basic_scan_channel_params channels[WL1271_SCAN_MAX_CHANNELS];
75
76 /* src mac address */
77 u8 addr[ETH_ALEN];
78 u8 padding[2];
79} __packed;
80
81struct wl1271_cmd_sched_scan_config {
82 struct wl1271_cmd_header header;
83
84 __le32 intervals[SCAN_MAX_CYCLE_INTERVALS];
85
86 s8 rssi_threshold; /* for filtering (in dBm) */
87 s8 snr_threshold; /* for filtering (in dB) */
88
89 u8 cycles; /* maximum number of scan cycles */
90 u8 report_after; /* report when this number of results are received */
91 u8 terminate; /* stop scanning after reporting */
92
93 u8 tag;
94 u8 bss_type; /* for filtering */
95 u8 filter_type;
96
97 u8 ssid_len; /* For SCAN_SSID_FILTER_SPECIFIC */
98 u8 ssid[IEEE80211_MAX_SSID_LEN];
99
100 u8 n_probe_reqs; /* Number of probes requests per channel */
101
102 u8 passive[SCAN_MAX_BANDS];
103 u8 active[SCAN_MAX_BANDS];
104
105 u8 dfs;
106
107 u8 n_pactive_ch; /* number of pactive (passive until fw detects energy)
108 channels in BG band */
109 u8 role_id;
110 u8 padding[1];
111 struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ];
112 struct conn_scan_ch_params channels_5[WL12XX_MAX_CHANNELS_5GHZ];
113 struct conn_scan_ch_params channels_4[MAX_CHANNELS_4GHZ];
114} __packed;
115
116struct wl1271_cmd_sched_scan_start {
117 struct wl1271_cmd_header header;
118
119 u8 tag;
120 u8 role_id;
121 u8 padding[2];
122} __packed;
123
124struct wl1271_cmd_sched_scan_stop {
125 struct wl1271_cmd_header header;
126
127 u8 tag;
128 u8 role_id;
129 u8 padding[2];
130} __packed;
131
132int wl12xx_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
133 struct cfg80211_scan_request *req);
134int wl12xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
135void wl12xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif);
136int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
137 struct cfg80211_sched_scan_request *req,
138 struct ieee80211_sched_scan_ies *ies);
139void wl12xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
140#endif
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
index 7182bbf6625d..d4552857480c 100644
--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -24,19 +24,37 @@
24 24
25#include "conf.h" 25#include "conf.h"
26 26
27/* minimum FW required for driver for wl127x */ 27/* WiLink 6/7 chip IDs */
28#define CHIP_ID_127X_PG10 (0x04030101)
29#define CHIP_ID_127X_PG20 (0x04030111)
30#define CHIP_ID_128X_PG10 (0x05030101)
31#define CHIP_ID_128X_PG20 (0x05030111)
32
33/* FW chip version for wl127x */
28#define WL127X_CHIP_VER 6 34#define WL127X_CHIP_VER 6
29#define WL127X_IFTYPE_VER 3 35/* minimum single-role FW version for wl127x */
30#define WL127X_MAJOR_VER 10 36#define WL127X_IFTYPE_SR_VER 3
31#define WL127X_SUBTYPE_VER 2 37#define WL127X_MAJOR_SR_VER 10
32#define WL127X_MINOR_VER 115 38#define WL127X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE
39#define WL127X_MINOR_SR_VER 115
40/* minimum multi-role FW version for wl127x */
41#define WL127X_IFTYPE_MR_VER 5
42#define WL127X_MAJOR_MR_VER 7
43#define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE
44#define WL127X_MINOR_MR_VER 115
33 45
34/* minimum FW required for driver for wl128x */ 46/* FW chip version for wl128x */
35#define WL128X_CHIP_VER 7 47#define WL128X_CHIP_VER 7
36#define WL128X_IFTYPE_VER 3 48/* minimum single-role FW version for wl128x */
37#define WL128X_MAJOR_VER 10 49#define WL128X_IFTYPE_SR_VER 3
38#define WL128X_SUBTYPE_VER 2 50#define WL128X_MAJOR_SR_VER 10
39#define WL128X_MINOR_VER 115 51#define WL128X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE
52#define WL128X_MINOR_SR_VER 115
53/* minimum multi-role FW version for wl128x */
54#define WL128X_IFTYPE_MR_VER 5
55#define WL128X_MAJOR_MR_VER 7
56#define WL128X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE
57#define WL128X_MINOR_MR_VER 42
40 58
41#define WL12XX_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) 59#define WL12XX_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
42 60
@@ -55,6 +73,8 @@ struct wl12xx_priv {
55 73
56 int ref_clock; 74 int ref_clock;
57 int tcxo_clock; 75 int tcxo_clock;
76
77 struct wl127x_rx_mem_pool_addr *rx_mem_addr;
58}; 78};
59 79
60#endif /* __WL12XX_PRIV_H__ */ 80#endif /* __WL12XX_PRIV_H__ */
diff --git a/drivers/net/wireless/ti/wl18xx/Makefile b/drivers/net/wireless/ti/wl18xx/Makefile
index 67c098734c7f..ae2b81735785 100644
--- a/drivers/net/wireless/ti/wl18xx/Makefile
+++ b/drivers/net/wireless/ti/wl18xx/Makefile
@@ -1,3 +1,3 @@
1wl18xx-objs = main.o acx.o tx.o io.o debugfs.o 1wl18xx-objs = main.o acx.o tx.o io.o debugfs.o scan.o cmd.o event.o
2 2
3obj-$(CONFIG_WL18XX) += wl18xx.o 3obj-$(CONFIG_WL18XX) += wl18xx.o
diff --git a/drivers/net/wireless/ti/wl18xx/acx.c b/drivers/net/wireless/ti/wl18xx/acx.c
index 72840e23bf59..a169bb5a5dbf 100644
--- a/drivers/net/wireless/ti/wl18xx/acx.c
+++ b/drivers/net/wireless/ti/wl18xx/acx.c
@@ -75,7 +75,7 @@ int wl18xx_acx_set_checksum_state(struct wl1271 *wl)
75 75
76 acx->checksum_state = CHECKSUM_OFFLOAD_ENABLED; 76 acx->checksum_state = CHECKSUM_OFFLOAD_ENABLED;
77 77
78 ret = wl1271_cmd_configure(wl, ACX_CHECKSUM_CONFIG, acx, sizeof(*acx)); 78 ret = wl1271_cmd_configure(wl, ACX_CSUM_CONFIG, acx, sizeof(*acx));
79 if (ret < 0) { 79 if (ret < 0) {
80 wl1271_warning("failed to set Tx checksum state: %d", ret); 80 wl1271_warning("failed to set Tx checksum state: %d", ret);
81 goto out; 81 goto out;
@@ -109,3 +109,88 @@ out:
109 kfree(acx); 109 kfree(acx);
110 return ret; 110 return ret;
111} 111}
112
113int wl18xx_acx_peer_ht_operation_mode(struct wl1271 *wl, u8 hlid, bool wide)
114{
115 struct wlcore_peer_ht_operation_mode *acx;
116 int ret;
117
118 wl1271_debug(DEBUG_ACX, "acx peer ht operation mode hlid %d bw %d",
119 hlid, wide);
120
121 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
122 if (!acx) {
123 ret = -ENOMEM;
124 goto out;
125 }
126
127 acx->hlid = hlid;
128 acx->bandwidth = wide ? WLCORE_BANDWIDTH_40MHZ : WLCORE_BANDWIDTH_20MHZ;
129
130 ret = wl1271_cmd_configure(wl, ACX_PEER_HT_OPERATION_MODE_CFG, acx,
131 sizeof(*acx));
132
133 if (ret < 0) {
134 wl1271_warning("acx peer ht operation mode failed: %d", ret);
135 goto out;
136 }
137
138out:
139 kfree(acx);
140 return ret;
141
142}
143
144/*
145 * this command is basically the same as wl1271_acx_ht_capabilities,
146 * with the addition of supported rates. they should be unified in
147 * the next fw api change
148 */
149int wl18xx_acx_set_peer_cap(struct wl1271 *wl,
150 struct ieee80211_sta_ht_cap *ht_cap,
151 bool allow_ht_operation,
152 u32 rate_set, u8 hlid)
153{
154 struct wlcore_acx_peer_cap *acx;
155 int ret = 0;
156 u32 ht_capabilites = 0;
157
158 wl1271_debug(DEBUG_ACX,
159 "acx set cap ht_supp: %d ht_cap: %d rates: 0x%x",
160 ht_cap->ht_supported, ht_cap->cap, rate_set);
161
162 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
163 if (!acx) {
164 ret = -ENOMEM;
165 goto out;
166 }
167
168 if (allow_ht_operation && ht_cap->ht_supported) {
169 /* no need to translate capabilities - use the spec values */
170 ht_capabilites = ht_cap->cap;
171
172 /*
173 * this bit is not employed by the spec but only by FW to
174 * indicate peer HT support
175 */
176 ht_capabilites |= WL12XX_HT_CAP_HT_OPERATION;
177
178 /* get data from A-MPDU parameters field */
179 acx->ampdu_max_length = ht_cap->ampdu_factor;
180 acx->ampdu_min_spacing = ht_cap->ampdu_density;
181 }
182
183 acx->hlid = hlid;
184 acx->ht_capabilites = cpu_to_le32(ht_capabilites);
185 acx->supported_rates = cpu_to_le32(rate_set);
186
187 ret = wl1271_cmd_configure(wl, ACX_PEER_CAP, acx, sizeof(*acx));
188 if (ret < 0) {
189 wl1271_warning("acx ht capabilities setting failed: %d", ret);
190 goto out;
191 }
192
193out:
194 kfree(acx);
195 return ret;
196}
diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h
index e2609a6b7341..0e636def1217 100644
--- a/drivers/net/wireless/ti/wl18xx/acx.h
+++ b/drivers/net/wireless/ti/wl18xx/acx.h
@@ -26,7 +26,13 @@
26#include "../wlcore/acx.h" 26#include "../wlcore/acx.h"
27 27
28enum { 28enum {
29 ACX_CLEAR_STATISTICS = 0x0047, 29 ACX_NS_IPV6_FILTER = 0x0050,
30 ACX_PEER_HT_OPERATION_MODE_CFG = 0x0051,
31 ACX_CSUM_CONFIG = 0x0052,
32 ACX_SIM_CONFIG = 0x0053,
33 ACX_CLEAR_STATISTICS = 0x0054,
34 ACX_AUTO_RX_STREAMING = 0x0055,
35 ACX_PEER_CAP = 0x0056
30}; 36};
31 37
32/* numbers of bits the length field takes (add 1 for the actual number) */ 38/* numbers of bits the length field takes (add 1 for the actual number) */
@@ -278,10 +284,57 @@ struct wl18xx_acx_clear_statistics {
278 struct acx_header header; 284 struct acx_header header;
279}; 285};
280 286
287enum wlcore_bandwidth {
288 WLCORE_BANDWIDTH_20MHZ,
289 WLCORE_BANDWIDTH_40MHZ,
290};
291
292struct wlcore_peer_ht_operation_mode {
293 struct acx_header header;
294
295 u8 hlid;
296 u8 bandwidth; /* enum wlcore_bandwidth */
297 u8 padding[2];
298};
299
300/*
301 * ACX_PEER_CAP
302 * this struct is very similar to wl1271_acx_ht_capabilities, with the
303 * addition of supported rates
304 */
305struct wlcore_acx_peer_cap {
306 struct acx_header header;
307
308 /* bitmask of capability bits supported by the peer */
309 __le32 ht_capabilites;
310
311 /* rates supported by the remote peer */
312 __le32 supported_rates;
313
314 /* Indicates to which link these capabilities apply. */
315 u8 hlid;
316
317 /*
318 * This the maximum A-MPDU length supported by the AP. The FW may not
319 * exceed this length when sending A-MPDUs
320 */
321 u8 ampdu_max_length;
322
323 /* This is the minimal spacing required when sending A-MPDUs to the AP*/
324 u8 ampdu_min_spacing;
325
326 u8 padding;
327} __packed;
328
281int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, 329int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap,
282 u32 sdio_blk_size, u32 extra_mem_blks, 330 u32 sdio_blk_size, u32 extra_mem_blks,
283 u32 len_field_size); 331 u32 len_field_size);
284int wl18xx_acx_set_checksum_state(struct wl1271 *wl); 332int wl18xx_acx_set_checksum_state(struct wl1271 *wl);
285int wl18xx_acx_clear_statistics(struct wl1271 *wl); 333int wl18xx_acx_clear_statistics(struct wl1271 *wl);
334int wl18xx_acx_peer_ht_operation_mode(struct wl1271 *wl, u8 hlid, bool wide);
335int wl18xx_acx_set_peer_cap(struct wl1271 *wl,
336 struct ieee80211_sta_ht_cap *ht_cap,
337 bool allow_ht_operation,
338 u32 rate_set, u8 hlid);
286 339
287#endif /* __WL18XX_ACX_H__ */ 340#endif /* __WL18XX_ACX_H__ */
diff --git a/drivers/net/wireless/ti/wl18xx/cmd.c b/drivers/net/wireless/ti/wl18xx/cmd.c
new file mode 100644
index 000000000000..1d1f6cc7a50a
--- /dev/null
+++ b/drivers/net/wireless/ti/wl18xx/cmd.c
@@ -0,0 +1,80 @@
1/*
2 * This file is part of wl18xx
3 *
4 * Copyright (C) 2011 Texas Instruments Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include "../wlcore/cmd.h"
23#include "../wlcore/debug.h"
24#include "../wlcore/hw_ops.h"
25
26#include "cmd.h"
27
28int wl18xx_cmd_channel_switch(struct wl1271 *wl,
29 struct wl12xx_vif *wlvif,
30 struct ieee80211_channel_switch *ch_switch)
31{
32 struct wl18xx_cmd_channel_switch *cmd;
33 u32 supported_rates;
34 int ret;
35
36 wl1271_debug(DEBUG_ACX, "cmd channel switch");
37
38 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
39 if (!cmd) {
40 ret = -ENOMEM;
41 goto out;
42 }
43
44 cmd->role_id = wlvif->role_id;
45 cmd->channel = ch_switch->channel->hw_value;
46 cmd->switch_time = ch_switch->count;
47 cmd->stop_tx = ch_switch->block_tx;
48
49 switch (ch_switch->channel->band) {
50 case IEEE80211_BAND_2GHZ:
51 cmd->band = WLCORE_BAND_2_4GHZ;
52 break;
53 case IEEE80211_BAND_5GHZ:
54 cmd->band = WLCORE_BAND_5GHZ;
55 break;
56 default:
57 wl1271_error("invalid channel switch band: %d",
58 ch_switch->channel->band);
59 ret = -EINVAL;
60 goto out_free;
61 }
62
63 supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES |
64 wlcore_hw_sta_get_ap_rate_mask(wl, wlvif);
65 if (wlvif->p2p)
66 supported_rates &= ~CONF_TX_CCK_RATES;
67 cmd->local_supported_rates = cpu_to_le32(supported_rates);
68 cmd->channel_type = wlvif->channel_type;
69
70 ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
71 if (ret < 0) {
72 wl1271_error("failed to send channel switch command");
73 goto out_free;
74 }
75
76out_free:
77 kfree(cmd);
78out:
79 return ret;
80}
diff --git a/drivers/net/wireless/ti/wl18xx/cmd.h b/drivers/net/wireless/ti/wl18xx/cmd.h
new file mode 100644
index 000000000000..6687d10899ac
--- /dev/null
+++ b/drivers/net/wireless/ti/wl18xx/cmd.h
@@ -0,0 +1,52 @@
1/*
2 * This file is part of wl18xx
3 *
4 * Copyright (C) 2011 Texas Instruments. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __WL18XX_CMD_H__
23#define __WL18XX_CMD_H__
24
25#include "../wlcore/wlcore.h"
26#include "../wlcore/acx.h"
27
28struct wl18xx_cmd_channel_switch {
29 struct wl1271_cmd_header header;
30
31 u8 role_id;
32
33 /* The new serving channel */
34 u8 channel;
35 /* Relative time of the serving channel switch in TBTT units */
36 u8 switch_time;
37 /* Stop the role TX, should expect it after radar detection */
38 u8 stop_tx;
39
40 __le32 local_supported_rates;
41
42 u8 channel_type;
43 u8 band;
44
45 u8 padding[2];
46} __packed;
47
48int wl18xx_cmd_channel_switch(struct wl1271 *wl,
49 struct wl12xx_vif *wlvif,
50 struct ieee80211_channel_switch *ch_switch);
51
52#endif
diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h
index 4d426cc20274..b5f114857191 100644
--- a/drivers/net/wireless/ti/wl18xx/conf.h
+++ b/drivers/net/wireless/ti/wl18xx/conf.h
@@ -23,20 +23,21 @@
23#define __WL18XX_CONF_H__ 23#define __WL18XX_CONF_H__
24 24
25#define WL18XX_CONF_MAGIC 0x10e100ca 25#define WL18XX_CONF_MAGIC 0x10e100ca
26#define WL18XX_CONF_VERSION (WLCORE_CONF_VERSION | 0x0003) 26#define WL18XX_CONF_VERSION (WLCORE_CONF_VERSION | 0x0005)
27#define WL18XX_CONF_MASK 0x0000ffff 27#define WL18XX_CONF_MASK 0x0000ffff
28#define WL18XX_CONF_SIZE (WLCORE_CONF_SIZE + \ 28#define WL18XX_CONF_SIZE (WLCORE_CONF_SIZE + \
29 sizeof(struct wl18xx_priv_conf)) 29 sizeof(struct wl18xx_priv_conf))
30 30
31#define NUM_OF_CHANNELS_11_ABG 150 31#define NUM_OF_CHANNELS_11_ABG 150
32#define NUM_OF_CHANNELS_11_P 7 32#define NUM_OF_CHANNELS_11_P 7
33#define WL18XX_NUM_OF_SUB_BANDS 9
34#define SRF_TABLE_LEN 16 33#define SRF_TABLE_LEN 16
35#define PIN_MUXING_SIZE 2 34#define PIN_MUXING_SIZE 2
35#define WL18XX_TRACE_LOSS_GAPS_TX 10
36#define WL18XX_TRACE_LOSS_GAPS_RX 18
36 37
37struct wl18xx_mac_and_phy_params { 38struct wl18xx_mac_and_phy_params {
38 u8 phy_standalone; 39 u8 phy_standalone;
39 u8 rdl; 40 u8 spare0;
40 u8 enable_clpc; 41 u8 enable_clpc;
41 u8 enable_tx_low_pwr_on_siso_rdl; 42 u8 enable_tx_low_pwr_on_siso_rdl;
42 u8 auto_detect; 43 u8 auto_detect;
@@ -69,18 +70,26 @@ struct wl18xx_mac_and_phy_params {
69 u8 pwr_limit_reference_11_abg; 70 u8 pwr_limit_reference_11_abg;
70 u8 per_chan_pwr_limit_arr_11p[NUM_OF_CHANNELS_11_P]; 71 u8 per_chan_pwr_limit_arr_11p[NUM_OF_CHANNELS_11_P];
71 u8 pwr_limit_reference_11p; 72 u8 pwr_limit_reference_11p;
72 u8 per_sub_band_tx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; 73 u8 spare1[9];
73 u8 per_sub_band_rx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; 74 u8 spare2[9];
74 u8 primary_clock_setting_time; 75 u8 primary_clock_setting_time;
75 u8 clock_valid_on_wake_up; 76 u8 clock_valid_on_wake_up;
76 u8 secondary_clock_setting_time; 77 u8 secondary_clock_setting_time;
77 u8 board_type; 78 u8 board_type;
78 /* enable point saturation */ 79 /* enable point saturation */
79 u8 psat; 80 u8 psat;
80 /* low/medium/high Tx power in dBm */ 81 /* low/medium/high Tx power in dBm for STA-HP BG */
81 s8 low_power_val; 82 s8 low_power_val;
82 s8 med_power_val; 83 s8 med_power_val;
83 s8 high_power_val; 84 s8 high_power_val;
85 s8 per_sub_band_tx_trace_loss[WL18XX_TRACE_LOSS_GAPS_TX];
86 s8 per_sub_band_rx_trace_loss[WL18XX_TRACE_LOSS_GAPS_RX];
87 u8 tx_rf_margin;
88 /* low/medium/high Tx power in dBm for other role */
89 s8 low_power_val_2nd;
90 s8 med_power_val_2nd;
91 s8 high_power_val_2nd;
92
84 u8 padding[1]; 93 u8 padding[1];
85} __packed; 94} __packed;
86 95
diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c
new file mode 100644
index 000000000000..c9199d7804c6
--- /dev/null
+++ b/drivers/net/wireless/ti/wl18xx/event.c
@@ -0,0 +1,111 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2012 Texas Instruments. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include "event.h"
23#include "scan.h"
24#include "../wlcore/cmd.h"
25#include "../wlcore/debug.h"
26
27int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
28 bool *timeout)
29{
30 u32 local_event;
31
32 switch (event) {
33 case WLCORE_EVENT_PEER_REMOVE_COMPLETE:
34 local_event = PEER_REMOVE_COMPLETE_EVENT_ID;
35 break;
36
37 case WLCORE_EVENT_DFS_CONFIG_COMPLETE:
38 local_event = DFS_CHANNELS_CONFIG_COMPLETE_EVENT;
39 break;
40
41 default:
42 /* event not implemented */
43 return 0;
44 }
45 return wlcore_cmd_wait_for_event_or_timeout(wl, local_event, timeout);
46}
47
48int wl18xx_process_mailbox_events(struct wl1271 *wl)
49{
50 struct wl18xx_event_mailbox *mbox = wl->mbox;
51 u32 vector;
52
53 vector = le32_to_cpu(mbox->events_vector);
54 wl1271_debug(DEBUG_EVENT, "MBOX vector: 0x%x", vector);
55
56 if (vector & SCAN_COMPLETE_EVENT_ID) {
57 wl1271_debug(DEBUG_EVENT, "scan results: %d",
58 mbox->number_of_scan_results);
59
60 if (wl->scan_wlvif)
61 wl18xx_scan_completed(wl, wl->scan_wlvif);
62 }
63
64 if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
65 wl1271_debug(DEBUG_EVENT,
66 "PERIODIC_SCAN_REPORT_EVENT (results %d)",
67 mbox->number_of_sched_scan_results);
68
69 wlcore_scan_sched_scan_results(wl);
70 }
71
72 if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID)
73 wlcore_event_sched_scan_completed(wl, 1);
74
75 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID)
76 wlcore_event_rssi_trigger(wl, mbox->rssi_snr_trigger_metric);
77
78 if (vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID)
79 wlcore_event_ba_rx_constraint(wl,
80 le16_to_cpu(mbox->rx_ba_role_id_bitmap),
81 le16_to_cpu(mbox->rx_ba_allowed_bitmap));
82
83 if (vector & BSS_LOSS_EVENT_ID)
84 wlcore_event_beacon_loss(wl,
85 le16_to_cpu(mbox->bss_loss_bitmap));
86
87 if (vector & CHANNEL_SWITCH_COMPLETE_EVENT_ID)
88 wlcore_event_channel_switch(wl,
89 le16_to_cpu(mbox->channel_switch_role_id_bitmap),
90 true);
91
92 if (vector & DUMMY_PACKET_EVENT_ID)
93 wlcore_event_dummy_packet(wl);
94
95 /*
96 * "TX retries exceeded" has a different meaning according to mode.
97 * In AP mode the offending station is disconnected.
98 */
99 if (vector & MAX_TX_FAILURE_EVENT_ID)
100 wlcore_event_max_tx_failure(wl,
101 le32_to_cpu(mbox->tx_retry_exceeded_bitmap));
102
103 if (vector & INACTIVE_STA_EVENT_ID)
104 wlcore_event_inactive_sta(wl,
105 le32_to_cpu(mbox->inactive_sta_bitmap));
106
107 if (vector & REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID)
108 wlcore_event_roc_complete(wl);
109
110 return 0;
111}
diff --git a/drivers/net/wireless/ti/wl18xx/event.h b/drivers/net/wireless/ti/wl18xx/event.h
new file mode 100644
index 000000000000..398f3d2c0a6c
--- /dev/null
+++ b/drivers/net/wireless/ti/wl18xx/event.h
@@ -0,0 +1,77 @@
1/*
2 * This file is part of wl18xx
3 *
4 * Copyright (C) 2012 Texas Instruments. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __WL18XX_EVENT_H__
23#define __WL18XX_EVENT_H__
24
25#include "../wlcore/wlcore.h"
26
27enum {
28 SCAN_COMPLETE_EVENT_ID = BIT(8),
29 RADAR_DETECTED_EVENT_ID = BIT(9),
30 CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(10),
31 BSS_LOSS_EVENT_ID = BIT(11),
32 MAX_TX_FAILURE_EVENT_ID = BIT(12),
33 DUMMY_PACKET_EVENT_ID = BIT(13),
34 INACTIVE_STA_EVENT_ID = BIT(14),
35 PEER_REMOVE_COMPLETE_EVENT_ID = BIT(15),
36 PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(16),
37 BA_SESSION_RX_CONSTRAINT_EVENT_ID = BIT(17),
38 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID = BIT(18),
39 DFS_CHANNELS_CONFIG_COMPLETE_EVENT = BIT(19),
40 PERIODIC_SCAN_REPORT_EVENT_ID = BIT(20),
41};
42
43struct wl18xx_event_mailbox {
44 __le32 events_vector;
45
46 u8 number_of_scan_results;
47 u8 number_of_sched_scan_results;
48
49 __le16 channel_switch_role_id_bitmap;
50
51 s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
52
53 /* bitmap of removed links */
54 __le32 hlid_removed_bitmap;
55
56 /* rx ba constraint */
57 __le16 rx_ba_role_id_bitmap; /* 0xfff means any role. */
58 __le16 rx_ba_allowed_bitmap;
59
60 /* bitmap of roc completed (by role id) */
61 __le16 roc_completed_bitmap;
62
63 /* bitmap of stations (by role id) with bss loss */
64 __le16 bss_loss_bitmap;
65
66 /* bitmap of stations (by HLID) which exceeded max tx retries */
67 __le32 tx_retry_exceeded_bitmap;
68
69 /* bitmap of inactive stations (by HLID) */
70 __le32 inactive_sta_bitmap;
71} __packed;
72
73int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
74 bool *timeout);
75int wl18xx_process_mailbox_events(struct wl1271 *wl);
76
77#endif
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 8d8c1f8c63b7..0be1cfc17a86 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -34,10 +34,13 @@
34 34
35#include "reg.h" 35#include "reg.h"
36#include "conf.h" 36#include "conf.h"
37#include "cmd.h"
37#include "acx.h" 38#include "acx.h"
38#include "tx.h" 39#include "tx.h"
39#include "wl18xx.h" 40#include "wl18xx.h"
40#include "io.h" 41#include "io.h"
42#include "scan.h"
43#include "event.h"
41#include "debugfs.h" 44#include "debugfs.h"
42 45
43#define WL18XX_RX_CHECKSUM_MASK 0x40 46#define WL18XX_RX_CHECKSUM_MASK 0x40
@@ -334,6 +337,8 @@ static struct wlcore_conf wl18xx_conf = {
334 .tmpl_short_retry_limit = 10, 337 .tmpl_short_retry_limit = 10,
335 .tmpl_long_retry_limit = 10, 338 .tmpl_long_retry_limit = 10,
336 .tx_watchdog_timeout = 5000, 339 .tx_watchdog_timeout = 5000,
340 .slow_link_thold = 3,
341 .fast_link_thold = 30,
337 }, 342 },
338 .conn = { 343 .conn = {
339 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, 344 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
@@ -391,8 +396,10 @@ static struct wlcore_conf wl18xx_conf = {
391 .scan = { 396 .scan = {
392 .min_dwell_time_active = 7500, 397 .min_dwell_time_active = 7500,
393 .max_dwell_time_active = 30000, 398 .max_dwell_time_active = 30000,
394 .min_dwell_time_passive = 100000, 399 .min_dwell_time_active_long = 25000,
395 .max_dwell_time_passive = 100000, 400 .max_dwell_time_active_long = 50000,
401 .dwell_time_passive = 100000,
402 .dwell_time_dfs = 150000,
396 .num_probe_reqs = 2, 403 .num_probe_reqs = 2,
397 .split_scan_timeout = 50000, 404 .split_scan_timeout = 50000,
398 }, 405 },
@@ -489,6 +496,10 @@ static struct wlcore_conf wl18xx_conf = {
489 .increase_time = 1, 496 .increase_time = 1,
490 .window_size = 16, 497 .window_size = 16,
491 }, 498 },
499 .recovery = {
500 .bug_on_recovery = 0,
501 .no_recovery = 0,
502 },
492}; 503};
493 504
494static struct wl18xx_priv_conf wl18xx_default_priv_conf = { 505static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
@@ -501,7 +512,6 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
501 .clock_valid_on_wake_up = 0x00, 512 .clock_valid_on_wake_up = 0x00,
502 .secondary_clock_setting_time = 0x05, 513 .secondary_clock_setting_time = 0x05,
503 .board_type = BOARD_TYPE_HDK_18XX, 514 .board_type = BOARD_TYPE_HDK_18XX,
504 .rdl = 0x01,
505 .auto_detect = 0x00, 515 .auto_detect = 0x00,
506 .dedicated_fem = FEM_NONE, 516 .dedicated_fem = FEM_NONE,
507 .low_band_component = COMPONENT_3_WAY_SWITCH, 517 .low_band_component = COMPONENT_3_WAY_SWITCH,
@@ -517,14 +527,39 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
517 .enable_clpc = 0x00, 527 .enable_clpc = 0x00,
518 .enable_tx_low_pwr_on_siso_rdl = 0x00, 528 .enable_tx_low_pwr_on_siso_rdl = 0x00,
519 .rx_profile = 0x00, 529 .rx_profile = 0x00,
520 .pwr_limit_reference_11_abg = 0xc8, 530 .pwr_limit_reference_11_abg = 0x64,
531 .per_chan_pwr_limit_arr_11abg = {
532 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
533 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
534 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
535 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
536 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
537 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
538 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
539 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
540 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
541 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
542 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
543 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
544 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
545 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
546 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
547 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
548 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
549 .pwr_limit_reference_11p = 0x64,
550 .per_chan_pwr_limit_arr_11p = { 0xff, 0xff, 0xff, 0xff,
551 0xff, 0xff, 0xff },
521 .psat = 0, 552 .psat = 0,
522 .low_power_val = 0x00, 553 .low_power_val = 0x08,
523 .med_power_val = 0x0a, 554 .med_power_val = 0x12,
524 .high_power_val = 0x1e, 555 .high_power_val = 0x18,
556 .low_power_val_2nd = 0x05,
557 .med_power_val_2nd = 0x0a,
558 .high_power_val_2nd = 0x14,
525 .external_pa_dc2dc = 0, 559 .external_pa_dc2dc = 0,
526 .number_of_assembled_ant2_4 = 1, 560 .number_of_assembled_ant2_4 = 2,
527 .number_of_assembled_ant5 = 1, 561 .number_of_assembled_ant5 = 1,
562 .tx_rf_margin = 1,
528 }, 563 },
529}; 564};
530 565
@@ -595,7 +630,7 @@ static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
595}; 630};
596 631
597/* TODO: maybe move to a new header file? */ 632/* TODO: maybe move to a new header file? */
598#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw.bin" 633#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-2.bin"
599 634
600static int wl18xx_identify_chip(struct wl1271 *wl) 635static int wl18xx_identify_chip(struct wl1271 *wl)
601{ 636{
@@ -608,15 +643,18 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
608 wl->sr_fw_name = WL18XX_FW_NAME; 643 wl->sr_fw_name = WL18XX_FW_NAME;
609 /* wl18xx uses the same firmware for PLT */ 644 /* wl18xx uses the same firmware for PLT */
610 wl->plt_fw_name = WL18XX_FW_NAME; 645 wl->plt_fw_name = WL18XX_FW_NAME;
611 wl->quirks |= WLCORE_QUIRK_NO_ELP | 646 wl->quirks |= WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
612 WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
613 WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | 647 WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
614 WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN | 648 WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN |
615 WLCORE_QUIRK_TX_PAD_LAST_FRAME; 649 WLCORE_QUIRK_TX_PAD_LAST_FRAME |
616 650 WLCORE_QUIRK_REGDOMAIN_CONF |
617 wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER, WL18XX_IFTYPE_VER, 651 WLCORE_QUIRK_DUAL_PROBE_TMPL;
618 WL18XX_MAJOR_VER, WL18XX_SUBTYPE_VER, 652
619 WL18XX_MINOR_VER); 653 wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER,
654 WL18XX_IFTYPE_VER, WL18XX_MAJOR_VER,
655 WL18XX_SUBTYPE_VER, WL18XX_MINOR_VER,
656 /* there's no separate multi-role FW */
657 0, 0, 0, 0);
620 break; 658 break;
621 case CHIP_ID_185x_PG10: 659 case CHIP_ID_185x_PG10:
622 wl1271_warning("chip id 0x%x (185x PG10) is deprecated", 660 wl1271_warning("chip id 0x%x (185x PG10) is deprecated",
@@ -630,6 +668,11 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
630 goto out; 668 goto out;
631 } 669 }
632 670
671 wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
672 wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
673 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
674 wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
675 wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
633out: 676out:
634 return ret; 677 return ret;
635} 678}
@@ -843,6 +886,20 @@ static int wl18xx_boot(struct wl1271 *wl)
843 if (ret < 0) 886 if (ret < 0)
844 goto out; 887 goto out;
845 888
889 wl->event_mask = BSS_LOSS_EVENT_ID |
890 SCAN_COMPLETE_EVENT_ID |
891 RSSI_SNR_TRIGGER_0_EVENT_ID |
892 PERIODIC_SCAN_COMPLETE_EVENT_ID |
893 PERIODIC_SCAN_REPORT_EVENT_ID |
894 DUMMY_PACKET_EVENT_ID |
895 PEER_REMOVE_COMPLETE_EVENT_ID |
896 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
897 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
898 INACTIVE_STA_EVENT_ID |
899 MAX_TX_FAILURE_EVENT_ID |
900 CHANNEL_SWITCH_COMPLETE_EVENT_ID |
901 DFS_CHANNELS_CONFIG_COMPLETE_EVENT;
902
846 ret = wlcore_boot_run_firmware(wl); 903 ret = wlcore_boot_run_firmware(wl);
847 if (ret < 0) 904 if (ret < 0)
848 goto out; 905 goto out;
@@ -964,7 +1021,7 @@ static int wl18xx_hw_init(struct wl1271 *wl)
964 1021
965 /* (re)init private structures. Relevant on recovery as well. */ 1022 /* (re)init private structures. Relevant on recovery as well. */
966 priv->last_fw_rls_idx = 0; 1023 priv->last_fw_rls_idx = 0;
967 priv->extra_spare_vif_count = 0; 1024 priv->extra_spare_key_count = 0;
968 1025
969 /* set the default amount of spare blocks in the bitmap */ 1026 /* set the default amount of spare blocks in the bitmap */
970 ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE); 1027 ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE);
@@ -1022,7 +1079,12 @@ static bool wl18xx_is_mimo_supported(struct wl1271 *wl)
1022{ 1079{
1023 struct wl18xx_priv *priv = wl->priv; 1080 struct wl18xx_priv *priv = wl->priv;
1024 1081
1025 return priv->conf.phy.number_of_assembled_ant2_4 >= 2; 1082 /* only support MIMO with multiple antennas, and when SISO
1083 * is not forced through config
1084 */
1085 return (priv->conf.phy.number_of_assembled_ant2_4 >= 2) &&
1086 (priv->conf.ht.mode != HT_MODE_WIDE) &&
1087 (priv->conf.ht.mode != HT_MODE_SISO20);
1026} 1088}
1027 1089
1028/* 1090/*
@@ -1223,8 +1285,8 @@ static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1223{ 1285{
1224 struct wl18xx_priv *priv = wl->priv; 1286 struct wl18xx_priv *priv = wl->priv;
1225 1287
1226 /* If we have VIFs requiring extra spare, indulge them */ 1288 /* If we have keys requiring extra spare, indulge them */
1227 if (priv->extra_spare_vif_count) 1289 if (priv->extra_spare_key_count)
1228 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE; 1290 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE;
1229 1291
1230 return WL18XX_TX_HW_BLOCK_SPARE; 1292 return WL18XX_TX_HW_BLOCK_SPARE;
@@ -1236,42 +1298,48 @@ static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1236 struct ieee80211_key_conf *key_conf) 1298 struct ieee80211_key_conf *key_conf)
1237{ 1299{
1238 struct wl18xx_priv *priv = wl->priv; 1300 struct wl18xx_priv *priv = wl->priv;
1239 bool change_spare = false; 1301 bool change_spare = false, special_enc;
1240 int ret; 1302 int ret;
1241 1303
1304 wl1271_debug(DEBUG_CRYPT, "extra spare keys before: %d",
1305 priv->extra_spare_key_count);
1306
1307 special_enc = key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
1308 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
1309
1310 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
1311 if (ret < 0)
1312 goto out;
1313
1242 /* 1314 /*
1243 * when adding the first or removing the last GEM/TKIP interface, 1315 * when adding the first or removing the last GEM/TKIP key,
1244 * we have to adjust the number of spare blocks. 1316 * we have to adjust the number of spare blocks.
1245 */ 1317 */
1246 change_spare = (key_conf->cipher == WL1271_CIPHER_SUITE_GEM || 1318 if (special_enc) {
1247 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP) && 1319 if (cmd == SET_KEY) {
1248 ((priv->extra_spare_vif_count == 0 && cmd == SET_KEY) || 1320 /* first key */
1249 (priv->extra_spare_vif_count == 1 && cmd == DISABLE_KEY)); 1321 change_spare = (priv->extra_spare_key_count == 0);
1322 priv->extra_spare_key_count++;
1323 } else if (cmd == DISABLE_KEY) {
1324 /* last key */
1325 change_spare = (priv->extra_spare_key_count == 1);
1326 priv->extra_spare_key_count--;
1327 }
1328 }
1250 1329
1251 /* no need to change spare - just regular set_key */ 1330 wl1271_debug(DEBUG_CRYPT, "extra spare keys after: %d",
1252 if (!change_spare) 1331 priv->extra_spare_key_count);
1253 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1254 1332
1255 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf); 1333 if (!change_spare)
1256 if (ret < 0)
1257 goto out; 1334 goto out;
1258 1335
1259 /* key is now set, change the spare blocks */ 1336 /* key is now set, change the spare blocks */
1260 if (cmd == SET_KEY) { 1337 if (priv->extra_spare_key_count)
1261 ret = wl18xx_set_host_cfg_bitmap(wl, 1338 ret = wl18xx_set_host_cfg_bitmap(wl,
1262 WL18XX_TX_HW_EXTRA_BLOCK_SPARE); 1339 WL18XX_TX_HW_EXTRA_BLOCK_SPARE);
1263 if (ret < 0) 1340 else
1264 goto out;
1265
1266 priv->extra_spare_vif_count++;
1267 } else {
1268 ret = wl18xx_set_host_cfg_bitmap(wl, 1341 ret = wl18xx_set_host_cfg_bitmap(wl,
1269 WL18XX_TX_HW_BLOCK_SPARE); 1342 WL18XX_TX_HW_BLOCK_SPARE);
1270 if (ret < 0)
1271 goto out;
1272
1273 priv->extra_spare_vif_count--;
1274 }
1275 1343
1276out: 1344out:
1277 return ret; 1345 return ret;
@@ -1296,6 +1364,92 @@ static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1296 return buf_offset; 1364 return buf_offset;
1297} 1365}
1298 1366
1367static void wl18xx_sta_rc_update(struct wl1271 *wl,
1368 struct wl12xx_vif *wlvif,
1369 struct ieee80211_sta *sta,
1370 u32 changed)
1371{
1372 bool wide = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1373
1374 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
1375
1376 if (!(changed & IEEE80211_RC_BW_CHANGED))
1377 return;
1378
1379 mutex_lock(&wl->mutex);
1380
1381 /* sanity */
1382 if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
1383 goto out;
1384
1385 /* ignore the change before association */
1386 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1387 goto out;
1388
1389 /*
1390 * If we started out as wide, we can change the operation mode. If we
1391 * thought this was a 20mhz AP, we have to reconnect
1392 */
1393 if (wlvif->sta.role_chan_type == NL80211_CHAN_HT40MINUS ||
1394 wlvif->sta.role_chan_type == NL80211_CHAN_HT40PLUS)
1395 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
1396 else
1397 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
1398
1399out:
1400 mutex_unlock(&wl->mutex);
1401}
1402
1403static int wl18xx_set_peer_cap(struct wl1271 *wl,
1404 struct ieee80211_sta_ht_cap *ht_cap,
1405 bool allow_ht_operation,
1406 u32 rate_set, u8 hlid)
1407{
1408 return wl18xx_acx_set_peer_cap(wl, ht_cap, allow_ht_operation,
1409 rate_set, hlid);
1410}
1411
1412static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1413 struct wl1271_link *lnk)
1414{
1415 u8 thold;
1416 struct wl18xx_fw_status_priv *status_priv =
1417 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
1418 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1419
1420 /* suspended links are never high priority */
1421 if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
1422 return false;
1423
1424 /* the priority thresholds are taken from FW */
1425 if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
1426 !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
1427 thold = status_priv->tx_fast_link_prio_threshold;
1428 else
1429 thold = status_priv->tx_slow_link_prio_threshold;
1430
1431 return lnk->allocated_pkts < thold;
1432}
1433
1434static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1435 struct wl1271_link *lnk)
1436{
1437 u8 thold;
1438 struct wl18xx_fw_status_priv *status_priv =
1439 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
1440 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1441
1442 if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
1443 thold = status_priv->tx_suspend_threshold;
1444 else if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
1445 !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
1446 thold = status_priv->tx_fast_stop_threshold;
1447 else
1448 thold = status_priv->tx_slow_stop_threshold;
1449
1450 return lnk->allocated_pkts < thold;
1451}
1452
1299static int wl18xx_setup(struct wl1271 *wl); 1453static int wl18xx_setup(struct wl1271 *wl);
1300 1454
1301static struct wlcore_ops wl18xx_ops = { 1455static struct wlcore_ops wl18xx_ops = {
@@ -1305,6 +1459,8 @@ static struct wlcore_ops wl18xx_ops = {
1305 .plt_init = wl18xx_plt_init, 1459 .plt_init = wl18xx_plt_init,
1306 .trigger_cmd = wl18xx_trigger_cmd, 1460 .trigger_cmd = wl18xx_trigger_cmd,
1307 .ack_event = wl18xx_ack_event, 1461 .ack_event = wl18xx_ack_event,
1462 .wait_for_event = wl18xx_wait_for_event,
1463 .process_mailbox_events = wl18xx_process_mailbox_events,
1308 .calc_tx_blocks = wl18xx_calc_tx_blocks, 1464 .calc_tx_blocks = wl18xx_calc_tx_blocks,
1309 .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks, 1465 .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks,
1310 .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len, 1466 .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len,
@@ -1320,16 +1476,26 @@ static struct wlcore_ops wl18xx_ops = {
1320 .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, 1476 .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask,
1321 .get_mac = wl18xx_get_mac, 1477 .get_mac = wl18xx_get_mac,
1322 .debugfs_init = wl18xx_debugfs_add_files, 1478 .debugfs_init = wl18xx_debugfs_add_files,
1479 .scan_start = wl18xx_scan_start,
1480 .scan_stop = wl18xx_scan_stop,
1481 .sched_scan_start = wl18xx_sched_scan_start,
1482 .sched_scan_stop = wl18xx_scan_sched_scan_stop,
1323 .handle_static_data = wl18xx_handle_static_data, 1483 .handle_static_data = wl18xx_handle_static_data,
1324 .get_spare_blocks = wl18xx_get_spare_blocks, 1484 .get_spare_blocks = wl18xx_get_spare_blocks,
1325 .set_key = wl18xx_set_key, 1485 .set_key = wl18xx_set_key,
1486 .channel_switch = wl18xx_cmd_channel_switch,
1326 .pre_pkt_send = wl18xx_pre_pkt_send, 1487 .pre_pkt_send = wl18xx_pre_pkt_send,
1488 .sta_rc_update = wl18xx_sta_rc_update,
1489 .set_peer_cap = wl18xx_set_peer_cap,
1490 .lnk_high_prio = wl18xx_lnk_high_prio,
1491 .lnk_low_prio = wl18xx_lnk_low_prio,
1327}; 1492};
1328 1493
1329/* HT cap appropriate for wide channels in 2Ghz */ 1494/* HT cap appropriate for wide channels in 2Ghz */
1330static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = { 1495static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1331 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | 1496 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1332 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40, 1497 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40 |
1498 IEEE80211_HT_CAP_GRN_FLD,
1333 .ht_supported = true, 1499 .ht_supported = true,
1334 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1500 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1335 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1501 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1343,7 +1509,8 @@ static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1343/* HT cap appropriate for wide channels in 5Ghz */ 1509/* HT cap appropriate for wide channels in 5Ghz */
1344static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = { 1510static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1345 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | 1511 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1346 IEEE80211_HT_CAP_SUP_WIDTH_20_40, 1512 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1513 IEEE80211_HT_CAP_GRN_FLD,
1347 .ht_supported = true, 1514 .ht_supported = true,
1348 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1515 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1349 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1516 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1356,7 +1523,8 @@ static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1356 1523
1357/* HT cap appropriate for SISO 20 */ 1524/* HT cap appropriate for SISO 20 */
1358static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = { 1525static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1359 .cap = IEEE80211_HT_CAP_SGI_20, 1526 .cap = IEEE80211_HT_CAP_SGI_20 |
1527 IEEE80211_HT_CAP_GRN_FLD,
1360 .ht_supported = true, 1528 .ht_supported = true,
1361 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1529 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1362 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1530 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1369,7 +1537,8 @@ static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1369 1537
1370/* HT cap appropriate for MIMO rates in 20mhz channel */ 1538/* HT cap appropriate for MIMO rates in 20mhz channel */
1371static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { 1539static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
1372 .cap = IEEE80211_HT_CAP_SGI_20, 1540 .cap = IEEE80211_HT_CAP_SGI_20 |
1541 IEEE80211_HT_CAP_GRN_FLD,
1373 .ht_supported = true, 1542 .ht_supported = true,
1374 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1543 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1375 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1544 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1387,7 +1556,8 @@ static int wl18xx_setup(struct wl1271 *wl)
1387 1556
1388 wl->rtable = wl18xx_rtable; 1557 wl->rtable = wl18xx_rtable;
1389 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS; 1558 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1390 wl->num_rx_desc = WL18XX_NUM_TX_DESCRIPTORS; 1559 wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
1560 wl->num_channels = 2;
1391 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES; 1561 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
1392 wl->band_rate_to_idx = wl18xx_band_rate_to_idx; 1562 wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
1393 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; 1563 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
@@ -1506,7 +1676,8 @@ static int wl18xx_probe(struct platform_device *pdev)
1506 int ret; 1676 int ret;
1507 1677
1508 hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv), 1678 hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv),
1509 WL18XX_AGGR_BUFFER_SIZE); 1679 WL18XX_AGGR_BUFFER_SIZE,
1680 sizeof(struct wl18xx_event_mailbox));
1510 if (IS_ERR(hw)) { 1681 if (IS_ERR(hw)) {
1511 wl1271_error("can't allocate hw"); 1682 wl1271_error("can't allocate hw");
1512 ret = PTR_ERR(hw); 1683 ret = PTR_ERR(hw);
diff --git a/drivers/net/wireless/ti/wl18xx/scan.c b/drivers/net/wireless/ti/wl18xx/scan.c
new file mode 100644
index 000000000000..09d944505ac0
--- /dev/null
+++ b/drivers/net/wireless/ti/wl18xx/scan.c
@@ -0,0 +1,326 @@
1/*
2 * This file is part of wl18xx
3 *
4 * Copyright (C) 2012 Texas Instruments. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/ieee80211.h>
23#include "scan.h"
24#include "../wlcore/debug.h"
25
26static void wl18xx_adjust_channels(struct wl18xx_cmd_scan_params *cmd,
27 struct wlcore_scan_channels *cmd_channels)
28{
29 memcpy(cmd->passive, cmd_channels->passive, sizeof(cmd->passive));
30 memcpy(cmd->active, cmd_channels->active, sizeof(cmd->active));
31 cmd->dfs = cmd_channels->dfs;
32 cmd->passive_active = cmd_channels->passive_active;
33
34 memcpy(cmd->channels_2, cmd_channels->channels_2,
35 sizeof(cmd->channels_2));
36 memcpy(cmd->channels_5, cmd_channels->channels_5,
37 sizeof(cmd->channels_2));
38 /* channels_4 are not supported, so no need to copy them */
39}
40
41static int wl18xx_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
42 struct cfg80211_scan_request *req)
43{
44 struct wl18xx_cmd_scan_params *cmd;
45 struct wlcore_scan_channels *cmd_channels = NULL;
46 int ret;
47
48 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
49 if (!cmd) {
50 ret = -ENOMEM;
51 goto out;
52 }
53
54 cmd->role_id = wlvif->role_id;
55
56 if (WARN_ON(cmd->role_id == WL12XX_INVALID_ROLE_ID)) {
57 ret = -EINVAL;
58 goto out;
59 }
60
61 cmd->scan_type = SCAN_TYPE_SEARCH;
62 cmd->rssi_threshold = -127;
63 cmd->snr_threshold = 0;
64
65 cmd->bss_type = SCAN_BSS_TYPE_ANY;
66
67 cmd->ssid_from_list = 0;
68 cmd->filter = 0;
69 cmd->add_broadcast = 0;
70
71 cmd->urgency = 0;
72 cmd->protect = 0;
73
74 cmd->n_probe_reqs = wl->conf.scan.num_probe_reqs;
75 cmd->terminate_after = 0;
76
77 /* configure channels */
78 WARN_ON(req->n_ssids > 1);
79
80 cmd_channels = kzalloc(sizeof(*cmd_channels), GFP_KERNEL);
81 if (!cmd_channels) {
82 ret = -ENOMEM;
83 goto out;
84 }
85
86 wlcore_set_scan_chan_params(wl, cmd_channels, req->channels,
87 req->n_channels, req->n_ssids,
88 SCAN_TYPE_SEARCH);
89 wl18xx_adjust_channels(cmd, cmd_channels);
90
91 /*
92 * all the cycles params (except total cycles) should
93 * remain 0 for normal scan
94 */
95 cmd->total_cycles = 1;
96
97 if (req->no_cck)
98 cmd->rate = WL18XX_SCAN_RATE_6;
99
100 cmd->tag = WL1271_SCAN_DEFAULT_TAG;
101
102 if (req->n_ssids) {
103 cmd->ssid_len = req->ssids[0].ssid_len;
104 memcpy(cmd->ssid, req->ssids[0].ssid, cmd->ssid_len);
105 }
106
107 /* TODO: per-band ies? */
108 if (cmd->active[0]) {
109 u8 band = IEEE80211_BAND_2GHZ;
110 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
111 cmd->role_id, band,
112 req->ssids ? req->ssids[0].ssid : NULL,
113 req->ssids ? req->ssids[0].ssid_len : 0,
114 req->ie,
115 req->ie_len,
116 false);
117 if (ret < 0) {
118 wl1271_error("2.4GHz PROBE request template failed");
119 goto out;
120 }
121 }
122
123 if (cmd->active[1] || cmd->dfs) {
124 u8 band = IEEE80211_BAND_5GHZ;
125 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
126 cmd->role_id, band,
127 req->ssids ? req->ssids[0].ssid : NULL,
128 req->ssids ? req->ssids[0].ssid_len : 0,
129 req->ie,
130 req->ie_len,
131 false);
132 if (ret < 0) {
133 wl1271_error("5GHz PROBE request template failed");
134 goto out;
135 }
136 }
137
138 wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd));
139
140 ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0);
141 if (ret < 0) {
142 wl1271_error("SCAN failed");
143 goto out;
144 }
145
146out:
147 kfree(cmd_channels);
148 kfree(cmd);
149 return ret;
150}
151
152void wl18xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif)
153{
154 wl->scan.failed = false;
155 cancel_delayed_work(&wl->scan_complete_work);
156 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
157 msecs_to_jiffies(0));
158}
159
160static
161int wl18xx_scan_sched_scan_config(struct wl1271 *wl,
162 struct wl12xx_vif *wlvif,
163 struct cfg80211_sched_scan_request *req,
164 struct ieee80211_sched_scan_ies *ies)
165{
166 struct wl18xx_cmd_scan_params *cmd;
167 struct wlcore_scan_channels *cmd_channels = NULL;
168 struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
169 int ret;
170 int filter_type;
171
172 wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config");
173
174 filter_type = wlcore_scan_sched_scan_ssid_list(wl, wlvif, req);
175 if (filter_type < 0)
176 return filter_type;
177
178 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
179 if (!cmd) {
180 ret = -ENOMEM;
181 goto out;
182 }
183
184 cmd->role_id = wlvif->role_id;
185
186 if (WARN_ON(cmd->role_id == WL12XX_INVALID_ROLE_ID)) {
187 ret = -EINVAL;
188 goto out;
189 }
190
191 cmd->scan_type = SCAN_TYPE_PERIODIC;
192 cmd->rssi_threshold = c->rssi_threshold;
193 cmd->snr_threshold = c->snr_threshold;
194
195 /* don't filter on BSS type */
196 cmd->bss_type = SCAN_BSS_TYPE_ANY;
197
198 cmd->ssid_from_list = 1;
199 if (filter_type == SCAN_SSID_FILTER_LIST)
200 cmd->filter = 1;
201 cmd->add_broadcast = 0;
202
203 cmd->urgency = 0;
204 cmd->protect = 0;
205
206 cmd->n_probe_reqs = c->num_probe_reqs;
207 /* don't stop scanning automatically when something is found */
208 cmd->terminate_after = 0;
209
210 cmd_channels = kzalloc(sizeof(*cmd_channels), GFP_KERNEL);
211 if (!cmd_channels) {
212 ret = -ENOMEM;
213 goto out;
214 }
215
216 /* configure channels */
217 wlcore_set_scan_chan_params(wl, cmd_channels, req->channels,
218 req->n_channels, req->n_ssids,
219 SCAN_TYPE_PERIODIC);
220 wl18xx_adjust_channels(cmd, cmd_channels);
221
222 cmd->short_cycles_sec = 0;
223 cmd->long_cycles_sec = cpu_to_le16(req->interval);
224 cmd->short_cycles_count = 0;
225
226 cmd->total_cycles = 0;
227
228 cmd->tag = WL1271_SCAN_DEFAULT_TAG;
229
230 /* create a PERIODIC_SCAN_REPORT_EVENT whenever we've got a match */
231 cmd->report_threshold = 1;
232 cmd->terminate_on_report = 0;
233
234 if (cmd->active[0]) {
235 u8 band = IEEE80211_BAND_2GHZ;
236 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
237 cmd->role_id, band,
238 req->ssids ? req->ssids[0].ssid : NULL,
239 req->ssids ? req->ssids[0].ssid_len : 0,
240 ies->ie[band],
241 ies->len[band],
242 true);
243 if (ret < 0) {
244 wl1271_error("2.4GHz PROBE request template failed");
245 goto out;
246 }
247 }
248
249 if (cmd->active[1] || cmd->dfs) {
250 u8 band = IEEE80211_BAND_5GHZ;
251 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
252 cmd->role_id, band,
253 req->ssids ? req->ssids[0].ssid : NULL,
254 req->ssids ? req->ssids[0].ssid_len : 0,
255 ies->ie[band],
256 ies->len[band],
257 true);
258 if (ret < 0) {
259 wl1271_error("5GHz PROBE request template failed");
260 goto out;
261 }
262 }
263
264 wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd));
265
266 ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0);
267 if (ret < 0) {
268 wl1271_error("SCAN failed");
269 goto out;
270 }
271
272out:
273 kfree(cmd_channels);
274 kfree(cmd);
275 return ret;
276}
277
278int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
279 struct cfg80211_sched_scan_request *req,
280 struct ieee80211_sched_scan_ies *ies)
281{
282 return wl18xx_scan_sched_scan_config(wl, wlvif, req, ies);
283}
284
285static int __wl18xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif,
286 u8 scan_type)
287{
288 struct wl18xx_cmd_scan_stop *stop;
289 int ret;
290
291 wl1271_debug(DEBUG_CMD, "cmd periodic scan stop");
292
293 stop = kzalloc(sizeof(*stop), GFP_KERNEL);
294 if (!stop) {
295 wl1271_error("failed to alloc memory to send sched scan stop");
296 return -ENOMEM;
297 }
298
299 stop->role_id = wlvif->role_id;
300 stop->scan_type = scan_type;
301
302 ret = wl1271_cmd_send(wl, CMD_STOP_SCAN, stop, sizeof(*stop), 0);
303 if (ret < 0) {
304 wl1271_error("failed to send sched scan stop command");
305 goto out_free;
306 }
307
308out_free:
309 kfree(stop);
310 return ret;
311}
312
313void wl18xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif)
314{
315 __wl18xx_scan_stop(wl, wlvif, SCAN_TYPE_PERIODIC);
316}
317int wl18xx_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
318 struct cfg80211_scan_request *req)
319{
320 return wl18xx_scan_send(wl, wlvif, req);
321}
322
323int wl18xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif)
324{
325 return __wl18xx_scan_stop(wl, wlvif, SCAN_TYPE_SEARCH);
326}
diff --git a/drivers/net/wireless/ti/wl18xx/scan.h b/drivers/net/wireless/ti/wl18xx/scan.h
new file mode 100644
index 000000000000..eadee42689d1
--- /dev/null
+++ b/drivers/net/wireless/ti/wl18xx/scan.h
@@ -0,0 +1,127 @@
1/*
2 * This file is part of wl18xx
3 *
4 * Copyright (C) 2012 Texas Instruments. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __WL18XX_SCAN_H__
23#define __WL18XX_SCAN_H__
24
25#include "../wlcore/wlcore.h"
26#include "../wlcore/cmd.h"
27#include "../wlcore/scan.h"
28
29struct tracking_ch_params {
30 struct conn_scan_ch_params channel;
31
32 __le32 bssid_lsb;
33 __le16 bssid_msb;
34
35 u8 padding[2];
36} __packed;
37
38/* probe request rate */
39enum
40{
41 WL18XX_SCAN_RATE_1 = 0,
42 WL18XX_SCAN_RATE_5_5 = 1,
43 WL18XX_SCAN_RATE_6 = 2,
44};
45
46#define WL18XX_MAX_CHANNELS_5GHZ 32
47
48struct wl18xx_cmd_scan_params {
49 struct wl1271_cmd_header header;
50
51 u8 role_id;
52 u8 scan_type;
53
54 s8 rssi_threshold; /* for filtering (in dBm) */
55 s8 snr_threshold; /* for filtering (in dB) */
56
57 u8 bss_type; /* for filtering */
58 u8 ssid_from_list; /* use ssid from configured ssid list */
59 u8 filter; /* forward only results with matching ssids */
60
61 /*
62 * add broadcast ssid in addition to the configured ssids.
63 * the driver should add dummy entry for it (?).
64 */
65 u8 add_broadcast;
66
67 u8 urgency;
68 u8 protect; /* ??? */
69 u8 n_probe_reqs; /* Number of probes requests per channel */
70 u8 terminate_after; /* early terminate scan operation */
71
72 u8 passive[SCAN_MAX_BANDS]; /* number of passive scan channels */
73 u8 active[SCAN_MAX_BANDS]; /* number of active scan channels */
74 u8 dfs; /* number of dfs channels in 5ghz */
75 u8 passive_active; /* number of passive before active channels 2.4ghz */
76
77 __le16 short_cycles_sec;
78 __le16 long_cycles_sec;
79 u8 short_cycles_count;
80 u8 total_cycles; /* 0 - infinite */
81 u8 padding[2];
82
83 union {
84 struct {
85 struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ];
86 struct conn_scan_ch_params channels_5[WL18XX_MAX_CHANNELS_5GHZ];
87 struct conn_scan_ch_params channels_4[MAX_CHANNELS_4GHZ];
88 };
89 struct tracking_ch_params channels_tracking[WL1271_SCAN_MAX_CHANNELS];
90 } ;
91
92 u8 ssid[IEEE80211_MAX_SSID_LEN];
93 u8 ssid_len; /* For SCAN_SSID_FILTER_SPECIFIC */
94 u8 tag;
95 u8 rate;
96
97 /* send SCAN_REPORT_EVENT in periodic scans after each cycle
98 * if number of results >= report_threshold. Must be 0 for
99 * non periodic scans
100 */
101 u8 report_threshold;
102
103 /* Should periodic scan stop after a report event was created.
104 * Must be 0 for non periodic scans.
105 */
106 u8 terminate_on_report;
107
108 u8 padding1[3];
109} __packed;
110
111struct wl18xx_cmd_scan_stop {
112 struct wl1271_cmd_header header;
113
114 u8 role_id;
115 u8 scan_type;
116 u8 padding[2];
117} __packed;
118
119int wl18xx_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
120 struct cfg80211_scan_request *req);
121int wl18xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
122void wl18xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif);
123int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
124 struct cfg80211_sched_scan_request *req,
125 struct ieee80211_sched_scan_ies *ies);
126void wl18xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
127#endif
diff --git a/drivers/net/wireless/ti/wl18xx/tx.c b/drivers/net/wireless/ti/wl18xx/tx.c
index 5b1fb10d9fd7..57c694396647 100644
--- a/drivers/net/wireless/ti/wl18xx/tx.c
+++ b/drivers/net/wireless/ti/wl18xx/tx.c
@@ -28,6 +28,49 @@
28#include "wl18xx.h" 28#include "wl18xx.h"
29#include "tx.h" 29#include "tx.h"
30 30
31static
32void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif,
33 struct ieee80211_tx_rate *rate)
34{
35 u8 fw_rate = wl->fw_status_2->counters.tx_last_rate;
36
37 if (fw_rate > CONF_HW_RATE_INDEX_MAX) {
38 wl1271_error("last Tx rate invalid: %d", fw_rate);
39 rate->idx = 0;
40 rate->flags = 0;
41 return;
42 }
43
44 if (fw_rate <= CONF_HW_RATE_INDEX_54MBPS) {
45 rate->idx = fw_rate;
46 rate->flags = 0;
47 } else {
48 rate->flags = IEEE80211_TX_RC_MCS;
49 rate->idx = fw_rate - CONF_HW_RATE_INDEX_MCS0;
50
51 /* SGI modifier is counted as a separate rate */
52 if (fw_rate >= CONF_HW_RATE_INDEX_MCS7_SGI)
53 (rate->idx)--;
54 if (fw_rate == CONF_HW_RATE_INDEX_MCS15_SGI)
55 (rate->idx)--;
56
57 /* this also covers the 40Mhz SGI case (= MCS15) */
58 if (fw_rate == CONF_HW_RATE_INDEX_MCS7_SGI ||
59 fw_rate == CONF_HW_RATE_INDEX_MCS15_SGI)
60 rate->flags |= IEEE80211_TX_RC_SHORT_GI;
61
62 if (fw_rate > CONF_HW_RATE_INDEX_MCS7_SGI && vif) {
63 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
64 if (wlvif->channel_type == NL80211_CHAN_HT40MINUS ||
65 wlvif->channel_type == NL80211_CHAN_HT40PLUS) {
66 /* adjustment needed for range 0-7 */
67 rate->idx -= 8;
68 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
69 }
70 }
71 }
72}
73
31static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) 74static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
32{ 75{
33 struct ieee80211_tx_info *info; 76 struct ieee80211_tx_info *info;
@@ -44,7 +87,6 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
44 /* a zero bit indicates Tx success */ 87 /* a zero bit indicates Tx success */
45 tx_success = !(tx_stat_byte & BIT(WL18XX_TX_STATUS_STAT_BIT_IDX)); 88 tx_success = !(tx_stat_byte & BIT(WL18XX_TX_STATUS_STAT_BIT_IDX));
46 89
47
48 skb = wl->tx_frames[id]; 90 skb = wl->tx_frames[id];
49 info = IEEE80211_SKB_CB(skb); 91 info = IEEE80211_SKB_CB(skb);
50 92
@@ -56,11 +98,13 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
56 /* update the TX status info */ 98 /* update the TX status info */
57 if (tx_success && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) 99 if (tx_success && !(info->flags & IEEE80211_TX_CTL_NO_ACK))
58 info->flags |= IEEE80211_TX_STAT_ACK; 100 info->flags |= IEEE80211_TX_STAT_ACK;
101 /*
102 * first pass info->control.vif while it's valid, and then fill out
103 * the info->status structures
104 */
105 wl18xx_get_last_tx_rate(wl, info->control.vif, &info->status.rates[0]);
59 106
60 /* no real data about Tx completion */ 107 info->status.rates[0].count = 1; /* no data about retries */
61 info->status.rates[0].idx = -1;
62 info->status.rates[0].count = 0;
63 info->status.rates[0].flags = 0;
64 info->status.ack_signal = -1; 108 info->status.ack_signal = -1;
65 109
66 if (!tx_success) 110 if (!tx_success)
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index 96a1e438d677..b6739e79efcf 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -26,10 +26,10 @@
26 26
27/* minimum FW required for driver */ 27/* minimum FW required for driver */
28#define WL18XX_CHIP_VER 8 28#define WL18XX_CHIP_VER 8
29#define WL18XX_IFTYPE_VER 2 29#define WL18XX_IFTYPE_VER 5
30#define WL18XX_MAJOR_VER 0 30#define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE
31#define WL18XX_SUBTYPE_VER 0 31#define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE
32#define WL18XX_MINOR_VER 100 32#define WL18XX_MINOR_VER 28
33 33
34#define WL18XX_CMD_MAX_SIZE 740 34#define WL18XX_CMD_MAX_SIZE 740
35 35
@@ -49,8 +49,8 @@ struct wl18xx_priv {
49 /* Index of last released Tx desc in FW */ 49 /* Index of last released Tx desc in FW */
50 u8 last_fw_rls_idx; 50 u8 last_fw_rls_idx;
51 51
52 /* number of VIFs requiring extra spare mem-blocks */ 52 /* number of keys requiring extra spare mem-blocks */
53 int extra_spare_vif_count; 53 int extra_spare_key_count;
54}; 54};
55 55
56#define WL18XX_FW_MAX_TX_STATUS_DESC 33 56#define WL18XX_FW_MAX_TX_STATUS_DESC 33
@@ -68,7 +68,43 @@ struct wl18xx_fw_status_priv {
68 */ 68 */
69 u8 released_tx_desc[WL18XX_FW_MAX_TX_STATUS_DESC]; 69 u8 released_tx_desc[WL18XX_FW_MAX_TX_STATUS_DESC];
70 70
71 u8 padding[2]; 71 /* A bitmap representing the currently suspended links. The suspend
72 * is short lived, for multi-channel Tx requirements.
73 */
74 __le32 link_suspend_bitmap;
75
76 /* packet threshold for an "almost empty" AC,
77 * for Tx schedulng purposes
78 */
79 u8 tx_ac_threshold;
80
81 /* number of packets to queue up for a link in PS */
82 u8 tx_ps_threshold;
83
84 /* number of packet to queue up for a suspended link */
85 u8 tx_suspend_threshold;
86
87 /* Should have less than this number of packets in queue of a slow
88 * link to qualify as high priority link
89 */
90 u8 tx_slow_link_prio_threshold;
91
92 /* Should have less than this number of packets in queue of a fast
93 * link to qualify as high priority link
94 */
95 u8 tx_fast_link_prio_threshold;
96
97 /* Should have less than this number of packets in queue of a slow
98 * link before we stop queuing up packets for it.
99 */
100 u8 tx_slow_stop_threshold;
101
102 /* Should have less than this number of packets in queue of a fast
103 * link before we stop queuing up packets for it.
104 */
105 u8 tx_fast_stop_threshold;
106
107 u8 padding[3];
72}; 108};
73 109
74#define WL18XX_PHY_VERSION_MAX_LEN 20 110#define WL18XX_PHY_VERSION_MAX_LEN 20
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index ce108a736bd0..c79654323396 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -1340,6 +1340,8 @@ out:
1340 kfree(acx); 1340 kfree(acx);
1341 return ret; 1341 return ret;
1342} 1342}
1343EXPORT_SYMBOL_GPL(wl1271_acx_set_ht_capabilities);
1344
1343 1345
1344int wl1271_acx_set_ht_information(struct wl1271 *wl, 1346int wl1271_acx_set_ht_information(struct wl1271 *wl,
1345 struct wl12xx_vif *wlvif, 1347 struct wl12xx_vif *wlvif,
@@ -1433,13 +1435,22 @@ int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
1433 acx->win_size = wl->conf.ht.rx_ba_win_size; 1435 acx->win_size = wl->conf.ht.rx_ba_win_size;
1434 acx->ssn = ssn; 1436 acx->ssn = ssn;
1435 1437
1436 ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx, 1438 ret = wlcore_cmd_configure_failsafe(wl, ACX_BA_SESSION_RX_SETUP, acx,
1437 sizeof(*acx)); 1439 sizeof(*acx),
1440 BIT(CMD_STATUS_NO_RX_BA_SESSION));
1438 if (ret < 0) { 1441 if (ret < 0) {
1439 wl1271_warning("acx ba receiver session failed: %d", ret); 1442 wl1271_warning("acx ba receiver session failed: %d", ret);
1440 goto out; 1443 goto out;
1441 } 1444 }
1442 1445
1446 /* sometimes we can't start the session */
1447 if (ret == CMD_STATUS_NO_RX_BA_SESSION) {
1448 wl1271_warning("no fw rx ba on tid %d", tid_index);
1449 ret = -EBUSY;
1450 goto out;
1451 }
1452
1453 ret = 0;
1443out: 1454out:
1444 kfree(acx); 1455 kfree(acx);
1445 return ret; 1456 return ret;
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index d03215d6b3bd..126536c6a393 100644
--- a/drivers/net/wireless/ti/wlcore/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -1025,7 +1025,6 @@ enum {
1025 ACX_CONFIG_HANGOVER = 0x0042, 1025 ACX_CONFIG_HANGOVER = 0x0042,
1026 ACX_FEATURE_CFG = 0x0043, 1026 ACX_FEATURE_CFG = 0x0043,
1027 ACX_PROTECTION_CFG = 0x0044, 1027 ACX_PROTECTION_CFG = 0x0044,
1028 ACX_CHECKSUM_CONFIG = 0x0045,
1029}; 1028};
1030 1029
1031 1030
diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c
index 375ea574eafb..b58ae5fc1487 100644
--- a/drivers/net/wireless/ti/wlcore/boot.c
+++ b/drivers/net/wireless/ti/wlcore/boot.c
@@ -84,47 +84,57 @@ out:
84static int wlcore_validate_fw_ver(struct wl1271 *wl) 84static int wlcore_validate_fw_ver(struct wl1271 *wl)
85{ 85{
86 unsigned int *fw_ver = wl->chip.fw_ver; 86 unsigned int *fw_ver = wl->chip.fw_ver;
87 unsigned int *min_ver = wl->min_fw_ver; 87 unsigned int *min_ver = (wl->fw_type == WL12XX_FW_TYPE_NORMAL) ?
88 wl->min_sr_fw_ver : wl->min_mr_fw_ver;
89 char min_fw_str[32] = "";
90 int i;
88 91
89 /* the chip must be exactly equal */ 92 /* the chip must be exactly equal */
90 if (min_ver[FW_VER_CHIP] != fw_ver[FW_VER_CHIP]) 93 if ((min_ver[FW_VER_CHIP] != WLCORE_FW_VER_IGNORE) &&
94 (min_ver[FW_VER_CHIP] != fw_ver[FW_VER_CHIP]))
91 goto fail; 95 goto fail;
92 96
93 /* always check the next digit if all previous ones are equal */ 97 /* the firmware type must be equal */
94 98 if ((min_ver[FW_VER_IF_TYPE] != WLCORE_FW_VER_IGNORE) &&
95 if (min_ver[FW_VER_IF_TYPE] < fw_ver[FW_VER_IF_TYPE]) 99 (min_ver[FW_VER_IF_TYPE] != fw_ver[FW_VER_IF_TYPE]))
96 goto out;
97 else if (min_ver[FW_VER_IF_TYPE] > fw_ver[FW_VER_IF_TYPE])
98 goto fail; 100 goto fail;
99 101
100 if (min_ver[FW_VER_MAJOR] < fw_ver[FW_VER_MAJOR]) 102 /* the project number must be equal */
101 goto out; 103 if ((min_ver[FW_VER_SUBTYPE] != WLCORE_FW_VER_IGNORE) &&
102 else if (min_ver[FW_VER_MAJOR] > fw_ver[FW_VER_MAJOR]) 104 (min_ver[FW_VER_SUBTYPE] != fw_ver[FW_VER_SUBTYPE]))
103 goto fail; 105 goto fail;
104 106
105 if (min_ver[FW_VER_SUBTYPE] < fw_ver[FW_VER_SUBTYPE]) 107 /* the API version must be greater or equal */
106 goto out; 108 if ((min_ver[FW_VER_MAJOR] != WLCORE_FW_VER_IGNORE) &&
107 else if (min_ver[FW_VER_SUBTYPE] > fw_ver[FW_VER_SUBTYPE]) 109 (min_ver[FW_VER_MAJOR] > fw_ver[FW_VER_MAJOR]))
108 goto fail; 110 goto fail;
109 111
110 if (min_ver[FW_VER_MINOR] < fw_ver[FW_VER_MINOR]) 112 /* if the API version is equal... */
111 goto out; 113 if (((min_ver[FW_VER_MAJOR] == WLCORE_FW_VER_IGNORE) ||
112 else if (min_ver[FW_VER_MINOR] > fw_ver[FW_VER_MINOR]) 114 (min_ver[FW_VER_MAJOR] == fw_ver[FW_VER_MAJOR])) &&
115 /* ...the minor must be greater or equal */
116 ((min_ver[FW_VER_MINOR] != WLCORE_FW_VER_IGNORE) &&
117 (min_ver[FW_VER_MINOR] > fw_ver[FW_VER_MINOR])))
113 goto fail; 118 goto fail;
114 119
115out:
116 return 0; 120 return 0;
117 121
118fail: 122fail:
119 wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is outdated.\n" 123 for (i = 0; i < NUM_FW_VER; i++)
120 "Please use at least FW %u.%u.%u.%u.%u.\n" 124 if (min_ver[i] == WLCORE_FW_VER_IGNORE)
121 "You can get more information at:\n" 125 snprintf(min_fw_str, sizeof(min_fw_str),
122 "http://wireless.kernel.org/en/users/Drivers/wl12xx", 126 "%s*.", min_fw_str);
127 else
128 snprintf(min_fw_str, sizeof(min_fw_str),
129 "%s%u.", min_fw_str, min_ver[i]);
130
131 wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is invalid.\n"
132 "Please use at least FW %s\n"
133 "You can get the latest firmwares at:\n"
134 "git://github.com/TI-OpenLink/firmwares.git",
123 fw_ver[FW_VER_CHIP], fw_ver[FW_VER_IF_TYPE], 135 fw_ver[FW_VER_CHIP], fw_ver[FW_VER_IF_TYPE],
124 fw_ver[FW_VER_MAJOR], fw_ver[FW_VER_SUBTYPE], 136 fw_ver[FW_VER_MAJOR], fw_ver[FW_VER_SUBTYPE],
125 fw_ver[FW_VER_MINOR], min_ver[FW_VER_CHIP], 137 fw_ver[FW_VER_MINOR], min_fw_str);
126 min_ver[FW_VER_IF_TYPE], min_ver[FW_VER_MAJOR],
127 min_ver[FW_VER_SUBTYPE], min_ver[FW_VER_MINOR]);
128 return -EINVAL; 138 return -EINVAL;
129} 139}
130 140
@@ -491,7 +501,7 @@ int wlcore_boot_run_firmware(struct wl1271 *wl)
491 if (ret < 0) 501 if (ret < 0)
492 return ret; 502 return ret;
493 503
494 wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox); 504 wl->mbox_ptr[1] = wl->mbox_ptr[0] + wl->mbox_size;
495 505
496 wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x", 506 wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x",
497 wl->mbox_ptr[0], wl->mbox_ptr[1]); 507 wl->mbox_ptr[0], wl->mbox_ptr[1]);
@@ -508,23 +518,6 @@ int wlcore_boot_run_firmware(struct wl1271 *wl)
508 */ 518 */
509 519
510 /* unmask required mbox events */ 520 /* unmask required mbox events */
511 wl->event_mask = BSS_LOSE_EVENT_ID |
512 REGAINED_BSS_EVENT_ID |
513 SCAN_COMPLETE_EVENT_ID |
514 ROLE_STOP_COMPLETE_EVENT_ID |
515 RSSI_SNR_TRIGGER_0_EVENT_ID |
516 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
517 SOFT_GEMINI_SENSE_EVENT_ID |
518 PERIODIC_SCAN_REPORT_EVENT_ID |
519 PERIODIC_SCAN_COMPLETE_EVENT_ID |
520 DUMMY_PACKET_EVENT_ID |
521 PEER_REMOVE_COMPLETE_EVENT_ID |
522 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
523 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
524 INACTIVE_STA_EVENT_ID |
525 MAX_TX_RETRY_EVENT_ID |
526 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
527
528 ret = wl1271_event_unmask(wl); 521 ret = wl1271_event_unmask(wl);
529 if (ret < 0) { 522 if (ret < 0) {
530 wl1271_error("EVENT mask setting failed"); 523 wl1271_error("EVENT mask setting failed");
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 27f83f72a93b..1201aca9c89a 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -48,14 +48,15 @@
48 * @id: command id 48 * @id: command id
49 * @buf: buffer containing the command, must work with dma 49 * @buf: buffer containing the command, must work with dma
50 * @len: length of the buffer 50 * @len: length of the buffer
51 * return the cmd status code on success.
51 */ 52 */
52int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, 53static int __wlcore_cmd_send(struct wl1271 *wl, u16 id, void *buf,
53 size_t res_len) 54 size_t len, size_t res_len)
54{ 55{
55 struct wl1271_cmd_header *cmd; 56 struct wl1271_cmd_header *cmd;
56 unsigned long timeout; 57 unsigned long timeout;
57 u32 intr; 58 u32 intr;
58 int ret = 0; 59 int ret;
59 u16 status; 60 u16 status;
60 u16 poll_count = 0; 61 u16 poll_count = 0;
61 62
@@ -71,7 +72,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
71 72
72 ret = wlcore_write(wl, wl->cmd_box_addr, buf, len, false); 73 ret = wlcore_write(wl, wl->cmd_box_addr, buf, len, false);
73 if (ret < 0) 74 if (ret < 0)
74 goto fail; 75 return ret;
75 76
76 /* 77 /*
77 * TODO: we just need this because one bit is in a different 78 * TODO: we just need this because one bit is in a different
@@ -79,19 +80,18 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
79 */ 80 */
80 ret = wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len); 81 ret = wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len);
81 if (ret < 0) 82 if (ret < 0)
82 goto fail; 83 return ret;
83 84
84 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); 85 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
85 86
86 ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr); 87 ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr);
87 if (ret < 0) 88 if (ret < 0)
88 goto fail; 89 return ret;
89 90
90 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { 91 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
91 if (time_after(jiffies, timeout)) { 92 if (time_after(jiffies, timeout)) {
92 wl1271_error("command complete timeout"); 93 wl1271_error("command complete timeout");
93 ret = -ETIMEDOUT; 94 return -ETIMEDOUT;
94 goto fail;
95 } 95 }
96 96
97 poll_count++; 97 poll_count++;
@@ -102,7 +102,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
102 102
103 ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr); 103 ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr);
104 if (ret < 0) 104 if (ret < 0)
105 goto fail; 105 return ret;
106 } 106 }
107 107
108 /* read back the status code of the command */ 108 /* read back the status code of the command */
@@ -111,33 +111,66 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
111 111
112 ret = wlcore_read(wl, wl->cmd_box_addr, cmd, res_len, false); 112 ret = wlcore_read(wl, wl->cmd_box_addr, cmd, res_len, false);
113 if (ret < 0) 113 if (ret < 0)
114 goto fail; 114 return ret;
115 115
116 status = le16_to_cpu(cmd->status); 116 status = le16_to_cpu(cmd->status);
117 if (status != CMD_STATUS_SUCCESS) {
118 wl1271_error("command execute failure %d", status);
119 ret = -EIO;
120 goto fail;
121 }
122 117
123 ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK, 118 ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK,
124 WL1271_ACX_INTR_CMD_COMPLETE); 119 WL1271_ACX_INTR_CMD_COMPLETE);
125 if (ret < 0) 120 if (ret < 0)
121 return ret;
122
123 return status;
124}
125
126/*
127 * send command to fw and return cmd status on success
128 * valid_rets contains a bitmap of allowed error codes
129 */
130int wlcore_cmd_send_failsafe(struct wl1271 *wl, u16 id, void *buf, size_t len,
131 size_t res_len, unsigned long valid_rets)
132{
133 int ret = __wlcore_cmd_send(wl, id, buf, len, res_len);
134
135 if (ret < 0)
126 goto fail; 136 goto fail;
127 137
128 return 0; 138 /* success is always a valid status */
139 valid_rets |= BIT(CMD_STATUS_SUCCESS);
129 140
141 if (ret >= MAX_COMMAND_STATUS ||
142 !test_bit(ret, &valid_rets)) {
143 wl1271_error("command execute failure %d", ret);
144 ret = -EIO;
145 goto fail;
146 }
147 return ret;
130fail: 148fail:
131 wl12xx_queue_recovery_work(wl); 149 wl12xx_queue_recovery_work(wl);
132 return ret; 150 return ret;
133} 151}
152EXPORT_SYMBOL_GPL(wl1271_cmd_send);
153
154/*
155 * wrapper for wlcore_cmd_send that accept only CMD_STATUS_SUCCESS
156 * return 0 on success.
157 */
158int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
159 size_t res_len)
160{
161 int ret = wlcore_cmd_send_failsafe(wl, id, buf, len, res_len, 0);
162
163 if (ret < 0)
164 return ret;
165 return 0;
166}
134 167
135/* 168/*
136 * Poll the mailbox event field until any of the bits in the mask is set or a 169 * Poll the mailbox event field until any of the bits in the mask is set or a
137 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) 170 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
138 */ 171 */
139static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, 172int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
140 u32 mask, bool *timeout) 173 u32 mask, bool *timeout)
141{ 174{
142 u32 *events_vector; 175 u32 *events_vector;
143 u32 event; 176 u32 event;
@@ -187,20 +220,7 @@ out:
187 kfree(events_vector); 220 kfree(events_vector);
188 return ret; 221 return ret;
189} 222}
190 223EXPORT_SYMBOL_GPL(wlcore_cmd_wait_for_event_or_timeout);
191static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
192{
193 int ret;
194 bool timeout = false;
195
196 ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask, &timeout);
197 if (ret != 0 || timeout) {
198 wl12xx_queue_recovery_work(wl);
199 return ret;
200 }
201
202 return 0;
203}
204 224
205int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, 225int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type,
206 u8 *role_id) 226 u8 *role_id)
@@ -278,6 +298,16 @@ out:
278 return ret; 298 return ret;
279} 299}
280 300
301static int wlcore_get_new_session_id(struct wl1271 *wl, u8 hlid)
302{
303 if (wl->session_ids[hlid] >= SESSION_COUNTER_MAX)
304 wl->session_ids[hlid] = 0;
305
306 wl->session_ids[hlid]++;
307
308 return wl->session_ids[hlid];
309}
310
281int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) 311int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
282{ 312{
283 unsigned long flags; 313 unsigned long flags;
@@ -285,12 +315,21 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
285 if (link >= WL12XX_MAX_LINKS) 315 if (link >= WL12XX_MAX_LINKS)
286 return -EBUSY; 316 return -EBUSY;
287 317
318 wl->session_ids[link] = wlcore_get_new_session_id(wl, link);
319
288 /* these bits are used by op_tx */ 320 /* these bits are used by op_tx */
289 spin_lock_irqsave(&wl->wl_lock, flags); 321 spin_lock_irqsave(&wl->wl_lock, flags);
290 __set_bit(link, wl->links_map); 322 __set_bit(link, wl->links_map);
291 __set_bit(link, wlvif->links_map); 323 __set_bit(link, wlvif->links_map);
292 spin_unlock_irqrestore(&wl->wl_lock, flags); 324 spin_unlock_irqrestore(&wl->wl_lock, flags);
325
326 /* take the last "freed packets" value from the current FW status */
327 wl->links[link].prev_freed_pkts =
328 wl->fw_status_2->counters.tx_lnk_free_pkts[link];
329 wl->links[link].wlvif = wlvif;
293 *hlid = link; 330 *hlid = link;
331
332 wl->active_link_count++;
294 return 0; 333 return 0;
295} 334}
296 335
@@ -307,24 +346,21 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
307 __clear_bit(*hlid, wlvif->links_map); 346 __clear_bit(*hlid, wlvif->links_map);
308 spin_unlock_irqrestore(&wl->wl_lock, flags); 347 spin_unlock_irqrestore(&wl->wl_lock, flags);
309 348
349 wl->links[*hlid].allocated_pkts = 0;
350 wl->links[*hlid].prev_freed_pkts = 0;
351 wl->links[*hlid].ba_bitmap = 0;
352 memset(wl->links[*hlid].addr, 0, ETH_ALEN);
353
310 /* 354 /*
311 * At this point op_tx() will not add more packets to the queues. We 355 * At this point op_tx() will not add more packets to the queues. We
312 * can purge them. 356 * can purge them.
313 */ 357 */
314 wl1271_tx_reset_link_queues(wl, *hlid); 358 wl1271_tx_reset_link_queues(wl, *hlid);
359 wl->links[*hlid].wlvif = NULL;
315 360
316 *hlid = WL12XX_INVALID_LINK_ID; 361 *hlid = WL12XX_INVALID_LINK_ID;
317} 362 wl->active_link_count--;
318 363 WARN_ON_ONCE(wl->active_link_count < 0);
319static int wl12xx_get_new_session_id(struct wl1271 *wl,
320 struct wl12xx_vif *wlvif)
321{
322 if (wlvif->session_counter >= SESSION_COUNTER_MAX)
323 wlvif->session_counter = 0;
324
325 wlvif->session_counter++;
326
327 return wlvif->session_counter;
328} 364}
329 365
330static u8 wlcore_get_native_channel_type(u8 nl_channel_type) 366static u8 wlcore_get_native_channel_type(u8 nl_channel_type)
@@ -345,7 +381,9 @@ static u8 wlcore_get_native_channel_type(u8 nl_channel_type)
345} 381}
346 382
347static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, 383static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
348 struct wl12xx_vif *wlvif) 384 struct wl12xx_vif *wlvif,
385 enum ieee80211_band band,
386 int channel)
349{ 387{
350 struct wl12xx_cmd_role_start *cmd; 388 struct wl12xx_cmd_role_start *cmd;
351 int ret; 389 int ret;
@@ -359,9 +397,9 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
359 wl1271_debug(DEBUG_CMD, "cmd role start dev %d", wlvif->dev_role_id); 397 wl1271_debug(DEBUG_CMD, "cmd role start dev %d", wlvif->dev_role_id);
360 398
361 cmd->role_id = wlvif->dev_role_id; 399 cmd->role_id = wlvif->dev_role_id;
362 if (wlvif->band == IEEE80211_BAND_5GHZ) 400 if (band == IEEE80211_BAND_5GHZ)
363 cmd->band = WLCORE_BAND_5GHZ; 401 cmd->band = WLCORE_BAND_5GHZ;
364 cmd->channel = wlvif->channel; 402 cmd->channel = channel;
365 403
366 if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) { 404 if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) {
367 ret = wl12xx_allocate_link(wl, wlvif, &wlvif->dev_hlid); 405 ret = wl12xx_allocate_link(wl, wlvif, &wlvif->dev_hlid);
@@ -369,7 +407,7 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
369 goto out_free; 407 goto out_free;
370 } 408 }
371 cmd->device.hlid = wlvif->dev_hlid; 409 cmd->device.hlid = wlvif->dev_hlid;
372 cmd->device.session = wl12xx_get_new_session_id(wl, wlvif); 410 cmd->device.session = wl->session_ids[wlvif->dev_hlid];
373 411
374 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d", 412 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d",
375 cmd->role_id, cmd->device.hlid, cmd->device.session); 413 cmd->role_id, cmd->device.hlid, cmd->device.session);
@@ -420,12 +458,6 @@ static int wl12xx_cmd_role_stop_dev(struct wl1271 *wl,
420 goto out_free; 458 goto out_free;
421 } 459 }
422 460
423 ret = wl1271_cmd_wait_for_event(wl, ROLE_STOP_COMPLETE_EVENT_ID);
424 if (ret < 0) {
425 wl1271_error("cmd role stop dev event completion error");
426 goto out_free;
427 }
428
429 wl12xx_free_link(wl, wlvif, &wlvif->dev_hlid); 461 wl12xx_free_link(wl, wlvif, &wlvif->dev_hlid);
430 462
431out_free: 463out_free:
@@ -439,6 +471,7 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
439{ 471{
440 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 472 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
441 struct wl12xx_cmd_role_start *cmd; 473 struct wl12xx_cmd_role_start *cmd;
474 u32 supported_rates;
442 int ret; 475 int ret;
443 476
444 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 477 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -459,7 +492,14 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
459 cmd->sta.ssid_len = wlvif->ssid_len; 492 cmd->sta.ssid_len = wlvif->ssid_len;
460 memcpy(cmd->sta.ssid, wlvif->ssid, wlvif->ssid_len); 493 memcpy(cmd->sta.ssid, wlvif->ssid, wlvif->ssid_len);
461 memcpy(cmd->sta.bssid, vif->bss_conf.bssid, ETH_ALEN); 494 memcpy(cmd->sta.bssid, vif->bss_conf.bssid, ETH_ALEN);
462 cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set); 495
496 supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES |
497 wlcore_hw_sta_get_ap_rate_mask(wl, wlvif);
498 if (wlvif->p2p)
499 supported_rates &= ~CONF_TX_CCK_RATES;
500
501 cmd->sta.local_rates = cpu_to_le32(supported_rates);
502
463 cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type); 503 cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type);
464 504
465 if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) { 505 if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) {
@@ -468,7 +508,11 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
468 goto out_free; 508 goto out_free;
469 } 509 }
470 cmd->sta.hlid = wlvif->sta.hlid; 510 cmd->sta.hlid = wlvif->sta.hlid;
471 cmd->sta.session = wl12xx_get_new_session_id(wl, wlvif); 511 cmd->sta.session = wl->session_ids[wlvif->sta.hlid];
512 /*
513 * We don't have the correct remote rates in this stage. the rates
514 * will be reconfigured later, after authorization.
515 */
472 cmd->sta.remote_rates = cpu_to_le32(wlvif->rate_set); 516 cmd->sta.remote_rates = cpu_to_le32(wlvif->rate_set);
473 517
474 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d " 518 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d "
@@ -482,6 +526,7 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
482 goto err_hlid; 526 goto err_hlid;
483 } 527 }
484 528
529 wlvif->sta.role_chan_type = wlvif->channel_type;
485 goto out_free; 530 goto out_free;
486 531
487err_hlid: 532err_hlid:
@@ -500,7 +545,6 @@ int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
500{ 545{
501 struct wl12xx_cmd_role_stop *cmd; 546 struct wl12xx_cmd_role_stop *cmd;
502 int ret; 547 int ret;
503 bool timeout = false;
504 548
505 if (WARN_ON(wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)) 549 if (WARN_ON(wlvif->sta.hlid == WL12XX_INVALID_LINK_ID))
506 return -EINVAL; 550 return -EINVAL;
@@ -523,17 +567,6 @@ int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
523 goto out_free; 567 goto out_free;
524 } 568 }
525 569
526 /*
527 * Sometimes the firmware doesn't send this event, so we just
528 * time out without failing. Queue recovery for other
529 * failures.
530 */
531 ret = wl1271_cmd_wait_for_event_or_timeout(wl,
532 ROLE_STOP_COMPLETE_EVENT_ID,
533 &timeout);
534 if (ret)
535 wl12xx_queue_recovery_work(wl);
536
537 wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid); 570 wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid);
538 571
539out_free: 572out_free:
@@ -579,12 +612,15 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
579 cmd->ap.bss_index = WL1271_AP_BSS_INDEX; 612 cmd->ap.bss_index = WL1271_AP_BSS_INDEX;
580 cmd->ap.global_hlid = wlvif->ap.global_hlid; 613 cmd->ap.global_hlid = wlvif->ap.global_hlid;
581 cmd->ap.broadcast_hlid = wlvif->ap.bcast_hlid; 614 cmd->ap.broadcast_hlid = wlvif->ap.bcast_hlid;
615 cmd->ap.global_session_id = wl->session_ids[wlvif->ap.global_hlid];
616 cmd->ap.bcast_session_id = wl->session_ids[wlvif->ap.bcast_hlid];
582 cmd->ap.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set); 617 cmd->ap.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
583 cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int); 618 cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int);
584 cmd->ap.dtim_interval = bss_conf->dtim_period; 619 cmd->ap.dtim_interval = bss_conf->dtim_period;
585 cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP; 620 cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
586 /* FIXME: Change when adding DFS */ 621 /* FIXME: Change when adding DFS */
587 cmd->ap.reset_tsf = 1; /* By default reset AP TSF */ 622 cmd->ap.reset_tsf = 1; /* By default reset AP TSF */
623 cmd->ap.wmm = wlvif->wmm_enabled;
588 cmd->channel = wlvif->channel; 624 cmd->channel = wlvif->channel;
589 cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type); 625 cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type);
590 626
@@ -599,8 +635,10 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
599 memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len); 635 memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len);
600 } 636 }
601 637
602 supported_rates = CONF_TX_AP_ENABLED_RATES | CONF_TX_MCS_RATES | 638 supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES |
603 wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif); 639 wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif);
640 if (wlvif->p2p)
641 supported_rates &= ~CONF_TX_CCK_RATES;
604 642
605 wl1271_debug(DEBUG_CMD, "cmd role start ap with supported_rates 0x%08x", 643 wl1271_debug(DEBUG_CMD, "cmd role start ap with supported_rates 0x%08x",
606 supported_rates); 644 supported_rates);
@@ -799,8 +837,11 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
799 * @id: acx id 837 * @id: acx id
800 * @buf: buffer containing acx, including all headers, must work with dma 838 * @buf: buffer containing acx, including all headers, must work with dma
801 * @len: length of buf 839 * @len: length of buf
840 * @valid_rets: bitmap of valid cmd status codes (i.e. return values).
841 * return the cmd status on success.
802 */ 842 */
803int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len) 843int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf,
844 size_t len, unsigned long valid_rets)
804{ 845{
805 struct acx_header *acx = buf; 846 struct acx_header *acx = buf;
806 int ret; 847 int ret;
@@ -812,12 +853,26 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
812 /* payload length, does not include any headers */ 853 /* payload length, does not include any headers */
813 acx->len = cpu_to_le16(len - sizeof(*acx)); 854 acx->len = cpu_to_le16(len - sizeof(*acx));
814 855
815 ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len, 0); 856 ret = wlcore_cmd_send_failsafe(wl, CMD_CONFIGURE, acx, len, 0,
857 valid_rets);
816 if (ret < 0) { 858 if (ret < 0) {
817 wl1271_warning("CONFIGURE command NOK"); 859 wl1271_warning("CONFIGURE command NOK");
818 return ret; 860 return ret;
819 } 861 }
820 862
863 return ret;
864}
865
866/*
867 * wrapper for wlcore_cmd_configure that accepts only success status.
868 * return 0 on success
869 */
870int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
871{
872 int ret = wlcore_cmd_configure_failsafe(wl, id, buf, len, 0);
873
874 if (ret < 0)
875 return ret;
821 return 0; 876 return 0;
822} 877}
823EXPORT_SYMBOL_GPL(wl1271_cmd_configure); 878EXPORT_SYMBOL_GPL(wl1271_cmd_configure);
@@ -1034,8 +1089,8 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1034 struct sk_buff *skb; 1089 struct sk_buff *skb;
1035 int ret; 1090 int ret;
1036 u32 rate; 1091 u32 rate;
1037 u16 template_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4; 1092 u16 template_id_2_4 = wl->scan_templ_id_2_4;
1038 u16 template_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5; 1093 u16 template_id_5 = wl->scan_templ_id_5;
1039 1094
1040 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len, 1095 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
1041 ie_len); 1096 ie_len);
@@ -1048,10 +1103,10 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1048 1103
1049 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); 1104 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
1050 1105
1051 if (!sched_scan && 1106 if (sched_scan &&
1052 (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) { 1107 (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) {
1053 template_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4; 1108 template_id_2_4 = wl->sched_scan_templ_id_2_4;
1054 template_id_5 = CMD_TEMPL_APP_PROBE_REQ_5; 1109 template_id_5 = wl->sched_scan_templ_id_5;
1055 } 1110 }
1056 1111
1057 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]); 1112 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
@@ -1068,6 +1123,7 @@ out:
1068 dev_kfree_skb(skb); 1123 dev_kfree_skb(skb);
1069 return ret; 1124 return ret;
1070} 1125}
1126EXPORT_SYMBOL_GPL(wl12xx_cmd_build_probe_req);
1071 1127
1072struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, 1128struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
1073 struct wl12xx_vif *wlvif, 1129 struct wl12xx_vif *wlvif,
@@ -1379,7 +1435,8 @@ out:
1379 return ret; 1435 return ret;
1380} 1436}
1381 1437
1382int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid) 1438int wl12xx_cmd_set_peer_state(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1439 u8 hlid)
1383{ 1440{
1384 struct wl12xx_cmd_set_peer_state *cmd; 1441 struct wl12xx_cmd_set_peer_state *cmd;
1385 int ret = 0; 1442 int ret = 0;
@@ -1395,6 +1452,10 @@ int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid)
1395 cmd->hlid = hlid; 1452 cmd->hlid = hlid;
1396 cmd->state = WL1271_CMD_STA_STATE_CONNECTED; 1453 cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
1397 1454
1455 /* wmm param is valid only for station role */
1456 if (wlvif->bss_type == BSS_TYPE_STA_BSS)
1457 cmd->wmm = wlvif->wmm_enabled;
1458
1398 ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0); 1459 ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0);
1399 if (ret < 0) { 1460 if (ret < 0) {
1400 wl1271_error("failed to send set peer state command"); 1461 wl1271_error("failed to send set peer state command");
@@ -1429,6 +1490,7 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1429 cmd->hlid = hlid; 1490 cmd->hlid = hlid;
1430 cmd->sp_len = sta->max_sp; 1491 cmd->sp_len = sta->max_sp;
1431 cmd->wmm = sta->wme ? 1 : 0; 1492 cmd->wmm = sta->wme ? 1 : 0;
1493 cmd->session_id = wl->session_ids[hlid];
1432 1494
1433 for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++) 1495 for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++)
1434 if (sta->wme && (sta->uapsd_queues & BIT(i))) 1496 if (sta->wme && (sta->uapsd_queues & BIT(i)))
@@ -1490,9 +1552,10 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid)
1490 goto out_free; 1552 goto out_free;
1491 } 1553 }
1492 1554
1493 ret = wl1271_cmd_wait_for_event_or_timeout(wl, 1555 ret = wl->ops->wait_for_event(wl,
1494 PEER_REMOVE_COMPLETE_EVENT_ID, 1556 WLCORE_EVENT_PEER_REMOVE_COMPLETE,
1495 &timeout); 1557 &timeout);
1558
1496 /* 1559 /*
1497 * We are ok with a timeout here. The event is sometimes not sent 1560 * We are ok with a timeout here. The event is sometimes not sent
1498 * due to a firmware bug. In case of another error (like SDIO timeout) 1561 * due to a firmware bug. In case of another error (like SDIO timeout)
@@ -1508,6 +1571,131 @@ out:
1508 return ret; 1571 return ret;
1509} 1572}
1510 1573
1574static int wlcore_get_reg_conf_ch_idx(enum ieee80211_band band, u16 ch)
1575{
1576 int idx = -1;
1577
1578 switch (band) {
1579 case IEEE80211_BAND_5GHZ:
1580 if (ch >= 8 && ch <= 16)
1581 idx = ((ch-8)/4 + 18);
1582 else if (ch >= 34 && ch <= 64)
1583 idx = ((ch-34)/2 + 3 + 18);
1584 else if (ch >= 100 && ch <= 140)
1585 idx = ((ch-100)/4 + 15 + 18);
1586 else if (ch >= 149 && ch <= 165)
1587 idx = ((ch-149)/4 + 26 + 18);
1588 else
1589 idx = -1;
1590 break;
1591 case IEEE80211_BAND_2GHZ:
1592 if (ch >= 1 && ch <= 14)
1593 idx = ch - 1;
1594 else
1595 idx = -1;
1596 break;
1597 default:
1598 wl1271_error("get reg conf ch idx - unknown band: %d",
1599 (int)band);
1600 }
1601
1602 return idx;
1603}
1604
1605void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel,
1606 enum ieee80211_band band)
1607{
1608 int ch_bit_idx = 0;
1609
1610 if (!(wl->quirks & WLCORE_QUIRK_REGDOMAIN_CONF))
1611 return;
1612
1613 ch_bit_idx = wlcore_get_reg_conf_ch_idx(band, channel);
1614
1615 if (ch_bit_idx > 0 && ch_bit_idx <= WL1271_MAX_CHANNELS)
1616 set_bit(ch_bit_idx, (long *)wl->reg_ch_conf_pending);
1617}
1618
1619int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
1620{
1621 struct wl12xx_cmd_regdomain_dfs_config *cmd = NULL;
1622 int ret = 0, i, b, ch_bit_idx;
1623 struct ieee80211_channel *channel;
1624 u32 tmp_ch_bitmap[2];
1625 u16 ch;
1626 struct wiphy *wiphy = wl->hw->wiphy;
1627 struct ieee80211_supported_band *band;
1628 bool timeout = false;
1629
1630 if (!(wl->quirks & WLCORE_QUIRK_REGDOMAIN_CONF))
1631 return 0;
1632
1633 wl1271_debug(DEBUG_CMD, "cmd reg domain config");
1634
1635 memset(tmp_ch_bitmap, 0, sizeof(tmp_ch_bitmap));
1636
1637 for (b = IEEE80211_BAND_2GHZ; b <= IEEE80211_BAND_5GHZ; b++) {
1638 band = wiphy->bands[b];
1639 for (i = 0; i < band->n_channels; i++) {
1640 channel = &band->channels[i];
1641 ch = channel->hw_value;
1642
1643 if (channel->flags & (IEEE80211_CHAN_DISABLED |
1644 IEEE80211_CHAN_RADAR |
1645 IEEE80211_CHAN_PASSIVE_SCAN))
1646 continue;
1647
1648 ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch);
1649 if (ch_bit_idx < 0)
1650 continue;
1651
1652 set_bit(ch_bit_idx, (long *)tmp_ch_bitmap);
1653 }
1654 }
1655
1656 tmp_ch_bitmap[0] |= wl->reg_ch_conf_pending[0];
1657 tmp_ch_bitmap[1] |= wl->reg_ch_conf_pending[1];
1658
1659 if (!memcmp(tmp_ch_bitmap, wl->reg_ch_conf_last, sizeof(tmp_ch_bitmap)))
1660 goto out;
1661
1662 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1663 if (!cmd) {
1664 ret = -ENOMEM;
1665 goto out;
1666 }
1667
1668 cmd->ch_bit_map1 = cpu_to_le32(tmp_ch_bitmap[0]);
1669 cmd->ch_bit_map2 = cpu_to_le32(tmp_ch_bitmap[1]);
1670
1671 wl1271_debug(DEBUG_CMD,
1672 "cmd reg domain bitmap1: 0x%08x, bitmap2: 0x%08x",
1673 cmd->ch_bit_map1, cmd->ch_bit_map2);
1674
1675 ret = wl1271_cmd_send(wl, CMD_DFS_CHANNEL_CONFIG, cmd, sizeof(*cmd), 0);
1676 if (ret < 0) {
1677 wl1271_error("failed to send reg domain dfs config");
1678 goto out;
1679 }
1680
1681 ret = wl->ops->wait_for_event(wl,
1682 WLCORE_EVENT_DFS_CONFIG_COMPLETE,
1683 &timeout);
1684 if (ret < 0 || timeout) {
1685 wl1271_error("reg domain conf %serror",
1686 timeout ? "completion " : "");
1687 ret = timeout ? -ETIMEDOUT : ret;
1688 goto out;
1689 }
1690
1691 memcpy(wl->reg_ch_conf_last, tmp_ch_bitmap, sizeof(tmp_ch_bitmap));
1692 memset(wl->reg_ch_conf_pending, 0, sizeof(wl->reg_ch_conf_pending));
1693
1694out:
1695 kfree(cmd);
1696 return ret;
1697}
1698
1511int wl12xx_cmd_config_fwlog(struct wl1271 *wl) 1699int wl12xx_cmd_config_fwlog(struct wl1271 *wl)
1512{ 1700{
1513 struct wl12xx_cmd_config_fwlog *cmd; 1701 struct wl12xx_cmd_config_fwlog *cmd;
@@ -1593,12 +1781,12 @@ out:
1593} 1781}
1594 1782
1595static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1783static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1596 u8 role_id) 1784 u8 role_id, enum ieee80211_band band, u8 channel)
1597{ 1785{
1598 struct wl12xx_cmd_roc *cmd; 1786 struct wl12xx_cmd_roc *cmd;
1599 int ret = 0; 1787 int ret = 0;
1600 1788
1601 wl1271_debug(DEBUG_CMD, "cmd roc %d (%d)", wlvif->channel, role_id); 1789 wl1271_debug(DEBUG_CMD, "cmd roc %d (%d)", channel, role_id);
1602 1790
1603 if (WARN_ON(role_id == WL12XX_INVALID_ROLE_ID)) 1791 if (WARN_ON(role_id == WL12XX_INVALID_ROLE_ID))
1604 return -EINVAL; 1792 return -EINVAL;
@@ -1610,8 +1798,8 @@ static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1610 } 1798 }
1611 1799
1612 cmd->role_id = role_id; 1800 cmd->role_id = role_id;
1613 cmd->channel = wlvif->channel; 1801 cmd->channel = channel;
1614 switch (wlvif->band) { 1802 switch (band) {
1615 case IEEE80211_BAND_2GHZ: 1803 case IEEE80211_BAND_2GHZ:
1616 cmd->band = WLCORE_BAND_2_4GHZ; 1804 cmd->band = WLCORE_BAND_2_4GHZ;
1617 break; 1805 break;
@@ -1666,30 +1854,18 @@ out:
1666 return ret; 1854 return ret;
1667} 1855}
1668 1856
1669int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id) 1857int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id,
1858 enum ieee80211_band band, u8 channel)
1670{ 1859{
1671 int ret = 0; 1860 int ret = 0;
1672 bool is_first_roc;
1673 1861
1674 if (WARN_ON(test_bit(role_id, wl->roc_map))) 1862 if (WARN_ON(test_bit(role_id, wl->roc_map)))
1675 return 0; 1863 return 0;
1676 1864
1677 is_first_roc = (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= 1865 ret = wl12xx_cmd_roc(wl, wlvif, role_id, band, channel);
1678 WL12XX_MAX_ROLES);
1679
1680 ret = wl12xx_cmd_roc(wl, wlvif, role_id);
1681 if (ret < 0) 1866 if (ret < 0)
1682 goto out; 1867 goto out;
1683 1868
1684 if (is_first_roc) {
1685 ret = wl1271_cmd_wait_for_event(wl,
1686 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID);
1687 if (ret < 0) {
1688 wl1271_error("cmd roc event completion error");
1689 goto out;
1690 }
1691 }
1692
1693 __set_bit(role_id, wl->roc_map); 1869 __set_bit(role_id, wl->roc_map);
1694out: 1870out:
1695 return ret; 1871 return ret;
@@ -1719,43 +1895,7 @@ out:
1719 return ret; 1895 return ret;
1720} 1896}
1721 1897
1722int wl12xx_cmd_channel_switch(struct wl1271 *wl, 1898int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1723 struct wl12xx_vif *wlvif,
1724 struct ieee80211_channel_switch *ch_switch)
1725{
1726 struct wl12xx_cmd_channel_switch *cmd;
1727 int ret;
1728
1729 wl1271_debug(DEBUG_ACX, "cmd channel switch");
1730
1731 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1732 if (!cmd) {
1733 ret = -ENOMEM;
1734 goto out;
1735 }
1736
1737 cmd->role_id = wlvif->role_id;
1738 cmd->channel = ch_switch->channel->hw_value;
1739 cmd->switch_time = ch_switch->count;
1740 cmd->stop_tx = ch_switch->block_tx;
1741
1742 /* FIXME: control from mac80211 in the future */
1743 cmd->post_switch_tx_disable = 0; /* Enable TX on the target channel */
1744
1745 ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
1746 if (ret < 0) {
1747 wl1271_error("failed to send channel switch command");
1748 goto out_free;
1749 }
1750
1751out_free:
1752 kfree(cmd);
1753
1754out:
1755 return ret;
1756}
1757
1758int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl)
1759{ 1899{
1760 struct wl12xx_cmd_stop_channel_switch *cmd; 1900 struct wl12xx_cmd_stop_channel_switch *cmd;
1761 int ret; 1901 int ret;
@@ -1768,6 +1908,8 @@ int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl)
1768 goto out; 1908 goto out;
1769 } 1909 }
1770 1910
1911 cmd->role_id = wlvif->role_id;
1912
1771 ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0); 1913 ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0);
1772 if (ret < 0) { 1914 if (ret < 0) {
1773 wl1271_error("failed to stop channel switch command"); 1915 wl1271_error("failed to stop channel switch command");
@@ -1782,7 +1924,8 @@ out:
1782} 1924}
1783 1925
1784/* start dev role and roc on its channel */ 1926/* start dev role and roc on its channel */
1785int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) 1927int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1928 enum ieee80211_band band, int channel)
1786{ 1929{
1787 int ret; 1930 int ret;
1788 1931
@@ -1797,11 +1940,11 @@ int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1797 if (ret < 0) 1940 if (ret < 0)
1798 goto out; 1941 goto out;
1799 1942
1800 ret = wl12xx_cmd_role_start_dev(wl, wlvif); 1943 ret = wl12xx_cmd_role_start_dev(wl, wlvif, band, channel);
1801 if (ret < 0) 1944 if (ret < 0)
1802 goto out_disable; 1945 goto out_disable;
1803 1946
1804 ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id); 1947 ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id, band, channel);
1805 if (ret < 0) 1948 if (ret < 0)
1806 goto out_stop; 1949 goto out_stop;
1807 1950
diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h
index 2409f3d71f63..fd34123047cd 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.h
+++ b/drivers/net/wireless/ti/wlcore/cmd.h
@@ -31,6 +31,8 @@ struct acx_header;
31 31
32int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, 32int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
33 size_t res_len); 33 size_t res_len);
34int wlcore_cmd_send_failsafe(struct wl1271 *wl, u16 id, void *buf, size_t len,
35 size_t res_len, unsigned long valid_rets);
34int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, 36int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type,
35 u8 *role_id); 37 u8 *role_id);
36int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id); 38int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id);
@@ -39,11 +41,14 @@ int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif);
39int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif); 41int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif);
40int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif); 42int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif);
41int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif); 43int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif);
42int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif); 44int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif,
45 enum ieee80211_band band, int channel);
43int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif); 46int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif);
44int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); 47int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
45int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); 48int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
46int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); 49int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
50int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf,
51 size_t len, unsigned long valid_rets);
47int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); 52int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
48int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, 53int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
49 u8 ps_mode, u16 auto_ps_timeout); 54 u8 ps_mode, u16 auto_ps_timeout);
@@ -75,22 +80,30 @@ int wl1271_cmd_set_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
75 u16 action, u8 id, u8 key_type, 80 u16 action, u8 id, u8 key_type,
76 u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32, 81 u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32,
77 u16 tx_seq_16); 82 u16 tx_seq_16);
78int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid); 83int wl12xx_cmd_set_peer_state(struct wl1271 *wl, struct wl12xx_vif *wlvif,
79int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id); 84 u8 hlid);
85int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id,
86 enum ieee80211_band band, u8 channel);
80int wl12xx_croc(struct wl1271 *wl, u8 role_id); 87int wl12xx_croc(struct wl1271 *wl, u8 role_id);
81int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, 88int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
82 struct ieee80211_sta *sta, u8 hlid); 89 struct ieee80211_sta *sta, u8 hlid);
83int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid); 90int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid);
91void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel,
92 enum ieee80211_band band);
93int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl);
84int wl12xx_cmd_config_fwlog(struct wl1271 *wl); 94int wl12xx_cmd_config_fwlog(struct wl1271 *wl);
85int wl12xx_cmd_start_fwlog(struct wl1271 *wl); 95int wl12xx_cmd_start_fwlog(struct wl1271 *wl);
86int wl12xx_cmd_stop_fwlog(struct wl1271 *wl); 96int wl12xx_cmd_stop_fwlog(struct wl1271 *wl);
87int wl12xx_cmd_channel_switch(struct wl1271 *wl, 97int wl12xx_cmd_channel_switch(struct wl1271 *wl,
88 struct wl12xx_vif *wlvif, 98 struct wl12xx_vif *wlvif,
89 struct ieee80211_channel_switch *ch_switch); 99 struct ieee80211_channel_switch *ch_switch);
90int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl); 100int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl,
101 struct wl12xx_vif *wlvif);
91int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, 102int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif,
92 u8 *hlid); 103 u8 *hlid);
93void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid); 104void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid);
105int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
106 u32 mask, bool *timeout);
94 107
95enum wl1271_commands { 108enum wl1271_commands {
96 CMD_INTERROGATE = 1, /* use this to read information elements */ 109 CMD_INTERROGATE = 1, /* use this to read information elements */
@@ -149,8 +162,11 @@ enum wl1271_commands {
149 CMD_WFD_START_DISCOVERY = 45, 162 CMD_WFD_START_DISCOVERY = 45,
150 CMD_WFD_STOP_DISCOVERY = 46, 163 CMD_WFD_STOP_DISCOVERY = 46,
151 CMD_WFD_ATTRIBUTE_CONFIG = 47, 164 CMD_WFD_ATTRIBUTE_CONFIG = 47,
152 CMD_NOP = 48, 165 CMD_GENERIC_CFG = 48,
153 CMD_LAST_COMMAND, 166 CMD_NOP = 49,
167
168 /* start of 18xx specific commands */
169 CMD_DFS_CHANNEL_CONFIG = 60,
154 170
155 MAX_COMMAND_ID = 0xFFFF, 171 MAX_COMMAND_ID = 0xFFFF,
156}; 172};
@@ -167,8 +183,8 @@ enum cmd_templ {
167 CMD_TEMPL_PS_POLL, 183 CMD_TEMPL_PS_POLL,
168 CMD_TEMPL_KLV, 184 CMD_TEMPL_KLV,
169 CMD_TEMPL_DISCONNECT, 185 CMD_TEMPL_DISCONNECT,
170 CMD_TEMPL_APP_PROBE_REQ_2_4, 186 CMD_TEMPL_APP_PROBE_REQ_2_4_LEGACY,
171 CMD_TEMPL_APP_PROBE_REQ_5, 187 CMD_TEMPL_APP_PROBE_REQ_5_LEGACY,
172 CMD_TEMPL_BAR, /* for firmware internal use only */ 188 CMD_TEMPL_BAR, /* for firmware internal use only */
173 CMD_TEMPL_CTS, /* 189 CMD_TEMPL_CTS, /*
174 * For CTS-to-self (FastCTS) mechanism 190 * For CTS-to-self (FastCTS) mechanism
@@ -179,6 +195,8 @@ enum cmd_templ {
179 CMD_TEMPL_DEAUTH_AP, 195 CMD_TEMPL_DEAUTH_AP,
180 CMD_TEMPL_TEMPORARY, 196 CMD_TEMPL_TEMPORARY,
181 CMD_TEMPL_LINK_MEASUREMENT_REPORT, 197 CMD_TEMPL_LINK_MEASUREMENT_REPORT,
198 CMD_TEMPL_PROBE_REQ_2_4_PERIODIC,
199 CMD_TEMPL_PROBE_REQ_5_PERIODIC,
182 200
183 CMD_TEMPL_MAX = 0xff 201 CMD_TEMPL_MAX = 0xff
184}; 202};
@@ -220,7 +238,8 @@ enum {
220 CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/ 238 CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/
221 CMD_STATUS_TEMPLATE_OOM = 23, 239 CMD_STATUS_TEMPLATE_OOM = 23,
222 CMD_STATUS_NO_RX_BA_SESSION = 24, 240 CMD_STATUS_NO_RX_BA_SESSION = 24,
223 MAX_COMMAND_STATUS = 0xff 241
242 MAX_COMMAND_STATUS
224}; 243};
225 244
226#define CMDMBOX_HEADER_LEN 4 245#define CMDMBOX_HEADER_LEN 4
@@ -345,7 +364,15 @@ struct wl12xx_cmd_role_start {
345 364
346 u8 reset_tsf; 365 u8 reset_tsf;
347 366
348 u8 padding_1[4]; 367 /*
368 * ap supports wmm (note that there is additional
369 * per-sta wmm configuration)
370 */
371 u8 wmm;
372
373 u8 bcast_session_id;
374 u8 global_session_id;
375 u8 padding_1[1];
349 } __packed ap; 376 } __packed ap;
350 }; 377 };
351} __packed; 378} __packed;
@@ -515,7 +542,14 @@ struct wl12xx_cmd_set_peer_state {
515 542
516 u8 hlid; 543 u8 hlid;
517 u8 state; 544 u8 state;
518 u8 padding[2]; 545
546 /*
547 * wmm is relevant for sta role only.
548 * ap role configures the per-sta wmm params in
549 * the add_peer command.
550 */
551 u8 wmm;
552 u8 padding[1];
519} __packed; 553} __packed;
520 554
521struct wl12xx_cmd_roc { 555struct wl12xx_cmd_roc {
@@ -558,7 +592,7 @@ struct wl12xx_cmd_add_peer {
558 u8 bss_index; 592 u8 bss_index;
559 u8 sp_len; 593 u8 sp_len;
560 u8 wmm; 594 u8 wmm;
561 u8 padding1; 595 u8 session_id;
562} __packed; 596} __packed;
563 597
564struct wl12xx_cmd_remove_peer { 598struct wl12xx_cmd_remove_peer {
@@ -597,6 +631,13 @@ enum wl12xx_fwlogger_output {
597 WL12XX_FWLOG_OUTPUT_HOST, 631 WL12XX_FWLOG_OUTPUT_HOST,
598}; 632};
599 633
634struct wl12xx_cmd_regdomain_dfs_config {
635 struct wl1271_cmd_header header;
636
637 __le32 ch_bit_map1;
638 __le32 ch_bit_map2;
639} __packed;
640
600struct wl12xx_cmd_config_fwlog { 641struct wl12xx_cmd_config_fwlog {
601 struct wl1271_cmd_header header; 642 struct wl1271_cmd_header header;
602 643
@@ -626,27 +667,13 @@ struct wl12xx_cmd_stop_fwlog {
626 struct wl1271_cmd_header header; 667 struct wl1271_cmd_header header;
627} __packed; 668} __packed;
628 669
629struct wl12xx_cmd_channel_switch { 670struct wl12xx_cmd_stop_channel_switch {
630 struct wl1271_cmd_header header; 671 struct wl1271_cmd_header header;
631 672
632 u8 role_id; 673 u8 role_id;
633
634 /* The new serving channel */
635 u8 channel;
636 /* Relative time of the serving channel switch in TBTT units */
637 u8 switch_time;
638 /* Stop the role TX, should expect it after radar detection */
639 u8 stop_tx;
640 /* The target channel tx status 1-stopped 0-open*/
641 u8 post_switch_tx_disable;
642
643 u8 padding[3]; 674 u8 padding[3];
644} __packed; 675} __packed;
645 676
646struct wl12xx_cmd_stop_channel_switch {
647 struct wl1271_cmd_header header;
648} __packed;
649
650/* Used to check radio status after calibration */ 677/* Used to check radio status after calibration */
651#define MAX_TLV_LENGTH 500 678#define MAX_TLV_LENGTH 500
652#define TEST_CMD_P2G_CAL 2 /* TX BiP */ 679#define TEST_CMD_P2G_CAL 2 /* TX BiP */
diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h
index 9e40760bafe1..2b96ff821341 100644
--- a/drivers/net/wireless/ti/wlcore/conf.h
+++ b/drivers/net/wireless/ti/wlcore/conf.h
@@ -57,20 +57,49 @@ enum {
57}; 57};
58 58
59enum { 59enum {
60 CONF_HW_RATE_INDEX_1MBPS = 0, 60 CONF_HW_RATE_INDEX_1MBPS = 0,
61 CONF_HW_RATE_INDEX_2MBPS = 1, 61 CONF_HW_RATE_INDEX_2MBPS = 1,
62 CONF_HW_RATE_INDEX_5_5MBPS = 2, 62 CONF_HW_RATE_INDEX_5_5MBPS = 2,
63 CONF_HW_RATE_INDEX_6MBPS = 3, 63 CONF_HW_RATE_INDEX_11MBPS = 3,
64 CONF_HW_RATE_INDEX_9MBPS = 4, 64 CONF_HW_RATE_INDEX_6MBPS = 4,
65 CONF_HW_RATE_INDEX_11MBPS = 5, 65 CONF_HW_RATE_INDEX_9MBPS = 5,
66 CONF_HW_RATE_INDEX_12MBPS = 6, 66 CONF_HW_RATE_INDEX_12MBPS = 6,
67 CONF_HW_RATE_INDEX_18MBPS = 7, 67 CONF_HW_RATE_INDEX_18MBPS = 7,
68 CONF_HW_RATE_INDEX_22MBPS = 8, 68 CONF_HW_RATE_INDEX_24MBPS = 8,
69 CONF_HW_RATE_INDEX_24MBPS = 9, 69 CONF_HW_RATE_INDEX_36MBPS = 9,
70 CONF_HW_RATE_INDEX_36MBPS = 10, 70 CONF_HW_RATE_INDEX_48MBPS = 10,
71 CONF_HW_RATE_INDEX_48MBPS = 11, 71 CONF_HW_RATE_INDEX_54MBPS = 11,
72 CONF_HW_RATE_INDEX_54MBPS = 12, 72 CONF_HW_RATE_INDEX_MCS0 = 12,
73 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, 73 CONF_HW_RATE_INDEX_MCS1 = 13,
74 CONF_HW_RATE_INDEX_MCS2 = 14,
75 CONF_HW_RATE_INDEX_MCS3 = 15,
76 CONF_HW_RATE_INDEX_MCS4 = 16,
77 CONF_HW_RATE_INDEX_MCS5 = 17,
78 CONF_HW_RATE_INDEX_MCS6 = 18,
79 CONF_HW_RATE_INDEX_MCS7 = 19,
80 CONF_HW_RATE_INDEX_MCS7_SGI = 20,
81 CONF_HW_RATE_INDEX_MCS0_40MHZ = 21,
82 CONF_HW_RATE_INDEX_MCS1_40MHZ = 22,
83 CONF_HW_RATE_INDEX_MCS2_40MHZ = 23,
84 CONF_HW_RATE_INDEX_MCS3_40MHZ = 24,
85 CONF_HW_RATE_INDEX_MCS4_40MHZ = 25,
86 CONF_HW_RATE_INDEX_MCS5_40MHZ = 26,
87 CONF_HW_RATE_INDEX_MCS6_40MHZ = 27,
88 CONF_HW_RATE_INDEX_MCS7_40MHZ = 28,
89 CONF_HW_RATE_INDEX_MCS7_40MHZ_SGI = 29,
90
91 /* MCS8+ rates overlap with 40Mhz rates */
92 CONF_HW_RATE_INDEX_MCS8 = 21,
93 CONF_HW_RATE_INDEX_MCS9 = 22,
94 CONF_HW_RATE_INDEX_MCS10 = 23,
95 CONF_HW_RATE_INDEX_MCS11 = 24,
96 CONF_HW_RATE_INDEX_MCS12 = 25,
97 CONF_HW_RATE_INDEX_MCS13 = 26,
98 CONF_HW_RATE_INDEX_MCS14 = 27,
99 CONF_HW_RATE_INDEX_MCS15 = 28,
100 CONF_HW_RATE_INDEX_MCS15_SGI = 29,
101
102 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_MCS7_40MHZ_SGI,
74}; 103};
75 104
76#define CONF_HW_RXTX_RATE_UNSUPPORTED 0xff 105#define CONF_HW_RXTX_RATE_UNSUPPORTED 0xff
@@ -415,11 +444,11 @@ struct conf_rx_settings {
415#define CONF_TX_RATE_MASK_BASIC_P2P CONF_HW_BIT_RATE_6MBPS 444#define CONF_TX_RATE_MASK_BASIC_P2P CONF_HW_BIT_RATE_6MBPS
416 445
417/* 446/*
418 * Rates supported for data packets when operating as AP. Note the absence 447 * Rates supported for data packets when operating as STA/AP. Note the absence
419 * of the 22Mbps rate. There is a FW limitation on 12 rates so we must drop 448 * of the 22Mbps rate. There is a FW limitation on 12 rates so we must drop
420 * one. The rate dropped is not mandatory under any operating mode. 449 * one. The rate dropped is not mandatory under any operating mode.
421 */ 450 */
422#define CONF_TX_AP_ENABLED_RATES (CONF_HW_BIT_RATE_1MBPS | \ 451#define CONF_TX_ENABLED_RATES (CONF_HW_BIT_RATE_1MBPS | \
423 CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \ 452 CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
424 CONF_HW_BIT_RATE_6MBPS | CONF_HW_BIT_RATE_9MBPS | \ 453 CONF_HW_BIT_RATE_6MBPS | CONF_HW_BIT_RATE_9MBPS | \
425 CONF_HW_BIT_RATE_11MBPS | CONF_HW_BIT_RATE_12MBPS | \ 454 CONF_HW_BIT_RATE_11MBPS | CONF_HW_BIT_RATE_12MBPS | \
@@ -677,6 +706,18 @@ struct conf_tx_settings {
677 706
678 /* Time in ms for Tx watchdog timer to expire */ 707 /* Time in ms for Tx watchdog timer to expire */
679 u32 tx_watchdog_timeout; 708 u32 tx_watchdog_timeout;
709
710 /*
711 * when a slow link has this much packets pending, it becomes a low
712 * priority link, scheduling-wise
713 */
714 u8 slow_link_thold;
715
716 /*
717 * when a fast link has this much packets pending, it becomes a low
718 * priority link, scheduling-wise
719 */
720 u8 fast_link_thold;
680} __packed; 721} __packed;
681 722
682enum { 723enum {
@@ -1047,6 +1088,7 @@ struct conf_roam_trigger_settings {
1047struct conf_scan_settings { 1088struct conf_scan_settings {
1048 /* 1089 /*
1049 * The minimum time to wait on each channel for active scans 1090 * The minimum time to wait on each channel for active scans
1091 * This value will be used whenever there's a connected interface.
1050 * 1092 *
1051 * Range: u32 tu/1000 1093 * Range: u32 tu/1000
1052 */ 1094 */
@@ -1054,24 +1096,37 @@ struct conf_scan_settings {
1054 1096
1055 /* 1097 /*
1056 * The maximum time to wait on each channel for active scans 1098 * The maximum time to wait on each channel for active scans
1099 * This value will be currently used whenever there's a
1100 * connected interface. It shouldn't exceed 30000 (~30ms) to avoid
1101 * possible interference of voip traffic going on while scanning.
1057 * 1102 *
1058 * Range: u32 tu/1000 1103 * Range: u32 tu/1000
1059 */ 1104 */
1060 u32 max_dwell_time_active; 1105 u32 max_dwell_time_active;
1061 1106
1062 /* 1107 /* The minimum time to wait on each channel for active scans
1063 * The minimum time to wait on each channel for passive scans 1108 * when it's possible to have longer scan dwell times.
1109 * Currently this is used whenever we're idle on all interfaces.
1110 * Longer dwell times improve detection of networks within a
1111 * single scan.
1064 * 1112 *
1065 * Range: u32 tu/1000 1113 * Range: u32 tu/1000
1066 */ 1114 */
1067 u32 min_dwell_time_passive; 1115 u32 min_dwell_time_active_long;
1068 1116
1069 /* 1117 /* The maximum time to wait on each channel for active scans
1070 * The maximum time to wait on each channel for passive scans 1118 * when it's possible to have longer scan dwell times.
1119 * See min_dwell_time_active_long
1071 * 1120 *
1072 * Range: u32 tu/1000 1121 * Range: u32 tu/1000
1073 */ 1122 */
1074 u32 max_dwell_time_passive; 1123 u32 max_dwell_time_active_long;
1124
1125 /* time to wait on the channel for passive scans (in TU/1000) */
1126 u32 dwell_time_passive;
1127
1128 /* time to wait on the channel for DFS scans (in TU/1000) */
1129 u32 dwell_time_dfs;
1075 1130
1076 /* 1131 /*
1077 * Number of probe requests to transmit on each active scan channel 1132 * Number of probe requests to transmit on each active scan channel
@@ -1276,12 +1331,20 @@ struct conf_hangover_settings {
1276 u8 window_size; 1331 u8 window_size;
1277} __packed; 1332} __packed;
1278 1333
1334struct conf_recovery_settings {
1335 /* BUG() on fw recovery */
1336 u8 bug_on_recovery;
1337
1338 /* Prevent HW recovery. FW will remain stuck. */
1339 u8 no_recovery;
1340} __packed;
1341
1279/* 1342/*
1280 * The conf version consists of 4 bytes. The two MSB are the wlcore 1343 * The conf version consists of 4 bytes. The two MSB are the wlcore
1281 * version, the two LSB are the lower driver's private conf 1344 * version, the two LSB are the lower driver's private conf
1282 * version. 1345 * version.
1283 */ 1346 */
1284#define WLCORE_CONF_VERSION (0x0002 << 16) 1347#define WLCORE_CONF_VERSION (0x0005 << 16)
1285#define WLCORE_CONF_MASK 0xffff0000 1348#define WLCORE_CONF_MASK 0xffff0000
1286#define WLCORE_CONF_SIZE (sizeof(struct wlcore_conf_header) + \ 1349#define WLCORE_CONF_SIZE (sizeof(struct wlcore_conf_header) + \
1287 sizeof(struct wlcore_conf)) 1350 sizeof(struct wlcore_conf))
@@ -1309,6 +1372,7 @@ struct wlcore_conf {
1309 struct conf_fwlog fwlog; 1372 struct conf_fwlog fwlog;
1310 struct conf_rate_policy_settings rate; 1373 struct conf_rate_policy_settings rate;
1311 struct conf_hangover_settings hangover; 1374 struct conf_hangover_settings hangover;
1375 struct conf_recovery_settings recovery;
1312} __packed; 1376} __packed;
1313 1377
1314struct wlcore_conf_file { 1378struct wlcore_conf_file {
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index c86bb00c2488..e70a7c864865 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -490,7 +490,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
490 DRIVER_STATE_PRINT_HEX(chip.id); 490 DRIVER_STATE_PRINT_HEX(chip.id);
491 DRIVER_STATE_PRINT_STR(chip.fw_ver_str); 491 DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
492 DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str); 492 DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
493 DRIVER_STATE_PRINT_INT(sched_scanning); 493 DRIVER_STATE_PRINT_INT(recovery_count);
494 494
495#undef DRIVER_STATE_PRINT_INT 495#undef DRIVER_STATE_PRINT_INT
496#undef DRIVER_STATE_PRINT_LONG 496#undef DRIVER_STATE_PRINT_LONG
@@ -560,7 +560,6 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
560 if (wlvif->bss_type == BSS_TYPE_STA_BSS || 560 if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
561 wlvif->bss_type == BSS_TYPE_IBSS) { 561 wlvif->bss_type == BSS_TYPE_IBSS) {
562 VIF_STATE_PRINT_INT(sta.hlid); 562 VIF_STATE_PRINT_INT(sta.hlid);
563 VIF_STATE_PRINT_INT(sta.ba_rx_bitmap);
564 VIF_STATE_PRINT_INT(sta.basic_rate_idx); 563 VIF_STATE_PRINT_INT(sta.basic_rate_idx);
565 VIF_STATE_PRINT_INT(sta.ap_rate_idx); 564 VIF_STATE_PRINT_INT(sta.ap_rate_idx);
566 VIF_STATE_PRINT_INT(sta.p2p_rate_idx); 565 VIF_STATE_PRINT_INT(sta.p2p_rate_idx);
@@ -577,6 +576,10 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
577 VIF_STATE_PRINT_INT(ap.ucast_rate_idx[3]); 576 VIF_STATE_PRINT_INT(ap.ucast_rate_idx[3]);
578 } 577 }
579 VIF_STATE_PRINT_INT(last_tx_hlid); 578 VIF_STATE_PRINT_INT(last_tx_hlid);
579 VIF_STATE_PRINT_INT(tx_queue_count[0]);
580 VIF_STATE_PRINT_INT(tx_queue_count[1]);
581 VIF_STATE_PRINT_INT(tx_queue_count[2]);
582 VIF_STATE_PRINT_INT(tx_queue_count[3]);
580 VIF_STATE_PRINT_LHEX(links_map[0]); 583 VIF_STATE_PRINT_LHEX(links_map[0]);
581 VIF_STATE_PRINT_NSTR(ssid, wlvif->ssid_len); 584 VIF_STATE_PRINT_NSTR(ssid, wlvif->ssid_len);
582 VIF_STATE_PRINT_INT(band); 585 VIF_STATE_PRINT_INT(band);
@@ -589,7 +592,6 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
589 VIF_STATE_PRINT_INT(beacon_int); 592 VIF_STATE_PRINT_INT(beacon_int);
590 VIF_STATE_PRINT_INT(default_key); 593 VIF_STATE_PRINT_INT(default_key);
591 VIF_STATE_PRINT_INT(aid); 594 VIF_STATE_PRINT_INT(aid);
592 VIF_STATE_PRINT_INT(session_counter);
593 VIF_STATE_PRINT_INT(psm_entry_retry); 595 VIF_STATE_PRINT_INT(psm_entry_retry);
594 VIF_STATE_PRINT_INT(power_level); 596 VIF_STATE_PRINT_INT(power_level);
595 VIF_STATE_PRINT_INT(rssi_thold); 597 VIF_STATE_PRINT_INT(rssi_thold);
@@ -993,7 +995,7 @@ static ssize_t sleep_auth_write(struct file *file,
993 return -EINVAL; 995 return -EINVAL;
994 } 996 }
995 997
996 if (value < 0 || value > WL1271_PSM_MAX) { 998 if (value > WL1271_PSM_MAX) {
997 wl1271_warning("sleep_auth must be between 0 and %d", 999 wl1271_warning("sleep_auth must be between 0 and %d",
998 WL1271_PSM_MAX); 1000 WL1271_PSM_MAX);
999 return -ERANGE; 1001 return -ERANGE;
diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c
index 48907054d493..70f289aa1bc6 100644
--- a/drivers/net/wireless/ti/wlcore/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -29,34 +29,39 @@
29#include "scan.h" 29#include "scan.h"
30#include "wl12xx_80211.h" 30#include "wl12xx_80211.h"
31 31
32static void wl1271_event_rssi_trigger(struct wl1271 *wl, 32void wlcore_event_rssi_trigger(struct wl1271 *wl, s8 *metric_arr)
33 struct wl12xx_vif *wlvif,
34 struct event_mailbox *mbox)
35{ 33{
36 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 34 struct wl12xx_vif *wlvif;
35 struct ieee80211_vif *vif;
37 enum nl80211_cqm_rssi_threshold_event event; 36 enum nl80211_cqm_rssi_threshold_event event;
38 s8 metric = mbox->rssi_snr_trigger_metric[0]; 37 s8 metric = metric_arr[0];
39 38
40 wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric); 39 wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric);
41 40
42 if (metric <= wlvif->rssi_thold) 41 /* TODO: check actual multi-role support */
43 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; 42 wl12xx_for_each_wlvif_sta(wl, wlvif) {
44 else 43 if (metric <= wlvif->rssi_thold)
45 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; 44 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
46 45 else
47 if (event != wlvif->last_rssi_event) 46 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
48 ieee80211_cqm_rssi_notify(vif, event, GFP_KERNEL); 47
49 wlvif->last_rssi_event = event; 48 vif = wl12xx_wlvif_to_vif(wlvif);
49 if (event != wlvif->last_rssi_event)
50 ieee80211_cqm_rssi_notify(vif, event, GFP_KERNEL);
51 wlvif->last_rssi_event = event;
52 }
50} 53}
54EXPORT_SYMBOL_GPL(wlcore_event_rssi_trigger);
51 55
52static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif) 56static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif)
53{ 57{
54 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 58 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
55 59
56 if (wlvif->bss_type != BSS_TYPE_AP_BSS) { 60 if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
57 if (!wlvif->sta.ba_rx_bitmap) 61 u8 hlid = wlvif->sta.hlid;
62 if (!wl->links[hlid].ba_bitmap)
58 return; 63 return;
59 ieee80211_stop_rx_ba_session(vif, wlvif->sta.ba_rx_bitmap, 64 ieee80211_stop_rx_ba_session(vif, wl->links[hlid].ba_bitmap,
60 vif->bss_conf.bssid); 65 vif->bss_conf.bssid);
61 } else { 66 } else {
62 u8 hlid; 67 u8 hlid;
@@ -74,8 +79,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif)
74 } 79 }
75} 80}
76 81
77static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl, 82void wlcore_event_soft_gemini_sense(struct wl1271 *wl, u8 enable)
78 u8 enable)
79{ 83{
80 struct wl12xx_vif *wlvif; 84 struct wl12xx_vif *wlvif;
81 85
@@ -87,201 +91,169 @@ static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl,
87 wl1271_recalc_rx_streaming(wl, wlvif); 91 wl1271_recalc_rx_streaming(wl, wlvif);
88 } 92 }
89 } 93 }
90
91} 94}
95EXPORT_SYMBOL_GPL(wlcore_event_soft_gemini_sense);
92 96
93static void wl1271_event_mbox_dump(struct event_mailbox *mbox) 97void wlcore_event_sched_scan_completed(struct wl1271 *wl,
98 u8 status)
94{ 99{
95 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); 100 wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT (status 0x%0x)",
96 wl1271_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector); 101 status);
97 wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask); 102
103 if (wl->sched_vif) {
104 ieee80211_sched_scan_stopped(wl->hw);
105 wl->sched_vif = NULL;
106 }
98} 107}
108EXPORT_SYMBOL_GPL(wlcore_event_sched_scan_completed);
99 109
100static int wl1271_event_process(struct wl1271 *wl) 110void wlcore_event_ba_rx_constraint(struct wl1271 *wl,
111 unsigned long roles_bitmap,
112 unsigned long allowed_bitmap)
101{ 113{
102 struct event_mailbox *mbox = wl->mbox;
103 struct ieee80211_vif *vif;
104 struct wl12xx_vif *wlvif; 114 struct wl12xx_vif *wlvif;
105 u32 vector;
106 bool disconnect_sta = false;
107 unsigned long sta_bitmap = 0;
108 int ret;
109
110 wl1271_event_mbox_dump(mbox);
111
112 vector = le32_to_cpu(mbox->events_vector);
113 vector &= ~(le32_to_cpu(mbox->events_mask));
114 wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector);
115 115
116 if (vector & SCAN_COMPLETE_EVENT_ID) { 116 wl1271_debug(DEBUG_EVENT, "%s: roles=0x%lx allowed=0x%lx",
117 wl1271_debug(DEBUG_EVENT, "status: 0x%x", 117 __func__, roles_bitmap, allowed_bitmap);
118 mbox->scheduled_scan_status);
119
120 wl1271_scan_stm(wl, wl->scan_vif);
121 }
122 118
123 if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) { 119 wl12xx_for_each_wlvif(wl, wlvif) {
124 wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_REPORT_EVENT " 120 if (wlvif->role_id == WL12XX_INVALID_ROLE_ID ||
125 "(status 0x%0x)", mbox->scheduled_scan_status); 121 !test_bit(wlvif->role_id , &roles_bitmap))
122 continue;
126 123
127 wl1271_scan_sched_scan_results(wl); 124 wlvif->ba_allowed = !!test_bit(wlvif->role_id,
125 &allowed_bitmap);
126 if (!wlvif->ba_allowed)
127 wl1271_stop_ba_event(wl, wlvif);
128 } 128 }
129}
130EXPORT_SYMBOL_GPL(wlcore_event_ba_rx_constraint);
129 131
130 if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID) { 132void wlcore_event_channel_switch(struct wl1271 *wl,
131 wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT " 133 unsigned long roles_bitmap,
132 "(status 0x%0x)", mbox->scheduled_scan_status); 134 bool success)
133 if (wl->sched_scanning) { 135{
134 ieee80211_sched_scan_stopped(wl->hw); 136 struct wl12xx_vif *wlvif;
135 wl->sched_scanning = false; 137 struct ieee80211_vif *vif;
136 }
137 }
138 138
139 if (vector & SOFT_GEMINI_SENSE_EVENT_ID) 139 wl1271_debug(DEBUG_EVENT, "%s: roles=0x%lx success=%d",
140 wl12xx_event_soft_gemini_sense(wl, 140 __func__, roles_bitmap, success);
141 mbox->soft_gemini_sense_info);
142 141
143 /* 142 wl12xx_for_each_wlvif_sta(wl, wlvif) {
144 * We are HW_MONITOR device. On beacon loss - queue 143 if (wlvif->role_id == WL12XX_INVALID_ROLE_ID ||
145 * connection loss work. Cancel it on REGAINED event. 144 !test_bit(wlvif->role_id , &roles_bitmap))
146 */ 145 continue;
147 if (vector & BSS_LOSE_EVENT_ID) {
148 /* TODO: check for multi-role */
149 int delay = wl->conf.conn.synch_fail_thold *
150 wl->conf.conn.bss_lose_timeout;
151 wl1271_info("Beacon loss detected.");
152 146
153 /* 147 if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS,
154 * if the work is already queued, it should take place. We 148 &wlvif->flags))
155 * don't want to delay the connection loss indication 149 continue;
156 * any more.
157 */
158 ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work,
159 msecs_to_jiffies(delay));
160 150
161 wl12xx_for_each_wlvif_sta(wl, wlvif) { 151 vif = wl12xx_wlvif_to_vif(wlvif);
162 vif = wl12xx_wlvif_to_vif(wlvif);
163 152
164 ieee80211_cqm_rssi_notify( 153 ieee80211_chswitch_done(vif, success);
165 vif, 154 cancel_delayed_work(&wlvif->channel_switch_work);
166 NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
167 GFP_KERNEL);
168 }
169 } 155 }
156}
157EXPORT_SYMBOL_GPL(wlcore_event_channel_switch);
170 158
171 if (vector & REGAINED_BSS_EVENT_ID) { 159void wlcore_event_dummy_packet(struct wl1271 *wl)
172 /* TODO: check for multi-role */ 160{
173 wl1271_info("Beacon regained."); 161 wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
174 cancel_delayed_work(&wl->connection_loss_work); 162 wl1271_tx_dummy_packet(wl);
175 163}
176 /* sanity check - we can't lose and gain the beacon together */ 164EXPORT_SYMBOL_GPL(wlcore_event_dummy_packet);
177 WARN(vector & BSS_LOSE_EVENT_ID,
178 "Concurrent beacon loss and gain from FW");
179 }
180 165
181 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { 166static void wlcore_disconnect_sta(struct wl1271 *wl, unsigned long sta_bitmap)
182 /* TODO: check actual multi-role support */ 167{
183 wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT"); 168 u32 num_packets = wl->conf.tx.max_tx_retries;
184 wl12xx_for_each_wlvif_sta(wl, wlvif) { 169 struct wl12xx_vif *wlvif;
185 wl1271_event_rssi_trigger(wl, wlvif, mbox); 170 struct ieee80211_vif *vif;
171 struct ieee80211_sta *sta;
172 const u8 *addr;
173 int h;
174
175 for_each_set_bit(h, &sta_bitmap, WL12XX_MAX_LINKS) {
176 bool found = false;
177 /* find the ap vif connected to this sta */
178 wl12xx_for_each_wlvif_ap(wl, wlvif) {
179 if (!test_bit(h, wlvif->ap.sta_hlid_map))
180 continue;
181 found = true;
182 break;
186 } 183 }
187 } 184 if (!found)
185 continue;
188 186
189 if (vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID) { 187 vif = wl12xx_wlvif_to_vif(wlvif);
190 u8 role_id = mbox->role_id; 188 addr = wl->links[h].addr;
191 wl1271_debug(DEBUG_EVENT, "BA_SESSION_RX_CONSTRAINT_EVENT_ID. "
192 "ba_allowed = 0x%x, role_id=%d",
193 mbox->rx_ba_allowed, role_id);
194 189
195 wl12xx_for_each_wlvif(wl, wlvif) { 190 rcu_read_lock();
196 if (role_id != 0xff && role_id != wlvif->role_id) 191 sta = ieee80211_find_sta(vif, addr);
197 continue; 192 if (sta) {
198 193 wl1271_debug(DEBUG_EVENT, "remove sta %d", h);
199 wlvif->ba_allowed = !!mbox->rx_ba_allowed; 194 ieee80211_report_low_ack(sta, num_packets);
200 if (!wlvif->ba_allowed)
201 wl1271_stop_ba_event(wl, wlvif);
202 } 195 }
196 rcu_read_unlock();
203 } 197 }
198}
204 199
205 if (vector & CHANNEL_SWITCH_COMPLETE_EVENT_ID) { 200void wlcore_event_max_tx_failure(struct wl1271 *wl, unsigned long sta_bitmap)
206 wl1271_debug(DEBUG_EVENT, "CHANNEL_SWITCH_COMPLETE_EVENT_ID. " 201{
207 "status = 0x%x", 202 wl1271_debug(DEBUG_EVENT, "MAX_TX_FAILURE_EVENT_ID");
208 mbox->channel_switch_status); 203 wlcore_disconnect_sta(wl, sta_bitmap);
209 /* 204}
210 * That event uses for two cases: 205EXPORT_SYMBOL_GPL(wlcore_event_max_tx_failure);
211 * 1) channel switch complete with status=0
212 * 2) channel switch failed status=1
213 */
214
215 /* TODO: configure only the relevant vif */
216 wl12xx_for_each_wlvif_sta(wl, wlvif) {
217 bool success;
218
219 if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS,
220 &wlvif->flags))
221 continue;
222
223 success = mbox->channel_switch_status ? false : true;
224 vif = wl12xx_wlvif_to_vif(wlvif);
225 206
226 ieee80211_chswitch_done(vif, success); 207void wlcore_event_inactive_sta(struct wl1271 *wl, unsigned long sta_bitmap)
227 } 208{
228 } 209 wl1271_debug(DEBUG_EVENT, "INACTIVE_STA_EVENT_ID");
210 wlcore_disconnect_sta(wl, sta_bitmap);
211}
212EXPORT_SYMBOL_GPL(wlcore_event_inactive_sta);
229 213
230 if ((vector & DUMMY_PACKET_EVENT_ID)) { 214void wlcore_event_roc_complete(struct wl1271 *wl)
231 wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); 215{
232 ret = wl1271_tx_dummy_packet(wl); 216 wl1271_debug(DEBUG_EVENT, "REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID");
233 if (ret < 0) 217 if (wl->roc_vif)
234 return ret; 218 ieee80211_ready_on_channel(wl->hw);
235 } 219}
220EXPORT_SYMBOL_GPL(wlcore_event_roc_complete);
236 221
222void wlcore_event_beacon_loss(struct wl1271 *wl, unsigned long roles_bitmap)
223{
237 /* 224 /*
238 * "TX retries exceeded" has a different meaning according to mode. 225 * We are HW_MONITOR device. On beacon loss - queue
239 * In AP mode the offending station is disconnected. 226 * connection loss work. Cancel it on REGAINED event.
240 */ 227 */
241 if (vector & MAX_TX_RETRY_EVENT_ID) { 228 struct wl12xx_vif *wlvif;
242 wl1271_debug(DEBUG_EVENT, "MAX_TX_RETRY_EVENT_ID"); 229 struct ieee80211_vif *vif;
243 sta_bitmap |= le16_to_cpu(mbox->sta_tx_retry_exceeded); 230 int delay = wl->conf.conn.synch_fail_thold *
244 disconnect_sta = true; 231 wl->conf.conn.bss_lose_timeout;
245 }
246 232
247 if (vector & INACTIVE_STA_EVENT_ID) { 233 wl1271_info("Beacon loss detected. roles:0x%lx", roles_bitmap);
248 wl1271_debug(DEBUG_EVENT, "INACTIVE_STA_EVENT_ID");
249 sta_bitmap |= le16_to_cpu(mbox->sta_aging_status);
250 disconnect_sta = true;
251 }
252 234
253 if (disconnect_sta) { 235 wl12xx_for_each_wlvif_sta(wl, wlvif) {
254 u32 num_packets = wl->conf.tx.max_tx_retries; 236 if (wlvif->role_id == WL12XX_INVALID_ROLE_ID ||
255 struct ieee80211_sta *sta; 237 !test_bit(wlvif->role_id , &roles_bitmap))
256 const u8 *addr; 238 continue;
257 int h;
258
259 for_each_set_bit(h, &sta_bitmap, WL12XX_MAX_LINKS) {
260 bool found = false;
261 /* find the ap vif connected to this sta */
262 wl12xx_for_each_wlvif_ap(wl, wlvif) {
263 if (!test_bit(h, wlvif->ap.sta_hlid_map))
264 continue;
265 found = true;
266 break;
267 }
268 if (!found)
269 continue;
270 239
271 vif = wl12xx_wlvif_to_vif(wlvif); 240 /*
272 addr = wl->links[h].addr; 241 * if the work is already queued, it should take place.
242 * We don't want to delay the connection loss
243 * indication any more.
244 */
245 ieee80211_queue_delayed_work(wl->hw,
246 &wlvif->connection_loss_work,
247 msecs_to_jiffies(delay));
273 248
274 rcu_read_lock(); 249 vif = wl12xx_wlvif_to_vif(wlvif);
275 sta = ieee80211_find_sta(vif, addr); 250 ieee80211_cqm_rssi_notify(
276 if (sta) { 251 vif,
277 wl1271_debug(DEBUG_EVENT, "remove sta %d", h); 252 NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
278 ieee80211_report_low_ack(sta, num_packets); 253 GFP_KERNEL);
279 }
280 rcu_read_unlock();
281 }
282 } 254 }
283 return 0;
284} 255}
256EXPORT_SYMBOL_GPL(wlcore_event_beacon_loss);
285 257
286int wl1271_event_unmask(struct wl1271 *wl) 258int wl1271_event_unmask(struct wl1271 *wl)
287{ 259{
@@ -305,12 +277,12 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
305 277
306 /* first we read the mbox descriptor */ 278 /* first we read the mbox descriptor */
307 ret = wlcore_read(wl, wl->mbox_ptr[mbox_num], wl->mbox, 279 ret = wlcore_read(wl, wl->mbox_ptr[mbox_num], wl->mbox,
308 sizeof(*wl->mbox), false); 280 wl->mbox_size, false);
309 if (ret < 0) 281 if (ret < 0)
310 return ret; 282 return ret;
311 283
312 /* process the descriptor */ 284 /* process the descriptor */
313 ret = wl1271_event_process(wl); 285 ret = wl->ops->process_mailbox_events(wl);
314 if (ret < 0) 286 if (ret < 0)
315 return ret; 287 return ret;
316 288
diff --git a/drivers/net/wireless/ti/wlcore/event.h b/drivers/net/wireless/ti/wlcore/event.h
index 8adf18d6c58f..acc7a59d3828 100644
--- a/drivers/net/wireless/ti/wlcore/event.h
+++ b/drivers/net/wireless/ti/wlcore/event.h
@@ -46,33 +46,17 @@ enum {
46 RSSI_SNR_TRIGGER_5_EVENT_ID = BIT(5), 46 RSSI_SNR_TRIGGER_5_EVENT_ID = BIT(5),
47 RSSI_SNR_TRIGGER_6_EVENT_ID = BIT(6), 47 RSSI_SNR_TRIGGER_6_EVENT_ID = BIT(6),
48 RSSI_SNR_TRIGGER_7_EVENT_ID = BIT(7), 48 RSSI_SNR_TRIGGER_7_EVENT_ID = BIT(7),
49 MEASUREMENT_START_EVENT_ID = BIT(8), 49
50 MEASUREMENT_COMPLETE_EVENT_ID = BIT(9),
51 SCAN_COMPLETE_EVENT_ID = BIT(10),
52 WFD_DISCOVERY_COMPLETE_EVENT_ID = BIT(11),
53 AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(12),
54 RESERVED1 = BIT(13),
55 PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(14),
56 ROLE_STOP_COMPLETE_EVENT_ID = BIT(15),
57 RADAR_DETECTED_EVENT_ID = BIT(16),
58 CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17),
59 BSS_LOSE_EVENT_ID = BIT(18),
60 REGAINED_BSS_EVENT_ID = BIT(19),
61 MAX_TX_RETRY_EVENT_ID = BIT(20),
62 DUMMY_PACKET_EVENT_ID = BIT(21),
63 SOFT_GEMINI_SENSE_EVENT_ID = BIT(22),
64 CHANGE_AUTO_MODE_TIMEOUT_EVENT_ID = BIT(23),
65 SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24),
66 PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25),
67 INACTIVE_STA_EVENT_ID = BIT(26),
68 PEER_REMOVE_COMPLETE_EVENT_ID = BIT(27),
69 PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(28),
70 PERIODIC_SCAN_REPORT_EVENT_ID = BIT(29),
71 BA_SESSION_RX_CONSTRAINT_EVENT_ID = BIT(30),
72 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID = BIT(31),
73 EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff, 50 EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff,
74}; 51};
75 52
53/* events the driver might want to wait for */
54enum wlcore_wait_event {
55 WLCORE_EVENT_ROLE_STOP_COMPLETE,
56 WLCORE_EVENT_PEER_REMOVE_COMPLETE,
57 WLCORE_EVENT_DFS_CONFIG_COMPLETE
58};
59
76enum { 60enum {
77 EVENT_ENTER_POWER_SAVE_FAIL = 0, 61 EVENT_ENTER_POWER_SAVE_FAIL = 0,
78 EVENT_ENTER_POWER_SAVE_SUCCESS, 62 EVENT_ENTER_POWER_SAVE_SUCCESS,
@@ -80,61 +64,24 @@ enum {
80 64
81#define NUM_OF_RSSI_SNR_TRIGGERS 8 65#define NUM_OF_RSSI_SNR_TRIGGERS 8
82 66
83struct event_mailbox {
84 __le32 events_vector;
85 __le32 events_mask;
86 __le32 reserved_1;
87 __le32 reserved_2;
88
89 u8 number_of_scan_results;
90 u8 scan_tag;
91 u8 completed_scan_status;
92 u8 reserved_3;
93
94 u8 soft_gemini_sense_info;
95 u8 soft_gemini_protective_info;
96 s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
97 u8 change_auto_mode_timeout;
98 u8 scheduled_scan_status;
99 u8 reserved4;
100 /* tuned channel (roc) */
101 u8 roc_channel;
102
103 __le16 hlid_removed_bitmap;
104
105 /* bitmap of aged stations (by HLID) */
106 __le16 sta_aging_status;
107
108 /* bitmap of stations (by HLID) which exceeded max tx retries */
109 __le16 sta_tx_retry_exceeded;
110
111 /* discovery completed results */
112 u8 discovery_tag;
113 u8 number_of_preq_results;
114 u8 number_of_prsp_results;
115 u8 reserved_5;
116
117 /* rx ba constraint */
118 u8 role_id; /* 0xFF means any role. */
119 u8 rx_ba_allowed;
120 u8 reserved_6[2];
121
122 /* Channel switch results */
123
124 u8 channel_switch_role_id;
125 u8 channel_switch_status;
126 u8 reserved_7[2];
127
128 u8 ps_poll_delivery_failure_role_ids;
129 u8 stopped_role_ids;
130 u8 started_role_ids;
131
132 u8 reserved_8[9];
133} __packed;
134
135struct wl1271; 67struct wl1271;
136 68
137int wl1271_event_unmask(struct wl1271 *wl); 69int wl1271_event_unmask(struct wl1271 *wl);
138int wl1271_event_handle(struct wl1271 *wl, u8 mbox); 70int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
139 71
72void wlcore_event_soft_gemini_sense(struct wl1271 *wl, u8 enable);
73void wlcore_event_sched_scan_completed(struct wl1271 *wl,
74 u8 status);
75void wlcore_event_ba_rx_constraint(struct wl1271 *wl,
76 unsigned long roles_bitmap,
77 unsigned long allowed_bitmap);
78void wlcore_event_channel_switch(struct wl1271 *wl,
79 unsigned long roles_bitmap,
80 bool success);
81void wlcore_event_beacon_loss(struct wl1271 *wl, unsigned long roles_bitmap);
82void wlcore_event_dummy_packet(struct wl1271 *wl);
83void wlcore_event_max_tx_failure(struct wl1271 *wl, unsigned long sta_bitmap);
84void wlcore_event_inactive_sta(struct wl1271 *wl, unsigned long sta_bitmap);
85void wlcore_event_roc_complete(struct wl1271 *wl);
86void wlcore_event_rssi_trigger(struct wl1271 *wl, s8 *metric_arr);
140#endif 87#endif
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
index 2673d783ec1e..7fd260c02a0a 100644
--- a/drivers/net/wireless/ti/wlcore/hw_ops.h
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -201,4 +201,45 @@ wlcore_hw_pre_pkt_send(struct wl1271 *wl, u32 buf_offset, u32 last_len)
201 return buf_offset; 201 return buf_offset;
202} 202}
203 203
204static inline void
205wlcore_hw_sta_rc_update(struct wl1271 *wl, struct wl12xx_vif *wlvif,
206 struct ieee80211_sta *sta, u32 changed)
207{
208 if (wl->ops->sta_rc_update)
209 wl->ops->sta_rc_update(wl, wlvif, sta, changed);
210}
211
212static inline int
213wlcore_hw_set_peer_cap(struct wl1271 *wl,
214 struct ieee80211_sta_ht_cap *ht_cap,
215 bool allow_ht_operation,
216 u32 rate_set, u8 hlid)
217{
218 if (wl->ops->set_peer_cap)
219 return wl->ops->set_peer_cap(wl, ht_cap, allow_ht_operation,
220 rate_set, hlid);
221
222 return 0;
223}
224
225static inline bool
226wlcore_hw_lnk_high_prio(struct wl1271 *wl, u8 hlid,
227 struct wl1271_link *lnk)
228{
229 if (!wl->ops->lnk_high_prio)
230 BUG_ON(1);
231
232 return wl->ops->lnk_high_prio(wl, hlid, lnk);
233}
234
235static inline bool
236wlcore_hw_lnk_low_prio(struct wl1271 *wl, u8 hlid,
237 struct wl1271_link *lnk)
238{
239 if (!wl->ops->lnk_low_prio)
240 BUG_ON(1);
241
242 return wl->ops->lnk_low_prio(wl, hlid, lnk);
243}
244
204#endif 245#endif
diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c
index 32d157f62f31..5c6f11e157d9 100644
--- a/drivers/net/wireless/ti/wlcore/init.c
+++ b/drivers/net/wireless/ti/wlcore/init.c
@@ -41,14 +41,14 @@ int wl1271_init_templates_config(struct wl1271 *wl)
41 41
42 /* send empty templates for fw memory reservation */ 42 /* send empty templates for fw memory reservation */
43 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 43 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
44 CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, 44 wl->scan_templ_id_2_4, NULL,
45 WL1271_CMD_TEMPL_MAX_SIZE, 45 WL1271_CMD_TEMPL_MAX_SIZE,
46 0, WL1271_RATE_AUTOMATIC); 46 0, WL1271_RATE_AUTOMATIC);
47 if (ret < 0) 47 if (ret < 0)
48 return ret; 48 return ret;
49 49
50 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 50 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
51 CMD_TEMPL_CFG_PROBE_REQ_5, 51 wl->scan_templ_id_5,
52 NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0, 52 NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0,
53 WL1271_RATE_AUTOMATIC); 53 WL1271_RATE_AUTOMATIC);
54 if (ret < 0) 54 if (ret < 0)
@@ -56,14 +56,16 @@ int wl1271_init_templates_config(struct wl1271 *wl)
56 56
57 if (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL) { 57 if (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL) {
58 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 58 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
59 CMD_TEMPL_APP_PROBE_REQ_2_4, NULL, 59 wl->sched_scan_templ_id_2_4,
60 NULL,
60 WL1271_CMD_TEMPL_MAX_SIZE, 61 WL1271_CMD_TEMPL_MAX_SIZE,
61 0, WL1271_RATE_AUTOMATIC); 62 0, WL1271_RATE_AUTOMATIC);
62 if (ret < 0) 63 if (ret < 0)
63 return ret; 64 return ret;
64 65
65 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 66 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
66 CMD_TEMPL_APP_PROBE_REQ_5, NULL, 67 wl->sched_scan_templ_id_5,
68 NULL,
67 WL1271_CMD_TEMPL_MAX_SIZE, 69 WL1271_CMD_TEMPL_MAX_SIZE,
68 0, WL1271_RATE_AUTOMATIC); 70 0, WL1271_RATE_AUTOMATIC);
69 if (ret < 0) 71 if (ret < 0)
@@ -463,7 +465,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif)
463 if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES)) 465 if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES))
464 supported_rates = CONF_TX_OFDM_RATES; 466 supported_rates = CONF_TX_OFDM_RATES;
465 else 467 else
466 supported_rates = CONF_TX_AP_ENABLED_RATES; 468 supported_rates = CONF_TX_ENABLED_RATES;
467 469
468 /* unconditionally enable HT rates */ 470 /* unconditionally enable HT rates */
469 supported_rates |= CONF_TX_MCS_RATES; 471 supported_rates |= CONF_TX_MCS_RATES;
@@ -575,9 +577,6 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif)
575 /* Configure for power according to debugfs */ 577 /* Configure for power according to debugfs */
576 if (sta_auth != WL1271_PSM_ILLEGAL) 578 if (sta_auth != WL1271_PSM_ILLEGAL)
577 ret = wl1271_acx_sleep_auth(wl, sta_auth); 579 ret = wl1271_acx_sleep_auth(wl, sta_auth);
578 /* Configure for power always on */
579 else if (wl->quirks & WLCORE_QUIRK_NO_ELP)
580 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
581 /* Configure for ELP power saving */ 580 /* Configure for ELP power saving */
582 else 581 else
583 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); 582 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
@@ -679,6 +678,10 @@ int wl1271_hw_init(struct wl1271 *wl)
679 if (ret < 0) 678 if (ret < 0)
680 return ret; 679 return ret;
681 680
681 ret = wlcore_cmd_regdomain_config_locked(wl);
682 if (ret < 0)
683 return ret;
684
682 /* Bluetooth WLAN coexistence */ 685 /* Bluetooth WLAN coexistence */
683 ret = wl1271_init_pta(wl); 686 ret = wl1271_init_pta(wl);
684 if (ret < 0) 687 if (ret < 0)
diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h
index f48530fec14f..af7d9f9b3b4d 100644
--- a/drivers/net/wireless/ti/wlcore/io.h
+++ b/drivers/net/wireless/ti/wlcore/io.h
@@ -105,13 +105,13 @@ static inline int __must_check wlcore_raw_read32(struct wl1271 *wl, int addr,
105{ 105{
106 int ret; 106 int ret;
107 107
108 ret = wlcore_raw_read(wl, addr, &wl->buffer_32, 108 ret = wlcore_raw_read(wl, addr, wl->buffer_32,
109 sizeof(wl->buffer_32), false); 109 sizeof(*wl->buffer_32), false);
110 if (ret < 0) 110 if (ret < 0)
111 return ret; 111 return ret;
112 112
113 if (val) 113 if (val)
114 *val = le32_to_cpu(wl->buffer_32); 114 *val = le32_to_cpu(*wl->buffer_32);
115 115
116 return 0; 116 return 0;
117} 117}
@@ -119,9 +119,9 @@ static inline int __must_check wlcore_raw_read32(struct wl1271 *wl, int addr,
119static inline int __must_check wlcore_raw_write32(struct wl1271 *wl, int addr, 119static inline int __must_check wlcore_raw_write32(struct wl1271 *wl, int addr,
120 u32 val) 120 u32 val)
121{ 121{
122 wl->buffer_32 = cpu_to_le32(val); 122 *wl->buffer_32 = cpu_to_le32(val);
123 return wlcore_raw_write(wl, addr, &wl->buffer_32, 123 return wlcore_raw_write(wl, addr, wl->buffer_32,
124 sizeof(wl->buffer_32), false); 124 sizeof(*wl->buffer_32), false);
125} 125}
126 126
127static inline int __must_check wlcore_read(struct wl1271 *wl, int addr, 127static inline int __must_check wlcore_read(struct wl1271 *wl, int addr,
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index ce6e62a37e14..e1dfdf94d0f7 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -56,8 +56,8 @@
56#define WL1271_BOOT_RETRIES 3 56#define WL1271_BOOT_RETRIES 3
57 57
58static char *fwlog_param; 58static char *fwlog_param;
59static bool bug_on_recovery; 59static int bug_on_recovery = -1;
60static bool no_recovery; 60static int no_recovery = -1;
61 61
62static void __wl1271_op_remove_interface(struct wl1271 *wl, 62static void __wl1271_op_remove_interface(struct wl1271 *wl,
63 struct ieee80211_vif *vif, 63 struct ieee80211_vif *vif,
@@ -79,12 +79,10 @@ static int wl12xx_set_authorized(struct wl1271 *wl,
79 if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags)) 79 if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags))
80 return 0; 80 return 0;
81 81
82 ret = wl12xx_cmd_set_peer_state(wl, wlvif->sta.hlid); 82 ret = wl12xx_cmd_set_peer_state(wl, wlvif, wlvif->sta.hlid);
83 if (ret < 0) 83 if (ret < 0)
84 return ret; 84 return ret;
85 85
86 wl12xx_croc(wl, wlvif->role_id);
87
88 wl1271_info("Association completed."); 86 wl1271_info("Association completed.");
89 return 0; 87 return 0;
90} 88}
@@ -95,6 +93,8 @@ static void wl1271_reg_notify(struct wiphy *wiphy,
95 struct ieee80211_supported_band *band; 93 struct ieee80211_supported_band *band;
96 struct ieee80211_channel *ch; 94 struct ieee80211_channel *ch;
97 int i; 95 int i;
96 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
97 struct wl1271 *wl = hw->priv;
98 98
99 band = wiphy->bands[IEEE80211_BAND_5GHZ]; 99 band = wiphy->bands[IEEE80211_BAND_5GHZ];
100 for (i = 0; i < band->n_channels; i++) { 100 for (i = 0; i < band->n_channels; i++) {
@@ -107,6 +107,9 @@ static void wl1271_reg_notify(struct wiphy *wiphy,
107 IEEE80211_CHAN_PASSIVE_SCAN; 107 IEEE80211_CHAN_PASSIVE_SCAN;
108 108
109 } 109 }
110
111 if (likely(wl->state == WLCORE_STATE_ON))
112 wlcore_regdomain_config(wl);
110} 113}
111 114
112static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, 115static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
@@ -301,6 +304,7 @@ out:
301static void wlcore_adjust_conf(struct wl1271 *wl) 304static void wlcore_adjust_conf(struct wl1271 *wl)
302{ 305{
303 /* Adjust settings according to optional module parameters */ 306 /* Adjust settings according to optional module parameters */
307
304 if (fwlog_param) { 308 if (fwlog_param) {
305 if (!strcmp(fwlog_param, "continuous")) { 309 if (!strcmp(fwlog_param, "continuous")) {
306 wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS; 310 wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS;
@@ -316,16 +320,22 @@ static void wlcore_adjust_conf(struct wl1271 *wl)
316 wl1271_error("Unknown fwlog parameter %s", fwlog_param); 320 wl1271_error("Unknown fwlog parameter %s", fwlog_param);
317 } 321 }
318 } 322 }
323
324 if (bug_on_recovery != -1)
325 wl->conf.recovery.bug_on_recovery = (u8) bug_on_recovery;
326
327 if (no_recovery != -1)
328 wl->conf.recovery.no_recovery = (u8) no_recovery;
319} 329}
320 330
321static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, 331static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
322 struct wl12xx_vif *wlvif, 332 struct wl12xx_vif *wlvif,
323 u8 hlid, u8 tx_pkts) 333 u8 hlid, u8 tx_pkts)
324{ 334{
325 bool fw_ps, single_sta; 335 bool fw_ps, single_link;
326 336
327 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 337 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
328 single_sta = (wl->active_sta_count == 1); 338 single_link = (wl->active_link_count == 1);
329 339
330 /* 340 /*
331 * Wake up from high level PS if the STA is asleep with too little 341 * Wake up from high level PS if the STA is asleep with too little
@@ -336,10 +346,10 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
336 346
337 /* 347 /*
338 * Start high-level PS if the STA is asleep with enough blocks in FW. 348 * Start high-level PS if the STA is asleep with enough blocks in FW.
339 * Make an exception if this is the only connected station. In this 349 * Make an exception if this is the only connected link. In this
340 * case FW-memory congestion is not a problem. 350 * case FW-memory congestion is less of a problem.
341 */ 351 */
342 else if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) 352 else if (!single_link && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
343 wl12xx_ps_link_start(wl, wlvif, hlid, true); 353 wl12xx_ps_link_start(wl, wlvif, hlid, true);
344} 354}
345 355
@@ -347,11 +357,8 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
347 struct wl12xx_vif *wlvif, 357 struct wl12xx_vif *wlvif,
348 struct wl_fw_status_2 *status) 358 struct wl_fw_status_2 *status)
349{ 359{
350 struct wl1271_link *lnk;
351 u32 cur_fw_ps_map; 360 u32 cur_fw_ps_map;
352 u8 hlid, cnt; 361 u8 hlid;
353
354 /* TODO: also use link_fast_bitmap here */
355 362
356 cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap); 363 cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap);
357 if (wl->ap_fw_ps_map != cur_fw_ps_map) { 364 if (wl->ap_fw_ps_map != cur_fw_ps_map) {
@@ -363,17 +370,9 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
363 wl->ap_fw_ps_map = cur_fw_ps_map; 370 wl->ap_fw_ps_map = cur_fw_ps_map;
364 } 371 }
365 372
366 for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) { 373 for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS)
367 lnk = &wl->links[hlid];
368 cnt = status->counters.tx_lnk_free_pkts[hlid] -
369 lnk->prev_freed_pkts;
370
371 lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[hlid];
372 lnk->allocated_pkts -= cnt;
373
374 wl12xx_irq_ps_regulate_link(wl, wlvif, hlid, 374 wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
375 lnk->allocated_pkts); 375 wl->links[hlid].allocated_pkts);
376 }
377} 376}
378 377
379static int wlcore_fw_status(struct wl1271 *wl, 378static int wlcore_fw_status(struct wl1271 *wl,
@@ -387,6 +386,7 @@ static int wlcore_fw_status(struct wl1271 *wl,
387 int i; 386 int i;
388 size_t status_len; 387 size_t status_len;
389 int ret; 388 int ret;
389 struct wl1271_link *lnk;
390 390
391 status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + 391 status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
392 sizeof(*status_2) + wl->fw_status_priv_len; 392 sizeof(*status_2) + wl->fw_status_priv_len;
@@ -412,6 +412,17 @@ static int wlcore_fw_status(struct wl1271 *wl,
412 wl->tx_pkts_freed[i] = status_2->counters.tx_released_pkts[i]; 412 wl->tx_pkts_freed[i] = status_2->counters.tx_released_pkts[i];
413 } 413 }
414 414
415
416 for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) {
417 lnk = &wl->links[i];
418 /* prevent wrap-around in freed-packets counter */
419 lnk->allocated_pkts -=
420 (status_2->counters.tx_lnk_free_pkts[i] -
421 lnk->prev_freed_pkts) & 0xff;
422
423 lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i];
424 }
425
415 /* prevent wrap-around in total blocks counter */ 426 /* prevent wrap-around in total blocks counter */
416 if (likely(wl->tx_blocks_freed <= 427 if (likely(wl->tx_blocks_freed <=
417 le32_to_cpu(status_2->total_released_blks))) 428 le32_to_cpu(status_2->total_released_blks)))
@@ -464,6 +475,8 @@ static int wlcore_fw_status(struct wl1271 *wl,
464 wl->time_offset = (timespec_to_ns(&ts) >> 10) - 475 wl->time_offset = (timespec_to_ns(&ts) >> 10) -
465 (s64)le32_to_cpu(status_2->fw_localtime); 476 (s64)le32_to_cpu(status_2->fw_localtime);
466 477
478 wl->fw_fast_lnk_map = le32_to_cpu(status_2->link_fast_bitmap);
479
467 return 0; 480 return 0;
468} 481}
469 482
@@ -800,11 +813,13 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
800 813
801 /* 814 /*
802 * Make sure the chip is awake and the logger isn't active. 815 * Make sure the chip is awake and the logger isn't active.
803 * Do not send a stop fwlog command if the fw is hanged. 816 * Do not send a stop fwlog command if the fw is hanged or if
817 * dbgpins are used (due to some fw bug).
804 */ 818 */
805 if (wl1271_ps_elp_wakeup(wl)) 819 if (wl1271_ps_elp_wakeup(wl))
806 goto out; 820 goto out;
807 if (!wl->watchdog_recovery) 821 if (!wl->watchdog_recovery &&
822 wl->conf.fwlog.output != WL12XX_FWLOG_OUTPUT_DBG_PINS)
808 wl12xx_cmd_stop_fwlog(wl); 823 wl12xx_cmd_stop_fwlog(wl);
809 824
810 /* Read the first memory block address */ 825 /* Read the first memory block address */
@@ -872,7 +887,8 @@ static void wlcore_print_recovery(struct wl1271 *wl)
872 if (ret < 0) 887 if (ret < 0)
873 return; 888 return;
874 889
875 wl1271_info("pc: 0x%x, hint_sts: 0x%08x", pc, hint_sts); 890 wl1271_info("pc: 0x%x, hint_sts: 0x%08x count: %d",
891 pc, hint_sts, ++wl->recovery_count);
876 892
877 wlcore_set_partition(wl, &wl->ptable[PART_WORK]); 893 wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
878} 894}
@@ -895,10 +911,10 @@ static void wl1271_recovery_work(struct work_struct *work)
895 wlcore_print_recovery(wl); 911 wlcore_print_recovery(wl);
896 } 912 }
897 913
898 BUG_ON(bug_on_recovery && 914 BUG_ON(wl->conf.recovery.bug_on_recovery &&
899 !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); 915 !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
900 916
901 if (no_recovery) { 917 if (wl->conf.recovery.no_recovery) {
902 wl1271_info("No recovery (chosen on module load). Fw will remain stuck."); 918 wl1271_info("No recovery (chosen on module load). Fw will remain stuck.");
903 goto out_unlock; 919 goto out_unlock;
904 } 920 }
@@ -918,11 +934,6 @@ static void wl1271_recovery_work(struct work_struct *work)
918 /* Prevent spurious TX during FW restart */ 934 /* Prevent spurious TX during FW restart */
919 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART); 935 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
920 936
921 if (wl->sched_scanning) {
922 ieee80211_sched_scan_stopped(wl->hw);
923 wl->sched_scanning = false;
924 }
925
926 /* reboot the chipset */ 937 /* reboot the chipset */
927 while (!list_empty(&wl->wlvif_list)) { 938 while (!list_empty(&wl->wlvif_list)) {
928 wlvif = list_first_entry(&wl->wlvif_list, 939 wlvif = list_first_entry(&wl->wlvif_list,
@@ -1139,7 +1150,6 @@ int wl1271_plt_stop(struct wl1271 *wl)
1139 cancel_work_sync(&wl->recovery_work); 1150 cancel_work_sync(&wl->recovery_work);
1140 cancel_delayed_work_sync(&wl->elp_work); 1151 cancel_delayed_work_sync(&wl->elp_work);
1141 cancel_delayed_work_sync(&wl->tx_watchdog_work); 1152 cancel_delayed_work_sync(&wl->tx_watchdog_work);
1142 cancel_delayed_work_sync(&wl->connection_loss_work);
1143 1153
1144 mutex_lock(&wl->mutex); 1154 mutex_lock(&wl->mutex);
1145 wl1271_power_off(wl); 1155 wl1271_power_off(wl);
@@ -1167,9 +1177,13 @@ static void wl1271_op_tx(struct ieee80211_hw *hw,
1167 int q, mapping; 1177 int q, mapping;
1168 u8 hlid; 1178 u8 hlid;
1169 1179
1170 if (vif) 1180 if (!vif) {
1171 wlvif = wl12xx_vif_to_data(vif); 1181 wl1271_debug(DEBUG_TX, "DROP skb with no vif");
1182 ieee80211_free_txskb(hw, skb);
1183 return;
1184 }
1172 1185
1186 wlvif = wl12xx_vif_to_data(vif);
1173 mapping = skb_get_queue_mapping(skb); 1187 mapping = skb_get_queue_mapping(skb);
1174 q = wl1271_tx_get_queue(mapping); 1188 q = wl1271_tx_get_queue(mapping);
1175 1189
@@ -1183,9 +1197,9 @@ static void wl1271_op_tx(struct ieee80211_hw *hw,
1183 * allow these packets through. 1197 * allow these packets through.
1184 */ 1198 */
1185 if (hlid == WL12XX_INVALID_LINK_ID || 1199 if (hlid == WL12XX_INVALID_LINK_ID ||
1186 (wlvif && !test_bit(hlid, wlvif->links_map)) || 1200 (!test_bit(hlid, wlvif->links_map)) ||
1187 (wlcore_is_queue_stopped(wl, q) && 1201 (wlcore_is_queue_stopped_locked(wl, wlvif, q) &&
1188 !wlcore_is_queue_stopped_by_reason(wl, q, 1202 !wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, q,
1189 WLCORE_QUEUE_STOP_REASON_WATERMARK))) { 1203 WLCORE_QUEUE_STOP_REASON_WATERMARK))) {
1190 wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", hlid, q); 1204 wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", hlid, q);
1191 ieee80211_free_txskb(hw, skb); 1205 ieee80211_free_txskb(hw, skb);
@@ -1197,16 +1211,17 @@ static void wl1271_op_tx(struct ieee80211_hw *hw,
1197 skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); 1211 skb_queue_tail(&wl->links[hlid].tx_queue[q], skb);
1198 1212
1199 wl->tx_queue_count[q]++; 1213 wl->tx_queue_count[q]++;
1214 wlvif->tx_queue_count[q]++;
1200 1215
1201 /* 1216 /*
1202 * The workqueue is slow to process the tx_queue and we need stop 1217 * The workqueue is slow to process the tx_queue and we need stop
1203 * the queue here, otherwise the queue will get too long. 1218 * the queue here, otherwise the queue will get too long.
1204 */ 1219 */
1205 if (wl->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK && 1220 if (wlvif->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK &&
1206 !wlcore_is_queue_stopped_by_reason(wl, q, 1221 !wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, q,
1207 WLCORE_QUEUE_STOP_REASON_WATERMARK)) { 1222 WLCORE_QUEUE_STOP_REASON_WATERMARK)) {
1208 wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q); 1223 wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q);
1209 wlcore_stop_queue_locked(wl, q, 1224 wlcore_stop_queue_locked(wl, wlvif, q,
1210 WLCORE_QUEUE_STOP_REASON_WATERMARK); 1225 WLCORE_QUEUE_STOP_REASON_WATERMARK);
1211 } 1226 }
1212 1227
@@ -1841,11 +1856,10 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
1841 cancel_work_sync(&wl->tx_work); 1856 cancel_work_sync(&wl->tx_work);
1842 cancel_delayed_work_sync(&wl->elp_work); 1857 cancel_delayed_work_sync(&wl->elp_work);
1843 cancel_delayed_work_sync(&wl->tx_watchdog_work); 1858 cancel_delayed_work_sync(&wl->tx_watchdog_work);
1844 cancel_delayed_work_sync(&wl->connection_loss_work);
1845 1859
1846 /* let's notify MAC80211 about the remaining pending TX frames */ 1860 /* let's notify MAC80211 about the remaining pending TX frames */
1847 wl12xx_tx_reset(wl);
1848 mutex_lock(&wl->mutex); 1861 mutex_lock(&wl->mutex);
1862 wl12xx_tx_reset(wl);
1849 1863
1850 wl1271_power_off(wl); 1864 wl1271_power_off(wl);
1851 /* 1865 /*
@@ -1868,14 +1882,17 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
1868 wl->time_offset = 0; 1882 wl->time_offset = 0;
1869 wl->ap_fw_ps_map = 0; 1883 wl->ap_fw_ps_map = 0;
1870 wl->ap_ps_map = 0; 1884 wl->ap_ps_map = 0;
1871 wl->sched_scanning = false;
1872 wl->sleep_auth = WL1271_PSM_ILLEGAL; 1885 wl->sleep_auth = WL1271_PSM_ILLEGAL;
1873 memset(wl->roles_map, 0, sizeof(wl->roles_map)); 1886 memset(wl->roles_map, 0, sizeof(wl->roles_map));
1874 memset(wl->links_map, 0, sizeof(wl->links_map)); 1887 memset(wl->links_map, 0, sizeof(wl->links_map));
1875 memset(wl->roc_map, 0, sizeof(wl->roc_map)); 1888 memset(wl->roc_map, 0, sizeof(wl->roc_map));
1889 memset(wl->session_ids, 0, sizeof(wl->session_ids));
1876 wl->active_sta_count = 0; 1890 wl->active_sta_count = 0;
1891 wl->active_link_count = 0;
1877 1892
1878 /* The system link is always allocated */ 1893 /* The system link is always allocated */
1894 wl->links[WL12XX_SYSTEM_HLID].allocated_pkts = 0;
1895 wl->links[WL12XX_SYSTEM_HLID].prev_freed_pkts = 0;
1879 __set_bit(WL12XX_SYSTEM_HLID, wl->links_map); 1896 __set_bit(WL12XX_SYSTEM_HLID, wl->links_map);
1880 1897
1881 /* 1898 /*
@@ -1901,6 +1918,12 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
1901 wl->tx_res_if = NULL; 1918 wl->tx_res_if = NULL;
1902 kfree(wl->target_mem_map); 1919 kfree(wl->target_mem_map);
1903 wl->target_mem_map = NULL; 1920 wl->target_mem_map = NULL;
1921
1922 /*
1923 * FW channels must be re-calibrated after recovery,
1924 * clear the last Reg-Domain channel configuration.
1925 */
1926 memset(wl->reg_ch_conf_last, 0, sizeof(wl->reg_ch_conf_last));
1904} 1927}
1905 1928
1906static void wlcore_op_stop(struct ieee80211_hw *hw) 1929static void wlcore_op_stop(struct ieee80211_hw *hw)
@@ -1916,6 +1939,71 @@ static void wlcore_op_stop(struct ieee80211_hw *hw)
1916 mutex_unlock(&wl->mutex); 1939 mutex_unlock(&wl->mutex);
1917} 1940}
1918 1941
1942static void wlcore_channel_switch_work(struct work_struct *work)
1943{
1944 struct delayed_work *dwork;
1945 struct wl1271 *wl;
1946 struct ieee80211_vif *vif;
1947 struct wl12xx_vif *wlvif;
1948 int ret;
1949
1950 dwork = container_of(work, struct delayed_work, work);
1951 wlvif = container_of(dwork, struct wl12xx_vif, channel_switch_work);
1952 wl = wlvif->wl;
1953
1954 wl1271_info("channel switch failed (role_id: %d).", wlvif->role_id);
1955
1956 mutex_lock(&wl->mutex);
1957
1958 if (unlikely(wl->state != WLCORE_STATE_ON))
1959 goto out;
1960
1961 /* check the channel switch is still ongoing */
1962 if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags))
1963 goto out;
1964
1965 vif = wl12xx_wlvif_to_vif(wlvif);
1966 ieee80211_chswitch_done(vif, false);
1967
1968 ret = wl1271_ps_elp_wakeup(wl);
1969 if (ret < 0)
1970 goto out;
1971
1972 wl12xx_cmd_stop_channel_switch(wl, wlvif);
1973
1974 wl1271_ps_elp_sleep(wl);
1975out:
1976 mutex_unlock(&wl->mutex);
1977}
1978
1979static void wlcore_connection_loss_work(struct work_struct *work)
1980{
1981 struct delayed_work *dwork;
1982 struct wl1271 *wl;
1983 struct ieee80211_vif *vif;
1984 struct wl12xx_vif *wlvif;
1985
1986 dwork = container_of(work, struct delayed_work, work);
1987 wlvif = container_of(dwork, struct wl12xx_vif, connection_loss_work);
1988 wl = wlvif->wl;
1989
1990 wl1271_info("Connection loss work (role_id: %d).", wlvif->role_id);
1991
1992 mutex_lock(&wl->mutex);
1993
1994 if (unlikely(wl->state != WLCORE_STATE_ON))
1995 goto out;
1996
1997 /* Call mac80211 connection loss */
1998 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1999 goto out;
2000
2001 vif = wl12xx_wlvif_to_vif(wlvif);
2002 ieee80211_connection_loss(vif);
2003out:
2004 mutex_unlock(&wl->mutex);
2005}
2006
1919static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx) 2007static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx)
1920{ 2008{
1921 u8 policy = find_first_zero_bit(wl->rate_policies_map, 2009 u8 policy = find_first_zero_bit(wl->rate_policies_map,
@@ -2035,15 +2123,15 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
2035 for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++) 2123 for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
2036 wl12xx_allocate_rate_policy(wl, 2124 wl12xx_allocate_rate_policy(wl,
2037 &wlvif->ap.ucast_rate_idx[i]); 2125 &wlvif->ap.ucast_rate_idx[i]);
2038 wlvif->basic_rate_set = CONF_TX_AP_ENABLED_RATES; 2126 wlvif->basic_rate_set = CONF_TX_ENABLED_RATES;
2039 /* 2127 /*
2040 * TODO: check if basic_rate shouldn't be 2128 * TODO: check if basic_rate shouldn't be
2041 * wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 2129 * wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
2042 * instead (the same thing for STA above). 2130 * instead (the same thing for STA above).
2043 */ 2131 */
2044 wlvif->basic_rate = CONF_TX_AP_ENABLED_RATES; 2132 wlvif->basic_rate = CONF_TX_ENABLED_RATES;
2045 /* TODO: this seems to be used only for STA, check it */ 2133 /* TODO: this seems to be used only for STA, check it */
2046 wlvif->rate_set = CONF_TX_AP_ENABLED_RATES; 2134 wlvif->rate_set = CONF_TX_ENABLED_RATES;
2047 } 2135 }
2048 2136
2049 wlvif->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; 2137 wlvif->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate;
@@ -2063,6 +2151,10 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
2063 wl1271_rx_streaming_enable_work); 2151 wl1271_rx_streaming_enable_work);
2064 INIT_WORK(&wlvif->rx_streaming_disable_work, 2152 INIT_WORK(&wlvif->rx_streaming_disable_work,
2065 wl1271_rx_streaming_disable_work); 2153 wl1271_rx_streaming_disable_work);
2154 INIT_DELAYED_WORK(&wlvif->channel_switch_work,
2155 wlcore_channel_switch_work);
2156 INIT_DELAYED_WORK(&wlvif->connection_loss_work,
2157 wlcore_connection_loss_work);
2066 INIT_LIST_HEAD(&wlvif->list); 2158 INIT_LIST_HEAD(&wlvif->list);
2067 2159
2068 setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer, 2160 setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer,
@@ -2196,6 +2288,81 @@ static void wl12xx_force_active_psm(struct wl1271 *wl)
2196 } 2288 }
2197} 2289}
2198 2290
2291struct wlcore_hw_queue_iter_data {
2292 unsigned long hw_queue_map[BITS_TO_LONGS(WLCORE_NUM_MAC_ADDRESSES)];
2293 /* current vif */
2294 struct ieee80211_vif *vif;
2295 /* is the current vif among those iterated */
2296 bool cur_running;
2297};
2298
2299static void wlcore_hw_queue_iter(void *data, u8 *mac,
2300 struct ieee80211_vif *vif)
2301{
2302 struct wlcore_hw_queue_iter_data *iter_data = data;
2303
2304 if (WARN_ON_ONCE(vif->hw_queue[0] == IEEE80211_INVAL_HW_QUEUE))
2305 return;
2306
2307 if (iter_data->cur_running || vif == iter_data->vif) {
2308 iter_data->cur_running = true;
2309 return;
2310 }
2311
2312 __set_bit(vif->hw_queue[0] / NUM_TX_QUEUES, iter_data->hw_queue_map);
2313}
2314
2315static int wlcore_allocate_hw_queue_base(struct wl1271 *wl,
2316 struct wl12xx_vif *wlvif)
2317{
2318 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
2319 struct wlcore_hw_queue_iter_data iter_data = {};
2320 int i, q_base;
2321
2322 iter_data.vif = vif;
2323
2324 /* mark all bits taken by active interfaces */
2325 ieee80211_iterate_active_interfaces_atomic(wl->hw,
2326 IEEE80211_IFACE_ITER_RESUME_ALL,
2327 wlcore_hw_queue_iter, &iter_data);
2328
2329 /* the current vif is already running in mac80211 (resume/recovery) */
2330 if (iter_data.cur_running) {
2331 wlvif->hw_queue_base = vif->hw_queue[0];
2332 wl1271_debug(DEBUG_MAC80211,
2333 "using pre-allocated hw queue base %d",
2334 wlvif->hw_queue_base);
2335
2336 /* interface type might have changed type */
2337 goto adjust_cab_queue;
2338 }
2339
2340 q_base = find_first_zero_bit(iter_data.hw_queue_map,
2341 WLCORE_NUM_MAC_ADDRESSES);
2342 if (q_base >= WLCORE_NUM_MAC_ADDRESSES)
2343 return -EBUSY;
2344
2345 wlvif->hw_queue_base = q_base * NUM_TX_QUEUES;
2346 wl1271_debug(DEBUG_MAC80211, "allocating hw queue base: %d",
2347 wlvif->hw_queue_base);
2348
2349 for (i = 0; i < NUM_TX_QUEUES; i++) {
2350 wl->queue_stop_reasons[wlvif->hw_queue_base + i] = 0;
2351 /* register hw queues in mac80211 */
2352 vif->hw_queue[i] = wlvif->hw_queue_base + i;
2353 }
2354
2355adjust_cab_queue:
2356 /* the last places are reserved for cab queues per interface */
2357 if (wlvif->bss_type == BSS_TYPE_AP_BSS)
2358 vif->cab_queue = NUM_TX_QUEUES * WLCORE_NUM_MAC_ADDRESSES +
2359 wlvif->hw_queue_base / NUM_TX_QUEUES;
2360 else
2361 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
2362
2363 return 0;
2364}
2365
2199static int wl1271_op_add_interface(struct ieee80211_hw *hw, 2366static int wl1271_op_add_interface(struct ieee80211_hw *hw,
2200 struct ieee80211_vif *vif) 2367 struct ieee80211_vif *vif)
2201{ 2368{
@@ -2242,6 +2409,10 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
2242 goto out; 2409 goto out;
2243 } 2410 }
2244 2411
2412 ret = wlcore_allocate_hw_queue_base(wl, wlvif);
2413 if (ret < 0)
2414 goto out;
2415
2245 if (wl12xx_need_fw_change(wl, vif_count, true)) { 2416 if (wl12xx_need_fw_change(wl, vif_count, true)) {
2246 wl12xx_force_active_psm(wl); 2417 wl12xx_force_active_psm(wl);
2247 set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); 2418 set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
@@ -2312,7 +2483,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2312 wl1271_info("down"); 2483 wl1271_info("down");
2313 2484
2314 if (wl->scan.state != WL1271_SCAN_STATE_IDLE && 2485 if (wl->scan.state != WL1271_SCAN_STATE_IDLE &&
2315 wl->scan_vif == vif) { 2486 wl->scan_wlvif == wlvif) {
2316 /* 2487 /*
2317 * Rearm the tx watchdog just before idling scan. This 2488 * Rearm the tx watchdog just before idling scan. This
2318 * prevents just-finished scans from triggering the watchdog 2489 * prevents just-finished scans from triggering the watchdog
@@ -2321,11 +2492,21 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2321 2492
2322 wl->scan.state = WL1271_SCAN_STATE_IDLE; 2493 wl->scan.state = WL1271_SCAN_STATE_IDLE;
2323 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 2494 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
2324 wl->scan_vif = NULL; 2495 wl->scan_wlvif = NULL;
2325 wl->scan.req = NULL; 2496 wl->scan.req = NULL;
2326 ieee80211_scan_completed(wl->hw, true); 2497 ieee80211_scan_completed(wl->hw, true);
2327 } 2498 }
2328 2499
2500 if (wl->sched_vif == wlvif) {
2501 ieee80211_sched_scan_stopped(wl->hw);
2502 wl->sched_vif = NULL;
2503 }
2504
2505 if (wl->roc_vif == vif) {
2506 wl->roc_vif = NULL;
2507 ieee80211_remain_on_channel_expired(wl->hw);
2508 }
2509
2329 if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) { 2510 if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) {
2330 /* disable active roles */ 2511 /* disable active roles */
2331 ret = wl1271_ps_elp_wakeup(wl); 2512 ret = wl1271_ps_elp_wakeup(wl);
@@ -2394,9 +2575,6 @@ deinit:
2394 /* Configure for power according to debugfs */ 2575 /* Configure for power according to debugfs */
2395 if (sta_auth != WL1271_PSM_ILLEGAL) 2576 if (sta_auth != WL1271_PSM_ILLEGAL)
2396 wl1271_acx_sleep_auth(wl, sta_auth); 2577 wl1271_acx_sleep_auth(wl, sta_auth);
2397 /* Configure for power always on */
2398 else if (wl->quirks & WLCORE_QUIRK_NO_ELP)
2399 wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
2400 /* Configure for ELP power saving */ 2578 /* Configure for ELP power saving */
2401 else 2579 else
2402 wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); 2580 wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
@@ -2408,6 +2586,7 @@ unlock:
2408 del_timer_sync(&wlvif->rx_streaming_timer); 2586 del_timer_sync(&wlvif->rx_streaming_timer);
2409 cancel_work_sync(&wlvif->rx_streaming_enable_work); 2587 cancel_work_sync(&wlvif->rx_streaming_enable_work);
2410 cancel_work_sync(&wlvif->rx_streaming_disable_work); 2588 cancel_work_sync(&wlvif->rx_streaming_disable_work);
2589 cancel_delayed_work_sync(&wlvif->connection_loss_work);
2411 2590
2412 mutex_lock(&wl->mutex); 2591 mutex_lock(&wl->mutex);
2413} 2592}
@@ -2466,8 +2645,7 @@ static int wl12xx_op_change_interface(struct ieee80211_hw *hw,
2466 return ret; 2645 return ret;
2467} 2646}
2468 2647
2469static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif, 2648static int wlcore_join(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2470 bool set_assoc)
2471{ 2649{
2472 int ret; 2650 int ret;
2473 bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS); 2651 bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
@@ -2487,18 +2665,111 @@ static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2487 /* clear encryption type */ 2665 /* clear encryption type */
2488 wlvif->encryption_type = KEY_NONE; 2666 wlvif->encryption_type = KEY_NONE;
2489 2667
2490 if (set_assoc)
2491 set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags);
2492
2493 if (is_ibss) 2668 if (is_ibss)
2494 ret = wl12xx_cmd_role_start_ibss(wl, wlvif); 2669 ret = wl12xx_cmd_role_start_ibss(wl, wlvif);
2495 else 2670 else {
2671 if (wl->quirks & WLCORE_QUIRK_START_STA_FAILS) {
2672 /*
2673 * TODO: this is an ugly workaround for wl12xx fw
2674 * bug - we are not able to tx/rx after the first
2675 * start_sta, so make dummy start+stop calls,
2676 * and then call start_sta again.
2677 * this should be fixed in the fw.
2678 */
2679 wl12xx_cmd_role_start_sta(wl, wlvif);
2680 wl12xx_cmd_role_stop_sta(wl, wlvif);
2681 }
2682
2496 ret = wl12xx_cmd_role_start_sta(wl, wlvif); 2683 ret = wl12xx_cmd_role_start_sta(wl, wlvif);
2684 }
2685
2686 return ret;
2687}
2688
2689static int wl1271_ssid_set(struct wl12xx_vif *wlvif, struct sk_buff *skb,
2690 int offset)
2691{
2692 u8 ssid_len;
2693 const u8 *ptr = cfg80211_find_ie(WLAN_EID_SSID, skb->data + offset,
2694 skb->len - offset);
2695
2696 if (!ptr) {
2697 wl1271_error("No SSID in IEs!");
2698 return -ENOENT;
2699 }
2700
2701 ssid_len = ptr[1];
2702 if (ssid_len > IEEE80211_MAX_SSID_LEN) {
2703 wl1271_error("SSID is too long!");
2704 return -EINVAL;
2705 }
2706
2707 wlvif->ssid_len = ssid_len;
2708 memcpy(wlvif->ssid, ptr+2, ssid_len);
2709 return 0;
2710}
2711
2712static int wlcore_set_ssid(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2713{
2714 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
2715 struct sk_buff *skb;
2716 int ieoffset;
2717
2718 /* we currently only support setting the ssid from the ap probe req */
2719 if (wlvif->bss_type != BSS_TYPE_STA_BSS)
2720 return -EINVAL;
2721
2722 skb = ieee80211_ap_probereq_get(wl->hw, vif);
2723 if (!skb)
2724 return -EINVAL;
2725
2726 ieoffset = offsetof(struct ieee80211_mgmt,
2727 u.probe_req.variable);
2728 wl1271_ssid_set(wlvif, skb, ieoffset);
2729 dev_kfree_skb(skb);
2730
2731 return 0;
2732}
2733
2734static int wlcore_set_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2735 struct ieee80211_bss_conf *bss_conf,
2736 u32 sta_rate_set)
2737{
2738 int ieoffset;
2739 int ret;
2740
2741 wlvif->aid = bss_conf->aid;
2742 wlvif->channel_type = cfg80211_get_chandef_type(&bss_conf->chandef);
2743 wlvif->beacon_int = bss_conf->beacon_int;
2744 wlvif->wmm_enabled = bss_conf->qos;
2745
2746 set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags);
2747
2748 /*
2749 * with wl1271, we don't need to update the
2750 * beacon_int and dtim_period, because the firmware
2751 * updates it by itself when the first beacon is
2752 * received after a join.
2753 */
2754 ret = wl1271_cmd_build_ps_poll(wl, wlvif, wlvif->aid);
2497 if (ret < 0) 2755 if (ret < 0)
2498 goto out; 2756 return ret;
2499 2757
2500 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 2758 /*
2501 goto out; 2759 * Get a template for hardware connection maintenance
2760 */
2761 dev_kfree_skb(wlvif->probereq);
2762 wlvif->probereq = wl1271_cmd_build_ap_probe_req(wl,
2763 wlvif,
2764 NULL);
2765 ieoffset = offsetof(struct ieee80211_mgmt,
2766 u.probe_req.variable);
2767 wl1271_ssid_set(wlvif, wlvif->probereq, ieoffset);
2768
2769 /* enable the connection monitoring feature */
2770 ret = wl1271_acx_conn_monit_params(wl, wlvif, true);
2771 if (ret < 0)
2772 return ret;
2502 2773
2503 /* 2774 /*
2504 * The join command disable the keep-alive mode, shut down its process, 2775 * The join command disable the keep-alive mode, shut down its process,
@@ -2508,35 +2779,83 @@ static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2508 */ 2779 */
2509 ret = wl1271_acx_keep_alive_mode(wl, wlvif, true); 2780 ret = wl1271_acx_keep_alive_mode(wl, wlvif, true);
2510 if (ret < 0) 2781 if (ret < 0)
2511 goto out; 2782 return ret;
2512 2783
2513 ret = wl1271_acx_aid(wl, wlvif, wlvif->aid); 2784 ret = wl1271_acx_aid(wl, wlvif, wlvif->aid);
2514 if (ret < 0) 2785 if (ret < 0)
2515 goto out; 2786 return ret;
2516 2787
2517 ret = wl12xx_cmd_build_klv_null_data(wl, wlvif); 2788 ret = wl12xx_cmd_build_klv_null_data(wl, wlvif);
2518 if (ret < 0) 2789 if (ret < 0)
2519 goto out; 2790 return ret;
2520 2791
2521 ret = wl1271_acx_keep_alive_config(wl, wlvif, 2792 ret = wl1271_acx_keep_alive_config(wl, wlvif,
2522 wlvif->sta.klv_template_id, 2793 wlvif->sta.klv_template_id,
2523 ACX_KEEP_ALIVE_TPL_VALID); 2794 ACX_KEEP_ALIVE_TPL_VALID);
2524 if (ret < 0) 2795 if (ret < 0)
2525 goto out; 2796 return ret;
2797
2798 /*
2799 * The default fw psm configuration is AUTO, while mac80211 default
2800 * setting is off (ACTIVE), so sync the fw with the correct value.
2801 */
2802 ret = wl1271_ps_set_mode(wl, wlvif, STATION_ACTIVE_MODE);
2803 if (ret < 0)
2804 return ret;
2805
2806 if (sta_rate_set) {
2807 wlvif->rate_set =
2808 wl1271_tx_enabled_rates_get(wl,
2809 sta_rate_set,
2810 wlvif->band);
2811 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
2812 if (ret < 0)
2813 return ret;
2814 }
2526 2815
2527out:
2528 return ret; 2816 return ret;
2529} 2817}
2530 2818
2531static int wl1271_unjoin(struct wl1271 *wl, struct wl12xx_vif *wlvif) 2819static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2532{ 2820{
2533 int ret; 2821 int ret;
2822 bool sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
2823
2824 /* make sure we are connected (sta) joined */
2825 if (sta &&
2826 !test_and_clear_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
2827 return false;
2828
2829 /* make sure we are joined (ibss) */
2830 if (!sta &&
2831 test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags))
2832 return false;
2833
2834 if (sta) {
2835 /* use defaults when not associated */
2836 wlvif->aid = 0;
2837
2838 /* free probe-request template */
2839 dev_kfree_skb(wlvif->probereq);
2840 wlvif->probereq = NULL;
2841
2842 /* disable connection monitor features */
2843 ret = wl1271_acx_conn_monit_params(wl, wlvif, false);
2844 if (ret < 0)
2845 return ret;
2846
2847 /* Disable the keep-alive feature */
2848 ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
2849 if (ret < 0)
2850 return ret;
2851 }
2534 2852
2535 if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) { 2853 if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) {
2536 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 2854 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
2537 2855
2538 wl12xx_cmd_stop_channel_switch(wl); 2856 wl12xx_cmd_stop_channel_switch(wl, wlvif);
2539 ieee80211_chswitch_done(vif, false); 2857 ieee80211_chswitch_done(vif, false);
2858 cancel_delayed_work(&wlvif->channel_switch_work);
2540 } 2859 }
2541 2860
2542 /* invalidate keep-alive template */ 2861 /* invalidate keep-alive template */
@@ -2544,17 +2863,11 @@ static int wl1271_unjoin(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2544 wlvif->sta.klv_template_id, 2863 wlvif->sta.klv_template_id,
2545 ACX_KEEP_ALIVE_TPL_INVALID); 2864 ACX_KEEP_ALIVE_TPL_INVALID);
2546 2865
2547 /* to stop listening to a channel, we disconnect */
2548 ret = wl12xx_cmd_role_stop_sta(wl, wlvif);
2549 if (ret < 0)
2550 goto out;
2551
2552 /* reset TX security counters on a clean disconnect */ 2866 /* reset TX security counters on a clean disconnect */
2553 wlvif->tx_security_last_seq_lsb = 0; 2867 wlvif->tx_security_last_seq_lsb = 0;
2554 wlvif->tx_security_seq = 0; 2868 wlvif->tx_security_seq = 0;
2555 2869
2556out: 2870 return 0;
2557 return ret;
2558} 2871}
2559 2872
2560static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif) 2873static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
@@ -2563,147 +2876,10 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2563 wlvif->rate_set = wlvif->basic_rate_set; 2876 wlvif->rate_set = wlvif->basic_rate_set;
2564} 2877}
2565 2878
2566static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2567 bool idle)
2568{
2569 int ret;
2570 bool cur_idle = !test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
2571
2572 if (idle == cur_idle)
2573 return 0;
2574
2575 if (idle) {
2576 /* no need to croc if we weren't busy (e.g. during boot) */
2577 if (wl12xx_dev_role_started(wlvif)) {
2578 ret = wl12xx_stop_dev(wl, wlvif);
2579 if (ret < 0)
2580 goto out;
2581 }
2582 wlvif->rate_set =
2583 wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
2584 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
2585 if (ret < 0)
2586 goto out;
2587 clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
2588 } else {
2589 /* The current firmware only supports sched_scan in idle */
2590 if (wl->sched_scanning) {
2591 wl1271_scan_sched_scan_stop(wl, wlvif);
2592 ieee80211_sched_scan_stopped(wl->hw);
2593 }
2594
2595 ret = wl12xx_start_dev(wl, wlvif);
2596 if (ret < 0)
2597 goto out;
2598 set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
2599 }
2600
2601out:
2602 return ret;
2603}
2604
2605static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, 2879static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2606 struct ieee80211_conf *conf, u32 changed) 2880 struct ieee80211_conf *conf, u32 changed)
2607{ 2881{
2608 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 2882 int ret;
2609 int channel, ret;
2610
2611 channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
2612
2613 /* if the channel changes while joined, join again */
2614 if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&
2615 ((wlvif->band != conf->channel->band) ||
2616 (wlvif->channel != channel) ||
2617 (wlvif->channel_type != conf->channel_type))) {
2618 /* send all pending packets */
2619 ret = wlcore_tx_work_locked(wl);
2620 if (ret < 0)
2621 return ret;
2622
2623 wlvif->band = conf->channel->band;
2624 wlvif->channel = channel;
2625 wlvif->channel_type = conf->channel_type;
2626
2627 if (is_ap) {
2628 wl1271_set_band_rate(wl, wlvif);
2629 ret = wl1271_init_ap_rates(wl, wlvif);
2630 if (ret < 0)
2631 wl1271_error("AP rate policy change failed %d",
2632 ret);
2633 } else {
2634 /*
2635 * FIXME: the mac80211 should really provide a fixed
2636 * rate to use here. for now, just use the smallest
2637 * possible rate for the band as a fixed rate for
2638 * association frames and other control messages.
2639 */
2640 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
2641 wl1271_set_band_rate(wl, wlvif);
2642
2643 wlvif->basic_rate =
2644 wl1271_tx_min_rate_get(wl,
2645 wlvif->basic_rate_set);
2646 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
2647 if (ret < 0)
2648 wl1271_warning("rate policy for channel "
2649 "failed %d", ret);
2650
2651 /*
2652 * change the ROC channel. do it only if we are
2653 * not idle. otherwise, CROC will be called
2654 * anyway.
2655 */
2656 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED,
2657 &wlvif->flags) &&
2658 wl12xx_dev_role_started(wlvif) &&
2659 !(conf->flags & IEEE80211_CONF_IDLE)) {
2660 ret = wl12xx_stop_dev(wl, wlvif);
2661 if (ret < 0)
2662 return ret;
2663
2664 ret = wl12xx_start_dev(wl, wlvif);
2665 if (ret < 0)
2666 return ret;
2667 }
2668 }
2669 }
2670
2671 if ((changed & IEEE80211_CONF_CHANGE_PS) && !is_ap) {
2672
2673 if ((conf->flags & IEEE80211_CONF_PS) &&
2674 test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
2675 !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
2676
2677 int ps_mode;
2678 char *ps_mode_str;
2679
2680 if (wl->conf.conn.forced_ps) {
2681 ps_mode = STATION_POWER_SAVE_MODE;
2682 ps_mode_str = "forced";
2683 } else {
2684 ps_mode = STATION_AUTO_PS_MODE;
2685 ps_mode_str = "auto";
2686 }
2687
2688 wl1271_debug(DEBUG_PSM, "%s ps enabled", ps_mode_str);
2689
2690 ret = wl1271_ps_set_mode(wl, wlvif, ps_mode);
2691
2692 if (ret < 0)
2693 wl1271_warning("enter %s ps failed %d",
2694 ps_mode_str, ret);
2695
2696 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
2697 test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
2698
2699 wl1271_debug(DEBUG_PSM, "auto ps disabled");
2700
2701 ret = wl1271_ps_set_mode(wl, wlvif,
2702 STATION_ACTIVE_MODE);
2703 if (ret < 0)
2704 wl1271_warning("exit auto ps failed %d", ret);
2705 }
2706 }
2707 2883
2708 if (conf->power_level != wlvif->power_level) { 2884 if (conf->power_level != wlvif->power_level) {
2709 ret = wl1271_acx_tx_power(wl, wlvif, conf->power_level); 2885 ret = wl1271_acx_tx_power(wl, wlvif, conf->power_level);
@@ -2721,37 +2897,17 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
2721 struct wl1271 *wl = hw->priv; 2897 struct wl1271 *wl = hw->priv;
2722 struct wl12xx_vif *wlvif; 2898 struct wl12xx_vif *wlvif;
2723 struct ieee80211_conf *conf = &hw->conf; 2899 struct ieee80211_conf *conf = &hw->conf;
2724 int channel, ret = 0; 2900 int ret = 0;
2725
2726 channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
2727 2901
2728 wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s" 2902 wl1271_debug(DEBUG_MAC80211, "mac80211 config psm %s power %d %s"
2729 " changed 0x%x", 2903 " changed 0x%x",
2730 channel,
2731 conf->flags & IEEE80211_CONF_PS ? "on" : "off", 2904 conf->flags & IEEE80211_CONF_PS ? "on" : "off",
2732 conf->power_level, 2905 conf->power_level,
2733 conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use", 2906 conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use",
2734 changed); 2907 changed);
2735 2908
2736 /*
2737 * mac80211 will go to idle nearly immediately after transmitting some
2738 * frames, such as the deauth. To make sure those frames reach the air,
2739 * wait here until the TX queue is fully flushed.
2740 */
2741 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) ||
2742 ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
2743 (conf->flags & IEEE80211_CONF_IDLE)))
2744 wl1271_tx_flush(wl);
2745
2746 mutex_lock(&wl->mutex); 2909 mutex_lock(&wl->mutex);
2747 2910
2748 /* we support configuring the channel and band even while off */
2749 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
2750 wl->band = conf->channel->band;
2751 wl->channel = channel;
2752 wl->channel_type = conf->channel_type;
2753 }
2754
2755 if (changed & IEEE80211_CONF_CHANGE_POWER) 2911 if (changed & IEEE80211_CONF_CHANGE_POWER)
2756 wl->power_level = conf->power_level; 2912 wl->power_level = conf->power_level;
2757 2913
@@ -3071,10 +3227,7 @@ static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3071 * stop the queues and flush to ensure the next packets are 3227 * stop the queues and flush to ensure the next packets are
3072 * in sync with FW spare block accounting 3228 * in sync with FW spare block accounting
3073 */ 3229 */
3074 mutex_lock(&wl->mutex);
3075 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK); 3230 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
3076 mutex_unlock(&wl->mutex);
3077
3078 wl1271_tx_flush(wl); 3231 wl1271_tx_flush(wl);
3079 } 3232 }
3080 3233
@@ -3200,6 +3353,29 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3200} 3353}
3201EXPORT_SYMBOL_GPL(wlcore_set_key); 3354EXPORT_SYMBOL_GPL(wlcore_set_key);
3202 3355
3356void wlcore_regdomain_config(struct wl1271 *wl)
3357{
3358 int ret;
3359
3360 if (!(wl->quirks & WLCORE_QUIRK_REGDOMAIN_CONF))
3361 return;
3362
3363 mutex_lock(&wl->mutex);
3364 ret = wl1271_ps_elp_wakeup(wl);
3365 if (ret < 0)
3366 goto out;
3367
3368 ret = wlcore_cmd_regdomain_config_locked(wl);
3369 if (ret < 0) {
3370 wl12xx_queue_recovery_work(wl);
3371 goto out;
3372 }
3373
3374 wl1271_ps_elp_sleep(wl);
3375out:
3376 mutex_unlock(&wl->mutex);
3377}
3378
3203static int wl1271_op_hw_scan(struct ieee80211_hw *hw, 3379static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
3204 struct ieee80211_vif *vif, 3380 struct ieee80211_vif *vif,
3205 struct cfg80211_scan_request *req) 3381 struct cfg80211_scan_request *req)
@@ -3239,7 +3415,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
3239 goto out_sleep; 3415 goto out_sleep;
3240 } 3416 }
3241 3417
3242 ret = wl1271_scan(hw->priv, vif, ssid, len, req); 3418 ret = wlcore_scan(hw->priv, vif, ssid, len, req);
3243out_sleep: 3419out_sleep:
3244 wl1271_ps_elp_sleep(wl); 3420 wl1271_ps_elp_sleep(wl);
3245out: 3421out:
@@ -3252,6 +3428,7 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
3252 struct ieee80211_vif *vif) 3428 struct ieee80211_vif *vif)
3253{ 3429{
3254 struct wl1271 *wl = hw->priv; 3430 struct wl1271 *wl = hw->priv;
3431 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3255 int ret; 3432 int ret;
3256 3433
3257 wl1271_debug(DEBUG_MAC80211, "mac80211 cancel hw scan"); 3434 wl1271_debug(DEBUG_MAC80211, "mac80211 cancel hw scan");
@@ -3269,7 +3446,7 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
3269 goto out; 3446 goto out;
3270 3447
3271 if (wl->scan.state != WL1271_SCAN_STATE_DONE) { 3448 if (wl->scan.state != WL1271_SCAN_STATE_DONE) {
3272 ret = wl1271_scan_stop(wl); 3449 ret = wl->ops->scan_stop(wl, wlvif);
3273 if (ret < 0) 3450 if (ret < 0)
3274 goto out_sleep; 3451 goto out_sleep;
3275 } 3452 }
@@ -3282,7 +3459,7 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
3282 3459
3283 wl->scan.state = WL1271_SCAN_STATE_IDLE; 3460 wl->scan.state = WL1271_SCAN_STATE_IDLE;
3284 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 3461 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
3285 wl->scan_vif = NULL; 3462 wl->scan_wlvif = NULL;
3286 wl->scan.req = NULL; 3463 wl->scan.req = NULL;
3287 ieee80211_scan_completed(wl->hw, true); 3464 ieee80211_scan_completed(wl->hw, true);
3288 3465
@@ -3316,15 +3493,11 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
3316 if (ret < 0) 3493 if (ret < 0)
3317 goto out; 3494 goto out;
3318 3495
3319 ret = wl1271_scan_sched_scan_config(wl, wlvif, req, ies); 3496 ret = wl->ops->sched_scan_start(wl, wlvif, req, ies);
3320 if (ret < 0) 3497 if (ret < 0)
3321 goto out_sleep; 3498 goto out_sleep;
3322 3499
3323 ret = wl1271_scan_sched_scan_start(wl, wlvif); 3500 wl->sched_vif = wlvif;
3324 if (ret < 0)
3325 goto out_sleep;
3326
3327 wl->sched_scanning = true;
3328 3501
3329out_sleep: 3502out_sleep:
3330 wl1271_ps_elp_sleep(wl); 3503 wl1271_ps_elp_sleep(wl);
@@ -3351,7 +3524,7 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
3351 if (ret < 0) 3524 if (ret < 0)
3352 goto out; 3525 goto out;
3353 3526
3354 wl1271_scan_sched_scan_stop(wl, wlvif); 3527 wl->ops->sched_scan_stop(wl, wlvif);
3355 3528
3356 wl1271_ps_elp_sleep(wl); 3529 wl1271_ps_elp_sleep(wl);
3357out: 3530out:
@@ -3416,30 +3589,6 @@ out:
3416 return ret; 3589 return ret;
3417} 3590}
3418 3591
3419static int wl1271_ssid_set(struct ieee80211_vif *vif, struct sk_buff *skb,
3420 int offset)
3421{
3422 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3423 u8 ssid_len;
3424 const u8 *ptr = cfg80211_find_ie(WLAN_EID_SSID, skb->data + offset,
3425 skb->len - offset);
3426
3427 if (!ptr) {
3428 wl1271_error("No SSID in IEs!");
3429 return -ENOENT;
3430 }
3431
3432 ssid_len = ptr[1];
3433 if (ssid_len > IEEE80211_MAX_SSID_LEN) {
3434 wl1271_error("SSID is too long!");
3435 return -EINVAL;
3436 }
3437
3438 wlvif->ssid_len = ssid_len;
3439 memcpy(wlvif->ssid, ptr+2, ssid_len);
3440 return 0;
3441}
3442
3443static void wl12xx_remove_ie(struct sk_buff *skb, u8 eid, int ieoffset) 3592static void wl12xx_remove_ie(struct sk_buff *skb, u8 eid, int ieoffset)
3444{ 3593{
3445 int len; 3594 int len;
@@ -3620,7 +3769,7 @@ static int wlcore_set_beacon_template(struct wl1271 *wl,
3620 3769
3621 wl1271_debug(DEBUG_MASTER, "beacon updated"); 3770 wl1271_debug(DEBUG_MASTER, "beacon updated");
3622 3771
3623 ret = wl1271_ssid_set(vif, beacon, ieoffset); 3772 ret = wl1271_ssid_set(wlvif, beacon, ieoffset);
3624 if (ret < 0) { 3773 if (ret < 0) {
3625 dev_kfree_skb(beacon); 3774 dev_kfree_skb(beacon);
3626 goto out; 3775 goto out;
@@ -3637,6 +3786,12 @@ static int wlcore_set_beacon_template(struct wl1271 *wl,
3637 goto out; 3786 goto out;
3638 } 3787 }
3639 3788
3789 wlvif->wmm_enabled =
3790 cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
3791 WLAN_OUI_TYPE_MICROSOFT_WMM,
3792 beacon->data + ieoffset,
3793 beacon->len - ieoffset);
3794
3640 /* 3795 /*
3641 * In case we already have a probe-resp beacon set explicitly 3796 * In case we already have a probe-resp beacon set explicitly
3642 * by usermode, don't use the beacon data. 3797 * by usermode, don't use the beacon data.
@@ -3690,7 +3845,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
3690 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 3845 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
3691 int ret = 0; 3846 int ret = 0;
3692 3847
3693 if ((changed & BSS_CHANGED_BEACON_INT)) { 3848 if (changed & BSS_CHANGED_BEACON_INT) {
3694 wl1271_debug(DEBUG_MASTER, "beacon interval updated: %d", 3849 wl1271_debug(DEBUG_MASTER, "beacon interval updated: %d",
3695 bss_conf->beacon_int); 3850 bss_conf->beacon_int);
3696 3851
@@ -3703,7 +3858,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
3703 wl1271_ap_set_probe_resp_tmpl(wl, rate, vif); 3858 wl1271_ap_set_probe_resp_tmpl(wl, rate, vif);
3704 } 3859 }
3705 3860
3706 if ((changed & BSS_CHANGED_BEACON)) { 3861 if (changed & BSS_CHANGED_BEACON) {
3707 ret = wlcore_set_beacon_template(wl, vif, is_ap); 3862 ret = wlcore_set_beacon_template(wl, vif, is_ap);
3708 if (ret < 0) 3863 if (ret < 0)
3709 goto out; 3864 goto out;
@@ -3724,7 +3879,7 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
3724 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 3879 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3725 int ret = 0; 3880 int ret = 0;
3726 3881
3727 if ((changed & BSS_CHANGED_BASIC_RATES)) { 3882 if (changed & BSS_CHANGED_BASIC_RATES) {
3728 u32 rates = bss_conf->basic_rates; 3883 u32 rates = bss_conf->basic_rates;
3729 3884
3730 wlvif->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, 3885 wlvif->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates,
@@ -3755,7 +3910,7 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
3755 if (ret < 0) 3910 if (ret < 0)
3756 goto out; 3911 goto out;
3757 3912
3758 if ((changed & BSS_CHANGED_BEACON_ENABLED)) { 3913 if (changed & BSS_CHANGED_BEACON_ENABLED) {
3759 if (bss_conf->enable_beacon) { 3914 if (bss_conf->enable_beacon) {
3760 if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) { 3915 if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
3761 ret = wl12xx_cmd_role_start_ap(wl, wlvif); 3916 ret = wl12xx_cmd_role_start_ap(wl, wlvif);
@@ -3802,6 +3957,79 @@ out:
3802 return; 3957 return;
3803} 3958}
3804 3959
3960static int wlcore_set_bssid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
3961 struct ieee80211_bss_conf *bss_conf,
3962 u32 sta_rate_set)
3963{
3964 u32 rates;
3965 int ret;
3966
3967 wl1271_debug(DEBUG_MAC80211,
3968 "changed_bssid: %pM, aid: %d, bcn_int: %d, brates: 0x%x sta_rate_set: 0x%x",
3969 bss_conf->bssid, bss_conf->aid,
3970 bss_conf->beacon_int,
3971 bss_conf->basic_rates, sta_rate_set);
3972
3973 wlvif->beacon_int = bss_conf->beacon_int;
3974 rates = bss_conf->basic_rates;
3975 wlvif->basic_rate_set =
3976 wl1271_tx_enabled_rates_get(wl, rates,
3977 wlvif->band);
3978 wlvif->basic_rate =
3979 wl1271_tx_min_rate_get(wl,
3980 wlvif->basic_rate_set);
3981
3982 if (sta_rate_set)
3983 wlvif->rate_set =
3984 wl1271_tx_enabled_rates_get(wl,
3985 sta_rate_set,
3986 wlvif->band);
3987
3988 /* we only support sched_scan while not connected */
3989 if (wl->sched_vif == wlvif)
3990 wl->ops->sched_scan_stop(wl, wlvif);
3991
3992 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
3993 if (ret < 0)
3994 return ret;
3995
3996 ret = wl12xx_cmd_build_null_data(wl, wlvif);
3997 if (ret < 0)
3998 return ret;
3999
4000 ret = wl1271_build_qos_null_data(wl, wl12xx_wlvif_to_vif(wlvif));
4001 if (ret < 0)
4002 return ret;
4003
4004 wlcore_set_ssid(wl, wlvif);
4005
4006 set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
4007
4008 return 0;
4009}
4010
4011static int wlcore_clear_bssid(struct wl1271 *wl, struct wl12xx_vif *wlvif)
4012{
4013 int ret;
4014
4015 /* revert back to minimum rates for the current band */
4016 wl1271_set_band_rate(wl, wlvif);
4017 wlvif->basic_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
4018
4019 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
4020 if (ret < 0)
4021 return ret;
4022
4023 if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
4024 test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) {
4025 ret = wl12xx_cmd_role_stop_sta(wl, wlvif);
4026 if (ret < 0)
4027 return ret;
4028 }
4029
4030 clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
4031 return 0;
4032}
3805/* STA/IBSS mode changes */ 4033/* STA/IBSS mode changes */
3806static void wl1271_bss_info_changed_sta(struct wl1271 *wl, 4034static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3807 struct ieee80211_vif *vif, 4035 struct ieee80211_vif *vif,
@@ -3809,7 +4037,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3809 u32 changed) 4037 u32 changed)
3810{ 4038{
3811 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 4039 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3812 bool do_join = false, set_assoc = false; 4040 bool do_join = false;
3813 bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS); 4041 bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
3814 bool ibss_joined = false; 4042 bool ibss_joined = false;
3815 u32 sta_rate_set = 0; 4043 u32 sta_rate_set = 0;
@@ -3830,9 +4058,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3830 set_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags); 4058 set_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags);
3831 ibss_joined = true; 4059 ibss_joined = true;
3832 } else { 4060 } else {
3833 if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, 4061 wlcore_unset_assoc(wl, wlvif);
3834 &wlvif->flags)) 4062 wl12xx_cmd_role_stop_sta(wl, wlvif);
3835 wl1271_unjoin(wl, wlvif);
3836 } 4063 }
3837 } 4064 }
3838 4065
@@ -3850,13 +4077,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3850 do_join = true; 4077 do_join = true;
3851 } 4078 }
3852 4079
3853 if (changed & BSS_CHANGED_IDLE && !is_ibss) { 4080 if (changed & BSS_CHANGED_CQM) {
3854 ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle);
3855 if (ret < 0)
3856 wl1271_warning("idle mode change failed %d", ret);
3857 }
3858
3859 if ((changed & BSS_CHANGED_CQM)) {
3860 bool enable = false; 4081 bool enable = false;
3861 if (bss_conf->cqm_rssi_thold) 4082 if (bss_conf->cqm_rssi_thold)
3862 enable = true; 4083 enable = true;
@@ -3868,150 +4089,39 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3868 wlvif->rssi_thold = bss_conf->cqm_rssi_thold; 4089 wlvif->rssi_thold = bss_conf->cqm_rssi_thold;
3869 } 4090 }
3870 4091
3871 if (changed & BSS_CHANGED_BSSID) 4092 if (changed & (BSS_CHANGED_BSSID | BSS_CHANGED_HT |
3872 if (!is_zero_ether_addr(bss_conf->bssid)) { 4093 BSS_CHANGED_ASSOC)) {
3873 ret = wl12xx_cmd_build_null_data(wl, wlvif);
3874 if (ret < 0)
3875 goto out;
3876
3877 ret = wl1271_build_qos_null_data(wl, vif);
3878 if (ret < 0)
3879 goto out;
3880 }
3881
3882 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) {
3883 rcu_read_lock(); 4094 rcu_read_lock();
3884 sta = ieee80211_find_sta(vif, bss_conf->bssid); 4095 sta = ieee80211_find_sta(vif, bss_conf->bssid);
3885 if (!sta) 4096 if (sta) {
3886 goto sta_not_found; 4097 u8 *rx_mask = sta->ht_cap.mcs.rx_mask;
3887 4098
3888 /* save the supp_rates of the ap */ 4099 /* save the supp_rates of the ap */
3889 sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band]; 4100 sta_rate_set = sta->supp_rates[wlvif->band];
3890 if (sta->ht_cap.ht_supported) 4101 if (sta->ht_cap.ht_supported)
3891 sta_rate_set |= 4102 sta_rate_set |=
3892 (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) | 4103 (rx_mask[0] << HW_HT_RATES_OFFSET) |
3893 (sta->ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET); 4104 (rx_mask[1] << HW_MIMO_RATES_OFFSET);
3894 sta_ht_cap = sta->ht_cap; 4105 sta_ht_cap = sta->ht_cap;
3895 sta_exists = true; 4106 sta_exists = true;
3896 4107 }
3897sta_not_found: 4108
3898 rcu_read_unlock(); 4109 rcu_read_unlock();
3899 } 4110 }
3900 4111
3901 if ((changed & BSS_CHANGED_ASSOC)) { 4112 if (changed & BSS_CHANGED_BSSID) {
3902 if (bss_conf->assoc) { 4113 if (!is_zero_ether_addr(bss_conf->bssid)) {
3903 u32 rates; 4114 ret = wlcore_set_bssid(wl, wlvif, bss_conf,
3904 int ieoffset; 4115 sta_rate_set);
3905 wlvif->aid = bss_conf->aid;
3906 wlvif->channel_type =
3907 cfg80211_get_chandef_type(&bss_conf->chandef);
3908 wlvif->beacon_int = bss_conf->beacon_int;
3909 do_join = true;
3910 set_assoc = true;
3911
3912 /*
3913 * use basic rates from AP, and determine lowest rate
3914 * to use with control frames.
3915 */
3916 rates = bss_conf->basic_rates;
3917 wlvif->basic_rate_set =
3918 wl1271_tx_enabled_rates_get(wl, rates,
3919 wlvif->band);
3920 wlvif->basic_rate =
3921 wl1271_tx_min_rate_get(wl,
3922 wlvif->basic_rate_set);
3923 if (sta_rate_set)
3924 wlvif->rate_set =
3925 wl1271_tx_enabled_rates_get(wl,
3926 sta_rate_set,
3927 wlvif->band);
3928 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
3929 if (ret < 0)
3930 goto out;
3931
3932 /*
3933 * with wl1271, we don't need to update the
3934 * beacon_int and dtim_period, because the firmware
3935 * updates it by itself when the first beacon is
3936 * received after a join.
3937 */
3938 ret = wl1271_cmd_build_ps_poll(wl, wlvif, wlvif->aid);
3939 if (ret < 0) 4116 if (ret < 0)
3940 goto out; 4117 goto out;
3941 4118
3942 /* 4119 /* Need to update the BSSID (for filtering etc) */
3943 * Get a template for hardware connection maintenance 4120 do_join = true;
3944 */
3945 dev_kfree_skb(wlvif->probereq);
3946 wlvif->probereq = wl1271_cmd_build_ap_probe_req(wl,
3947 wlvif,
3948 NULL);
3949 ieoffset = offsetof(struct ieee80211_mgmt,
3950 u.probe_req.variable);
3951 wl1271_ssid_set(vif, wlvif->probereq, ieoffset);
3952
3953 /* enable the connection monitoring feature */
3954 ret = wl1271_acx_conn_monit_params(wl, wlvif, true);
3955 if (ret < 0)
3956 goto out;
3957 } else { 4121 } else {
3958 /* use defaults when not associated */ 4122 ret = wlcore_clear_bssid(wl, wlvif);
3959 bool was_assoc =
3960 !!test_and_clear_bit(WLVIF_FLAG_STA_ASSOCIATED,
3961 &wlvif->flags);
3962 bool was_ifup =
3963 !!test_and_clear_bit(WLVIF_FLAG_STA_STATE_SENT,
3964 &wlvif->flags);
3965 wlvif->aid = 0;
3966
3967 /* free probe-request template */
3968 dev_kfree_skb(wlvif->probereq);
3969 wlvif->probereq = NULL;
3970
3971 /* revert back to minimum rates for the current band */
3972 wl1271_set_band_rate(wl, wlvif);
3973 wlvif->basic_rate =
3974 wl1271_tx_min_rate_get(wl,
3975 wlvif->basic_rate_set);
3976 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
3977 if (ret < 0)
3978 goto out;
3979
3980 /* disable connection monitor features */
3981 ret = wl1271_acx_conn_monit_params(wl, wlvif, false);
3982
3983 /* Disable the keep-alive feature */
3984 ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
3985 if (ret < 0) 4123 if (ret < 0)
3986 goto out; 4124 goto out;
3987
3988 /* restore the bssid filter and go to dummy bssid */
3989 if (was_assoc) {
3990 /*
3991 * we might have to disable roc, if there was
3992 * no IF_OPER_UP notification.
3993 */
3994 if (!was_ifup) {
3995 ret = wl12xx_croc(wl, wlvif->role_id);
3996 if (ret < 0)
3997 goto out;
3998 }
3999 /*
4000 * (we also need to disable roc in case of
4001 * roaming on the same channel. until we will
4002 * have a better flow...)
4003 */
4004 if (test_bit(wlvif->dev_role_id, wl->roc_map)) {
4005 ret = wl12xx_croc(wl,
4006 wlvif->dev_role_id);
4007 if (ret < 0)
4008 goto out;
4009 }
4010
4011 wl1271_unjoin(wl, wlvif);
4012 if (!bss_conf->idle)
4013 wl12xx_start_dev(wl, wlvif);
4014 }
4015 } 4125 }
4016 } 4126 }
4017 4127
@@ -4041,71 +4151,87 @@ sta_not_found:
4041 goto out; 4151 goto out;
4042 4152
4043 if (do_join) { 4153 if (do_join) {
4044 ret = wl1271_join(wl, wlvif, set_assoc); 4154 ret = wlcore_join(wl, wlvif);
4045 if (ret < 0) { 4155 if (ret < 0) {
4046 wl1271_warning("cmd join failed %d", ret); 4156 wl1271_warning("cmd join failed %d", ret);
4047 goto out; 4157 goto out;
4048 } 4158 }
4159 }
4049 4160
4050 /* ROC until connected (after EAPOL exchange) */ 4161 if (changed & BSS_CHANGED_ASSOC) {
4051 if (!is_ibss) { 4162 if (bss_conf->assoc) {
4052 ret = wl12xx_roc(wl, wlvif, wlvif->role_id); 4163 ret = wlcore_set_assoc(wl, wlvif, bss_conf,
4164 sta_rate_set);
4053 if (ret < 0) 4165 if (ret < 0)
4054 goto out; 4166 goto out;
4055 4167
4056 if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags)) 4168 if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags))
4057 wl12xx_set_authorized(wl, wlvif); 4169 wl12xx_set_authorized(wl, wlvif);
4170 } else {
4171 wlcore_unset_assoc(wl, wlvif);
4058 } 4172 }
4059 /* 4173 }
4060 * stop device role if started (we might already be in 4174
4061 * STA/IBSS role). 4175 if (changed & BSS_CHANGED_PS) {
4062 */ 4176 if ((bss_conf->ps) &&
4063 if (wl12xx_dev_role_started(wlvif)) { 4177 test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
4064 ret = wl12xx_stop_dev(wl, wlvif); 4178 !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
4179 int ps_mode;
4180 char *ps_mode_str;
4181
4182 if (wl->conf.conn.forced_ps) {
4183 ps_mode = STATION_POWER_SAVE_MODE;
4184 ps_mode_str = "forced";
4185 } else {
4186 ps_mode = STATION_AUTO_PS_MODE;
4187 ps_mode_str = "auto";
4188 }
4189
4190 wl1271_debug(DEBUG_PSM, "%s ps enabled", ps_mode_str);
4191
4192 ret = wl1271_ps_set_mode(wl, wlvif, ps_mode);
4065 if (ret < 0) 4193 if (ret < 0)
4066 goto out; 4194 wl1271_warning("enter %s ps failed %d",
4195 ps_mode_str, ret);
4196 } else if (!bss_conf->ps &&
4197 test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
4198 wl1271_debug(DEBUG_PSM, "auto ps disabled");
4199
4200 ret = wl1271_ps_set_mode(wl, wlvif,
4201 STATION_ACTIVE_MODE);
4202 if (ret < 0)
4203 wl1271_warning("exit auto ps failed %d", ret);
4067 } 4204 }
4068 } 4205 }
4069 4206
4070 /* Handle new association with HT. Do this after join. */ 4207 /* Handle new association with HT. Do this after join. */
4071 if (sta_exists) { 4208 if (sta_exists &&
4072 if ((changed & BSS_CHANGED_HT) && 4209 (changed & BSS_CHANGED_HT)) {
4073 (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) { 4210 bool enabled =
4074 ret = wl1271_acx_set_ht_capabilities(wl, 4211 bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT;
4075 &sta_ht_cap, 4212
4076 true, 4213 ret = wlcore_hw_set_peer_cap(wl,
4077 wlvif->sta.hlid); 4214 &sta_ht_cap,
4078 if (ret < 0) { 4215 enabled,
4079 wl1271_warning("Set ht cap true failed %d", 4216 wlvif->rate_set,
4080 ret); 4217 wlvif->sta.hlid);
4081 goto out; 4218 if (ret < 0) {
4082 } 4219 wl1271_warning("Set ht cap failed %d", ret);
4220 goto out;
4221
4083 } 4222 }
4084 /* handle new association without HT and disassociation */ 4223
4085 else if (changed & BSS_CHANGED_ASSOC) { 4224 if (enabled) {
4086 ret = wl1271_acx_set_ht_capabilities(wl, 4225 ret = wl1271_acx_set_ht_information(wl, wlvif,
4087 &sta_ht_cap, 4226 bss_conf->ht_operation_mode);
4088 false,
4089 wlvif->sta.hlid);
4090 if (ret < 0) { 4227 if (ret < 0) {
4091 wl1271_warning("Set ht cap false failed %d", 4228 wl1271_warning("Set ht information failed %d",
4092 ret); 4229 ret);
4093 goto out; 4230 goto out;
4094 } 4231 }
4095 } 4232 }
4096 } 4233 }
4097 4234
4098 /* Handle HT information change. Done after join. */
4099 if ((changed & BSS_CHANGED_HT) &&
4100 (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
4101 ret = wl1271_acx_set_ht_information(wl, wlvif,
4102 bss_conf->ht_operation_mode);
4103 if (ret < 0) {
4104 wl1271_warning("Set ht information failed %d", ret);
4105 goto out;
4106 }
4107 }
4108
4109 /* Handle arp filtering. Done after join. */ 4235 /* Handle arp filtering. Done after join. */
4110 if ((changed & BSS_CHANGED_ARP_FILTER) || 4236 if ((changed & BSS_CHANGED_ARP_FILTER) ||
4111 (!is_ibss && (changed & BSS_CHANGED_QOS))) { 4237 (!is_ibss && (changed & BSS_CHANGED_QOS))) {
@@ -4113,8 +4239,7 @@ sta_not_found:
4113 wlvif->sta.qos = bss_conf->qos; 4239 wlvif->sta.qos = bss_conf->qos;
4114 WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS); 4240 WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS);
4115 4241
4116 if (bss_conf->arp_addr_cnt == 1 && 4242 if (bss_conf->arp_addr_cnt == 1 && bss_conf->assoc) {
4117 bss_conf->arp_filter_enabled) {
4118 wlvif->ip_addr = addr; 4243 wlvif->ip_addr = addr;
4119 /* 4244 /*
4120 * The template should have been configured only upon 4245 * The template should have been configured only upon
@@ -4155,15 +4280,15 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
4155 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 4280 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
4156 int ret; 4281 int ret;
4157 4282
4158 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x", 4283 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info role %d changed 0x%x",
4159 (int)changed); 4284 wlvif->role_id, (int)changed);
4160 4285
4161 /* 4286 /*
4162 * make sure to cancel pending disconnections if our association 4287 * make sure to cancel pending disconnections if our association
4163 * state changed 4288 * state changed
4164 */ 4289 */
4165 if (!is_ap && (changed & BSS_CHANGED_ASSOC)) 4290 if (!is_ap && (changed & BSS_CHANGED_ASSOC))
4166 cancel_delayed_work_sync(&wl->connection_loss_work); 4291 cancel_delayed_work_sync(&wlvif->connection_loss_work);
4167 4292
4168 if (is_ap && (changed & BSS_CHANGED_BEACON_ENABLED) && 4293 if (is_ap && (changed & BSS_CHANGED_BEACON_ENABLED) &&
4169 !bss_conf->enable_beacon) 4294 !bss_conf->enable_beacon)
@@ -4192,6 +4317,76 @@ out:
4192 mutex_unlock(&wl->mutex); 4317 mutex_unlock(&wl->mutex);
4193} 4318}
4194 4319
4320static int wlcore_op_add_chanctx(struct ieee80211_hw *hw,
4321 struct ieee80211_chanctx_conf *ctx)
4322{
4323 wl1271_debug(DEBUG_MAC80211, "mac80211 add chanctx %d (type %d)",
4324 ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
4325 cfg80211_get_chandef_type(&ctx->def));
4326 return 0;
4327}
4328
4329static void wlcore_op_remove_chanctx(struct ieee80211_hw *hw,
4330 struct ieee80211_chanctx_conf *ctx)
4331{
4332 wl1271_debug(DEBUG_MAC80211, "mac80211 remove chanctx %d (type %d)",
4333 ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
4334 cfg80211_get_chandef_type(&ctx->def));
4335}
4336
4337static void wlcore_op_change_chanctx(struct ieee80211_hw *hw,
4338 struct ieee80211_chanctx_conf *ctx,
4339 u32 changed)
4340{
4341 wl1271_debug(DEBUG_MAC80211,
4342 "mac80211 change chanctx %d (type %d) changed 0x%x",
4343 ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
4344 cfg80211_get_chandef_type(&ctx->def), changed);
4345}
4346
4347static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
4348 struct ieee80211_vif *vif,
4349 struct ieee80211_chanctx_conf *ctx)
4350{
4351 struct wl1271 *wl = hw->priv;
4352 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4353 int channel = ieee80211_frequency_to_channel(
4354 ctx->def.chan->center_freq);
4355
4356 wl1271_debug(DEBUG_MAC80211,
4357 "mac80211 assign chanctx (role %d) %d (type %d)",
4358 wlvif->role_id, channel, cfg80211_get_chandef_type(&ctx->def));
4359
4360 mutex_lock(&wl->mutex);
4361
4362 wlvif->band = ctx->def.chan->band;
4363 wlvif->channel = channel;
4364 wlvif->channel_type = cfg80211_get_chandef_type(&ctx->def);
4365
4366 /* update default rates according to the band */
4367 wl1271_set_band_rate(wl, wlvif);
4368
4369 mutex_unlock(&wl->mutex);
4370
4371 return 0;
4372}
4373
4374static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
4375 struct ieee80211_vif *vif,
4376 struct ieee80211_chanctx_conf *ctx)
4377{
4378 struct wl1271 *wl = hw->priv;
4379 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4380
4381 wl1271_debug(DEBUG_MAC80211,
4382 "mac80211 unassign chanctx (role %d) %d (type %d)",
4383 wlvif->role_id,
4384 ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
4385 cfg80211_get_chandef_type(&ctx->def));
4386
4387 wl1271_tx_flush(wl);
4388}
4389
4195static int wl1271_op_conf_tx(struct ieee80211_hw *hw, 4390static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
4196 struct ieee80211_vif *vif, u16 queue, 4391 struct ieee80211_vif *vif, u16 queue,
4197 const struct ieee80211_tx_queue_params *params) 4392 const struct ieee80211_tx_queue_params *params)
@@ -4319,8 +4514,6 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
4319 return; 4514 return;
4320 4515
4321 clear_bit(hlid, wlvif->ap.sta_hlid_map); 4516 clear_bit(hlid, wlvif->ap.sta_hlid_map);
4322 memset(wl->links[hlid].addr, 0, ETH_ALEN);
4323 wl->links[hlid].ba_bitmap = 0;
4324 __clear_bit(hlid, &wl->ap_ps_map); 4517 __clear_bit(hlid, &wl->ap_ps_map);
4325 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 4518 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
4326 wl12xx_free_link(wl, wlvif, &hlid); 4519 wl12xx_free_link(wl, wlvif, &hlid);
@@ -4380,6 +4573,45 @@ static int wl12xx_sta_remove(struct wl1271 *wl,
4380 return ret; 4573 return ret;
4381} 4574}
4382 4575
4576static void wlcore_roc_if_possible(struct wl1271 *wl,
4577 struct wl12xx_vif *wlvif)
4578{
4579 if (find_first_bit(wl->roc_map,
4580 WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES)
4581 return;
4582
4583 if (WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID))
4584 return;
4585
4586 wl12xx_roc(wl, wlvif, wlvif->role_id, wlvif->band, wlvif->channel);
4587}
4588
4589static void wlcore_update_inconn_sta(struct wl1271 *wl,
4590 struct wl12xx_vif *wlvif,
4591 struct wl1271_station *wl_sta,
4592 bool in_connection)
4593{
4594 if (in_connection) {
4595 if (WARN_ON(wl_sta->in_connection))
4596 return;
4597 wl_sta->in_connection = true;
4598 if (!wlvif->inconn_count++)
4599 wlcore_roc_if_possible(wl, wlvif);
4600 } else {
4601 if (!wl_sta->in_connection)
4602 return;
4603
4604 wl_sta->in_connection = false;
4605 wlvif->inconn_count--;
4606 if (WARN_ON(wlvif->inconn_count < 0))
4607 return;
4608
4609 if (!wlvif->inconn_count)
4610 if (test_bit(wlvif->role_id, wl->roc_map))
4611 wl12xx_croc(wl, wlvif->role_id);
4612 }
4613}
4614
4383static int wl12xx_update_sta_state(struct wl1271 *wl, 4615static int wl12xx_update_sta_state(struct wl1271 *wl,
4384 struct wl12xx_vif *wlvif, 4616 struct wl12xx_vif *wlvif,
4385 struct ieee80211_sta *sta, 4617 struct ieee80211_sta *sta,
@@ -4398,8 +4630,13 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
4398 /* Add station (AP mode) */ 4630 /* Add station (AP mode) */
4399 if (is_ap && 4631 if (is_ap &&
4400 old_state == IEEE80211_STA_NOTEXIST && 4632 old_state == IEEE80211_STA_NOTEXIST &&
4401 new_state == IEEE80211_STA_NONE) 4633 new_state == IEEE80211_STA_NONE) {
4402 return wl12xx_sta_add(wl, wlvif, sta); 4634 ret = wl12xx_sta_add(wl, wlvif, sta);
4635 if (ret)
4636 return ret;
4637
4638 wlcore_update_inconn_sta(wl, wlvif, wl_sta, true);
4639 }
4403 4640
4404 /* Remove station (AP mode) */ 4641 /* Remove station (AP mode) */
4405 if (is_ap && 4642 if (is_ap &&
@@ -4407,35 +4644,59 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
4407 new_state == IEEE80211_STA_NOTEXIST) { 4644 new_state == IEEE80211_STA_NOTEXIST) {
4408 /* must not fail */ 4645 /* must not fail */
4409 wl12xx_sta_remove(wl, wlvif, sta); 4646 wl12xx_sta_remove(wl, wlvif, sta);
4410 return 0; 4647
4648 wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
4411 } 4649 }
4412 4650
4413 /* Authorize station (AP mode) */ 4651 /* Authorize station (AP mode) */
4414 if (is_ap && 4652 if (is_ap &&
4415 new_state == IEEE80211_STA_AUTHORIZED) { 4653 new_state == IEEE80211_STA_AUTHORIZED) {
4416 ret = wl12xx_cmd_set_peer_state(wl, hlid); 4654 ret = wl12xx_cmd_set_peer_state(wl, wlvif, hlid);
4417 if (ret < 0) 4655 if (ret < 0)
4418 return ret; 4656 return ret;
4419 4657
4420 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, 4658 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true,
4421 hlid); 4659 hlid);
4422 return ret; 4660 if (ret)
4661 return ret;
4662
4663 wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
4423 } 4664 }
4424 4665
4425 /* Authorize station */ 4666 /* Authorize station */
4426 if (is_sta && 4667 if (is_sta &&
4427 new_state == IEEE80211_STA_AUTHORIZED) { 4668 new_state == IEEE80211_STA_AUTHORIZED) {
4428 set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); 4669 set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
4429 return wl12xx_set_authorized(wl, wlvif); 4670 ret = wl12xx_set_authorized(wl, wlvif);
4671 if (ret)
4672 return ret;
4430 } 4673 }
4431 4674
4432 if (is_sta && 4675 if (is_sta &&
4433 old_state == IEEE80211_STA_AUTHORIZED && 4676 old_state == IEEE80211_STA_AUTHORIZED &&
4434 new_state == IEEE80211_STA_ASSOC) { 4677 new_state == IEEE80211_STA_ASSOC) {
4435 clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); 4678 clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
4436 return 0; 4679 clear_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags);
4437 } 4680 }
4438 4681
4682 /* clear ROCs on failure or authorization */
4683 if (is_sta &&
4684 (new_state == IEEE80211_STA_AUTHORIZED ||
4685 new_state == IEEE80211_STA_NOTEXIST)) {
4686 if (test_bit(wlvif->role_id, wl->roc_map))
4687 wl12xx_croc(wl, wlvif->role_id);
4688 }
4689
4690 if (is_sta &&
4691 old_state == IEEE80211_STA_NOTEXIST &&
4692 new_state == IEEE80211_STA_NONE) {
4693 if (find_first_bit(wl->roc_map,
4694 WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES) {
4695 WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID);
4696 wl12xx_roc(wl, wlvif, wlvif->role_id,
4697 wlvif->band, wlvif->channel);
4698 }
4699 }
4439 return 0; 4700 return 0;
4440} 4701}
4441 4702
@@ -4500,18 +4761,18 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
4500 4761
4501 if (wlvif->bss_type == BSS_TYPE_STA_BSS) { 4762 if (wlvif->bss_type == BSS_TYPE_STA_BSS) {
4502 hlid = wlvif->sta.hlid; 4763 hlid = wlvif->sta.hlid;
4503 ba_bitmap = &wlvif->sta.ba_rx_bitmap;
4504 } else if (wlvif->bss_type == BSS_TYPE_AP_BSS) { 4764 } else if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
4505 struct wl1271_station *wl_sta; 4765 struct wl1271_station *wl_sta;
4506 4766
4507 wl_sta = (struct wl1271_station *)sta->drv_priv; 4767 wl_sta = (struct wl1271_station *)sta->drv_priv;
4508 hlid = wl_sta->hlid; 4768 hlid = wl_sta->hlid;
4509 ba_bitmap = &wl->links[hlid].ba_bitmap;
4510 } else { 4769 } else {
4511 ret = -EINVAL; 4770 ret = -EINVAL;
4512 goto out; 4771 goto out;
4513 } 4772 }
4514 4773
4774 ba_bitmap = &wl->links[hlid].ba_bitmap;
4775
4515 ret = wl1271_ps_elp_wakeup(wl); 4776 ret = wl1271_ps_elp_wakeup(wl);
4516 if (ret < 0) 4777 if (ret < 0)
4517 goto out; 4778 goto out;
@@ -4665,12 +4926,23 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
4665 4926
4666 /* TODO: change mac80211 to pass vif as param */ 4927 /* TODO: change mac80211 to pass vif as param */
4667 wl12xx_for_each_wlvif_sta(wl, wlvif) { 4928 wl12xx_for_each_wlvif_sta(wl, wlvif) {
4668 ret = wl12xx_cmd_channel_switch(wl, wlvif, ch_switch); 4929 unsigned long delay_usec;
4930
4931 ret = wl->ops->channel_switch(wl, wlvif, ch_switch);
4932 if (ret)
4933 goto out_sleep;
4934
4935 set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
4669 4936
4670 if (!ret) 4937 /* indicate failure 5 seconds after channel switch time */
4671 set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags); 4938 delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) *
4939 ch_switch->count;
4940 ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work,
4941 usecs_to_jiffies(delay_usec) +
4942 msecs_to_jiffies(5000));
4672 } 4943 }
4673 4944
4945out_sleep:
4674 wl1271_ps_elp_sleep(wl); 4946 wl1271_ps_elp_sleep(wl);
4675 4947
4676out: 4948out:
@@ -4684,6 +4956,144 @@ static void wlcore_op_flush(struct ieee80211_hw *hw, bool drop)
4684 wl1271_tx_flush(wl); 4956 wl1271_tx_flush(wl);
4685} 4957}
4686 4958
4959static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw,
4960 struct ieee80211_vif *vif,
4961 struct ieee80211_channel *chan,
4962 int duration)
4963{
4964 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4965 struct wl1271 *wl = hw->priv;
4966 int channel, ret = 0;
4967
4968 channel = ieee80211_frequency_to_channel(chan->center_freq);
4969
4970 wl1271_debug(DEBUG_MAC80211, "mac80211 roc %d (%d)",
4971 channel, wlvif->role_id);
4972
4973 mutex_lock(&wl->mutex);
4974
4975 if (unlikely(wl->state != WLCORE_STATE_ON))
4976 goto out;
4977
4978 /* return EBUSY if we can't ROC right now */
4979 if (WARN_ON(wl->roc_vif ||
4980 find_first_bit(wl->roc_map,
4981 WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES)) {
4982 ret = -EBUSY;
4983 goto out;
4984 }
4985
4986 ret = wl1271_ps_elp_wakeup(wl);
4987 if (ret < 0)
4988 goto out;
4989
4990 ret = wl12xx_start_dev(wl, wlvif, chan->band, channel);
4991 if (ret < 0)
4992 goto out_sleep;
4993
4994 wl->roc_vif = vif;
4995 ieee80211_queue_delayed_work(hw, &wl->roc_complete_work,
4996 msecs_to_jiffies(duration));
4997out_sleep:
4998 wl1271_ps_elp_sleep(wl);
4999out:
5000 mutex_unlock(&wl->mutex);
5001 return ret;
5002}
5003
5004static int __wlcore_roc_completed(struct wl1271 *wl)
5005{
5006 struct wl12xx_vif *wlvif;
5007 int ret;
5008
5009 /* already completed */
5010 if (unlikely(!wl->roc_vif))
5011 return 0;
5012
5013 wlvif = wl12xx_vif_to_data(wl->roc_vif);
5014
5015 if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
5016 return -EBUSY;
5017
5018 ret = wl12xx_stop_dev(wl, wlvif);
5019 if (ret < 0)
5020 return ret;
5021
5022 wl->roc_vif = NULL;
5023
5024 return 0;
5025}
5026
5027static int wlcore_roc_completed(struct wl1271 *wl)
5028{
5029 int ret;
5030
5031 wl1271_debug(DEBUG_MAC80211, "roc complete");
5032
5033 mutex_lock(&wl->mutex);
5034
5035 if (unlikely(wl->state != WLCORE_STATE_ON)) {
5036 ret = -EBUSY;
5037 goto out;
5038 }
5039
5040 ret = wl1271_ps_elp_wakeup(wl);
5041 if (ret < 0)
5042 goto out;
5043
5044 ret = __wlcore_roc_completed(wl);
5045
5046 wl1271_ps_elp_sleep(wl);
5047out:
5048 mutex_unlock(&wl->mutex);
5049
5050 return ret;
5051}
5052
5053static void wlcore_roc_complete_work(struct work_struct *work)
5054{
5055 struct delayed_work *dwork;
5056 struct wl1271 *wl;
5057 int ret;
5058
5059 dwork = container_of(work, struct delayed_work, work);
5060 wl = container_of(dwork, struct wl1271, roc_complete_work);
5061
5062 ret = wlcore_roc_completed(wl);
5063 if (!ret)
5064 ieee80211_remain_on_channel_expired(wl->hw);
5065}
5066
5067static int wlcore_op_cancel_remain_on_channel(struct ieee80211_hw *hw)
5068{
5069 struct wl1271 *wl = hw->priv;
5070
5071 wl1271_debug(DEBUG_MAC80211, "mac80211 croc");
5072
5073 /* TODO: per-vif */
5074 wl1271_tx_flush(wl);
5075
5076 /*
5077 * we can't just flush_work here, because it might deadlock
5078 * (as we might get called from the same workqueue)
5079 */
5080 cancel_delayed_work_sync(&wl->roc_complete_work);
5081 wlcore_roc_completed(wl);
5082
5083 return 0;
5084}
5085
5086static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
5087 struct ieee80211_vif *vif,
5088 struct ieee80211_sta *sta,
5089 u32 changed)
5090{
5091 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5092 struct wl1271 *wl = hw->priv;
5093
5094 wlcore_hw_sta_rc_update(wl, wlvif, sta, changed);
5095}
5096
4687static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) 5097static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
4688{ 5098{
4689 struct wl1271 *wl = hw->priv; 5099 struct wl1271 *wl = hw->priv;
@@ -4747,20 +5157,20 @@ static struct ieee80211_rate wl1271_rates[] = {
4747 5157
4748/* can't be const, mac80211 writes to this */ 5158/* can't be const, mac80211 writes to this */
4749static struct ieee80211_channel wl1271_channels[] = { 5159static struct ieee80211_channel wl1271_channels[] = {
4750 { .hw_value = 1, .center_freq = 2412, .max_power = 25 }, 5160 { .hw_value = 1, .center_freq = 2412, .max_power = WLCORE_MAX_TXPWR },
4751 { .hw_value = 2, .center_freq = 2417, .max_power = 25 }, 5161 { .hw_value = 2, .center_freq = 2417, .max_power = WLCORE_MAX_TXPWR },
4752 { .hw_value = 3, .center_freq = 2422, .max_power = 25 }, 5162 { .hw_value = 3, .center_freq = 2422, .max_power = WLCORE_MAX_TXPWR },
4753 { .hw_value = 4, .center_freq = 2427, .max_power = 25 }, 5163 { .hw_value = 4, .center_freq = 2427, .max_power = WLCORE_MAX_TXPWR },
4754 { .hw_value = 5, .center_freq = 2432, .max_power = 25 }, 5164 { .hw_value = 5, .center_freq = 2432, .max_power = WLCORE_MAX_TXPWR },
4755 { .hw_value = 6, .center_freq = 2437, .max_power = 25 }, 5165 { .hw_value = 6, .center_freq = 2437, .max_power = WLCORE_MAX_TXPWR },
4756 { .hw_value = 7, .center_freq = 2442, .max_power = 25 }, 5166 { .hw_value = 7, .center_freq = 2442, .max_power = WLCORE_MAX_TXPWR },
4757 { .hw_value = 8, .center_freq = 2447, .max_power = 25 }, 5167 { .hw_value = 8, .center_freq = 2447, .max_power = WLCORE_MAX_TXPWR },
4758 { .hw_value = 9, .center_freq = 2452, .max_power = 25 }, 5168 { .hw_value = 9, .center_freq = 2452, .max_power = WLCORE_MAX_TXPWR },
4759 { .hw_value = 10, .center_freq = 2457, .max_power = 25 }, 5169 { .hw_value = 10, .center_freq = 2457, .max_power = WLCORE_MAX_TXPWR },
4760 { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, 5170 { .hw_value = 11, .center_freq = 2462, .max_power = WLCORE_MAX_TXPWR },
4761 { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, 5171 { .hw_value = 12, .center_freq = 2467, .max_power = WLCORE_MAX_TXPWR },
4762 { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, 5172 { .hw_value = 13, .center_freq = 2472, .max_power = WLCORE_MAX_TXPWR },
4763 { .hw_value = 14, .center_freq = 2484, .max_power = 25 }, 5173 { .hw_value = 14, .center_freq = 2484, .max_power = WLCORE_MAX_TXPWR },
4764}; 5174};
4765 5175
4766/* can't be const, mac80211 writes to this */ 5176/* can't be const, mac80211 writes to this */
@@ -4801,40 +5211,40 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = {
4801 5211
4802/* 5 GHz band channels for WL1273 */ 5212/* 5 GHz band channels for WL1273 */
4803static struct ieee80211_channel wl1271_channels_5ghz[] = { 5213static struct ieee80211_channel wl1271_channels_5ghz[] = {
4804 { .hw_value = 7, .center_freq = 5035, .max_power = 25 }, 5214 { .hw_value = 7, .center_freq = 5035, .max_power = WLCORE_MAX_TXPWR },
4805 { .hw_value = 8, .center_freq = 5040, .max_power = 25 }, 5215 { .hw_value = 8, .center_freq = 5040, .max_power = WLCORE_MAX_TXPWR },
4806 { .hw_value = 9, .center_freq = 5045, .max_power = 25 }, 5216 { .hw_value = 9, .center_freq = 5045, .max_power = WLCORE_MAX_TXPWR },
4807 { .hw_value = 11, .center_freq = 5055, .max_power = 25 }, 5217 { .hw_value = 11, .center_freq = 5055, .max_power = WLCORE_MAX_TXPWR },
4808 { .hw_value = 12, .center_freq = 5060, .max_power = 25 }, 5218 { .hw_value = 12, .center_freq = 5060, .max_power = WLCORE_MAX_TXPWR },
4809 { .hw_value = 16, .center_freq = 5080, .max_power = 25 }, 5219 { .hw_value = 16, .center_freq = 5080, .max_power = WLCORE_MAX_TXPWR },
4810 { .hw_value = 34, .center_freq = 5170, .max_power = 25 }, 5220 { .hw_value = 34, .center_freq = 5170, .max_power = WLCORE_MAX_TXPWR },
4811 { .hw_value = 36, .center_freq = 5180, .max_power = 25 }, 5221 { .hw_value = 36, .center_freq = 5180, .max_power = WLCORE_MAX_TXPWR },
4812 { .hw_value = 38, .center_freq = 5190, .max_power = 25 }, 5222 { .hw_value = 38, .center_freq = 5190, .max_power = WLCORE_MAX_TXPWR },
4813 { .hw_value = 40, .center_freq = 5200, .max_power = 25 }, 5223 { .hw_value = 40, .center_freq = 5200, .max_power = WLCORE_MAX_TXPWR },
4814 { .hw_value = 42, .center_freq = 5210, .max_power = 25 }, 5224 { .hw_value = 42, .center_freq = 5210, .max_power = WLCORE_MAX_TXPWR },
4815 { .hw_value = 44, .center_freq = 5220, .max_power = 25 }, 5225 { .hw_value = 44, .center_freq = 5220, .max_power = WLCORE_MAX_TXPWR },
4816 { .hw_value = 46, .center_freq = 5230, .max_power = 25 }, 5226 { .hw_value = 46, .center_freq = 5230, .max_power = WLCORE_MAX_TXPWR },
4817 { .hw_value = 48, .center_freq = 5240, .max_power = 25 }, 5227 { .hw_value = 48, .center_freq = 5240, .max_power = WLCORE_MAX_TXPWR },
4818 { .hw_value = 52, .center_freq = 5260, .max_power = 25 }, 5228 { .hw_value = 52, .center_freq = 5260, .max_power = WLCORE_MAX_TXPWR },
4819 { .hw_value = 56, .center_freq = 5280, .max_power = 25 }, 5229 { .hw_value = 56, .center_freq = 5280, .max_power = WLCORE_MAX_TXPWR },
4820 { .hw_value = 60, .center_freq = 5300, .max_power = 25 }, 5230 { .hw_value = 60, .center_freq = 5300, .max_power = WLCORE_MAX_TXPWR },
4821 { .hw_value = 64, .center_freq = 5320, .max_power = 25 }, 5231 { .hw_value = 64, .center_freq = 5320, .max_power = WLCORE_MAX_TXPWR },
4822 { .hw_value = 100, .center_freq = 5500, .max_power = 25 }, 5232 { .hw_value = 100, .center_freq = 5500, .max_power = WLCORE_MAX_TXPWR },
4823 { .hw_value = 104, .center_freq = 5520, .max_power = 25 }, 5233 { .hw_value = 104, .center_freq = 5520, .max_power = WLCORE_MAX_TXPWR },
4824 { .hw_value = 108, .center_freq = 5540, .max_power = 25 }, 5234 { .hw_value = 108, .center_freq = 5540, .max_power = WLCORE_MAX_TXPWR },
4825 { .hw_value = 112, .center_freq = 5560, .max_power = 25 }, 5235 { .hw_value = 112, .center_freq = 5560, .max_power = WLCORE_MAX_TXPWR },
4826 { .hw_value = 116, .center_freq = 5580, .max_power = 25 }, 5236 { .hw_value = 116, .center_freq = 5580, .max_power = WLCORE_MAX_TXPWR },
4827 { .hw_value = 120, .center_freq = 5600, .max_power = 25 }, 5237 { .hw_value = 120, .center_freq = 5600, .max_power = WLCORE_MAX_TXPWR },
4828 { .hw_value = 124, .center_freq = 5620, .max_power = 25 }, 5238 { .hw_value = 124, .center_freq = 5620, .max_power = WLCORE_MAX_TXPWR },
4829 { .hw_value = 128, .center_freq = 5640, .max_power = 25 }, 5239 { .hw_value = 128, .center_freq = 5640, .max_power = WLCORE_MAX_TXPWR },
4830 { .hw_value = 132, .center_freq = 5660, .max_power = 25 }, 5240 { .hw_value = 132, .center_freq = 5660, .max_power = WLCORE_MAX_TXPWR },
4831 { .hw_value = 136, .center_freq = 5680, .max_power = 25 }, 5241 { .hw_value = 136, .center_freq = 5680, .max_power = WLCORE_MAX_TXPWR },
4832 { .hw_value = 140, .center_freq = 5700, .max_power = 25 }, 5242 { .hw_value = 140, .center_freq = 5700, .max_power = WLCORE_MAX_TXPWR },
4833 { .hw_value = 149, .center_freq = 5745, .max_power = 25 }, 5243 { .hw_value = 149, .center_freq = 5745, .max_power = WLCORE_MAX_TXPWR },
4834 { .hw_value = 153, .center_freq = 5765, .max_power = 25 }, 5244 { .hw_value = 153, .center_freq = 5765, .max_power = WLCORE_MAX_TXPWR },
4835 { .hw_value = 157, .center_freq = 5785, .max_power = 25 }, 5245 { .hw_value = 157, .center_freq = 5785, .max_power = WLCORE_MAX_TXPWR },
4836 { .hw_value = 161, .center_freq = 5805, .max_power = 25 }, 5246 { .hw_value = 161, .center_freq = 5805, .max_power = WLCORE_MAX_TXPWR },
4837 { .hw_value = 165, .center_freq = 5825, .max_power = 25 }, 5247 { .hw_value = 165, .center_freq = 5825, .max_power = WLCORE_MAX_TXPWR },
4838}; 5248};
4839 5249
4840static struct ieee80211_supported_band wl1271_band_5ghz = { 5250static struct ieee80211_supported_band wl1271_band_5ghz = {
@@ -4875,6 +5285,14 @@ static const struct ieee80211_ops wl1271_ops = {
4875 .set_bitrate_mask = wl12xx_set_bitrate_mask, 5285 .set_bitrate_mask = wl12xx_set_bitrate_mask,
4876 .channel_switch = wl12xx_op_channel_switch, 5286 .channel_switch = wl12xx_op_channel_switch,
4877 .flush = wlcore_op_flush, 5287 .flush = wlcore_op_flush,
5288 .remain_on_channel = wlcore_op_remain_on_channel,
5289 .cancel_remain_on_channel = wlcore_op_cancel_remain_on_channel,
5290 .add_chanctx = wlcore_op_add_chanctx,
5291 .remove_chanctx = wlcore_op_remove_chanctx,
5292 .change_chanctx = wlcore_op_change_chanctx,
5293 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
5294 .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx,
5295 .sta_rc_update = wlcore_op_sta_rc_update,
4878 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 5296 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
4879}; 5297};
4880 5298
@@ -5044,34 +5462,6 @@ static struct bin_attribute fwlog_attr = {
5044 .read = wl1271_sysfs_read_fwlog, 5462 .read = wl1271_sysfs_read_fwlog,
5045}; 5463};
5046 5464
5047static void wl1271_connection_loss_work(struct work_struct *work)
5048{
5049 struct delayed_work *dwork;
5050 struct wl1271 *wl;
5051 struct ieee80211_vif *vif;
5052 struct wl12xx_vif *wlvif;
5053
5054 dwork = container_of(work, struct delayed_work, work);
5055 wl = container_of(dwork, struct wl1271, connection_loss_work);
5056
5057 wl1271_info("Connection loss work.");
5058
5059 mutex_lock(&wl->mutex);
5060
5061 if (unlikely(wl->state != WLCORE_STATE_ON))
5062 goto out;
5063
5064 /* Call mac80211 connection loss */
5065 wl12xx_for_each_wlvif_sta(wl, wlvif) {
5066 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
5067 goto out;
5068 vif = wl12xx_wlvif_to_vif(wlvif);
5069 ieee80211_connection_loss(vif);
5070 }
5071out:
5072 mutex_unlock(&wl->mutex);
5073}
5074
5075static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic) 5465static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic)
5076{ 5466{
5077 int i; 5467 int i;
@@ -5117,7 +5507,7 @@ static int wl12xx_get_hw_info(struct wl1271 *wl)
5117 5507
5118 ret = wl12xx_set_power_on(wl); 5508 ret = wl12xx_set_power_on(wl);
5119 if (ret < 0) 5509 if (ret < 0)
5120 goto out; 5510 return ret;
5121 5511
5122 ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &wl->chip.id); 5512 ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &wl->chip.id);
5123 if (ret < 0) 5513 if (ret < 0)
@@ -5207,10 +5597,9 @@ static const struct ieee80211_iface_limit wlcore_iface_limits[] = {
5207 }, 5597 },
5208}; 5598};
5209 5599
5210static const struct ieee80211_iface_combination 5600static struct ieee80211_iface_combination
5211wlcore_iface_combinations[] = { 5601wlcore_iface_combinations[] = {
5212 { 5602 {
5213 .num_different_channels = 1,
5214 .max_interfaces = 3, 5603 .max_interfaces = 3,
5215 .limits = wlcore_iface_limits, 5604 .limits = wlcore_iface_limits,
5216 .n_limits = ARRAY_SIZE(wlcore_iface_limits), 5605 .n_limits = ARRAY_SIZE(wlcore_iface_limits),
@@ -5219,6 +5608,7 @@ wlcore_iface_combinations[] = {
5219 5608
5220static int wl1271_init_ieee80211(struct wl1271 *wl) 5609static int wl1271_init_ieee80211(struct wl1271 *wl)
5221{ 5610{
5611 int i;
5222 static const u32 cipher_suites[] = { 5612 static const u32 cipher_suites[] = {
5223 WLAN_CIPHER_SUITE_WEP40, 5613 WLAN_CIPHER_SUITE_WEP40,
5224 WLAN_CIPHER_SUITE_WEP104, 5614 WLAN_CIPHER_SUITE_WEP104,
@@ -5249,7 +5639,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5249 IEEE80211_HW_AP_LINK_PS | 5639 IEEE80211_HW_AP_LINK_PS |
5250 IEEE80211_HW_AMPDU_AGGREGATION | 5640 IEEE80211_HW_AMPDU_AGGREGATION |
5251 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | 5641 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
5252 IEEE80211_HW_SCAN_WHILE_IDLE; 5642 IEEE80211_HW_SCAN_WHILE_IDLE |
5643 IEEE80211_HW_QUEUE_CONTROL;
5253 5644
5254 wl->hw->wiphy->cipher_suites = cipher_suites; 5645 wl->hw->wiphy->cipher_suites = cipher_suites;
5255 wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 5646 wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
@@ -5271,6 +5662,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5271 wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE - 5662 wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
5272 sizeof(struct ieee80211_header); 5663 sizeof(struct ieee80211_header);
5273 5664
5665 wl->hw->wiphy->max_remain_on_channel_duration = 5000;
5666
5274 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD | 5667 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD |
5275 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 5668 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
5276 5669
@@ -5279,6 +5672,22 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5279 ARRAY_SIZE(wl1271_channels_5ghz) > 5672 ARRAY_SIZE(wl1271_channels_5ghz) >
5280 WL1271_MAX_CHANNELS); 5673 WL1271_MAX_CHANNELS);
5281 /* 5674 /*
5675 * clear channel flags from the previous usage
5676 * and restore max_power & max_antenna_gain values.
5677 */
5678 for (i = 0; i < ARRAY_SIZE(wl1271_channels); i++) {
5679 wl1271_band_2ghz.channels[i].flags = 0;
5680 wl1271_band_2ghz.channels[i].max_power = WLCORE_MAX_TXPWR;
5681 wl1271_band_2ghz.channels[i].max_antenna_gain = 0;
5682 }
5683
5684 for (i = 0; i < ARRAY_SIZE(wl1271_channels_5ghz); i++) {
5685 wl1271_band_5ghz.channels[i].flags = 0;
5686 wl1271_band_5ghz.channels[i].max_power = WLCORE_MAX_TXPWR;
5687 wl1271_band_5ghz.channels[i].max_antenna_gain = 0;
5688 }
5689
5690 /*
5282 * We keep local copies of the band structs because we need to 5691 * We keep local copies of the band structs because we need to
5283 * modify them on a per-device basis. 5692 * modify them on a per-device basis.
5284 */ 5693 */
@@ -5298,7 +5707,14 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5298 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 5707 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
5299 &wl->bands[IEEE80211_BAND_5GHZ]; 5708 &wl->bands[IEEE80211_BAND_5GHZ];
5300 5709
5301 wl->hw->queues = 4; 5710 /*
5711 * allow 4 queues per mac address we support +
5712 * 1 cab queue per mac + one global offchannel Tx queue
5713 */
5714 wl->hw->queues = (NUM_TX_QUEUES + 1) * WLCORE_NUM_MAC_ADDRESSES + 1;
5715
5716 /* the last queue is the offchannel queue */
5717 wl->hw->offchannel_tx_hw_queue = wl->hw->queues - 1;
5302 wl->hw->max_rates = 1; 5718 wl->hw->max_rates = 1;
5303 5719
5304 wl->hw->wiphy->reg_notifier = wl1271_reg_notify; 5720 wl->hw->wiphy->reg_notifier = wl1271_reg_notify;
@@ -5311,6 +5727,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5311 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; 5727 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
5312 5728
5313 /* allowed interface combinations */ 5729 /* allowed interface combinations */
5730 wlcore_iface_combinations[0].num_different_channels = wl->num_channels;
5314 wl->hw->wiphy->iface_combinations = wlcore_iface_combinations; 5731 wl->hw->wiphy->iface_combinations = wlcore_iface_combinations;
5315 wl->hw->wiphy->n_iface_combinations = 5732 wl->hw->wiphy->n_iface_combinations =
5316 ARRAY_SIZE(wlcore_iface_combinations); 5733 ARRAY_SIZE(wlcore_iface_combinations);
@@ -5327,7 +5744,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5327 5744
5328#define WL1271_DEFAULT_CHANNEL 0 5745#define WL1271_DEFAULT_CHANNEL 0
5329 5746
5330struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size) 5747struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
5748 u32 mbox_size)
5331{ 5749{
5332 struct ieee80211_hw *hw; 5750 struct ieee80211_hw *hw;
5333 struct wl1271 *wl; 5751 struct wl1271 *wl;
@@ -5369,9 +5787,8 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size)
5369 INIT_WORK(&wl->tx_work, wl1271_tx_work); 5787 INIT_WORK(&wl->tx_work, wl1271_tx_work);
5370 INIT_WORK(&wl->recovery_work, wl1271_recovery_work); 5788 INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
5371 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); 5789 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
5790 INIT_DELAYED_WORK(&wl->roc_complete_work, wlcore_roc_complete_work);
5372 INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work); 5791 INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work);
5373 INIT_DELAYED_WORK(&wl->connection_loss_work,
5374 wl1271_connection_loss_work);
5375 5792
5376 wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); 5793 wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
5377 if (!wl->freezable_wq) { 5794 if (!wl->freezable_wq) {
@@ -5387,14 +5804,15 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size)
5387 wl->flags = 0; 5804 wl->flags = 0;
5388 wl->sg_enabled = true; 5805 wl->sg_enabled = true;
5389 wl->sleep_auth = WL1271_PSM_ILLEGAL; 5806 wl->sleep_auth = WL1271_PSM_ILLEGAL;
5807 wl->recovery_count = 0;
5390 wl->hw_pg_ver = -1; 5808 wl->hw_pg_ver = -1;
5391 wl->ap_ps_map = 0; 5809 wl->ap_ps_map = 0;
5392 wl->ap_fw_ps_map = 0; 5810 wl->ap_fw_ps_map = 0;
5393 wl->quirks = 0; 5811 wl->quirks = 0;
5394 wl->platform_quirks = 0; 5812 wl->platform_quirks = 0;
5395 wl->sched_scanning = false;
5396 wl->system_hlid = WL12XX_SYSTEM_HLID; 5813 wl->system_hlid = WL12XX_SYSTEM_HLID;
5397 wl->active_sta_count = 0; 5814 wl->active_sta_count = 0;
5815 wl->active_link_count = 0;
5398 wl->fwlog_size = 0; 5816 wl->fwlog_size = 0;
5399 init_waitqueue_head(&wl->fwlog_waitq); 5817 init_waitqueue_head(&wl->fwlog_waitq);
5400 5818
@@ -5434,14 +5852,24 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size)
5434 goto err_dummy_packet; 5852 goto err_dummy_packet;
5435 } 5853 }
5436 5854
5437 wl->mbox = kmalloc(sizeof(*wl->mbox), GFP_KERNEL | GFP_DMA); 5855 wl->mbox_size = mbox_size;
5856 wl->mbox = kmalloc(wl->mbox_size, GFP_KERNEL | GFP_DMA);
5438 if (!wl->mbox) { 5857 if (!wl->mbox) {
5439 ret = -ENOMEM; 5858 ret = -ENOMEM;
5440 goto err_fwlog; 5859 goto err_fwlog;
5441 } 5860 }
5442 5861
5862 wl->buffer_32 = kmalloc(sizeof(*wl->buffer_32), GFP_KERNEL);
5863 if (!wl->buffer_32) {
5864 ret = -ENOMEM;
5865 goto err_mbox;
5866 }
5867
5443 return hw; 5868 return hw;
5444 5869
5870err_mbox:
5871 kfree(wl->mbox);
5872
5445err_fwlog: 5873err_fwlog:
5446 free_page((unsigned long)wl->fwlog); 5874 free_page((unsigned long)wl->fwlog);
5447 5875
@@ -5480,6 +5908,8 @@ int wlcore_free_hw(struct wl1271 *wl)
5480 device_remove_file(wl->dev, &dev_attr_hw_pg_ver); 5908 device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
5481 5909
5482 device_remove_file(wl->dev, &dev_attr_bt_coex_state); 5910 device_remove_file(wl->dev, &dev_attr_bt_coex_state);
5911 kfree(wl->buffer_32);
5912 kfree(wl->mbox);
5483 free_page((unsigned long)wl->fwlog); 5913 free_page((unsigned long)wl->fwlog);
5484 dev_kfree_skb(wl->dummy_packet); 5914 dev_kfree_skb(wl->dummy_packet);
5485 free_pages((unsigned long)wl->aggr_buf, get_order(wl->aggr_buf_size)); 5915 free_pages((unsigned long)wl->aggr_buf, get_order(wl->aggr_buf_size));
@@ -5712,10 +6142,10 @@ module_param_named(fwlog, fwlog_param, charp, 0);
5712MODULE_PARM_DESC(fwlog, 6142MODULE_PARM_DESC(fwlog,
5713 "FW logger options: continuous, ondemand, dbgpins or disable"); 6143 "FW logger options: continuous, ondemand, dbgpins or disable");
5714 6144
5715module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR); 6145module_param(bug_on_recovery, int, S_IRUSR | S_IWUSR);
5716MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); 6146MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery");
5717 6147
5718module_param(no_recovery, bool, S_IRUSR | S_IWUSR); 6148module_param(no_recovery, int, S_IRUSR | S_IWUSR);
5719MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck."); 6149MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck.");
5720 6150
5721MODULE_LICENSE("GPL"); 6151MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 4d1414a673fb..9b7b6e2e4fbc 100644
--- a/drivers/net/wireless/ti/wlcore/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -151,9 +151,6 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
151 wl12xx_queue_recovery_work(wl); 151 wl12xx_queue_recovery_work(wl);
152 ret = -ETIMEDOUT; 152 ret = -ETIMEDOUT;
153 goto err; 153 goto err;
154 } else if (ret < 0) {
155 wl1271_error("ELP wakeup completion error.");
156 goto err;
157 } 154 }
158 } 155 }
159 156
@@ -242,11 +239,12 @@ static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid)
242 struct ieee80211_tx_info *info; 239 struct ieee80211_tx_info *info;
243 unsigned long flags; 240 unsigned long flags;
244 int filtered[NUM_TX_QUEUES]; 241 int filtered[NUM_TX_QUEUES];
242 struct wl1271_link *lnk = &wl->links[hlid];
245 243
246 /* filter all frames currently in the low level queues for this hlid */ 244 /* filter all frames currently in the low level queues for this hlid */
247 for (i = 0; i < NUM_TX_QUEUES; i++) { 245 for (i = 0; i < NUM_TX_QUEUES; i++) {
248 filtered[i] = 0; 246 filtered[i] = 0;
249 while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) { 247 while ((skb = skb_dequeue(&lnk->tx_queue[i]))) {
250 filtered[i]++; 248 filtered[i]++;
251 249
252 if (WARN_ON(wl12xx_is_dummy_packet(wl, skb))) 250 if (WARN_ON(wl12xx_is_dummy_packet(wl, skb)))
@@ -260,8 +258,11 @@ static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid)
260 } 258 }
261 259
262 spin_lock_irqsave(&wl->wl_lock, flags); 260 spin_lock_irqsave(&wl->wl_lock, flags);
263 for (i = 0; i < NUM_TX_QUEUES; i++) 261 for (i = 0; i < NUM_TX_QUEUES; i++) {
264 wl->tx_queue_count[i] -= filtered[i]; 262 wl->tx_queue_count[i] -= filtered[i];
263 if (lnk->wlvif)
264 lnk->wlvif->tx_queue_count[i] -= filtered[i];
265 }
265 spin_unlock_irqrestore(&wl->wl_lock, flags); 266 spin_unlock_irqrestore(&wl->wl_lock, flags);
266 267
267 wl1271_handle_tx_low_watermark(wl); 268 wl1271_handle_tx_low_watermark(wl);
diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c
index 9ee0ec6fd1db..6791a1a6afba 100644
--- a/drivers/net/wireless/ti/wlcore/rx.c
+++ b/drivers/net/wireless/ti/wlcore/rx.c
@@ -92,11 +92,16 @@ static void wl1271_rx_status(struct wl1271 *wl,
92 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED | 92 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED |
93 RX_FLAG_DECRYPTED; 93 RX_FLAG_DECRYPTED;
94 94
95 if (unlikely(desc_err_code == WL1271_RX_DESC_MIC_FAIL)) { 95 if (unlikely(desc_err_code & WL1271_RX_DESC_MIC_FAIL)) {
96 status->flag |= RX_FLAG_MMIC_ERROR; 96 status->flag |= RX_FLAG_MMIC_ERROR;
97 wl1271_warning("Michael MIC error"); 97 wl1271_warning("Michael MIC error. Desc: 0x%x",
98 desc_err_code);
98 } 99 }
99 } 100 }
101
102 if (beacon)
103 wlcore_set_pending_regdomain_ch(wl, (u16)desc->channel,
104 status->band);
100} 105}
101 106
102static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, 107static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
@@ -108,7 +113,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
108 u8 *buf; 113 u8 *buf;
109 u8 beacon = 0; 114 u8 beacon = 0;
110 u8 is_data = 0; 115 u8 is_data = 0;
111 u8 reserved = 0; 116 u8 reserved = 0, offset_to_data = 0;
112 u16 seq_num; 117 u16 seq_num;
113 u32 pkt_data_len; 118 u32 pkt_data_len;
114 119
@@ -128,6 +133,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
128 133
129 if (rx_align == WLCORE_RX_BUF_UNALIGNED) 134 if (rx_align == WLCORE_RX_BUF_UNALIGNED)
130 reserved = RX_BUF_ALIGN; 135 reserved = RX_BUF_ALIGN;
136 else if (rx_align == WLCORE_RX_BUF_PADDED)
137 offset_to_data = RX_BUF_ALIGN;
131 138
132 /* the data read starts with the descriptor */ 139 /* the data read starts with the descriptor */
133 desc = (struct wl1271_rx_descriptor *) data; 140 desc = (struct wl1271_rx_descriptor *) data;
@@ -139,19 +146,15 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
139 return 0; 146 return 0;
140 } 147 }
141 148
142 switch (desc->status & WL1271_RX_DESC_STATUS_MASK) {
143 /* discard corrupted packets */ 149 /* discard corrupted packets */
144 case WL1271_RX_DESC_DRIVER_RX_Q_FAIL: 150 if (desc->status & WL1271_RX_DESC_DECRYPT_FAIL) {
145 case WL1271_RX_DESC_DECRYPT_FAIL: 151 hdr = (void *)(data + sizeof(*desc) + offset_to_data);
146 wl1271_warning("corrupted packet in RX with status: 0x%x", 152 wl1271_warning("corrupted packet in RX: status: 0x%x len: %d",
147 desc->status & WL1271_RX_DESC_STATUS_MASK); 153 desc->status & WL1271_RX_DESC_STATUS_MASK,
148 return -EINVAL; 154 pkt_data_len);
149 case WL1271_RX_DESC_SUCCESS: 155 wl1271_dump((DEBUG_RX|DEBUG_CMD), "PKT: ", data + sizeof(*desc),
150 case WL1271_RX_DESC_MIC_FAIL: 156 min(pkt_data_len,
151 break; 157 ieee80211_hdrlen(hdr->frame_control)));
152 default:
153 wl1271_error("invalid RX descriptor status: 0x%x",
154 desc->status & WL1271_RX_DESC_STATUS_MASK);
155 return -EINVAL; 158 return -EINVAL;
156 } 159 }
157 160
diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h
index 71eba1899915..3363f60fb7da 100644
--- a/drivers/net/wireless/ti/wlcore/rx.h
+++ b/drivers/net/wireless/ti/wlcore/rx.h
@@ -84,12 +84,11 @@
84 * Bits 3-5 - process_id tag (AP mode FW) 84 * Bits 3-5 - process_id tag (AP mode FW)
85 * Bits 6-7 - reserved 85 * Bits 6-7 - reserved
86 */ 86 */
87#define WL1271_RX_DESC_STATUS_MASK 0x03 87#define WL1271_RX_DESC_STATUS_MASK 0x07
88 88
89#define WL1271_RX_DESC_SUCCESS 0x00 89#define WL1271_RX_DESC_SUCCESS 0x00
90#define WL1271_RX_DESC_DECRYPT_FAIL 0x01 90#define WL1271_RX_DESC_DECRYPT_FAIL 0x01
91#define WL1271_RX_DESC_MIC_FAIL 0x02 91#define WL1271_RX_DESC_MIC_FAIL 0x02
92#define WL1271_RX_DESC_DRIVER_RX_Q_FAIL 0x03
93 92
94#define RX_MEM_BLOCK_MASK 0xFF 93#define RX_MEM_BLOCK_MASK 0xFF
95#define RX_BUF_SIZE_MASK 0xFFF00 94#define RX_BUF_SIZE_MASK 0xFFF00
diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
index d00501493dfe..f407101e525b 100644
--- a/drivers/net/wireless/ti/wlcore/scan.c
+++ b/drivers/net/wireless/ti/wlcore/scan.c
@@ -35,7 +35,6 @@ void wl1271_scan_complete_work(struct work_struct *work)
35{ 35{
36 struct delayed_work *dwork; 36 struct delayed_work *dwork;
37 struct wl1271 *wl; 37 struct wl1271 *wl;
38 struct ieee80211_vif *vif;
39 struct wl12xx_vif *wlvif; 38 struct wl12xx_vif *wlvif;
40 int ret; 39 int ret;
41 40
@@ -52,8 +51,7 @@ void wl1271_scan_complete_work(struct work_struct *work)
52 if (wl->scan.state == WL1271_SCAN_STATE_IDLE) 51 if (wl->scan.state == WL1271_SCAN_STATE_IDLE)
53 goto out; 52 goto out;
54 53
55 vif = wl->scan_vif; 54 wlvif = wl->scan_wlvif;
56 wlvif = wl12xx_vif_to_data(vif);
57 55
58 /* 56 /*
59 * Rearm the tx watchdog just before idling scan. This 57 * Rearm the tx watchdog just before idling scan. This
@@ -64,7 +62,7 @@ void wl1271_scan_complete_work(struct work_struct *work)
64 wl->scan.state = WL1271_SCAN_STATE_IDLE; 62 wl->scan.state = WL1271_SCAN_STATE_IDLE;
65 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 63 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
66 wl->scan.req = NULL; 64 wl->scan.req = NULL;
67 wl->scan_vif = NULL; 65 wl->scan_wlvif = NULL;
68 66
69 ret = wl1271_ps_elp_wakeup(wl); 67 ret = wl1271_ps_elp_wakeup(wl);
70 if (ret < 0) 68 if (ret < 0)
@@ -82,6 +80,8 @@ void wl1271_scan_complete_work(struct work_struct *work)
82 wl12xx_queue_recovery_work(wl); 80 wl12xx_queue_recovery_work(wl);
83 } 81 }
84 82
83 wlcore_cmd_regdomain_config_locked(wl);
84
85 ieee80211_scan_completed(wl->hw, false); 85 ieee80211_scan_completed(wl->hw, false);
86 86
87out: 87out:
@@ -89,371 +89,99 @@ out:
89 89
90} 90}
91 91
92 92static void wlcore_started_vifs_iter(void *data, u8 *mac,
93static int wl1271_get_scan_channels(struct wl1271 *wl, 93 struct ieee80211_vif *vif)
94 struct cfg80211_scan_request *req,
95 struct basic_scan_channel_params *channels,
96 enum ieee80211_band band, bool passive)
97{
98 struct conf_scan_settings *c = &wl->conf.scan;
99 int i, j;
100 u32 flags;
101
102 for (i = 0, j = 0;
103 i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS;
104 i++) {
105 flags = req->channels[i]->flags;
106
107 if (!test_bit(i, wl->scan.scanned_ch) &&
108 !(flags & IEEE80211_CHAN_DISABLED) &&
109 (req->channels[i]->band == band) &&
110 /*
111 * In passive scans, we scan all remaining
112 * channels, even if not marked as such.
113 * In active scans, we only scan channels not
114 * marked as passive.
115 */
116 (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) {
117 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
118 req->channels[i]->band,
119 req->channels[i]->center_freq);
120 wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
121 req->channels[i]->hw_value,
122 req->channels[i]->flags);
123 wl1271_debug(DEBUG_SCAN,
124 "max_antenna_gain %d, max_power %d",
125 req->channels[i]->max_antenna_gain,
126 req->channels[i]->max_power);
127 wl1271_debug(DEBUG_SCAN, "beacon_found %d",
128 req->channels[i]->beacon_found);
129
130 if (!passive) {
131 channels[j].min_duration =
132 cpu_to_le32(c->min_dwell_time_active);
133 channels[j].max_duration =
134 cpu_to_le32(c->max_dwell_time_active);
135 } else {
136 channels[j].min_duration =
137 cpu_to_le32(c->min_dwell_time_passive);
138 channels[j].max_duration =
139 cpu_to_le32(c->max_dwell_time_passive);
140 }
141 channels[j].early_termination = 0;
142 channels[j].tx_power_att = req->channels[i]->max_power;
143 channels[j].channel = req->channels[i]->hw_value;
144
145 memset(&channels[j].bssid_lsb, 0xff, 4);
146 memset(&channels[j].bssid_msb, 0xff, 2);
147
148 /* Mark the channels we already used */
149 set_bit(i, wl->scan.scanned_ch);
150
151 j++;
152 }
153 }
154
155 return j;
156}
157
158#define WL1271_NOTHING_TO_SCAN 1
159
160static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
161 enum ieee80211_band band,
162 bool passive, u32 basic_rate)
163{ 94{
164 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 95 int *count = (int *)data;
165 struct wl1271_cmd_scan *cmd;
166 struct wl1271_cmd_trigger_scan_to *trigger;
167 int ret;
168 u16 scan_options = 0;
169
170 /* skip active scans if we don't have SSIDs */
171 if (!passive && wl->scan.req->n_ssids == 0)
172 return WL1271_NOTHING_TO_SCAN;
173
174 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
175 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
176 if (!cmd || !trigger) {
177 ret = -ENOMEM;
178 goto out;
179 }
180
181 if (wl->conf.scan.split_scan_timeout)
182 scan_options |= WL1271_SCAN_OPT_SPLIT_SCAN;
183
184 if (passive)
185 scan_options |= WL1271_SCAN_OPT_PASSIVE;
186
187 cmd->params.role_id = wlvif->role_id;
188
189 if (WARN_ON(cmd->params.role_id == WL12XX_INVALID_ROLE_ID)) {
190 ret = -EINVAL;
191 goto out;
192 }
193
194 cmd->params.scan_options = cpu_to_le16(scan_options);
195
196 cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req,
197 cmd->channels,
198 band, passive);
199 if (cmd->params.n_ch == 0) {
200 ret = WL1271_NOTHING_TO_SCAN;
201 goto out;
202 }
203
204 cmd->params.tx_rate = cpu_to_le32(basic_rate);
205 cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs;
206 cmd->params.tid_trigger = CONF_TX_AC_ANY_TID;
207 cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
208
209 if (band == IEEE80211_BAND_2GHZ)
210 cmd->params.band = WL1271_SCAN_BAND_2_4_GHZ;
211 else
212 cmd->params.band = WL1271_SCAN_BAND_5_GHZ;
213
214 if (wl->scan.ssid_len && wl->scan.ssid) {
215 cmd->params.ssid_len = wl->scan.ssid_len;
216 memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len);
217 }
218
219 memcpy(cmd->addr, vif->addr, ETH_ALEN);
220
221 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
222 cmd->params.role_id, band,
223 wl->scan.ssid, wl->scan.ssid_len,
224 wl->scan.req->ie,
225 wl->scan.req->ie_len, false);
226 if (ret < 0) {
227 wl1271_error("PROBE request template failed");
228 goto out;
229 }
230
231 trigger->timeout = cpu_to_le32(wl->conf.scan.split_scan_timeout);
232 ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
233 sizeof(*trigger), 0);
234 if (ret < 0) {
235 wl1271_error("trigger scan to failed for hw scan");
236 goto out;
237 }
238
239 wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd));
240 96
241 ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0); 97 if (!vif->bss_conf.idle)
242 if (ret < 0) { 98 (*count)++;
243 wl1271_error("SCAN failed");
244 goto out;
245 }
246
247out:
248 kfree(cmd);
249 kfree(trigger);
250 return ret;
251} 99}
252 100
253void wl1271_scan_stm(struct wl1271 *wl, struct ieee80211_vif *vif) 101static int wlcore_count_started_vifs(struct wl1271 *wl)
254{ 102{
255 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 103 int count = 0;
256 int ret = 0;
257 enum ieee80211_band band;
258 u32 rate, mask;
259
260 switch (wl->scan.state) {
261 case WL1271_SCAN_STATE_IDLE:
262 break;
263
264 case WL1271_SCAN_STATE_2GHZ_ACTIVE:
265 band = IEEE80211_BAND_2GHZ;
266 mask = wlvif->bitrate_masks[band];
267 if (wl->scan.req->no_cck) {
268 mask &= ~CONF_TX_CCK_RATES;
269 if (!mask)
270 mask = CONF_TX_RATE_MASK_BASIC_P2P;
271 }
272 rate = wl1271_tx_min_rate_get(wl, mask);
273 ret = wl1271_scan_send(wl, vif, band, false, rate);
274 if (ret == WL1271_NOTHING_TO_SCAN) {
275 wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
276 wl1271_scan_stm(wl, vif);
277 }
278
279 break;
280
281 case WL1271_SCAN_STATE_2GHZ_PASSIVE:
282 band = IEEE80211_BAND_2GHZ;
283 mask = wlvif->bitrate_masks[band];
284 if (wl->scan.req->no_cck) {
285 mask &= ~CONF_TX_CCK_RATES;
286 if (!mask)
287 mask = CONF_TX_RATE_MASK_BASIC_P2P;
288 }
289 rate = wl1271_tx_min_rate_get(wl, mask);
290 ret = wl1271_scan_send(wl, vif, band, true, rate);
291 if (ret == WL1271_NOTHING_TO_SCAN) {
292 if (wl->enable_11a)
293 wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
294 else
295 wl->scan.state = WL1271_SCAN_STATE_DONE;
296 wl1271_scan_stm(wl, vif);
297 }
298
299 break;
300 104
301 case WL1271_SCAN_STATE_5GHZ_ACTIVE: 105 ieee80211_iterate_active_interfaces_atomic(wl->hw,
302 band = IEEE80211_BAND_5GHZ; 106 IEEE80211_IFACE_ITER_RESUME_ALL,
303 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]); 107 wlcore_started_vifs_iter, &count);
304 ret = wl1271_scan_send(wl, vif, band, false, rate); 108 return count;
305 if (ret == WL1271_NOTHING_TO_SCAN) {
306 wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
307 wl1271_scan_stm(wl, vif);
308 }
309
310 break;
311
312 case WL1271_SCAN_STATE_5GHZ_PASSIVE:
313 band = IEEE80211_BAND_5GHZ;
314 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
315 ret = wl1271_scan_send(wl, vif, band, true, rate);
316 if (ret == WL1271_NOTHING_TO_SCAN) {
317 wl->scan.state = WL1271_SCAN_STATE_DONE;
318 wl1271_scan_stm(wl, vif);
319 }
320
321 break;
322
323 case WL1271_SCAN_STATE_DONE:
324 wl->scan.failed = false;
325 cancel_delayed_work(&wl->scan_complete_work);
326 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
327 msecs_to_jiffies(0));
328 break;
329
330 default:
331 wl1271_error("invalid scan state");
332 break;
333 }
334
335 if (ret < 0) {
336 cancel_delayed_work(&wl->scan_complete_work);
337 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
338 msecs_to_jiffies(0));
339 }
340}
341
342int wl1271_scan(struct wl1271 *wl, struct ieee80211_vif *vif,
343 const u8 *ssid, size_t ssid_len,
344 struct cfg80211_scan_request *req)
345{
346 /*
347 * cfg80211 should guarantee that we don't get more channels
348 * than what we have registered.
349 */
350 BUG_ON(req->n_channels > WL1271_MAX_CHANNELS);
351
352 if (wl->scan.state != WL1271_SCAN_STATE_IDLE)
353 return -EBUSY;
354
355 wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE;
356
357 if (ssid_len && ssid) {
358 wl->scan.ssid_len = ssid_len;
359 memcpy(wl->scan.ssid, ssid, ssid_len);
360 } else {
361 wl->scan.ssid_len = 0;
362 }
363
364 wl->scan_vif = vif;
365 wl->scan.req = req;
366 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
367
368 /* we assume failure so that timeout scenarios are handled correctly */
369 wl->scan.failed = true;
370 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
371 msecs_to_jiffies(WL1271_SCAN_TIMEOUT));
372
373 wl1271_scan_stm(wl, vif);
374
375 return 0;
376}
377
378int wl1271_scan_stop(struct wl1271 *wl)
379{
380 struct wl1271_cmd_header *cmd = NULL;
381 int ret = 0;
382
383 if (WARN_ON(wl->scan.state == WL1271_SCAN_STATE_IDLE))
384 return -EINVAL;
385
386 wl1271_debug(DEBUG_CMD, "cmd scan stop");
387
388 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
389 if (!cmd) {
390 ret = -ENOMEM;
391 goto out;
392 }
393
394 ret = wl1271_cmd_send(wl, CMD_STOP_SCAN, cmd,
395 sizeof(*cmd), 0);
396 if (ret < 0) {
397 wl1271_error("cmd stop_scan failed");
398 goto out;
399 }
400out:
401 kfree(cmd);
402 return ret;
403} 109}
404 110
405static int 111static int
406wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, 112wlcore_scan_get_channels(struct wl1271 *wl,
407 struct cfg80211_sched_scan_request *req, 113 struct ieee80211_channel *req_channels[],
408 struct conn_scan_ch_params *channels, 114 u32 n_channels,
409 u32 band, bool radar, bool passive, 115 u32 n_ssids,
410 int start, int max_channels, 116 struct conn_scan_ch_params *channels,
411 u8 *n_pactive_ch) 117 u32 band, bool radar, bool passive,
118 int start, int max_channels,
119 u8 *n_pactive_ch,
120 int scan_type)
412{ 121{
413 struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
414 int i, j; 122 int i, j;
415 u32 flags; 123 u32 flags;
416 bool force_passive = !req->n_ssids; 124 bool force_passive = !n_ssids;
417 u32 min_dwell_time_active, max_dwell_time_active, delta_per_probe; 125 u32 min_dwell_time_active, max_dwell_time_active;
418 u32 dwell_time_passive, dwell_time_dfs; 126 u32 dwell_time_passive, dwell_time_dfs;
419 127
420 if (band == IEEE80211_BAND_5GHZ) 128 /* configure dwell times according to scan type */
421 delta_per_probe = c->dwell_time_delta_per_probe_5; 129 if (scan_type == SCAN_TYPE_SEARCH) {
422 else 130 struct conf_scan_settings *c = &wl->conf.scan;
423 delta_per_probe = c->dwell_time_delta_per_probe; 131 bool active_vif_exists = !!wlcore_count_started_vifs(wl);
132
133 min_dwell_time_active = active_vif_exists ?
134 c->min_dwell_time_active :
135 c->min_dwell_time_active_long;
136 max_dwell_time_active = active_vif_exists ?
137 c->max_dwell_time_active :
138 c->max_dwell_time_active_long;
139 dwell_time_passive = c->dwell_time_passive;
140 dwell_time_dfs = c->dwell_time_dfs;
141 } else {
142 struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
143 u32 delta_per_probe;
424 144
425 min_dwell_time_active = c->base_dwell_time + 145 if (band == IEEE80211_BAND_5GHZ)
426 req->n_ssids * c->num_probe_reqs * delta_per_probe; 146 delta_per_probe = c->dwell_time_delta_per_probe_5;
147 else
148 delta_per_probe = c->dwell_time_delta_per_probe;
427 149
428 max_dwell_time_active = min_dwell_time_active + c->max_dwell_time_delta; 150 min_dwell_time_active = c->base_dwell_time +
151 n_ssids * c->num_probe_reqs * delta_per_probe;
429 152
153 max_dwell_time_active = min_dwell_time_active +
154 c->max_dwell_time_delta;
155 dwell_time_passive = c->dwell_time_passive;
156 dwell_time_dfs = c->dwell_time_dfs;
157 }
430 min_dwell_time_active = DIV_ROUND_UP(min_dwell_time_active, 1000); 158 min_dwell_time_active = DIV_ROUND_UP(min_dwell_time_active, 1000);
431 max_dwell_time_active = DIV_ROUND_UP(max_dwell_time_active, 1000); 159 max_dwell_time_active = DIV_ROUND_UP(max_dwell_time_active, 1000);
432 dwell_time_passive = DIV_ROUND_UP(c->dwell_time_passive, 1000); 160 dwell_time_passive = DIV_ROUND_UP(dwell_time_passive, 1000);
433 dwell_time_dfs = DIV_ROUND_UP(c->dwell_time_dfs, 1000); 161 dwell_time_dfs = DIV_ROUND_UP(dwell_time_dfs, 1000);
434 162
435 for (i = 0, j = start; 163 for (i = 0, j = start;
436 i < req->n_channels && j < max_channels; 164 i < n_channels && j < max_channels;
437 i++) { 165 i++) {
438 flags = req->channels[i]->flags; 166 flags = req_channels[i]->flags;
439 167
440 if (force_passive) 168 if (force_passive)
441 flags |= IEEE80211_CHAN_PASSIVE_SCAN; 169 flags |= IEEE80211_CHAN_PASSIVE_SCAN;
442 170
443 if ((req->channels[i]->band == band) && 171 if ((req_channels[i]->band == band) &&
444 !(flags & IEEE80211_CHAN_DISABLED) && 172 !(flags & IEEE80211_CHAN_DISABLED) &&
445 (!!(flags & IEEE80211_CHAN_RADAR) == radar) && 173 (!!(flags & IEEE80211_CHAN_RADAR) == radar) &&
446 /* if radar is set, we ignore the passive flag */ 174 /* if radar is set, we ignore the passive flag */
447 (radar || 175 (radar ||
448 !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) { 176 !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) {
449 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", 177 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
450 req->channels[i]->band, 178 req_channels[i]->band,
451 req->channels[i]->center_freq); 179 req_channels[i]->center_freq);
452 wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X", 180 wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
453 req->channels[i]->hw_value, 181 req_channels[i]->hw_value,
454 req->channels[i]->flags); 182 req_channels[i]->flags);
455 wl1271_debug(DEBUG_SCAN, "max_power %d", 183 wl1271_debug(DEBUG_SCAN, "max_power %d",
456 req->channels[i]->max_power); 184 req_channels[i]->max_power);
457 wl1271_debug(DEBUG_SCAN, "min_dwell_time %d max dwell time %d", 185 wl1271_debug(DEBUG_SCAN, "min_dwell_time %d max dwell time %d",
458 min_dwell_time_active, 186 min_dwell_time_active,
459 max_dwell_time_active); 187 max_dwell_time_active);
@@ -473,10 +201,11 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
473 channels[j].max_duration = 201 channels[j].max_duration =
474 cpu_to_le16(max_dwell_time_active); 202 cpu_to_le16(max_dwell_time_active);
475 203
476 channels[j].tx_power_att = req->channels[i]->max_power; 204 channels[j].tx_power_att = req_channels[i]->max_power;
477 channels[j].channel = req->channels[i]->hw_value; 205 channels[j].channel = req_channels[i]->hw_value;
478 206
479 if ((band == IEEE80211_BAND_2GHZ) && 207 if (n_pactive_ch &&
208 (band == IEEE80211_BAND_2GHZ) &&
480 (channels[j].channel >= 12) && 209 (channels[j].channel >= 12) &&
481 (channels[j].channel <= 14) && 210 (channels[j].channel <= 14) &&
482 (flags & IEEE80211_CHAN_PASSIVE_SCAN) && 211 (flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
@@ -500,51 +229,80 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
500 return j - start; 229 return j - start;
501} 230}
502 231
503static bool 232bool
504wl1271_scan_sched_scan_channels(struct wl1271 *wl, 233wlcore_set_scan_chan_params(struct wl1271 *wl,
505 struct cfg80211_sched_scan_request *req, 234 struct wlcore_scan_channels *cfg,
506 struct wl1271_cmd_sched_scan_config *cfg) 235 struct ieee80211_channel *channels[],
236 u32 n_channels,
237 u32 n_ssids,
238 int scan_type)
507{ 239{
508 u8 n_pactive_ch = 0; 240 u8 n_pactive_ch = 0;
509 241
510 cfg->passive[0] = 242 cfg->passive[0] =
511 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, 243 wlcore_scan_get_channels(wl,
512 IEEE80211_BAND_2GHZ, 244 channels,
513 false, true, 0, 245 n_channels,
514 MAX_CHANNELS_2GHZ, 246 n_ssids,
515 &n_pactive_ch); 247 cfg->channels_2,
248 IEEE80211_BAND_2GHZ,
249 false, true, 0,
250 MAX_CHANNELS_2GHZ,
251 &n_pactive_ch,
252 scan_type);
516 cfg->active[0] = 253 cfg->active[0] =
517 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, 254 wlcore_scan_get_channels(wl,
518 IEEE80211_BAND_2GHZ, 255 channels,
519 false, false, 256 n_channels,
520 cfg->passive[0], 257 n_ssids,
521 MAX_CHANNELS_2GHZ, 258 cfg->channels_2,
522 &n_pactive_ch); 259 IEEE80211_BAND_2GHZ,
260 false, false,
261 cfg->passive[0],
262 MAX_CHANNELS_2GHZ,
263 &n_pactive_ch,
264 scan_type);
523 cfg->passive[1] = 265 cfg->passive[1] =
524 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, 266 wlcore_scan_get_channels(wl,
525 IEEE80211_BAND_5GHZ, 267 channels,
526 false, true, 0, 268 n_channels,
527 MAX_CHANNELS_5GHZ, 269 n_ssids,
528 &n_pactive_ch); 270 cfg->channels_5,
271 IEEE80211_BAND_5GHZ,
272 false, true, 0,
273 wl->max_channels_5,
274 &n_pactive_ch,
275 scan_type);
529 cfg->dfs = 276 cfg->dfs =
530 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, 277 wlcore_scan_get_channels(wl,
531 IEEE80211_BAND_5GHZ, 278 channels,
532 true, true, 279 n_channels,
533 cfg->passive[1], 280 n_ssids,
534 MAX_CHANNELS_5GHZ, 281 cfg->channels_5,
535 &n_pactive_ch); 282 IEEE80211_BAND_5GHZ,
283 true, true,
284 cfg->passive[1],
285 wl->max_channels_5,
286 &n_pactive_ch,
287 scan_type);
536 cfg->active[1] = 288 cfg->active[1] =
537 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, 289 wlcore_scan_get_channels(wl,
538 IEEE80211_BAND_5GHZ, 290 channels,
539 false, false, 291 n_channels,
540 cfg->passive[1] + cfg->dfs, 292 n_ssids,
541 MAX_CHANNELS_5GHZ, 293 cfg->channels_5,
542 &n_pactive_ch); 294 IEEE80211_BAND_5GHZ,
295 false, false,
296 cfg->passive[1] + cfg->dfs,
297 wl->max_channels_5,
298 &n_pactive_ch,
299 scan_type);
300
543 /* 802.11j channels are not supported yet */ 301 /* 802.11j channels are not supported yet */
544 cfg->passive[2] = 0; 302 cfg->passive[2] = 0;
545 cfg->active[2] = 0; 303 cfg->active[2] = 0;
546 304
547 cfg->n_pactive_ch = n_pactive_ch; 305 cfg->passive_active = n_pactive_ch;
548 306
549 wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", 307 wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d",
550 cfg->active[0], cfg->passive[0]); 308 cfg->active[0], cfg->passive[0]);
@@ -556,10 +314,48 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl,
556 cfg->passive[1] || cfg->active[1] || cfg->dfs || 314 cfg->passive[1] || cfg->active[1] || cfg->dfs ||
557 cfg->passive[2] || cfg->active[2]; 315 cfg->passive[2] || cfg->active[2];
558} 316}
317EXPORT_SYMBOL_GPL(wlcore_set_scan_chan_params);
318
319int wlcore_scan(struct wl1271 *wl, struct ieee80211_vif *vif,
320 const u8 *ssid, size_t ssid_len,
321 struct cfg80211_scan_request *req)
322{
323 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
324
325 /*
326 * cfg80211 should guarantee that we don't get more channels
327 * than what we have registered.
328 */
329 BUG_ON(req->n_channels > WL1271_MAX_CHANNELS);
330
331 if (wl->scan.state != WL1271_SCAN_STATE_IDLE)
332 return -EBUSY;
333
334 wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE;
335
336 if (ssid_len && ssid) {
337 wl->scan.ssid_len = ssid_len;
338 memcpy(wl->scan.ssid, ssid, ssid_len);
339 } else {
340 wl->scan.ssid_len = 0;
341 }
342
343 wl->scan_wlvif = wlvif;
344 wl->scan.req = req;
345 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
346
347 /* we assume failure so that timeout scenarios are handled correctly */
348 wl->scan.failed = true;
349 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
350 msecs_to_jiffies(WL1271_SCAN_TIMEOUT));
559 351
352 wl->ops->scan_start(wl, wlvif, req);
353
354 return 0;
355}
560/* Returns the scan type to be used or a negative value on error */ 356/* Returns the scan type to be used or a negative value on error */
561static int 357int
562wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, 358wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl,
563 struct wl12xx_vif *wlvif, 359 struct wl12xx_vif *wlvif,
564 struct cfg80211_sched_scan_request *req) 360 struct cfg80211_sched_scan_request *req)
565{ 361{
@@ -662,160 +458,12 @@ out:
662 return ret; 458 return ret;
663 return type; 459 return type;
664} 460}
461EXPORT_SYMBOL_GPL(wlcore_scan_sched_scan_ssid_list);
665 462
666int wl1271_scan_sched_scan_config(struct wl1271 *wl, 463void wlcore_scan_sched_scan_results(struct wl1271 *wl)
667 struct wl12xx_vif *wlvif,
668 struct cfg80211_sched_scan_request *req,
669 struct ieee80211_sched_scan_ies *ies)
670{
671 struct wl1271_cmd_sched_scan_config *cfg = NULL;
672 struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
673 int i, ret;
674 bool force_passive = !req->n_ssids;
675
676 wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config");
677
678 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
679 if (!cfg)
680 return -ENOMEM;
681
682 cfg->role_id = wlvif->role_id;
683 cfg->rssi_threshold = c->rssi_threshold;
684 cfg->snr_threshold = c->snr_threshold;
685 cfg->n_probe_reqs = c->num_probe_reqs;
686 /* cycles set to 0 it means infinite (until manually stopped) */
687 cfg->cycles = 0;
688 /* report APs when at least 1 is found */
689 cfg->report_after = 1;
690 /* don't stop scanning automatically when something is found */
691 cfg->terminate = 0;
692 cfg->tag = WL1271_SCAN_DEFAULT_TAG;
693 /* don't filter on BSS type */
694 cfg->bss_type = SCAN_BSS_TYPE_ANY;
695 /* currently NL80211 supports only a single interval */
696 for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++)
697 cfg->intervals[i] = cpu_to_le32(req->interval);
698
699 cfg->ssid_len = 0;
700 ret = wl12xx_scan_sched_scan_ssid_list(wl, wlvif, req);
701 if (ret < 0)
702 goto out;
703
704 cfg->filter_type = ret;
705
706 wl1271_debug(DEBUG_SCAN, "filter_type = %d", cfg->filter_type);
707
708 if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) {
709 wl1271_error("scan channel list is empty");
710 ret = -EINVAL;
711 goto out;
712 }
713
714 if (!force_passive && cfg->active[0]) {
715 u8 band = IEEE80211_BAND_2GHZ;
716 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
717 wlvif->role_id, band,
718 req->ssids[0].ssid,
719 req->ssids[0].ssid_len,
720 ies->ie[band],
721 ies->len[band], true);
722 if (ret < 0) {
723 wl1271_error("2.4GHz PROBE request template failed");
724 goto out;
725 }
726 }
727
728 if (!force_passive && cfg->active[1]) {
729 u8 band = IEEE80211_BAND_5GHZ;
730 ret = wl12xx_cmd_build_probe_req(wl, wlvif,
731 wlvif->role_id, band,
732 req->ssids[0].ssid,
733 req->ssids[0].ssid_len,
734 ies->ie[band],
735 ies->len[band], true);
736 if (ret < 0) {
737 wl1271_error("5GHz PROBE request template failed");
738 goto out;
739 }
740 }
741
742 wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg));
743
744 ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg,
745 sizeof(*cfg), 0);
746 if (ret < 0) {
747 wl1271_error("SCAN configuration failed");
748 goto out;
749 }
750out:
751 kfree(cfg);
752 return ret;
753}
754
755int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif)
756{
757 struct wl1271_cmd_sched_scan_start *start;
758 int ret = 0;
759
760 wl1271_debug(DEBUG_CMD, "cmd periodic scan start");
761
762 if (wlvif->bss_type != BSS_TYPE_STA_BSS)
763 return -EOPNOTSUPP;
764
765 if ((wl->quirks & WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN) &&
766 test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
767 return -EBUSY;
768
769 start = kzalloc(sizeof(*start), GFP_KERNEL);
770 if (!start)
771 return -ENOMEM;
772
773 start->role_id = wlvif->role_id;
774 start->tag = WL1271_SCAN_DEFAULT_TAG;
775
776 ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start,
777 sizeof(*start), 0);
778 if (ret < 0) {
779 wl1271_error("failed to send scan start command");
780 goto out_free;
781 }
782
783out_free:
784 kfree(start);
785 return ret;
786}
787
788void wl1271_scan_sched_scan_results(struct wl1271 *wl)
789{ 464{
790 wl1271_debug(DEBUG_SCAN, "got periodic scan results"); 465 wl1271_debug(DEBUG_SCAN, "got periodic scan results");
791 466
792 ieee80211_sched_scan_results(wl->hw); 467 ieee80211_sched_scan_results(wl->hw);
793} 468}
794 469EXPORT_SYMBOL_GPL(wlcore_scan_sched_scan_results);
795void wl1271_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif)
796{
797 struct wl1271_cmd_sched_scan_stop *stop;
798 int ret = 0;
799
800 wl1271_debug(DEBUG_CMD, "cmd periodic scan stop");
801
802 /* FIXME: what to do if alloc'ing to stop fails? */
803 stop = kzalloc(sizeof(*stop), GFP_KERNEL);
804 if (!stop) {
805 wl1271_error("failed to alloc memory to send sched scan stop");
806 return;
807 }
808
809 stop->role_id = wlvif->role_id;
810 stop->tag = WL1271_SCAN_DEFAULT_TAG;
811
812 ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop,
813 sizeof(*stop), 0);
814 if (ret < 0) {
815 wl1271_error("failed to send sched scan stop command");
816 goto out_free;
817 }
818
819out_free:
820 kfree(stop);
821}
diff --git a/drivers/net/wireless/ti/wlcore/scan.h b/drivers/net/wireless/ti/wlcore/scan.h
index 29f3c8d6b046..a6ab24b5c0f9 100644
--- a/drivers/net/wireless/ti/wlcore/scan.h
+++ b/drivers/net/wireless/ti/wlcore/scan.h
@@ -26,22 +26,20 @@
26 26
27#include "wlcore.h" 27#include "wlcore.h"
28 28
29int wl1271_scan(struct wl1271 *wl, struct ieee80211_vif *vif, 29int wlcore_scan(struct wl1271 *wl, struct ieee80211_vif *vif,
30 const u8 *ssid, size_t ssid_len, 30 const u8 *ssid, size_t ssid_len,
31 struct cfg80211_scan_request *req); 31 struct cfg80211_scan_request *req);
32int wl1271_scan_stop(struct wl1271 *wl);
33int wl1271_scan_build_probe_req(struct wl1271 *wl, 32int wl1271_scan_build_probe_req(struct wl1271 *wl,
34 const u8 *ssid, size_t ssid_len, 33 const u8 *ssid, size_t ssid_len,
35 const u8 *ie, size_t ie_len, u8 band); 34 const u8 *ie, size_t ie_len, u8 band);
36void wl1271_scan_stm(struct wl1271 *wl, struct ieee80211_vif *vif); 35void wl1271_scan_stm(struct wl1271 *wl, struct wl12xx_vif *wlvif);
37void wl1271_scan_complete_work(struct work_struct *work); 36void wl1271_scan_complete_work(struct work_struct *work);
38int wl1271_scan_sched_scan_config(struct wl1271 *wl, 37int wl1271_scan_sched_scan_config(struct wl1271 *wl,
39 struct wl12xx_vif *wlvif, 38 struct wl12xx_vif *wlvif,
40 struct cfg80211_sched_scan_request *req, 39 struct cfg80211_sched_scan_request *req,
41 struct ieee80211_sched_scan_ies *ies); 40 struct ieee80211_sched_scan_ies *ies);
42int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif); 41int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif);
43void wl1271_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif); 42void wlcore_scan_sched_scan_results(struct wl1271 *wl);
44void wl1271_scan_sched_scan_results(struct wl1271 *wl);
45 43
46#define WL1271_SCAN_MAX_CHANNELS 24 44#define WL1271_SCAN_MAX_CHANNELS 24
47#define WL1271_SCAN_DEFAULT_TAG 1 45#define WL1271_SCAN_DEFAULT_TAG 1
@@ -66,56 +64,6 @@ enum {
66 WL1271_SCAN_STATE_DONE 64 WL1271_SCAN_STATE_DONE
67}; 65};
68 66
69struct basic_scan_params {
70 /* Scan option flags (WL1271_SCAN_OPT_*) */
71 __le16 scan_options;
72 u8 role_id;
73 /* Number of scan channels in the list (maximum 30) */
74 u8 n_ch;
75 /* This field indicates the number of probe requests to send
76 per channel for an active scan */
77 u8 n_probe_reqs;
78 u8 tid_trigger;
79 u8 ssid_len;
80 u8 use_ssid_list;
81
82 /* Rate bit field for sending the probes */
83 __le32 tx_rate;
84
85 u8 ssid[IEEE80211_MAX_SSID_LEN];
86 /* Band to scan */
87 u8 band;
88
89 u8 scan_tag;
90 u8 padding2[2];
91} __packed;
92
93struct basic_scan_channel_params {
94 /* Duration in TU to wait for frames on a channel for active scan */
95 __le32 min_duration;
96 __le32 max_duration;
97 __le32 bssid_lsb;
98 __le16 bssid_msb;
99 u8 early_termination;
100 u8 tx_power_att;
101 u8 channel;
102 /* FW internal use only! */
103 u8 dfs_candidate;
104 u8 activity_detected;
105 u8 pad;
106} __packed;
107
108struct wl1271_cmd_scan {
109 struct wl1271_cmd_header header;
110
111 struct basic_scan_params params;
112 struct basic_scan_channel_params channels[WL1271_SCAN_MAX_CHANNELS];
113
114 /* src mac address */
115 u8 addr[ETH_ALEN];
116 u8 padding[2];
117} __packed;
118
119struct wl1271_cmd_trigger_scan_to { 67struct wl1271_cmd_trigger_scan_to {
120 struct wl1271_cmd_header header; 68 struct wl1271_cmd_header header;
121 69
@@ -123,9 +71,17 @@ struct wl1271_cmd_trigger_scan_to {
123} __packed; 71} __packed;
124 72
125#define MAX_CHANNELS_2GHZ 14 73#define MAX_CHANNELS_2GHZ 14
126#define MAX_CHANNELS_5GHZ 23
127#define MAX_CHANNELS_4GHZ 4 74#define MAX_CHANNELS_4GHZ 4
128 75
76/*
77 * This max value here is used only for the struct definition of
78 * wlcore_scan_channels. This struct is used by both 12xx
79 * and 18xx (which have different max 5ghz channels value).
80 * In order to make sure this is large enough, just use the
81 * max possible 5ghz channels.
82 */
83#define MAX_CHANNELS_5GHZ 42
84
129#define SCAN_MAX_CYCLE_INTERVALS 16 85#define SCAN_MAX_CYCLE_INTERVALS 16
130#define SCAN_MAX_BANDS 3 86#define SCAN_MAX_BANDS 3
131 87
@@ -160,43 +116,6 @@ struct conn_scan_ch_params {
160 u8 padding[3]; 116 u8 padding[3];
161} __packed; 117} __packed;
162 118
163struct wl1271_cmd_sched_scan_config {
164 struct wl1271_cmd_header header;
165
166 __le32 intervals[SCAN_MAX_CYCLE_INTERVALS];
167
168 s8 rssi_threshold; /* for filtering (in dBm) */
169 s8 snr_threshold; /* for filtering (in dB) */
170
171 u8 cycles; /* maximum number of scan cycles */
172 u8 report_after; /* report when this number of results are received */
173 u8 terminate; /* stop scanning after reporting */
174
175 u8 tag;
176 u8 bss_type; /* for filtering */
177 u8 filter_type;
178
179 u8 ssid_len; /* For SCAN_SSID_FILTER_SPECIFIC */
180 u8 ssid[IEEE80211_MAX_SSID_LEN];
181
182 u8 n_probe_reqs; /* Number of probes requests per channel */
183
184 u8 passive[SCAN_MAX_BANDS];
185 u8 active[SCAN_MAX_BANDS];
186
187 u8 dfs;
188
189 u8 n_pactive_ch; /* number of pactive (passive until fw detects energy)
190 channels in BG band */
191 u8 role_id;
192 u8 padding[1];
193
194 struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ];
195 struct conn_scan_ch_params channels_5[MAX_CHANNELS_5GHZ];
196 struct conn_scan_ch_params channels_4[MAX_CHANNELS_4GHZ];
197} __packed;
198
199
200#define SCHED_SCAN_MAX_SSIDS 16 119#define SCHED_SCAN_MAX_SSIDS 16
201 120
202enum { 121enum {
@@ -220,21 +139,34 @@ struct wl1271_cmd_sched_scan_ssid_list {
220 u8 padding[2]; 139 u8 padding[2];
221} __packed; 140} __packed;
222 141
223struct wl1271_cmd_sched_scan_start { 142struct wlcore_scan_channels {
224 struct wl1271_cmd_header header; 143 u8 passive[SCAN_MAX_BANDS]; /* number of passive scan channels */
144 u8 active[SCAN_MAX_BANDS]; /* number of active scan channels */
145 u8 dfs; /* number of dfs channels in 5ghz */
146 u8 passive_active; /* number of passive before active channels 2.4ghz */
225 147
226 u8 tag; 148 struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ];
227 u8 role_id; 149 struct conn_scan_ch_params channels_5[MAX_CHANNELS_5GHZ];
228 u8 padding[2]; 150 struct conn_scan_ch_params channels_4[MAX_CHANNELS_4GHZ];
229} __packed; 151};
230
231struct wl1271_cmd_sched_scan_stop {
232 struct wl1271_cmd_header header;
233 152
234 u8 tag; 153enum {
235 u8 role_id; 154 SCAN_TYPE_SEARCH = 0,
236 u8 padding[2]; 155 SCAN_TYPE_PERIODIC = 1,
237} __packed; 156 SCAN_TYPE_TRACKING = 2,
157};
238 158
159bool
160wlcore_set_scan_chan_params(struct wl1271 *wl,
161 struct wlcore_scan_channels *cfg,
162 struct ieee80211_channel *channels[],
163 u32 n_channels,
164 u32 n_ssids,
165 int scan_type);
166
167int
168wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl,
169 struct wl12xx_vif *wlvif,
170 struct cfg80211_sched_scan_request *req);
239 171
240#endif /* __WL1271_SCAN_H__ */ 172#endif /* __WL1271_SCAN_H__ */
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index a3a20be2036f..75622f6f3e6c 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -324,8 +324,7 @@ static void wl1271_remove(struct sdio_func *func)
324 /* Undo decrement done above in wl1271_probe */ 324 /* Undo decrement done above in wl1271_probe */
325 pm_runtime_get_noresume(&func->dev); 325 pm_runtime_get_noresume(&func->dev);
326 326
327 platform_device_del(glue->core); 327 platform_device_unregister(glue->core);
328 platform_device_put(glue->core);
329 kfree(glue); 328 kfree(glue);
330} 329}
331 330
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index 18cadc07b754..53790d1d0d27 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -264,7 +264,7 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
264 void *buf, size_t len, bool fixed) 264 void *buf, size_t len, bool fixed)
265{ 265{
266 struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); 266 struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
267 struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; 267 struct spi_transfer t[2 * (WSPI_MAX_NUM_OF_CHUNKS + 1)];
268 struct spi_message m; 268 struct spi_message m;
269 u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; 269 u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
270 u32 *cmd; 270 u32 *cmd;
@@ -399,8 +399,7 @@ static int wl1271_remove(struct spi_device *spi)
399{ 399{
400 struct wl12xx_spi_glue *glue = spi_get_drvdata(spi); 400 struct wl12xx_spi_glue *glue = spi_get_drvdata(spi);
401 401
402 platform_device_del(glue->core); 402 platform_device_unregister(glue->core);
403 platform_device_put(glue->core);
404 kfree(glue); 403 kfree(glue);
405 404
406 return 0; 405 return 0;
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index a90d3cd09408..ece392c54d9c 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -104,7 +104,7 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
104 struct wl12xx_vif *wlvif, 104 struct wl12xx_vif *wlvif,
105 u8 hlid) 105 u8 hlid)
106{ 106{
107 bool fw_ps, single_sta; 107 bool fw_ps, single_link;
108 u8 tx_pkts; 108 u8 tx_pkts;
109 109
110 if (WARN_ON(!test_bit(hlid, wlvif->links_map))) 110 if (WARN_ON(!test_bit(hlid, wlvif->links_map)))
@@ -112,15 +112,15 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
112 112
113 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 113 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
114 tx_pkts = wl->links[hlid].allocated_pkts; 114 tx_pkts = wl->links[hlid].allocated_pkts;
115 single_sta = (wl->active_sta_count == 1); 115 single_link = (wl->active_link_count == 1);
116 116
117 /* 117 /*
118 * if in FW PS and there is enough data in FW we can put the link 118 * if in FW PS and there is enough data in FW we can put the link
119 * into high-level PS and clean out its TX queues. 119 * into high-level PS and clean out its TX queues.
120 * Make an exception if this is the only connected station. In this 120 * Make an exception if this is the only connected link. In this
121 * case FW-memory congestion is not a problem. 121 * case FW-memory congestion is less of a problem.
122 */ 122 */
123 if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) 123 if (!single_link && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
124 wl12xx_ps_link_start(wl, wlvif, hlid, true); 124 wl12xx_ps_link_start(wl, wlvif, hlid, true);
125} 125}
126 126
@@ -155,21 +155,18 @@ static u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif,
155u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif, 155u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
156 struct sk_buff *skb, struct ieee80211_sta *sta) 156 struct sk_buff *skb, struct ieee80211_sta *sta)
157{ 157{
158 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 158 struct ieee80211_tx_info *control;
159
160 if (!wlvif || wl12xx_is_dummy_packet(wl, skb))
161 return wl->system_hlid;
162 159
163 if (wlvif->bss_type == BSS_TYPE_AP_BSS) 160 if (wlvif->bss_type == BSS_TYPE_AP_BSS)
164 return wl12xx_tx_get_hlid_ap(wl, wlvif, skb, sta); 161 return wl12xx_tx_get_hlid_ap(wl, wlvif, skb, sta);
165 162
166 if ((test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) || 163 control = IEEE80211_SKB_CB(skb);
167 test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags)) && 164 if (control->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
168 !ieee80211_is_auth(hdr->frame_control) && 165 wl1271_debug(DEBUG_TX, "tx offchannel");
169 !ieee80211_is_assoc_req(hdr->frame_control))
170 return wlvif->sta.hlid;
171 else
172 return wlvif->dev_hlid; 166 return wlvif->dev_hlid;
167 }
168
169 return wlvif->sta.hlid;
173} 170}
174 171
175unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl, 172unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl,
@@ -224,9 +221,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
224 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); 221 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
225 wl->tx_allocated_pkts[ac]++; 222 wl->tx_allocated_pkts[ac]++;
226 223
227 if (!wl12xx_is_dummy_packet(wl, skb) && wlvif && 224 if (test_bit(hlid, wl->links_map))
228 wlvif->bss_type == BSS_TYPE_AP_BSS &&
229 test_bit(hlid, wlvif->ap.sta_hlid_map))
230 wl->links[hlid].allocated_pkts++; 225 wl->links[hlid].allocated_pkts++;
231 226
232 ret = 0; 227 ret = 0;
@@ -293,9 +288,14 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
293 288
294 tx_attr |= TX_HW_ATTR_TX_DUMMY_REQ; 289 tx_attr |= TX_HW_ATTR_TX_DUMMY_REQ;
295 } else if (wlvif) { 290 } else if (wlvif) {
291 u8 session_id = wl->session_ids[hlid];
292
293 if ((wl->quirks & WLCORE_QUIRK_AP_ZERO_SESSION_ID) &&
294 (wlvif->bss_type == BSS_TYPE_AP_BSS))
295 session_id = 0;
296
296 /* configure the tx attributes */ 297 /* configure the tx attributes */
297 tx_attr = wlvif->session_counter << 298 tx_attr = session_id << TX_HW_ATTR_OFST_SESSION_COUNTER;
298 TX_HW_ATTR_OFST_SESSION_COUNTER;
299 } 299 }
300 300
301 desc->hlid = hlid; 301 desc->hlid = hlid;
@@ -452,20 +452,22 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
452void wl1271_handle_tx_low_watermark(struct wl1271 *wl) 452void wl1271_handle_tx_low_watermark(struct wl1271 *wl)
453{ 453{
454 int i; 454 int i;
455 struct wl12xx_vif *wlvif;
455 456
456 for (i = 0; i < NUM_TX_QUEUES; i++) { 457 wl12xx_for_each_wlvif(wl, wlvif) {
457 if (wlcore_is_queue_stopped_by_reason(wl, i, 458 for (i = 0; i < NUM_TX_QUEUES; i++) {
458 WLCORE_QUEUE_STOP_REASON_WATERMARK) && 459 if (wlcore_is_queue_stopped_by_reason(wl, wlvif, i,
459 wl->tx_queue_count[i] <= WL1271_TX_QUEUE_LOW_WATERMARK) { 460 WLCORE_QUEUE_STOP_REASON_WATERMARK) &&
460 /* firmware buffer has space, restart queues */ 461 wlvif->tx_queue_count[i] <=
461 wlcore_wake_queue(wl, i, 462 WL1271_TX_QUEUE_LOW_WATERMARK)
462 WLCORE_QUEUE_STOP_REASON_WATERMARK); 463 /* firmware buffer has space, restart queues */
464 wlcore_wake_queue(wl, wlvif, i,
465 WLCORE_QUEUE_STOP_REASON_WATERMARK);
463 } 466 }
464 } 467 }
465} 468}
466 469
467static struct sk_buff_head *wl1271_select_queue(struct wl1271 *wl, 470static int wlcore_select_ac(struct wl1271 *wl)
468 struct sk_buff_head *queues)
469{ 471{
470 int i, q = -1, ac; 472 int i, q = -1, ac;
471 u32 min_pkts = 0xffffffff; 473 u32 min_pkts = 0xffffffff;
@@ -479,45 +481,60 @@ static struct sk_buff_head *wl1271_select_queue(struct wl1271 *wl,
479 */ 481 */
480 for (i = 0; i < NUM_TX_QUEUES; i++) { 482 for (i = 0; i < NUM_TX_QUEUES; i++) {
481 ac = wl1271_tx_get_queue(i); 483 ac = wl1271_tx_get_queue(i);
482 if (!skb_queue_empty(&queues[ac]) && 484 if (wl->tx_queue_count[ac] &&
483 (wl->tx_allocated_pkts[ac] < min_pkts)) { 485 wl->tx_allocated_pkts[ac] < min_pkts) {
484 q = ac; 486 q = ac;
485 min_pkts = wl->tx_allocated_pkts[q]; 487 min_pkts = wl->tx_allocated_pkts[q];
486 } 488 }
487 } 489 }
488 490
489 if (q == -1) 491 return q;
490 return NULL;
491
492 return &queues[q];
493} 492}
494 493
495static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl, 494static struct sk_buff *wlcore_lnk_dequeue(struct wl1271 *wl,
496 struct wl1271_link *lnk) 495 struct wl1271_link *lnk, u8 q)
497{ 496{
498 struct sk_buff *skb; 497 struct sk_buff *skb;
499 unsigned long flags; 498 unsigned long flags;
500 struct sk_buff_head *queue;
501 499
502 queue = wl1271_select_queue(wl, lnk->tx_queue); 500 skb = skb_dequeue(&lnk->tx_queue[q]);
503 if (!queue)
504 return NULL;
505
506 skb = skb_dequeue(queue);
507 if (skb) { 501 if (skb) {
508 int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
509 spin_lock_irqsave(&wl->wl_lock, flags); 502 spin_lock_irqsave(&wl->wl_lock, flags);
510 WARN_ON_ONCE(wl->tx_queue_count[q] <= 0); 503 WARN_ON_ONCE(wl->tx_queue_count[q] <= 0);
511 wl->tx_queue_count[q]--; 504 wl->tx_queue_count[q]--;
505 if (lnk->wlvif) {
506 WARN_ON_ONCE(lnk->wlvif->tx_queue_count[q] <= 0);
507 lnk->wlvif->tx_queue_count[q]--;
508 }
512 spin_unlock_irqrestore(&wl->wl_lock, flags); 509 spin_unlock_irqrestore(&wl->wl_lock, flags);
513 } 510 }
514 511
515 return skb; 512 return skb;
516} 513}
517 514
518static struct sk_buff *wl12xx_vif_skb_dequeue(struct wl1271 *wl, 515static struct sk_buff *wlcore_lnk_dequeue_high_prio(struct wl1271 *wl,
519 struct wl12xx_vif *wlvif, 516 u8 hlid, u8 ac,
520 u8 *hlid) 517 u8 *low_prio_hlid)
518{
519 struct wl1271_link *lnk = &wl->links[hlid];
520
521 if (!wlcore_hw_lnk_high_prio(wl, hlid, lnk)) {
522 if (*low_prio_hlid == WL12XX_INVALID_LINK_ID &&
523 !skb_queue_empty(&lnk->tx_queue[ac]) &&
524 wlcore_hw_lnk_low_prio(wl, hlid, lnk))
525 /* we found the first non-empty low priority queue */
526 *low_prio_hlid = hlid;
527
528 return NULL;
529 }
530
531 return wlcore_lnk_dequeue(wl, lnk, ac);
532}
533
534static struct sk_buff *wlcore_vif_dequeue_high_prio(struct wl1271 *wl,
535 struct wl12xx_vif *wlvif,
536 u8 ac, u8 *hlid,
537 u8 *low_prio_hlid)
521{ 538{
522 struct sk_buff *skb = NULL; 539 struct sk_buff *skb = NULL;
523 int i, h, start_hlid; 540 int i, h, start_hlid;
@@ -533,7 +550,8 @@ static struct sk_buff *wl12xx_vif_skb_dequeue(struct wl1271 *wl,
533 if (!test_bit(h, wlvif->links_map)) 550 if (!test_bit(h, wlvif->links_map))
534 continue; 551 continue;
535 552
536 skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[h]); 553 skb = wlcore_lnk_dequeue_high_prio(wl, h, ac,
554 low_prio_hlid);
537 if (!skb) 555 if (!skb)
538 continue; 556 continue;
539 557
@@ -553,42 +571,74 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl, u8 *hlid)
553 unsigned long flags; 571 unsigned long flags;
554 struct wl12xx_vif *wlvif = wl->last_wlvif; 572 struct wl12xx_vif *wlvif = wl->last_wlvif;
555 struct sk_buff *skb = NULL; 573 struct sk_buff *skb = NULL;
574 int ac;
575 u8 low_prio_hlid = WL12XX_INVALID_LINK_ID;
576
577 ac = wlcore_select_ac(wl);
578 if (ac < 0)
579 goto out;
556 580
557 /* continue from last wlvif (round robin) */ 581 /* continue from last wlvif (round robin) */
558 if (wlvif) { 582 if (wlvif) {
559 wl12xx_for_each_wlvif_continue(wl, wlvif) { 583 wl12xx_for_each_wlvif_continue(wl, wlvif) {
560 skb = wl12xx_vif_skb_dequeue(wl, wlvif, hlid); 584 if (!wlvif->tx_queue_count[ac])
561 if (skb) { 585 continue;
562 wl->last_wlvif = wlvif; 586
563 break; 587 skb = wlcore_vif_dequeue_high_prio(wl, wlvif, ac, hlid,
564 } 588 &low_prio_hlid);
589 if (!skb)
590 continue;
591
592 wl->last_wlvif = wlvif;
593 break;
565 } 594 }
566 } 595 }
567 596
568 /* dequeue from the system HLID before the restarting wlvif list */ 597 /* dequeue from the system HLID before the restarting wlvif list */
569 if (!skb) { 598 if (!skb) {
570 skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]); 599 skb = wlcore_lnk_dequeue_high_prio(wl, wl->system_hlid,
571 *hlid = wl->system_hlid; 600 ac, &low_prio_hlid);
601 if (skb) {
602 *hlid = wl->system_hlid;
603 wl->last_wlvif = NULL;
604 }
572 } 605 }
573 606
574 /* do a new pass over the wlvif list */ 607 /* Do a new pass over the wlvif list. But no need to continue
608 * after last_wlvif. The previous pass should have found it. */
575 if (!skb) { 609 if (!skb) {
576 wl12xx_for_each_wlvif(wl, wlvif) { 610 wl12xx_for_each_wlvif(wl, wlvif) {
577 skb = wl12xx_vif_skb_dequeue(wl, wlvif, hlid); 611 if (!wlvif->tx_queue_count[ac])
612 goto next;
613
614 skb = wlcore_vif_dequeue_high_prio(wl, wlvif, ac, hlid,
615 &low_prio_hlid);
578 if (skb) { 616 if (skb) {
579 wl->last_wlvif = wlvif; 617 wl->last_wlvif = wlvif;
580 break; 618 break;
581 } 619 }
582 620
583 /* 621next:
584 * No need to continue after last_wlvif. The previous
585 * pass should have found it.
586 */
587 if (wlvif == wl->last_wlvif) 622 if (wlvif == wl->last_wlvif)
588 break; 623 break;
589 } 624 }
590 } 625 }
591 626
627 /* no high priority skbs found - but maybe a low priority one? */
628 if (!skb && low_prio_hlid != WL12XX_INVALID_LINK_ID) {
629 struct wl1271_link *lnk = &wl->links[low_prio_hlid];
630 skb = wlcore_lnk_dequeue(wl, lnk, ac);
631
632 WARN_ON(!skb); /* we checked this before */
633 *hlid = low_prio_hlid;
634
635 /* ensure proper round robin in the vif/link levels */
636 wl->last_wlvif = lnk->wlvif;
637 if (lnk->wlvif)
638 lnk->wlvif->last_tx_hlid = low_prio_hlid;
639
640 }
641
592 if (!skb && 642 if (!skb &&
593 test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { 643 test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
594 int q; 644 int q;
@@ -602,6 +652,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl, u8 *hlid)
602 spin_unlock_irqrestore(&wl->wl_lock, flags); 652 spin_unlock_irqrestore(&wl->wl_lock, flags);
603 } 653 }
604 654
655out:
605 return skb; 656 return skb;
606} 657}
607 658
@@ -623,6 +674,8 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct wl12xx_vif *wlvif,
623 674
624 spin_lock_irqsave(&wl->wl_lock, flags); 675 spin_lock_irqsave(&wl->wl_lock, flags);
625 wl->tx_queue_count[q]++; 676 wl->tx_queue_count[q]++;
677 if (wlvif)
678 wlvif->tx_queue_count[q]++;
626 spin_unlock_irqrestore(&wl->wl_lock, flags); 679 spin_unlock_irqrestore(&wl->wl_lock, flags);
627} 680}
628 681
@@ -699,7 +752,7 @@ int wlcore_tx_work_locked(struct wl1271 *wl)
699 bool has_data = false; 752 bool has_data = false;
700 753
701 wlvif = NULL; 754 wlvif = NULL;
702 if (!wl12xx_is_dummy_packet(wl, skb) && info->control.vif) 755 if (!wl12xx_is_dummy_packet(wl, skb))
703 wlvif = wl12xx_vif_to_data(info->control.vif); 756 wlvif = wl12xx_vif_to_data(info->control.vif);
704 else 757 else
705 hlid = wl->system_hlid; 758 hlid = wl->system_hlid;
@@ -972,10 +1025,11 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
972 unsigned long flags; 1025 unsigned long flags;
973 struct ieee80211_tx_info *info; 1026 struct ieee80211_tx_info *info;
974 int total[NUM_TX_QUEUES]; 1027 int total[NUM_TX_QUEUES];
1028 struct wl1271_link *lnk = &wl->links[hlid];
975 1029
976 for (i = 0; i < NUM_TX_QUEUES; i++) { 1030 for (i = 0; i < NUM_TX_QUEUES; i++) {
977 total[i] = 0; 1031 total[i] = 0;
978 while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) { 1032 while ((skb = skb_dequeue(&lnk->tx_queue[i]))) {
979 wl1271_debug(DEBUG_TX, "link freeing skb 0x%p", skb); 1033 wl1271_debug(DEBUG_TX, "link freeing skb 0x%p", skb);
980 1034
981 if (!wl12xx_is_dummy_packet(wl, skb)) { 1035 if (!wl12xx_is_dummy_packet(wl, skb)) {
@@ -990,8 +1044,11 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
990 } 1044 }
991 1045
992 spin_lock_irqsave(&wl->wl_lock, flags); 1046 spin_lock_irqsave(&wl->wl_lock, flags);
993 for (i = 0; i < NUM_TX_QUEUES; i++) 1047 for (i = 0; i < NUM_TX_QUEUES; i++) {
994 wl->tx_queue_count[i] -= total[i]; 1048 wl->tx_queue_count[i] -= total[i];
1049 if (lnk->wlvif)
1050 lnk->wlvif->tx_queue_count[i] -= total[i];
1051 }
995 spin_unlock_irqrestore(&wl->wl_lock, flags); 1052 spin_unlock_irqrestore(&wl->wl_lock, flags);
996 1053
997 wl1271_handle_tx_low_watermark(wl); 1054 wl1271_handle_tx_low_watermark(wl);
@@ -1004,16 +1061,18 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1004 1061
1005 /* TX failure */ 1062 /* TX failure */
1006 for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) { 1063 for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) {
1007 if (wlvif->bss_type == BSS_TYPE_AP_BSS) 1064 if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
1065 /* this calls wl12xx_free_link */
1008 wl1271_free_sta(wl, wlvif, i); 1066 wl1271_free_sta(wl, wlvif, i);
1009 else 1067 } else {
1010 wlvif->sta.ba_rx_bitmap = 0; 1068 u8 hlid = i;
1011 1069 wl12xx_free_link(wl, wlvif, &hlid);
1012 wl->links[i].allocated_pkts = 0; 1070 }
1013 wl->links[i].prev_freed_pkts = 0;
1014 } 1071 }
1015 wlvif->last_tx_hlid = 0; 1072 wlvif->last_tx_hlid = 0;
1016 1073
1074 for (i = 0; i < NUM_TX_QUEUES; i++)
1075 wlvif->tx_queue_count[i] = 0;
1017} 1076}
1018/* caller must hold wl->mutex and TX must be stopped */ 1077/* caller must hold wl->mutex and TX must be stopped */
1019void wl12xx_tx_reset(struct wl1271 *wl) 1078void wl12xx_tx_reset(struct wl1271 *wl)
@@ -1023,7 +1082,7 @@ void wl12xx_tx_reset(struct wl1271 *wl)
1023 struct ieee80211_tx_info *info; 1082 struct ieee80211_tx_info *info;
1024 1083
1025 /* only reset the queues if something bad happened */ 1084 /* only reset the queues if something bad happened */
1026 if (WARN_ON_ONCE(wl1271_tx_total_queue_count(wl) != 0)) { 1085 if (wl1271_tx_total_queue_count(wl) != 0) {
1027 for (i = 0; i < WL12XX_MAX_LINKS; i++) 1086 for (i = 0; i < WL12XX_MAX_LINKS; i++)
1028 wl1271_tx_reset_link_queues(wl, i); 1087 wl1271_tx_reset_link_queues(wl, i);
1029 1088
@@ -1135,45 +1194,48 @@ u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set)
1135 1194
1136 return BIT(__ffs(rate_set)); 1195 return BIT(__ffs(rate_set));
1137} 1196}
1197EXPORT_SYMBOL_GPL(wl1271_tx_min_rate_get);
1138 1198
1139void wlcore_stop_queue_locked(struct wl1271 *wl, u8 queue, 1199void wlcore_stop_queue_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1140 enum wlcore_queue_stop_reason reason) 1200 u8 queue, enum wlcore_queue_stop_reason reason)
1141{ 1201{
1142 bool stopped = !!wl->queue_stop_reasons[queue]; 1202 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
1203 bool stopped = !!wl->queue_stop_reasons[hwq];
1143 1204
1144 /* queue should not be stopped for this reason */ 1205 /* queue should not be stopped for this reason */
1145 WARN_ON(test_and_set_bit(reason, &wl->queue_stop_reasons[queue])); 1206 WARN_ON_ONCE(test_and_set_bit(reason, &wl->queue_stop_reasons[hwq]));
1146 1207
1147 if (stopped) 1208 if (stopped)
1148 return; 1209 return;
1149 1210
1150 ieee80211_stop_queue(wl->hw, wl1271_tx_get_mac80211_queue(queue)); 1211 ieee80211_stop_queue(wl->hw, hwq);
1151} 1212}
1152 1213
1153void wlcore_stop_queue(struct wl1271 *wl, u8 queue, 1214void wlcore_stop_queue(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 queue,
1154 enum wlcore_queue_stop_reason reason) 1215 enum wlcore_queue_stop_reason reason)
1155{ 1216{
1156 unsigned long flags; 1217 unsigned long flags;
1157 1218
1158 spin_lock_irqsave(&wl->wl_lock, flags); 1219 spin_lock_irqsave(&wl->wl_lock, flags);
1159 wlcore_stop_queue_locked(wl, queue, reason); 1220 wlcore_stop_queue_locked(wl, wlvif, queue, reason);
1160 spin_unlock_irqrestore(&wl->wl_lock, flags); 1221 spin_unlock_irqrestore(&wl->wl_lock, flags);
1161} 1222}
1162 1223
1163void wlcore_wake_queue(struct wl1271 *wl, u8 queue, 1224void wlcore_wake_queue(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 queue,
1164 enum wlcore_queue_stop_reason reason) 1225 enum wlcore_queue_stop_reason reason)
1165{ 1226{
1166 unsigned long flags; 1227 unsigned long flags;
1228 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
1167 1229
1168 spin_lock_irqsave(&wl->wl_lock, flags); 1230 spin_lock_irqsave(&wl->wl_lock, flags);
1169 1231
1170 /* queue should not be clear for this reason */ 1232 /* queue should not be clear for this reason */
1171 WARN_ON(!test_and_clear_bit(reason, &wl->queue_stop_reasons[queue])); 1233 WARN_ON_ONCE(!test_and_clear_bit(reason, &wl->queue_stop_reasons[hwq]));
1172 1234
1173 if (wl->queue_stop_reasons[queue]) 1235 if (wl->queue_stop_reasons[hwq])
1174 goto out; 1236 goto out;
1175 1237
1176 ieee80211_wake_queue(wl->hw, wl1271_tx_get_mac80211_queue(queue)); 1238 ieee80211_wake_queue(wl->hw, hwq);
1177 1239
1178out: 1240out:
1179 spin_unlock_irqrestore(&wl->wl_lock, flags); 1241 spin_unlock_irqrestore(&wl->wl_lock, flags);
@@ -1183,48 +1245,74 @@ void wlcore_stop_queues(struct wl1271 *wl,
1183 enum wlcore_queue_stop_reason reason) 1245 enum wlcore_queue_stop_reason reason)
1184{ 1246{
1185 int i; 1247 int i;
1248 unsigned long flags;
1186 1249
1187 for (i = 0; i < NUM_TX_QUEUES; i++) 1250 spin_lock_irqsave(&wl->wl_lock, flags);
1188 wlcore_stop_queue(wl, i, reason); 1251
1252 /* mark all possible queues as stopped */
1253 for (i = 0; i < WLCORE_NUM_MAC_ADDRESSES * NUM_TX_QUEUES; i++)
1254 WARN_ON_ONCE(test_and_set_bit(reason,
1255 &wl->queue_stop_reasons[i]));
1256
1257 /* use the global version to make sure all vifs in mac80211 we don't
1258 * know are stopped.
1259 */
1260 ieee80211_stop_queues(wl->hw);
1261
1262 spin_unlock_irqrestore(&wl->wl_lock, flags);
1189} 1263}
1190EXPORT_SYMBOL_GPL(wlcore_stop_queues);
1191 1264
1192void wlcore_wake_queues(struct wl1271 *wl, 1265void wlcore_wake_queues(struct wl1271 *wl,
1193 enum wlcore_queue_stop_reason reason) 1266 enum wlcore_queue_stop_reason reason)
1194{ 1267{
1195 int i; 1268 int i;
1269 unsigned long flags;
1196 1270
1197 for (i = 0; i < NUM_TX_QUEUES; i++) 1271 spin_lock_irqsave(&wl->wl_lock, flags);
1198 wlcore_wake_queue(wl, i, reason); 1272
1273 /* mark all possible queues as awake */
1274 for (i = 0; i < WLCORE_NUM_MAC_ADDRESSES * NUM_TX_QUEUES; i++)
1275 WARN_ON_ONCE(!test_and_clear_bit(reason,
1276 &wl->queue_stop_reasons[i]));
1277
1278 /* use the global version to make sure all vifs in mac80211 we don't
1279 * know are woken up.
1280 */
1281 ieee80211_wake_queues(wl->hw);
1282
1283 spin_unlock_irqrestore(&wl->wl_lock, flags);
1199} 1284}
1200EXPORT_SYMBOL_GPL(wlcore_wake_queues);
1201 1285
1202void wlcore_reset_stopped_queues(struct wl1271 *wl) 1286bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl,
1287 struct wl12xx_vif *wlvif, u8 queue,
1288 enum wlcore_queue_stop_reason reason)
1203{ 1289{
1204 int i;
1205 unsigned long flags; 1290 unsigned long flags;
1291 bool stopped;
1206 1292
1207 spin_lock_irqsave(&wl->wl_lock, flags); 1293 spin_lock_irqsave(&wl->wl_lock, flags);
1208 1294 stopped = wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, queue,
1209 for (i = 0; i < NUM_TX_QUEUES; i++) { 1295 reason);
1210 if (!wl->queue_stop_reasons[i])
1211 continue;
1212
1213 wl->queue_stop_reasons[i] = 0;
1214 ieee80211_wake_queue(wl->hw,
1215 wl1271_tx_get_mac80211_queue(i));
1216 }
1217
1218 spin_unlock_irqrestore(&wl->wl_lock, flags); 1296 spin_unlock_irqrestore(&wl->wl_lock, flags);
1297
1298 return stopped;
1219} 1299}
1220 1300
1221bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl, u8 queue, 1301bool wlcore_is_queue_stopped_by_reason_locked(struct wl1271 *wl,
1222 enum wlcore_queue_stop_reason reason) 1302 struct wl12xx_vif *wlvif, u8 queue,
1303 enum wlcore_queue_stop_reason reason)
1223{ 1304{
1224 return test_bit(reason, &wl->queue_stop_reasons[queue]); 1305 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
1306
1307 WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock));
1308 return test_bit(reason, &wl->queue_stop_reasons[hwq]);
1225} 1309}
1226 1310
1227bool wlcore_is_queue_stopped(struct wl1271 *wl, u8 queue) 1311bool wlcore_is_queue_stopped_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1312 u8 queue)
1228{ 1313{
1229 return !!wl->queue_stop_reasons[queue]; 1314 int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
1315
1316 WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock));
1317 return !!wl->queue_stop_reasons[hwq];
1230} 1318}
diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h
index 349520d8b724..55aa4acf9105 100644
--- a/drivers/net/wireless/ti/wlcore/tx.h
+++ b/drivers/net/wireless/ti/wlcore/tx.h
@@ -207,19 +207,22 @@ static inline int wl1271_tx_get_queue(int queue)
207 } 207 }
208} 208}
209 209
210static inline int wl1271_tx_get_mac80211_queue(int queue) 210static inline
211int wlcore_tx_get_mac80211_queue(struct wl12xx_vif *wlvif, int queue)
211{ 212{
213 int mac_queue = wlvif->hw_queue_base;
214
212 switch (queue) { 215 switch (queue) {
213 case CONF_TX_AC_VO: 216 case CONF_TX_AC_VO:
214 return 0; 217 return mac_queue + 0;
215 case CONF_TX_AC_VI: 218 case CONF_TX_AC_VI:
216 return 1; 219 return mac_queue + 1;
217 case CONF_TX_AC_BE: 220 case CONF_TX_AC_BE:
218 return 2; 221 return mac_queue + 2;
219 case CONF_TX_AC_BK: 222 case CONF_TX_AC_BK:
220 return 3; 223 return mac_queue + 3;
221 default: 224 default:
222 return 2; 225 return mac_queue + 2;
223 } 226 }
224} 227}
225 228
@@ -252,20 +255,26 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids);
252unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl, 255unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl,
253 unsigned int packet_length); 256 unsigned int packet_length);
254void wl1271_free_tx_id(struct wl1271 *wl, int id); 257void wl1271_free_tx_id(struct wl1271 *wl, int id);
255void wlcore_stop_queue_locked(struct wl1271 *wl, u8 queue, 258void wlcore_stop_queue_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
256 enum wlcore_queue_stop_reason reason); 259 u8 queue, enum wlcore_queue_stop_reason reason);
257void wlcore_stop_queue(struct wl1271 *wl, u8 queue, 260void wlcore_stop_queue(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 queue,
258 enum wlcore_queue_stop_reason reason); 261 enum wlcore_queue_stop_reason reason);
259void wlcore_wake_queue(struct wl1271 *wl, u8 queue, 262void wlcore_wake_queue(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 queue,
260 enum wlcore_queue_stop_reason reason); 263 enum wlcore_queue_stop_reason reason);
261void wlcore_stop_queues(struct wl1271 *wl, 264void wlcore_stop_queues(struct wl1271 *wl,
262 enum wlcore_queue_stop_reason reason); 265 enum wlcore_queue_stop_reason reason);
263void wlcore_wake_queues(struct wl1271 *wl, 266void wlcore_wake_queues(struct wl1271 *wl,
264 enum wlcore_queue_stop_reason reason); 267 enum wlcore_queue_stop_reason reason);
265void wlcore_reset_stopped_queues(struct wl1271 *wl); 268bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl,
266bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl, u8 queue, 269 struct wl12xx_vif *wlvif, u8 queue,
267 enum wlcore_queue_stop_reason reason); 270 enum wlcore_queue_stop_reason reason);
268bool wlcore_is_queue_stopped(struct wl1271 *wl, u8 queue); 271bool
272wlcore_is_queue_stopped_by_reason_locked(struct wl1271 *wl,
273 struct wl12xx_vif *wlvif,
274 u8 queue,
275 enum wlcore_queue_stop_reason reason);
276bool wlcore_is_queue_stopped_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
277 u8 queue);
269 278
270/* from main.c */ 279/* from main.c */
271void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); 280void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index c3884937c007..ebd8c6fad7cd 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -37,6 +37,9 @@
37 */ 37 */
38#define WLCORE_NUM_MAC_ADDRESSES 3 38#define WLCORE_NUM_MAC_ADDRESSES 3
39 39
40/* wl12xx/wl18xx maximum transmission power (in dBm) */
41#define WLCORE_MAX_TXPWR 25
42
40/* forward declaration */ 43/* forward declaration */
41struct wl1271_tx_hw_descr; 44struct wl1271_tx_hw_descr;
42enum wl_rx_buf_align; 45enum wl_rx_buf_align;
@@ -51,6 +54,9 @@ struct wlcore_ops {
51 int (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, 54 int (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr,
52 void *buf, size_t len); 55 void *buf, size_t len);
53 int (*ack_event)(struct wl1271 *wl); 56 int (*ack_event)(struct wl1271 *wl);
57 int (*wait_for_event)(struct wl1271 *wl, enum wlcore_wait_event event,
58 bool *timeout);
59 int (*process_mailbox_events)(struct wl1271 *wl);
54 u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks); 60 u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks);
55 void (*set_tx_desc_blocks)(struct wl1271 *wl, 61 void (*set_tx_desc_blocks)(struct wl1271 *wl,
56 struct wl1271_tx_hw_descr *desc, 62 struct wl1271_tx_hw_descr *desc,
@@ -82,12 +88,32 @@ struct wlcore_ops {
82 int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir); 88 int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir);
83 int (*handle_static_data)(struct wl1271 *wl, 89 int (*handle_static_data)(struct wl1271 *wl,
84 struct wl1271_static_data *static_data); 90 struct wl1271_static_data *static_data);
91 int (*scan_start)(struct wl1271 *wl, struct wl12xx_vif *wlvif,
92 struct cfg80211_scan_request *req);
93 int (*scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
94 int (*sched_scan_start)(struct wl1271 *wl, struct wl12xx_vif *wlvif,
95 struct cfg80211_sched_scan_request *req,
96 struct ieee80211_sched_scan_ies *ies);
97 void (*sched_scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
85 int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem); 98 int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem);
86 int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd, 99 int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd,
87 struct ieee80211_vif *vif, 100 struct ieee80211_vif *vif,
88 struct ieee80211_sta *sta, 101 struct ieee80211_sta *sta,
89 struct ieee80211_key_conf *key_conf); 102 struct ieee80211_key_conf *key_conf);
103 int (*channel_switch)(struct wl1271 *wl,
104 struct wl12xx_vif *wlvif,
105 struct ieee80211_channel_switch *ch_switch);
90 u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len); 106 u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len);
107 void (*sta_rc_update)(struct wl1271 *wl, struct wl12xx_vif *wlvif,
108 struct ieee80211_sta *sta, u32 changed);
109 int (*set_peer_cap)(struct wl1271 *wl,
110 struct ieee80211_sta_ht_cap *ht_cap,
111 bool allow_ht_operation,
112 u32 rate_set, u8 hlid);
113 bool (*lnk_high_prio)(struct wl1271 *wl, u8 hlid,
114 struct wl1271_link *lnk);
115 bool (*lnk_low_prio)(struct wl1271 *wl, u8 hlid,
116 struct wl1271_link *lnk);
91}; 117};
92 118
93enum wlcore_partitions { 119enum wlcore_partitions {
@@ -202,6 +228,8 @@ struct wl1271 {
202 unsigned long klv_templates_map[ 228 unsigned long klv_templates_map[
203 BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)]; 229 BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)];
204 230
231 u8 session_ids[WL12XX_MAX_LINKS];
232
205 struct list_head wlvif_list; 233 struct list_head wlvif_list;
206 234
207 u8 sta_count; 235 u8 sta_count;
@@ -227,7 +255,8 @@ struct wl1271 {
227 255
228 /* Frames scheduled for transmission, not handled yet */ 256 /* Frames scheduled for transmission, not handled yet */
229 int tx_queue_count[NUM_TX_QUEUES]; 257 int tx_queue_count[NUM_TX_QUEUES];
230 unsigned long queue_stop_reasons[NUM_TX_QUEUES]; 258 unsigned long queue_stop_reasons[
259 NUM_TX_QUEUES * WLCORE_NUM_MAC_ADDRESSES];
231 260
232 /* Frames received, not handled yet by mac80211 */ 261 /* Frames received, not handled yet by mac80211 */
233 struct sk_buff_head deferred_rx_queue; 262 struct sk_buff_head deferred_rx_queue;
@@ -269,24 +298,30 @@ struct wl1271 {
269 struct work_struct recovery_work; 298 struct work_struct recovery_work;
270 bool watchdog_recovery; 299 bool watchdog_recovery;
271 300
301 /* Reg domain last configuration */
302 u32 reg_ch_conf_last[2];
303 /* Reg domain pending configuration */
304 u32 reg_ch_conf_pending[2];
305
272 /* Pointer that holds DMA-friendly block for the mailbox */ 306 /* Pointer that holds DMA-friendly block for the mailbox */
273 struct event_mailbox *mbox; 307 void *mbox;
274 308
275 /* The mbox event mask */ 309 /* The mbox event mask */
276 u32 event_mask; 310 u32 event_mask;
277 311
278 /* Mailbox pointers */ 312 /* Mailbox pointers */
313 u32 mbox_size;
279 u32 mbox_ptr[2]; 314 u32 mbox_ptr[2];
280 315
281 /* Are we currently scanning */ 316 /* Are we currently scanning */
282 struct ieee80211_vif *scan_vif; 317 struct wl12xx_vif *scan_wlvif;
283 struct wl1271_scan scan; 318 struct wl1271_scan scan;
284 struct delayed_work scan_complete_work; 319 struct delayed_work scan_complete_work;
285 320
286 /* Connection loss work */ 321 struct ieee80211_vif *roc_vif;
287 struct delayed_work connection_loss_work; 322 struct delayed_work roc_complete_work;
288 323
289 bool sched_scanning; 324 struct wl12xx_vif *sched_vif;
290 325
291 /* The current band */ 326 /* The current band */
292 enum ieee80211_band band; 327 enum ieee80211_band band;
@@ -299,7 +334,7 @@ struct wl1271 {
299 334
300 struct wl1271_stats stats; 335 struct wl1271_stats stats;
301 336
302 __le32 buffer_32; 337 __le32 *buffer_32;
303 u32 buffer_cmd; 338 u32 buffer_cmd;
304 u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; 339 u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
305 340
@@ -314,6 +349,8 @@ struct wl1271 {
314 349
315 bool enable_11a; 350 bool enable_11a;
316 351
352 int recovery_count;
353
317 /* Most recently reported noise in dBm */ 354 /* Most recently reported noise in dBm */
318 s8 noise; 355 s8 noise;
319 356
@@ -333,6 +370,12 @@ struct wl1271 {
333 */ 370 */
334 struct wl1271_link links[WL12XX_MAX_LINKS]; 371 struct wl1271_link links[WL12XX_MAX_LINKS];
335 372
373 /* number of currently active links */
374 int active_link_count;
375
376 /* Fast/slow links bitmap according to FW */
377 u32 fw_fast_lnk_map;
378
336 /* AP-mode - a bitmap of links currently in PS mode according to FW */ 379 /* AP-mode - a bitmap of links currently in PS mode according to FW */
337 u32 ap_fw_ps_map; 380 u32 ap_fw_ps_map;
338 381
@@ -367,6 +410,12 @@ struct wl1271 {
367 const char *sr_fw_name; 410 const char *sr_fw_name;
368 const char *mr_fw_name; 411 const char *mr_fw_name;
369 412
413 u8 scan_templ_id_2_4;
414 u8 scan_templ_id_5;
415 u8 sched_scan_templ_id_2_4;
416 u8 sched_scan_templ_id_5;
417 u8 max_channels_5;
418
370 /* per-chip-family private structure */ 419 /* per-chip-family private structure */
371 void *priv; 420 void *priv;
372 421
@@ -408,20 +457,28 @@ struct wl1271 {
408 /* the number of allocated MAC addresses in this chip */ 457 /* the number of allocated MAC addresses in this chip */
409 int num_mac_addr; 458 int num_mac_addr;
410 459
411 /* the minimum FW version required for the driver to work */ 460 /* minimum FW version required for the driver to work in single-role */
412 unsigned int min_fw_ver[NUM_FW_VER]; 461 unsigned int min_sr_fw_ver[NUM_FW_VER];
462
463 /* minimum FW version required for the driver to work in multi-role */
464 unsigned int min_mr_fw_ver[NUM_FW_VER];
413 465
414 struct completion nvs_loading_complete; 466 struct completion nvs_loading_complete;
467
468 /* number of concurrent channels the HW supports */
469 u32 num_channels;
415}; 470};
416 471
417int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); 472int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
418int wlcore_remove(struct platform_device *pdev); 473int wlcore_remove(struct platform_device *pdev);
419struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size); 474struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
475 u32 mbox_size);
420int wlcore_free_hw(struct wl1271 *wl); 476int wlcore_free_hw(struct wl1271 *wl);
421int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, 477int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
422 struct ieee80211_vif *vif, 478 struct ieee80211_vif *vif,
423 struct ieee80211_sta *sta, 479 struct ieee80211_sta *sta,
424 struct ieee80211_key_conf *key_conf); 480 struct ieee80211_key_conf *key_conf);
481void wlcore_regdomain_config(struct wl1271 *wl);
425 482
426static inline void 483static inline void
427wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band, 484wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band,
@@ -430,16 +487,27 @@ wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band,
430 memcpy(&wl->ht_cap[band], ht_cap, sizeof(*ht_cap)); 487 memcpy(&wl->ht_cap[band], ht_cap, sizeof(*ht_cap));
431} 488}
432 489
490/* Tell wlcore not to care about this element when checking the version */
491#define WLCORE_FW_VER_IGNORE -1
492
433static inline void 493static inline void
434wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip, 494wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip,
435 unsigned int iftype, unsigned int major, 495 unsigned int iftype_sr, unsigned int major_sr,
436 unsigned int subtype, unsigned int minor) 496 unsigned int subtype_sr, unsigned int minor_sr,
497 unsigned int iftype_mr, unsigned int major_mr,
498 unsigned int subtype_mr, unsigned int minor_mr)
437{ 499{
438 wl->min_fw_ver[FW_VER_CHIP] = chip; 500 wl->min_sr_fw_ver[FW_VER_CHIP] = chip;
439 wl->min_fw_ver[FW_VER_IF_TYPE] = iftype; 501 wl->min_sr_fw_ver[FW_VER_IF_TYPE] = iftype_sr;
440 wl->min_fw_ver[FW_VER_MAJOR] = major; 502 wl->min_sr_fw_ver[FW_VER_MAJOR] = major_sr;
441 wl->min_fw_ver[FW_VER_SUBTYPE] = subtype; 503 wl->min_sr_fw_ver[FW_VER_SUBTYPE] = subtype_sr;
442 wl->min_fw_ver[FW_VER_MINOR] = minor; 504 wl->min_sr_fw_ver[FW_VER_MINOR] = minor_sr;
505
506 wl->min_mr_fw_ver[FW_VER_CHIP] = chip;
507 wl->min_mr_fw_ver[FW_VER_IF_TYPE] = iftype_mr;
508 wl->min_mr_fw_ver[FW_VER_MAJOR] = major_mr;
509 wl->min_mr_fw_ver[FW_VER_SUBTYPE] = subtype_mr;
510 wl->min_mr_fw_ver[FW_VER_MINOR] = minor_mr;
443} 511}
444 512
445/* Firmware image load chunk size */ 513/* Firmware image load chunk size */
@@ -450,6 +518,9 @@ wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip,
450/* Each RX/TX transaction requires an end-of-transaction transfer */ 518/* Each RX/TX transaction requires an end-of-transaction transfer */
451#define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0) 519#define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0)
452 520
521/* the first start_role(sta) sometimes doesn't work on wl12xx */
522#define WLCORE_QUIRK_START_STA_FAILS BIT(1)
523
453/* wl127x and SPI don't support SDIO block size alignment */ 524/* wl127x and SPI don't support SDIO block size alignment */
454#define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2) 525#define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2)
455 526
@@ -462,9 +533,6 @@ wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip,
462/* Older firmwares use an old NVS format */ 533/* Older firmwares use an old NVS format */
463#define WLCORE_QUIRK_LEGACY_NVS BIT(5) 534#define WLCORE_QUIRK_LEGACY_NVS BIT(5)
464 535
465/* Some firmwares may not support ELP */
466#define WLCORE_QUIRK_NO_ELP BIT(6)
467
468/* pad only the last frame in the aggregate buffer */ 536/* pad only the last frame in the aggregate buffer */
469#define WLCORE_QUIRK_TX_PAD_LAST_FRAME BIT(7) 537#define WLCORE_QUIRK_TX_PAD_LAST_FRAME BIT(7)
470 538
@@ -477,11 +545,11 @@ wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip,
477/* separate probe response templates for one-shot and sched scans */ 545/* separate probe response templates for one-shot and sched scans */
478#define WLCORE_QUIRK_DUAL_PROBE_TMPL BIT(10) 546#define WLCORE_QUIRK_DUAL_PROBE_TMPL BIT(10)
479 547
480/* TODO: move to the lower drivers when all usages are abstracted */ 548/* Firmware requires reg domain configuration for active calibration */
481#define CHIP_ID_1271_PG10 (0x4030101) 549#define WLCORE_QUIRK_REGDOMAIN_CONF BIT(11)
482#define CHIP_ID_1271_PG20 (0x4030111) 550
483#define CHIP_ID_1283_PG10 (0x05030101) 551/* The FW only support a zero session id for AP */
484#define CHIP_ID_1283_PG20 (0x05030111) 552#define WLCORE_QUIRK_AP_ZERO_SESSION_ID BIT(12)
485 553
486/* TODO: move all these common registers and values elsewhere */ 554/* TODO: move all these common registers and values elsewhere */
487#define HW_ACCESS_ELP_CTRL_REG 0x1FFFC 555#define HW_ACCESS_ELP_CTRL_REG 0x1FFFC
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 5ce26cf402fc..910f8e2e556a 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -109,17 +109,6 @@ enum {
109 NUM_FW_VER 109 NUM_FW_VER
110}; 110};
111 111
112#define FW_VER_CHIP_WL127X 6
113#define FW_VER_CHIP_WL128X 7
114
115#define FW_VER_IF_TYPE_STA 1
116#define FW_VER_IF_TYPE_AP 2
117
118#define FW_VER_MINOR_1_SPARE_STA_MIN 58
119#define FW_VER_MINOR_1_SPARE_AP_MIN 47
120
121#define FW_VER_MINOR_FWLOG_STA_MIN 70
122
123struct wl1271_chip { 112struct wl1271_chip {
124 u32 id; 113 u32 id;
125 char fw_ver_str[ETHTOOL_FWVERS_LEN]; 114 char fw_ver_str[ETHTOOL_FWVERS_LEN];
@@ -141,7 +130,10 @@ struct wl_fw_packet_counters {
141 /* Cumulative counter of released Voice memory blocks */ 130 /* Cumulative counter of released Voice memory blocks */
142 u8 tx_voice_released_blks; 131 u8 tx_voice_released_blks;
143 132
144 u8 padding[3]; 133 /* Tx rate of the last transmitted packet */
134 u8 tx_last_rate;
135
136 u8 padding[2];
145} __packed; 137} __packed;
146 138
147/* FW status registers */ 139/* FW status registers */
@@ -260,6 +252,8 @@ enum wl12xx_vif_flags {
260 WLVIF_FLAG_IN_USE, 252 WLVIF_FLAG_IN_USE,
261}; 253};
262 254
255struct wl12xx_vif;
256
263struct wl1271_link { 257struct wl1271_link {
264 /* AP-mode - TX queue per AC in link */ 258 /* AP-mode - TX queue per AC in link */
265 struct sk_buff_head tx_queue[NUM_TX_QUEUES]; 259 struct sk_buff_head tx_queue[NUM_TX_QUEUES];
@@ -272,6 +266,9 @@ struct wl1271_link {
272 266
273 /* bitmap of TIDs where RX BA sessions are active for this link */ 267 /* bitmap of TIDs where RX BA sessions are active for this link */
274 u8 ba_bitmap; 268 u8 ba_bitmap;
269
270 /* The wlvif this link belongs to. Might be null for global links */
271 struct wl12xx_vif *wlvif;
275}; 272};
276 273
277#define WL1271_MAX_RX_FILTERS 5 274#define WL1271_MAX_RX_FILTERS 5
@@ -315,6 +312,7 @@ struct wl12xx_rx_filter {
315 312
316struct wl1271_station { 313struct wl1271_station {
317 u8 hlid; 314 u8 hlid;
315 bool in_connection;
318}; 316};
319 317
320struct wl12xx_vif { 318struct wl12xx_vif {
@@ -332,7 +330,6 @@ struct wl12xx_vif {
332 union { 330 union {
333 struct { 331 struct {
334 u8 hlid; 332 u8 hlid;
335 u8 ba_rx_bitmap;
336 333
337 u8 basic_rate_idx; 334 u8 basic_rate_idx;
338 u8 ap_rate_idx; 335 u8 ap_rate_idx;
@@ -341,6 +338,8 @@ struct wl12xx_vif {
341 u8 klv_template_id; 338 u8 klv_template_id;
342 339
343 bool qos; 340 bool qos;
341 /* channel type we started the STA role with */
342 enum nl80211_channel_type role_chan_type;
344 } sta; 343 } sta;
345 struct { 344 struct {
346 u8 global_hlid; 345 u8 global_hlid;
@@ -362,6 +361,9 @@ struct wl12xx_vif {
362 /* the hlid of the last transmitted skb */ 361 /* the hlid of the last transmitted skb */
363 int last_tx_hlid; 362 int last_tx_hlid;
364 363
364 /* counters of packets per AC, across all links in the vif */
365 int tx_queue_count[NUM_TX_QUEUES];
366
365 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; 367 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
366 368
367 u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; 369 u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
@@ -396,9 +398,6 @@ struct wl12xx_vif {
396 /* Our association ID */ 398 /* Our association ID */
397 u16 aid; 399 u16 aid;
398 400
399 /* Session counter for the chipset */
400 int session_counter;
401
402 /* retry counter for PSM entries */ 401 /* retry counter for PSM entries */
403 u8 psm_entry_retry; 402 u8 psm_entry_retry;
404 403
@@ -416,11 +415,28 @@ struct wl12xx_vif {
416 bool ba_support; 415 bool ba_support;
417 bool ba_allowed; 416 bool ba_allowed;
418 417
418 bool wmm_enabled;
419
419 /* Rx Streaming */ 420 /* Rx Streaming */
420 struct work_struct rx_streaming_enable_work; 421 struct work_struct rx_streaming_enable_work;
421 struct work_struct rx_streaming_disable_work; 422 struct work_struct rx_streaming_disable_work;
422 struct timer_list rx_streaming_timer; 423 struct timer_list rx_streaming_timer;
423 424
425 struct delayed_work channel_switch_work;
426 struct delayed_work connection_loss_work;
427
428 /* number of in connection stations */
429 int inconn_count;
430
431 /*
432 * This vif's queues are mapped to mac80211 HW queues as:
433 * VO - hw_queue_base
434 * VI - hw_queue_base + 1
435 * BE - hw_queue_base + 2
436 * BK - hw_queue_base + 3
437 */
438 int hw_queue_base;
439
424 /* 440 /*
425 * This struct must be last! 441 * This struct must be last!
426 * data that has to be saved acrossed reconfigs (e.g. recovery) 442 * data that has to be saved acrossed reconfigs (e.g. recovery)
@@ -443,6 +459,7 @@ struct wl12xx_vif {
443 459
444static inline struct wl12xx_vif *wl12xx_vif_to_data(struct ieee80211_vif *vif) 460static inline struct wl12xx_vif *wl12xx_vif_to_data(struct ieee80211_vif *vif)
445{ 461{
462 WARN_ON(!vif);
446 return (struct wl12xx_vif *)vif->drv_priv; 463 return (struct wl12xx_vif *)vif->drv_priv;
447} 464}
448 465
diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c
index 97ac0a38e3d0..accabe39b320 100644
--- a/drivers/ssb/driver_gpio.c
+++ b/drivers/ssb/driver_gpio.c
@@ -74,6 +74,16 @@ static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio)
74 ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0); 74 ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
75} 75}
76 76
77static int ssb_gpio_chipco_to_irq(struct gpio_chip *chip, unsigned gpio)
78{
79 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
80
81 if (bus->bustype == SSB_BUSTYPE_SSB)
82 return ssb_mips_irq(bus->chipco.dev) + 2;
83 else
84 return -EINVAL;
85}
86
77static int ssb_gpio_chipco_init(struct ssb_bus *bus) 87static int ssb_gpio_chipco_init(struct ssb_bus *bus)
78{ 88{
79 struct gpio_chip *chip = &bus->gpio; 89 struct gpio_chip *chip = &bus->gpio;
@@ -86,6 +96,7 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus)
86 chip->set = ssb_gpio_chipco_set_value; 96 chip->set = ssb_gpio_chipco_set_value;
87 chip->direction_input = ssb_gpio_chipco_direction_input; 97 chip->direction_input = ssb_gpio_chipco_direction_input;
88 chip->direction_output = ssb_gpio_chipco_direction_output; 98 chip->direction_output = ssb_gpio_chipco_direction_output;
99 chip->to_irq = ssb_gpio_chipco_to_irq;
89 chip->ngpio = 16; 100 chip->ngpio = 16;
90 /* There is just one SoC in one device and its GPIO addresses should be 101 /* There is just one SoC in one device and its GPIO addresses should be
91 * deterministic to address them more easily. The other buses could get 102 * deterministic to address them more easily. The other buses could get
@@ -134,6 +145,16 @@ static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,
134 return 0; 145 return 0;
135} 146}
136 147
148static int ssb_gpio_extif_to_irq(struct gpio_chip *chip, unsigned gpio)
149{
150 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
151
152 if (bus->bustype == SSB_BUSTYPE_SSB)
153 return ssb_mips_irq(bus->extif.dev) + 2;
154 else
155 return -EINVAL;
156}
157
137static int ssb_gpio_extif_init(struct ssb_bus *bus) 158static int ssb_gpio_extif_init(struct ssb_bus *bus)
138{ 159{
139 struct gpio_chip *chip = &bus->gpio; 160 struct gpio_chip *chip = &bus->gpio;
@@ -144,6 +165,7 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus)
144 chip->set = ssb_gpio_extif_set_value; 165 chip->set = ssb_gpio_extif_set_value;
145 chip->direction_input = ssb_gpio_extif_direction_input; 166 chip->direction_input = ssb_gpio_extif_direction_input;
146 chip->direction_output = ssb_gpio_extif_direction_output; 167 chip->direction_output = ssb_gpio_extif_direction_output;
168 chip->to_irq = ssb_gpio_extif_to_irq;
147 chip->ngpio = 5; 169 chip->ngpio = 5;
148 /* There is just one SoC in one device and its GPIO addresses should be 170 /* There is just one SoC in one device and its GPIO addresses should be
149 * deterministic to address them more easily. The other buses could get 171 * deterministic to address them more easily. The other buses could get
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index 2a7684c90243..33b37dac40bd 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/ssb/ssb.h> 11#include <linux/ssb/ssb.h>
12 12
13#include <linux/mtd/physmap.h>
13#include <linux/serial.h> 14#include <linux/serial.h>
14#include <linux/serial_core.h> 15#include <linux/serial_core.h>
15#include <linux/serial_reg.h> 16#include <linux/serial_reg.h>
@@ -17,6 +18,25 @@
17 18
18#include "ssb_private.h" 19#include "ssb_private.h"
19 20
21static const char *part_probes[] = { "bcm47xxpart", NULL };
22
23static struct physmap_flash_data ssb_pflash_data = {
24 .part_probe_types = part_probes,
25};
26
27static struct resource ssb_pflash_resource = {
28 .name = "ssb_pflash",
29 .flags = IORESOURCE_MEM,
30};
31
32struct platform_device ssb_pflash_dev = {
33 .name = "physmap-flash",
34 .dev = {
35 .platform_data = &ssb_pflash_data,
36 },
37 .resource = &ssb_pflash_resource,
38 .num_resources = 1,
39};
20 40
21static inline u32 mips_read32(struct ssb_mipscore *mcore, 41static inline u32 mips_read32(struct ssb_mipscore *mcore,
22 u16 offset) 42 u16 offset)
@@ -189,14 +209,15 @@ static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
189static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) 209static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
190{ 210{
191 struct ssb_bus *bus = mcore->dev->bus; 211 struct ssb_bus *bus = mcore->dev->bus;
212 struct ssb_pflash *pflash = &mcore->pflash;
192 213
193 /* When there is no chipcommon on the bus there is 4MB flash */ 214 /* When there is no chipcommon on the bus there is 4MB flash */
194 if (!ssb_chipco_available(&bus->chipco)) { 215 if (!ssb_chipco_available(&bus->chipco)) {
195 mcore->pflash.present = true; 216 pflash->present = true;
196 mcore->pflash.buswidth = 2; 217 pflash->buswidth = 2;
197 mcore->pflash.window = SSB_FLASH1; 218 pflash->window = SSB_FLASH1;
198 mcore->pflash.window_size = SSB_FLASH1_SZ; 219 pflash->window_size = SSB_FLASH1_SZ;
199 return; 220 goto ssb_pflash;
200 } 221 }
201 222
202 /* There is ChipCommon, so use it to read info about flash */ 223 /* There is ChipCommon, so use it to read info about flash */
@@ -208,16 +229,23 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
208 break; 229 break;
209 case SSB_CHIPCO_FLASHT_PARA: 230 case SSB_CHIPCO_FLASHT_PARA:
210 pr_debug("Found parallel flash\n"); 231 pr_debug("Found parallel flash\n");
211 mcore->pflash.present = true; 232 pflash->present = true;
212 mcore->pflash.window = SSB_FLASH2; 233 pflash->window = SSB_FLASH2;
213 mcore->pflash.window_size = SSB_FLASH2_SZ; 234 pflash->window_size = SSB_FLASH2_SZ;
214 if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG) 235 if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG)
215 & SSB_CHIPCO_CFG_DS16) == 0) 236 & SSB_CHIPCO_CFG_DS16) == 0)
216 mcore->pflash.buswidth = 1; 237 pflash->buswidth = 1;
217 else 238 else
218 mcore->pflash.buswidth = 2; 239 pflash->buswidth = 2;
219 break; 240 break;
220 } 241 }
242
243ssb_pflash:
244 if (pflash->present) {
245 ssb_pflash_data.width = pflash->buswidth;
246 ssb_pflash_resource.start = pflash->window;
247 ssb_pflash_resource.end = pflash->window + pflash->window_size;
248 }
221} 249}
222 250
223u32 ssb_cpu_clock(struct ssb_mipscore *mcore) 251u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 772ad9b5c304..9987d9f366f4 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -540,6 +540,14 @@ static int ssb_devices_register(struct ssb_bus *bus)
540 dev_idx++; 540 dev_idx++;
541 } 541 }
542 542
543#ifdef CONFIG_SSB_DRIVER_MIPS
544 if (bus->mipscore.pflash.present) {
545 err = platform_device_register(&ssb_pflash_dev);
546 if (err)
547 pr_err("Error registering parallel flash\n");
548 }
549#endif
550
543 return 0; 551 return 0;
544error: 552error:
545 /* Unwind the already registered devices. */ 553 /* Unwind the already registered devices. */
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index 77d942630750..53198dcec90e 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -228,6 +228,10 @@ static inline int ssb_sflash_init(struct ssb_chipcommon *cc)
228} 228}
229#endif /* CONFIG_SSB_SFLASH */ 229#endif /* CONFIG_SSB_SFLASH */
230 230
231#ifdef CONFIG_SSB_DRIVER_MIPS
232extern struct platform_device ssb_pflash_dev;
233#endif
234
231#ifdef CONFIG_SSB_DRIVER_EXTIF 235#ifdef CONFIG_SSB_DRIVER_EXTIF
232extern u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks); 236extern u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks);
233extern u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms); 237extern u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);