aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-02-11 12:44:25 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-11 12:44:25 -0500
commit78f42aee884dedfd157f79d01f069550edbc95cf (patch)
tree1f0b6a91c06cae83a647a076377d3279f7a9fb78
parentaa5a1b8e68c95151fd249a3b5ec444c6b0aa2f1c (diff)
parent8708aac79e4572ba673d7a21e94ddca9f3abb7fc (diff)
Merge remote-tracking branch 'wireless-next/master' into HEAD
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c10
-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/ath5k/phy.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c2
-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/brcmfmac/Makefile3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h57
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h19
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c311
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c25
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c11
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h66
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c2277
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.h183
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c11
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c1365
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h113
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c13
-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.c8
-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.c171
-rw-r--r--drivers/net/wireless/p54/p54usb.c2
-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.c25
-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/rtl8192ce/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/mac.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c11
-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.c9
-rw-r--r--drivers/net/wireless/rtlwifi/usb.h3
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h2
-rw-r--r--drivers/net/wireless/ti/Kconfig9
-rw-r--r--drivers/net/wireless/ti/Makefile4
-rw-r--r--drivers/net/wireless/ti/wilink_platform_data.c (renamed from drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c)0
-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.c195
-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.h22
-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.c272
-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/Kconfig5
-rw-r--r--drivers/net/wireless/ti/wlcore/Makefile3
-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.c423
-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.c1586
-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.c36
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c33
-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.h119
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h54
-rw-r--r--drivers/nfc/Kconfig1
-rw-r--r--drivers/nfc/Makefile1
-rw-r--r--drivers/nfc/microread/Kconfig35
-rw-r--r--drivers/nfc/microread/Makefile10
-rw-r--r--drivers/nfc/microread/i2c.c340
-rw-r--r--drivers/nfc/microread/mei.c241
-rw-r--r--drivers/nfc/microread/microread.c728
-rw-r--r--drivers/nfc/microread/microread.h33
-rw-r--r--drivers/nfc/pn533.c8
-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
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h2
-rw-r--r--include/linux/bcma/bcma_driver_mips.h9
-rw-r--r--include/linux/platform_data/microread.h35
-rw-r--r--include/linux/ssb/ssb_driver_mips.h5
-rw-r--r--include/linux/wl12xx.h16
-rw-r--r--include/net/bluetooth/a2mp.h4
-rw-r--r--include/net/bluetooth/bluetooth.h23
-rw-r--r--include/net/bluetooth/hci.h18
-rw-r--r--include/net/bluetooth/hci_core.h5
-rw-r--r--include/net/bluetooth/l2cap.h1
-rw-r--r--net/bluetooth/a2mp.c42
-rw-r--r--net/bluetooth/amp.c25
-rw-r--r--net/bluetooth/bnep/core.c1
-rw-r--r--net/bluetooth/hci_core.c30
-rw-r--r--net/bluetooth/hci_event.c64
-rw-r--r--net/bluetooth/hci_sysfs.c22
-rw-r--r--net/bluetooth/l2cap_core.c5
-rw-r--r--net/bluetooth/mgmt.c489
-rw-r--r--net/bluetooth/sco.c18
-rw-r--r--net/nfc/llcp/llcp.c5
267 files changed, 31181 insertions, 3632 deletions
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 3985f35aee06..a4ca63ba7faa 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -309,7 +309,7 @@ static struct omap2_hsmmc_info mmc[] = {
309 .gpio_wp = 63, 309 .gpio_wp = 63,
310 .deferred = true, 310 .deferred = true,
311 }, 311 },
312#ifdef CONFIG_WL12XX_PLATFORM_DATA 312#ifdef CONFIG_WILINK_PLATFORM_DATA
313 { 313 {
314 .name = "wl1271", 314 .name = "wl1271",
315 .mmc = 2, 315 .mmc = 2,
@@ -450,7 +450,7 @@ static struct regulator_init_data omap3evm_vio = {
450 .consumer_supplies = omap3evm_vio_supply, 450 .consumer_supplies = omap3evm_vio_supply,
451}; 451};
452 452
453#ifdef CONFIG_WL12XX_PLATFORM_DATA 453#ifdef CONFIG_WILINK_PLATFORM_DATA
454 454
455#define OMAP3EVM_WLAN_PMENA_GPIO (150) 455#define OMAP3EVM_WLAN_PMENA_GPIO (150)
456#define OMAP3EVM_WLAN_IRQ_GPIO (149) 456#define OMAP3EVM_WLAN_IRQ_GPIO (149)
@@ -563,7 +563,7 @@ static struct omap_board_mux omap35x_board_mux[] __initdata = {
563 OMAP_PIN_OFF_NONE), 563 OMAP_PIN_OFF_NONE),
564 OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | 564 OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
565 OMAP_PIN_OFF_NONE), 565 OMAP_PIN_OFF_NONE),
566#ifdef CONFIG_WL12XX_PLATFORM_DATA 566#ifdef CONFIG_WILINK_PLATFORM_DATA
567 /* WLAN IRQ - GPIO 149 */ 567 /* WLAN IRQ - GPIO 149 */
568 OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), 568 OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
569 569
@@ -601,7 +601,7 @@ static struct omap_board_mux omap36x_board_mux[] __initdata = {
601 OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), 601 OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
602 OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), 602 OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
603 OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), 603 OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
604#ifdef CONFIG_WL12XX_PLATFORM_DATA 604#ifdef CONFIG_WILINK_PLATFORM_DATA
605 /* WLAN IRQ - GPIO 149 */ 605 /* WLAN IRQ - GPIO 149 */
606 OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), 606 OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
607 607
@@ -637,7 +637,7 @@ static struct gpio omap3_evm_ehci_gpios[] __initdata = {
637 637
638static void __init omap3_evm_wl12xx_init(void) 638static void __init omap3_evm_wl12xx_init(void)
639{ 639{
640#ifdef CONFIG_WL12XX_PLATFORM_DATA 640#ifdef CONFIG_WILINK_PLATFORM_DATA
641 int ret; 641 int ret;
642 642
643 /* WL12xx WLAN Init */ 643 /* WL12xx WLAN Init */
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index d35294e81d15..16c1dddfda00 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 dbda91e4dff5..19fafcf78840 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 d12b7da556e1..95ba5756c67e 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/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index ab363f34b4df..a78afa98c650 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1613,6 +1613,10 @@ ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1613 ah->ah_cal_mask |= AR5K_CALIBRATION_NF; 1613 ah->ah_cal_mask |= AR5K_CALIBRATION_NF;
1614 1614
1615 ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel); 1615 ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel);
1616 if (WARN_ON(ee_mode < 0)) {
1617 ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF;
1618 return;
1619 }
1616 1620
1617 /* completed NF calibration, test threshold */ 1621 /* completed NF calibration, test threshold */
1618 nf = ath5k_hw_read_measured_noise_floor(ah); 1622 nf = ath5k_hw_read_measured_noise_floor(ah);
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 4084b1076286..e2d8b2cf19eb 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -985,6 +985,8 @@ ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
985 return; 985 return;
986 986
987 ee_mode = ath5k_eeprom_mode_from_channel(channel); 987 ee_mode = ath5k_eeprom_mode_from_channel(channel);
988 if (WARN_ON(ee_mode < 0))
989 return;
988 990
989 /* Adjust power delta for channel 14 */ 991 /* Adjust power delta for channel 14 */
990 if (channel->center_freq == 2484) 992 if (channel->center_freq == 2484)
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/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 1a6661a9f008..756e19fc2795 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -26,6 +26,7 @@ brcmfmac-objs += \
26 wl_cfg80211.o \ 26 wl_cfg80211.o \
27 fwil.o \ 27 fwil.o \
28 fweh.o \ 28 fweh.o \
29 p2p.o \
29 dhd_cdc.o \ 30 dhd_cdc.o \
30 dhd_common.o \ 31 dhd_common.o \
31 dhd_linux.o 32 dhd_linux.o
@@ -37,4 +38,4 @@ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
37brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ 38brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
38 usb.o 39 usb.o
39brcmfmac-$(CONFIG_BRCMDBG) += \ 40brcmfmac-$(CONFIG_BRCMDBG) += \
40 dhd_dbg.o \ No newline at end of file 41 dhd_dbg.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index a2f32fb990fa..ef6f23be6d32 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -72,6 +72,7 @@
72#define BRCMF_C_SET_WSEC 134 72#define BRCMF_C_SET_WSEC 134
73#define BRCMF_C_GET_PHY_NOISE 135 73#define BRCMF_C_GET_PHY_NOISE 135
74#define BRCMF_C_GET_BSS_INFO 136 74#define BRCMF_C_GET_BSS_INFO 136
75#define BRCMF_C_SET_SCB_TIMEOUT 158
75#define BRCMF_C_GET_PHYLIST 180 76#define BRCMF_C_GET_PHYLIST 180
76#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 77#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
77#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 78#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
@@ -149,6 +150,7 @@
149#define BRCMF_E_REASON_MINTXRATE 9 150#define BRCMF_E_REASON_MINTXRATE 9
150#define BRCMF_E_REASON_TXFAIL 10 151#define BRCMF_E_REASON_TXFAIL 10
151 152
153#define BRCMF_E_REASON_LINK_BSSCFG_DIS 4
152#define BRCMF_E_REASON_FAST_ROAM_FAILED 5 154#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
153#define BRCMF_E_REASON_DIRECTED_ROAM 6 155#define BRCMF_E_REASON_DIRECTED_ROAM 6
154#define BRCMF_E_REASON_TSPEC_REJECTED 7 156#define BRCMF_E_REASON_TSPEC_REJECTED 7
@@ -375,6 +377,28 @@ struct brcmf_join_params {
375 struct brcmf_assoc_params_le params_le; 377 struct brcmf_assoc_params_le params_le;
376}; 378};
377 379
380/* scan params for extended join */
381struct brcmf_join_scan_params_le {
382 u8 scan_type; /* 0 use default, active or passive scan */
383 __le32 nprobes; /* -1 use default, nr of probes per channel */
384 __le32 active_time; /* -1 use default, dwell time per channel for
385 * active scanning
386 */
387 __le32 passive_time; /* -1 use default, dwell time per channel
388 * for passive scanning
389 */
390 __le32 home_time; /* -1 use default, dwell time for the home
391 * channel between channel scans
392 */
393};
394
395/* extended join params */
396struct brcmf_ext_join_params_le {
397 struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */
398 struct brcmf_join_scan_params_le scan_le;
399 struct brcmf_assoc_params_le assoc_le;
400};
401
378struct brcmf_wsec_key { 402struct brcmf_wsec_key {
379 u32 index; /* key index */ 403 u32 index; /* key index */
380 u32 len; /* key length */ 404 u32 len; /* key length */
@@ -451,6 +475,19 @@ struct brcmf_sta_info_le {
451 __le32 rx_decrypt_failures; /* # of packet decrypted failed */ 475 __le32 rx_decrypt_failures; /* # of packet decrypted failed */
452}; 476};
453 477
478/*
479 * WLC_E_PROBRESP_MSG
480 * WLC_E_P2P_PROBREQ_MSG
481 * WLC_E_ACTION_FRAME_RX
482 */
483struct brcmf_rx_mgmt_data {
484 __be16 version;
485 __be16 chanspec;
486 __be32 rssi;
487 __be32 mactime;
488 __be32 rate;
489};
490
454/* Bus independent dongle command */ 491/* Bus independent dongle command */
455struct brcmf_dcmd { 492struct brcmf_dcmd {
456 uint cmd; /* common dongle cmd definition */ 493 uint cmd; /* common dongle cmd definition */
@@ -489,9 +526,6 @@ struct brcmf_pub {
489 struct mutex proto_block; 526 struct mutex proto_block;
490 unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; 527 unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
491 528
492 atomic_t pend_8021x_cnt;
493 wait_queue_head_t pend_8021x_wait;
494
495 struct brcmf_fweh_info fweh; 529 struct brcmf_fweh_info fweh;
496#ifdef DEBUG 530#ifdef DEBUG
497 struct dentry *dbgfs_dir; 531 struct dentry *dbgfs_dir;
@@ -515,9 +549,11 @@ struct brcmf_cfg80211_vif;
515 * @vif: points to cfg80211 specific interface information. 549 * @vif: points to cfg80211 specific interface information.
516 * @ndev: associated network device. 550 * @ndev: associated network device.
517 * @stats: interface specific network statistics. 551 * @stats: interface specific network statistics.
518 * @idx: interface index in device firmware. 552 * @ifidx: interface index in device firmware.
519 * @bssidx: index of bss associated with this interface. 553 * @bssidx: index of bss associated with this interface.
520 * @mac_addr: assigned mac address. 554 * @mac_addr: assigned mac address.
555 * @pend_8021x_cnt: tracks outstanding number of 802.1x frames.
556 * @pend_8021x_wait: used for signalling change in count.
521 */ 557 */
522struct brcmf_if { 558struct brcmf_if {
523 struct brcmf_pub *drvr; 559 struct brcmf_pub *drvr;
@@ -526,9 +562,11 @@ struct brcmf_if {
526 struct net_device_stats stats; 562 struct net_device_stats stats;
527 struct work_struct setmacaddr_work; 563 struct work_struct setmacaddr_work;
528 struct work_struct multicast_work; 564 struct work_struct multicast_work;
529 int idx; 565 int ifidx;
530 s32 bssidx; 566 s32 bssidx;
531 u8 mac_addr[ETH_ALEN]; 567 u8 mac_addr[ETH_ALEN];
568 atomic_t pend_8021x_cnt;
569 wait_queue_head_t pend_8021x_wait;
532}; 570};
533 571
534 572
@@ -547,9 +585,10 @@ extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
547extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, 585extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
548 struct sk_buff *rxp); 586 struct sk_buff *rxp);
549 587
550extern int brcmf_net_attach(struct brcmf_if *ifp); 588extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
551extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, 589extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx,
552 s32 bssidx, char *name, u8 *mac_addr); 590 s32 ifidx, char *name, u8 *mac_addr);
553extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); 591extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx);
592extern u32 brcmf_get_chip_info(struct brcmf_if *ifp);
554 593
555#endif /* _BRCMF_H_ */ 594#endif /* _BRCMF_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 64c38f4226a3..ad25c3408b59 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -24,18 +24,6 @@ enum brcmf_bus_state {
24 BRCMF_BUS_DATA /* Ready for frame transfers */ 24 BRCMF_BUS_DATA /* Ready for frame transfers */
25}; 25};
26 26
27struct dngl_stats {
28 unsigned long rx_packets; /* total packets received */
29 unsigned long tx_packets; /* total packets transmitted */
30 unsigned long rx_bytes; /* total bytes received */
31 unsigned long tx_bytes; /* total bytes transmitted */
32 unsigned long rx_errors; /* bad packets received */
33 unsigned long tx_errors; /* packet transmit problems */
34 unsigned long rx_dropped; /* packets dropped by dongle */
35 unsigned long tx_dropped; /* packets dropped by dongle */
36 unsigned long multicast; /* multicast packets received */
37};
38
39struct brcmf_bus_dcmd { 27struct brcmf_bus_dcmd {
40 char *name; 28 char *name;
41 char *param; 29 char *param;
@@ -72,11 +60,12 @@ struct brcmf_bus_ops {
72 * @drvr: public driver information. 60 * @drvr: public driver information.
73 * @state: operational state of the bus interface. 61 * @state: operational state of the bus interface.
74 * @maxctl: maximum size for rxctl request message. 62 * @maxctl: maximum size for rxctl request message.
75 * @drvr_up: indicates driver up/down status.
76 * @tx_realloc: number of tx packets realloced for headroom. 63 * @tx_realloc: number of tx packets realloced for headroom.
77 * @dstats: dongle-based statistical data. 64 * @dstats: dongle-based statistical data.
78 * @align: alignment requirement for the bus. 65 * @align: alignment requirement for the bus.
79 * @dcmd_list: bus/device specific dongle initialization commands. 66 * @dcmd_list: bus/device specific dongle initialization commands.
67 * @chip: device identifier of the dongle chip.
68 * @chiprev: revision of the dongle chip.
80 */ 69 */
81struct brcmf_bus { 70struct brcmf_bus {
82 union { 71 union {
@@ -87,10 +76,10 @@ struct brcmf_bus {
87 struct brcmf_pub *drvr; 76 struct brcmf_pub *drvr;
88 enum brcmf_bus_state state; 77 enum brcmf_bus_state state;
89 uint maxctl; 78 uint maxctl;
90 bool drvr_up;
91 unsigned long tx_realloc; 79 unsigned long tx_realloc;
92 struct dngl_stats dstats;
93 u8 align; 80 u8 align;
81 u32 chip;
82 u32 chiprev;
94 struct list_head dcmd_list; 83 struct list_head dcmd_list;
95 84
96 struct brcmf_bus_ops *ops; 85 struct brcmf_bus_ops *ops;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
index bb454cdab29d..a2354d951dd7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -303,6 +303,14 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
303 brcmf_err("rx data ifnum out of range (%d)\n", *ifidx); 303 brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
304 return -EBADE; 304 return -EBADE;
305 } 305 }
306 /* The ifidx is the idx to map to matching netdev/ifp. When receiving
307 * events this is easy because it contains the bssidx which maps
308 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
309 * bssidx 1 is used for p2p0 and no data can be received or
310 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
311 */
312 if (*ifidx)
313 (*ifidx)++;
306 314
307 if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != 315 if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
308 BDC_PROTO_VER) { 316 BDC_PROTO_VER) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index e3326a58bdb1..6e3846ca88be 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -26,6 +26,8 @@
26#include "dhd_bus.h" 26#include "dhd_bus.h"
27#include "dhd_proto.h" 27#include "dhd_proto.h"
28#include "dhd_dbg.h" 28#include "dhd_dbg.h"
29#include "fwil_types.h"
30#include "p2p.h"
29#include "wl_cfg80211.h" 31#include "wl_cfg80211.h"
30#include "fwil.h" 32#include "fwil.h"
31 33
@@ -40,6 +42,12 @@ MODULE_LICENSE("Dual BSD/GPL");
40int brcmf_msg_level; 42int brcmf_msg_level;
41module_param(brcmf_msg_level, int, 0); 43module_param(brcmf_msg_level, int, 0);
42 44
45/* P2P0 enable */
46static int brcmf_p2p_enable;
47#ifdef CONFIG_BRCMDBG
48module_param_named(p2pon, brcmf_p2p_enable, int, 0);
49MODULE_PARM_DESC(p2pon, "enable p2p management functionality");
50#endif
43 51
44char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) 52char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
45{ 53{
@@ -70,9 +78,10 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
70 u32 buflen; 78 u32 buflen;
71 s32 err; 79 s32 err;
72 80
73 brcmf_dbg(TRACE, "enter\n");
74
75 ifp = container_of(work, struct brcmf_if, multicast_work); 81 ifp = container_of(work, struct brcmf_if, multicast_work);
82
83 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
84
76 ndev = ifp->ndev; 85 ndev = ifp->ndev;
77 86
78 /* Determine initial value of allmulti flag */ 87 /* Determine initial value of allmulti flag */
@@ -129,9 +138,10 @@ _brcmf_set_mac_address(struct work_struct *work)
129 struct brcmf_if *ifp; 138 struct brcmf_if *ifp;
130 s32 err; 139 s32 err;
131 140
132 brcmf_dbg(TRACE, "enter\n");
133
134 ifp = container_of(work, struct brcmf_if, setmacaddr_work); 141 ifp = container_of(work, struct brcmf_if, setmacaddr_work);
142
143 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
144
135 err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr, 145 err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr,
136 ETH_ALEN); 146 ETH_ALEN);
137 if (err < 0) { 147 if (err < 0) {
@@ -168,7 +178,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
168 struct brcmf_pub *drvr = ifp->drvr; 178 struct brcmf_pub *drvr = ifp->drvr;
169 struct ethhdr *eh; 179 struct ethhdr *eh;
170 180
171 brcmf_dbg(TRACE, "Enter\n"); 181 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
172 182
173 /* Can the device send data? */ 183 /* Can the device send data? */
174 if (drvr->bus_if->state != BRCMF_BUS_DATA) { 184 if (drvr->bus_if->state != BRCMF_BUS_DATA) {
@@ -179,8 +189,8 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
179 goto done; 189 goto done;
180 } 190 }
181 191
182 if (!drvr->iflist[ifp->idx]) { 192 if (!drvr->iflist[ifp->bssidx]) {
183 brcmf_err("bad ifidx %d\n", ifp->idx); 193 brcmf_err("bad ifidx %d\n", ifp->bssidx);
184 netif_stop_queue(ndev); 194 netif_stop_queue(ndev);
185 dev_kfree_skb(skb); 195 dev_kfree_skb(skb);
186 ret = -ENODEV; 196 ret = -ENODEV;
@@ -192,14 +202,14 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
192 struct sk_buff *skb2; 202 struct sk_buff *skb2;
193 203
194 brcmf_dbg(INFO, "%s: insufficient headroom\n", 204 brcmf_dbg(INFO, "%s: insufficient headroom\n",
195 brcmf_ifname(drvr, ifp->idx)); 205 brcmf_ifname(drvr, ifp->bssidx));
196 drvr->bus_if->tx_realloc++; 206 drvr->bus_if->tx_realloc++;
197 skb2 = skb_realloc_headroom(skb, drvr->hdrlen); 207 skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
198 dev_kfree_skb(skb); 208 dev_kfree_skb(skb);
199 skb = skb2; 209 skb = skb2;
200 if (skb == NULL) { 210 if (skb == NULL) {
201 brcmf_err("%s: skb_realloc_headroom failed\n", 211 brcmf_err("%s: skb_realloc_headroom failed\n",
202 brcmf_ifname(drvr, ifp->idx)); 212 brcmf_ifname(drvr, ifp->bssidx));
203 ret = -ENOMEM; 213 ret = -ENOMEM;
204 goto done; 214 goto done;
205 } 215 }
@@ -217,19 +227,21 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
217 if (is_multicast_ether_addr(eh->h_dest)) 227 if (is_multicast_ether_addr(eh->h_dest))
218 drvr->tx_multicast++; 228 drvr->tx_multicast++;
219 if (ntohs(eh->h_proto) == ETH_P_PAE) 229 if (ntohs(eh->h_proto) == ETH_P_PAE)
220 atomic_inc(&drvr->pend_8021x_cnt); 230 atomic_inc(&ifp->pend_8021x_cnt);
221 231
222 /* If the protocol uses a data header, apply it */ 232 /* If the protocol uses a data header, apply it */
223 brcmf_proto_hdrpush(drvr, ifp->idx, skb); 233 brcmf_proto_hdrpush(drvr, ifp->ifidx, skb);
224 234
225 /* Use bus module to send data frame */ 235 /* Use bus module to send data frame */
226 ret = brcmf_bus_txdata(drvr->bus_if, skb); 236 ret = brcmf_bus_txdata(drvr->bus_if, skb);
227 237
228done: 238done:
229 if (ret) 239 if (ret) {
230 drvr->bus_if->dstats.tx_dropped++; 240 ifp->stats.tx_dropped++;
231 else 241 } else {
232 drvr->bus_if->dstats.tx_packets++; 242 ifp->stats.tx_packets++;
243 ifp->stats.tx_bytes += skb->len;
244 }
233 245
234 /* Return ok: we always eat the packet */ 246 /* Return ok: we always eat the packet */
235 return NETDEV_TX_OK; 247 return NETDEV_TX_OK;
@@ -270,12 +282,13 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
270 skb_queue_walk_safe(skb_list, skb, pnext) { 282 skb_queue_walk_safe(skb_list, skb, pnext) {
271 skb_unlink(skb, skb_list); 283 skb_unlink(skb, skb_list);
272 284
273 /* process and remove protocol-specific header 285 /* process and remove protocol-specific header */
274 */
275 ret = brcmf_proto_hdrpull(drvr, &ifidx, skb); 286 ret = brcmf_proto_hdrpull(drvr, &ifidx, skb);
276 if (ret < 0) { 287 ifp = drvr->iflist[ifidx];
277 if (ret != -ENODATA) 288
278 bus_if->dstats.rx_errors++; 289 if (ret || !ifp || !ifp->ndev) {
290 if ((ret != -ENODATA) && ifp)
291 ifp->stats.rx_errors++;
279 brcmu_pkt_buf_free_skb(skb); 292 brcmu_pkt_buf_free_skb(skb);
280 continue; 293 continue;
281 } 294 }
@@ -295,21 +308,11 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
295 eth = skb->data; 308 eth = skb->data;
296 len = skb->len; 309 len = skb->len;
297 310
298 ifp = drvr->iflist[ifidx];
299 if (ifp == NULL)
300 ifp = drvr->iflist[0];
301
302 if (!ifp || !ifp->ndev ||
303 ifp->ndev->reg_state != NETREG_REGISTERED) {
304 brcmu_pkt_buf_free_skb(skb);
305 continue;
306 }
307
308 skb->dev = ifp->ndev; 311 skb->dev = ifp->ndev;
309 skb->protocol = eth_type_trans(skb, skb->dev); 312 skb->protocol = eth_type_trans(skb, skb->dev);
310 313
311 if (skb->pkt_type == PACKET_MULTICAST) 314 if (skb->pkt_type == PACKET_MULTICAST)
312 bus_if->dstats.multicast++; 315 ifp->stats.multicast++;
313 316
314 skb->data = eth; 317 skb->data = eth;
315 skb->len = len; 318 skb->len = len;
@@ -325,8 +328,13 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
325 ifp->ndev->last_rx = jiffies; 328 ifp->ndev->last_rx = jiffies;
326 } 329 }
327 330
328 bus_if->dstats.rx_bytes += skb->len; 331 if (!(ifp->ndev->flags & IFF_UP)) {
329 bus_if->dstats.rx_packets++; /* Local count */ 332 brcmu_pkt_buf_free_skb(skb);
333 continue;
334 }
335
336 ifp->stats.rx_bytes += skb->len;
337 ifp->stats.rx_packets++;
330 338
331 if (in_interrupt()) 339 if (in_interrupt())
332 netif_rx(skb); 340 netif_rx(skb);
@@ -348,36 +356,31 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
348 u16 type; 356 u16 type;
349 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 357 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
350 struct brcmf_pub *drvr = bus_if->drvr; 358 struct brcmf_pub *drvr = bus_if->drvr;
359 struct brcmf_if *ifp;
351 360
352 brcmf_proto_hdrpull(drvr, &ifidx, txp); 361 brcmf_proto_hdrpull(drvr, &ifidx, txp);
353 362
363 ifp = drvr->iflist[ifidx];
364 if (!ifp)
365 return;
366
354 eh = (struct ethhdr *)(txp->data); 367 eh = (struct ethhdr *)(txp->data);
355 type = ntohs(eh->h_proto); 368 type = ntohs(eh->h_proto);
356 369
357 if (type == ETH_P_PAE) { 370 if (type == ETH_P_PAE) {
358 atomic_dec(&drvr->pend_8021x_cnt); 371 atomic_dec(&ifp->pend_8021x_cnt);
359 if (waitqueue_active(&drvr->pend_8021x_wait)) 372 if (waitqueue_active(&ifp->pend_8021x_wait))
360 wake_up(&drvr->pend_8021x_wait); 373 wake_up(&ifp->pend_8021x_wait);
361 } 374 }
375 if (!success)
376 ifp->stats.tx_errors++;
362} 377}
363 378
364static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) 379static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
365{ 380{
366 struct brcmf_if *ifp = netdev_priv(ndev); 381 struct brcmf_if *ifp = netdev_priv(ndev);
367 struct brcmf_bus *bus_if = ifp->drvr->bus_if;
368
369 brcmf_dbg(TRACE, "Enter\n");
370 382
371 /* Copy dongle stats to net device stats */ 383 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
372 ifp->stats.rx_packets = bus_if->dstats.rx_packets;
373 ifp->stats.tx_packets = bus_if->dstats.tx_packets;
374 ifp->stats.rx_bytes = bus_if->dstats.rx_bytes;
375 ifp->stats.tx_bytes = bus_if->dstats.tx_bytes;
376 ifp->stats.rx_errors = bus_if->dstats.rx_errors;
377 ifp->stats.tx_errors = bus_if->dstats.tx_errors;
378 ifp->stats.rx_dropped = bus_if->dstats.rx_dropped;
379 ifp->stats.tx_dropped = bus_if->dstats.tx_dropped;
380 ifp->stats.multicast = bus_if->dstats.multicast;
381 384
382 return &ifp->stats; 385 return &ifp->stats;
383} 386}
@@ -429,7 +432,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
429 u32 toe_cmpnt, csum_dir; 432 u32 toe_cmpnt, csum_dir;
430 int ret; 433 int ret;
431 434
432 brcmf_dbg(TRACE, "Enter\n"); 435 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
433 436
434 /* all ethtool calls start with a cmd word */ 437 /* all ethtool calls start with a cmd word */
435 if (copy_from_user(&cmd, uaddr, sizeof(u32))) 438 if (copy_from_user(&cmd, uaddr, sizeof(u32)))
@@ -452,13 +455,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
452 sprintf(info.driver, "dhd"); 455 sprintf(info.driver, "dhd");
453 strcpy(info.version, BRCMF_VERSION_STR); 456 strcpy(info.version, BRCMF_VERSION_STR);
454 } 457 }
455 458 /* report dongle driver type */
456 /* otherwise, require dongle to be up */
457 else if (!drvr->bus_if->drvr_up) {
458 brcmf_err("dongle is not up\n");
459 return -ENODEV;
460 }
461 /* finally, report dongle driver type */
462 else 459 else
463 sprintf(info.driver, "wl"); 460 sprintf(info.driver, "wl");
464 461
@@ -532,9 +529,9 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
532 struct brcmf_if *ifp = netdev_priv(ndev); 529 struct brcmf_if *ifp = netdev_priv(ndev);
533 struct brcmf_pub *drvr = ifp->drvr; 530 struct brcmf_pub *drvr = ifp->drvr;
534 531
535 brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd); 532 brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd);
536 533
537 if (!drvr->iflist[ifp->idx]) 534 if (!drvr->iflist[ifp->bssidx])
538 return -1; 535 return -1;
539 536
540 if (cmd == SIOCETHTOOL) 537 if (cmd == SIOCETHTOOL)
@@ -546,17 +543,12 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
546static int brcmf_netdev_stop(struct net_device *ndev) 543static int brcmf_netdev_stop(struct net_device *ndev)
547{ 544{
548 struct brcmf_if *ifp = netdev_priv(ndev); 545 struct brcmf_if *ifp = netdev_priv(ndev);
549 struct brcmf_pub *drvr = ifp->drvr;
550
551 brcmf_dbg(TRACE, "Enter\n");
552 546
553 if (drvr->bus_if->drvr_up == 0) 547 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
554 return 0;
555 548
556 brcmf_cfg80211_down(ndev); 549 brcmf_cfg80211_down(ndev);
557 550
558 /* Set state and stop OS transmissions */ 551 /* Set state and stop OS transmissions */
559 drvr->bus_if->drvr_up = false;
560 netif_stop_queue(ndev); 552 netif_stop_queue(ndev);
561 553
562 return 0; 554 return 0;
@@ -570,7 +562,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
570 u32 toe_ol; 562 u32 toe_ol;
571 s32 ret = 0; 563 s32 ret = 0;
572 564
573 brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); 565 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
574 566
575 /* If bus is not ready, can't continue */ 567 /* If bus is not ready, can't continue */
576 if (bus_if->state != BRCMF_BUS_DATA) { 568 if (bus_if->state != BRCMF_BUS_DATA) {
@@ -578,9 +570,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
578 return -EAGAIN; 570 return -EAGAIN;
579 } 571 }
580 572
581 atomic_set(&drvr->pend_8021x_cnt, 0); 573 atomic_set(&ifp->pend_8021x_cnt, 0);
582
583 memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
584 574
585 /* Get current TOE mode from dongle */ 575 /* Get current TOE mode from dongle */
586 if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0 576 if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
@@ -591,7 +581,6 @@ static int brcmf_netdev_open(struct net_device *ndev)
591 581
592 /* Allow transmit calls */ 582 /* Allow transmit calls */
593 netif_start_queue(ndev); 583 netif_start_queue(ndev);
594 drvr->bus_if->drvr_up = true;
595 if (brcmf_cfg80211_up(ndev)) { 584 if (brcmf_cfg80211_up(ndev)) {
596 brcmf_err("failed to bring up cfg80211\n"); 585 brcmf_err("failed to bring up cfg80211\n");
597 return -1; 586 return -1;
@@ -610,29 +599,18 @@ static const struct net_device_ops brcmf_netdev_ops_pri = {
610 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list 599 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
611}; 600};
612 601
613static const struct net_device_ops brcmf_netdev_ops_virt = { 602int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
614 .ndo_open = brcmf_cfg80211_up,
615 .ndo_stop = brcmf_cfg80211_down,
616 .ndo_get_stats = brcmf_netdev_get_stats,
617 .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
618 .ndo_start_xmit = brcmf_netdev_start_xmit,
619 .ndo_set_mac_address = brcmf_netdev_set_mac_address,
620 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
621};
622
623int brcmf_net_attach(struct brcmf_if *ifp)
624{ 603{
625 struct brcmf_pub *drvr = ifp->drvr; 604 struct brcmf_pub *drvr = ifp->drvr;
626 struct net_device *ndev; 605 struct net_device *ndev;
606 s32 err;
627 607
628 brcmf_dbg(TRACE, "ifidx %d mac %pM\n", ifp->idx, ifp->mac_addr); 608 brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
609 ifp->mac_addr);
629 ndev = ifp->ndev; 610 ndev = ifp->ndev;
630 611
631 /* set appropriate operations */ 612 /* set appropriate operations */
632 if (!ifp->idx) 613 ndev->netdev_ops = &brcmf_netdev_ops_pri;
633 ndev->netdev_ops = &brcmf_netdev_ops_pri;
634 else
635 ndev->netdev_ops = &brcmf_netdev_ops_virt;
636 614
637 ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; 615 ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
638 ndev->ethtool_ops = &brcmf_ethtool_ops; 616 ndev->ethtool_ops = &brcmf_ethtool_ops;
@@ -643,7 +621,14 @@ int brcmf_net_attach(struct brcmf_if *ifp)
643 /* set the mac address */ 621 /* set the mac address */
644 memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); 622 memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
645 623
646 if (register_netdev(ndev) != 0) { 624 INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
625 INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
626
627 if (rtnl_locked)
628 err = register_netdevice(ndev);
629 else
630 err = register_netdev(ndev);
631 if (err != 0) {
647 brcmf_err("couldn't register the net device\n"); 632 brcmf_err("couldn't register the net device\n");
648 goto fail; 633 goto fail;
649 } 634 }
@@ -657,16 +642,78 @@ fail:
657 return -EBADE; 642 return -EBADE;
658} 643}
659 644
660struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, 645static int brcmf_net_p2p_open(struct net_device *ndev)
661 char *name, u8 *addr_mask) 646{
647 brcmf_dbg(TRACE, "Enter\n");
648
649 return brcmf_cfg80211_up(ndev);
650}
651
652static int brcmf_net_p2p_stop(struct net_device *ndev)
653{
654 brcmf_dbg(TRACE, "Enter\n");
655
656 return brcmf_cfg80211_down(ndev);
657}
658
659static int brcmf_net_p2p_do_ioctl(struct net_device *ndev,
660 struct ifreq *ifr, int cmd)
661{
662 brcmf_dbg(TRACE, "Enter\n");
663 return 0;
664}
665
666static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
667 struct net_device *ndev)
668{
669 if (skb)
670 dev_kfree_skb_any(skb);
671
672 return NETDEV_TX_OK;
673}
674
675static const struct net_device_ops brcmf_netdev_ops_p2p = {
676 .ndo_open = brcmf_net_p2p_open,
677 .ndo_stop = brcmf_net_p2p_stop,
678 .ndo_do_ioctl = brcmf_net_p2p_do_ioctl,
679 .ndo_start_xmit = brcmf_net_p2p_start_xmit
680};
681
682static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
683{
684 struct net_device *ndev;
685
686 brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
687 ifp->mac_addr);
688 ndev = ifp->ndev;
689
690 ndev->netdev_ops = &brcmf_netdev_ops_p2p;
691
692 /* set the mac address */
693 memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
694
695 if (register_netdev(ndev) != 0) {
696 brcmf_err("couldn't register the p2p net device\n");
697 goto fail;
698 }
699
700 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
701
702 return 0;
703
704fail:
705 return -EBADE;
706}
707
708struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
709 char *name, u8 *mac_addr)
662{ 710{
663 struct brcmf_if *ifp; 711 struct brcmf_if *ifp;
664 struct net_device *ndev; 712 struct net_device *ndev;
665 int i;
666 713
667 brcmf_dbg(TRACE, "idx %d\n", ifidx); 714 brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifidx);
668 715
669 ifp = drvr->iflist[ifidx]; 716 ifp = drvr->iflist[bssidx];
670 /* 717 /*
671 * Delete the existing interface before overwriting it 718 * Delete the existing interface before overwriting it
672 * in case we missed the BRCMF_E_IF_DEL event. 719 * in case we missed the BRCMF_E_IF_DEL event.
@@ -678,7 +725,7 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx,
678 netif_stop_queue(ifp->ndev); 725 netif_stop_queue(ifp->ndev);
679 unregister_netdev(ifp->ndev); 726 unregister_netdev(ifp->ndev);
680 free_netdev(ifp->ndev); 727 free_netdev(ifp->ndev);
681 drvr->iflist[ifidx] = NULL; 728 drvr->iflist[bssidx] = NULL;
682 } else { 729 } else {
683 brcmf_err("ignore IF event\n"); 730 brcmf_err("ignore IF event\n");
684 return ERR_PTR(-EINVAL); 731 return ERR_PTR(-EINVAL);
@@ -695,16 +742,15 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx,
695 ifp = netdev_priv(ndev); 742 ifp = netdev_priv(ndev);
696 ifp->ndev = ndev; 743 ifp->ndev = ndev;
697 ifp->drvr = drvr; 744 ifp->drvr = drvr;
698 drvr->iflist[ifidx] = ifp; 745 drvr->iflist[bssidx] = ifp;
699 ifp->idx = ifidx; 746 ifp->ifidx = ifidx;
700 ifp->bssidx = bssidx; 747 ifp->bssidx = bssidx;
701 748
702 INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
703 INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
704 749
705 if (addr_mask != NULL) 750 init_waitqueue_head(&ifp->pend_8021x_wait);
706 for (i = 0; i < ETH_ALEN; i++) 751
707 ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i]; 752 if (mac_addr != NULL)
753 memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
708 754
709 brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n", 755 brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
710 current->pid, ifp->ndev->name, ifp->mac_addr); 756 current->pid, ifp->ndev->name, ifp->mac_addr);
@@ -712,19 +758,18 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx,
712 return ifp; 758 return ifp;
713} 759}
714 760
715void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) 761void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
716{ 762{
717 struct brcmf_if *ifp; 763 struct brcmf_if *ifp;
718 764
719 brcmf_dbg(TRACE, "idx %d\n", ifidx); 765 ifp = drvr->iflist[bssidx];
720
721 ifp = drvr->iflist[ifidx];
722 if (!ifp) { 766 if (!ifp) {
723 brcmf_err("Null interface\n"); 767 brcmf_err("Null interface, idx=%d\n", bssidx);
724 return; 768 return;
725 } 769 }
770 brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
726 if (ifp->ndev) { 771 if (ifp->ndev) {
727 if (ifidx == 0) { 772 if (bssidx == 0) {
728 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { 773 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
729 rtnl_lock(); 774 rtnl_lock();
730 brcmf_netdev_stop(ifp->ndev); 775 brcmf_netdev_stop(ifp->ndev);
@@ -734,12 +779,14 @@ void brcmf_del_if(struct brcmf_pub *drvr, int ifidx)
734 netif_stop_queue(ifp->ndev); 779 netif_stop_queue(ifp->ndev);
735 } 780 }
736 781
737 cancel_work_sync(&ifp->setmacaddr_work); 782 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
738 cancel_work_sync(&ifp->multicast_work); 783 cancel_work_sync(&ifp->setmacaddr_work);
784 cancel_work_sync(&ifp->multicast_work);
785 }
739 786
740 unregister_netdev(ifp->ndev); 787 unregister_netdev(ifp->ndev);
741 drvr->iflist[ifidx] = NULL; 788 drvr->iflist[bssidx] = NULL;
742 if (ifidx == 0) 789 if (bssidx == 0)
743 brcmf_cfg80211_detach(drvr->config); 790 brcmf_cfg80211_detach(drvr->config);
744 free_netdev(ifp->ndev); 791 free_netdev(ifp->ndev);
745 } 792 }
@@ -779,8 +826,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
779 826
780 INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); 827 INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
781 828
782 init_waitqueue_head(&drvr->pend_8021x_wait);
783
784 return ret; 829 return ret;
785 830
786fail: 831fail:
@@ -795,6 +840,7 @@ int brcmf_bus_start(struct device *dev)
795 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 840 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
796 struct brcmf_pub *drvr = bus_if->drvr; 841 struct brcmf_pub *drvr = bus_if->drvr;
797 struct brcmf_if *ifp; 842 struct brcmf_if *ifp;
843 struct brcmf_if *p2p_ifp;
798 844
799 brcmf_dbg(TRACE, "\n"); 845 brcmf_dbg(TRACE, "\n");
800 846
@@ -810,6 +856,13 @@ int brcmf_bus_start(struct device *dev)
810 if (IS_ERR(ifp)) 856 if (IS_ERR(ifp))
811 return PTR_ERR(ifp); 857 return PTR_ERR(ifp);
812 858
859 if (brcmf_p2p_enable)
860 p2p_ifp = brcmf_add_if(drvr, 1, 0, "p2p%d", NULL);
861 else
862 p2p_ifp = NULL;
863 if (IS_ERR(p2p_ifp))
864 p2p_ifp = NULL;
865
813 /* signal bus ready */ 866 /* signal bus ready */
814 bus_if->state = BRCMF_BUS_DATA; 867 bus_if->state = BRCMF_BUS_DATA;
815 868
@@ -828,16 +881,22 @@ int brcmf_bus_start(struct device *dev)
828 if (ret < 0) 881 if (ret < 0)
829 goto fail; 882 goto fail;
830 883
831 ret = brcmf_net_attach(ifp); 884 ret = brcmf_net_attach(ifp, false);
832fail: 885fail:
833 if (ret < 0) { 886 if (ret < 0) {
834 brcmf_err("failed: %d\n", ret); 887 brcmf_err("failed: %d\n", ret);
835 if (drvr->config) 888 if (drvr->config)
836 brcmf_cfg80211_detach(drvr->config); 889 brcmf_cfg80211_detach(drvr->config);
837 free_netdev(drvr->iflist[0]->ndev); 890 free_netdev(ifp->ndev);
838 drvr->iflist[0] = NULL; 891 drvr->iflist[0] = NULL;
892 if (p2p_ifp) {
893 free_netdev(p2p_ifp->ndev);
894 drvr->iflist[1] = NULL;
895 }
839 return ret; 896 return ret;
840 } 897 }
898 if ((brcmf_p2p_enable) && (p2p_ifp))
899 brcmf_net_p2p_attach(p2p_ifp);
841 900
842 return 0; 901 return 0;
843} 902}
@@ -863,12 +922,13 @@ void brcmf_dev_reset(struct device *dev)
863 if (drvr == NULL) 922 if (drvr == NULL)
864 return; 923 return;
865 924
866 brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1); 925 if (drvr->iflist[0])
926 brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
867} 927}
868 928
869void brcmf_detach(struct device *dev) 929void brcmf_detach(struct device *dev)
870{ 930{
871 int i; 931 s32 i;
872 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 932 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
873 struct brcmf_pub *drvr = bus_if->drvr; 933 struct brcmf_pub *drvr = bus_if->drvr;
874 934
@@ -895,19 +955,18 @@ void brcmf_detach(struct device *dev)
895 kfree(drvr); 955 kfree(drvr);
896} 956}
897 957
898static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) 958static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
899{ 959{
900 return atomic_read(&drvr->pend_8021x_cnt); 960 return atomic_read(&ifp->pend_8021x_cnt);
901} 961}
902 962
903int brcmf_netdev_wait_pend8021x(struct net_device *ndev) 963int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
904{ 964{
905 struct brcmf_if *ifp = netdev_priv(ndev); 965 struct brcmf_if *ifp = netdev_priv(ndev);
906 struct brcmf_pub *drvr = ifp->drvr;
907 int err; 966 int err;
908 967
909 err = wait_event_timeout(drvr->pend_8021x_wait, 968 err = wait_event_timeout(ifp->pend_8021x_wait,
910 !brcmf_get_pend_8021x_cnt(drvr), 969 !brcmf_get_pend_8021x_cnt(ifp),
911 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX)); 970 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));
912 971
913 WARN_ON(!err); 972 WARN_ON(!err);
@@ -915,6 +974,16 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
915 return !err; 974 return !err;
916} 975}
917 976
977/*
978 * return chip id and rev of the device encoded in u32.
979 */
980u32 brcmf_get_chip_info(struct brcmf_if *ifp)
981{
982 struct brcmf_bus *bus = ifp->drvr->bus_if;
983
984 return bus->chip << 4 | bus->chiprev;
985}
986
918static void brcmf_driver_init(struct work_struct *work) 987static void brcmf_driver_init(struct work_struct *work)
919{ 988{
920 brcmf_debugfs_init(); 989 brcmf_debugfs_init();
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 7fef9b5ba003..35817631ea06 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1096,7 +1096,6 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1096 if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL && 1096 if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL &&
1097 type != BRCMF_SDIO_FT_SUPER) { 1097 type != BRCMF_SDIO_FT_SUPER) {
1098 brcmf_err("HW header length too long\n"); 1098 brcmf_err("HW header length too long\n");
1099 bus->sdiodev->bus_if->dstats.rx_errors++;
1100 bus->sdcnt.rx_toolong++; 1099 bus->sdcnt.rx_toolong++;
1101 brcmf_sdbrcm_rxfail(bus, false, false); 1100 brcmf_sdbrcm_rxfail(bus, false, false);
1102 rd->len = 0; 1101 rd->len = 0;
@@ -1298,7 +1297,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1298 if (errcode < 0) { 1297 if (errcode < 0) {
1299 brcmf_err("glom read of %d bytes failed: %d\n", 1298 brcmf_err("glom read of %d bytes failed: %d\n",
1300 dlen, errcode); 1299 dlen, errcode);
1301 bus->sdiodev->bus_if->dstats.rx_errors++;
1302 1300
1303 sdio_claim_host(bus->sdiodev->func[1]); 1301 sdio_claim_host(bus->sdiodev->func[1]);
1304 if (bus->glomerr++ < 3) { 1302 if (bus->glomerr++ < 3) {
@@ -1478,7 +1476,6 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1478 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) { 1476 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
1479 brcmf_err("%d-byte control read exceeds %d-byte buffer\n", 1477 brcmf_err("%d-byte control read exceeds %d-byte buffer\n",
1480 rdlen, bus->sdiodev->bus_if->maxctl); 1478 rdlen, bus->sdiodev->bus_if->maxctl);
1481 bus->sdiodev->bus_if->dstats.rx_errors++;
1482 brcmf_sdbrcm_rxfail(bus, false, false); 1479 brcmf_sdbrcm_rxfail(bus, false, false);
1483 goto done; 1480 goto done;
1484 } 1481 }
@@ -1486,7 +1483,6 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1486 if ((len - doff) > bus->sdiodev->bus_if->maxctl) { 1483 if ((len - doff) > bus->sdiodev->bus_if->maxctl) {
1487 brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", 1484 brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
1488 len, len - doff, bus->sdiodev->bus_if->maxctl); 1485 len, len - doff, bus->sdiodev->bus_if->maxctl);
1489 bus->sdiodev->bus_if->dstats.rx_errors++;
1490 bus->sdcnt.rx_toolong++; 1486 bus->sdcnt.rx_toolong++;
1491 brcmf_sdbrcm_rxfail(bus, false, false); 1487 brcmf_sdbrcm_rxfail(bus, false, false);
1492 goto done; 1488 goto done;
@@ -1634,7 +1630,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1634 if (!pkt) { 1630 if (!pkt) {
1635 /* Give up on data, request rtx of events */ 1631 /* Give up on data, request rtx of events */
1636 brcmf_err("brcmu_pkt_buf_get_skb failed\n"); 1632 brcmf_err("brcmu_pkt_buf_get_skb failed\n");
1637 bus->sdiodev->bus_if->dstats.rx_dropped++;
1638 brcmf_sdbrcm_rxfail(bus, false, 1633 brcmf_sdbrcm_rxfail(bus, false,
1639 RETRYCHAN(rd->channel)); 1634 RETRYCHAN(rd->channel));
1640 sdio_release_host(bus->sdiodev->func[1]); 1635 sdio_release_host(bus->sdiodev->func[1]);
@@ -1652,7 +1647,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1652 brcmf_err("read %d bytes from channel %d failed: %d\n", 1647 brcmf_err("read %d bytes from channel %d failed: %d\n",
1653 rd->len, rd->channel, sdret); 1648 rd->len, rd->channel, sdret);
1654 brcmu_pkt_buf_free_skb(pkt); 1649 brcmu_pkt_buf_free_skb(pkt);
1655 bus->sdiodev->bus_if->dstats.rx_errors++;
1656 sdio_claim_host(bus->sdiodev->func[1]); 1650 sdio_claim_host(bus->sdiodev->func[1]);
1657 brcmf_sdbrcm_rxfail(bus, true, 1651 brcmf_sdbrcm_rxfail(bus, true,
1658 RETRYCHAN(rd->channel)); 1652 RETRYCHAN(rd->channel));
@@ -1940,10 +1934,6 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
1940 datalen = pkt->len - SDPCM_HDRLEN; 1934 datalen = pkt->len - SDPCM_HDRLEN;
1941 1935
1942 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); 1936 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
1943 if (ret)
1944 bus->sdiodev->bus_if->dstats.tx_errors++;
1945 else
1946 bus->sdiodev->bus_if->dstats.tx_bytes += datalen;
1947 1937
1948 /* In poll mode, need to check for other events */ 1938 /* In poll mode, need to check for other events */
1949 if (!bus->intr && cnt) { 1939 if (!bus->intr && cnt) {
@@ -1962,8 +1952,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
1962 } 1952 }
1963 1953
1964 /* Deflow-control stack if needed */ 1954 /* Deflow-control stack if needed */
1965 if (bus->sdiodev->bus_if->drvr_up && 1955 if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
1966 (bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
1967 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { 1956 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
1968 bus->txoff = false; 1957 bus->txoff = false;
1969 brcmf_txflowblock(bus->sdiodev->dev, false); 1958 brcmf_txflowblock(bus->sdiodev->dev, false);
@@ -2710,9 +2699,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2710 * address of sdpcm_shared structure 2699 * address of sdpcm_shared structure
2711 */ 2700 */
2712 sdio_claim_host(bus->sdiodev->func[1]); 2701 sdio_claim_host(bus->sdiodev->func[1]);
2702 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
2713 rv = brcmf_sdbrcm_membytes(bus, false, shaddr, 2703 rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
2714 (u8 *)&addr_le, 4); 2704 (u8 *)&addr_le, 4);
2715 sdio_claim_host(bus->sdiodev->func[1]); 2705 sdio_release_host(bus->sdiodev->func[1]);
2716 if (rv < 0) 2706 if (rv < 0)
2717 return rv; 2707 return rv;
2718 2708
@@ -2731,10 +2721,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2731 } 2721 }
2732 2722
2733 /* Read hndrte_shared structure */ 2723 /* Read hndrte_shared structure */
2734 sdio_claim_host(bus->sdiodev->func[1]);
2735 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, 2724 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le,
2736 sizeof(struct sdpcm_shared_le)); 2725 sizeof(struct sdpcm_shared_le));
2737 sdio_release_host(bus->sdiodev->func[1]);
2738 if (rv < 0) 2726 if (rv < 0)
2739 return rv; 2727 return rv;
2740 2728
@@ -2836,14 +2824,12 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
2836 if ((sh->flags & SDPCM_SHARED_TRAP) == 0) 2824 if ((sh->flags & SDPCM_SHARED_TRAP) == 0)
2837 return 0; 2825 return 0;
2838 2826
2839 sdio_claim_host(bus->sdiodev->func[1]);
2840 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, 2827 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
2841 sizeof(struct brcmf_trap_info)); 2828 sizeof(struct brcmf_trap_info));
2842 if (error < 0) 2829 if (error < 0)
2843 return error; 2830 return error;
2844 2831
2845 nbytes = brcmf_sdio_dump_console(bus, sh, data, count); 2832 nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
2846 sdio_release_host(bus->sdiodev->func[1]);
2847 if (nbytes < 0) 2833 if (nbytes < 0)
2848 return nbytes; 2834 return nbytes;
2849 2835
@@ -3308,9 +3294,6 @@ static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
3308{ 3294{
3309 int ret; 3295 int ret;
3310 3296
3311 if (bus->sdiodev->bus_if->drvr_up)
3312 return -EISCONN;
3313
3314 ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME, 3297 ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
3315 &bus->sdiodev->func[2]->dev); 3298 &bus->sdiodev->func[2]->dev);
3316 if (ret) { 3299 if (ret) {
@@ -3941,6 +3924,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3941 /* Assign bus interface call back */ 3924 /* Assign bus interface call back */
3942 bus->sdiodev->bus_if->dev = bus->sdiodev->dev; 3925 bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
3943 bus->sdiodev->bus_if->ops = &brcmf_sdio_bus_ops; 3926 bus->sdiodev->bus_if->ops = &brcmf_sdio_bus_ops;
3927 bus->sdiodev->bus_if->chip = bus->ci->chip;
3928 bus->sdiodev->bus_if->chiprev = bus->ci->chiprev;
3944 3929
3945 /* Attach to the brcmf/OS/network interface */ 3930 /* Attach to the brcmf/OS/network interface */
3946 ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev); 3931 ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index ba0b22512f12..e9d6f91a1f2b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -189,24 +189,24 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
189 return; 189 return;
190 } 190 }
191 191
192 ifp = drvr->iflist[ifevent->ifidx]; 192 ifp = drvr->iflist[ifevent->bssidx];
193 193
194 if (ifevent->action == BRCMF_E_IF_ADD) { 194 if (ifevent->action == BRCMF_E_IF_ADD) {
195 brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname, 195 brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname,
196 emsg->addr); 196 emsg->addr);
197 ifp = brcmf_add_if(drvr, ifevent->ifidx, ifevent->bssidx, 197 ifp = brcmf_add_if(drvr, ifevent->bssidx, ifevent->ifidx,
198 emsg->ifname, emsg->addr); 198 emsg->ifname, emsg->addr);
199 if (IS_ERR(ifp)) 199 if (IS_ERR(ifp))
200 return; 200 return;
201 201
202 if (!drvr->fweh.evt_handler[BRCMF_E_IF]) 202 if (!drvr->fweh.evt_handler[BRCMF_E_IF])
203 err = brcmf_net_attach(ifp); 203 err = brcmf_net_attach(ifp, false);
204 } 204 }
205 205
206 err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); 206 err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
207 207
208 if (ifevent->action == BRCMF_E_IF_DEL) 208 if (ifevent->action == BRCMF_E_IF_DEL)
209 brcmf_del_if(drvr, ifevent->ifidx); 209 brcmf_del_if(drvr, ifevent->bssidx);
210} 210}
211 211
212/** 212/**
@@ -250,8 +250,6 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
250 drvr = container_of(fweh, struct brcmf_pub, fweh); 250 drvr = container_of(fweh, struct brcmf_pub, fweh);
251 251
252 while ((event = brcmf_fweh_dequeue_event(fweh))) { 252 while ((event = brcmf_fweh_dequeue_event(fweh))) {
253 ifp = drvr->iflist[event->ifidx];
254
255 brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM\n", 253 brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM\n",
256 brcmf_fweh_event_name(event->code), event->code, 254 brcmf_fweh_event_name(event->code), event->code,
257 event->emsg.ifidx, event->emsg.bsscfgidx, 255 event->emsg.ifidx, event->emsg.bsscfgidx,
@@ -283,6 +281,7 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
283 goto event_free; 281 goto event_free;
284 } 282 }
285 283
284 ifp = drvr->iflist[emsg.bsscfgidx];
286 err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg, 285 err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg,
287 event->data); 286 event->data);
288 if (err) { 287 if (err) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index 36901f76a3b5..8c39b51dcccf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -83,6 +83,7 @@ struct brcmf_event;
83 BRCMF_ENUM_DEF(MULTICAST_DECODE_ERROR, 51) \ 83 BRCMF_ENUM_DEF(MULTICAST_DECODE_ERROR, 51) \
84 BRCMF_ENUM_DEF(TRACE, 52) \ 84 BRCMF_ENUM_DEF(TRACE, 52) \
85 BRCMF_ENUM_DEF(IF, 54) \ 85 BRCMF_ENUM_DEF(IF, 54) \
86 BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \
86 BRCMF_ENUM_DEF(RSSI, 56) \ 87 BRCMF_ENUM_DEF(RSSI, 56) \
87 BRCMF_ENUM_DEF(PFN_SCAN_COMPLETE, 57) \ 88 BRCMF_ENUM_DEF(PFN_SCAN_COMPLETE, 57) \
88 BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \ 89 BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \
@@ -96,8 +97,11 @@ struct brcmf_event;
96 BRCMF_ENUM_DEF(DFS_AP_RESUME, 66) \ 97 BRCMF_ENUM_DEF(DFS_AP_RESUME, 66) \
97 BRCMF_ENUM_DEF(ESCAN_RESULT, 69) \ 98 BRCMF_ENUM_DEF(ESCAN_RESULT, 69) \
98 BRCMF_ENUM_DEF(ACTION_FRAME_OFF_CHAN_COMPLETE, 70) \ 99 BRCMF_ENUM_DEF(ACTION_FRAME_OFF_CHAN_COMPLETE, 70) \
100 BRCMF_ENUM_DEF(PROBERESP_MSG, 71) \
101 BRCMF_ENUM_DEF(P2P_PROBEREQ_MSG, 72) \
99 BRCMF_ENUM_DEF(DCS_REQUEST, 73) \ 102 BRCMF_ENUM_DEF(DCS_REQUEST, 73) \
100 BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) 103 BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
104 BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75)
101 105
102#define BRCMF_ENUM_DEF(id, val) \ 106#define BRCMF_ENUM_DEF(id, val) \
103 BRCMF_E_##id = (val), 107 BRCMF_E_##id = (val),
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index d8d8b6549dc5..8d1def935b8d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -45,9 +45,10 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
45 if (data != NULL) 45 if (data != NULL)
46 len = min_t(uint, len, BRCMF_DCMD_MAXLEN); 46 len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
47 if (set) 47 if (set)
48 err = brcmf_proto_cdc_set_dcmd(drvr, ifp->idx, cmd, data, len); 48 err = brcmf_proto_cdc_set_dcmd(drvr, ifp->ifidx, cmd, data,
49 len);
49 else 50 else
50 err = brcmf_proto_cdc_query_dcmd(drvr, ifp->idx, cmd, data, 51 err = brcmf_proto_cdc_query_dcmd(drvr, ifp->ifidx, cmd, data,
51 len); 52 len);
52 53
53 if (err >= 0) 54 if (err >= 0)
@@ -100,6 +101,7 @@ brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data)
100 __le32 data_le = cpu_to_le32(data); 101 __le32 data_le = cpu_to_le32(data);
101 102
102 mutex_lock(&ifp->drvr->proto_block); 103 mutex_lock(&ifp->drvr->proto_block);
104 brcmf_dbg(FIL, "cmd=%d, value=%d\n", cmd, data);
103 err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), true); 105 err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), true);
104 mutex_unlock(&ifp->drvr->proto_block); 106 mutex_unlock(&ifp->drvr->proto_block);
105 107
@@ -116,6 +118,7 @@ brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data)
116 err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), false); 118 err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), false);
117 mutex_unlock(&ifp->drvr->proto_block); 119 mutex_unlock(&ifp->drvr->proto_block);
118 *data = le32_to_cpu(data_le); 120 *data = le32_to_cpu(data_le);
121 brcmf_dbg(FIL, "cmd=%d, value=%d\n", cmd, *data);
119 122
120 return err; 123 return err;
121} 124}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
new file mode 100644
index 000000000000..0f2c83bc95dc
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) 2012 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17
18#ifndef FWIL_TYPES_H_
19#define FWIL_TYPES_H_
20
21#include <linux/if_ether.h>
22
23
24#define BRCMF_FIL_ACTION_FRAME_SIZE 1800
25
26
27enum brcmf_fil_p2p_if_types {
28 BRCMF_FIL_P2P_IF_CLIENT,
29 BRCMF_FIL_P2P_IF_GO,
30 BRCMF_FIL_P2P_IF_DYNBCN_GO,
31 BRCMF_FIL_P2P_IF_DEV,
32};
33
34struct brcmf_fil_p2p_if_le {
35 u8 addr[ETH_ALEN];
36 __le16 type;
37 __le16 chspec;
38};
39
40struct brcmf_fil_chan_info_le {
41 __le32 hw_channel;
42 __le32 target_channel;
43 __le32 scan_channel;
44};
45
46struct brcmf_fil_action_frame_le {
47 u8 da[ETH_ALEN];
48 __le16 len;
49 __le32 packet_id;
50 u8 data[BRCMF_FIL_ACTION_FRAME_SIZE];
51};
52
53struct brcmf_fil_af_params_le {
54 __le32 channel;
55 __le32 dwell_time;
56 u8 bssid[ETH_ALEN];
57 u8 pad[2];
58 struct brcmf_fil_action_frame_le action_frame;
59};
60
61struct brcmf_fil_bss_enable_le {
62 __le32 bsscfg_idx;
63 __le32 enable;
64};
65
66#endif /* FWIL_TYPES_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
new file mode 100644
index 000000000000..4166e642068b
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -0,0 +1,2277 @@
1/*
2 * Copyright (c) 2012 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/slab.h>
17#include <linux/netdevice.h>
18#include <net/cfg80211.h>
19
20#include <brcmu_wifi.h>
21#include <brcmu_utils.h>
22#include <defs.h>
23#include <dhd.h>
24#include <dhd_dbg.h>
25#include "fwil.h"
26#include "fwil_types.h"
27#include "p2p.h"
28#include "wl_cfg80211.h"
29
30/* parameters used for p2p escan */
31#define P2PAPI_SCAN_NPROBES 1
32#define P2PAPI_SCAN_DWELL_TIME_MS 80
33#define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 40
34#define P2PAPI_SCAN_HOME_TIME_MS 60
35#define P2PAPI_SCAN_NPROBS_TIME_MS 30
36#define P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS 100
37#define WL_SCAN_CONNECT_DWELL_TIME_MS 200
38#define WL_SCAN_JOIN_PROBE_INTERVAL_MS 20
39
40#define BRCMF_P2P_WILDCARD_SSID "DIRECT-"
41#define BRCMF_P2P_WILDCARD_SSID_LEN (sizeof(BRCMF_P2P_WILDCARD_SSID) - 1)
42
43#define SOCIAL_CHAN_1 1
44#define SOCIAL_CHAN_2 6
45#define SOCIAL_CHAN_3 11
46#define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \
47 (channel == SOCIAL_CHAN_2) || \
48 (channel == SOCIAL_CHAN_3))
49#define SOCIAL_CHAN_CNT 3
50#define AF_PEER_SEARCH_CNT 2
51
52#define BRCMF_SCB_TIMEOUT_VALUE 20
53
54#define P2P_VER 9 /* P2P version: 9=WiFi P2P v1.0 */
55#define P2P_PUB_AF_CATEGORY 0x04
56#define P2P_PUB_AF_ACTION 0x09
57#define P2P_AF_CATEGORY 0x7f
58#define P2P_OUI "\x50\x6F\x9A" /* P2P OUI */
59#define P2P_OUI_LEN 3 /* P2P OUI length */
60
61/* Action Frame Constants */
62#define DOT11_ACTION_HDR_LEN 2 /* action frame category + action */
63#define DOT11_ACTION_CAT_OFF 0 /* category offset */
64#define DOT11_ACTION_ACT_OFF 1 /* action offset */
65
66#define P2P_AF_DWELL_TIME 200
67#define P2P_AF_MIN_DWELL_TIME 100
68#define P2P_AF_MED_DWELL_TIME 400
69#define P2P_AF_LONG_DWELL_TIME 1000
70#define P2P_AF_TX_MAX_RETRY 1
71#define P2P_AF_MAX_WAIT_TIME 2000
72#define P2P_INVALID_CHANNEL -1
73#define P2P_CHANNEL_SYNC_RETRY 5
74#define P2P_AF_FRM_SCAN_MAX_WAIT 1500
75#define P2P_DEFAULT_SLEEP_TIME_VSDB 200
76
77/* WiFi P2P Public Action Frame OUI Subtypes */
78#define P2P_PAF_GON_REQ 0 /* Group Owner Negotiation Req */
79#define P2P_PAF_GON_RSP 1 /* Group Owner Negotiation Rsp */
80#define P2P_PAF_GON_CONF 2 /* Group Owner Negotiation Confirm */
81#define P2P_PAF_INVITE_REQ 3 /* P2P Invitation Request */
82#define P2P_PAF_INVITE_RSP 4 /* P2P Invitation Response */
83#define P2P_PAF_DEVDIS_REQ 5 /* Device Discoverability Request */
84#define P2P_PAF_DEVDIS_RSP 6 /* Device Discoverability Response */
85#define P2P_PAF_PROVDIS_REQ 7 /* Provision Discovery Request */
86#define P2P_PAF_PROVDIS_RSP 8 /* Provision Discovery Response */
87#define P2P_PAF_SUBTYPE_INVALID 255 /* Invalid Subtype */
88
89/* WiFi P2P Action Frame OUI Subtypes */
90#define P2P_AF_NOTICE_OF_ABSENCE 0 /* Notice of Absence */
91#define P2P_AF_PRESENCE_REQ 1 /* P2P Presence Request */
92#define P2P_AF_PRESENCE_RSP 2 /* P2P Presence Response */
93#define P2P_AF_GO_DISC_REQ 3 /* GO Discoverability Request */
94
95/* P2P Service Discovery related */
96#define P2PSD_ACTION_CATEGORY 0x04 /* Public action frame */
97#define P2PSD_ACTION_ID_GAS_IREQ 0x0a /* GAS Initial Request AF */
98#define P2PSD_ACTION_ID_GAS_IRESP 0x0b /* GAS Initial Response AF */
99#define P2PSD_ACTION_ID_GAS_CREQ 0x0c /* GAS Comback Request AF */
100#define P2PSD_ACTION_ID_GAS_CRESP 0x0d /* GAS Comback Response AF */
101
102/**
103 * struct brcmf_p2p_disc_st_le - set discovery state in firmware.
104 *
105 * @state: requested discovery state (see enum brcmf_p2p_disc_state).
106 * @chspec: channel parameter for %WL_P2P_DISC_ST_LISTEN state.
107 * @dwell: dwell time in ms for %WL_P2P_DISC_ST_LISTEN state.
108 */
109struct brcmf_p2p_disc_st_le {
110 u8 state;
111 __le16 chspec;
112 __le16 dwell;
113};
114
115/**
116 * enum brcmf_p2p_disc_state - P2P discovery state values
117 *
118 * @WL_P2P_DISC_ST_SCAN: P2P discovery with wildcard SSID and P2P IE.
119 * @WL_P2P_DISC_ST_LISTEN: P2P discovery off-channel for specified time.
120 * @WL_P2P_DISC_ST_SEARCH: P2P discovery with P2P wildcard SSID and P2P IE.
121 */
122enum brcmf_p2p_disc_state {
123 WL_P2P_DISC_ST_SCAN,
124 WL_P2P_DISC_ST_LISTEN,
125 WL_P2P_DISC_ST_SEARCH
126};
127
128/**
129 * struct brcmf_p2p_scan_le - P2P specific scan request.
130 *
131 * @type: type of scan method requested (values: 'E' or 'S').
132 * @reserved: reserved (ignored).
133 * @eparams: parameters used for type 'E'.
134 * @sparams: parameters used for type 'S'.
135 */
136struct brcmf_p2p_scan_le {
137 u8 type;
138 u8 reserved[3];
139 union {
140 struct brcmf_escan_params_le eparams;
141 struct brcmf_scan_params_le sparams;
142 };
143};
144
145/**
146 * struct brcmf_p2p_pub_act_frame - WiFi P2P Public Action Frame
147 *
148 * @category: P2P_PUB_AF_CATEGORY
149 * @action: P2P_PUB_AF_ACTION
150 * @oui[3]: P2P_OUI
151 * @oui_type: OUI type - P2P_VER
152 * @subtype: OUI subtype - P2P_TYPE_*
153 * @dialog_token: nonzero, identifies req/rsp transaction
154 * @elts[1]: Variable length information elements.
155 */
156struct brcmf_p2p_pub_act_frame {
157 u8 category;
158 u8 action;
159 u8 oui[3];
160 u8 oui_type;
161 u8 subtype;
162 u8 dialog_token;
163 u8 elts[1];
164};
165
166/**
167 * struct brcmf_p2p_action_frame - WiFi P2P Action Frame
168 *
169 * @category: P2P_AF_CATEGORY
170 * @OUI[3]: OUI - P2P_OUI
171 * @type: OUI Type - P2P_VER
172 * @subtype: OUI Subtype - P2P_AF_*
173 * @dialog_token: nonzero, identifies req/resp tranaction
174 * @elts[1]: Variable length information elements.
175 */
176struct brcmf_p2p_action_frame {
177 u8 category;
178 u8 oui[3];
179 u8 type;
180 u8 subtype;
181 u8 dialog_token;
182 u8 elts[1];
183};
184
185/**
186 * struct brcmf_p2psd_gas_pub_act_frame - Wi-Fi GAS Public Action Frame
187 *
188 * @category: 0x04 Public Action Frame
189 * @action: 0x6c Advertisement Protocol
190 * @dialog_token: nonzero, identifies req/rsp transaction
191 * @query_data[1]: Query Data. SD gas ireq SD gas iresp
192 */
193struct brcmf_p2psd_gas_pub_act_frame {
194 u8 category;
195 u8 action;
196 u8 dialog_token;
197 u8 query_data[1];
198};
199
200/**
201 * struct brcmf_config_af_params - Action Frame Parameters for tx.
202 *
203 * @mpc_onoff: To make sure to send successfully action frame, we have to
204 * turn off mpc 0: off, 1: on, (-1): do nothing
205 * @search_channel: 1: search peer's channel to send af
206 * extra_listen: keep the dwell time to get af response frame.
207 */
208struct brcmf_config_af_params {
209 s32 mpc_onoff;
210 bool search_channel;
211 bool extra_listen;
212};
213
214/**
215 * brcmf_p2p_is_pub_action() - true if p2p public type frame.
216 *
217 * @frame: action frame data.
218 * @frame_len: length of action frame data.
219 *
220 * Determine if action frame is p2p public action type
221 */
222static bool brcmf_p2p_is_pub_action(void *frame, u32 frame_len)
223{
224 struct brcmf_p2p_pub_act_frame *pact_frm;
225
226 if (frame == NULL)
227 return false;
228
229 pact_frm = (struct brcmf_p2p_pub_act_frame *)frame;
230 if (frame_len < sizeof(struct brcmf_p2p_pub_act_frame) - 1)
231 return false;
232
233 if (pact_frm->category == P2P_PUB_AF_CATEGORY &&
234 pact_frm->action == P2P_PUB_AF_ACTION &&
235 pact_frm->oui_type == P2P_VER &&
236 memcmp(pact_frm->oui, P2P_OUI, P2P_OUI_LEN) == 0)
237 return true;
238
239 return false;
240}
241
242/**
243 * brcmf_p2p_is_p2p_action() - true if p2p action type frame.
244 *
245 * @frame: action frame data.
246 * @frame_len: length of action frame data.
247 *
248 * Determine if action frame is p2p action type
249 */
250static bool brcmf_p2p_is_p2p_action(void *frame, u32 frame_len)
251{
252 struct brcmf_p2p_action_frame *act_frm;
253
254 if (frame == NULL)
255 return false;
256
257 act_frm = (struct brcmf_p2p_action_frame *)frame;
258 if (frame_len < sizeof(struct brcmf_p2p_action_frame) - 1)
259 return false;
260
261 if (act_frm->category == P2P_AF_CATEGORY &&
262 act_frm->type == P2P_VER &&
263 memcmp(act_frm->oui, P2P_OUI, P2P_OUI_LEN) == 0)
264 return true;
265
266 return false;
267}
268
269/**
270 * brcmf_p2p_is_gas_action() - true if p2p gas action type frame.
271 *
272 * @frame: action frame data.
273 * @frame_len: length of action frame data.
274 *
275 * Determine if action frame is p2p gas action type
276 */
277static bool brcmf_p2p_is_gas_action(void *frame, u32 frame_len)
278{
279 struct brcmf_p2psd_gas_pub_act_frame *sd_act_frm;
280
281 if (frame == NULL)
282 return false;
283
284 sd_act_frm = (struct brcmf_p2psd_gas_pub_act_frame *)frame;
285 if (frame_len < sizeof(struct brcmf_p2psd_gas_pub_act_frame) - 1)
286 return false;
287
288 if (sd_act_frm->category != P2PSD_ACTION_CATEGORY)
289 return false;
290
291 if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ ||
292 sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP ||
293 sd_act_frm->action == P2PSD_ACTION_ID_GAS_CREQ ||
294 sd_act_frm->action == P2PSD_ACTION_ID_GAS_CRESP)
295 return true;
296
297 return false;
298}
299
300/**
301 * brcmf_p2p_print_actframe() - debug print routine.
302 *
303 * @tx: Received or to be transmitted
304 * @frame: action frame data.
305 * @frame_len: length of action frame data.
306 *
307 * Print information about the p2p action frame
308 */
309
310#ifdef DEBUG
311
312static void brcmf_p2p_print_actframe(bool tx, void *frame, u32 frame_len)
313{
314 struct brcmf_p2p_pub_act_frame *pact_frm;
315 struct brcmf_p2p_action_frame *act_frm;
316 struct brcmf_p2psd_gas_pub_act_frame *sd_act_frm;
317
318 if (!frame || frame_len <= 2)
319 return;
320
321 if (brcmf_p2p_is_pub_action(frame, frame_len)) {
322 pact_frm = (struct brcmf_p2p_pub_act_frame *)frame;
323 switch (pact_frm->subtype) {
324 case P2P_PAF_GON_REQ:
325 brcmf_dbg(TRACE, "%s P2P Group Owner Negotiation Req Frame\n",
326 (tx) ? "TX" : "RX");
327 break;
328 case P2P_PAF_GON_RSP:
329 brcmf_dbg(TRACE, "%s P2P Group Owner Negotiation Rsp Frame\n",
330 (tx) ? "TX" : "RX");
331 break;
332 case P2P_PAF_GON_CONF:
333 brcmf_dbg(TRACE, "%s P2P Group Owner Negotiation Confirm Frame\n",
334 (tx) ? "TX" : "RX");
335 break;
336 case P2P_PAF_INVITE_REQ:
337 brcmf_dbg(TRACE, "%s P2P Invitation Request Frame\n",
338 (tx) ? "TX" : "RX");
339 break;
340 case P2P_PAF_INVITE_RSP:
341 brcmf_dbg(TRACE, "%s P2P Invitation Response Frame\n",
342 (tx) ? "TX" : "RX");
343 break;
344 case P2P_PAF_DEVDIS_REQ:
345 brcmf_dbg(TRACE, "%s P2P Device Discoverability Request Frame\n",
346 (tx) ? "TX" : "RX");
347 break;
348 case P2P_PAF_DEVDIS_RSP:
349 brcmf_dbg(TRACE, "%s P2P Device Discoverability Response Frame\n",
350 (tx) ? "TX" : "RX");
351 break;
352 case P2P_PAF_PROVDIS_REQ:
353 brcmf_dbg(TRACE, "%s P2P Provision Discovery Request Frame\n",
354 (tx) ? "TX" : "RX");
355 break;
356 case P2P_PAF_PROVDIS_RSP:
357 brcmf_dbg(TRACE, "%s P2P Provision Discovery Response Frame\n",
358 (tx) ? "TX" : "RX");
359 break;
360 default:
361 brcmf_dbg(TRACE, "%s Unknown P2P Public Action Frame\n",
362 (tx) ? "TX" : "RX");
363 break;
364 }
365 } else if (brcmf_p2p_is_p2p_action(frame, frame_len)) {
366 act_frm = (struct brcmf_p2p_action_frame *)frame;
367 switch (act_frm->subtype) {
368 case P2P_AF_NOTICE_OF_ABSENCE:
369 brcmf_dbg(TRACE, "%s P2P Notice of Absence Frame\n",
370 (tx) ? "TX" : "RX");
371 break;
372 case P2P_AF_PRESENCE_REQ:
373 brcmf_dbg(TRACE, "%s P2P Presence Request Frame\n",
374 (tx) ? "TX" : "RX");
375 break;
376 case P2P_AF_PRESENCE_RSP:
377 brcmf_dbg(TRACE, "%s P2P Presence Response Frame\n",
378 (tx) ? "TX" : "RX");
379 break;
380 case P2P_AF_GO_DISC_REQ:
381 brcmf_dbg(TRACE, "%s P2P Discoverability Request Frame\n",
382 (tx) ? "TX" : "RX");
383 break;
384 default:
385 brcmf_dbg(TRACE, "%s Unknown P2P Action Frame\n",
386 (tx) ? "TX" : "RX");
387 }
388
389 } else if (brcmf_p2p_is_gas_action(frame, frame_len)) {
390 sd_act_frm = (struct brcmf_p2psd_gas_pub_act_frame *)frame;
391 switch (sd_act_frm->action) {
392 case P2PSD_ACTION_ID_GAS_IREQ:
393 brcmf_dbg(TRACE, "%s P2P GAS Initial Request\n",
394 (tx) ? "TX" : "RX");
395 break;
396 case P2PSD_ACTION_ID_GAS_IRESP:
397 brcmf_dbg(TRACE, "%s P2P GAS Initial Response\n",
398 (tx) ? "TX" : "RX");
399 break;
400 case P2PSD_ACTION_ID_GAS_CREQ:
401 brcmf_dbg(TRACE, "%s P2P GAS Comback Request\n",
402 (tx) ? "TX" : "RX");
403 break;
404 case P2PSD_ACTION_ID_GAS_CRESP:
405 brcmf_dbg(TRACE, "%s P2P GAS Comback Response\n",
406 (tx) ? "TX" : "RX");
407 break;
408 default:
409 brcmf_dbg(TRACE, "%s Unknown P2P GAS Frame\n",
410 (tx) ? "TX" : "RX");
411 break;
412 }
413 }
414}
415
416#else
417
418static void brcmf_p2p_print_actframe(bool tx, void *frame, u32 frame_len)
419{
420}
421
422#endif
423
424
425/**
426 * brcmf_p2p_chnr_to_chspec() - convert channel number to chanspec.
427 *
428 * @channel: channel number
429 */
430static u16 brcmf_p2p_chnr_to_chspec(u16 channel)
431{
432 u16 chanspec;
433
434 chanspec = channel & WL_CHANSPEC_CHAN_MASK;
435
436 if (channel <= CH_MAX_2G_CHANNEL)
437 chanspec |= WL_CHANSPEC_BAND_2G;
438 else
439 chanspec |= WL_CHANSPEC_BAND_5G;
440
441 chanspec |= WL_CHANSPEC_BW_20;
442 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
443
444 return chanspec;
445}
446
447
448/**
449 * brcmf_p2p_set_firmware() - prepare firmware for peer-to-peer operation.
450 *
451 * @ifp: ifp to use for iovars (primary).
452 * @p2p_mac: mac address to configure for p2p_da_override
453 */
454static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac)
455{
456 s32 ret = 0;
457
458 brcmf_fil_iovar_int_set(ifp, "apsta", 1);
459
460 /* In case of COB type, firmware has default mac address
461 * After Initializing firmware, we have to set current mac address to
462 * firmware for P2P device address
463 */
464 ret = brcmf_fil_iovar_data_set(ifp, "p2p_da_override", p2p_mac,
465 ETH_ALEN);
466 if (ret)
467 brcmf_err("failed to update device address ret %d\n", ret);
468
469 return ret;
470}
471
472/**
473 * brcmf_p2p_generate_bss_mac() - derive mac addresses for P2P.
474 *
475 * @p2p: P2P specific data.
476 *
477 * P2P needs mac addresses for P2P device and interface. These are
478 * derived from the primary net device, ie. the permanent ethernet
479 * address of the device.
480 */
481static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p)
482{
483 struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
484 struct brcmf_if *p2p_ifp = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->ifp;
485
486 /* Generate the P2P Device Address. This consists of the device's
487 * primary MAC address with the locally administered bit set.
488 */
489 memcpy(p2p->dev_addr, pri_ifp->mac_addr, ETH_ALEN);
490 p2p->dev_addr[0] |= 0x02;
491 memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
492
493 /* Generate the P2P Interface Address. If the discovery and connection
494 * BSSCFGs need to simultaneously co-exist, then this address must be
495 * different from the P2P Device Address, but also locally administered.
496 */
497 memcpy(p2p->int_addr, p2p->dev_addr, ETH_ALEN);
498 p2p->int_addr[4] ^= 0x80;
499}
500
501/**
502 * brcmf_p2p_scan_is_p2p_request() - is cfg80211 scan request a P2P scan.
503 *
504 * @request: the scan request as received from cfg80211.
505 *
506 * returns true if one of the ssids in the request matches the
507 * P2P wildcard ssid; otherwise returns false.
508 */
509static bool brcmf_p2p_scan_is_p2p_request(struct cfg80211_scan_request *request)
510{
511 struct cfg80211_ssid *ssids = request->ssids;
512 int i;
513
514 for (i = 0; i < request->n_ssids; i++) {
515 if (ssids[i].ssid_len != BRCMF_P2P_WILDCARD_SSID_LEN)
516 continue;
517
518 brcmf_dbg(INFO, "comparing ssid \"%s\"", ssids[i].ssid);
519 if (!memcmp(BRCMF_P2P_WILDCARD_SSID, ssids[i].ssid,
520 BRCMF_P2P_WILDCARD_SSID_LEN))
521 return true;
522 }
523 return false;
524}
525
526/**
527 * brcmf_p2p_set_discover_state - set discover state in firmware.
528 *
529 * @ifp: low-level interface object.
530 * @state: discover state to set.
531 * @chanspec: channel parameters (for state @WL_P2P_DISC_ST_LISTEN only).
532 * @listen_ms: duration to listen (for state @WL_P2P_DISC_ST_LISTEN only).
533 */
534static s32 brcmf_p2p_set_discover_state(struct brcmf_if *ifp, u8 state,
535 u16 chanspec, u16 listen_ms)
536{
537 struct brcmf_p2p_disc_st_le discover_state;
538 s32 ret = 0;
539 brcmf_dbg(TRACE, "enter\n");
540
541 discover_state.state = state;
542 discover_state.chspec = cpu_to_le16(chanspec);
543 discover_state.dwell = cpu_to_le16(listen_ms);
544 ret = brcmf_fil_bsscfg_data_set(ifp, "p2p_state", &discover_state,
545 sizeof(discover_state));
546 return ret;
547}
548
549/**
550 * brcmf_p2p_deinit_discovery() - disable P2P device discovery.
551 *
552 * @p2p: P2P specific data.
553 *
554 * Resets the discovery state and disables it in firmware.
555 */
556static s32 brcmf_p2p_deinit_discovery(struct brcmf_p2p_info *p2p)
557{
558 struct brcmf_cfg80211_vif *vif;
559
560 brcmf_dbg(TRACE, "enter\n");
561
562 /* Set the discovery state to SCAN */
563 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
564 (void)brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0);
565
566 /* Disable P2P discovery in the firmware */
567 vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
568 (void)brcmf_fil_iovar_int_set(vif->ifp, "p2p_disc", 0);
569
570 return 0;
571}
572
573/**
574 * brcmf_p2p_enable_discovery() - initialize and configure discovery.
575 *
576 * @p2p: P2P specific data.
577 *
578 * Initializes the discovery device and configure the virtual interface.
579 */
580static int brcmf_p2p_enable_discovery(struct brcmf_p2p_info *p2p)
581{
582 struct brcmf_cfg80211_vif *vif;
583 s32 ret = 0;
584
585 brcmf_dbg(TRACE, "enter\n");
586 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
587 if (!vif) {
588 brcmf_err("P2P config device not available\n");
589 ret = -EPERM;
590 goto exit;
591 }
592
593 if (test_bit(BRCMF_P2P_STATUS_ENABLED, &p2p->status)) {
594 brcmf_dbg(INFO, "P2P config device already configured\n");
595 goto exit;
596 }
597
598 /* Re-initialize P2P Discovery in the firmware */
599 vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
600 ret = brcmf_fil_iovar_int_set(vif->ifp, "p2p_disc", 1);
601 if (ret < 0) {
602 brcmf_err("set p2p_disc error\n");
603 goto exit;
604 }
605 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
606 ret = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0);
607 if (ret < 0) {
608 brcmf_err("unable to set WL_P2P_DISC_ST_SCAN\n");
609 goto exit;
610 }
611
612 /*
613 * Set wsec to any non-zero value in the discovery bsscfg
614 * to ensure our P2P probe responses have the privacy bit
615 * set in the 802.11 WPA IE. Some peer devices may not
616 * initiate WPS with us if this bit is not set.
617 */
618 ret = brcmf_fil_bsscfg_int_set(vif->ifp, "wsec", AES_ENABLED);
619 if (ret < 0) {
620 brcmf_err("wsec error %d\n", ret);
621 goto exit;
622 }
623
624 set_bit(BRCMF_P2P_STATUS_ENABLED, &p2p->status);
625exit:
626 return ret;
627}
628
629/**
630 * brcmf_p2p_escan() - initiate a P2P scan.
631 *
632 * @p2p: P2P specific data.
633 * @num_chans: number of channels to scan.
634 * @chanspecs: channel parameters for @num_chans channels.
635 * @search_state: P2P discover state to use.
636 * @action: scan action to pass to firmware.
637 * @bss_type: type of P2P bss.
638 */
639static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
640 u16 chanspecs[], s32 search_state, u16 action,
641 enum p2p_bss_type bss_type)
642{
643 s32 ret = 0;
644 s32 memsize = offsetof(struct brcmf_p2p_scan_le,
645 eparams.params_le.channel_list);
646 s32 nprobes;
647 s32 active;
648 u32 i;
649 u8 *memblk;
650 struct brcmf_cfg80211_vif *vif;
651 struct brcmf_p2p_scan_le *p2p_params;
652 struct brcmf_scan_params_le *sparams;
653 struct brcmf_ssid ssid;
654
655 memsize += num_chans * sizeof(__le16);
656 memblk = kzalloc(memsize, GFP_KERNEL);
657 if (!memblk)
658 return -ENOMEM;
659
660 vif = p2p->bss_idx[bss_type].vif;
661 if (vif == NULL) {
662 brcmf_err("no vif for bss type %d\n", bss_type);
663 ret = -EINVAL;
664 goto exit;
665 }
666
667 switch (search_state) {
668 case WL_P2P_DISC_ST_SEARCH:
669 /*
670 * If we in SEARCH STATE, we don't need to set SSID explictly
671 * because dongle use P2P WILDCARD internally by default
672 */
673 /* use null ssid */
674 ssid.SSID_len = 0;
675 memset(ssid.SSID, 0, sizeof(ssid.SSID));
676 break;
677 case WL_P2P_DISC_ST_SCAN:
678 /*
679 * wpa_supplicant has p2p_find command with type social or
680 * progressive. For progressive, we need to set the ssid to
681 * P2P WILDCARD because we just do broadcast scan unless
682 * setting SSID.
683 */
684 ssid.SSID_len = BRCMF_P2P_WILDCARD_SSID_LEN;
685 memcpy(ssid.SSID, BRCMF_P2P_WILDCARD_SSID, ssid.SSID_len);
686 break;
687 default:
688 brcmf_err(" invalid search state %d\n", search_state);
689 ret = -EINVAL;
690 goto exit;
691 }
692
693 brcmf_p2p_set_discover_state(vif->ifp, search_state, 0, 0);
694
695 /*
696 * set p2p scan parameters.
697 */
698 p2p_params = (struct brcmf_p2p_scan_le *)memblk;
699 p2p_params->type = 'E';
700
701 /* determine the scan engine parameters */
702 sparams = &p2p_params->eparams.params_le;
703 sparams->bss_type = DOT11_BSSTYPE_ANY;
704 if (p2p->cfg->active_scan)
705 sparams->scan_type = 0;
706 else
707 sparams->scan_type = 1;
708
709 memset(&sparams->bssid, 0xFF, ETH_ALEN);
710 if (ssid.SSID_len)
711 memcpy(sparams->ssid_le.SSID, ssid.SSID, ssid.SSID_len);
712 sparams->ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
713 sparams->home_time = cpu_to_le32(P2PAPI_SCAN_HOME_TIME_MS);
714
715 /*
716 * SOCIAL_CHAN_CNT + 1 takes care of the Progressive scan
717 * supported by the supplicant.
718 */
719 if (num_chans == SOCIAL_CHAN_CNT || num_chans == (SOCIAL_CHAN_CNT + 1))
720 active = P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS;
721 else if (num_chans == AF_PEER_SEARCH_CNT)
722 active = P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS;
723 else if (wl_get_vif_state_all(p2p->cfg, BRCMF_VIF_STATUS_CONNECTED))
724 active = -1;
725 else
726 active = P2PAPI_SCAN_DWELL_TIME_MS;
727
728 /* Override scan params to find a peer for a connection */
729 if (num_chans == 1) {
730 active = WL_SCAN_CONNECT_DWELL_TIME_MS;
731 /* WAR to sync with presence period of VSDB GO.
732 * send probe request more frequently
733 */
734 nprobes = active / WL_SCAN_JOIN_PROBE_INTERVAL_MS;
735 } else {
736 nprobes = active / P2PAPI_SCAN_NPROBS_TIME_MS;
737 }
738
739 if (nprobes <= 0)
740 nprobes = 1;
741
742 brcmf_dbg(INFO, "nprobes # %d, active_time %d\n", nprobes, active);
743 sparams->active_time = cpu_to_le32(active);
744 sparams->nprobes = cpu_to_le32(nprobes);
745 sparams->passive_time = cpu_to_le32(-1);
746 sparams->channel_num = cpu_to_le32(num_chans &
747 BRCMF_SCAN_PARAMS_COUNT_MASK);
748 for (i = 0; i < num_chans; i++)
749 sparams->channel_list[i] = cpu_to_le16(chanspecs[i]);
750
751 /* set the escan specific parameters */
752 p2p_params->eparams.version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
753 p2p_params->eparams.action = cpu_to_le16(action);
754 p2p_params->eparams.sync_id = cpu_to_le16(0x1234);
755 /* perform p2p scan on primary device */
756 ret = brcmf_fil_bsscfg_data_set(vif->ifp, "p2p_scan", memblk, memsize);
757 if (!ret)
758 set_bit(BRCMF_SCAN_STATUS_BUSY, &p2p->cfg->scan_status);
759exit:
760 kfree(memblk);
761 return ret;
762}
763
764/**
765 * brcmf_p2p_run_escan() - escan callback for peer-to-peer.
766 *
767 * @cfg: driver private data for cfg80211 interface.
768 * @ndev: net device for which scan is requested.
769 * @request: scan request from cfg80211.
770 * @action: scan action.
771 *
772 * Determines the P2P discovery state based to scan request parameters and
773 * validates the channels in the request.
774 */
775static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
776 struct net_device *ndev,
777 struct cfg80211_scan_request *request,
778 u16 action)
779{
780 struct brcmf_p2p_info *p2p = &cfg->p2p;
781 s32 err = 0;
782 s32 search_state = WL_P2P_DISC_ST_SCAN;
783 struct brcmf_cfg80211_vif *vif;
784 struct net_device *dev = NULL;
785 int i, num_nodfs = 0;
786 u16 *chanspecs;
787
788 brcmf_dbg(TRACE, "enter\n");
789
790 if (!request) {
791 err = -EINVAL;
792 goto exit;
793 }
794
795 if (request->n_channels) {
796 chanspecs = kcalloc(request->n_channels, sizeof(*chanspecs),
797 GFP_KERNEL);
798 if (!chanspecs) {
799 err = -ENOMEM;
800 goto exit;
801 }
802 vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif;
803 if (vif)
804 dev = vif->wdev.netdev;
805 if (request->n_channels == 3 &&
806 request->channels[0]->hw_value == SOCIAL_CHAN_1 &&
807 request->channels[1]->hw_value == SOCIAL_CHAN_2 &&
808 request->channels[2]->hw_value == SOCIAL_CHAN_3) {
809 /* SOCIAL CHANNELS 1, 6, 11 */
810 search_state = WL_P2P_DISC_ST_SEARCH;
811 brcmf_dbg(INFO, "P2P SEARCH PHASE START\n");
812 } else if (dev != NULL && vif->mode == WL_MODE_AP) {
813 /* If you are already a GO, then do SEARCH only */
814 brcmf_dbg(INFO, "Already a GO. Do SEARCH Only\n");
815 search_state = WL_P2P_DISC_ST_SEARCH;
816 } else {
817 brcmf_dbg(INFO, "P2P SCAN STATE START\n");
818 }
819
820 /*
821 * no P2P scanning on passive or DFS channels.
822 */
823 for (i = 0; i < request->n_channels; i++) {
824 struct ieee80211_channel *chan = request->channels[i];
825
826 if (chan->flags & (IEEE80211_CHAN_RADAR |
827 IEEE80211_CHAN_PASSIVE_SCAN))
828 continue;
829
830 chanspecs[i] = channel_to_chanspec(chan);
831 brcmf_dbg(INFO, "%d: chan=%d, channel spec=%x\n",
832 num_nodfs, chan->hw_value, chanspecs[i]);
833 num_nodfs++;
834 }
835 err = brcmf_p2p_escan(p2p, num_nodfs, chanspecs, search_state,
836 action, P2PAPI_BSSCFG_DEVICE);
837 }
838exit:
839 if (err)
840 brcmf_err("error (%d)\n", err);
841 return err;
842}
843
844
845/**
846 * brcmf_p2p_find_listen_channel() - find listen channel in ie string.
847 *
848 * @ie: string of information elements.
849 * @ie_len: length of string.
850 *
851 * Scan ie for p2p ie and look for attribute 6 channel. If available determine
852 * channel and return it.
853 */
854static s32 brcmf_p2p_find_listen_channel(const u8 *ie, u32 ie_len)
855{
856 u8 channel_ie[5];
857 s32 listen_channel;
858 s32 err;
859
860 err = cfg80211_get_p2p_attr(ie, ie_len,
861 IEEE80211_P2P_ATTR_LISTEN_CHANNEL,
862 channel_ie, sizeof(channel_ie));
863 if (err < 0)
864 return err;
865
866 /* listen channel subel length format: */
867 /* 3(country) + 1(op. class) + 1(chan num) */
868 listen_channel = (s32)channel_ie[3 + 1];
869
870 if (listen_channel == SOCIAL_CHAN_1 ||
871 listen_channel == SOCIAL_CHAN_2 ||
872 listen_channel == SOCIAL_CHAN_3) {
873 brcmf_dbg(INFO, "Found my Listen Channel %d\n", listen_channel);
874 return listen_channel;
875 }
876
877 return -EPERM;
878}
879
880
881/**
882 * brcmf_p2p_scan_prep() - prepare scan based on request.
883 *
884 * @wiphy: wiphy device.
885 * @request: scan request from cfg80211.
886 * @vif: vif on which scan request is to be executed.
887 *
888 * Prepare the scan appropriately for type of scan requested. Overrides the
889 * escan .run() callback for peer-to-peer scanning.
890 */
891int brcmf_p2p_scan_prep(struct wiphy *wiphy,
892 struct cfg80211_scan_request *request,
893 struct brcmf_cfg80211_vif *vif)
894{
895 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
896 struct brcmf_p2p_info *p2p = &cfg->p2p;
897 int err = 0;
898
899 if (brcmf_p2p_scan_is_p2p_request(request)) {
900 /* find my listen channel */
901 err = brcmf_p2p_find_listen_channel(request->ie,
902 request->ie_len);
903 if (err < 0)
904 return err;
905
906 p2p->afx_hdl.my_listen_chan = err;
907
908 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
909 brcmf_dbg(INFO, "P2P: GO_NEG_PHASE status cleared\n");
910
911 err = brcmf_p2p_enable_discovery(p2p);
912 if (err)
913 return err;
914
915 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
916
917 /* override .run_escan() callback. */
918 cfg->escan_info.run = brcmf_p2p_run_escan;
919 }
920 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
921 request->ie, request->ie_len);
922 return err;
923}
924
925
926/**
927 * brcmf_p2p_discover_listen() - set firmware to discover listen state.
928 *
929 * @p2p: p2p device.
930 * @channel: channel nr for discover listen.
931 * @duration: time in ms to stay on channel.
932 *
933 */
934static s32
935brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration)
936{
937 struct brcmf_cfg80211_vif *vif;
938 s32 err = 0;
939 u16 chanspec;
940
941 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
942 if (!vif) {
943 brcmf_err("Discovery is not set, so we have nothing to do\n");
944 err = -EPERM;
945 goto exit;
946 }
947
948 if (test_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status)) {
949 brcmf_err("Previous LISTEN is not completed yet\n");
950 /* WAR: prevent cookie mismatch in wpa_supplicant return OK */
951 goto exit;
952 }
953
954 chanspec = brcmf_p2p_chnr_to_chspec(channel);
955 err = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_LISTEN,
956 chanspec, (u16)duration);
957 if (!err) {
958 set_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status);
959 p2p->remain_on_channel_cookie++;
960 }
961exit:
962 return err;
963}
964
965
966/**
967 * brcmf_p2p_remain_on_channel() - put device on channel and stay there.
968 *
969 * @wiphy: wiphy device.
970 * @channel: channel to stay on.
971 * @duration: time in ms to remain on channel.
972 *
973 */
974int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
975 struct ieee80211_channel *channel,
976 unsigned int duration, u64 *cookie)
977{
978 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
979 struct brcmf_p2p_info *p2p = &cfg->p2p;
980 s32 err;
981 u16 channel_nr;
982
983 channel_nr = ieee80211_frequency_to_channel(channel->center_freq);
984 brcmf_dbg(TRACE, "Enter, channel: %d, duration ms (%d)\n", channel_nr,
985 duration);
986
987 err = brcmf_p2p_enable_discovery(p2p);
988 if (err)
989 goto exit;
990 err = brcmf_p2p_discover_listen(p2p, channel_nr, duration);
991 if (err)
992 goto exit;
993
994 memcpy(&p2p->remain_on_channel, channel, sizeof(*channel));
995 *cookie = p2p->remain_on_channel_cookie;
996 cfg80211_ready_on_channel(wdev, *cookie, channel, duration, GFP_KERNEL);
997
998exit:
999 return err;
1000}
1001
1002
1003/**
1004 * brcmf_p2p_notify_listen_complete() - p2p listen has completed.
1005 *
1006 * @ifp: interfac control.
1007 * @e: event message. Not used, to make it usable for fweh event dispatcher.
1008 * @data: payload of message. Not used.
1009 *
1010 */
1011int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp,
1012 const struct brcmf_event_msg *e,
1013 void *data)
1014{
1015 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1016 struct brcmf_p2p_info *p2p = &cfg->p2p;
1017
1018 brcmf_dbg(TRACE, "Enter\n");
1019 if (test_and_clear_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN,
1020 &p2p->status)) {
1021 if (test_and_clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
1022 &p2p->status)) {
1023 clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME,
1024 &p2p->status);
1025 brcmf_dbg(INFO, "Listen DONE, wake up wait_next_af\n");
1026 complete(&p2p->wait_next_af);
1027 }
1028
1029 cfg80211_remain_on_channel_expired(&ifp->vif->wdev,
1030 p2p->remain_on_channel_cookie,
1031 &p2p->remain_on_channel,
1032 GFP_KERNEL);
1033 }
1034 return 0;
1035}
1036
1037
1038/**
1039 * brcmf_p2p_cancel_remain_on_channel() - cancel p2p listen state.
1040 *
1041 * @ifp: interfac control.
1042 *
1043 */
1044void brcmf_p2p_cancel_remain_on_channel(struct brcmf_if *ifp)
1045{
1046 if (!ifp)
1047 return;
1048 brcmf_p2p_set_discover_state(ifp, WL_P2P_DISC_ST_SCAN, 0, 0);
1049 brcmf_p2p_notify_listen_complete(ifp, NULL, NULL);
1050}
1051
1052
1053/**
1054 * brcmf_p2p_act_frm_search() - search function for action frame.
1055 *
1056 * @p2p: p2p device.
1057 * channel: channel on which action frame is to be trasmitted.
1058 *
1059 * search function to reach at common channel to send action frame. When
1060 * channel is 0 then all social channels will be used to send af
1061 */
1062static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel)
1063{
1064 s32 err;
1065 u32 channel_cnt;
1066 u16 *default_chan_list;
1067 u32 i;
1068
1069 brcmf_dbg(TRACE, "Enter\n");
1070
1071 if (channel)
1072 channel_cnt = AF_PEER_SEARCH_CNT;
1073 else
1074 channel_cnt = SOCIAL_CHAN_CNT;
1075 default_chan_list = kzalloc(channel_cnt * sizeof(*default_chan_list),
1076 GFP_KERNEL);
1077 if (default_chan_list == NULL) {
1078 brcmf_err("channel list allocation failed\n");
1079 err = -ENOMEM;
1080 goto exit;
1081 }
1082 if (channel) {
1083 /* insert same channel to the chan_list */
1084 for (i = 0; i < channel_cnt; i++)
1085 default_chan_list[i] =
1086 brcmf_p2p_chnr_to_chspec(channel);
1087 } else {
1088 default_chan_list[0] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_1);
1089 default_chan_list[1] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_2);
1090 default_chan_list[2] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_3);
1091 }
1092 err = brcmf_p2p_escan(p2p, channel_cnt, default_chan_list,
1093 WL_P2P_DISC_ST_SEARCH, WL_ESCAN_ACTION_START,
1094 P2PAPI_BSSCFG_DEVICE);
1095 kfree(default_chan_list);
1096exit:
1097 return err;
1098}
1099
1100
1101/**
1102 * brcmf_p2p_afx_handler() - afx worker thread.
1103 *
1104 * @work:
1105 *
1106 */
1107static void brcmf_p2p_afx_handler(struct work_struct *work)
1108{
1109 struct afx_hdl *afx_hdl = container_of(work, struct afx_hdl, afx_work);
1110 struct brcmf_p2p_info *p2p = container_of(afx_hdl,
1111 struct brcmf_p2p_info,
1112 afx_hdl);
1113 s32 err;
1114
1115 if (!afx_hdl->is_active)
1116 return;
1117
1118 if (afx_hdl->is_listen && afx_hdl->my_listen_chan)
1119 /* 100ms ~ 300ms */
1120 err = brcmf_p2p_discover_listen(p2p, afx_hdl->my_listen_chan,
1121 100 * (1 + (random32() % 3)));
1122 else
1123 err = brcmf_p2p_act_frm_search(p2p, afx_hdl->peer_listen_chan);
1124
1125 if (err) {
1126 brcmf_err("ERROR occurred! value is (%d)\n", err);
1127 if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1128 &p2p->status))
1129 complete(&afx_hdl->act_frm_scan);
1130 }
1131}
1132
1133
1134/**
1135 * brcmf_p2p_af_searching_channel() - search channel.
1136 *
1137 * @p2p: p2p device info struct.
1138 *
1139 */
1140static s32 brcmf_p2p_af_searching_channel(struct brcmf_p2p_info *p2p)
1141{
1142 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1143 struct brcmf_cfg80211_vif *pri_vif;
1144 unsigned long duration;
1145 s32 retry;
1146
1147 brcmf_dbg(TRACE, "Enter\n");
1148
1149 pri_vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1150
1151 INIT_COMPLETION(afx_hdl->act_frm_scan);
1152 set_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status);
1153 afx_hdl->is_active = true;
1154 afx_hdl->peer_chan = P2P_INVALID_CHANNEL;
1155
1156 /* Loop to wait until we find a peer's channel or the
1157 * pending action frame tx is cancelled.
1158 */
1159 retry = 0;
1160 duration = msecs_to_jiffies(P2P_AF_FRM_SCAN_MAX_WAIT);
1161 while ((retry < P2P_CHANNEL_SYNC_RETRY) &&
1162 (afx_hdl->peer_chan == P2P_INVALID_CHANNEL)) {
1163 afx_hdl->is_listen = false;
1164 brcmf_dbg(TRACE, "Scheduling action frame for sending.. (%d)\n",
1165 retry);
1166 /* search peer on peer's listen channel */
1167 schedule_work(&afx_hdl->afx_work);
1168 wait_for_completion_timeout(&afx_hdl->act_frm_scan, duration);
1169 if ((afx_hdl->peer_chan != P2P_INVALID_CHANNEL) ||
1170 (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1171 &p2p->status)))
1172 break;
1173
1174 if (afx_hdl->my_listen_chan) {
1175 brcmf_dbg(TRACE, "Scheduling listen peer, channel=%d\n",
1176 afx_hdl->my_listen_chan);
1177 /* listen on my listen channel */
1178 afx_hdl->is_listen = true;
1179 schedule_work(&afx_hdl->afx_work);
1180 wait_for_completion_timeout(&afx_hdl->act_frm_scan,
1181 duration);
1182 }
1183 if ((afx_hdl->peer_chan != P2P_INVALID_CHANNEL) ||
1184 (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1185 &p2p->status)))
1186 break;
1187 retry++;
1188
1189 /* if sta is connected or connecting, sleep for a while before
1190 * retry af tx or finding a peer
1191 */
1192 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &pri_vif->sme_state) ||
1193 test_bit(BRCMF_VIF_STATUS_CONNECTING, &pri_vif->sme_state))
1194 msleep(P2P_DEFAULT_SLEEP_TIME_VSDB);
1195 }
1196
1197 brcmf_dbg(TRACE, "Completed search/listen peer_chan=%d\n",
1198 afx_hdl->peer_chan);
1199 afx_hdl->is_active = false;
1200
1201 clear_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status);
1202
1203 return afx_hdl->peer_chan;
1204}
1205
1206
1207/**
1208 * brcmf_p2p_scan_finding_common_channel() - was escan used for finding channel
1209 *
1210 * @cfg: common configuration struct.
1211 * @bi: bss info struct, result from scan.
1212 *
1213 */
1214bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,
1215 struct brcmf_bss_info_le *bi)
1216
1217{
1218 struct brcmf_p2p_info *p2p = &cfg->p2p;
1219 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1220 u8 *ie;
1221 s32 err;
1222 u8 p2p_dev_addr[ETH_ALEN];
1223
1224 if (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status))
1225 return false;
1226
1227 if (bi == NULL) {
1228 brcmf_dbg(TRACE, "ACTION FRAME SCAN Done\n");
1229 if (afx_hdl->peer_chan == P2P_INVALID_CHANNEL)
1230 complete(&afx_hdl->act_frm_scan);
1231 return true;
1232 }
1233
1234 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
1235 memset(p2p_dev_addr, 0, sizeof(p2p_dev_addr));
1236 err = cfg80211_get_p2p_attr(ie, le32_to_cpu(bi->ie_length),
1237 IEEE80211_P2P_ATTR_DEVICE_INFO,
1238 p2p_dev_addr, sizeof(p2p_dev_addr));
1239 if (err < 0)
1240 err = cfg80211_get_p2p_attr(ie, le32_to_cpu(bi->ie_length),
1241 IEEE80211_P2P_ATTR_DEVICE_ID,
1242 p2p_dev_addr, sizeof(p2p_dev_addr));
1243 if ((err >= 0) &&
1244 (!memcmp(p2p_dev_addr, afx_hdl->tx_dst_addr, ETH_ALEN))) {
1245 afx_hdl->peer_chan = bi->ctl_ch ? bi->ctl_ch :
1246 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
1247 brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n",
1248 afx_hdl->tx_dst_addr, afx_hdl->peer_chan);
1249 complete(&afx_hdl->act_frm_scan);
1250 }
1251 return true;
1252}
1253
1254/**
1255 * brcmf_p2p_stop_wait_next_action_frame() - finish scan if af tx complete.
1256 *
1257 * @cfg: common configuration struct.
1258 *
1259 */
1260static void
1261brcmf_p2p_stop_wait_next_action_frame(struct brcmf_cfg80211_info *cfg)
1262{
1263 struct brcmf_p2p_info *p2p = &cfg->p2p;
1264 struct net_device *ndev = cfg->escan_info.ndev;
1265
1266 if (test_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status) &&
1267 (test_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status) ||
1268 test_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status))) {
1269 brcmf_dbg(TRACE, "*** Wake UP ** abort actframe iovar\n");
1270 /* if channel is not zero, "actfame" uses off channel scan.
1271 * So abort scan for off channel completion.
1272 */
1273 if (p2p->af_sent_channel)
1274 brcmf_notify_escan_complete(cfg, ndev, true, true);
1275 } else if (test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
1276 &p2p->status)) {
1277 brcmf_dbg(TRACE, "*** Wake UP ** abort listen for next af frame\n");
1278 /* So abort scan to cancel listen */
1279 brcmf_notify_escan_complete(cfg, ndev, true, true);
1280 }
1281}
1282
1283
1284/**
1285 * brcmf_p2p_gon_req_collision() - Check if go negotiaton collission
1286 *
1287 * @p2p: p2p device info struct.
1288 *
1289 * return true if recevied action frame is to be dropped.
1290 */
1291static bool
1292brcmf_p2p_gon_req_collision(struct brcmf_p2p_info *p2p, u8 *mac)
1293{
1294 struct brcmf_cfg80211_info *cfg = p2p->cfg;
1295 struct brcmf_if *ifp;
1296
1297 brcmf_dbg(TRACE, "Enter\n");
1298
1299 if (!test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status) ||
1300 !p2p->gon_req_action)
1301 return false;
1302
1303 brcmf_dbg(TRACE, "GO Negotiation Request COLLISION !!!\n");
1304 /* if sa(peer) addr is less than da(my) addr, then this device
1305 * process peer's gon request and block to send gon req.
1306 * if not (sa addr > da addr),
1307 * this device will process gon request and drop gon req of peer.
1308 */
1309 ifp = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->ifp;
1310 if (memcmp(mac, ifp->mac_addr, ETH_ALEN) < 0) {
1311 brcmf_dbg(INFO, "Block transmit gon req !!!\n");
1312 p2p->block_gon_req_tx = true;
1313 /* if we are finding a common channel for sending af,
1314 * do not scan more to block to send current gon req
1315 */
1316 if (test_and_clear_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1317 &p2p->status))
1318 complete(&p2p->afx_hdl.act_frm_scan);
1319 if (test_and_clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME,
1320 &p2p->status))
1321 brcmf_p2p_stop_wait_next_action_frame(cfg);
1322 return false;
1323 }
1324
1325 /* drop gon request of peer to process gon request by this device. */
1326 brcmf_dbg(INFO, "Drop received gon req !!!\n");
1327
1328 return true;
1329}
1330
1331
1332/**
1333 * brcmf_p2p_notify_action_frame_rx() - received action frame.
1334 *
1335 * @ifp: interfac control.
1336 * @e: event message. Not used, to make it usable for fweh event dispatcher.
1337 * @data: payload of message, containing action frame data.
1338 *
1339 */
1340int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
1341 const struct brcmf_event_msg *e,
1342 void *data)
1343{
1344 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1345 struct brcmf_p2p_info *p2p = &cfg->p2p;
1346 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1347 struct wireless_dev *wdev;
1348 u32 mgmt_frame_len = e->datalen - sizeof(struct brcmf_rx_mgmt_data);
1349 struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data;
1350 u8 *frame = (u8 *)(rxframe + 1);
1351 struct brcmf_p2p_pub_act_frame *act_frm;
1352 struct brcmf_p2psd_gas_pub_act_frame *sd_act_frm;
1353 u16 chanspec = be16_to_cpu(rxframe->chanspec);
1354 struct ieee80211_mgmt *mgmt_frame;
1355 s32 freq;
1356 u16 mgmt_type;
1357 u8 action;
1358
1359 /* Check if wpa_supplicant has registered for this frame */
1360 brcmf_dbg(INFO, "ifp->vif->mgmt_rx_reg %04x\n", ifp->vif->mgmt_rx_reg);
1361 mgmt_type = (IEEE80211_STYPE_ACTION & IEEE80211_FCTL_STYPE) >> 4;
1362 if ((ifp->vif->mgmt_rx_reg & BIT(mgmt_type)) == 0)
1363 return 0;
1364
1365 brcmf_p2p_print_actframe(false, frame, mgmt_frame_len);
1366
1367 action = P2P_PAF_SUBTYPE_INVALID;
1368 if (brcmf_p2p_is_pub_action(frame, mgmt_frame_len)) {
1369 act_frm = (struct brcmf_p2p_pub_act_frame *)frame;
1370 action = act_frm->subtype;
1371 if ((action == P2P_PAF_GON_REQ) &&
1372 (brcmf_p2p_gon_req_collision(p2p, (u8 *)e->addr))) {
1373 if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1374 &p2p->status) &&
1375 (memcmp(afx_hdl->tx_dst_addr, e->addr,
1376 ETH_ALEN) == 0)) {
1377 afx_hdl->peer_chan = CHSPEC_CHANNEL(chanspec);
1378 brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n",
1379 afx_hdl->peer_chan);
1380 complete(&afx_hdl->act_frm_scan);
1381 }
1382 return 0;
1383 }
1384 /* After complete GO Negotiation, roll back to mpc mode */
1385 if ((action == P2P_PAF_GON_CONF) ||
1386 (action == P2P_PAF_PROVDIS_RSP))
1387 brcmf_set_mpc(ifp->ndev, 1);
1388 if (action == P2P_PAF_GON_CONF) {
1389 brcmf_dbg(TRACE, "P2P: GO_NEG_PHASE status cleared\n");
1390 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
1391 }
1392 } else if (brcmf_p2p_is_gas_action(frame, mgmt_frame_len)) {
1393 sd_act_frm = (struct brcmf_p2psd_gas_pub_act_frame *)frame;
1394 action = sd_act_frm->action;
1395 }
1396
1397 if (test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status) &&
1398 (p2p->next_af_subtype == action)) {
1399 brcmf_dbg(TRACE, "We got a right next frame! (%d)\n", action);
1400 clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME,
1401 &p2p->status);
1402 /* Stop waiting for next AF. */
1403 brcmf_p2p_stop_wait_next_action_frame(cfg);
1404 }
1405
1406 mgmt_frame = kzalloc(offsetof(struct ieee80211_mgmt, u) +
1407 mgmt_frame_len, GFP_KERNEL);
1408 if (!mgmt_frame) {
1409 brcmf_err("No memory available for action frame\n");
1410 return -ENOMEM;
1411 }
1412 memcpy(mgmt_frame->da, ifp->mac_addr, ETH_ALEN);
1413 brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, mgmt_frame->bssid,
1414 ETH_ALEN);
1415 memcpy(mgmt_frame->sa, e->addr, ETH_ALEN);
1416 mgmt_frame->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);
1417 memcpy(&mgmt_frame->u, frame, mgmt_frame_len);
1418 mgmt_frame_len += offsetof(struct ieee80211_mgmt, u);
1419
1420 freq = ieee80211_channel_to_frequency(CHSPEC_CHANNEL(chanspec),
1421 CHSPEC_IS2G(chanspec) ?
1422 IEEE80211_BAND_2GHZ :
1423 IEEE80211_BAND_5GHZ);
1424 wdev = ifp->ndev->ieee80211_ptr;
1425 cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len,
1426 GFP_ATOMIC);
1427
1428 kfree(mgmt_frame);
1429 return 0;
1430}
1431
1432
1433/**
1434 * brcmf_p2p_notify_action_tx_complete() - transmit action frame complete
1435 *
1436 * @ifp: interfac control.
1437 * @e: event message. Not used, to make it usable for fweh event dispatcher.
1438 * @data: not used.
1439 *
1440 */
1441int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
1442 const struct brcmf_event_msg *e,
1443 void *data)
1444{
1445 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1446 struct brcmf_p2p_info *p2p = &cfg->p2p;
1447
1448 brcmf_dbg(INFO, "Enter: event %s, status=%d\n",
1449 e->event_code == BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE ?
1450 "ACTION_FRAME_OFF_CHAN_COMPLETE" : "ACTION_FRAME_COMPLETE",
1451 e->status);
1452
1453 if (!test_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status))
1454 return 0;
1455
1456 if (e->event_code == BRCMF_E_ACTION_FRAME_COMPLETE) {
1457 if (e->status == BRCMF_E_STATUS_SUCCESS)
1458 set_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED,
1459 &p2p->status);
1460 else {
1461 set_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
1462 /* If there is no ack, we don't need to wait for
1463 * WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE event
1464 */
1465 brcmf_p2p_stop_wait_next_action_frame(cfg);
1466 }
1467
1468 } else {
1469 complete(&p2p->send_af_done);
1470 }
1471 return 0;
1472}
1473
1474
1475/**
1476 * brcmf_p2p_tx_action_frame() - send action frame over fil.
1477 *
1478 * @p2p: p2p info struct for vif.
1479 * @af_params: action frame data/info.
1480 *
1481 * Send an action frame immediately without doing channel synchronization.
1482 *
1483 * This function waits for a completion event before returning.
1484 * The WLC_E_ACTION_FRAME_COMPLETE event will be received when the action
1485 * frame is transmitted.
1486 */
1487static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
1488 struct brcmf_fil_af_params_le *af_params)
1489{
1490 struct brcmf_cfg80211_vif *vif;
1491 s32 err = 0;
1492 s32 timeout = 0;
1493
1494 brcmf_dbg(TRACE, "Enter\n");
1495
1496 INIT_COMPLETION(p2p->send_af_done);
1497 clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status);
1498 clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
1499
1500 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
1501 err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params,
1502 sizeof(*af_params));
1503 if (err) {
1504 brcmf_err(" sending action frame has failed\n");
1505 goto exit;
1506 }
1507
1508 p2p->af_sent_channel = le32_to_cpu(af_params->channel);
1509 p2p->af_tx_sent_jiffies = jiffies;
1510
1511 timeout = wait_for_completion_timeout(&p2p->send_af_done,
1512 msecs_to_jiffies(P2P_AF_MAX_WAIT_TIME));
1513
1514 if (test_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status)) {
1515 brcmf_dbg(TRACE, "TX action frame operation is success\n");
1516 } else {
1517 err = -EIO;
1518 brcmf_dbg(TRACE, "TX action frame operation has failed\n");
1519 }
1520 /* clear status bit for action tx */
1521 clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status);
1522 clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
1523
1524exit:
1525 return err;
1526}
1527
1528
1529/**
1530 * brcmf_p2p_pub_af_tx() - public action frame tx routine.
1531 *
1532 * @cfg: driver private data for cfg80211 interface.
1533 * @af_params: action frame data/info.
1534 * @config_af_params: configuration data for action frame.
1535 *
1536 * routine which transmits ation frame public type.
1537 */
1538static s32 brcmf_p2p_pub_af_tx(struct brcmf_cfg80211_info *cfg,
1539 struct brcmf_fil_af_params_le *af_params,
1540 struct brcmf_config_af_params *config_af_params)
1541{
1542 struct brcmf_p2p_info *p2p = &cfg->p2p;
1543 struct brcmf_fil_action_frame_le *action_frame;
1544 struct brcmf_p2p_pub_act_frame *act_frm;
1545 s32 err = 0;
1546 u16 ie_len;
1547
1548 action_frame = &af_params->action_frame;
1549 act_frm = (struct brcmf_p2p_pub_act_frame *)(action_frame->data);
1550
1551 config_af_params->extra_listen = true;
1552
1553 switch (act_frm->subtype) {
1554 case P2P_PAF_GON_REQ:
1555 brcmf_dbg(TRACE, "P2P: GO_NEG_PHASE status set\n");
1556 set_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
1557 config_af_params->mpc_onoff = 0;
1558 config_af_params->search_channel = true;
1559 p2p->next_af_subtype = act_frm->subtype + 1;
1560 p2p->gon_req_action = true;
1561 /* increase dwell time to wait for RESP frame */
1562 af_params->dwell_time = cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1563 break;
1564 case P2P_PAF_GON_RSP:
1565 p2p->next_af_subtype = act_frm->subtype + 1;
1566 /* increase dwell time to wait for CONF frame */
1567 af_params->dwell_time = cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1568 break;
1569 case P2P_PAF_GON_CONF:
1570 /* If we reached till GO Neg confirmation reset the filter */
1571 brcmf_dbg(TRACE, "P2P: GO_NEG_PHASE status cleared\n");
1572 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
1573 /* turn on mpc again if go nego is done */
1574 config_af_params->mpc_onoff = 1;
1575 /* minimize dwell time */
1576 af_params->dwell_time = cpu_to_le32(P2P_AF_MIN_DWELL_TIME);
1577 config_af_params->extra_listen = false;
1578 break;
1579 case P2P_PAF_INVITE_REQ:
1580 config_af_params->search_channel = true;
1581 p2p->next_af_subtype = act_frm->subtype + 1;
1582 /* increase dwell time */
1583 af_params->dwell_time = cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1584 break;
1585 case P2P_PAF_INVITE_RSP:
1586 /* minimize dwell time */
1587 af_params->dwell_time = cpu_to_le32(P2P_AF_MIN_DWELL_TIME);
1588 config_af_params->extra_listen = false;
1589 break;
1590 case P2P_PAF_DEVDIS_REQ:
1591 config_af_params->search_channel = true;
1592 p2p->next_af_subtype = act_frm->subtype + 1;
1593 /* maximize dwell time to wait for RESP frame */
1594 af_params->dwell_time = cpu_to_le32(P2P_AF_LONG_DWELL_TIME);
1595 break;
1596 case P2P_PAF_DEVDIS_RSP:
1597 /* minimize dwell time */
1598 af_params->dwell_time = cpu_to_le32(P2P_AF_MIN_DWELL_TIME);
1599 config_af_params->extra_listen = false;
1600 break;
1601 case P2P_PAF_PROVDIS_REQ:
1602 ie_len = le16_to_cpu(action_frame->len) -
1603 offsetof(struct brcmf_p2p_pub_act_frame, elts);
1604 if (cfg80211_get_p2p_attr(&act_frm->elts[0], ie_len,
1605 IEEE80211_P2P_ATTR_GROUP_ID,
1606 NULL, 0) < 0)
1607 config_af_params->search_channel = true;
1608 config_af_params->mpc_onoff = 0;
1609 p2p->next_af_subtype = act_frm->subtype + 1;
1610 /* increase dwell time to wait for RESP frame */
1611 af_params->dwell_time = cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1612 break;
1613 case P2P_PAF_PROVDIS_RSP:
1614 /* wpa_supplicant send go nego req right after prov disc */
1615 p2p->next_af_subtype = P2P_PAF_GON_REQ;
1616 /* increase dwell time to MED level */
1617 af_params->dwell_time = cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1618 config_af_params->extra_listen = false;
1619 break;
1620 default:
1621 brcmf_err("Unknown p2p pub act frame subtype: %d\n",
1622 act_frm->subtype);
1623 err = -EINVAL;
1624 }
1625 return err;
1626}
1627
1628/**
1629 * brcmf_p2p_send_action_frame() - send action frame .
1630 *
1631 * @cfg: driver private data for cfg80211 interface.
1632 * @ndev: net device to transmit on.
1633 * @af_params: configuration data for action frame.
1634 */
1635bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
1636 struct net_device *ndev,
1637 struct brcmf_fil_af_params_le *af_params)
1638{
1639 struct brcmf_p2p_info *p2p = &cfg->p2p;
1640 struct brcmf_fil_action_frame_le *action_frame;
1641 struct brcmf_config_af_params config_af_params;
1642 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1643 u16 action_frame_len;
1644 bool ack = false;
1645 u8 category;
1646 u8 action;
1647 s32 tx_retry;
1648 s32 extra_listen_time;
1649 uint delta_ms;
1650
1651 action_frame = &af_params->action_frame;
1652 action_frame_len = le16_to_cpu(action_frame->len);
1653
1654 brcmf_p2p_print_actframe(true, action_frame->data, action_frame_len);
1655
1656 /* Add the default dwell time. Dwell time to stay off-channel */
1657 /* to wait for a response action frame after transmitting an */
1658 /* GO Negotiation action frame */
1659 af_params->dwell_time = cpu_to_le32(P2P_AF_DWELL_TIME);
1660
1661 category = action_frame->data[DOT11_ACTION_CAT_OFF];
1662 action = action_frame->data[DOT11_ACTION_ACT_OFF];
1663
1664 /* initialize variables */
1665 p2p->next_af_subtype = P2P_PAF_SUBTYPE_INVALID;
1666 p2p->gon_req_action = false;
1667
1668 /* config parameters */
1669 config_af_params.mpc_onoff = -1;
1670 config_af_params.search_channel = false;
1671 config_af_params.extra_listen = false;
1672
1673 if (brcmf_p2p_is_pub_action(action_frame->data, action_frame_len)) {
1674 /* p2p public action frame process */
1675 if (brcmf_p2p_pub_af_tx(cfg, af_params, &config_af_params)) {
1676 /* Just send unknown subtype frame with */
1677 /* default parameters. */
1678 brcmf_err("P2P Public action frame, unknown subtype.\n");
1679 }
1680 } else if (brcmf_p2p_is_gas_action(action_frame->data,
1681 action_frame_len)) {
1682 /* service discovery process */
1683 if (action == P2PSD_ACTION_ID_GAS_IREQ ||
1684 action == P2PSD_ACTION_ID_GAS_CREQ) {
1685 /* configure service discovery query frame */
1686 config_af_params.search_channel = true;
1687
1688 /* save next af suptype to cancel */
1689 /* remaining dwell time */
1690 p2p->next_af_subtype = action + 1;
1691
1692 af_params->dwell_time =
1693 cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1694 } else if (action == P2PSD_ACTION_ID_GAS_IRESP ||
1695 action == P2PSD_ACTION_ID_GAS_CRESP) {
1696 /* configure service discovery response frame */
1697 af_params->dwell_time =
1698 cpu_to_le32(P2P_AF_MIN_DWELL_TIME);
1699 } else {
1700 brcmf_err("Unknown action type: %d\n", action);
1701 goto exit;
1702 }
1703 } else if (brcmf_p2p_is_p2p_action(action_frame->data,
1704 action_frame_len)) {
1705 /* do not configure anything. it will be */
1706 /* sent with a default configuration */
1707 } else {
1708 brcmf_err("Unknown Frame: category 0x%x, action 0x%x\n",
1709 category, action);
1710 return false;
1711 }
1712
1713 /* if connecting on primary iface, sleep for a while before sending
1714 * af tx for VSDB
1715 */
1716 if (test_bit(BRCMF_VIF_STATUS_CONNECTING,
1717 &p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->sme_state))
1718 msleep(50);
1719
1720 /* if scan is ongoing, abort current scan. */
1721 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
1722 brcmf_abort_scanning(cfg);
1723
1724 memcpy(afx_hdl->tx_dst_addr, action_frame->da, ETH_ALEN);
1725
1726 /* To make sure to send successfully action frame, turn off mpc */
1727 if (config_af_params.mpc_onoff == 0)
1728 brcmf_set_mpc(ndev, 0);
1729
1730 /* set status and destination address before sending af */
1731 if (p2p->next_af_subtype != P2P_PAF_SUBTYPE_INVALID) {
1732 /* set status to cancel the remained dwell time in rx process */
1733 set_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status);
1734 }
1735
1736 p2p->af_sent_channel = 0;
1737 set_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status);
1738 /* validate channel and p2p ies */
1739 if (config_af_params.search_channel &&
1740 IS_P2P_SOCIAL_CHANNEL(le32_to_cpu(af_params->channel)) &&
1741 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->saved_ie.probe_req_ie_len) {
1742 afx_hdl = &p2p->afx_hdl;
1743 afx_hdl->peer_listen_chan = le32_to_cpu(af_params->channel);
1744
1745 if (brcmf_p2p_af_searching_channel(p2p) ==
1746 P2P_INVALID_CHANNEL) {
1747 brcmf_err("Couldn't find peer's channel.\n");
1748 goto exit;
1749 }
1750
1751 /* Abort scan even for VSDB scenarios. Scan gets aborted in
1752 * firmware but after the check of piggyback algorithm. To take
1753 * care of current piggback algo, lets abort the scan here
1754 * itself.
1755 */
1756 brcmf_notify_escan_complete(cfg, ndev, true, true);
1757
1758 /* update channel */
1759 af_params->channel = cpu_to_le32(afx_hdl->peer_chan);
1760 }
1761
1762 tx_retry = 0;
1763 while (!p2p->block_gon_req_tx &&
1764 (ack == false) && (tx_retry < P2P_AF_TX_MAX_RETRY)) {
1765 ack = !brcmf_p2p_tx_action_frame(p2p, af_params);
1766 tx_retry++;
1767 }
1768 if (ack == false) {
1769 brcmf_err("Failed to send Action Frame(retry %d)\n", tx_retry);
1770 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
1771 }
1772
1773exit:
1774 clear_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status);
1775
1776 /* WAR: sometimes dongle does not keep the dwell time of 'actframe'.
1777 * if we coundn't get the next action response frame and dongle does
1778 * not keep the dwell time, go to listen state again to get next action
1779 * response frame.
1780 */
1781 if (ack && config_af_params.extra_listen && !p2p->block_gon_req_tx &&
1782 test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status) &&
1783 p2p->af_sent_channel == afx_hdl->my_listen_chan) {
1784 delta_ms = jiffies_to_msecs(jiffies - p2p->af_tx_sent_jiffies);
1785 if (le32_to_cpu(af_params->dwell_time) > delta_ms)
1786 extra_listen_time = le32_to_cpu(af_params->dwell_time) -
1787 delta_ms;
1788 else
1789 extra_listen_time = 0;
1790 if (extra_listen_time > 50) {
1791 set_bit(BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
1792 &p2p->status);
1793 brcmf_dbg(INFO, "Wait more time! actual af time:%d, calculated extra listen:%d\n",
1794 le32_to_cpu(af_params->dwell_time),
1795 extra_listen_time);
1796 extra_listen_time += 100;
1797 if (!brcmf_p2p_discover_listen(p2p,
1798 p2p->af_sent_channel,
1799 extra_listen_time)) {
1800 unsigned long duration;
1801
1802 extra_listen_time += 100;
1803 duration = msecs_to_jiffies(extra_listen_time);
1804 wait_for_completion_timeout(&p2p->wait_next_af,
1805 duration);
1806 }
1807 clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
1808 &p2p->status);
1809 }
1810 }
1811
1812 if (p2p->block_gon_req_tx) {
1813 /* if ack is true, supplicant will wait more time(100ms).
1814 * so we will return it as a success to get more time .
1815 */
1816 p2p->block_gon_req_tx = false;
1817 ack = true;
1818 }
1819
1820 clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status);
1821 /* if all done, turn mpc on again */
1822 if (config_af_params.mpc_onoff == 1)
1823 brcmf_set_mpc(ndev, 1);
1824
1825 return ack;
1826}
1827
1828/**
1829 * brcmf_p2p_notify_rx_mgmt_p2p_probereq() - Event handler for p2p probe req.
1830 *
1831 * @ifp: interface pointer for which event was received.
1832 * @e: even message.
1833 * @data: payload of event message (probe request).
1834 */
1835s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
1836 const struct brcmf_event_msg *e,
1837 void *data)
1838{
1839 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1840 struct brcmf_p2p_info *p2p = &cfg->p2p;
1841 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1842 struct wireless_dev *wdev;
1843 struct brcmf_cfg80211_vif *vif = ifp->vif;
1844 struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data;
1845 u16 chanspec = be16_to_cpu(rxframe->chanspec);
1846 u8 *mgmt_frame;
1847 u32 mgmt_frame_len;
1848 s32 freq;
1849 u16 mgmt_type;
1850
1851 brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code,
1852 e->reason);
1853
1854 if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) &&
1855 (memcmp(afx_hdl->tx_dst_addr, e->addr, ETH_ALEN) == 0)) {
1856 afx_hdl->peer_chan = CHSPEC_CHANNEL(chanspec);
1857 brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n",
1858 afx_hdl->peer_chan);
1859 complete(&afx_hdl->act_frm_scan);
1860 }
1861
1862 /* Firmware sends us two proberesponses for each idx one. At the */
1863 /* moment anything but bsscfgidx 0 is passed up to supplicant */
1864 if (e->bsscfgidx == 0)
1865 return 0;
1866
1867 /* Filter any P2P probe reqs arriving during the GO-NEG Phase */
1868 if (test_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status)) {
1869 brcmf_dbg(INFO, "Filtering P2P probe_req in GO-NEG phase\n");
1870 return 0;
1871 }
1872
1873 /* Check if wpa_supplicant has registered for this frame */
1874 brcmf_dbg(INFO, "vif->mgmt_rx_reg %04x\n", vif->mgmt_rx_reg);
1875 mgmt_type = (IEEE80211_STYPE_PROBE_REQ & IEEE80211_FCTL_STYPE) >> 4;
1876 if ((vif->mgmt_rx_reg & BIT(mgmt_type)) == 0)
1877 return 0;
1878
1879 mgmt_frame = (u8 *)(rxframe + 1);
1880 mgmt_frame_len = e->datalen - sizeof(*rxframe);
1881 freq = ieee80211_channel_to_frequency(CHSPEC_CHANNEL(chanspec),
1882 CHSPEC_IS2G(chanspec) ?
1883 IEEE80211_BAND_2GHZ :
1884 IEEE80211_BAND_5GHZ);
1885 wdev = ifp->ndev->ieee80211_ptr;
1886 cfg80211_rx_mgmt(wdev, freq, 0, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
1887
1888 brcmf_dbg(INFO, "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n",
1889 mgmt_frame_len, e->datalen, chanspec, freq);
1890
1891 return 0;
1892}
1893
1894
1895/**
1896 * brcmf_p2p_attach() - attach for P2P.
1897 *
1898 * @cfg: driver private data for cfg80211 interface.
1899 */
1900s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
1901{
1902 struct brcmf_if *pri_ifp;
1903 struct brcmf_if *p2p_ifp;
1904 struct brcmf_cfg80211_vif *p2p_vif;
1905 struct brcmf_p2p_info *p2p;
1906 struct brcmf_pub *drvr;
1907 s32 bssidx;
1908 s32 err = 0;
1909
1910 p2p = &cfg->p2p;
1911 p2p->cfg = cfg;
1912
1913 drvr = cfg->pub;
1914
1915 pri_ifp = drvr->iflist[0];
1916 p2p_ifp = drvr->iflist[1];
1917
1918 p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
1919
1920 if (p2p_ifp) {
1921 p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE,
1922 false);
1923 if (IS_ERR(p2p_vif)) {
1924 brcmf_err("could not create discovery vif\n");
1925 err = -ENOMEM;
1926 goto exit;
1927 }
1928
1929 p2p_vif->ifp = p2p_ifp;
1930 p2p_ifp->vif = p2p_vif;
1931 p2p_vif->wdev.netdev = p2p_ifp->ndev;
1932 p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev;
1933 SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy));
1934
1935 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
1936
1937 brcmf_p2p_generate_bss_mac(p2p);
1938 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
1939
1940 /* Initialize P2P Discovery in the firmware */
1941 err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
1942 if (err < 0) {
1943 brcmf_err("set p2p_disc error\n");
1944 brcmf_free_vif(p2p_vif);
1945 goto exit;
1946 }
1947 /* obtain bsscfg index for P2P discovery */
1948 err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
1949 if (err < 0) {
1950 brcmf_err("retrieving discover bsscfg index failed\n");
1951 brcmf_free_vif(p2p_vif);
1952 goto exit;
1953 }
1954 /* Verify that firmware uses same bssidx as driver !! */
1955 if (p2p_ifp->bssidx != bssidx) {
1956 brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
1957 bssidx, p2p_ifp->bssidx);
1958 brcmf_free_vif(p2p_vif);
1959 goto exit;
1960 }
1961
1962 init_completion(&p2p->send_af_done);
1963 INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
1964 init_completion(&p2p->afx_hdl.act_frm_scan);
1965 init_completion(&p2p->wait_next_af);
1966 }
1967exit:
1968 return err;
1969}
1970
1971
1972/**
1973 * brcmf_p2p_detach() - detach P2P.
1974 *
1975 * @p2p: P2P specific data.
1976 */
1977void brcmf_p2p_detach(struct brcmf_p2p_info *p2p)
1978{
1979 struct brcmf_cfg80211_vif *vif;
1980
1981 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
1982 if (vif != NULL) {
1983 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
1984 brcmf_p2p_deinit_discovery(p2p);
1985 /* remove discovery interface */
1986 brcmf_free_vif(vif);
1987 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
1988 }
1989 /* just set it all to zero */
1990 memset(p2p, 0, sizeof(*p2p));
1991}
1992
1993/**
1994 * brcmf_p2p_get_current_chanspec() - Get current operation channel.
1995 *
1996 * @p2p: P2P specific data.
1997 * @chanspec: chanspec to be returned.
1998 */
1999static void brcmf_p2p_get_current_chanspec(struct brcmf_p2p_info *p2p,
2000 u16 *chanspec)
2001{
2002 struct brcmf_if *ifp;
2003 struct brcmf_fil_chan_info_le ci;
2004 s32 err;
2005
2006 ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
2007
2008 *chanspec = 11 & WL_CHANSPEC_CHAN_MASK;
2009
2010 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, &ci, sizeof(ci));
2011 if (!err) {
2012 *chanspec = le32_to_cpu(ci.hw_channel) & WL_CHANSPEC_CHAN_MASK;
2013 if (*chanspec < CH_MAX_2G_CHANNEL)
2014 *chanspec |= WL_CHANSPEC_BAND_2G;
2015 else
2016 *chanspec |= WL_CHANSPEC_BAND_5G;
2017 }
2018 *chanspec |= WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
2019}
2020
2021/**
2022 * Change a P2P Role.
2023 * Parameters:
2024 * @mac: MAC address of the BSS to change a role
2025 * Returns 0 if success.
2026 */
2027int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
2028 enum brcmf_fil_p2p_if_types if_type)
2029{
2030 struct brcmf_p2p_info *p2p = &cfg->p2p;
2031 struct brcmf_cfg80211_vif *vif;
2032 struct brcmf_fil_p2p_if_le if_request;
2033 s32 err;
2034 u16 chanspec;
2035
2036 brcmf_dbg(TRACE, "Enter\n");
2037
2038 vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
2039 if (!vif) {
2040 brcmf_err("vif for P2PAPI_BSSCFG_PRIMARY does not exist\n");
2041 return -EPERM;
2042 }
2043 brcmf_notify_escan_complete(cfg, vif->ifp->ndev, true, true);
2044 vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif;
2045 if (!vif) {
2046 brcmf_err("vif for P2PAPI_BSSCFG_CONNECTION does not exist\n");
2047 return -EPERM;
2048 }
2049 brcmf_set_mpc(vif->ifp->ndev, 0);
2050
2051 /* In concurrency case, STA may be already associated in a particular */
2052 /* channel. so retrieve the current channel of primary interface and */
2053 /* then start the virtual interface on that. */
2054 brcmf_p2p_get_current_chanspec(p2p, &chanspec);
2055
2056 if_request.type = cpu_to_le16((u16)if_type);
2057 if_request.chspec = cpu_to_le16(chanspec);
2058 memcpy(if_request.addr, p2p->int_addr, sizeof(if_request.addr));
2059
2060 brcmf_cfg80211_arm_vif_event(cfg, vif);
2061 err = brcmf_fil_iovar_data_set(vif->ifp, "p2p_ifupd", &if_request,
2062 sizeof(if_request));
2063 if (err) {
2064 brcmf_err("p2p_ifupd FAILED, err=%d\n", err);
2065 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2066 return err;
2067 }
2068 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_CHANGE,
2069 msecs_to_jiffies(1500));
2070 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2071 if (!err) {
2072 brcmf_err("No BRCMF_E_IF_CHANGE event received\n");
2073 return -EIO;
2074 }
2075
2076 err = brcmf_fil_cmd_int_set(vif->ifp, BRCMF_C_SET_SCB_TIMEOUT,
2077 BRCMF_SCB_TIMEOUT_VALUE);
2078
2079 return err;
2080}
2081
2082static int brcmf_p2p_request_p2p_if(struct brcmf_p2p_info *p2p,
2083 struct brcmf_if *ifp, u8 ea[ETH_ALEN],
2084 enum brcmf_fil_p2p_if_types iftype)
2085{
2086 struct brcmf_fil_p2p_if_le if_request;
2087 int err;
2088 u16 chanspec;
2089
2090 /* we need a default channel */
2091 brcmf_p2p_get_current_chanspec(p2p, &chanspec);
2092
2093 /* fill the firmware request */
2094 memcpy(if_request.addr, ea, ETH_ALEN);
2095 if_request.type = cpu_to_le16((u16)iftype);
2096 if_request.chspec = cpu_to_le16(chanspec);
2097
2098 err = brcmf_fil_iovar_data_set(ifp, "p2p_ifadd", &if_request,
2099 sizeof(if_request));
2100 if (err)
2101 return err;
2102
2103 return err;
2104}
2105
2106static int brcmf_p2p_disable_p2p_if(struct brcmf_cfg80211_vif *vif)
2107{
2108 struct brcmf_cfg80211_info *cfg = wdev_to_cfg(&vif->wdev);
2109 struct net_device *pri_ndev = cfg_to_ndev(cfg);
2110 struct brcmf_if *ifp = netdev_priv(pri_ndev);
2111 u8 *addr = vif->wdev.netdev->dev_addr;
2112
2113 return brcmf_fil_iovar_data_set(ifp, "p2p_ifdis", addr, ETH_ALEN);
2114}
2115
2116static int brcmf_p2p_release_p2p_if(struct brcmf_cfg80211_vif *vif)
2117{
2118 struct brcmf_cfg80211_info *cfg = wdev_to_cfg(&vif->wdev);
2119 struct net_device *pri_ndev = cfg_to_ndev(cfg);
2120 struct brcmf_if *ifp = netdev_priv(pri_ndev);
2121 u8 *addr = vif->wdev.netdev->dev_addr;
2122
2123 return brcmf_fil_iovar_data_set(ifp, "p2p_ifdel", addr, ETH_ALEN);
2124}
2125
2126/**
2127 * brcmf_p2p_add_vif() - create a new P2P virtual interface.
2128 *
2129 * @wiphy: wiphy device of new interface.
2130 * @name: name of the new interface.
2131 * @type: nl80211 interface type.
2132 * @flags: TBD
2133 * @params: TBD
2134 */
2135struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2136 enum nl80211_iftype type, u32 *flags,
2137 struct vif_params *params)
2138{
2139 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2140 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
2141 struct brcmf_cfg80211_vif *vif;
2142 enum brcmf_fil_p2p_if_types iftype;
2143 enum wl_mode mode;
2144 int err;
2145
2146 if (brcmf_cfg80211_vif_event_armed(cfg))
2147 return ERR_PTR(-EBUSY);
2148
2149 brcmf_dbg(INFO, "adding vif \"%s\" (type=%d)\n", name, type);
2150
2151 switch (type) {
2152 case NL80211_IFTYPE_P2P_CLIENT:
2153 iftype = BRCMF_FIL_P2P_IF_CLIENT;
2154 mode = WL_MODE_BSS;
2155 break;
2156 case NL80211_IFTYPE_P2P_GO:
2157 iftype = BRCMF_FIL_P2P_IF_GO;
2158 mode = WL_MODE_AP;
2159 break;
2160 default:
2161 return ERR_PTR(-EOPNOTSUPP);
2162 }
2163
2164 vif = brcmf_alloc_vif(cfg, type, false);
2165 if (IS_ERR(vif))
2166 return (struct wireless_dev *)vif;
2167 brcmf_cfg80211_arm_vif_event(cfg, vif);
2168
2169 err = brcmf_p2p_request_p2p_if(&cfg->p2p, ifp, cfg->p2p.int_addr,
2170 iftype);
2171 if (err) {
2172 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2173 goto fail;
2174 }
2175
2176 /* wait for firmware event */
2177 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD,
2178 msecs_to_jiffies(1500));
2179 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2180 if (!err) {
2181 brcmf_err("timeout occurred\n");
2182 err = -EIO;
2183 goto fail;
2184 }
2185
2186 /* interface created in firmware */
2187 ifp = vif->ifp;
2188 if (!ifp) {
2189 brcmf_err("no if pointer provided\n");
2190 err = -ENOENT;
2191 goto fail;
2192 }
2193
2194 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
2195 err = brcmf_net_attach(ifp, true);
2196 if (err) {
2197 brcmf_err("Registering netdevice failed\n");
2198 goto fail;
2199 }
2200 cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
2201 /* Disable firmware roaming for P2P interface */
2202 brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
2203 if (iftype == BRCMF_FIL_P2P_IF_GO) {
2204 /* set station timeout for p2p */
2205 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCB_TIMEOUT,
2206 BRCMF_SCB_TIMEOUT_VALUE);
2207 }
2208 return &ifp->vif->wdev;
2209
2210fail:
2211 brcmf_free_vif(vif);
2212 return ERR_PTR(err);
2213}
2214
2215/**
2216 * brcmf_p2p_del_vif() - delete a P2P virtual interface.
2217 *
2218 * @wiphy: wiphy device of interface.
2219 * @wdev: wireless device of interface.
2220 *
2221 * TODO: not yet supported.
2222 */
2223int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2224{
2225 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
2226 struct brcmf_p2p_info *p2p = &cfg->p2p;
2227 struct brcmf_cfg80211_vif *vif;
2228 unsigned long jiffie_timeout = msecs_to_jiffies(1500);
2229 bool wait_for_disable = false;
2230 int err;
2231
2232 brcmf_dbg(TRACE, "delete P2P vif\n");
2233 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
2234
2235 switch (vif->wdev.iftype) {
2236 case NL80211_IFTYPE_P2P_CLIENT:
2237 if (test_bit(BRCMF_VIF_STATUS_DISCONNECTING, &vif->sme_state))
2238 wait_for_disable = true;
2239 break;
2240
2241 case NL80211_IFTYPE_P2P_GO:
2242 if (!brcmf_p2p_disable_p2p_if(vif))
2243 wait_for_disable = true;
2244 break;
2245
2246 case NL80211_IFTYPE_P2P_DEVICE:
2247 default:
2248 return -ENOTSUPP;
2249 break;
2250 }
2251
2252 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
2253 brcmf_dbg(INFO, "P2P: GO_NEG_PHASE status cleared\n");
2254
2255 if (wait_for_disable)
2256 wait_for_completion_timeout(&cfg->vif_disabled,
2257 msecs_to_jiffies(500));
2258
2259 brcmf_vif_clear_mgmt_ies(vif);
2260
2261 brcmf_cfg80211_arm_vif_event(cfg, vif);
2262 err = brcmf_p2p_release_p2p_if(vif);
2263 if (!err) {
2264 /* wait for firmware event */
2265 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL,
2266 jiffie_timeout);
2267 if (!err)
2268 err = -EIO;
2269 else
2270 err = 0;
2271 }
2272 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2273 brcmf_free_vif(vif);
2274 p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
2275
2276 return err;
2277}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.h b/drivers/net/wireless/brcm80211/brcmfmac/p2p.h
new file mode 100644
index 000000000000..6821b26224be
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.h
@@ -0,0 +1,183 @@
1/*
2 * Copyright (c) 2012 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef WL_CFGP2P_H_
17#define WL_CFGP2P_H_
18
19#include <net/cfg80211.h>
20
21struct brcmf_cfg80211_info;
22
23/**
24 * enum p2p_bss_type - different type of BSS configurations.
25 *
26 * @P2PAPI_BSSCFG_PRIMARY: maps to driver's primary bsscfg.
27 * @P2PAPI_BSSCFG_DEVICE: maps to driver's P2P device discovery bsscfg.
28 * @P2PAPI_BSSCFG_CONNECTION: maps to driver's P2P connection bsscfg.
29 * @P2PAPI_BSSCFG_MAX: used for range checking.
30 */
31enum p2p_bss_type {
32 P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
33 P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */
34 P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */
35 P2PAPI_BSSCFG_MAX
36};
37
38/**
39 * struct p2p_bss - peer-to-peer bss related information.
40 *
41 * @vif: virtual interface of this P2P bss.
42 * @private_data: TBD
43 */
44struct p2p_bss {
45 struct brcmf_cfg80211_vif *vif;
46 void *private_data;
47};
48
49/**
50 * enum brcmf_p2p_status - P2P specific dongle status.
51 *
52 * @BRCMF_P2P_STATUS_IF_ADD: peer-to-peer vif add sent to dongle.
53 * @BRCMF_P2P_STATUS_IF_DEL: NOT-USED?
54 * @BRCMF_P2P_STATUS_IF_DELETING: peer-to-peer vif delete sent to dongle.
55 * @BRCMF_P2P_STATUS_IF_CHANGING: peer-to-peer vif change sent to dongle.
56 * @BRCMF_P2P_STATUS_IF_CHANGED: peer-to-peer vif change completed on dongle.
57 * @BRCMF_P2P_STATUS_ACTION_TX_COMPLETED: action frame tx completed.
58 * @BRCMF_P2P_STATUS_ACTION_TX_NOACK: action frame tx not acked.
59 * @BRCMF_P2P_STATUS_GO_NEG_PHASE: P2P GO negotiation ongoing.
60 * @BRCMF_P2P_STATUS_DISCOVER_LISTEN: P2P listen, remaining on channel.
61 * @BRCMF_P2P_STATUS_SENDING_ACT_FRAME: In the process of sending action frame.
62 * @BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN: extra listen time for af tx.
63 * @BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME: waiting for action frame response.
64 * @BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL: search channel for AF active.
65 */
66enum brcmf_p2p_status {
67 BRCMF_P2P_STATUS_ENABLED,
68 BRCMF_P2P_STATUS_IF_ADD,
69 BRCMF_P2P_STATUS_IF_DEL,
70 BRCMF_P2P_STATUS_IF_DELETING,
71 BRCMF_P2P_STATUS_IF_CHANGING,
72 BRCMF_P2P_STATUS_IF_CHANGED,
73 BRCMF_P2P_STATUS_ACTION_TX_COMPLETED,
74 BRCMF_P2P_STATUS_ACTION_TX_NOACK,
75 BRCMF_P2P_STATUS_GO_NEG_PHASE,
76 BRCMF_P2P_STATUS_DISCOVER_LISTEN,
77 BRCMF_P2P_STATUS_SENDING_ACT_FRAME,
78 BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
79 BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME,
80 BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL
81};
82
83/**
84 * struct afx_hdl - action frame off channel storage.
85 *
86 * @afx_work: worker thread for searching channel
87 * @act_frm_scan: thread synchronizing struct.
88 * @is_active: channel searching active.
89 * @peer_chan: current channel.
90 * @is_listen: sets mode for afx worker.
91 * @my_listen_chan: this peers listen channel.
92 * @peer_listen_chan: remote peers listen channel.
93 * @tx_dst_addr: mac address where tx af should be sent to.
94 */
95struct afx_hdl {
96 struct work_struct afx_work;
97 struct completion act_frm_scan;
98 bool is_active;
99 s32 peer_chan;
100 bool is_listen;
101 u16 my_listen_chan;
102 u16 peer_listen_chan;
103 u8 tx_dst_addr[ETH_ALEN];
104};
105
106/**
107 * struct brcmf_p2p_info - p2p specific driver information.
108 *
109 * @cfg: driver private data for cfg80211 interface.
110 * @status: status of P2P (see enum brcmf_p2p_status).
111 * @dev_addr: P2P device address.
112 * @int_addr: P2P interface address.
113 * @bss_idx: informate for P2P bss types.
114 * @listen_timer: timer for @WL_P2P_DISC_ST_LISTEN discover state.
115 * @ssid: ssid for P2P GO.
116 * @listen_channel: channel for @WL_P2P_DISC_ST_LISTEN discover state.
117 * @remain_on_channel: contains copy of struct used by cfg80211.
118 * @remain_on_channel_cookie: cookie counter for remain on channel cmd
119 * @next_af_subtype: expected action frame subtype.
120 * @send_af_done: indication that action frame tx is complete.
121 * @afx_hdl: action frame search handler info.
122 * @af_sent_channel: channel action frame is sent.
123 * @af_tx_sent_jiffies: jiffies time when af tx was transmitted.
124 * @wait_next_af: thread synchronizing struct.
125 * @gon_req_action: about to send go negotiation requets frame.
126 * @block_gon_req_tx: drop tx go negotiation requets frame.
127 */
128struct brcmf_p2p_info {
129 struct brcmf_cfg80211_info *cfg;
130 unsigned long status;
131 u8 dev_addr[ETH_ALEN];
132 u8 int_addr[ETH_ALEN];
133 struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX];
134 struct timer_list listen_timer;
135 struct brcmf_ssid ssid;
136 u8 listen_channel;
137 struct ieee80211_channel remain_on_channel;
138 u32 remain_on_channel_cookie;
139 u8 next_af_subtype;
140 struct completion send_af_done;
141 struct afx_hdl afx_hdl;
142 u32 af_sent_channel;
143 unsigned long af_tx_sent_jiffies;
144 struct completion wait_next_af;
145 bool gon_req_action;
146 bool block_gon_req_tx;
147};
148
149s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg);
150void brcmf_p2p_detach(struct brcmf_p2p_info *p2p);
151struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
152 enum nl80211_iftype type, u32 *flags,
153 struct vif_params *params);
154int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev);
155int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
156 enum brcmf_fil_p2p_if_types if_type);
157int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev);
158void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev);
159int brcmf_p2p_scan_prep(struct wiphy *wiphy,
160 struct cfg80211_scan_request *request,
161 struct brcmf_cfg80211_vif *vif);
162int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
163 struct ieee80211_channel *channel,
164 unsigned int duration, u64 *cookie);
165int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp,
166 const struct brcmf_event_msg *e,
167 void *data);
168void brcmf_p2p_cancel_remain_on_channel(struct brcmf_if *ifp);
169int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
170 const struct brcmf_event_msg *e,
171 void *data);
172int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
173 const struct brcmf_event_msg *e,
174 void *data);
175bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
176 struct net_device *ndev,
177 struct brcmf_fil_af_params_le *af_params);
178bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,
179 struct brcmf_bss_info_le *bi);
180s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
181 const struct brcmf_event_msg *e,
182 void *data);
183#endif /* WL_CFGP2P_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index e15630cc3889..a55994d33763 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -421,10 +421,6 @@ static void brcmf_usb_tx_complete(struct urb *urb)
421 brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status, 421 brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status,
422 req->skb); 422 req->skb);
423 brcmf_usb_del_fromq(devinfo, req); 423 brcmf_usb_del_fromq(devinfo, req);
424 if (urb->status == 0)
425 devinfo->bus_pub.bus->dstats.tx_packets++;
426 else
427 devinfo->bus_pub.bus->dstats.tx_errors++;
428 424
429 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0); 425 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
430 426
@@ -451,10 +447,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
451 req->skb = NULL; 447 req->skb = NULL;
452 448
453 /* zero lenght packets indicate usb "failure". Do not refill */ 449 /* zero lenght packets indicate usb "failure". Do not refill */
454 if (urb->status == 0 && urb->actual_length) { 450 if (urb->status != 0 || !urb->actual_length) {
455 devinfo->bus_pub.bus->dstats.rx_packets++;
456 } else {
457 devinfo->bus_pub.bus->dstats.rx_errors++;
458 brcmu_pkt_buf_free_skb(skb); 451 brcmu_pkt_buf_free_skb(skb);
459 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL); 452 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
460 return; 453 return;
@@ -1257,6 +1250,8 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1257 bus->bus_priv.usb = bus_pub; 1250 bus->bus_priv.usb = bus_pub;
1258 dev_set_drvdata(dev, bus); 1251 dev_set_drvdata(dev, bus);
1259 bus->ops = &brcmf_usb_bus_ops; 1252 bus->ops = &brcmf_usb_bus_ops;
1253 bus->chip = bus_pub->devid;
1254 bus->chiprev = bus_pub->chiprev;
1260 1255
1261 /* Attach to the common driver interface */ 1256 /* Attach to the common driver interface */
1262 ret = brcmf_attach(0, dev); 1257 ret = brcmf_attach(0, dev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 62a528e8b958..481f41ad7989 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -26,6 +26,8 @@
26#include <brcmu_wifi.h> 26#include <brcmu_wifi.h>
27#include "dhd.h" 27#include "dhd.h"
28#include "dhd_dbg.h" 28#include "dhd_dbg.h"
29#include "fwil_types.h"
30#include "p2p.h"
29#include "wl_cfg80211.h" 31#include "wl_cfg80211.h"
30#include "fwil.h" 32#include "fwil.h"
31 33
@@ -41,16 +43,13 @@
41#define BRCMF_PNO_SCAN_COMPLETE 1 43#define BRCMF_PNO_SCAN_COMPLETE 1
42#define BRCMF_PNO_SCAN_INCOMPLETE 0 44#define BRCMF_PNO_SCAN_INCOMPLETE 0
43 45
44#define BRCMF_IFACE_MAX_CNT 2 46#define BRCMF_IFACE_MAX_CNT 3
45 47
46#define TLV_LEN_OFF 1 /* length offset */
47#define TLV_HDR_LEN 2 /* header length */
48#define TLV_BODY_OFF 2 /* body offset */
49#define TLV_OUI_LEN 3 /* oui id length */
50#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ 48#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
51#define WPA_OUI_TYPE 1 49#define WPA_OUI_TYPE 1
52#define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */ 50#define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
53#define WME_OUI_TYPE 2 51#define WME_OUI_TYPE 2
52#define WPS_OUI_TYPE 4
54 53
55#define VS_IE_FIXED_HDR_LEN 6 54#define VS_IE_FIXED_HDR_LEN 6
56#define WPA_IE_VERSION_LEN 2 55#define WPA_IE_VERSION_LEN 2
@@ -76,13 +75,15 @@
76#define VNDR_IE_PKTFLAG_OFFSET 8 75#define VNDR_IE_PKTFLAG_OFFSET 8
77#define VNDR_IE_VSIE_OFFSET 12 76#define VNDR_IE_VSIE_OFFSET 12
78#define VNDR_IE_HDR_SIZE 12 77#define VNDR_IE_HDR_SIZE 12
79#define VNDR_IE_BEACON_FLAG 0x1 78#define VNDR_IE_PARSE_LIMIT 5
80#define VNDR_IE_PRBRSP_FLAG 0x2
81#define MAX_VNDR_IE_NUMBER 5
82 79
83#define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */ 80#define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
84#define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */ 81#define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
85 82
83#define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
84#define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
85#define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
86
86#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ 87#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
87 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16)) 88 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
88 89
@@ -271,13 +272,6 @@ static const u32 __wl_cipher_suites[] = {
271 WLAN_CIPHER_SUITE_AES_CMAC, 272 WLAN_CIPHER_SUITE_AES_CMAC,
272}; 273};
273 274
274/* tag_ID/length/value_buffer tuple */
275struct brcmf_tlv {
276 u8 id;
277 u8 len;
278 u8 data[1];
279};
280
281/* Vendor specific ie. id = 221, oui and type defines exact ie */ 275/* Vendor specific ie. id = 221, oui and type defines exact ie */
282struct brcmf_vs_tlv { 276struct brcmf_vs_tlv {
283 u8 id; 277 u8 id;
@@ -294,7 +288,7 @@ struct parsed_vndr_ie_info {
294 288
295struct parsed_vndr_ies { 289struct parsed_vndr_ies {
296 u32 count; 290 u32 count;
297 struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER]; 291 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
298}; 292};
299 293
300/* Quarter dBm units to mW 294/* Quarter dBm units to mW
@@ -381,7 +375,7 @@ static u8 brcmf_mw_to_qdbm(u16 mw)
381 return qdbm; 375 return qdbm;
382} 376}
383 377
384static u16 channel_to_chanspec(struct ieee80211_channel *ch) 378u16 channel_to_chanspec(struct ieee80211_channel *ch)
385{ 379{
386 u16 chanspec; 380 u16 chanspec;
387 381
@@ -393,19 +387,92 @@ static u16 channel_to_chanspec(struct ieee80211_channel *ch)
393 else 387 else
394 chanspec |= WL_CHANSPEC_BAND_5G; 388 chanspec |= WL_CHANSPEC_BAND_5G;
395 389
396 if (ch->flags & IEEE80211_CHAN_NO_HT40) { 390 chanspec |= WL_CHANSPEC_BW_20;
397 chanspec |= WL_CHANSPEC_BW_20; 391 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
398 chanspec |= WL_CHANSPEC_CTL_SB_NONE; 392
399 } else {
400 chanspec |= WL_CHANSPEC_BW_40;
401 if (ch->flags & IEEE80211_CHAN_NO_HT40PLUS)
402 chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
403 else
404 chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
405 }
406 return chanspec; 393 return chanspec;
407} 394}
408 395
396/* Traverse a string of 1-byte tag/1-byte length/variable-length value
397 * triples, returning a pointer to the substring whose first element
398 * matches tag
399 */
400struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
401{
402 struct brcmf_tlv *elt;
403 int totlen;
404
405 elt = (struct brcmf_tlv *)buf;
406 totlen = buflen;
407
408 /* find tagged parameter */
409 while (totlen >= TLV_HDR_LEN) {
410 int len = elt->len;
411
412 /* validate remaining totlen */
413 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
414 return elt;
415
416 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
417 totlen -= (len + TLV_HDR_LEN);
418 }
419
420 return NULL;
421}
422
423/* Is any of the tlvs the expected entry? If
424 * not update the tlvs buffer pointer/length.
425 */
426static bool
427brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
428 u8 *oui, u32 oui_len, u8 type)
429{
430 /* If the contents match the OUI and the type */
431 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
432 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
433 type == ie[TLV_BODY_OFF + oui_len]) {
434 return true;
435 }
436
437 if (tlvs == NULL)
438 return false;
439 /* point to the next ie */
440 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
441 /* calculate the length of the rest of the buffer */
442 *tlvs_len -= (int)(ie - *tlvs);
443 /* update the pointer to the start of the buffer */
444 *tlvs = ie;
445
446 return false;
447}
448
449static struct brcmf_vs_tlv *
450brcmf_find_wpaie(u8 *parse, u32 len)
451{
452 struct brcmf_tlv *ie;
453
454 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
455 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
456 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
457 return (struct brcmf_vs_tlv *)ie;
458 }
459 return NULL;
460}
461
462static struct brcmf_vs_tlv *
463brcmf_find_wpsie(u8 *parse, u32 len)
464{
465 struct brcmf_tlv *ie;
466
467 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
468 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
469 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
470 return (struct brcmf_vs_tlv *)ie;
471 }
472 return NULL;
473}
474
475
409static void convert_key_from_CPU(struct brcmf_wsec_key *key, 476static void convert_key_from_CPU(struct brcmf_wsec_key *key,
410 struct brcmf_wsec_key_le *key_le) 477 struct brcmf_wsec_key_le *key_le)
411{ 478{
@@ -438,11 +505,153 @@ send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
438 return err; 505 return err;
439} 506}
440 507
508static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
509 const char *name,
510 enum nl80211_iftype type,
511 u32 *flags,
512 struct vif_params *params)
513{
514 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
515 switch (type) {
516 case NL80211_IFTYPE_ADHOC:
517 case NL80211_IFTYPE_STATION:
518 case NL80211_IFTYPE_AP:
519 case NL80211_IFTYPE_AP_VLAN:
520 case NL80211_IFTYPE_WDS:
521 case NL80211_IFTYPE_MONITOR:
522 case NL80211_IFTYPE_MESH_POINT:
523 return ERR_PTR(-EOPNOTSUPP);
524 case NL80211_IFTYPE_P2P_CLIENT:
525 case NL80211_IFTYPE_P2P_GO:
526 return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
527 case NL80211_IFTYPE_UNSPECIFIED:
528 case NL80211_IFTYPE_P2P_DEVICE:
529 default:
530 return ERR_PTR(-EINVAL);
531 }
532}
533
534void brcmf_set_mpc(struct net_device *ndev, int mpc)
535{
536 struct brcmf_if *ifp = netdev_priv(ndev);
537 s32 err = 0;
538
539 if (check_vif_up(ifp->vif)) {
540 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
541 if (err) {
542 brcmf_err("fail to set mpc\n");
543 return;
544 }
545 brcmf_dbg(INFO, "MPC : %d\n", mpc);
546 }
547}
548
549s32
550brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
551 struct net_device *ndev,
552 bool aborted, bool fw_abort)
553{
554 struct brcmf_scan_params_le params_le;
555 struct cfg80211_scan_request *scan_request;
556 s32 err = 0;
557
558 brcmf_dbg(SCAN, "Enter\n");
559
560 /* clear scan request, because the FW abort can cause a second call */
561 /* to this functon and might cause a double cfg80211_scan_done */
562 scan_request = cfg->scan_request;
563 cfg->scan_request = NULL;
564
565 if (timer_pending(&cfg->escan_timeout))
566 del_timer_sync(&cfg->escan_timeout);
567
568 if (fw_abort) {
569 /* Do a scan abort to stop the driver's scan engine */
570 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
571 memset(&params_le, 0, sizeof(params_le));
572 memset(params_le.bssid, 0xFF, ETH_ALEN);
573 params_le.bss_type = DOT11_BSSTYPE_ANY;
574 params_le.scan_type = 0;
575 params_le.channel_num = cpu_to_le32(1);
576 params_le.nprobes = cpu_to_le32(1);
577 params_le.active_time = cpu_to_le32(-1);
578 params_le.passive_time = cpu_to_le32(-1);
579 params_le.home_time = cpu_to_le32(-1);
580 /* Scan is aborted by setting channel_list[0] to -1 */
581 params_le.channel_list[0] = cpu_to_le16(-1);
582 /* E-Scan (or anyother type) can be aborted by SCAN */
583 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
584 &params_le, sizeof(params_le));
585 if (err)
586 brcmf_err("Scan abort failed\n");
587 }
588 /*
589 * e-scan can be initiated by scheduled scan
590 * which takes precedence.
591 */
592 if (cfg->sched_escan) {
593 brcmf_dbg(SCAN, "scheduled scan completed\n");
594 cfg->sched_escan = false;
595 if (!aborted)
596 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
597 brcmf_set_mpc(ndev, 1);
598 } else if (scan_request) {
599 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
600 aborted ? "Aborted" : "Done");
601 cfg80211_scan_done(scan_request, aborted);
602 brcmf_set_mpc(ndev, 1);
603 }
604 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
605 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
606
607 return err;
608}
609
610static
611int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
612{
613 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
614 struct net_device *ndev = wdev->netdev;
615
616 /* vif event pending in firmware */
617 if (brcmf_cfg80211_vif_event_armed(cfg))
618 return -EBUSY;
619
620 if (ndev) {
621 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
622 cfg->escan_info.ndev == ndev)
623 brcmf_notify_escan_complete(cfg, ndev, true,
624 true);
625
626 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
627 }
628
629 switch (wdev->iftype) {
630 case NL80211_IFTYPE_ADHOC:
631 case NL80211_IFTYPE_STATION:
632 case NL80211_IFTYPE_AP:
633 case NL80211_IFTYPE_AP_VLAN:
634 case NL80211_IFTYPE_WDS:
635 case NL80211_IFTYPE_MONITOR:
636 case NL80211_IFTYPE_MESH_POINT:
637 return -EOPNOTSUPP;
638 case NL80211_IFTYPE_P2P_CLIENT:
639 case NL80211_IFTYPE_P2P_GO:
640 return brcmf_p2p_del_vif(wiphy, wdev);
641 case NL80211_IFTYPE_UNSPECIFIED:
642 case NL80211_IFTYPE_P2P_DEVICE:
643 default:
644 return -EINVAL;
645 }
646 return -EOPNOTSUPP;
647}
648
441static s32 649static s32
442brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, 650brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
443 enum nl80211_iftype type, u32 *flags, 651 enum nl80211_iftype type, u32 *flags,
444 struct vif_params *params) 652 struct vif_params *params)
445{ 653{
654 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
446 struct brcmf_if *ifp = netdev_priv(ndev); 655 struct brcmf_if *ifp = netdev_priv(ndev);
447 struct brcmf_cfg80211_vif *vif = ifp->vif; 656 struct brcmf_cfg80211_vif *vif = ifp->vif;
448 s32 infra = 0; 657 s32 infra = 0;
@@ -462,10 +671,23 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
462 infra = 0; 671 infra = 0;
463 break; 672 break;
464 case NL80211_IFTYPE_STATION: 673 case NL80211_IFTYPE_STATION:
674 /* Ignore change for p2p IF. Unclear why supplicant does this */
675 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
676 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
677 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
678 /* WAR: It is unexpected to get a change of VIF for P2P
679 * IF, but it happens. The request can not be handled
680 * but returning EPERM causes a crash. Returning 0
681 * without setting ieee80211_ptr->iftype causes trace
682 * (WARN_ON) but it works with wpa_supplicant
683 */
684 return 0;
685 }
465 vif->mode = WL_MODE_BSS; 686 vif->mode = WL_MODE_BSS;
466 infra = 1; 687 infra = 1;
467 break; 688 break;
468 case NL80211_IFTYPE_AP: 689 case NL80211_IFTYPE_AP:
690 case NL80211_IFTYPE_P2P_GO:
469 vif->mode = WL_MODE_AP; 691 vif->mode = WL_MODE_AP;
470 ap = 1; 692 ap = 1;
471 break; 693 break;
@@ -475,8 +697,14 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
475 } 697 }
476 698
477 if (ap) { 699 if (ap) {
478 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state); 700 if (type == NL80211_IFTYPE_P2P_GO) {
479 brcmf_dbg(INFO, "IF Type = AP\n"); 701 brcmf_dbg(INFO, "IF Type = P2P GO\n");
702 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
703 }
704 if (!err) {
705 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
706 brcmf_dbg(INFO, "IF Type = AP\n");
707 }
480 } else { 708 } else {
481 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra); 709 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
482 if (err) { 710 if (err) {
@@ -495,21 +723,6 @@ done:
495 return err; 723 return err;
496} 724}
497 725
498static void brcmf_set_mpc(struct net_device *ndev, int mpc)
499{
500 struct brcmf_if *ifp = netdev_priv(ndev);
501 s32 err = 0;
502
503 if (check_vif_up(ifp->vif)) {
504 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
505 if (err) {
506 brcmf_err("fail to set mpc\n");
507 return;
508 }
509 brcmf_dbg(INFO, "MPC : %d\n", mpc);
510 }
511}
512
513static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, 726static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
514 struct cfg80211_scan_request *request) 727 struct cfg80211_scan_request *request)
515{ 728{
@@ -590,69 +803,6 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
590} 803}
591 804
592static s32 805static s32
593brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
594 struct net_device *ndev,
595 bool aborted, bool fw_abort)
596{
597 struct brcmf_scan_params_le params_le;
598 struct cfg80211_scan_request *scan_request;
599 s32 err = 0;
600
601 brcmf_dbg(SCAN, "Enter\n");
602
603 /* clear scan request, because the FW abort can cause a second call */
604 /* to this functon and might cause a double cfg80211_scan_done */
605 scan_request = cfg->scan_request;
606 cfg->scan_request = NULL;
607
608 if (timer_pending(&cfg->escan_timeout))
609 del_timer_sync(&cfg->escan_timeout);
610
611 if (fw_abort) {
612 /* Do a scan abort to stop the driver's scan engine */
613 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
614 memset(&params_le, 0, sizeof(params_le));
615 memset(params_le.bssid, 0xFF, ETH_ALEN);
616 params_le.bss_type = DOT11_BSSTYPE_ANY;
617 params_le.scan_type = 0;
618 params_le.channel_num = cpu_to_le32(1);
619 params_le.nprobes = cpu_to_le32(1);
620 params_le.active_time = cpu_to_le32(-1);
621 params_le.passive_time = cpu_to_le32(-1);
622 params_le.home_time = cpu_to_le32(-1);
623 /* Scan is aborted by setting channel_list[0] to -1 */
624 params_le.channel_list[0] = cpu_to_le16(-1);
625 /* E-Scan (or anyother type) can be aborted by SCAN */
626 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
627 &params_le, sizeof(params_le));
628 if (err)
629 brcmf_err("Scan abort failed\n");
630 }
631 /*
632 * e-scan can be initiated by scheduled scan
633 * which takes precedence.
634 */
635 if (cfg->sched_escan) {
636 brcmf_dbg(SCAN, "scheduled scan completed\n");
637 cfg->sched_escan = false;
638 if (!aborted)
639 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
640 brcmf_set_mpc(ndev, 1);
641 } else if (scan_request) {
642 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
643 aborted ? "Aborted" : "Done");
644 cfg80211_scan_done(scan_request, aborted);
645 brcmf_set_mpc(ndev, 1);
646 }
647 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
648 brcmf_err("Scan complete while device not scanning\n");
649 return -EPERM;
650 }
651
652 return err;
653}
654
655static s32
656brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev, 806brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
657 struct cfg80211_scan_request *request, u16 action) 807 struct cfg80211_scan_request *request, u16 action)
658{ 808{
@@ -703,11 +853,12 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
703 s32 err; 853 s32 err;
704 u32 passive_scan; 854 u32 passive_scan;
705 struct brcmf_scan_results *results; 855 struct brcmf_scan_results *results;
856 struct escan_info *escan = &cfg->escan_info;
706 857
707 brcmf_dbg(SCAN, "Enter\n"); 858 brcmf_dbg(SCAN, "Enter\n");
708 cfg->escan_info.ndev = ndev; 859 escan->ndev = ndev;
709 cfg->escan_info.wiphy = wiphy; 860 escan->wiphy = wiphy;
710 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING; 861 escan->escan_state = WL_ESCAN_STATE_SCANNING;
711 passive_scan = cfg->active_scan ? 0 : 1; 862 passive_scan = cfg->active_scan ? 0 : 1;
712 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN, 863 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN,
713 passive_scan); 864 passive_scan);
@@ -721,7 +872,7 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
721 results->count = 0; 872 results->count = 0;
722 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE; 873 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
723 874
724 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START); 875 err = escan->run(cfg, ndev, request, WL_ESCAN_ACTION_START);
725 if (err) 876 if (err)
726 brcmf_set_mpc(ndev, 1); 877 brcmf_set_mpc(ndev, 1);
727 return err; 878 return err;
@@ -758,6 +909,12 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
758 return -EAGAIN; 909 return -EAGAIN;
759 } 910 }
760 911
912 /* If scan req comes for p2p0, send it over primary I/F */
913 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) {
914 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
915 ndev = ifp->ndev;
916 }
917
761 /* Arm scan timeout timer */ 918 /* Arm scan timeout timer */
762 mod_timer(&cfg->escan_timeout, jiffies + 919 mod_timer(&cfg->escan_timeout, jiffies +
763 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); 920 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
@@ -776,6 +933,11 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
776 cfg->scan_request = request; 933 cfg->scan_request = request;
777 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 934 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
778 if (escan_req) { 935 if (escan_req) {
936 cfg->escan_info.run = brcmf_run_escan;
937 err = brcmf_p2p_scan_prep(wiphy, request, ifp->vif);
938 if (err)
939 goto scan_out;
940
779 err = brcmf_do_escan(cfg, wiphy, ndev, request); 941 err = brcmf_do_escan(cfg, wiphy, ndev, request);
780 if (err) 942 if (err)
781 goto scan_out; 943 goto scan_out;
@@ -933,31 +1095,6 @@ static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
933 memset(prof, 0, sizeof(*prof)); 1095 memset(prof, 0, sizeof(*prof));
934} 1096}
935 1097
936static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
937 size_t *join_params_size)
938{
939 u16 chanspec = 0;
940
941 if (ch != 0) {
942 if (ch <= CH_MAX_2G_CHANNEL)
943 chanspec |= WL_CHANSPEC_BAND_2G;
944 else
945 chanspec |= WL_CHANSPEC_BAND_5G;
946
947 chanspec |= WL_CHANSPEC_BW_20;
948 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
949
950 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
951 sizeof(u16);
952
953 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
954 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
955 join_params->params_le.chanspec_num = cpu_to_le32(1);
956
957 brcmf_dbg(CONN, "channel %d, chanspec %#X\n", ch, chanspec);
958 }
959}
960
961static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) 1098static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
962{ 1099{
963 s32 err = 0; 1100 s32 err = 0;
@@ -988,6 +1125,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
988 s32 err = 0; 1125 s32 err = 0;
989 s32 wsec = 0; 1126 s32 wsec = 0;
990 s32 bcnprd; 1127 s32 bcnprd;
1128 u16 chanspec;
991 1129
992 brcmf_dbg(TRACE, "Enter\n"); 1130 brcmf_dbg(TRACE, "Enter\n");
993 if (!check_vif_up(ifp->vif)) 1131 if (!check_vif_up(ifp->vif))
@@ -1091,8 +1229,11 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1091 params->chandef.chan->center_freq); 1229 params->chandef.chan->center_freq);
1092 if (params->channel_fixed) { 1230 if (params->channel_fixed) {
1093 /* adding chanspec */ 1231 /* adding chanspec */
1094 brcmf_ch_to_chanspec(cfg->channel, 1232 chanspec = channel_to_chanspec(params->chandef.chan);
1095 &join_params, &join_params_size); 1233 join_params.params_le.chanspec_list[0] =
1234 cpu_to_le16(chanspec);
1235 join_params.params_le.chanspec_num = cpu_to_le32(1);
1236 join_params_size += sizeof(join_params.params_le);
1096 } 1237 }
1097 1238
1098 /* set channel for starter */ 1239 /* set channel for starter */
@@ -1155,7 +1296,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
1155 else 1296 else
1156 val = WPA_AUTH_DISABLED; 1297 val = WPA_AUTH_DISABLED;
1157 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val); 1298 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1158 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val); 1299 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1159 if (err) { 1300 if (err) {
1160 brcmf_err("set wpa_auth failed (%d)\n", err); 1301 brcmf_err("set wpa_auth failed (%d)\n", err);
1161 return err; 1302 return err;
@@ -1194,7 +1335,7 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
1194 break; 1335 break;
1195 } 1336 }
1196 1337
1197 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val); 1338 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1198 if (err) { 1339 if (err) {
1199 brcmf_err("set auth failed (%d)\n", err); 1340 brcmf_err("set auth failed (%d)\n", err);
1200 return err; 1341 return err;
@@ -1258,7 +1399,12 @@ brcmf_set_set_cipher(struct net_device *ndev,
1258 } 1399 }
1259 1400
1260 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval); 1401 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1261 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval); 1402 /* In case of privacy, but no security and WPS then simulate */
1403 /* setting AES. WPS-2.0 allows no security */
1404 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1405 sme->privacy)
1406 pval = AES_ENABLED;
1407 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
1262 if (err) { 1408 if (err) {
1263 brcmf_err("error (%d)\n", err); 1409 brcmf_err("error (%d)\n", err);
1264 return err; 1410 return err;
@@ -1280,8 +1426,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1280 s32 err = 0; 1426 s32 err = 0;
1281 1427
1282 if (sme->crypto.n_akm_suites) { 1428 if (sme->crypto.n_akm_suites) {
1283 err = brcmf_fil_iovar_int_get(netdev_priv(ndev), 1429 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1284 "wpa_auth", &val); 1430 "wpa_auth", &val);
1285 if (err) { 1431 if (err) {
1286 brcmf_err("could not get wpa_auth (%d)\n", err); 1432 brcmf_err("could not get wpa_auth (%d)\n", err);
1287 return err; 1433 return err;
@@ -1315,8 +1461,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1315 } 1461 }
1316 1462
1317 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val); 1463 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1318 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), 1464 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1319 "wpa_auth", val); 1465 "wpa_auth", val);
1320 if (err) { 1466 if (err) {
1321 brcmf_err("could not set wpa_auth (%d)\n", err); 1467 brcmf_err("could not set wpa_auth (%d)\n", err);
1322 return err; 1468 return err;
@@ -1393,9 +1539,28 @@ brcmf_set_sharedkey(struct net_device *ndev,
1393 return err; 1539 return err;
1394} 1540}
1395 1541
1542static
1543enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1544 enum nl80211_auth_type type)
1545{
1546 u32 ci;
1547 if (type == NL80211_AUTHTYPE_AUTOMATIC) {
1548 /* shift to ignore chip revision */
1549 ci = brcmf_get_chip_info(ifp) >> 4;
1550 switch (ci) {
1551 case 43236:
1552 brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1553 return NL80211_AUTHTYPE_OPEN_SYSTEM;
1554 default:
1555 break;
1556 }
1557 }
1558 return type;
1559}
1560
1396static s32 1561static s32
1397brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, 1562brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1398 struct cfg80211_connect_params *sme) 1563 struct cfg80211_connect_params *sme)
1399{ 1564{
1400 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 1565 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1401 struct brcmf_if *ifp = netdev_priv(ndev); 1566 struct brcmf_if *ifp = netdev_priv(ndev);
@@ -1403,7 +1568,12 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1403 struct ieee80211_channel *chan = sme->channel; 1568 struct ieee80211_channel *chan = sme->channel;
1404 struct brcmf_join_params join_params; 1569 struct brcmf_join_params join_params;
1405 size_t join_params_size; 1570 size_t join_params_size;
1406 struct brcmf_ssid ssid; 1571 struct brcmf_tlv *rsn_ie;
1572 struct brcmf_vs_tlv *wpa_ie;
1573 void *ie;
1574 u32 ie_len;
1575 struct brcmf_ext_join_params_le *ext_join_params;
1576 u16 chanspec;
1407 1577
1408 s32 err = 0; 1578 s32 err = 0;
1409 1579
@@ -1416,15 +1586,46 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1416 return -EOPNOTSUPP; 1586 return -EOPNOTSUPP;
1417 } 1587 }
1418 1588
1589 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1590 /* A normal (non P2P) connection request setup. */
1591 ie = NULL;
1592 ie_len = 0;
1593 /* find the WPA_IE */
1594 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1595 if (wpa_ie) {
1596 ie = wpa_ie;
1597 ie_len = wpa_ie->len + TLV_HDR_LEN;
1598 } else {
1599 /* find the RSN_IE */
1600 rsn_ie = brcmf_parse_tlvs((u8 *)sme->ie, sme->ie_len,
1601 WLAN_EID_RSN);
1602 if (rsn_ie) {
1603 ie = rsn_ie;
1604 ie_len = rsn_ie->len + TLV_HDR_LEN;
1605 }
1606 }
1607 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1608 }
1609
1610 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1611 sme->ie, sme->ie_len);
1612 if (err)
1613 brcmf_err("Set Assoc REQ IE Failed\n");
1614 else
1615 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1616
1419 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); 1617 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1420 1618
1421 if (chan) { 1619 if (chan) {
1422 cfg->channel = 1620 cfg->channel =
1423 ieee80211_frequency_to_channel(chan->center_freq); 1621 ieee80211_frequency_to_channel(chan->center_freq);
1424 brcmf_dbg(CONN, "channel (%d), center_req (%d)\n", 1622 chanspec = channel_to_chanspec(chan);
1425 cfg->channel, chan->center_freq); 1623 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1426 } else 1624 cfg->channel, chan->center_freq, chanspec);
1625 } else {
1427 cfg->channel = 0; 1626 cfg->channel = 0;
1627 chanspec = 0;
1628 }
1428 1629
1429 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len); 1630 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1430 1631
@@ -1434,6 +1635,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1434 goto done; 1635 goto done;
1435 } 1636 }
1436 1637
1638 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1437 err = brcmf_set_auth_type(ndev, sme); 1639 err = brcmf_set_auth_type(ndev, sme);
1438 if (err) { 1640 if (err) {
1439 brcmf_err("wl_set_auth_type failed (%d)\n", err); 1641 brcmf_err("wl_set_auth_type failed (%d)\n", err);
@@ -1458,27 +1660,88 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1458 goto done; 1660 goto done;
1459 } 1661 }
1460 1662
1663 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1664 (u32)sme->ssid_len);
1665 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1666 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1667 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1668 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1669 profile->ssid.SSID_len);
1670 }
1671
1672 /* Join with specific BSSID and cached SSID
1673 * If SSID is zero join based on BSSID only
1674 */
1675 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1676 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1677 if (cfg->channel)
1678 join_params_size += sizeof(u16);
1679 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1680 if (ext_join_params == NULL) {
1681 err = -ENOMEM;
1682 goto done;
1683 }
1684 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1685 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1686 profile->ssid.SSID_len);
1687 /*increase dwell time to receive probe response or detect Beacon
1688 * from target AP at a noisy air only during connect command
1689 */
1690 ext_join_params->scan_le.active_time =
1691 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1692 ext_join_params->scan_le.passive_time =
1693 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1694 /* Set up join scan parameters */
1695 ext_join_params->scan_le.scan_type = -1;
1696 /* to sync with presence period of VSDB GO.
1697 * Send probe request more frequently. Probe request will be stopped
1698 * when it gets probe response from target AP/GO.
1699 */
1700 ext_join_params->scan_le.nprobes =
1701 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1702 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1703 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1704
1705 if (sme->bssid)
1706 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1707 else
1708 memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
1709
1710 if (cfg->channel) {
1711 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1712
1713 ext_join_params->assoc_le.chanspec_list[0] =
1714 cpu_to_le16(chanspec);
1715 }
1716
1717 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1718 join_params_size);
1719 kfree(ext_join_params);
1720 if (!err)
1721 /* This is it. join command worked, we are done */
1722 goto done;
1723
1724 /* join command failed, fallback to set ssid */
1461 memset(&join_params, 0, sizeof(join_params)); 1725 memset(&join_params, 0, sizeof(join_params));
1462 join_params_size = sizeof(join_params.ssid_le); 1726 join_params_size = sizeof(join_params.ssid_le);
1463 1727
1464 profile->ssid.SSID_len = min_t(u32,
1465 sizeof(ssid.SSID), (u32)sme->ssid_len);
1466 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len); 1728 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1467 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1468 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len); 1729 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1469 1730
1470 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN); 1731 if (sme->bssid)
1471 1732 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1472 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN) 1733 else
1473 brcmf_dbg(CONN, "ssid \"%s\", len (%d)\n", 1734 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1474 ssid.SSID, ssid.SSID_len);
1475 1735
1476 brcmf_ch_to_chanspec(cfg->channel, 1736 if (cfg->channel) {
1477 &join_params, &join_params_size); 1737 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1738 join_params.params_le.chanspec_num = cpu_to_le32(1);
1739 join_params_size += sizeof(join_params.params_le);
1740 }
1478 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, 1741 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1479 &join_params, join_params_size); 1742 &join_params, join_params_size);
1480 if (err) 1743 if (err)
1481 brcmf_err("WLC_SET_SSID failed (%d)\n", err); 1744 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1482 1745
1483done: 1746done:
1484 if (err) 1747 if (err)
@@ -1937,7 +2200,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1937 goto done; 2200 goto done;
1938 } 2201 }
1939 /* Report the current tx rate */ 2202 /* Report the current tx rate */
1940 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); 2203 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
1941 if (err) { 2204 if (err) {
1942 brcmf_err("Could not get rate (%d)\n", err); 2205 brcmf_err("Could not get rate (%d)\n", err);
1943 goto done; 2206 goto done;
@@ -2182,78 +2445,10 @@ static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2182 return vif->mode == WL_MODE_IBSS; 2445 return vif->mode == WL_MODE_IBSS;
2183} 2446}
2184 2447
2185/* 2448static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2186 * Traverse a string of 1-byte tag/1-byte length/variable-length value 2449 struct brcmf_if *ifp)
2187 * triples, returning a pointer to the substring whose first element
2188 * matches tag
2189 */
2190static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2191{
2192 struct brcmf_tlv *elt;
2193 int totlen;
2194
2195 elt = (struct brcmf_tlv *) buf;
2196 totlen = buflen;
2197
2198 /* find tagged parameter */
2199 while (totlen >= TLV_HDR_LEN) {
2200 int len = elt->len;
2201
2202 /* validate remaining totlen */
2203 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2204 return elt;
2205
2206 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2207 totlen -= (len + TLV_HDR_LEN);
2208 }
2209
2210 return NULL;
2211}
2212
2213/* Is any of the tlvs the expected entry? If
2214 * not update the tlvs buffer pointer/length.
2215 */
2216static bool
2217brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2218 u8 *oui, u32 oui_len, u8 type)
2219{
2220 /* If the contents match the OUI and the type */
2221 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2222 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2223 type == ie[TLV_BODY_OFF + oui_len]) {
2224 return true;
2225 }
2226
2227 if (tlvs == NULL)
2228 return false;
2229 /* point to the next ie */
2230 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2231 /* calculate the length of the rest of the buffer */
2232 *tlvs_len -= (int)(ie - *tlvs);
2233 /* update the pointer to the start of the buffer */
2234 *tlvs = ie;
2235
2236 return false;
2237}
2238
2239static struct brcmf_vs_tlv *
2240brcmf_find_wpaie(u8 *parse, u32 len)
2241{ 2450{
2242 struct brcmf_tlv *ie; 2451 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2243
2244 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
2245 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2246 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2247 return (struct brcmf_vs_tlv *)ie;
2248 }
2249 return NULL;
2250}
2251
2252static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2253{
2254 struct net_device *ndev = cfg_to_ndev(cfg);
2255 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2256 struct brcmf_if *ifp = netdev_priv(ndev);
2257 struct brcmf_bss_info_le *bi; 2452 struct brcmf_bss_info_le *bi;
2258 struct brcmf_ssid *ssid; 2453 struct brcmf_ssid *ssid;
2259 struct brcmf_tlv *tim; 2454 struct brcmf_tlv *tim;
@@ -2309,7 +2504,7 @@ update_bss_info_out:
2309 return err; 2504 return err;
2310} 2505}
2311 2506
2312static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) 2507void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2313{ 2508{
2314 struct escan_info *escan = &cfg->escan_info; 2509 struct escan_info *escan = &cfg->escan_info;
2315 2510
@@ -2328,8 +2523,7 @@ static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2328 container_of(work, struct brcmf_cfg80211_info, 2523 container_of(work, struct brcmf_cfg80211_info,
2329 escan_timeout_work); 2524 escan_timeout_work);
2330 2525
2331 brcmf_notify_escan_complete(cfg, 2526 brcmf_notify_escan_complete(cfg, cfg->escan_info.ndev, true, true);
2332 cfg->escan_info.ndev, true, true);
2333} 2527}
2334 2528
2335static void brcmf_escan_timeout(unsigned long data) 2529static void brcmf_escan_timeout(unsigned long data)
@@ -2406,11 +2600,6 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2406 brcmf_err("Invalid escan result (NULL pointer)\n"); 2600 brcmf_err("Invalid escan result (NULL pointer)\n");
2407 goto exit; 2601 goto exit;
2408 } 2602 }
2409 if (!cfg->scan_request) {
2410 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2411 goto exit;
2412 }
2413
2414 if (le16_to_cpu(escan_result_le->bss_count) != 1) { 2603 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2415 brcmf_err("Invalid bss_count %d: ignoring\n", 2604 brcmf_err("Invalid bss_count %d: ignoring\n",
2416 escan_result_le->bss_count); 2605 escan_result_le->bss_count);
@@ -2418,6 +2607,14 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2418 } 2607 }
2419 bss_info_le = &escan_result_le->bss_info_le; 2608 bss_info_le = &escan_result_le->bss_info_le;
2420 2609
2610 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2611 goto exit;
2612
2613 if (!cfg->scan_request) {
2614 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2615 goto exit;
2616 }
2617
2421 bi_length = le32_to_cpu(bss_info_le->length); 2618 bi_length = le32_to_cpu(bss_info_le->length);
2422 if (bi_length != (le32_to_cpu(escan_result_le->buflen) - 2619 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2423 WL_ESCAN_RESULTS_FIXED_SIZE)) { 2620 WL_ESCAN_RESULTS_FIXED_SIZE)) {
@@ -2456,6 +2653,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2456 list->count++; 2653 list->count++;
2457 } else { 2654 } else {
2458 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; 2655 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2656 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2657 goto exit;
2459 if (cfg->scan_request) { 2658 if (cfg->scan_request) {
2460 cfg->bss_list = (struct brcmf_scan_results *) 2659 cfg->bss_list = (struct brcmf_scan_results *)
2461 cfg->escan_info.escan_buf; 2660 cfg->escan_info.escan_buf;
@@ -2464,7 +2663,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2464 brcmf_notify_escan_complete(cfg, ndev, aborted, 2663 brcmf_notify_escan_complete(cfg, ndev, aborted,
2465 false); 2664 false);
2466 } else 2665 } else
2467 brcmf_err("Unexpected scan result 0x%x\n", status); 2666 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2667 status);
2468 } 2668 }
2469exit: 2669exit:
2470 return err; 2670 return err;
@@ -2968,9 +3168,8 @@ static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
2968} 3168}
2969#endif 3169#endif
2970 3170
2971static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx) 3171static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
2972{ 3172{
2973 struct brcmf_if *ifp = netdev_priv(ndev);
2974 s32 err; 3173 s32 err;
2975 3174
2976 /* set auth */ 3175 /* set auth */
@@ -3229,7 +3428,7 @@ brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3229 parsed_info->vndrie.oui[2], 3428 parsed_info->vndrie.oui[2],
3230 parsed_info->vndrie.oui_type); 3429 parsed_info->vndrie.oui_type);
3231 3430
3232 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER) 3431 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3233 break; 3432 break;
3234next: 3433next:
3235 remaining_len -= (ie->len + TLV_HDR_LEN); 3434 remaining_len -= (ie->len + TLV_HDR_LEN);
@@ -3263,7 +3462,6 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3263 return ie_len + VNDR_IE_HDR_SIZE; 3462 return ie_len + VNDR_IE_HDR_SIZE;
3264} 3463}
3265 3464
3266static
3267s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, 3465s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3268 const u8 *vndr_ie_buf, u32 vndr_ie_len) 3466 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3269{ 3467{
@@ -3295,24 +3493,28 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3295 if (!iovar_ie_buf) 3493 if (!iovar_ie_buf)
3296 return -ENOMEM; 3494 return -ENOMEM;
3297 curr_ie_buf = iovar_ie_buf; 3495 curr_ie_buf = iovar_ie_buf;
3298 if (ifp->vif->mode == WL_MODE_AP) { 3496 switch (pktflag) {
3299 switch (pktflag) { 3497 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3300 case VNDR_IE_PRBRSP_FLAG: 3498 mgmt_ie_buf = saved_ie->probe_req_ie;
3301 mgmt_ie_buf = saved_ie->probe_res_ie; 3499 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3302 mgmt_ie_len = &saved_ie->probe_res_ie_len; 3500 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3303 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie); 3501 break;
3304 break; 3502 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3305 case VNDR_IE_BEACON_FLAG: 3503 mgmt_ie_buf = saved_ie->probe_res_ie;
3306 mgmt_ie_buf = saved_ie->beacon_ie; 3504 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3307 mgmt_ie_len = &saved_ie->beacon_ie_len; 3505 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3308 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie); 3506 break;
3309 break; 3507 case BRCMF_VNDR_IE_BEACON_FLAG:
3310 default: 3508 mgmt_ie_buf = saved_ie->beacon_ie;
3311 err = -EPERM; 3509 mgmt_ie_len = &saved_ie->beacon_ie_len;
3312 brcmf_err("not suitable type\n"); 3510 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3313 goto exit; 3511 break;
3314 } 3512 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3315 } else { 3513 mgmt_ie_buf = saved_ie->assoc_req_ie;
3514 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3515 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3516 break;
3517 default:
3316 err = -EPERM; 3518 err = -EPERM;
3317 brcmf_err("not suitable type\n"); 3519 brcmf_err("not suitable type\n");
3318 goto exit; 3520 goto exit;
@@ -3421,6 +3623,49 @@ exit:
3421 return err; 3623 return err;
3422} 3624}
3423 3625
3626s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3627{
3628 s32 pktflags[] = {
3629 BRCMF_VNDR_IE_PRBREQ_FLAG,
3630 BRCMF_VNDR_IE_PRBRSP_FLAG,
3631 BRCMF_VNDR_IE_BEACON_FLAG
3632 };
3633 int i;
3634
3635 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3636 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3637
3638 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3639 return 0;
3640}
3641
3642static s32
3643brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3644 struct cfg80211_beacon_data *beacon)
3645{
3646 s32 err;
3647
3648 /* Set Beacon IEs to FW */
3649 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3650 beacon->tail, beacon->tail_len);
3651 if (err) {
3652 brcmf_err("Set Beacon IE Failed\n");
3653 return err;
3654 }
3655 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3656
3657 /* Set Probe Response IEs to FW */
3658 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3659 beacon->proberesp_ies,
3660 beacon->proberesp_ies_len);
3661 if (err)
3662 brcmf_err("Set Probe Resp IE Failed\n");
3663 else
3664 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3665
3666 return err;
3667}
3668
3424static s32 3669static s32
3425brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, 3670brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3426 struct cfg80211_ap_settings *settings) 3671 struct cfg80211_ap_settings *settings)
@@ -3433,7 +3678,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3433 struct brcmf_tlv *rsn_ie; 3678 struct brcmf_tlv *rsn_ie;
3434 struct brcmf_vs_tlv *wpa_ie; 3679 struct brcmf_vs_tlv *wpa_ie;
3435 struct brcmf_join_params join_params; 3680 struct brcmf_join_params join_params;
3436 s32 bssidx = 0; 3681 enum nl80211_iftype dev_role;
3682 struct brcmf_fil_bss_enable_le bss_enable;
3437 3683
3438 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", 3684 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3439 cfg80211_get_chandef_type(&settings->chandef), 3685 cfg80211_get_chandef_type(&settings->chandef),
@@ -3443,10 +3689,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3443 settings->ssid, settings->ssid_len, settings->auth_type, 3689 settings->ssid, settings->ssid_len, settings->auth_type,
3444 settings->inactivity_timeout); 3690 settings->inactivity_timeout);
3445 3691
3446 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) { 3692 dev_role = ifp->vif->wdev.iftype;
3447 brcmf_err("Not in AP creation mode\n");
3448 return -EPERM;
3449 }
3450 3693
3451 memset(&ssid_le, 0, sizeof(ssid_le)); 3694 memset(&ssid_le, 0, sizeof(ssid_le));
3452 if (settings->ssid == NULL || settings->ssid_len == 0) { 3695 if (settings->ssid == NULL || settings->ssid_len == 0) {
@@ -3467,21 +3710,6 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3467 } 3710 }
3468 3711
3469 brcmf_set_mpc(ndev, 0); 3712 brcmf_set_mpc(ndev, 0);
3470 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3471 if (err < 0) {
3472 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3473 goto exit;
3474 }
3475 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3476 if (err < 0) {
3477 brcmf_err("SET INFRA error %d\n", err);
3478 goto exit;
3479 }
3480 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3481 if (err < 0) {
3482 brcmf_err("setting AP mode failed %d\n", err);
3483 goto exit;
3484 }
3485 3713
3486 /* find the RSN_IE */ 3714 /* find the RSN_IE */
3487 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, 3715 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
@@ -3507,27 +3735,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3507 } 3735 }
3508 } else { 3736 } else {
3509 brcmf_dbg(TRACE, "No WPA(2) IEs found\n"); 3737 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3510 brcmf_configure_opensecurity(ndev, bssidx); 3738 brcmf_configure_opensecurity(ifp);
3511 } 3739 }
3512 /* Set Beacon IEs to FW */
3513 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3514 VNDR_IE_BEACON_FLAG,
3515 settings->beacon.tail,
3516 settings->beacon.tail_len);
3517 if (err)
3518 brcmf_err("Set Beacon IE Failed\n");
3519 else
3520 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3521 3740
3522 /* Set Probe Response IEs to FW */ 3741 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3523 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3524 VNDR_IE_PRBRSP_FLAG,
3525 settings->beacon.proberesp_ies,
3526 settings->beacon.proberesp_ies_len);
3527 if (err)
3528 brcmf_err("Set Probe Resp IE Failed\n");
3529 else
3530 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3531 3742
3532 if (settings->beacon_interval) { 3743 if (settings->beacon_interval) {
3533 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, 3744 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
@@ -3545,22 +3756,62 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3545 goto exit; 3756 goto exit;
3546 } 3757 }
3547 } 3758 }
3548 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); 3759
3549 if (err < 0) { 3760 if (dev_role == NL80211_IFTYPE_AP) {
3550 brcmf_err("BRCMF_C_UP error (%d)\n", err); 3761 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3551 goto exit; 3762 if (err < 0) {
3763 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3764 goto exit;
3765 }
3766 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3552 } 3767 }
3553 3768
3554 memset(&join_params, 0, sizeof(join_params)); 3769 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3555 /* join parameters starts with ssid */
3556 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3557 /* create softap */
3558 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3559 &join_params, sizeof(join_params));
3560 if (err < 0) { 3770 if (err < 0) {
3561 brcmf_err("SET SSID error (%d)\n", err); 3771 brcmf_err("SET INFRA error %d\n", err);
3562 goto exit; 3772 goto exit;
3563 } 3773 }
3774 if (dev_role == NL80211_IFTYPE_AP) {
3775 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3776 if (err < 0) {
3777 brcmf_err("setting AP mode failed %d\n", err);
3778 goto exit;
3779 }
3780 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3781 if (err < 0) {
3782 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3783 goto exit;
3784 }
3785
3786 memset(&join_params, 0, sizeof(join_params));
3787 /* join parameters starts with ssid */
3788 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3789 /* create softap */
3790 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3791 &join_params, sizeof(join_params));
3792 if (err < 0) {
3793 brcmf_err("SET SSID error (%d)\n", err);
3794 goto exit;
3795 }
3796 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3797 } else {
3798 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3799 sizeof(ssid_le));
3800 if (err < 0) {
3801 brcmf_err("setting ssid failed %d\n", err);
3802 goto exit;
3803 }
3804 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3805 bss_enable.enable = cpu_to_le32(1);
3806 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3807 sizeof(bss_enable));
3808 if (err < 0) {
3809 brcmf_err("bss_enable config failed %d\n", err);
3810 goto exit;
3811 }
3812
3813 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3814 }
3564 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); 3815 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3565 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); 3816 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3566 3817
@@ -3574,10 +3825,11 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3574{ 3825{
3575 struct brcmf_if *ifp = netdev_priv(ndev); 3826 struct brcmf_if *ifp = netdev_priv(ndev);
3576 s32 err = -EPERM; 3827 s32 err = -EPERM;
3828 struct brcmf_fil_bss_enable_le bss_enable;
3577 3829
3578 brcmf_dbg(TRACE, "Enter\n"); 3830 brcmf_dbg(TRACE, "Enter\n");
3579 3831
3580 if (ifp->vif->mode == WL_MODE_AP) { 3832 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3581 /* Due to most likely deauths outstanding we sleep */ 3833 /* Due to most likely deauths outstanding we sleep */
3582 /* first to make sure they get processed by fw. */ 3834 /* first to make sure they get processed by fw. */
3583 msleep(400); 3835 msleep(400);
@@ -3591,18 +3843,41 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3591 brcmf_err("BRCMF_C_UP error %d\n", err); 3843 brcmf_err("BRCMF_C_UP error %d\n", err);
3592 goto exit; 3844 goto exit;
3593 } 3845 }
3594 brcmf_set_mpc(ndev, 1); 3846 } else {
3595 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); 3847 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3596 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); 3848 bss_enable.enable = cpu_to_le32(0);
3849 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3850 sizeof(bss_enable));
3851 if (err < 0)
3852 brcmf_err("bss_enable config failed %d\n", err);
3597 } 3853 }
3854 brcmf_set_mpc(ndev, 1);
3855 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3856 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3857
3598exit: 3858exit:
3599 return err; 3859 return err;
3600} 3860}
3601 3861
3862static s32
3863brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3864 struct cfg80211_beacon_data *info)
3865{
3866 struct brcmf_if *ifp = netdev_priv(ndev);
3867 s32 err;
3868
3869 brcmf_dbg(TRACE, "Enter\n");
3870
3871 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3872
3873 return err;
3874}
3875
3602static int 3876static int
3603brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, 3877brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3604 u8 *mac) 3878 u8 *mac)
3605{ 3879{
3880 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3606 struct brcmf_scb_val_le scbval; 3881 struct brcmf_scb_val_le scbval;
3607 struct brcmf_if *ifp = netdev_priv(ndev); 3882 struct brcmf_if *ifp = netdev_priv(ndev);
3608 s32 err; 3883 s32 err;
@@ -3612,6 +3887,8 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3612 3887
3613 brcmf_dbg(TRACE, "Enter %pM\n", mac); 3888 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3614 3889
3890 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3891 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3615 if (!check_vif_up(ifp->vif)) 3892 if (!check_vif_up(ifp->vif))
3616 return -EIO; 3893 return -EIO;
3617 3894
@@ -3626,7 +3903,147 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3626 return err; 3903 return err;
3627} 3904}
3628 3905
3906
3907static void
3908brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3909 struct wireless_dev *wdev,
3910 u16 frame_type, bool reg)
3911{
3912 struct brcmf_if *ifp = netdev_priv(wdev->netdev);
3913 struct brcmf_cfg80211_vif *vif = ifp->vif;
3914 u16 mgmt_type;
3915
3916 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3917
3918 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3919 if (reg)
3920 vif->mgmt_rx_reg |= BIT(mgmt_type);
3921 else
3922 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
3923}
3924
3925
3926static int
3927brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3928 struct ieee80211_channel *chan, bool offchan,
3929 unsigned int wait, const u8 *buf, size_t len,
3930 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3931{
3932 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3933 const struct ieee80211_mgmt *mgmt;
3934 struct brcmf_if *ifp;
3935 struct brcmf_cfg80211_vif *vif;
3936 s32 err = 0;
3937 s32 ie_offset;
3938 s32 ie_len;
3939 struct brcmf_fil_action_frame_le *action_frame;
3940 struct brcmf_fil_af_params_le *af_params;
3941 bool ack;
3942 s32 chan_nr;
3943
3944 brcmf_dbg(TRACE, "Enter\n");
3945
3946 *cookie = 0;
3947
3948 mgmt = (const struct ieee80211_mgmt *)buf;
3949
3950 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
3951 brcmf_err("Driver only allows MGMT packet type\n");
3952 return -EPERM;
3953 }
3954
3955 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
3956 /* Right now the only reason to get a probe response */
3957 /* is for p2p listen response or for p2p GO from */
3958 /* wpa_supplicant. Unfortunately the probe is send */
3959 /* on primary ndev, while dongle wants it on the p2p */
3960 /* vif. Since this is only reason for a probe */
3961 /* response to be sent, the vif is taken from cfg. */
3962 /* If ever desired to send proberesp for non p2p */
3963 /* response then data should be checked for */
3964 /* "DIRECT-". Note in future supplicant will take */
3965 /* dedicated p2p wdev to do this and then this 'hack'*/
3966 /* is not needed anymore. */
3967 ie_offset = DOT11_MGMT_HDR_LEN +
3968 DOT11_BCN_PRB_FIXED_LEN;
3969 ie_len = len - ie_offset;
3970 ifp = netdev_priv(wdev->netdev);
3971 vif = ifp->vif;
3972 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
3973 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
3974 err = brcmf_vif_set_mgmt_ie(vif,
3975 BRCMF_VNDR_IE_PRBRSP_FLAG,
3976 &buf[ie_offset],
3977 ie_len);
3978 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
3979 GFP_KERNEL);
3980 } else if (ieee80211_is_action(mgmt->frame_control)) {
3981 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
3982 if (af_params == NULL) {
3983 brcmf_err("unable to allocate frame\n");
3984 err = -ENOMEM;
3985 goto exit;
3986 }
3987 action_frame = &af_params->action_frame;
3988 /* Add the packet Id */
3989 action_frame->packet_id = cpu_to_le32(*cookie);
3990 /* Add BSSID */
3991 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
3992 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
3993 /* Add the length exepted for 802.11 header */
3994 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
3995 /* Add the channel */
3996 chan_nr = ieee80211_frequency_to_channel(chan->center_freq);
3997 af_params->channel = cpu_to_le32(chan_nr);
3998
3999 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4000 le16_to_cpu(action_frame->len));
4001
4002 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4003 *cookie, le16_to_cpu(action_frame->len),
4004 chan->center_freq);
4005
4006 ack = brcmf_p2p_send_action_frame(cfg, wdev->netdev,
4007 af_params);
4008
4009 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4010 GFP_KERNEL);
4011 kfree(af_params);
4012 } else {
4013 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4014 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4015 }
4016
4017exit:
4018 return err;
4019}
4020
4021
4022static int
4023brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4024 struct wireless_dev *wdev,
4025 u64 cookie)
4026{
4027 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4028 struct brcmf_cfg80211_vif *vif;
4029 int err = 0;
4030
4031 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4032
4033 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4034 if (vif == NULL) {
4035 brcmf_err("No p2p device available for probe response\n");
4036 err = -ENODEV;
4037 goto exit;
4038 }
4039 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4040exit:
4041 return err;
4042}
4043
3629static struct cfg80211_ops wl_cfg80211_ops = { 4044static struct cfg80211_ops wl_cfg80211_ops = {
4045 .add_virtual_intf = brcmf_cfg80211_add_iface,
4046 .del_virtual_intf = brcmf_cfg80211_del_iface,
3630 .change_virtual_intf = brcmf_cfg80211_change_iface, 4047 .change_virtual_intf = brcmf_cfg80211_change_iface,
3631 .scan = brcmf_cfg80211_scan, 4048 .scan = brcmf_cfg80211_scan,
3632 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params, 4049 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
@@ -3650,28 +4067,43 @@ static struct cfg80211_ops wl_cfg80211_ops = {
3650 .flush_pmksa = brcmf_cfg80211_flush_pmksa, 4067 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
3651 .start_ap = brcmf_cfg80211_start_ap, 4068 .start_ap = brcmf_cfg80211_start_ap,
3652 .stop_ap = brcmf_cfg80211_stop_ap, 4069 .stop_ap = brcmf_cfg80211_stop_ap,
4070 .change_beacon = brcmf_cfg80211_change_beacon,
3653 .del_station = brcmf_cfg80211_del_station, 4071 .del_station = brcmf_cfg80211_del_station,
3654 .sched_scan_start = brcmf_cfg80211_sched_scan_start, 4072 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
3655 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, 4073 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4074 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4075 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4076 .remain_on_channel = brcmf_p2p_remain_on_channel,
4077 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
3656#ifdef CONFIG_NL80211_TESTMODE 4078#ifdef CONFIG_NL80211_TESTMODE
3657 .testmode_cmd = brcmf_cfg80211_testmode 4079 .testmode_cmd = brcmf_cfg80211_testmode
3658#endif 4080#endif
3659}; 4081};
3660 4082
3661static s32 brcmf_mode_to_nl80211_iftype(s32 mode) 4083static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
3662{ 4084{
3663 s32 err = 0; 4085 switch (type) {
3664 4086 case NL80211_IFTYPE_AP_VLAN:
3665 switch (mode) { 4087 case NL80211_IFTYPE_WDS:
3666 case WL_MODE_BSS: 4088 case NL80211_IFTYPE_MONITOR:
3667 return NL80211_IFTYPE_STATION; 4089 case NL80211_IFTYPE_MESH_POINT:
3668 case WL_MODE_IBSS: 4090 return -ENOTSUPP;
3669 return NL80211_IFTYPE_ADHOC; 4091 case NL80211_IFTYPE_ADHOC:
4092 return WL_MODE_IBSS;
4093 case NL80211_IFTYPE_STATION:
4094 case NL80211_IFTYPE_P2P_CLIENT:
4095 return WL_MODE_BSS;
4096 case NL80211_IFTYPE_AP:
4097 case NL80211_IFTYPE_P2P_GO:
4098 return WL_MODE_AP;
4099 case NL80211_IFTYPE_P2P_DEVICE:
4100 return WL_MODE_P2P;
4101 case NL80211_IFTYPE_UNSPECIFIED:
3670 default: 4102 default:
3671 return NL80211_IFTYPE_UNSPECIFIED; 4103 break;
3672 } 4104 }
3673 4105
3674 return err; 4106 return -EINVAL;
3675} 4107}
3676 4108
3677static void brcmf_wiphy_pno_params(struct wiphy *wiphy) 4109static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
@@ -3683,6 +4115,56 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
3683 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 4115 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3684} 4116}
3685 4117
4118static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4119 {
4120 .max = 2,
4121 .types = BIT(NL80211_IFTYPE_STATION) |
4122 BIT(NL80211_IFTYPE_ADHOC) |
4123 BIT(NL80211_IFTYPE_AP)
4124 },
4125 {
4126 .max = 1,
4127 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4128 },
4129 {
4130 .max = 1,
4131 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4132 BIT(NL80211_IFTYPE_P2P_GO)
4133 },
4134};
4135static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4136 {
4137 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4138 .num_different_channels = 1, /* no multi-channel for now */
4139 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4140 .limits = brcmf_iface_limits
4141 }
4142};
4143
4144static const struct ieee80211_txrx_stypes
4145brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4146 [NL80211_IFTYPE_STATION] = {
4147 .tx = 0xffff,
4148 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4149 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4150 },
4151 [NL80211_IFTYPE_P2P_CLIENT] = {
4152 .tx = 0xffff,
4153 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4154 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4155 },
4156 [NL80211_IFTYPE_P2P_GO] = {
4157 .tx = 0xffff,
4158 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4159 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4160 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4161 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4162 BIT(IEEE80211_STYPE_AUTH >> 4) |
4163 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4164 BIT(IEEE80211_STYPE_ACTION >> 4)
4165 }
4166};
4167
3686static struct wiphy *brcmf_setup_wiphy(struct device *phydev) 4168static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3687{ 4169{
3688 struct wiphy *wiphy; 4170 struct wiphy *wiphy;
@@ -3695,10 +4177,16 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3695 } 4177 }
3696 set_wiphy_dev(wiphy, phydev); 4178 set_wiphy_dev(wiphy, phydev);
3697 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; 4179 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4180 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
3698 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; 4181 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3699 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 4182 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3700 BIT(NL80211_IFTYPE_ADHOC) | 4183 BIT(NL80211_IFTYPE_ADHOC) |
3701 BIT(NL80211_IFTYPE_AP); 4184 BIT(NL80211_IFTYPE_AP) |
4185 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4186 BIT(NL80211_IFTYPE_P2P_GO) |
4187 BIT(NL80211_IFTYPE_P2P_DEVICE);
4188 wiphy->iface_combinations = brcmf_iface_combos;
4189 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
3702 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; 4190 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3703 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set 4191 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
3704 * it as 11a by default. 4192 * it as 11a by default.
@@ -3710,10 +4198,11 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3710 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 4198 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3711 wiphy->cipher_suites = __wl_cipher_suites; 4199 wiphy->cipher_suites = __wl_cipher_suites;
3712 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); 4200 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3713 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power 4201 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
3714 * save mode 4202 WIPHY_FLAG_OFFCHAN_TX |
3715 * by default 4203 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
3716 */ 4204 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4205 wiphy->max_remain_on_channel_duration = 5000;
3717 brcmf_wiphy_pno_params(wiphy); 4206 brcmf_wiphy_pno_params(wiphy);
3718 err = wiphy_register(wiphy); 4207 err = wiphy_register(wiphy);
3719 if (err < 0) { 4208 if (err < 0) {
@@ -3724,31 +4213,25 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3724 return wiphy; 4213 return wiphy;
3725} 4214}
3726 4215
3727static
3728struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, 4216struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
3729 struct net_device *netdev, 4217 enum nl80211_iftype type,
3730 s32 mode, bool pm_block) 4218 bool pm_block)
3731{ 4219{
3732 struct brcmf_cfg80211_vif *vif; 4220 struct brcmf_cfg80211_vif *vif;
3733 4221
3734 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT) 4222 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
3735 return ERR_PTR(-ENOSPC); 4223 return ERR_PTR(-ENOSPC);
3736 4224
4225 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4226 sizeof(*vif));
3737 vif = kzalloc(sizeof(*vif), GFP_KERNEL); 4227 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
3738 if (!vif) 4228 if (!vif)
3739 return ERR_PTR(-ENOMEM); 4229 return ERR_PTR(-ENOMEM);
3740 4230
3741 vif->wdev.wiphy = cfg->wiphy; 4231 vif->wdev.wiphy = cfg->wiphy;
3742 vif->wdev.netdev = netdev; 4232 vif->wdev.iftype = type;
3743 vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode);
3744
3745 if (netdev) {
3746 vif->ifp = netdev_priv(netdev);
3747 netdev->ieee80211_ptr = &vif->wdev;
3748 SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy));
3749 }
3750 4233
3751 vif->mode = mode; 4234 vif->mode = brcmf_nl80211_iftype_to_mode(type);
3752 vif->pm_block = pm_block; 4235 vif->pm_block = pm_block;
3753 vif->roam_off = -1; 4236 vif->roam_off = -1;
3754 4237
@@ -3759,7 +4242,7 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
3759 return vif; 4242 return vif;
3760} 4243}
3761 4244
3762static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) 4245void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
3763{ 4246{
3764 struct brcmf_cfg80211_info *cfg; 4247 struct brcmf_cfg80211_info *cfg;
3765 struct wiphy *wiphy; 4248 struct wiphy *wiphy;
@@ -3833,9 +4316,9 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
3833 conn_info->resp_ie_len = 0; 4316 conn_info->resp_ie_len = 0;
3834} 4317}
3835 4318
3836static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) 4319static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4320 struct brcmf_if *ifp)
3837{ 4321{
3838 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
3839 struct brcmf_cfg80211_assoc_ielen_le *assoc_info; 4322 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
3840 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); 4323 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3841 u32 req_len; 4324 u32 req_len;
@@ -3911,9 +4394,9 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
3911 4394
3912 brcmf_dbg(TRACE, "Enter\n"); 4395 brcmf_dbg(TRACE, "Enter\n");
3913 4396
3914 brcmf_get_assoc_ies(cfg); 4397 brcmf_get_assoc_ies(cfg, ifp);
3915 memcpy(profile->bssid, e->addr, ETH_ALEN); 4398 memcpy(profile->bssid, e->addr, ETH_ALEN);
3916 brcmf_update_bss_info(cfg); 4399 brcmf_update_bss_info(cfg, ifp);
3917 4400
3918 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); 4401 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3919 if (buf == NULL) { 4402 if (buf == NULL) {
@@ -3968,9 +4451,11 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
3968 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING, 4451 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
3969 &ifp->vif->sme_state)) { 4452 &ifp->vif->sme_state)) {
3970 if (completed) { 4453 if (completed) {
3971 brcmf_get_assoc_ies(cfg); 4454 brcmf_get_assoc_ies(cfg, ifp);
3972 memcpy(profile->bssid, e->addr, ETH_ALEN); 4455 memcpy(profile->bssid, e->addr, ETH_ALEN);
3973 brcmf_update_bss_info(cfg); 4456 brcmf_update_bss_info(cfg, ifp);
4457 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4458 &ifp->vif->sme_state);
3974 } 4459 }
3975 cfg80211_connect_result(ndev, 4460 cfg80211_connect_result(ndev,
3976 (u8 *)profile->bssid, 4461 (u8 *)profile->bssid,
@@ -3981,9 +4466,6 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
3981 completed ? WLAN_STATUS_SUCCESS : 4466 completed ? WLAN_STATUS_SUCCESS :
3982 WLAN_STATUS_AUTH_TIMEOUT, 4467 WLAN_STATUS_AUTH_TIMEOUT,
3983 GFP_KERNEL); 4468 GFP_KERNEL);
3984 if (completed)
3985 set_bit(BRCMF_VIF_STATUS_CONNECTED,
3986 &ifp->vif->sme_state);
3987 brcmf_dbg(CONN, "Report connect result - connection %s\n", 4469 brcmf_dbg(CONN, "Report connect result - connection %s\n",
3988 completed ? "succeeded" : "failed"); 4470 completed ? "succeeded" : "failed");
3989 } 4471 }
@@ -3996,38 +4478,38 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
3996 struct net_device *ndev, 4478 struct net_device *ndev,
3997 const struct brcmf_event_msg *e, void *data) 4479 const struct brcmf_event_msg *e, void *data)
3998{ 4480{
3999 s32 err = 0; 4481 static int generation;
4000 u32 event = e->event_code; 4482 u32 event = e->event_code;
4001 u32 reason = e->reason; 4483 u32 reason = e->reason;
4002 u32 len = e->datalen;
4003 static int generation;
4004
4005 struct station_info sinfo; 4484 struct station_info sinfo;
4006 4485
4007 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason); 4486 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4008 memset(&sinfo, 0, sizeof(sinfo)); 4487 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4488 ndev != cfg_to_ndev(cfg)) {
4489 brcmf_dbg(CONN, "AP mode link down\n");
4490 complete(&cfg->vif_disabled);
4491 return 0;
4492 }
4009 4493
4010 sinfo.filled = 0;
4011 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) && 4494 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4012 reason == BRCMF_E_STATUS_SUCCESS) { 4495 (reason == BRCMF_E_STATUS_SUCCESS)) {
4496 memset(&sinfo, 0, sizeof(sinfo));
4013 sinfo.filled = STATION_INFO_ASSOC_REQ_IES; 4497 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4014 if (!data) { 4498 if (!data) {
4015 brcmf_err("No IEs present in ASSOC/REASSOC_IND"); 4499 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4016 return -EINVAL; 4500 return -EINVAL;
4017 } 4501 }
4018 sinfo.assoc_req_ies = data; 4502 sinfo.assoc_req_ies = data;
4019 sinfo.assoc_req_ies_len = len; 4503 sinfo.assoc_req_ies_len = e->datalen;
4020 generation++; 4504 generation++;
4021 sinfo.generation = generation; 4505 sinfo.generation = generation;
4022 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC); 4506 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4023 } else if ((event == BRCMF_E_DISASSOC_IND) || 4507 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4024 (event == BRCMF_E_DEAUTH_IND) || 4508 (event == BRCMF_E_DEAUTH_IND) ||
4025 (event == BRCMF_E_DEAUTH)) { 4509 (event == BRCMF_E_DEAUTH)) {
4026 generation++; 4510 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4027 sinfo.generation = generation;
4028 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4029 } 4511 }
4030 return err; 4512 return 0;
4031} 4513}
4032 4514
4033static s32 4515static s32
@@ -4064,6 +4546,8 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4064 } 4546 }
4065 brcmf_link_down(ifp->vif); 4547 brcmf_link_down(ifp->vif);
4066 brcmf_init_prof(ndev_to_prof(ndev)); 4548 brcmf_init_prof(ndev_to_prof(ndev));
4549 if (ndev != cfg_to_ndev(cfg))
4550 complete(&cfg->vif_disabled);
4067 } else if (brcmf_is_nonetwork(cfg, e)) { 4551 } else if (brcmf_is_nonetwork(cfg, e)) {
4068 if (brcmf_is_ibssmode(ifp->vif)) 4552 if (brcmf_is_ibssmode(ifp->vif))
4069 clear_bit(BRCMF_VIF_STATUS_CONNECTING, 4553 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
@@ -4112,6 +4596,57 @@ brcmf_notify_mic_status(struct brcmf_if *ifp,
4112 return 0; 4596 return 0;
4113} 4597}
4114 4598
4599static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4600 const struct brcmf_event_msg *e, void *data)
4601{
4602 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4603 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4604 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4605 struct brcmf_cfg80211_vif *vif;
4606
4607 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4608 ifevent->action, ifevent->flags, ifevent->ifidx,
4609 ifevent->bssidx);
4610
4611 mutex_lock(&event->vif_event_lock);
4612 event->action = ifevent->action;
4613 vif = event->vif;
4614
4615 switch (ifevent->action) {
4616 case BRCMF_E_IF_ADD:
4617 /* waiting process may have timed out */
4618 if (!cfg->vif_event.vif)
4619 return -EBADF;
4620
4621 ifp->vif = vif;
4622 vif->ifp = ifp;
4623 vif->wdev.netdev = ifp->ndev;
4624 ifp->ndev->ieee80211_ptr = &vif->wdev;
4625 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4626 mutex_unlock(&event->vif_event_lock);
4627 wake_up(&event->vif_wq);
4628 return 0;
4629
4630 case BRCMF_E_IF_DEL:
4631 ifp->vif = NULL;
4632 mutex_unlock(&event->vif_event_lock);
4633 /* event may not be upon user request */
4634 if (brcmf_cfg80211_vif_event_armed(cfg))
4635 wake_up(&event->vif_wq);
4636 return 0;
4637
4638 case BRCMF_E_IF_CHANGE:
4639 mutex_unlock(&event->vif_event_lock);
4640 wake_up(&event->vif_wq);
4641 return 0;
4642
4643 default:
4644 mutex_unlock(&event->vif_event_lock);
4645 break;
4646 }
4647 return -EINVAL;
4648}
4649
4115static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) 4650static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4116{ 4651{
4117 conf->frag_threshold = (u32)-1; 4652 conf->frag_threshold = (u32)-1;
@@ -4143,6 +4678,18 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4143 brcmf_notify_connect_status); 4678 brcmf_notify_connect_status);
4144 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND, 4679 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4145 brcmf_notify_sched_scan_results); 4680 brcmf_notify_sched_scan_results);
4681 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4682 brcmf_notify_vif_event);
4683 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4684 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4685 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4686 brcmf_p2p_notify_listen_complete);
4687 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4688 brcmf_p2p_notify_action_frame_rx);
4689 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4690 brcmf_p2p_notify_action_tx_complete);
4691 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4692 brcmf_p2p_notify_action_tx_complete);
4146} 4693}
4147 4694
4148static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) 4695static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
@@ -4198,7 +4745,7 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4198 mutex_init(&cfg->usr_sync); 4745 mutex_init(&cfg->usr_sync);
4199 brcmf_init_escan(cfg); 4746 brcmf_init_escan(cfg);
4200 brcmf_init_conf(cfg->conf); 4747 brcmf_init_conf(cfg->conf);
4201 4748 init_completion(&cfg->vif_disabled);
4202 return err; 4749 return err;
4203} 4750}
4204 4751
@@ -4209,6 +4756,12 @@ static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4209 brcmf_deinit_priv_mem(cfg); 4756 brcmf_deinit_priv_mem(cfg);
4210} 4757}
4211 4758
4759static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4760{
4761 init_waitqueue_head(&event->vif_wq);
4762 mutex_init(&event->vif_event_lock);
4763}
4764
4212struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, 4765struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4213 struct device *busdev) 4766 struct device *busdev)
4214{ 4767{
@@ -4232,25 +4785,41 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4232 cfg = wiphy_priv(wiphy); 4785 cfg = wiphy_priv(wiphy);
4233 cfg->wiphy = wiphy; 4786 cfg->wiphy = wiphy;
4234 cfg->pub = drvr; 4787 cfg->pub = drvr;
4788 init_vif_event(&cfg->vif_event);
4235 INIT_LIST_HEAD(&cfg->vif_list); 4789 INIT_LIST_HEAD(&cfg->vif_list);
4236 4790
4237 vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false); 4791 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4238 if (IS_ERR(vif)) { 4792 if (IS_ERR(vif)) {
4239 wiphy_free(wiphy); 4793 wiphy_free(wiphy);
4240 return NULL; 4794 return NULL;
4241 } 4795 }
4242 4796
4797 vif->ifp = ifp;
4798 vif->wdev.netdev = ndev;
4799 ndev->ieee80211_ptr = &vif->wdev;
4800 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4801
4243 err = wl_init_priv(cfg); 4802 err = wl_init_priv(cfg);
4244 if (err) { 4803 if (err) {
4245 brcmf_err("Failed to init iwm_priv (%d)\n", err); 4804 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4246 goto cfg80211_attach_out; 4805 goto cfg80211_attach_out;
4247 } 4806 }
4248
4249 ifp->vif = vif; 4807 ifp->vif = vif;
4808
4809 err = brcmf_p2p_attach(cfg);
4810 if (err) {
4811 brcmf_err("P2P initilisation failed (%d)\n", err);
4812 goto cfg80211_p2p_attach_out;
4813 }
4814
4250 return cfg; 4815 return cfg;
4251 4816
4817cfg80211_p2p_attach_out:
4818 wl_deinit_priv(cfg);
4819
4252cfg80211_attach_out: 4820cfg80211_attach_out:
4253 brcmf_free_vif(vif); 4821 brcmf_free_vif(vif);
4822 wiphy_free(wiphy);
4254 return NULL; 4823 return NULL;
4255} 4824}
4256 4825
@@ -4489,3 +5058,57 @@ s32 brcmf_cfg80211_down(struct net_device *ndev)
4489 return err; 5058 return err;
4490} 5059}
4491 5060
5061u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5062{
5063 struct brcmf_cfg80211_vif *vif;
5064 bool result = 0;
5065
5066 list_for_each_entry(vif, &cfg->vif_list, list) {
5067 if (test_bit(state, &vif->sme_state))
5068 result++;
5069 }
5070 return result;
5071}
5072
5073static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5074 u8 action)
5075{
5076 u8 evt_action;
5077
5078 mutex_lock(&event->vif_event_lock);
5079 evt_action = event->action;
5080 mutex_unlock(&event->vif_event_lock);
5081 return evt_action == action;
5082}
5083
5084void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5085 struct brcmf_cfg80211_vif *vif)
5086{
5087 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5088
5089 mutex_lock(&event->vif_event_lock);
5090 event->vif = vif;
5091 event->action = 0;
5092 mutex_unlock(&event->vif_event_lock);
5093}
5094
5095bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5096{
5097 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5098 bool armed;
5099
5100 mutex_lock(&event->vif_event_lock);
5101 armed = event->vif != NULL;
5102 mutex_unlock(&event->vif_event_lock);
5103
5104 return armed;
5105}
5106int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5107 u8 action, ulong timeout)
5108{
5109 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5110
5111 return wait_event_timeout(event->vif_wq,
5112 vif_event_equals(event, action), timeout);
5113}
5114
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index e4d9cc7a8e63..8b5d4989906c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -41,6 +41,38 @@
41#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ 41#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */
42#define IE_MAX_LEN 512 42#define IE_MAX_LEN 512
43 43
44/* IE TLV processing */
45#define TLV_LEN_OFF 1 /* length offset */
46#define TLV_HDR_LEN 2 /* header length */
47#define TLV_BODY_OFF 2 /* body offset */
48#define TLV_OUI_LEN 3 /* oui id length */
49
50/* 802.11 Mgmt Packet flags */
51#define BRCMF_VNDR_IE_BEACON_FLAG 0x1
52#define BRCMF_VNDR_IE_PRBRSP_FLAG 0x2
53#define BRCMF_VNDR_IE_ASSOCRSP_FLAG 0x4
54#define BRCMF_VNDR_IE_AUTHRSP_FLAG 0x8
55#define BRCMF_VNDR_IE_PRBREQ_FLAG 0x10
56#define BRCMF_VNDR_IE_ASSOCREQ_FLAG 0x20
57/* vendor IE in IW advertisement protocol ID field */
58#define BRCMF_VNDR_IE_IWAPID_FLAG 0x40
59/* allow custom IE id */
60#define BRCMF_VNDR_IE_CUSTOM_FLAG 0x100
61
62/* P2P Action Frames flags (spec ordered) */
63#define BRCMF_VNDR_IE_GONREQ_FLAG 0x001000
64#define BRCMF_VNDR_IE_GONRSP_FLAG 0x002000
65#define BRCMF_VNDR_IE_GONCFM_FLAG 0x004000
66#define BRCMF_VNDR_IE_INVREQ_FLAG 0x008000
67#define BRCMF_VNDR_IE_INVRSP_FLAG 0x010000
68#define BRCMF_VNDR_IE_DISREQ_FLAG 0x020000
69#define BRCMF_VNDR_IE_DISRSP_FLAG 0x040000
70#define BRCMF_VNDR_IE_PRDREQ_FLAG 0x080000
71#define BRCMF_VNDR_IE_PRDRSP_FLAG 0x100000
72
73#define BRCMF_VNDR_IE_P2PAF_SHIFT 12
74
75
44/** 76/**
45 * enum brcmf_scan_status - dongle scan status 77 * enum brcmf_scan_status - dongle scan status
46 * 78 *
@@ -52,11 +84,19 @@ enum brcmf_scan_status {
52 BRCMF_SCAN_STATUS_ABORT, 84 BRCMF_SCAN_STATUS_ABORT,
53}; 85};
54 86
55/* wi-fi mode */ 87/**
88 * enum wl_mode - driver mode of virtual interface.
89 *
90 * @WL_MODE_BSS: connects to BSS.
91 * @WL_MODE_IBSS: operate as ad-hoc.
92 * @WL_MODE_AP: operate as access-point.
93 * @WL_MODE_P2P: provide P2P discovery.
94 */
56enum wl_mode { 95enum wl_mode {
57 WL_MODE_BSS, 96 WL_MODE_BSS,
58 WL_MODE_IBSS, 97 WL_MODE_IBSS,
59 WL_MODE_AP 98 WL_MODE_AP,
99 WL_MODE_P2P
60}; 100};
61 101
62/* dongle configuration */ 102/* dongle configuration */
@@ -108,6 +148,7 @@ struct brcmf_cfg80211_profile {
108 * @BRCMF_VIF_STATUS_READY: ready for operation. 148 * @BRCMF_VIF_STATUS_READY: ready for operation.
109 * @BRCMF_VIF_STATUS_CONNECTING: connect/join in progress. 149 * @BRCMF_VIF_STATUS_CONNECTING: connect/join in progress.
110 * @BRCMF_VIF_STATUS_CONNECTED: connected/joined succesfully. 150 * @BRCMF_VIF_STATUS_CONNECTED: connected/joined succesfully.
151 * @BRCMF_VIF_STATUS_DISCONNECTING: disconnect/disable in progress.
111 * @BRCMF_VIF_STATUS_AP_CREATING: interface configured for AP operation. 152 * @BRCMF_VIF_STATUS_AP_CREATING: interface configured for AP operation.
112 * @BRCMF_VIF_STATUS_AP_CREATED: AP operation started. 153 * @BRCMF_VIF_STATUS_AP_CREATED: AP operation started.
113 */ 154 */
@@ -115,6 +156,7 @@ enum brcmf_vif_status {
115 BRCMF_VIF_STATUS_READY, 156 BRCMF_VIF_STATUS_READY,
116 BRCMF_VIF_STATUS_CONNECTING, 157 BRCMF_VIF_STATUS_CONNECTING,
117 BRCMF_VIF_STATUS_CONNECTED, 158 BRCMF_VIF_STATUS_CONNECTED,
159 BRCMF_VIF_STATUS_DISCONNECTING,
118 BRCMF_VIF_STATUS_AP_CREATING, 160 BRCMF_VIF_STATUS_AP_CREATING,
119 BRCMF_VIF_STATUS_AP_CREATED 161 BRCMF_VIF_STATUS_AP_CREATED
120}; 162};
@@ -122,16 +164,22 @@ enum brcmf_vif_status {
122/** 164/**
123 * struct vif_saved_ie - holds saved IEs for a virtual interface. 165 * struct vif_saved_ie - holds saved IEs for a virtual interface.
124 * 166 *
167 * @probe_req_ie: IE info for probe request.
125 * @probe_res_ie: IE info for probe response. 168 * @probe_res_ie: IE info for probe response.
126 * @beacon_ie: IE info for beacon frame. 169 * @beacon_ie: IE info for beacon frame.
170 * @probe_req_ie_len: IE info length for probe request.
127 * @probe_res_ie_len: IE info length for probe response. 171 * @probe_res_ie_len: IE info length for probe response.
128 * @beacon_ie_len: IE info length for beacon frame. 172 * @beacon_ie_len: IE info length for beacon frame.
129 */ 173 */
130struct vif_saved_ie { 174struct vif_saved_ie {
175 u8 probe_req_ie[IE_MAX_LEN];
131 u8 probe_res_ie[IE_MAX_LEN]; 176 u8 probe_res_ie[IE_MAX_LEN];
132 u8 beacon_ie[IE_MAX_LEN]; 177 u8 beacon_ie[IE_MAX_LEN];
178 u8 assoc_req_ie[IE_MAX_LEN];
179 u32 probe_req_ie_len;
133 u32 probe_res_ie_len; 180 u32 probe_res_ie_len;
134 u32 beacon_ie_len; 181 u32 beacon_ie_len;
182 u32 assoc_req_ie_len;
135}; 183};
136 184
137/** 185/**
@@ -145,6 +193,7 @@ struct vif_saved_ie {
145 * @sme_state: SME state using enum brcmf_vif_status bits. 193 * @sme_state: SME state using enum brcmf_vif_status bits.
146 * @pm_block: power-management blocked. 194 * @pm_block: power-management blocked.
147 * @list: linked list. 195 * @list: linked list.
196 * @mgmt_rx_reg: registered rx mgmt frame types.
148 */ 197 */
149struct brcmf_cfg80211_vif { 198struct brcmf_cfg80211_vif {
150 struct brcmf_if *ifp; 199 struct brcmf_if *ifp;
@@ -156,6 +205,7 @@ struct brcmf_cfg80211_vif {
156 bool pm_block; 205 bool pm_block;
157 struct vif_saved_ie saved_ie; 206 struct vif_saved_ie saved_ie;
158 struct list_head list; 207 struct list_head list;
208 u16 mgmt_rx_reg;
159}; 209};
160 210
161/* association inform */ 211/* association inform */
@@ -189,6 +239,9 @@ struct escan_info {
189 u8 escan_buf[WL_ESCAN_BUF_SIZE]; 239 u8 escan_buf[WL_ESCAN_BUF_SIZE];
190 struct wiphy *wiphy; 240 struct wiphy *wiphy;
191 struct net_device *ndev; 241 struct net_device *ndev;
242 s32 (*run)(struct brcmf_cfg80211_info *cfg,
243 struct net_device *ndev,
244 struct cfg80211_scan_request *request, u16 action);
192}; 245};
193 246
194/** 247/**
@@ -273,10 +326,27 @@ struct brcmf_pno_scanresults_le {
273}; 326};
274 327
275/** 328/**
329 * struct brcmf_cfg80211_vif_event - virtual interface event information.
330 *
331 * @vif_wq: waitqueue awaiting interface event from firmware.
332 * @vif_event_lock: protects other members in this structure.
333 * @vif_complete: completion for net attach.
334 * @action: either add, change, or delete.
335 * @vif: virtual interface object related to the event.
336 */
337struct brcmf_cfg80211_vif_event {
338 wait_queue_head_t vif_wq;
339 struct mutex vif_event_lock;
340 u8 action;
341 struct brcmf_cfg80211_vif *vif;
342};
343
344/**
276 * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface 345 * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
277 * 346 *
278 * @wiphy: wiphy object for cfg80211 interface. 347 * @wiphy: wiphy object for cfg80211 interface.
279 * @conf: dongle configuration. 348 * @conf: dongle configuration.
349 * @p2p: peer-to-peer specific information.
280 * @scan_request: cfg80211 scan request object. 350 * @scan_request: cfg80211 scan request object.
281 * @usr_sync: mainly for dongle up/down synchronization. 351 * @usr_sync: mainly for dongle up/down synchronization.
282 * @bss_list: bss_list holding scanned ap information. 352 * @bss_list: bss_list holding scanned ap information.
@@ -304,10 +374,12 @@ struct brcmf_pno_scanresults_le {
304 * @escan_ioctl_buf: dongle command buffer for escan commands. 374 * @escan_ioctl_buf: dongle command buffer for escan commands.
305 * @vif_list: linked list of vif instances. 375 * @vif_list: linked list of vif instances.
306 * @vif_cnt: number of vif instances. 376 * @vif_cnt: number of vif instances.
377 * @vif_event: vif event signalling.
307 */ 378 */
308struct brcmf_cfg80211_info { 379struct brcmf_cfg80211_info {
309 struct wiphy *wiphy; 380 struct wiphy *wiphy;
310 struct brcmf_cfg80211_conf *conf; 381 struct brcmf_cfg80211_conf *conf;
382 struct brcmf_p2p_info p2p;
311 struct cfg80211_scan_request *scan_request; 383 struct cfg80211_scan_request *scan_request;
312 struct mutex usr_sync; 384 struct mutex usr_sync;
313 struct brcmf_scan_results *bss_list; 385 struct brcmf_scan_results *bss_list;
@@ -335,6 +407,21 @@ struct brcmf_cfg80211_info {
335 u8 *escan_ioctl_buf; 407 u8 *escan_ioctl_buf;
336 struct list_head vif_list; 408 struct list_head vif_list;
337 u8 vif_cnt; 409 u8 vif_cnt;
410 struct brcmf_cfg80211_vif_event vif_event;
411 struct completion vif_disabled;
412};
413
414/**
415 * struct brcmf_tlv - tag_ID/length/value_buffer tuple.
416 *
417 * @id: tag identifier.
418 * @len: number of bytes in value buffer.
419 * @data: value buffer.
420 */
421struct brcmf_tlv {
422 u8 id;
423 u8 len;
424 u8 data[1];
338}; 425};
339 426
340static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *cfg) 427static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *cfg)
@@ -389,4 +476,26 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
389s32 brcmf_cfg80211_up(struct net_device *ndev); 476s32 brcmf_cfg80211_up(struct net_device *ndev);
390s32 brcmf_cfg80211_down(struct net_device *ndev); 477s32 brcmf_cfg80211_down(struct net_device *ndev);
391 478
479struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
480 enum nl80211_iftype type,
481 bool pm_block);
482void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
483
484s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
485 const u8 *vndr_ie_buf, u32 vndr_ie_len);
486s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif);
487struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key);
488u16 channel_to_chanspec(struct ieee80211_channel *ch);
489u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state);
490void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
491 struct brcmf_cfg80211_vif *vif);
492bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg);
493int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
494 u8 action, ulong timeout);
495s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
496 struct net_device *ndev,
497 bool aborted, bool fw_abort);
498void brcmf_set_mpc(struct net_device *ndev, int mpc);
499void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg);
500
392#endif /* _wl_cfg80211_h_ */ 501#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index c26992a60e6c..0985925cd3f4 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -101,8 +101,6 @@
101#define DOT11_RTS_LEN 16 101#define DOT11_RTS_LEN 16
102#define DOT11_CTS_LEN 10 102#define DOT11_CTS_LEN 10
103#define DOT11_BA_BITMAP_LEN 128 103#define DOT11_BA_BITMAP_LEN 128
104#define DOT11_MIN_BEACON_PERIOD 1
105#define DOT11_MAX_BEACON_PERIOD 0xFFFF
106#define DOT11_MAXNUMFRAGS 16 104#define DOT11_MAXNUMFRAGS 16
107#define DOT11_MAX_FRAG_LEN 2346 105#define DOT11_MAX_FRAG_LEN 2346
108 106
@@ -5555,8 +5553,7 @@ int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
5555 5553
5556int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period) 5554int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
5557{ 5555{
5558 if (period < DOT11_MIN_BEACON_PERIOD || 5556 if (period == 0)
5559 period > DOT11_MAX_BEACON_PERIOD)
5560 return -EINVAL; 5557 return -EINVAL;
5561 5558
5562 wlc->default_bss->beacon_period = period; 5559 wlc->default_bss->beacon_period = period;
@@ -7408,9 +7405,13 @@ brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
7408 struct brcms_bss_cfg *cfg, 7405 struct brcms_bss_cfg *cfg,
7409 bool suspend) 7406 bool suspend)
7410{ 7407{
7411 u16 prb_resp[BCN_TMPL_LEN / 2]; 7408 u16 *prb_resp;
7412 int len = BCN_TMPL_LEN; 7409 int len = BCN_TMPL_LEN;
7413 7410
7411 prb_resp = kmalloc(BCN_TMPL_LEN, GFP_ATOMIC);
7412 if (!prb_resp)
7413 return;
7414
7414 /* 7415 /*
7415 * write the probe response to hardware, or save in 7416 * write the probe response to hardware, or save in
7416 * the config structure 7417 * the config structure
@@ -7444,6 +7445,8 @@ brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
7444 7445
7445 if (suspend) 7446 if (suspend)
7446 brcms_c_enable_mac(wlc); 7447 brcms_c_enable_mac(wlc);
7448
7449 kfree(prb_resp);
7447} 7450}
7448 7451
7449void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) 7452void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
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 d3cc776d2d34..835662a449da 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 8e5c5c5ce06f..75f6f6cfdd47 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) {
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 6b01fc195940..7b0550d35a91 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 d1a86b66bc51..de3c24a5a620 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..ce6127caabdf
--- /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_BEFORE_ASSOC |
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 9cd6216c61e6..48cc46bc152f 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 e00b8060aff7..820a19cfa562 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -317,7 +317,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
317 317
318 adapter->pm_wakeup_fw_try = false; 318 adapter->pm_wakeup_fw_try = false;
319 319
320 adapter->max_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
321 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; 320 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
322 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; 321 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
323 322
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 5a1c1d0e5599..e35b67a9e6a6 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..8186af4ed47b 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
@@ -1146,7 +1149,6 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
1146 1149
1147 rxq->buf = kcalloc(MWL8K_RX_DESCS, sizeof(*rxq->buf), GFP_KERNEL); 1150 rxq->buf = kcalloc(MWL8K_RX_DESCS, sizeof(*rxq->buf), GFP_KERNEL);
1148 if (rxq->buf == NULL) { 1151 if (rxq->buf == NULL) {
1149 wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n");
1150 pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); 1152 pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma);
1151 return -ENOMEM; 1153 return -ENOMEM;
1152 } 1154 }
@@ -1439,7 +1441,6 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
1439 1441
1440 txq->skb = kcalloc(MWL8K_TX_DESCS, sizeof(*txq->skb), GFP_KERNEL); 1442 txq->skb = kcalloc(MWL8K_TX_DESCS, sizeof(*txq->skb), GFP_KERNEL);
1441 if (txq->skb == NULL) { 1443 if (txq->skb == NULL) {
1442 wiphy_err(hw->wiphy, "failed to alloc TX skbuff list\n");
1443 pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); 1444 pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma);
1444 return -ENOMEM; 1445 return -ENOMEM;
1445 } 1446 }
@@ -2156,6 +2157,8 @@ static void mwl8k_fw_unlock(struct ieee80211_hw *hw)
2156 } 2157 }
2157} 2158}
2158 2159
2160static void mwl8k_enable_bsses(struct ieee80211_hw *hw, bool enable,
2161 u32 bitmap);
2159 2162
2160/* 2163/*
2161 * Command processing. 2164 * Command processing.
@@ -2174,6 +2177,34 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
2174 int rc; 2177 int rc;
2175 unsigned long timeout = 0; 2178 unsigned long timeout = 0;
2176 u8 buf[32]; 2179 u8 buf[32];
2180 u32 bitmap = 0;
2181
2182 wiphy_dbg(hw->wiphy, "Posting %s [%d]\n",
2183 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), cmd->macid);
2184
2185 /* Before posting firmware commands that could change the hardware
2186 * characteristics, make sure that all BSSes are stopped temporary.
2187 * Enable these stopped BSSes after completion of the commands
2188 */
2189
2190 rc = mwl8k_fw_lock(hw);
2191 if (rc)
2192 return rc;
2193
2194 if (priv->ap_fw && priv->running_bsses) {
2195 switch (le16_to_cpu(cmd->code)) {
2196 case MWL8K_CMD_SET_RF_CHANNEL:
2197 case MWL8K_CMD_RADIO_CONTROL:
2198 case MWL8K_CMD_RF_TX_POWER:
2199 case MWL8K_CMD_TX_POWER:
2200 case MWL8K_CMD_RF_ANTENNA:
2201 case MWL8K_CMD_RTS_THRESHOLD:
2202 case MWL8K_CMD_MIMO_CONFIG:
2203 bitmap = priv->running_bsses;
2204 mwl8k_enable_bsses(hw, false, bitmap);
2205 break;
2206 }
2207 }
2177 2208
2178 cmd->result = (__force __le16) 0xffff; 2209 cmd->result = (__force __le16) 0xffff;
2179 dma_size = le16_to_cpu(cmd->length); 2210 dma_size = le16_to_cpu(cmd->length);
@@ -2182,13 +2213,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)) 2213 if (pci_dma_mapping_error(priv->pdev, dma_addr))
2183 return -ENOMEM; 2214 return -ENOMEM;
2184 2215
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; 2216 priv->hostcmd_wait = &cmd_wait;
2193 iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR); 2217 iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
2194 iowrite32(MWL8K_H2A_INT_DOORBELL, 2218 iowrite32(MWL8K_H2A_INT_DOORBELL,
@@ -2201,7 +2225,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
2201 2225
2202 priv->hostcmd_wait = NULL; 2226 priv->hostcmd_wait = NULL;
2203 2227
2204 mwl8k_fw_unlock(hw);
2205 2228
2206 pci_unmap_single(priv->pdev, dma_addr, dma_size, 2229 pci_unmap_single(priv->pdev, dma_addr, dma_size,
2207 PCI_DMA_BIDIRECTIONAL); 2230 PCI_DMA_BIDIRECTIONAL);
@@ -2228,6 +2251,11 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
2228 ms); 2251 ms);
2229 } 2252 }
2230 2253
2254 if (bitmap)
2255 mwl8k_enable_bsses(hw, true, bitmap);
2256
2257 mwl8k_fw_unlock(hw);
2258
2231 return rc; 2259 return rc;
2232} 2260}
2233 2261
@@ -2489,7 +2517,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
2489 priv->hw_rev = cmd->hw_rev; 2517 priv->hw_rev = cmd->hw_rev;
2490 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps)); 2518 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
2491 priv->ap_macids_supported = 0x000000ff; 2519 priv->ap_macids_supported = 0x000000ff;
2492 priv->sta_macids_supported = 0x00000000; 2520 priv->sta_macids_supported = 0x00000100;
2493 priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues); 2521 priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues);
2494 if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) { 2522 if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) {
2495 wiphy_warn(hw->wiphy, "fw reported %d ampdu queues" 2523 wiphy_warn(hw->wiphy, "fw reported %d ampdu queues"
@@ -3508,7 +3536,10 @@ static int mwl8k_cmd_update_mac_addr(struct ieee80211_hw *hw,
3508 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP; 3536 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
3509 if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) { 3537 if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) {
3510 if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported)) 3538 if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported))
3511 mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT; 3539 if (priv->ap_fw)
3540 mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
3541 else
3542 mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT;
3512 else 3543 else
3513 mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT; 3544 mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
3514 } else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) { 3545 } else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) {
@@ -3680,8 +3711,16 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
3680 struct ieee80211_vif *vif, int enable) 3711 struct ieee80211_vif *vif, int enable)
3681{ 3712{
3682 struct mwl8k_cmd_bss_start *cmd; 3713 struct mwl8k_cmd_bss_start *cmd;
3714 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
3715 struct mwl8k_priv *priv = hw->priv;
3683 int rc; 3716 int rc;
3684 3717
3718 if (enable && (priv->running_bsses & (1 << mwl8k_vif->macid)))
3719 return 0;
3720
3721 if (!enable && !(priv->running_bsses & (1 << mwl8k_vif->macid)))
3722 return 0;
3723
3685 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 3724 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3686 if (cmd == NULL) 3725 if (cmd == NULL)
3687 return -ENOMEM; 3726 return -ENOMEM;
@@ -3693,9 +3732,31 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
3693 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); 3732 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
3694 kfree(cmd); 3733 kfree(cmd);
3695 3734
3735 if (!rc) {
3736 if (enable)
3737 priv->running_bsses |= (1 << mwl8k_vif->macid);
3738 else
3739 priv->running_bsses &= ~(1 << mwl8k_vif->macid);
3740 }
3696 return rc; 3741 return rc;
3697} 3742}
3698 3743
3744static void mwl8k_enable_bsses(struct ieee80211_hw *hw, bool enable, u32 bitmap)
3745{
3746 struct mwl8k_priv *priv = hw->priv;
3747 struct mwl8k_vif *mwl8k_vif, *tmp_vif;
3748 struct ieee80211_vif *vif;
3749
3750 list_for_each_entry_safe(mwl8k_vif, tmp_vif, &priv->vif_list, list) {
3751 vif = mwl8k_vif->vif;
3752
3753 if (!(bitmap & (1 << mwl8k_vif->macid)))
3754 continue;
3755
3756 if (vif->type == NL80211_IFTYPE_AP)
3757 mwl8k_cmd_bss_start(hw, vif, enable);
3758 }
3759}
3699/* 3760/*
3700 * CMD_BASTREAM. 3761 * CMD_BASTREAM.
3701 */ 3762 */
@@ -4202,8 +4263,9 @@ static int mwl8k_set_key(struct ieee80211_hw *hw,
4202 u8 encr_type; 4263 u8 encr_type;
4203 u8 *addr; 4264 u8 *addr;
4204 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); 4265 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
4266 struct mwl8k_priv *priv = hw->priv;
4205 4267
4206 if (vif->type == NL80211_IFTYPE_STATION) 4268 if (vif->type == NL80211_IFTYPE_STATION && !priv->ap_fw)
4207 return -EOPNOTSUPP; 4269 return -EOPNOTSUPP;
4208 4270
4209 if (sta == NULL) 4271 if (sta == NULL)
@@ -4609,12 +4671,18 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
4609 break; 4671 break;
4610 case NL80211_IFTYPE_STATION: 4672 case NL80211_IFTYPE_STATION:
4611 if (priv->ap_fw && di->fw_image_sta) { 4673 if (priv->ap_fw && di->fw_image_sta) {
4612 /* we must load the sta fw to meet this request */ 4674 if (!list_empty(&priv->vif_list)) {
4613 if (!list_empty(&priv->vif_list)) 4675 wiphy_warn(hw->wiphy, "AP interface is running.\n"
4614 return -EBUSY; 4676 "Adding STA interface for WDS");
4615 rc = mwl8k_reload_firmware(hw, di->fw_image_sta); 4677 } else {
4616 if (rc) 4678 /* we must load the sta fw to
4617 return rc; 4679 * meet this request.
4680 */
4681 rc = mwl8k_reload_firmware(hw,
4682 di->fw_image_sta);
4683 if (rc)
4684 return rc;
4685 }
4618 } 4686 }
4619 macids_supported = priv->sta_macids_supported; 4687 macids_supported = priv->sta_macids_supported;
4620 break; 4688 break;
@@ -4638,7 +4706,7 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
4638 /* Set the mac address. */ 4706 /* Set the mac address. */
4639 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr); 4707 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr);
4640 4708
4641 if (priv->ap_fw) 4709 if (vif->type == NL80211_IFTYPE_AP)
4642 mwl8k_cmd_set_new_stn_add_self(hw, vif); 4710 mwl8k_cmd_set_new_stn_add_self(hw, vif);
4643 4711
4644 priv->macids_used |= 1 << mwl8k_vif->macid; 4712 priv->macids_used |= 1 << mwl8k_vif->macid;
@@ -4663,7 +4731,7 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw,
4663 struct mwl8k_priv *priv = hw->priv; 4731 struct mwl8k_priv *priv = hw->priv;
4664 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); 4732 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
4665 4733
4666 if (priv->ap_fw) 4734 if (vif->type == NL80211_IFTYPE_AP)
4667 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr); 4735 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr);
4668 4736
4669 mwl8k_cmd_del_mac_addr(hw, vif, vif->addr); 4737 mwl8k_cmd_del_mac_addr(hw, vif, vif->addr);
@@ -4737,9 +4805,11 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
4737 if (rc) 4805 if (rc)
4738 goto out; 4806 goto out;
4739 4807
4740 rc = mwl8k_cmd_set_rf_channel(hw, conf); 4808 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
4741 if (rc) 4809 rc = mwl8k_cmd_set_rf_channel(hw, conf);
4742 goto out; 4810 if (rc)
4811 goto out;
4812 }
4743 4813
4744 if (conf->power_level > 18) 4814 if (conf->power_level > 18)
4745 conf->power_level = 18; 4815 conf->power_level = 18;
@@ -4752,12 +4822,6 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
4752 goto out; 4822 goto out;
4753 } 4823 }
4754 4824
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 4825
4762 } else { 4826 } else {
4763 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); 4827 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
@@ -4815,7 +4879,8 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4815 rcu_read_unlock(); 4879 rcu_read_unlock();
4816 } 4880 }
4817 4881
4818 if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) { 4882 if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc &&
4883 !priv->ap_fw) {
4819 rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates); 4884 rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates);
4820 if (rc) 4885 if (rc)
4821 goto out; 4886 goto out;
@@ -4823,6 +4888,25 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4823 rc = mwl8k_cmd_use_fixed_rate_sta(hw); 4888 rc = mwl8k_cmd_use_fixed_rate_sta(hw);
4824 if (rc) 4889 if (rc)
4825 goto out; 4890 goto out;
4891 } else {
4892 if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc &&
4893 priv->ap_fw) {
4894 int idx;
4895 int rate;
4896
4897 /* Use AP firmware specific rate command.
4898 */
4899 idx = ffs(vif->bss_conf.basic_rates);
4900 if (idx)
4901 idx--;
4902
4903 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
4904 rate = mwl8k_rates_24[idx].hw_value;
4905 else
4906 rate = mwl8k_rates_50[idx].hw_value;
4907
4908 mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate);
4909 }
4826 } 4910 }
4827 4911
4828 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 4912 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
@@ -4832,13 +4916,13 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4832 goto out; 4916 goto out;
4833 } 4917 }
4834 4918
4835 if (changed & BSS_CHANGED_ERP_SLOT) { 4919 if ((changed & BSS_CHANGED_ERP_SLOT) && !priv->ap_fw) {
4836 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot); 4920 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot);
4837 if (rc) 4921 if (rc)
4838 goto out; 4922 goto out;
4839 } 4923 }
4840 4924
4841 if (vif->bss_conf.assoc && 4925 if (vif->bss_conf.assoc && !priv->ap_fw &&
4842 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT | 4926 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT |
4843 BSS_CHANGED_HT))) { 4927 BSS_CHANGED_HT))) {
4844 rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates); 4928 rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates);
@@ -4918,11 +5002,9 @@ static void
4918mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 5002mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4919 struct ieee80211_bss_conf *info, u32 changed) 5003 struct ieee80211_bss_conf *info, u32 changed)
4920{ 5004{
4921 struct mwl8k_priv *priv = hw->priv; 5005 if (vif->type == NL80211_IFTYPE_STATION)
4922
4923 if (!priv->ap_fw)
4924 mwl8k_bss_info_changed_sta(hw, vif, info, changed); 5006 mwl8k_bss_info_changed_sta(hw, vif, info, changed);
4925 else 5007 if (vif->type == NL80211_IFTYPE_AP)
4926 mwl8k_bss_info_changed_ap(hw, vif, info, changed); 5008 mwl8k_bss_info_changed_ap(hw, vif, info, changed);
4927} 5009}
4928 5010
@@ -5389,6 +5471,8 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
5389 { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, }, 5471 { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
5390 { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, }, 5472 { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, },
5391 { PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, }, 5473 { PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, },
5474 { PCI_VDEVICE(MARVELL, 0x2a41), .driver_data = MWL8366, },
5475 { PCI_VDEVICE(MARVELL, 0x2a42), .driver_data = MWL8366, },
5392 { PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, }, 5476 { PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, },
5393 { }, 5477 { },
5394}; 5478};
@@ -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/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 800a16526c8e..1f7858588919 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -84,8 +84,8 @@ static struct usb_device_id p54u_table[] = {
84 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ 84 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
85 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ 85 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
86 {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ 86 {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */
87 {USB_DEVICE(0x083a, 0x4503)}, /* T-Com Sinus 154 data II */
88 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ 87 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
88 {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */
89 {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */ 89 {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */
90 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ 90 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */
91 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ 91 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
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..8a57646925a8 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) },
@@ -1098,9 +1099,11 @@ static struct usb_device_id rt2800usb_device_table[] = {
1098 { USB_DEVICE(0x15a9, 0x0006) }, 1099 { USB_DEVICE(0x15a9, 0x0006) },
1099 /* Sweex */ 1100 /* Sweex */
1100 { USB_DEVICE(0x177f, 0x0153) }, 1101 { USB_DEVICE(0x177f, 0x0153) },
1102 { USB_DEVICE(0x177f, 0x0164) },
1101 { USB_DEVICE(0x177f, 0x0302) }, 1103 { USB_DEVICE(0x177f, 0x0302) },
1102 { USB_DEVICE(0x177f, 0x0313) }, 1104 { USB_DEVICE(0x177f, 0x0313) },
1103 { USB_DEVICE(0x177f, 0x0323) }, 1105 { USB_DEVICE(0x177f, 0x0323) },
1106 { USB_DEVICE(0x177f, 0x0324) },
1104 /* U-Media */ 1107 /* U-Media */
1105 { USB_DEVICE(0x157e, 0x300e) }, 1108 { USB_DEVICE(0x157e, 0x300e) },
1106 { USB_DEVICE(0x157e, 0x3013) }, 1109 { USB_DEVICE(0x157e, 0x3013) },
@@ -1115,6 +1118,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
1115 /* Zyxel */ 1118 /* Zyxel */
1116 { USB_DEVICE(0x0586, 0x3416) }, 1119 { USB_DEVICE(0x0586, 0x3416) },
1117 { USB_DEVICE(0x0586, 0x3418) }, 1120 { USB_DEVICE(0x0586, 0x3418) },
1121 { USB_DEVICE(0x0586, 0x341a) },
1118 { USB_DEVICE(0x0586, 0x341e) }, 1122 { USB_DEVICE(0x0586, 0x341e) },
1119 { USB_DEVICE(0x0586, 0x343e) }, 1123 { USB_DEVICE(0x0586, 0x343e) },
1120#ifdef CONFIG_RT2800USB_RT33XX 1124#ifdef CONFIG_RT2800USB_RT33XX
@@ -1131,6 +1135,9 @@ static struct usb_device_id rt2800usb_device_table[] = {
1131 { USB_DEVICE(0x148f, 0x8070) }, 1135 { USB_DEVICE(0x148f, 0x8070) },
1132 /* Sitecom */ 1136 /* Sitecom */
1133 { USB_DEVICE(0x0df6, 0x0050) }, 1137 { USB_DEVICE(0x0df6, 0x0050) },
1138 /* Sweex */
1139 { USB_DEVICE(0x177f, 0x0163) },
1140 { USB_DEVICE(0x177f, 0x0165) },
1134#endif 1141#endif
1135#ifdef CONFIG_RT2800USB_RT35XX 1142#ifdef CONFIG_RT2800USB_RT35XX
1136 /* Allwin */ 1143 /* Allwin */
@@ -1166,6 +1173,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
1166#ifdef CONFIG_RT2800USB_RT53XX 1173#ifdef CONFIG_RT2800USB_RT53XX
1167 /* Arcadyan */ 1174 /* Arcadyan */
1168 { USB_DEVICE(0x043e, 0x7a12) }, 1175 { USB_DEVICE(0x043e, 0x7a12) },
1176 { USB_DEVICE(0x043e, 0x7a32) },
1169 /* Azurewave */ 1177 /* Azurewave */
1170 { USB_DEVICE(0x13d3, 0x3329) }, 1178 { USB_DEVICE(0x13d3, 0x3329) },
1171 { USB_DEVICE(0x13d3, 0x3365) }, 1179 { USB_DEVICE(0x13d3, 0x3365) },
@@ -1177,16 +1185,20 @@ static struct usb_device_id rt2800usb_device_table[] = {
1177 { USB_DEVICE(0x2001, 0x3c1e) }, 1185 { USB_DEVICE(0x2001, 0x3c1e) },
1178 /* LG innotek */ 1186 /* LG innotek */
1179 { USB_DEVICE(0x043e, 0x7a22) }, 1187 { USB_DEVICE(0x043e, 0x7a22) },
1188 { USB_DEVICE(0x043e, 0x7a42) },
1180 /* Panasonic */ 1189 /* Panasonic */
1181 { USB_DEVICE(0x04da, 0x1801) }, 1190 { USB_DEVICE(0x04da, 0x1801) },
1182 { USB_DEVICE(0x04da, 0x1800) }, 1191 { USB_DEVICE(0x04da, 0x1800) },
1192 { USB_DEVICE(0x04da, 0x23f6) },
1183 /* Philips */ 1193 /* Philips */
1184 { USB_DEVICE(0x0471, 0x2104) }, 1194 { USB_DEVICE(0x0471, 0x2104) },
1195 { USB_DEVICE(0x0471, 0x2126) },
1196 { USB_DEVICE(0x0471, 0x2180) },
1197 { USB_DEVICE(0x0471, 0x2181) },
1198 { USB_DEVICE(0x0471, 0x2182) },
1185 /* Ralink */ 1199 /* Ralink */
1186 { USB_DEVICE(0x148f, 0x5370) }, 1200 { USB_DEVICE(0x148f, 0x5370) },
1187 { USB_DEVICE(0x148f, 0x5372) }, 1201 { USB_DEVICE(0x148f, 0x5372) },
1188 /* Unknown */
1189 { USB_DEVICE(0x04da, 0x23f6) },
1190#endif 1202#endif
1191#ifdef CONFIG_RT2800USB_UNKNOWN 1203#ifdef CONFIG_RT2800USB_UNKNOWN
1192 /* 1204 /*
@@ -1223,7 +1235,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
1223 { USB_DEVICE(0x18c5, 0x0008) }, 1235 { USB_DEVICE(0x18c5, 0x0008) },
1224 /* D-Link */ 1236 /* D-Link */
1225 { USB_DEVICE(0x07d1, 0x3c0b) }, 1237 { USB_DEVICE(0x07d1, 0x3c0b) },
1226 { USB_DEVICE(0x07d1, 0x3c17) },
1227 /* Encore */ 1238 /* Encore */
1228 { USB_DEVICE(0x203d, 0x14a1) }, 1239 { USB_DEVICE(0x203d, 0x14a1) },
1229 /* Gemtek */ 1240 /* Gemtek */
@@ -1261,8 +1272,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
1261 { USB_DEVICE(0x083a, 0xc522) }, 1272 { USB_DEVICE(0x083a, 0xc522) },
1262 { USB_DEVICE(0x083a, 0xd522) }, 1273 { USB_DEVICE(0x083a, 0xd522) },
1263 { USB_DEVICE(0x083a, 0xf511) }, 1274 { USB_DEVICE(0x083a, 0xf511) },
1264 /* Zyxel */
1265 { USB_DEVICE(0x0586, 0x341a) },
1266#endif 1275#endif
1267 { 0, } 1276 { 0, }
1268}; 1277};
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/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index c31795e379f7..da0e9022a99a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -488,7 +488,7 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
488 u8 *praddr; 488 u8 *praddr;
489 __le16 fc; 489 __le16 fc;
490 u16 type, c_fc; 490 u16 type, c_fc;
491 bool packet_matchbssid, packet_toself, packet_beacon; 491 bool packet_matchbssid, packet_toself, packet_beacon = false;
492 492
493 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; 493 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
494 494
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
index 32ff959a0251..85b6bdb163c0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
@@ -1084,7 +1084,7 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
1084 u8 *praddr; 1084 u8 *praddr;
1085 __le16 fc; 1085 __le16 fc;
1086 u16 type, cpu_fc; 1086 u16 type, cpu_fc;
1087 bool packet_matchbssid, packet_toself, packet_beacon; 1087 bool packet_matchbssid, packet_toself, packet_beacon = false;
1088 1088
1089 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; 1089 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
1090 hdr = (struct ieee80211_hdr *)tmp_buf; 1090 hdr = (struct ieee80211_hdr *)tmp_buf;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index b7e6607e6b6d..a73a17bc56dd 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)
@@ -285,6 +285,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
285 {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)}, 285 {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)},
286 /* RTL8188CUS-VL */ 286 /* RTL8188CUS-VL */
287 {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x818a, rtl92cu_hal_cfg)}, 287 {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x818a, rtl92cu_hal_cfg)},
288 {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x819a, rtl92cu_hal_cfg)},
288 /* 8188 Combo for BC4 */ 289 /* 8188 Combo for BC4 */
289 {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, 290 {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)},
290 291
@@ -363,9 +364,15 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
363 364
364MODULE_DEVICE_TABLE(usb, rtl8192c_usb_ids); 365MODULE_DEVICE_TABLE(usb, rtl8192c_usb_ids);
365 366
367static int rtl8192cu_probe(struct usb_interface *intf,
368 const struct usb_device_id *id)
369{
370 return rtl_usb_probe(intf, id, &rtl92cu_hal_cfg);
371}
372
366static struct usb_driver rtl8192cu_driver = { 373static struct usb_driver rtl8192cu_driver = {
367 .name = "rtl8192cu", 374 .name = "rtl8192cu",
368 .probe = rtl_usb_probe, 375 .probe = rtl8192cu_probe,
369 .disconnect = rtl_usb_disconnect, 376 .disconnect = rtl_usb_disconnect,
370 .id_table = rtl8192c_usb_ids, 377 .id_table = rtl8192c_usb_ids,
371 378
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 f2ecdeb3a90d..80730c72e0d6 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
@@ -941,7 +937,8 @@ static struct rtl_intf_ops rtl_usb_ops = {
941}; 937};
942 938
943int rtl_usb_probe(struct usb_interface *intf, 939int rtl_usb_probe(struct usb_interface *intf,
944 const struct usb_device_id *id) 940 const struct usb_device_id *id,
941 struct rtl_hal_cfg *rtl_hal_cfg)
945{ 942{
946 int err; 943 int err;
947 struct ieee80211_hw *hw = NULL; 944 struct ieee80211_hw *hw = NULL;
@@ -976,7 +973,7 @@ int rtl_usb_probe(struct usb_interface *intf,
976 usb_set_intfdata(intf, hw); 973 usb_set_intfdata(intf, hw);
977 /* init cfg & intf_ops */ 974 /* init cfg & intf_ops */
978 rtlpriv->rtlhal.interface = INTF_USB; 975 rtlpriv->rtlhal.interface = INTF_USB;
979 rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_info); 976 rtlpriv->cfg = rtl_hal_cfg;
980 rtlpriv->intf_ops = &rtl_usb_ops; 977 rtlpriv->intf_ops = &rtl_usb_ops;
981 rtl_dbgp_flag_init(hw); 978 rtl_dbgp_flag_init(hw);
982 /* Init IO handler */ 979 /* Init IO handler */
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h
index 5235136f6dd2..fb986f98d1df 100644
--- a/drivers/net/wireless/rtlwifi/usb.h
+++ b/drivers/net/wireless/rtlwifi/usb.h
@@ -157,7 +157,8 @@ struct rtl_usb_priv {
157 157
158 158
159int rtl_usb_probe(struct usb_interface *intf, 159int rtl_usb_probe(struct usb_interface *intf,
160 const struct usb_device_id *id); 160 const struct usb_device_id *id,
161 struct rtl_hal_cfg *rtl92cu_hal_cfg);
161void rtl_usb_disconnect(struct usb_interface *intf); 162void rtl_usb_disconnect(struct usb_interface *intf);
162int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message); 163int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message);
163int rtl_usb_resume(struct usb_interface *pusb_intf); 164int rtl_usb_resume(struct usb_interface *pusb_intf);
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/Kconfig b/drivers/net/wireless/ti/Kconfig
index be800119d0a3..cbe1e7fef61b 100644
--- a/drivers/net/wireless/ti/Kconfig
+++ b/drivers/net/wireless/ti/Kconfig
@@ -12,4 +12,13 @@ source "drivers/net/wireless/ti/wl18xx/Kconfig"
12 12
13# keep last for automatic dependencies 13# keep last for automatic dependencies
14source "drivers/net/wireless/ti/wlcore/Kconfig" 14source "drivers/net/wireless/ti/wlcore/Kconfig"
15
16config WILINK_PLATFORM_DATA
17 bool "TI WiLink platform data"
18 depends on WLCORE_SDIO || WL1251_SDIO
19 default y
20 ---help---
21 Small platform data bit needed to pass data to the sdio modules.
22
23
15endif # WL_TI 24endif # WL_TI
diff --git a/drivers/net/wireless/ti/Makefile b/drivers/net/wireless/ti/Makefile
index 4d6823983c04..af14231aeede 100644
--- a/drivers/net/wireless/ti/Makefile
+++ b/drivers/net/wireless/ti/Makefile
@@ -1,5 +1,7 @@
1obj-$(CONFIG_WLCORE) += wlcore/ 1obj-$(CONFIG_WLCORE) += wlcore/
2obj-$(CONFIG_WL12XX) += wl12xx/ 2obj-$(CONFIG_WL12XX) += wl12xx/
3obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wlcore/
4obj-$(CONFIG_WL1251) += wl1251/ 3obj-$(CONFIG_WL1251) += wl1251/
5obj-$(CONFIG_WL18XX) += wl18xx/ 4obj-$(CONFIG_WL18XX) += wl18xx/
5
6# small builtin driver bit
7obj-$(CONFIG_WILINK_PLATFORM_DATA) += wilink_platform_data.o
diff --git a/drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
index 998e95895f9d..998e95895f9d 100644
--- a/drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c
+++ b/drivers/net/wireless/ti/wilink_platform_data.c
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..09694e39bb14 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 = {
@@ -1636,11 +1703,13 @@ static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
1636static int wl12xx_setup(struct wl1271 *wl) 1703static int wl12xx_setup(struct wl1271 *wl)
1637{ 1704{
1638 struct wl12xx_priv *priv = wl->priv; 1705 struct wl12xx_priv *priv = wl->priv;
1639 struct wl12xx_platform_data *pdata = wl->pdev->dev.platform_data; 1706 struct wlcore_platdev_data *pdev_data = wl->pdev->dev.platform_data;
1707 struct wl12xx_platform_data *pdata = pdev_data->pdata;
1640 1708
1641 wl->rtable = wl12xx_rtable; 1709 wl->rtable = wl12xx_rtable;
1642 wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS; 1710 wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
1643 wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS; 1711 wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
1712 wl->num_channels = 1;
1644 wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES; 1713 wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
1645 wl->band_rate_to_idx = wl12xx_band_rate_to_idx; 1714 wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1646 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; 1715 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
@@ -1693,6 +1762,10 @@ static int wl12xx_setup(struct wl1271 *wl)
1693 wl1271_error("Invalid tcxo parameter %s", tcxo_param); 1762 wl1271_error("Invalid tcxo parameter %s", tcxo_param);
1694 } 1763 }
1695 1764
1765 priv->rx_mem_addr = kmalloc(sizeof(*priv->rx_mem_addr), GFP_KERNEL);
1766 if (!priv->rx_mem_addr)
1767 return -ENOMEM;
1768
1696 return 0; 1769 return 0;
1697} 1770}
1698 1771
@@ -1703,7 +1776,8 @@ static int wl12xx_probe(struct platform_device *pdev)
1703 int ret; 1776 int ret;
1704 1777
1705 hw = wlcore_alloc_hw(sizeof(struct wl12xx_priv), 1778 hw = wlcore_alloc_hw(sizeof(struct wl12xx_priv),
1706 WL12XX_AGGR_BUFFER_SIZE); 1779 WL12XX_AGGR_BUFFER_SIZE,
1780 sizeof(struct wl12xx_event_mailbox));
1707 if (IS_ERR(hw)) { 1781 if (IS_ERR(hw)) {
1708 wl1271_error("can't allocate hw"); 1782 wl1271_error("can't allocate hw");
1709 ret = PTR_ERR(hw); 1783 ret = PTR_ERR(hw);
@@ -1725,6 +1799,21 @@ out:
1725 return ret; 1799 return ret;
1726} 1800}
1727 1801
1802static int wl12xx_remove(struct platform_device *pdev)
1803{
1804 struct wl1271 *wl = platform_get_drvdata(pdev);
1805 struct wl12xx_priv *priv;
1806
1807 if (!wl)
1808 goto out;
1809 priv = wl->priv;
1810
1811 kfree(priv->rx_mem_addr);
1812
1813out:
1814 return wlcore_remove(pdev);
1815}
1816
1728static const struct platform_device_id wl12xx_id_table[] = { 1817static const struct platform_device_id wl12xx_id_table[] = {
1729 { "wl12xx", 0 }, 1818 { "wl12xx", 0 },
1730 { } /* Terminating Entry */ 1819 { } /* Terminating Entry */
@@ -1733,7 +1822,7 @@ MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
1733 1822
1734static struct platform_driver wl12xx_driver = { 1823static struct platform_driver wl12xx_driver = {
1735 .probe = wl12xx_probe, 1824 .probe = wl12xx_probe,
1736 .remove = wlcore_remove, 1825 .remove = wl12xx_remove,
1737 .id_table = wl12xx_id_table, 1826 .id_table = wl12xx_id_table,
1738 .driver = { 1827 .driver = {
1739 .name = "wl12xx_driver", 1828 .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..e34302e3b51d 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 | 0x0006)
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,27 @@ 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;
73 u8 per_sub_band_rx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; 74 u8 per_chan_bo_mode_11_abg[13];
75 u8 per_chan_bo_mode_11_p[4];
74 u8 primary_clock_setting_time; 76 u8 primary_clock_setting_time;
75 u8 clock_valid_on_wake_up; 77 u8 clock_valid_on_wake_up;
76 u8 secondary_clock_setting_time; 78 u8 secondary_clock_setting_time;
77 u8 board_type; 79 u8 board_type;
78 /* enable point saturation */ 80 /* enable point saturation */
79 u8 psat; 81 u8 psat;
80 /* low/medium/high Tx power in dBm */ 82 /* low/medium/high Tx power in dBm for STA-HP BG */
81 s8 low_power_val; 83 s8 low_power_val;
82 s8 med_power_val; 84 s8 med_power_val;
83 s8 high_power_val; 85 s8 high_power_val;
86 s8 per_sub_band_tx_trace_loss[WL18XX_TRACE_LOSS_GAPS_TX];
87 s8 per_sub_band_rx_trace_loss[WL18XX_TRACE_LOSS_GAPS_RX];
88 u8 tx_rf_margin;
89 /* low/medium/high Tx power in dBm for other role */
90 s8 low_power_val_2nd;
91 s8 med_power_val_2nd;
92 s8 high_power_val_2nd;
93
84 u8 padding[1]; 94 u8 padding[1];
85} __packed; 95} __packed;
86 96
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..a10b7a7a215a 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,44 @@ 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_bo_mode_11_abg = { 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0x00, 0x00,
552 0x00, 0x00, 0x00, 0x00,
553 0x00 },
554 .per_chan_bo_mode_11_p = { 0x00, 0x00, 0x00, 0x00 },
555 .per_chan_pwr_limit_arr_11p = { 0xff, 0xff, 0xff, 0xff,
556 0xff, 0xff, 0xff },
521 .psat = 0, 557 .psat = 0,
522 .low_power_val = 0x00, 558 .low_power_val = 0x08,
523 .med_power_val = 0x0a, 559 .med_power_val = 0x12,
524 .high_power_val = 0x1e, 560 .high_power_val = 0x18,
561 .low_power_val_2nd = 0x05,
562 .med_power_val_2nd = 0x0a,
563 .high_power_val_2nd = 0x14,
525 .external_pa_dc2dc = 0, 564 .external_pa_dc2dc = 0,
526 .number_of_assembled_ant2_4 = 1, 565 .number_of_assembled_ant2_4 = 2,
527 .number_of_assembled_ant5 = 1, 566 .number_of_assembled_ant5 = 1,
567 .tx_rf_margin = 1,
528 }, 568 },
529}; 569};
530 570
@@ -595,7 +635,7 @@ static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
595}; 635};
596 636
597/* TODO: maybe move to a new header file? */ 637/* TODO: maybe move to a new header file? */
598#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw.bin" 638#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-2.bin"
599 639
600static int wl18xx_identify_chip(struct wl1271 *wl) 640static int wl18xx_identify_chip(struct wl1271 *wl)
601{ 641{
@@ -608,15 +648,18 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
608 wl->sr_fw_name = WL18XX_FW_NAME; 648 wl->sr_fw_name = WL18XX_FW_NAME;
609 /* wl18xx uses the same firmware for PLT */ 649 /* wl18xx uses the same firmware for PLT */
610 wl->plt_fw_name = WL18XX_FW_NAME; 650 wl->plt_fw_name = WL18XX_FW_NAME;
611 wl->quirks |= WLCORE_QUIRK_NO_ELP | 651 wl->quirks |= WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
612 WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
613 WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | 652 WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
614 WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN | 653 WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN |
615 WLCORE_QUIRK_TX_PAD_LAST_FRAME; 654 WLCORE_QUIRK_TX_PAD_LAST_FRAME |
616 655 WLCORE_QUIRK_REGDOMAIN_CONF |
617 wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER, WL18XX_IFTYPE_VER, 656 WLCORE_QUIRK_DUAL_PROBE_TMPL;
618 WL18XX_MAJOR_VER, WL18XX_SUBTYPE_VER, 657
619 WL18XX_MINOR_VER); 658 wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER,
659 WL18XX_IFTYPE_VER, WL18XX_MAJOR_VER,
660 WL18XX_SUBTYPE_VER, WL18XX_MINOR_VER,
661 /* there's no separate multi-role FW */
662 0, 0, 0, 0);
620 break; 663 break;
621 case CHIP_ID_185x_PG10: 664 case CHIP_ID_185x_PG10:
622 wl1271_warning("chip id 0x%x (185x PG10) is deprecated", 665 wl1271_warning("chip id 0x%x (185x PG10) is deprecated",
@@ -630,6 +673,11 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
630 goto out; 673 goto out;
631 } 674 }
632 675
676 wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
677 wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
678 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
679 wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC;
680 wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ;
633out: 681out:
634 return ret; 682 return ret;
635} 683}
@@ -843,6 +891,20 @@ static int wl18xx_boot(struct wl1271 *wl)
843 if (ret < 0) 891 if (ret < 0)
844 goto out; 892 goto out;
845 893
894 wl->event_mask = BSS_LOSS_EVENT_ID |
895 SCAN_COMPLETE_EVENT_ID |
896 RSSI_SNR_TRIGGER_0_EVENT_ID |
897 PERIODIC_SCAN_COMPLETE_EVENT_ID |
898 PERIODIC_SCAN_REPORT_EVENT_ID |
899 DUMMY_PACKET_EVENT_ID |
900 PEER_REMOVE_COMPLETE_EVENT_ID |
901 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
902 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
903 INACTIVE_STA_EVENT_ID |
904 MAX_TX_FAILURE_EVENT_ID |
905 CHANNEL_SWITCH_COMPLETE_EVENT_ID |
906 DFS_CHANNELS_CONFIG_COMPLETE_EVENT;
907
846 ret = wlcore_boot_run_firmware(wl); 908 ret = wlcore_boot_run_firmware(wl);
847 if (ret < 0) 909 if (ret < 0)
848 goto out; 910 goto out;
@@ -964,7 +1026,7 @@ static int wl18xx_hw_init(struct wl1271 *wl)
964 1026
965 /* (re)init private structures. Relevant on recovery as well. */ 1027 /* (re)init private structures. Relevant on recovery as well. */
966 priv->last_fw_rls_idx = 0; 1028 priv->last_fw_rls_idx = 0;
967 priv->extra_spare_vif_count = 0; 1029 priv->extra_spare_key_count = 0;
968 1030
969 /* set the default amount of spare blocks in the bitmap */ 1031 /* set the default amount of spare blocks in the bitmap */
970 ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE); 1032 ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE);
@@ -1022,7 +1084,12 @@ static bool wl18xx_is_mimo_supported(struct wl1271 *wl)
1022{ 1084{
1023 struct wl18xx_priv *priv = wl->priv; 1085 struct wl18xx_priv *priv = wl->priv;
1024 1086
1025 return priv->conf.phy.number_of_assembled_ant2_4 >= 2; 1087 /* only support MIMO with multiple antennas, and when SISO
1088 * is not forced through config
1089 */
1090 return (priv->conf.phy.number_of_assembled_ant2_4 >= 2) &&
1091 (priv->conf.ht.mode != HT_MODE_WIDE) &&
1092 (priv->conf.ht.mode != HT_MODE_SISO20);
1026} 1093}
1027 1094
1028/* 1095/*
@@ -1223,8 +1290,8 @@ static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
1223{ 1290{
1224 struct wl18xx_priv *priv = wl->priv; 1291 struct wl18xx_priv *priv = wl->priv;
1225 1292
1226 /* If we have VIFs requiring extra spare, indulge them */ 1293 /* If we have keys requiring extra spare, indulge them */
1227 if (priv->extra_spare_vif_count) 1294 if (priv->extra_spare_key_count)
1228 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE; 1295 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE;
1229 1296
1230 return WL18XX_TX_HW_BLOCK_SPARE; 1297 return WL18XX_TX_HW_BLOCK_SPARE;
@@ -1236,42 +1303,48 @@ static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
1236 struct ieee80211_key_conf *key_conf) 1303 struct ieee80211_key_conf *key_conf)
1237{ 1304{
1238 struct wl18xx_priv *priv = wl->priv; 1305 struct wl18xx_priv *priv = wl->priv;
1239 bool change_spare = false; 1306 bool change_spare = false, special_enc;
1240 int ret; 1307 int ret;
1241 1308
1309 wl1271_debug(DEBUG_CRYPT, "extra spare keys before: %d",
1310 priv->extra_spare_key_count);
1311
1312 special_enc = key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
1313 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
1314
1315 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
1316 if (ret < 0)
1317 goto out;
1318
1242 /* 1319 /*
1243 * when adding the first or removing the last GEM/TKIP interface, 1320 * when adding the first or removing the last GEM/TKIP key,
1244 * we have to adjust the number of spare blocks. 1321 * we have to adjust the number of spare blocks.
1245 */ 1322 */
1246 change_spare = (key_conf->cipher == WL1271_CIPHER_SUITE_GEM || 1323 if (special_enc) {
1247 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP) && 1324 if (cmd == SET_KEY) {
1248 ((priv->extra_spare_vif_count == 0 && cmd == SET_KEY) || 1325 /* first key */
1249 (priv->extra_spare_vif_count == 1 && cmd == DISABLE_KEY)); 1326 change_spare = (priv->extra_spare_key_count == 0);
1327 priv->extra_spare_key_count++;
1328 } else if (cmd == DISABLE_KEY) {
1329 /* last key */
1330 change_spare = (priv->extra_spare_key_count == 1);
1331 priv->extra_spare_key_count--;
1332 }
1333 }
1250 1334
1251 /* no need to change spare - just regular set_key */ 1335 wl1271_debug(DEBUG_CRYPT, "extra spare keys after: %d",
1252 if (!change_spare) 1336 priv->extra_spare_key_count);
1253 return wlcore_set_key(wl, cmd, vif, sta, key_conf);
1254 1337
1255 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf); 1338 if (!change_spare)
1256 if (ret < 0)
1257 goto out; 1339 goto out;
1258 1340
1259 /* key is now set, change the spare blocks */ 1341 /* key is now set, change the spare blocks */
1260 if (cmd == SET_KEY) { 1342 if (priv->extra_spare_key_count)
1261 ret = wl18xx_set_host_cfg_bitmap(wl, 1343 ret = wl18xx_set_host_cfg_bitmap(wl,
1262 WL18XX_TX_HW_EXTRA_BLOCK_SPARE); 1344 WL18XX_TX_HW_EXTRA_BLOCK_SPARE);
1263 if (ret < 0) 1345 else
1264 goto out;
1265
1266 priv->extra_spare_vif_count++;
1267 } else {
1268 ret = wl18xx_set_host_cfg_bitmap(wl, 1346 ret = wl18xx_set_host_cfg_bitmap(wl,
1269 WL18XX_TX_HW_BLOCK_SPARE); 1347 WL18XX_TX_HW_BLOCK_SPARE);
1270 if (ret < 0)
1271 goto out;
1272
1273 priv->extra_spare_vif_count--;
1274 }
1275 1348
1276out: 1349out:
1277 return ret; 1350 return ret;
@@ -1296,6 +1369,92 @@ static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1296 return buf_offset; 1369 return buf_offset;
1297} 1370}
1298 1371
1372static void wl18xx_sta_rc_update(struct wl1271 *wl,
1373 struct wl12xx_vif *wlvif,
1374 struct ieee80211_sta *sta,
1375 u32 changed)
1376{
1377 bool wide = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1378
1379 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
1380
1381 if (!(changed & IEEE80211_RC_BW_CHANGED))
1382 return;
1383
1384 mutex_lock(&wl->mutex);
1385
1386 /* sanity */
1387 if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
1388 goto out;
1389
1390 /* ignore the change before association */
1391 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1392 goto out;
1393
1394 /*
1395 * If we started out as wide, we can change the operation mode. If we
1396 * thought this was a 20mhz AP, we have to reconnect
1397 */
1398 if (wlvif->sta.role_chan_type == NL80211_CHAN_HT40MINUS ||
1399 wlvif->sta.role_chan_type == NL80211_CHAN_HT40PLUS)
1400 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
1401 else
1402 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
1403
1404out:
1405 mutex_unlock(&wl->mutex);
1406}
1407
1408static int wl18xx_set_peer_cap(struct wl1271 *wl,
1409 struct ieee80211_sta_ht_cap *ht_cap,
1410 bool allow_ht_operation,
1411 u32 rate_set, u8 hlid)
1412{
1413 return wl18xx_acx_set_peer_cap(wl, ht_cap, allow_ht_operation,
1414 rate_set, hlid);
1415}
1416
1417static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
1418 struct wl1271_link *lnk)
1419{
1420 u8 thold;
1421 struct wl18xx_fw_status_priv *status_priv =
1422 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
1423 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1424
1425 /* suspended links are never high priority */
1426 if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
1427 return false;
1428
1429 /* the priority thresholds are taken from FW */
1430 if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
1431 !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
1432 thold = status_priv->tx_fast_link_prio_threshold;
1433 else
1434 thold = status_priv->tx_slow_link_prio_threshold;
1435
1436 return lnk->allocated_pkts < thold;
1437}
1438
1439static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1440 struct wl1271_link *lnk)
1441{
1442 u8 thold;
1443 struct wl18xx_fw_status_priv *status_priv =
1444 (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
1445 u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
1446
1447 if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
1448 thold = status_priv->tx_suspend_threshold;
1449 else if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
1450 !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
1451 thold = status_priv->tx_fast_stop_threshold;
1452 else
1453 thold = status_priv->tx_slow_stop_threshold;
1454
1455 return lnk->allocated_pkts < thold;
1456}
1457
1299static int wl18xx_setup(struct wl1271 *wl); 1458static int wl18xx_setup(struct wl1271 *wl);
1300 1459
1301static struct wlcore_ops wl18xx_ops = { 1460static struct wlcore_ops wl18xx_ops = {
@@ -1305,6 +1464,8 @@ static struct wlcore_ops wl18xx_ops = {
1305 .plt_init = wl18xx_plt_init, 1464 .plt_init = wl18xx_plt_init,
1306 .trigger_cmd = wl18xx_trigger_cmd, 1465 .trigger_cmd = wl18xx_trigger_cmd,
1307 .ack_event = wl18xx_ack_event, 1466 .ack_event = wl18xx_ack_event,
1467 .wait_for_event = wl18xx_wait_for_event,
1468 .process_mailbox_events = wl18xx_process_mailbox_events,
1308 .calc_tx_blocks = wl18xx_calc_tx_blocks, 1469 .calc_tx_blocks = wl18xx_calc_tx_blocks,
1309 .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks, 1470 .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks,
1310 .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len, 1471 .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len,
@@ -1320,16 +1481,26 @@ static struct wlcore_ops wl18xx_ops = {
1320 .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, 1481 .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask,
1321 .get_mac = wl18xx_get_mac, 1482 .get_mac = wl18xx_get_mac,
1322 .debugfs_init = wl18xx_debugfs_add_files, 1483 .debugfs_init = wl18xx_debugfs_add_files,
1484 .scan_start = wl18xx_scan_start,
1485 .scan_stop = wl18xx_scan_stop,
1486 .sched_scan_start = wl18xx_sched_scan_start,
1487 .sched_scan_stop = wl18xx_scan_sched_scan_stop,
1323 .handle_static_data = wl18xx_handle_static_data, 1488 .handle_static_data = wl18xx_handle_static_data,
1324 .get_spare_blocks = wl18xx_get_spare_blocks, 1489 .get_spare_blocks = wl18xx_get_spare_blocks,
1325 .set_key = wl18xx_set_key, 1490 .set_key = wl18xx_set_key,
1491 .channel_switch = wl18xx_cmd_channel_switch,
1326 .pre_pkt_send = wl18xx_pre_pkt_send, 1492 .pre_pkt_send = wl18xx_pre_pkt_send,
1493 .sta_rc_update = wl18xx_sta_rc_update,
1494 .set_peer_cap = wl18xx_set_peer_cap,
1495 .lnk_high_prio = wl18xx_lnk_high_prio,
1496 .lnk_low_prio = wl18xx_lnk_low_prio,
1327}; 1497};
1328 1498
1329/* HT cap appropriate for wide channels in 2Ghz */ 1499/* HT cap appropriate for wide channels in 2Ghz */
1330static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = { 1500static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1331 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | 1501 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1332 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40, 1502 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40 |
1503 IEEE80211_HT_CAP_GRN_FLD,
1333 .ht_supported = true, 1504 .ht_supported = true,
1334 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1505 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1335 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1506 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1343,7 +1514,8 @@ static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
1343/* HT cap appropriate for wide channels in 5Ghz */ 1514/* HT cap appropriate for wide channels in 5Ghz */
1344static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = { 1515static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1345 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | 1516 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
1346 IEEE80211_HT_CAP_SUP_WIDTH_20_40, 1517 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1518 IEEE80211_HT_CAP_GRN_FLD,
1347 .ht_supported = true, 1519 .ht_supported = true,
1348 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1520 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1349 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1521 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1356,7 +1528,8 @@ static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
1356 1528
1357/* HT cap appropriate for SISO 20 */ 1529/* HT cap appropriate for SISO 20 */
1358static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = { 1530static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1359 .cap = IEEE80211_HT_CAP_SGI_20, 1531 .cap = IEEE80211_HT_CAP_SGI_20 |
1532 IEEE80211_HT_CAP_GRN_FLD,
1360 .ht_supported = true, 1533 .ht_supported = true,
1361 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1534 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1362 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1535 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1369,7 +1542,8 @@ static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
1369 1542
1370/* HT cap appropriate for MIMO rates in 20mhz channel */ 1543/* HT cap appropriate for MIMO rates in 20mhz channel */
1371static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { 1544static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
1372 .cap = IEEE80211_HT_CAP_SGI_20, 1545 .cap = IEEE80211_HT_CAP_SGI_20 |
1546 IEEE80211_HT_CAP_GRN_FLD,
1373 .ht_supported = true, 1547 .ht_supported = true,
1374 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1548 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
1375 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1549 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@@ -1387,7 +1561,8 @@ static int wl18xx_setup(struct wl1271 *wl)
1387 1561
1388 wl->rtable = wl18xx_rtable; 1562 wl->rtable = wl18xx_rtable;
1389 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS; 1563 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
1390 wl->num_rx_desc = WL18XX_NUM_TX_DESCRIPTORS; 1564 wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
1565 wl->num_channels = 2;
1391 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES; 1566 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
1392 wl->band_rate_to_idx = wl18xx_band_rate_to_idx; 1567 wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
1393 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; 1568 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
@@ -1506,7 +1681,8 @@ static int wl18xx_probe(struct platform_device *pdev)
1506 int ret; 1681 int ret;
1507 1682
1508 hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv), 1683 hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv),
1509 WL18XX_AGGR_BUFFER_SIZE); 1684 WL18XX_AGGR_BUFFER_SIZE,
1685 sizeof(struct wl18xx_event_mailbox));
1510 if (IS_ERR(hw)) { 1686 if (IS_ERR(hw)) {
1511 wl1271_error("can't allocate hw"); 1687 wl1271_error("can't allocate hw");
1512 ret = PTR_ERR(hw); 1688 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/Kconfig b/drivers/net/wireless/ti/wlcore/Kconfig
index d7b907e67170..2b832825c3d4 100644
--- a/drivers/net/wireless/ti/wlcore/Kconfig
+++ b/drivers/net/wireless/ti/wlcore/Kconfig
@@ -33,8 +33,3 @@ config WLCORE_SDIO
33 33
34 If you choose to build a module, it'll be called wlcore_sdio. 34 If you choose to build a module, it'll be called wlcore_sdio.
35 Say N if unsure. 35 Say N if unsure.
36
37config WL12XX_PLATFORM_DATA
38 bool
39 depends on WLCORE_SDIO != n || WL1251_SDIO != n
40 default y
diff --git a/drivers/net/wireless/ti/wlcore/Makefile b/drivers/net/wireless/ti/wlcore/Makefile
index d9fba9e32130..b21398f6c3ec 100644
--- a/drivers/net/wireless/ti/wlcore/Makefile
+++ b/drivers/net/wireless/ti/wlcore/Makefile
@@ -9,7 +9,4 @@ obj-$(CONFIG_WLCORE) += wlcore.o
9obj-$(CONFIG_WLCORE_SPI) += wlcore_spi.o 9obj-$(CONFIG_WLCORE_SPI) += wlcore_spi.o
10obj-$(CONFIG_WLCORE_SDIO) += wlcore_sdio.o 10obj-$(CONFIG_WLCORE_SDIO) += wlcore_sdio.o
11 11
12# small builtin driver bit
13obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
14
15ccflags-y += -D__CHECK_ENDIAN__ 12ccflags-y += -D__CHECK_ENDIAN__
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..77752b03f189 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_MULTI) ?
88 wl->min_mr_fw_ver : wl->min_sr_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..6331f9e1cb39 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,8 +508,14 @@ 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];
472 cmd->sta.remote_rates = cpu_to_le32(wlvif->rate_set); 512 /*
513 * We don't have the correct remote rates in this stage. The
514 * rates will be reconfigured later, after association, if the
515 * firmware supports ACX_PEER_CAP. Otherwise, there's nothing
516 * we can do, so use all supported_rates here.
517 */
518 cmd->sta.remote_rates = cpu_to_le32(supported_rates);
473 519
474 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d " 520 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d "
475 "basic_rate_set: 0x%x, remote_rates: 0x%x", 521 "basic_rate_set: 0x%x, remote_rates: 0x%x",
@@ -482,6 +528,7 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
482 goto err_hlid; 528 goto err_hlid;
483 } 529 }
484 530
531 wlvif->sta.role_chan_type = wlvif->channel_type;
485 goto out_free; 532 goto out_free;
486 533
487err_hlid: 534err_hlid:
@@ -500,7 +547,6 @@ int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
500{ 547{
501 struct wl12xx_cmd_role_stop *cmd; 548 struct wl12xx_cmd_role_stop *cmd;
502 int ret; 549 int ret;
503 bool timeout = false;
504 550
505 if (WARN_ON(wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)) 551 if (WARN_ON(wlvif->sta.hlid == WL12XX_INVALID_LINK_ID))
506 return -EINVAL; 552 return -EINVAL;
@@ -523,17 +569,6 @@ int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
523 goto out_free; 569 goto out_free;
524 } 570 }
525 571
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); 572 wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid);
538 573
539out_free: 574out_free:
@@ -579,12 +614,15 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
579 cmd->ap.bss_index = WL1271_AP_BSS_INDEX; 614 cmd->ap.bss_index = WL1271_AP_BSS_INDEX;
580 cmd->ap.global_hlid = wlvif->ap.global_hlid; 615 cmd->ap.global_hlid = wlvif->ap.global_hlid;
581 cmd->ap.broadcast_hlid = wlvif->ap.bcast_hlid; 616 cmd->ap.broadcast_hlid = wlvif->ap.bcast_hlid;
617 cmd->ap.global_session_id = wl->session_ids[wlvif->ap.global_hlid];
618 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); 619 cmd->ap.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
583 cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int); 620 cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int);
584 cmd->ap.dtim_interval = bss_conf->dtim_period; 621 cmd->ap.dtim_interval = bss_conf->dtim_period;
585 cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP; 622 cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
586 /* FIXME: Change when adding DFS */ 623 /* FIXME: Change when adding DFS */
587 cmd->ap.reset_tsf = 1; /* By default reset AP TSF */ 624 cmd->ap.reset_tsf = 1; /* By default reset AP TSF */
625 cmd->ap.wmm = wlvif->wmm_enabled;
588 cmd->channel = wlvif->channel; 626 cmd->channel = wlvif->channel;
589 cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type); 627 cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type);
590 628
@@ -599,8 +637,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); 637 memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len);
600 } 638 }
601 639
602 supported_rates = CONF_TX_AP_ENABLED_RATES | CONF_TX_MCS_RATES | 640 supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES |
603 wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif); 641 wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif);
642 if (wlvif->p2p)
643 supported_rates &= ~CONF_TX_CCK_RATES;
604 644
605 wl1271_debug(DEBUG_CMD, "cmd role start ap with supported_rates 0x%08x", 645 wl1271_debug(DEBUG_CMD, "cmd role start ap with supported_rates 0x%08x",
606 supported_rates); 646 supported_rates);
@@ -799,8 +839,11 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
799 * @id: acx id 839 * @id: acx id
800 * @buf: buffer containing acx, including all headers, must work with dma 840 * @buf: buffer containing acx, including all headers, must work with dma
801 * @len: length of buf 841 * @len: length of buf
842 * @valid_rets: bitmap of valid cmd status codes (i.e. return values).
843 * return the cmd status on success.
802 */ 844 */
803int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len) 845int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf,
846 size_t len, unsigned long valid_rets)
804{ 847{
805 struct acx_header *acx = buf; 848 struct acx_header *acx = buf;
806 int ret; 849 int ret;
@@ -812,12 +855,26 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
812 /* payload length, does not include any headers */ 855 /* payload length, does not include any headers */
813 acx->len = cpu_to_le16(len - sizeof(*acx)); 856 acx->len = cpu_to_le16(len - sizeof(*acx));
814 857
815 ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len, 0); 858 ret = wlcore_cmd_send_failsafe(wl, CMD_CONFIGURE, acx, len, 0,
859 valid_rets);
816 if (ret < 0) { 860 if (ret < 0) {
817 wl1271_warning("CONFIGURE command NOK"); 861 wl1271_warning("CONFIGURE command NOK");
818 return ret; 862 return ret;
819 } 863 }
820 864
865 return ret;
866}
867
868/*
869 * wrapper for wlcore_cmd_configure that accepts only success status.
870 * return 0 on success
871 */
872int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
873{
874 int ret = wlcore_cmd_configure_failsafe(wl, id, buf, len, 0);
875
876 if (ret < 0)
877 return ret;
821 return 0; 878 return 0;
822} 879}
823EXPORT_SYMBOL_GPL(wl1271_cmd_configure); 880EXPORT_SYMBOL_GPL(wl1271_cmd_configure);
@@ -1034,8 +1091,8 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1034 struct sk_buff *skb; 1091 struct sk_buff *skb;
1035 int ret; 1092 int ret;
1036 u32 rate; 1093 u32 rate;
1037 u16 template_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4; 1094 u16 template_id_2_4 = wl->scan_templ_id_2_4;
1038 u16 template_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5; 1095 u16 template_id_5 = wl->scan_templ_id_5;
1039 1096
1040 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len, 1097 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
1041 ie_len); 1098 ie_len);
@@ -1048,10 +1105,10 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1048 1105
1049 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); 1106 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
1050 1107
1051 if (!sched_scan && 1108 if (sched_scan &&
1052 (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) { 1109 (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) {
1053 template_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4; 1110 template_id_2_4 = wl->sched_scan_templ_id_2_4;
1054 template_id_5 = CMD_TEMPL_APP_PROBE_REQ_5; 1111 template_id_5 = wl->sched_scan_templ_id_5;
1055 } 1112 }
1056 1113
1057 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]); 1114 rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
@@ -1068,6 +1125,7 @@ out:
1068 dev_kfree_skb(skb); 1125 dev_kfree_skb(skb);
1069 return ret; 1126 return ret;
1070} 1127}
1128EXPORT_SYMBOL_GPL(wl12xx_cmd_build_probe_req);
1071 1129
1072struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, 1130struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
1073 struct wl12xx_vif *wlvif, 1131 struct wl12xx_vif *wlvif,
@@ -1379,7 +1437,8 @@ out:
1379 return ret; 1437 return ret;
1380} 1438}
1381 1439
1382int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid) 1440int wl12xx_cmd_set_peer_state(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1441 u8 hlid)
1383{ 1442{
1384 struct wl12xx_cmd_set_peer_state *cmd; 1443 struct wl12xx_cmd_set_peer_state *cmd;
1385 int ret = 0; 1444 int ret = 0;
@@ -1395,6 +1454,10 @@ int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid)
1395 cmd->hlid = hlid; 1454 cmd->hlid = hlid;
1396 cmd->state = WL1271_CMD_STA_STATE_CONNECTED; 1455 cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
1397 1456
1457 /* wmm param is valid only for station role */
1458 if (wlvif->bss_type == BSS_TYPE_STA_BSS)
1459 cmd->wmm = wlvif->wmm_enabled;
1460
1398 ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0); 1461 ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0);
1399 if (ret < 0) { 1462 if (ret < 0) {
1400 wl1271_error("failed to send set peer state command"); 1463 wl1271_error("failed to send set peer state command");
@@ -1429,6 +1492,7 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1429 cmd->hlid = hlid; 1492 cmd->hlid = hlid;
1430 cmd->sp_len = sta->max_sp; 1493 cmd->sp_len = sta->max_sp;
1431 cmd->wmm = sta->wme ? 1 : 0; 1494 cmd->wmm = sta->wme ? 1 : 0;
1495 cmd->session_id = wl->session_ids[hlid];
1432 1496
1433 for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++) 1497 for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++)
1434 if (sta->wme && (sta->uapsd_queues & BIT(i))) 1498 if (sta->wme && (sta->uapsd_queues & BIT(i)))
@@ -1490,9 +1554,10 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid)
1490 goto out_free; 1554 goto out_free;
1491 } 1555 }
1492 1556
1493 ret = wl1271_cmd_wait_for_event_or_timeout(wl, 1557 ret = wl->ops->wait_for_event(wl,
1494 PEER_REMOVE_COMPLETE_EVENT_ID, 1558 WLCORE_EVENT_PEER_REMOVE_COMPLETE,
1495 &timeout); 1559 &timeout);
1560
1496 /* 1561 /*
1497 * We are ok with a timeout here. The event is sometimes not sent 1562 * 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) 1563 * due to a firmware bug. In case of another error (like SDIO timeout)
@@ -1508,6 +1573,131 @@ out:
1508 return ret; 1573 return ret;
1509} 1574}
1510 1575
1576static int wlcore_get_reg_conf_ch_idx(enum ieee80211_band band, u16 ch)
1577{
1578 int idx = -1;
1579
1580 switch (band) {
1581 case IEEE80211_BAND_5GHZ:
1582 if (ch >= 8 && ch <= 16)
1583 idx = ((ch-8)/4 + 18);
1584 else if (ch >= 34 && ch <= 64)
1585 idx = ((ch-34)/2 + 3 + 18);
1586 else if (ch >= 100 && ch <= 140)
1587 idx = ((ch-100)/4 + 15 + 18);
1588 else if (ch >= 149 && ch <= 165)
1589 idx = ((ch-149)/4 + 26 + 18);
1590 else
1591 idx = -1;
1592 break;
1593 case IEEE80211_BAND_2GHZ:
1594 if (ch >= 1 && ch <= 14)
1595 idx = ch - 1;
1596 else
1597 idx = -1;
1598 break;
1599 default:
1600 wl1271_error("get reg conf ch idx - unknown band: %d",
1601 (int)band);
1602 }
1603
1604 return idx;
1605}
1606
1607void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel,
1608 enum ieee80211_band band)
1609{
1610 int ch_bit_idx = 0;
1611
1612 if (!(wl->quirks & WLCORE_QUIRK_REGDOMAIN_CONF))
1613 return;
1614
1615 ch_bit_idx = wlcore_get_reg_conf_ch_idx(band, channel);
1616
1617 if (ch_bit_idx > 0 && ch_bit_idx <= WL1271_MAX_CHANNELS)
1618 set_bit(ch_bit_idx, (long *)wl->reg_ch_conf_pending);
1619}
1620
1621int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
1622{
1623 struct wl12xx_cmd_regdomain_dfs_config *cmd = NULL;
1624 int ret = 0, i, b, ch_bit_idx;
1625 struct ieee80211_channel *channel;
1626 u32 tmp_ch_bitmap[2];
1627 u16 ch;
1628 struct wiphy *wiphy = wl->hw->wiphy;
1629 struct ieee80211_supported_band *band;
1630 bool timeout = false;
1631
1632 if (!(wl->quirks & WLCORE_QUIRK_REGDOMAIN_CONF))
1633 return 0;
1634
1635 wl1271_debug(DEBUG_CMD, "cmd reg domain config");
1636
1637 memset(tmp_ch_bitmap, 0, sizeof(tmp_ch_bitmap));
1638
1639 for (b = IEEE80211_BAND_2GHZ; b <= IEEE80211_BAND_5GHZ; b++) {
1640 band = wiphy->bands[b];
1641 for (i = 0; i < band->n_channels; i++) {
1642 channel = &band->channels[i];
1643 ch = channel->hw_value;
1644
1645 if (channel->flags & (IEEE80211_CHAN_DISABLED |
1646 IEEE80211_CHAN_RADAR |
1647 IEEE80211_CHAN_PASSIVE_SCAN))
1648 continue;
1649
1650 ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch);
1651 if (ch_bit_idx < 0)
1652 continue;
1653
1654 set_bit(ch_bit_idx, (long *)tmp_ch_bitmap);
1655 }
1656 }
1657
1658 tmp_ch_bitmap[0] |= wl->reg_ch_conf_pending[0];
1659 tmp_ch_bitmap[1] |= wl->reg_ch_conf_pending[1];
1660
1661 if (!memcmp(tmp_ch_bitmap, wl->reg_ch_conf_last, sizeof(tmp_ch_bitmap)))
1662 goto out;
1663
1664 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1665 if (!cmd) {
1666 ret = -ENOMEM;
1667 goto out;
1668 }
1669
1670 cmd->ch_bit_map1 = cpu_to_le32(tmp_ch_bitmap[0]);
1671 cmd->ch_bit_map2 = cpu_to_le32(tmp_ch_bitmap[1]);
1672
1673 wl1271_debug(DEBUG_CMD,
1674 "cmd reg domain bitmap1: 0x%08x, bitmap2: 0x%08x",
1675 cmd->ch_bit_map1, cmd->ch_bit_map2);
1676
1677 ret = wl1271_cmd_send(wl, CMD_DFS_CHANNEL_CONFIG, cmd, sizeof(*cmd), 0);
1678 if (ret < 0) {
1679 wl1271_error("failed to send reg domain dfs config");
1680 goto out;
1681 }
1682
1683 ret = wl->ops->wait_for_event(wl,
1684 WLCORE_EVENT_DFS_CONFIG_COMPLETE,
1685 &timeout);
1686 if (ret < 0 || timeout) {
1687 wl1271_error("reg domain conf %serror",
1688 timeout ? "completion " : "");
1689 ret = timeout ? -ETIMEDOUT : ret;
1690 goto out;
1691 }
1692
1693 memcpy(wl->reg_ch_conf_last, tmp_ch_bitmap, sizeof(tmp_ch_bitmap));
1694 memset(wl->reg_ch_conf_pending, 0, sizeof(wl->reg_ch_conf_pending));
1695
1696out:
1697 kfree(cmd);
1698 return ret;
1699}
1700
1511int wl12xx_cmd_config_fwlog(struct wl1271 *wl) 1701int wl12xx_cmd_config_fwlog(struct wl1271 *wl)
1512{ 1702{
1513 struct wl12xx_cmd_config_fwlog *cmd; 1703 struct wl12xx_cmd_config_fwlog *cmd;
@@ -1593,12 +1783,12 @@ out:
1593} 1783}
1594 1784
1595static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1785static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1596 u8 role_id) 1786 u8 role_id, enum ieee80211_band band, u8 channel)
1597{ 1787{
1598 struct wl12xx_cmd_roc *cmd; 1788 struct wl12xx_cmd_roc *cmd;
1599 int ret = 0; 1789 int ret = 0;
1600 1790
1601 wl1271_debug(DEBUG_CMD, "cmd roc %d (%d)", wlvif->channel, role_id); 1791 wl1271_debug(DEBUG_CMD, "cmd roc %d (%d)", channel, role_id);
1602 1792
1603 if (WARN_ON(role_id == WL12XX_INVALID_ROLE_ID)) 1793 if (WARN_ON(role_id == WL12XX_INVALID_ROLE_ID))
1604 return -EINVAL; 1794 return -EINVAL;
@@ -1610,8 +1800,8 @@ static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1610 } 1800 }
1611 1801
1612 cmd->role_id = role_id; 1802 cmd->role_id = role_id;
1613 cmd->channel = wlvif->channel; 1803 cmd->channel = channel;
1614 switch (wlvif->band) { 1804 switch (band) {
1615 case IEEE80211_BAND_2GHZ: 1805 case IEEE80211_BAND_2GHZ:
1616 cmd->band = WLCORE_BAND_2_4GHZ; 1806 cmd->band = WLCORE_BAND_2_4GHZ;
1617 break; 1807 break;
@@ -1666,30 +1856,18 @@ out:
1666 return ret; 1856 return ret;
1667} 1857}
1668 1858
1669int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id) 1859int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id,
1860 enum ieee80211_band band, u8 channel)
1670{ 1861{
1671 int ret = 0; 1862 int ret = 0;
1672 bool is_first_roc;
1673 1863
1674 if (WARN_ON(test_bit(role_id, wl->roc_map))) 1864 if (WARN_ON(test_bit(role_id, wl->roc_map)))
1675 return 0; 1865 return 0;
1676 1866
1677 is_first_roc = (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= 1867 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) 1868 if (ret < 0)
1682 goto out; 1869 goto out;
1683 1870
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); 1871 __set_bit(role_id, wl->roc_map);
1694out: 1872out:
1695 return ret; 1873 return ret;
@@ -1719,43 +1897,7 @@ out:
1719 return ret; 1897 return ret;
1720} 1898}
1721 1899
1722int wl12xx_cmd_channel_switch(struct wl1271 *wl, 1900int 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{ 1901{
1760 struct wl12xx_cmd_stop_channel_switch *cmd; 1902 struct wl12xx_cmd_stop_channel_switch *cmd;
1761 int ret; 1903 int ret;
@@ -1768,6 +1910,8 @@ int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl)
1768 goto out; 1910 goto out;
1769 } 1911 }
1770 1912
1913 cmd->role_id = wlvif->role_id;
1914
1771 ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0); 1915 ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0);
1772 if (ret < 0) { 1916 if (ret < 0) {
1773 wl1271_error("failed to stop channel switch command"); 1917 wl1271_error("failed to stop channel switch command");
@@ -1782,7 +1926,8 @@ out:
1782} 1926}
1783 1927
1784/* start dev role and roc on its channel */ 1928/* start dev role and roc on its channel */
1785int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) 1929int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1930 enum ieee80211_band band, int channel)
1786{ 1931{
1787 int ret; 1932 int ret;
1788 1933
@@ -1797,11 +1942,11 @@ int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1797 if (ret < 0) 1942 if (ret < 0)
1798 goto out; 1943 goto out;
1799 1944
1800 ret = wl12xx_cmd_role_start_dev(wl, wlvif); 1945 ret = wl12xx_cmd_role_start_dev(wl, wlvif, band, channel);
1801 if (ret < 0) 1946 if (ret < 0)
1802 goto out_disable; 1947 goto out_disable;
1803 1948
1804 ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id); 1949 ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id, band, channel);
1805 if (ret < 0) 1950 if (ret < 0)
1806 goto out_stop; 1951 goto out_stop;
1807 1952
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 919ad70cc520..28a37576d568 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,
@@ -2070,7 +2162,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
2070 return 0; 2162 return 0;
2071} 2163}
2072 2164
2073static bool wl12xx_init_fw(struct wl1271 *wl) 2165static int wl12xx_init_fw(struct wl1271 *wl)
2074{ 2166{
2075 int retries = WL1271_BOOT_RETRIES; 2167 int retries = WL1271_BOOT_RETRIES;
2076 bool booted = false; 2168 bool booted = false;
@@ -2136,7 +2228,7 @@ power_off:
2136 2228
2137 wl->state = WLCORE_STATE_ON; 2229 wl->state = WLCORE_STATE_ON;
2138out: 2230out:
2139 return booted; 2231 return ret;
2140} 2232}
2141 2233
2142static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif) 2234static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif)
@@ -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{
@@ -2204,7 +2371,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
2204 struct vif_counter_data vif_count; 2371 struct vif_counter_data vif_count;
2205 int ret = 0; 2372 int ret = 0;
2206 u8 role_type; 2373 u8 role_type;
2207 bool booted = false;
2208 2374
2209 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 2375 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
2210 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 2376 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
@@ -2242,6 +2408,10 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
2242 goto out; 2408 goto out;
2243 } 2409 }
2244 2410
2411 ret = wlcore_allocate_hw_queue_base(wl, wlvif);
2412 if (ret < 0)
2413 goto out;
2414
2245 if (wl12xx_need_fw_change(wl, vif_count, true)) { 2415 if (wl12xx_need_fw_change(wl, vif_count, true)) {
2246 wl12xx_force_active_psm(wl); 2416 wl12xx_force_active_psm(wl);
2247 set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); 2417 set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
@@ -2261,11 +2431,9 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
2261 */ 2431 */
2262 memcpy(wl->addresses[0].addr, vif->addr, ETH_ALEN); 2432 memcpy(wl->addresses[0].addr, vif->addr, ETH_ALEN);
2263 2433
2264 booted = wl12xx_init_fw(wl); 2434 ret = wl12xx_init_fw(wl);
2265 if (!booted) { 2435 if (ret < 0)
2266 ret = -EINVAL;
2267 goto out; 2436 goto out;
2268 }
2269 } 2437 }
2270 2438
2271 ret = wl12xx_cmd_role_enable(wl, vif->addr, 2439 ret = wl12xx_cmd_role_enable(wl, vif->addr,
@@ -2312,7 +2480,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2312 wl1271_info("down"); 2480 wl1271_info("down");
2313 2481
2314 if (wl->scan.state != WL1271_SCAN_STATE_IDLE && 2482 if (wl->scan.state != WL1271_SCAN_STATE_IDLE &&
2315 wl->scan_vif == vif) { 2483 wl->scan_wlvif == wlvif) {
2316 /* 2484 /*
2317 * Rearm the tx watchdog just before idling scan. This 2485 * Rearm the tx watchdog just before idling scan. This
2318 * prevents just-finished scans from triggering the watchdog 2486 * prevents just-finished scans from triggering the watchdog
@@ -2321,11 +2489,21 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
2321 2489
2322 wl->scan.state = WL1271_SCAN_STATE_IDLE; 2490 wl->scan.state = WL1271_SCAN_STATE_IDLE;
2323 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 2491 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
2324 wl->scan_vif = NULL; 2492 wl->scan_wlvif = NULL;
2325 wl->scan.req = NULL; 2493 wl->scan.req = NULL;
2326 ieee80211_scan_completed(wl->hw, true); 2494 ieee80211_scan_completed(wl->hw, true);
2327 } 2495 }
2328 2496
2497 if (wl->sched_vif == wlvif) {
2498 ieee80211_sched_scan_stopped(wl->hw);
2499 wl->sched_vif = NULL;
2500 }
2501
2502 if (wl->roc_vif == vif) {
2503 wl->roc_vif = NULL;
2504 ieee80211_remain_on_channel_expired(wl->hw);
2505 }
2506
2329 if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) { 2507 if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) {
2330 /* disable active roles */ 2508 /* disable active roles */
2331 ret = wl1271_ps_elp_wakeup(wl); 2509 ret = wl1271_ps_elp_wakeup(wl);
@@ -2394,9 +2572,6 @@ deinit:
2394 /* Configure for power according to debugfs */ 2572 /* Configure for power according to debugfs */
2395 if (sta_auth != WL1271_PSM_ILLEGAL) 2573 if (sta_auth != WL1271_PSM_ILLEGAL)
2396 wl1271_acx_sleep_auth(wl, sta_auth); 2574 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 */ 2575 /* Configure for ELP power saving */
2401 else 2576 else
2402 wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); 2577 wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
@@ -2408,6 +2583,7 @@ unlock:
2408 del_timer_sync(&wlvif->rx_streaming_timer); 2583 del_timer_sync(&wlvif->rx_streaming_timer);
2409 cancel_work_sync(&wlvif->rx_streaming_enable_work); 2584 cancel_work_sync(&wlvif->rx_streaming_enable_work);
2410 cancel_work_sync(&wlvif->rx_streaming_disable_work); 2585 cancel_work_sync(&wlvif->rx_streaming_disable_work);
2586 cancel_delayed_work_sync(&wlvif->connection_loss_work);
2411 2587
2412 mutex_lock(&wl->mutex); 2588 mutex_lock(&wl->mutex);
2413} 2589}
@@ -2466,8 +2642,7 @@ static int wl12xx_op_change_interface(struct ieee80211_hw *hw,
2466 return ret; 2642 return ret;
2467} 2643}
2468 2644
2469static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif, 2645static int wlcore_join(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2470 bool set_assoc)
2471{ 2646{
2472 int ret; 2647 int ret;
2473 bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS); 2648 bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
@@ -2487,18 +2662,111 @@ static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2487 /* clear encryption type */ 2662 /* clear encryption type */
2488 wlvif->encryption_type = KEY_NONE; 2663 wlvif->encryption_type = KEY_NONE;
2489 2664
2490 if (set_assoc)
2491 set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags);
2492
2493 if (is_ibss) 2665 if (is_ibss)
2494 ret = wl12xx_cmd_role_start_ibss(wl, wlvif); 2666 ret = wl12xx_cmd_role_start_ibss(wl, wlvif);
2495 else 2667 else {
2668 if (wl->quirks & WLCORE_QUIRK_START_STA_FAILS) {
2669 /*
2670 * TODO: this is an ugly workaround for wl12xx fw
2671 * bug - we are not able to tx/rx after the first
2672 * start_sta, so make dummy start+stop calls,
2673 * and then call start_sta again.
2674 * this should be fixed in the fw.
2675 */
2676 wl12xx_cmd_role_start_sta(wl, wlvif);
2677 wl12xx_cmd_role_stop_sta(wl, wlvif);
2678 }
2679
2496 ret = wl12xx_cmd_role_start_sta(wl, wlvif); 2680 ret = wl12xx_cmd_role_start_sta(wl, wlvif);
2681 }
2682
2683 return ret;
2684}
2685
2686static int wl1271_ssid_set(struct wl12xx_vif *wlvif, struct sk_buff *skb,
2687 int offset)
2688{
2689 u8 ssid_len;
2690 const u8 *ptr = cfg80211_find_ie(WLAN_EID_SSID, skb->data + offset,
2691 skb->len - offset);
2692
2693 if (!ptr) {
2694 wl1271_error("No SSID in IEs!");
2695 return -ENOENT;
2696 }
2697
2698 ssid_len = ptr[1];
2699 if (ssid_len > IEEE80211_MAX_SSID_LEN) {
2700 wl1271_error("SSID is too long!");
2701 return -EINVAL;
2702 }
2703
2704 wlvif->ssid_len = ssid_len;
2705 memcpy(wlvif->ssid, ptr+2, ssid_len);
2706 return 0;
2707}
2708
2709static int wlcore_set_ssid(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2710{
2711 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
2712 struct sk_buff *skb;
2713 int ieoffset;
2714
2715 /* we currently only support setting the ssid from the ap probe req */
2716 if (wlvif->bss_type != BSS_TYPE_STA_BSS)
2717 return -EINVAL;
2718
2719 skb = ieee80211_ap_probereq_get(wl->hw, vif);
2720 if (!skb)
2721 return -EINVAL;
2722
2723 ieoffset = offsetof(struct ieee80211_mgmt,
2724 u.probe_req.variable);
2725 wl1271_ssid_set(wlvif, skb, ieoffset);
2726 dev_kfree_skb(skb);
2727
2728 return 0;
2729}
2730
2731static int wlcore_set_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2732 struct ieee80211_bss_conf *bss_conf,
2733 u32 sta_rate_set)
2734{
2735 int ieoffset;
2736 int ret;
2737
2738 wlvif->aid = bss_conf->aid;
2739 wlvif->channel_type = cfg80211_get_chandef_type(&bss_conf->chandef);
2740 wlvif->beacon_int = bss_conf->beacon_int;
2741 wlvif->wmm_enabled = bss_conf->qos;
2742
2743 set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags);
2744
2745 /*
2746 * with wl1271, we don't need to update the
2747 * beacon_int and dtim_period, because the firmware
2748 * updates it by itself when the first beacon is
2749 * received after a join.
2750 */
2751 ret = wl1271_cmd_build_ps_poll(wl, wlvif, wlvif->aid);
2497 if (ret < 0) 2752 if (ret < 0)
2498 goto out; 2753 return ret;
2499 2754
2500 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 2755 /*
2501 goto out; 2756 * Get a template for hardware connection maintenance
2757 */
2758 dev_kfree_skb(wlvif->probereq);
2759 wlvif->probereq = wl1271_cmd_build_ap_probe_req(wl,
2760 wlvif,
2761 NULL);
2762 ieoffset = offsetof(struct ieee80211_mgmt,
2763 u.probe_req.variable);
2764 wl1271_ssid_set(wlvif, wlvif->probereq, ieoffset);
2765
2766 /* enable the connection monitoring feature */
2767 ret = wl1271_acx_conn_monit_params(wl, wlvif, true);
2768 if (ret < 0)
2769 return ret;
2502 2770
2503 /* 2771 /*
2504 * The join command disable the keep-alive mode, shut down its process, 2772 * The join command disable the keep-alive mode, shut down its process,
@@ -2508,35 +2776,83 @@ static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2508 */ 2776 */
2509 ret = wl1271_acx_keep_alive_mode(wl, wlvif, true); 2777 ret = wl1271_acx_keep_alive_mode(wl, wlvif, true);
2510 if (ret < 0) 2778 if (ret < 0)
2511 goto out; 2779 return ret;
2512 2780
2513 ret = wl1271_acx_aid(wl, wlvif, wlvif->aid); 2781 ret = wl1271_acx_aid(wl, wlvif, wlvif->aid);
2514 if (ret < 0) 2782 if (ret < 0)
2515 goto out; 2783 return ret;
2516 2784
2517 ret = wl12xx_cmd_build_klv_null_data(wl, wlvif); 2785 ret = wl12xx_cmd_build_klv_null_data(wl, wlvif);
2518 if (ret < 0) 2786 if (ret < 0)
2519 goto out; 2787 return ret;
2520 2788
2521 ret = wl1271_acx_keep_alive_config(wl, wlvif, 2789 ret = wl1271_acx_keep_alive_config(wl, wlvif,
2522 wlvif->sta.klv_template_id, 2790 wlvif->sta.klv_template_id,
2523 ACX_KEEP_ALIVE_TPL_VALID); 2791 ACX_KEEP_ALIVE_TPL_VALID);
2524 if (ret < 0) 2792 if (ret < 0)
2525 goto out; 2793 return ret;
2794
2795 /*
2796 * The default fw psm configuration is AUTO, while mac80211 default
2797 * setting is off (ACTIVE), so sync the fw with the correct value.
2798 */
2799 ret = wl1271_ps_set_mode(wl, wlvif, STATION_ACTIVE_MODE);
2800 if (ret < 0)
2801 return ret;
2802
2803 if (sta_rate_set) {
2804 wlvif->rate_set =
2805 wl1271_tx_enabled_rates_get(wl,
2806 sta_rate_set,
2807 wlvif->band);
2808 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
2809 if (ret < 0)
2810 return ret;
2811 }
2526 2812
2527out:
2528 return ret; 2813 return ret;
2529} 2814}
2530 2815
2531static int wl1271_unjoin(struct wl1271 *wl, struct wl12xx_vif *wlvif) 2816static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2532{ 2817{
2533 int ret; 2818 int ret;
2819 bool sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
2820
2821 /* make sure we are connected (sta) joined */
2822 if (sta &&
2823 !test_and_clear_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
2824 return false;
2825
2826 /* make sure we are joined (ibss) */
2827 if (!sta &&
2828 test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags))
2829 return false;
2830
2831 if (sta) {
2832 /* use defaults when not associated */
2833 wlvif->aid = 0;
2834
2835 /* free probe-request template */
2836 dev_kfree_skb(wlvif->probereq);
2837 wlvif->probereq = NULL;
2838
2839 /* disable connection monitor features */
2840 ret = wl1271_acx_conn_monit_params(wl, wlvif, false);
2841 if (ret < 0)
2842 return ret;
2843
2844 /* Disable the keep-alive feature */
2845 ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
2846 if (ret < 0)
2847 return ret;
2848 }
2534 2849
2535 if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) { 2850 if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) {
2536 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 2851 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
2537 2852
2538 wl12xx_cmd_stop_channel_switch(wl); 2853 wl12xx_cmd_stop_channel_switch(wl, wlvif);
2539 ieee80211_chswitch_done(vif, false); 2854 ieee80211_chswitch_done(vif, false);
2855 cancel_delayed_work(&wlvif->channel_switch_work);
2540 } 2856 }
2541 2857
2542 /* invalidate keep-alive template */ 2858 /* invalidate keep-alive template */
@@ -2544,17 +2860,11 @@ static int wl1271_unjoin(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2544 wlvif->sta.klv_template_id, 2860 wlvif->sta.klv_template_id,
2545 ACX_KEEP_ALIVE_TPL_INVALID); 2861 ACX_KEEP_ALIVE_TPL_INVALID);
2546 2862
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 */ 2863 /* reset TX security counters on a clean disconnect */
2553 wlvif->tx_security_last_seq_lsb = 0; 2864 wlvif->tx_security_last_seq_lsb = 0;
2554 wlvif->tx_security_seq = 0; 2865 wlvif->tx_security_seq = 0;
2555 2866
2556out: 2867 return 0;
2557 return ret;
2558} 2868}
2559 2869
2560static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif) 2870static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
@@ -2563,147 +2873,10 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2563 wlvif->rate_set = wlvif->basic_rate_set; 2873 wlvif->rate_set = wlvif->basic_rate_set;
2564} 2874}
2565 2875
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, 2876static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2606 struct ieee80211_conf *conf, u32 changed) 2877 struct ieee80211_conf *conf, u32 changed)
2607{ 2878{
2608 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 2879 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 2880
2708 if (conf->power_level != wlvif->power_level) { 2881 if (conf->power_level != wlvif->power_level) {
2709 ret = wl1271_acx_tx_power(wl, wlvif, conf->power_level); 2882 ret = wl1271_acx_tx_power(wl, wlvif, conf->power_level);
@@ -2721,37 +2894,17 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
2721 struct wl1271 *wl = hw->priv; 2894 struct wl1271 *wl = hw->priv;
2722 struct wl12xx_vif *wlvif; 2895 struct wl12xx_vif *wlvif;
2723 struct ieee80211_conf *conf = &hw->conf; 2896 struct ieee80211_conf *conf = &hw->conf;
2724 int channel, ret = 0; 2897 int ret = 0;
2725
2726 channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
2727 2898
2728 wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s" 2899 wl1271_debug(DEBUG_MAC80211, "mac80211 config psm %s power %d %s"
2729 " changed 0x%x", 2900 " changed 0x%x",
2730 channel,
2731 conf->flags & IEEE80211_CONF_PS ? "on" : "off", 2901 conf->flags & IEEE80211_CONF_PS ? "on" : "off",
2732 conf->power_level, 2902 conf->power_level,
2733 conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use", 2903 conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use",
2734 changed); 2904 changed);
2735 2905
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); 2906 mutex_lock(&wl->mutex);
2747 2907
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) 2908 if (changed & IEEE80211_CONF_CHANGE_POWER)
2756 wl->power_level = conf->power_level; 2909 wl->power_level = conf->power_level;
2757 2910
@@ -3071,10 +3224,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 3224 * stop the queues and flush to ensure the next packets are
3072 * in sync with FW spare block accounting 3225 * in sync with FW spare block accounting
3073 */ 3226 */
3074 mutex_lock(&wl->mutex);
3075 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK); 3227 wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
3076 mutex_unlock(&wl->mutex);
3077
3078 wl1271_tx_flush(wl); 3228 wl1271_tx_flush(wl);
3079 } 3229 }
3080 3230
@@ -3200,6 +3350,29 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
3200} 3350}
3201EXPORT_SYMBOL_GPL(wlcore_set_key); 3351EXPORT_SYMBOL_GPL(wlcore_set_key);
3202 3352
3353void wlcore_regdomain_config(struct wl1271 *wl)
3354{
3355 int ret;
3356
3357 if (!(wl->quirks & WLCORE_QUIRK_REGDOMAIN_CONF))
3358 return;
3359
3360 mutex_lock(&wl->mutex);
3361 ret = wl1271_ps_elp_wakeup(wl);
3362 if (ret < 0)
3363 goto out;
3364
3365 ret = wlcore_cmd_regdomain_config_locked(wl);
3366 if (ret < 0) {
3367 wl12xx_queue_recovery_work(wl);
3368 goto out;
3369 }
3370
3371 wl1271_ps_elp_sleep(wl);
3372out:
3373 mutex_unlock(&wl->mutex);
3374}
3375
3203static int wl1271_op_hw_scan(struct ieee80211_hw *hw, 3376static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
3204 struct ieee80211_vif *vif, 3377 struct ieee80211_vif *vif,
3205 struct cfg80211_scan_request *req) 3378 struct cfg80211_scan_request *req)
@@ -3239,7 +3412,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
3239 goto out_sleep; 3412 goto out_sleep;
3240 } 3413 }
3241 3414
3242 ret = wl1271_scan(hw->priv, vif, ssid, len, req); 3415 ret = wlcore_scan(hw->priv, vif, ssid, len, req);
3243out_sleep: 3416out_sleep:
3244 wl1271_ps_elp_sleep(wl); 3417 wl1271_ps_elp_sleep(wl);
3245out: 3418out:
@@ -3252,6 +3425,7 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
3252 struct ieee80211_vif *vif) 3425 struct ieee80211_vif *vif)
3253{ 3426{
3254 struct wl1271 *wl = hw->priv; 3427 struct wl1271 *wl = hw->priv;
3428 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3255 int ret; 3429 int ret;
3256 3430
3257 wl1271_debug(DEBUG_MAC80211, "mac80211 cancel hw scan"); 3431 wl1271_debug(DEBUG_MAC80211, "mac80211 cancel hw scan");
@@ -3269,7 +3443,7 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
3269 goto out; 3443 goto out;
3270 3444
3271 if (wl->scan.state != WL1271_SCAN_STATE_DONE) { 3445 if (wl->scan.state != WL1271_SCAN_STATE_DONE) {
3272 ret = wl1271_scan_stop(wl); 3446 ret = wl->ops->scan_stop(wl, wlvif);
3273 if (ret < 0) 3447 if (ret < 0)
3274 goto out_sleep; 3448 goto out_sleep;
3275 } 3449 }
@@ -3282,7 +3456,7 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
3282 3456
3283 wl->scan.state = WL1271_SCAN_STATE_IDLE; 3457 wl->scan.state = WL1271_SCAN_STATE_IDLE;
3284 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); 3458 memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
3285 wl->scan_vif = NULL; 3459 wl->scan_wlvif = NULL;
3286 wl->scan.req = NULL; 3460 wl->scan.req = NULL;
3287 ieee80211_scan_completed(wl->hw, true); 3461 ieee80211_scan_completed(wl->hw, true);
3288 3462
@@ -3316,15 +3490,11 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
3316 if (ret < 0) 3490 if (ret < 0)
3317 goto out; 3491 goto out;
3318 3492
3319 ret = wl1271_scan_sched_scan_config(wl, wlvif, req, ies); 3493 ret = wl->ops->sched_scan_start(wl, wlvif, req, ies);
3320 if (ret < 0) 3494 if (ret < 0)
3321 goto out_sleep; 3495 goto out_sleep;
3322 3496
3323 ret = wl1271_scan_sched_scan_start(wl, wlvif); 3497 wl->sched_vif = wlvif;
3324 if (ret < 0)
3325 goto out_sleep;
3326
3327 wl->sched_scanning = true;
3328 3498
3329out_sleep: 3499out_sleep:
3330 wl1271_ps_elp_sleep(wl); 3500 wl1271_ps_elp_sleep(wl);
@@ -3351,7 +3521,7 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
3351 if (ret < 0) 3521 if (ret < 0)
3352 goto out; 3522 goto out;
3353 3523
3354 wl1271_scan_sched_scan_stop(wl, wlvif); 3524 wl->ops->sched_scan_stop(wl, wlvif);
3355 3525
3356 wl1271_ps_elp_sleep(wl); 3526 wl1271_ps_elp_sleep(wl);
3357out: 3527out:
@@ -3416,30 +3586,6 @@ out:
3416 return ret; 3586 return ret;
3417} 3587}
3418 3588
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) 3589static void wl12xx_remove_ie(struct sk_buff *skb, u8 eid, int ieoffset)
3444{ 3590{
3445 int len; 3591 int len;
@@ -3620,7 +3766,7 @@ static int wlcore_set_beacon_template(struct wl1271 *wl,
3620 3766
3621 wl1271_debug(DEBUG_MASTER, "beacon updated"); 3767 wl1271_debug(DEBUG_MASTER, "beacon updated");
3622 3768
3623 ret = wl1271_ssid_set(vif, beacon, ieoffset); 3769 ret = wl1271_ssid_set(wlvif, beacon, ieoffset);
3624 if (ret < 0) { 3770 if (ret < 0) {
3625 dev_kfree_skb(beacon); 3771 dev_kfree_skb(beacon);
3626 goto out; 3772 goto out;
@@ -3637,6 +3783,12 @@ static int wlcore_set_beacon_template(struct wl1271 *wl,
3637 goto out; 3783 goto out;
3638 } 3784 }
3639 3785
3786 wlvif->wmm_enabled =
3787 cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
3788 WLAN_OUI_TYPE_MICROSOFT_WMM,
3789 beacon->data + ieoffset,
3790 beacon->len - ieoffset);
3791
3640 /* 3792 /*
3641 * In case we already have a probe-resp beacon set explicitly 3793 * In case we already have a probe-resp beacon set explicitly
3642 * by usermode, don't use the beacon data. 3794 * by usermode, don't use the beacon data.
@@ -3690,7 +3842,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
3690 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 3842 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
3691 int ret = 0; 3843 int ret = 0;
3692 3844
3693 if ((changed & BSS_CHANGED_BEACON_INT)) { 3845 if (changed & BSS_CHANGED_BEACON_INT) {
3694 wl1271_debug(DEBUG_MASTER, "beacon interval updated: %d", 3846 wl1271_debug(DEBUG_MASTER, "beacon interval updated: %d",
3695 bss_conf->beacon_int); 3847 bss_conf->beacon_int);
3696 3848
@@ -3703,7 +3855,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
3703 wl1271_ap_set_probe_resp_tmpl(wl, rate, vif); 3855 wl1271_ap_set_probe_resp_tmpl(wl, rate, vif);
3704 } 3856 }
3705 3857
3706 if ((changed & BSS_CHANGED_BEACON)) { 3858 if (changed & BSS_CHANGED_BEACON) {
3707 ret = wlcore_set_beacon_template(wl, vif, is_ap); 3859 ret = wlcore_set_beacon_template(wl, vif, is_ap);
3708 if (ret < 0) 3860 if (ret < 0)
3709 goto out; 3861 goto out;
@@ -3724,7 +3876,7 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
3724 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 3876 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3725 int ret = 0; 3877 int ret = 0;
3726 3878
3727 if ((changed & BSS_CHANGED_BASIC_RATES)) { 3879 if (changed & BSS_CHANGED_BASIC_RATES) {
3728 u32 rates = bss_conf->basic_rates; 3880 u32 rates = bss_conf->basic_rates;
3729 3881
3730 wlvif->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, 3882 wlvif->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates,
@@ -3755,7 +3907,7 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
3755 if (ret < 0) 3907 if (ret < 0)
3756 goto out; 3908 goto out;
3757 3909
3758 if ((changed & BSS_CHANGED_BEACON_ENABLED)) { 3910 if (changed & BSS_CHANGED_BEACON_ENABLED) {
3759 if (bss_conf->enable_beacon) { 3911 if (bss_conf->enable_beacon) {
3760 if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) { 3912 if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
3761 ret = wl12xx_cmd_role_start_ap(wl, wlvif); 3913 ret = wl12xx_cmd_role_start_ap(wl, wlvif);
@@ -3802,6 +3954,79 @@ out:
3802 return; 3954 return;
3803} 3955}
3804 3956
3957static int wlcore_set_bssid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
3958 struct ieee80211_bss_conf *bss_conf,
3959 u32 sta_rate_set)
3960{
3961 u32 rates;
3962 int ret;
3963
3964 wl1271_debug(DEBUG_MAC80211,
3965 "changed_bssid: %pM, aid: %d, bcn_int: %d, brates: 0x%x sta_rate_set: 0x%x",
3966 bss_conf->bssid, bss_conf->aid,
3967 bss_conf->beacon_int,
3968 bss_conf->basic_rates, sta_rate_set);
3969
3970 wlvif->beacon_int = bss_conf->beacon_int;
3971 rates = bss_conf->basic_rates;
3972 wlvif->basic_rate_set =
3973 wl1271_tx_enabled_rates_get(wl, rates,
3974 wlvif->band);
3975 wlvif->basic_rate =
3976 wl1271_tx_min_rate_get(wl,
3977 wlvif->basic_rate_set);
3978
3979 if (sta_rate_set)
3980 wlvif->rate_set =
3981 wl1271_tx_enabled_rates_get(wl,
3982 sta_rate_set,
3983 wlvif->band);
3984
3985 /* we only support sched_scan while not connected */
3986 if (wl->sched_vif == wlvif)
3987 wl->ops->sched_scan_stop(wl, wlvif);
3988
3989 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
3990 if (ret < 0)
3991 return ret;
3992
3993 ret = wl12xx_cmd_build_null_data(wl, wlvif);
3994 if (ret < 0)
3995 return ret;
3996
3997 ret = wl1271_build_qos_null_data(wl, wl12xx_wlvif_to_vif(wlvif));
3998 if (ret < 0)
3999 return ret;
4000
4001 wlcore_set_ssid(wl, wlvif);
4002
4003 set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
4004
4005 return 0;
4006}
4007
4008static int wlcore_clear_bssid(struct wl1271 *wl, struct wl12xx_vif *wlvif)
4009{
4010 int ret;
4011
4012 /* revert back to minimum rates for the current band */
4013 wl1271_set_band_rate(wl, wlvif);
4014 wlvif->basic_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
4015
4016 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
4017 if (ret < 0)
4018 return ret;
4019
4020 if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
4021 test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) {
4022 ret = wl12xx_cmd_role_stop_sta(wl, wlvif);
4023 if (ret < 0)
4024 return ret;
4025 }
4026
4027 clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
4028 return 0;
4029}
3805/* STA/IBSS mode changes */ 4030/* STA/IBSS mode changes */
3806static void wl1271_bss_info_changed_sta(struct wl1271 *wl, 4031static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3807 struct ieee80211_vif *vif, 4032 struct ieee80211_vif *vif,
@@ -3809,7 +4034,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3809 u32 changed) 4034 u32 changed)
3810{ 4035{
3811 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 4036 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3812 bool do_join = false, set_assoc = false; 4037 bool do_join = false;
3813 bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS); 4038 bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
3814 bool ibss_joined = false; 4039 bool ibss_joined = false;
3815 u32 sta_rate_set = 0; 4040 u32 sta_rate_set = 0;
@@ -3830,9 +4055,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3830 set_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags); 4055 set_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags);
3831 ibss_joined = true; 4056 ibss_joined = true;
3832 } else { 4057 } else {
3833 if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, 4058 wlcore_unset_assoc(wl, wlvif);
3834 &wlvif->flags)) 4059 wl12xx_cmd_role_stop_sta(wl, wlvif);
3835 wl1271_unjoin(wl, wlvif);
3836 } 4060 }
3837 } 4061 }
3838 4062
@@ -3850,13 +4074,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3850 do_join = true; 4074 do_join = true;
3851 } 4075 }
3852 4076
3853 if (changed & BSS_CHANGED_IDLE && !is_ibss) { 4077 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; 4078 bool enable = false;
3861 if (bss_conf->cqm_rssi_thold) 4079 if (bss_conf->cqm_rssi_thold)
3862 enable = true; 4080 enable = true;
@@ -3868,150 +4086,39 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3868 wlvif->rssi_thold = bss_conf->cqm_rssi_thold; 4086 wlvif->rssi_thold = bss_conf->cqm_rssi_thold;
3869 } 4087 }
3870 4088
3871 if (changed & BSS_CHANGED_BSSID) 4089 if (changed & (BSS_CHANGED_BSSID | BSS_CHANGED_HT |
3872 if (!is_zero_ether_addr(bss_conf->bssid)) { 4090 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(); 4091 rcu_read_lock();
3884 sta = ieee80211_find_sta(vif, bss_conf->bssid); 4092 sta = ieee80211_find_sta(vif, bss_conf->bssid);
3885 if (!sta) 4093 if (sta) {
3886 goto sta_not_found; 4094 u8 *rx_mask = sta->ht_cap.mcs.rx_mask;
3887 4095
3888 /* save the supp_rates of the ap */ 4096 /* save the supp_rates of the ap */
3889 sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band]; 4097 sta_rate_set = sta->supp_rates[wlvif->band];
3890 if (sta->ht_cap.ht_supported) 4098 if (sta->ht_cap.ht_supported)
3891 sta_rate_set |= 4099 sta_rate_set |=
3892 (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) | 4100 (rx_mask[0] << HW_HT_RATES_OFFSET) |
3893 (sta->ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET); 4101 (rx_mask[1] << HW_MIMO_RATES_OFFSET);
3894 sta_ht_cap = sta->ht_cap; 4102 sta_ht_cap = sta->ht_cap;
3895 sta_exists = true; 4103 sta_exists = true;
3896 4104 }
3897sta_not_found: 4105
3898 rcu_read_unlock(); 4106 rcu_read_unlock();
3899 } 4107 }
3900 4108
3901 if ((changed & BSS_CHANGED_ASSOC)) { 4109 if (changed & BSS_CHANGED_BSSID) {
3902 if (bss_conf->assoc) { 4110 if (!is_zero_ether_addr(bss_conf->bssid)) {
3903 u32 rates; 4111 ret = wlcore_set_bssid(wl, wlvif, bss_conf,
3904 int ieoffset; 4112 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) 4113 if (ret < 0)
3940 goto out; 4114 goto out;
3941 4115
3942 /* 4116 /* Need to update the BSSID (for filtering etc) */
3943 * Get a template for hardware connection maintenance 4117 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 { 4118 } else {
3958 /* use defaults when not associated */ 4119 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) 4120 if (ret < 0)
3986 goto out; 4121 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 } 4122 }
4016 } 4123 }
4017 4124
@@ -4041,71 +4148,87 @@ sta_not_found:
4041 goto out; 4148 goto out;
4042 4149
4043 if (do_join) { 4150 if (do_join) {
4044 ret = wl1271_join(wl, wlvif, set_assoc); 4151 ret = wlcore_join(wl, wlvif);
4045 if (ret < 0) { 4152 if (ret < 0) {
4046 wl1271_warning("cmd join failed %d", ret); 4153 wl1271_warning("cmd join failed %d", ret);
4047 goto out; 4154 goto out;
4048 } 4155 }
4156 }
4049 4157
4050 /* ROC until connected (after EAPOL exchange) */ 4158 if (changed & BSS_CHANGED_ASSOC) {
4051 if (!is_ibss) { 4159 if (bss_conf->assoc) {
4052 ret = wl12xx_roc(wl, wlvif, wlvif->role_id); 4160 ret = wlcore_set_assoc(wl, wlvif, bss_conf,
4161 sta_rate_set);
4053 if (ret < 0) 4162 if (ret < 0)
4054 goto out; 4163 goto out;
4055 4164
4056 if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags)) 4165 if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags))
4057 wl12xx_set_authorized(wl, wlvif); 4166 wl12xx_set_authorized(wl, wlvif);
4167 } else {
4168 wlcore_unset_assoc(wl, wlvif);
4058 } 4169 }
4059 /* 4170 }
4060 * stop device role if started (we might already be in 4171
4061 * STA/IBSS role). 4172 if (changed & BSS_CHANGED_PS) {
4062 */ 4173 if ((bss_conf->ps) &&
4063 if (wl12xx_dev_role_started(wlvif)) { 4174 test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
4064 ret = wl12xx_stop_dev(wl, wlvif); 4175 !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
4176 int ps_mode;
4177 char *ps_mode_str;
4178
4179 if (wl->conf.conn.forced_ps) {
4180 ps_mode = STATION_POWER_SAVE_MODE;
4181 ps_mode_str = "forced";
4182 } else {
4183 ps_mode = STATION_AUTO_PS_MODE;
4184 ps_mode_str = "auto";
4185 }
4186
4187 wl1271_debug(DEBUG_PSM, "%s ps enabled", ps_mode_str);
4188
4189 ret = wl1271_ps_set_mode(wl, wlvif, ps_mode);
4065 if (ret < 0) 4190 if (ret < 0)
4066 goto out; 4191 wl1271_warning("enter %s ps failed %d",
4192 ps_mode_str, ret);
4193 } else if (!bss_conf->ps &&
4194 test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
4195 wl1271_debug(DEBUG_PSM, "auto ps disabled");
4196
4197 ret = wl1271_ps_set_mode(wl, wlvif,
4198 STATION_ACTIVE_MODE);
4199 if (ret < 0)
4200 wl1271_warning("exit auto ps failed %d", ret);
4067 } 4201 }
4068 } 4202 }
4069 4203
4070 /* Handle new association with HT. Do this after join. */ 4204 /* Handle new association with HT. Do this after join. */
4071 if (sta_exists) { 4205 if (sta_exists &&
4072 if ((changed & BSS_CHANGED_HT) && 4206 (changed & BSS_CHANGED_HT)) {
4073 (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) { 4207 bool enabled =
4074 ret = wl1271_acx_set_ht_capabilities(wl, 4208 bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT;
4075 &sta_ht_cap, 4209
4076 true, 4210 ret = wlcore_hw_set_peer_cap(wl,
4077 wlvif->sta.hlid); 4211 &sta_ht_cap,
4078 if (ret < 0) { 4212 enabled,
4079 wl1271_warning("Set ht cap true failed %d", 4213 wlvif->rate_set,
4080 ret); 4214 wlvif->sta.hlid);
4081 goto out; 4215 if (ret < 0) {
4082 } 4216 wl1271_warning("Set ht cap failed %d", ret);
4217 goto out;
4218
4083 } 4219 }
4084 /* handle new association without HT and disassociation */ 4220
4085 else if (changed & BSS_CHANGED_ASSOC) { 4221 if (enabled) {
4086 ret = wl1271_acx_set_ht_capabilities(wl, 4222 ret = wl1271_acx_set_ht_information(wl, wlvif,
4087 &sta_ht_cap, 4223 bss_conf->ht_operation_mode);
4088 false,
4089 wlvif->sta.hlid);
4090 if (ret < 0) { 4224 if (ret < 0) {
4091 wl1271_warning("Set ht cap false failed %d", 4225 wl1271_warning("Set ht information failed %d",
4092 ret); 4226 ret);
4093 goto out; 4227 goto out;
4094 } 4228 }
4095 } 4229 }
4096 } 4230 }
4097 4231
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. */ 4232 /* Handle arp filtering. Done after join. */
4110 if ((changed & BSS_CHANGED_ARP_FILTER) || 4233 if ((changed & BSS_CHANGED_ARP_FILTER) ||
4111 (!is_ibss && (changed & BSS_CHANGED_QOS))) { 4234 (!is_ibss && (changed & BSS_CHANGED_QOS))) {
@@ -4154,15 +4277,15 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
4154 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 4277 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
4155 int ret; 4278 int ret;
4156 4279
4157 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x", 4280 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info role %d changed 0x%x",
4158 (int)changed); 4281 wlvif->role_id, (int)changed);
4159 4282
4160 /* 4283 /*
4161 * make sure to cancel pending disconnections if our association 4284 * make sure to cancel pending disconnections if our association
4162 * state changed 4285 * state changed
4163 */ 4286 */
4164 if (!is_ap && (changed & BSS_CHANGED_ASSOC)) 4287 if (!is_ap && (changed & BSS_CHANGED_ASSOC))
4165 cancel_delayed_work_sync(&wl->connection_loss_work); 4288 cancel_delayed_work_sync(&wlvif->connection_loss_work);
4166 4289
4167 if (is_ap && (changed & BSS_CHANGED_BEACON_ENABLED) && 4290 if (is_ap && (changed & BSS_CHANGED_BEACON_ENABLED) &&
4168 !bss_conf->enable_beacon) 4291 !bss_conf->enable_beacon)
@@ -4191,6 +4314,76 @@ out:
4191 mutex_unlock(&wl->mutex); 4314 mutex_unlock(&wl->mutex);
4192} 4315}
4193 4316
4317static int wlcore_op_add_chanctx(struct ieee80211_hw *hw,
4318 struct ieee80211_chanctx_conf *ctx)
4319{
4320 wl1271_debug(DEBUG_MAC80211, "mac80211 add chanctx %d (type %d)",
4321 ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
4322 cfg80211_get_chandef_type(&ctx->def));
4323 return 0;
4324}
4325
4326static void wlcore_op_remove_chanctx(struct ieee80211_hw *hw,
4327 struct ieee80211_chanctx_conf *ctx)
4328{
4329 wl1271_debug(DEBUG_MAC80211, "mac80211 remove chanctx %d (type %d)",
4330 ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
4331 cfg80211_get_chandef_type(&ctx->def));
4332}
4333
4334static void wlcore_op_change_chanctx(struct ieee80211_hw *hw,
4335 struct ieee80211_chanctx_conf *ctx,
4336 u32 changed)
4337{
4338 wl1271_debug(DEBUG_MAC80211,
4339 "mac80211 change chanctx %d (type %d) changed 0x%x",
4340 ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
4341 cfg80211_get_chandef_type(&ctx->def), changed);
4342}
4343
4344static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
4345 struct ieee80211_vif *vif,
4346 struct ieee80211_chanctx_conf *ctx)
4347{
4348 struct wl1271 *wl = hw->priv;
4349 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4350 int channel = ieee80211_frequency_to_channel(
4351 ctx->def.chan->center_freq);
4352
4353 wl1271_debug(DEBUG_MAC80211,
4354 "mac80211 assign chanctx (role %d) %d (type %d)",
4355 wlvif->role_id, channel, cfg80211_get_chandef_type(&ctx->def));
4356
4357 mutex_lock(&wl->mutex);
4358
4359 wlvif->band = ctx->def.chan->band;
4360 wlvif->channel = channel;
4361 wlvif->channel_type = cfg80211_get_chandef_type(&ctx->def);
4362
4363 /* update default rates according to the band */
4364 wl1271_set_band_rate(wl, wlvif);
4365
4366 mutex_unlock(&wl->mutex);
4367
4368 return 0;
4369}
4370
4371static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
4372 struct ieee80211_vif *vif,
4373 struct ieee80211_chanctx_conf *ctx)
4374{
4375 struct wl1271 *wl = hw->priv;
4376 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4377
4378 wl1271_debug(DEBUG_MAC80211,
4379 "mac80211 unassign chanctx (role %d) %d (type %d)",
4380 wlvif->role_id,
4381 ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
4382 cfg80211_get_chandef_type(&ctx->def));
4383
4384 wl1271_tx_flush(wl);
4385}
4386
4194static int wl1271_op_conf_tx(struct ieee80211_hw *hw, 4387static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
4195 struct ieee80211_vif *vif, u16 queue, 4388 struct ieee80211_vif *vif, u16 queue,
4196 const struct ieee80211_tx_queue_params *params) 4389 const struct ieee80211_tx_queue_params *params)
@@ -4318,8 +4511,6 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
4318 return; 4511 return;
4319 4512
4320 clear_bit(hlid, wlvif->ap.sta_hlid_map); 4513 clear_bit(hlid, wlvif->ap.sta_hlid_map);
4321 memset(wl->links[hlid].addr, 0, ETH_ALEN);
4322 wl->links[hlid].ba_bitmap = 0;
4323 __clear_bit(hlid, &wl->ap_ps_map); 4514 __clear_bit(hlid, &wl->ap_ps_map);
4324 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 4515 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
4325 wl12xx_free_link(wl, wlvif, &hlid); 4516 wl12xx_free_link(wl, wlvif, &hlid);
@@ -4379,6 +4570,45 @@ static int wl12xx_sta_remove(struct wl1271 *wl,
4379 return ret; 4570 return ret;
4380} 4571}
4381 4572
4573static void wlcore_roc_if_possible(struct wl1271 *wl,
4574 struct wl12xx_vif *wlvif)
4575{
4576 if (find_first_bit(wl->roc_map,
4577 WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES)
4578 return;
4579
4580 if (WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID))
4581 return;
4582
4583 wl12xx_roc(wl, wlvif, wlvif->role_id, wlvif->band, wlvif->channel);
4584}
4585
4586static void wlcore_update_inconn_sta(struct wl1271 *wl,
4587 struct wl12xx_vif *wlvif,
4588 struct wl1271_station *wl_sta,
4589 bool in_connection)
4590{
4591 if (in_connection) {
4592 if (WARN_ON(wl_sta->in_connection))
4593 return;
4594 wl_sta->in_connection = true;
4595 if (!wlvif->inconn_count++)
4596 wlcore_roc_if_possible(wl, wlvif);
4597 } else {
4598 if (!wl_sta->in_connection)
4599 return;
4600
4601 wl_sta->in_connection = false;
4602 wlvif->inconn_count--;
4603 if (WARN_ON(wlvif->inconn_count < 0))
4604 return;
4605
4606 if (!wlvif->inconn_count)
4607 if (test_bit(wlvif->role_id, wl->roc_map))
4608 wl12xx_croc(wl, wlvif->role_id);
4609 }
4610}
4611
4382static int wl12xx_update_sta_state(struct wl1271 *wl, 4612static int wl12xx_update_sta_state(struct wl1271 *wl,
4383 struct wl12xx_vif *wlvif, 4613 struct wl12xx_vif *wlvif,
4384 struct ieee80211_sta *sta, 4614 struct ieee80211_sta *sta,
@@ -4397,8 +4627,13 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
4397 /* Add station (AP mode) */ 4627 /* Add station (AP mode) */
4398 if (is_ap && 4628 if (is_ap &&
4399 old_state == IEEE80211_STA_NOTEXIST && 4629 old_state == IEEE80211_STA_NOTEXIST &&
4400 new_state == IEEE80211_STA_NONE) 4630 new_state == IEEE80211_STA_NONE) {
4401 return wl12xx_sta_add(wl, wlvif, sta); 4631 ret = wl12xx_sta_add(wl, wlvif, sta);
4632 if (ret)
4633 return ret;
4634
4635 wlcore_update_inconn_sta(wl, wlvif, wl_sta, true);
4636 }
4402 4637
4403 /* Remove station (AP mode) */ 4638 /* Remove station (AP mode) */
4404 if (is_ap && 4639 if (is_ap &&
@@ -4406,35 +4641,59 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
4406 new_state == IEEE80211_STA_NOTEXIST) { 4641 new_state == IEEE80211_STA_NOTEXIST) {
4407 /* must not fail */ 4642 /* must not fail */
4408 wl12xx_sta_remove(wl, wlvif, sta); 4643 wl12xx_sta_remove(wl, wlvif, sta);
4409 return 0; 4644
4645 wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
4410 } 4646 }
4411 4647
4412 /* Authorize station (AP mode) */ 4648 /* Authorize station (AP mode) */
4413 if (is_ap && 4649 if (is_ap &&
4414 new_state == IEEE80211_STA_AUTHORIZED) { 4650 new_state == IEEE80211_STA_AUTHORIZED) {
4415 ret = wl12xx_cmd_set_peer_state(wl, hlid); 4651 ret = wl12xx_cmd_set_peer_state(wl, wlvif, hlid);
4416 if (ret < 0) 4652 if (ret < 0)
4417 return ret; 4653 return ret;
4418 4654
4419 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, 4655 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true,
4420 hlid); 4656 hlid);
4421 return ret; 4657 if (ret)
4658 return ret;
4659
4660 wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
4422 } 4661 }
4423 4662
4424 /* Authorize station */ 4663 /* Authorize station */
4425 if (is_sta && 4664 if (is_sta &&
4426 new_state == IEEE80211_STA_AUTHORIZED) { 4665 new_state == IEEE80211_STA_AUTHORIZED) {
4427 set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); 4666 set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
4428 return wl12xx_set_authorized(wl, wlvif); 4667 ret = wl12xx_set_authorized(wl, wlvif);
4668 if (ret)
4669 return ret;
4429 } 4670 }
4430 4671
4431 if (is_sta && 4672 if (is_sta &&
4432 old_state == IEEE80211_STA_AUTHORIZED && 4673 old_state == IEEE80211_STA_AUTHORIZED &&
4433 new_state == IEEE80211_STA_ASSOC) { 4674 new_state == IEEE80211_STA_ASSOC) {
4434 clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); 4675 clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
4435 return 0; 4676 clear_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags);
4436 } 4677 }
4437 4678
4679 /* clear ROCs on failure or authorization */
4680 if (is_sta &&
4681 (new_state == IEEE80211_STA_AUTHORIZED ||
4682 new_state == IEEE80211_STA_NOTEXIST)) {
4683 if (test_bit(wlvif->role_id, wl->roc_map))
4684 wl12xx_croc(wl, wlvif->role_id);
4685 }
4686
4687 if (is_sta &&
4688 old_state == IEEE80211_STA_NOTEXIST &&
4689 new_state == IEEE80211_STA_NONE) {
4690 if (find_first_bit(wl->roc_map,
4691 WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES) {
4692 WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID);
4693 wl12xx_roc(wl, wlvif, wlvif->role_id,
4694 wlvif->band, wlvif->channel);
4695 }
4696 }
4438 return 0; 4697 return 0;
4439} 4698}
4440 4699
@@ -4499,18 +4758,18 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
4499 4758
4500 if (wlvif->bss_type == BSS_TYPE_STA_BSS) { 4759 if (wlvif->bss_type == BSS_TYPE_STA_BSS) {
4501 hlid = wlvif->sta.hlid; 4760 hlid = wlvif->sta.hlid;
4502 ba_bitmap = &wlvif->sta.ba_rx_bitmap;
4503 } else if (wlvif->bss_type == BSS_TYPE_AP_BSS) { 4761 } else if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
4504 struct wl1271_station *wl_sta; 4762 struct wl1271_station *wl_sta;
4505 4763
4506 wl_sta = (struct wl1271_station *)sta->drv_priv; 4764 wl_sta = (struct wl1271_station *)sta->drv_priv;
4507 hlid = wl_sta->hlid; 4765 hlid = wl_sta->hlid;
4508 ba_bitmap = &wl->links[hlid].ba_bitmap;
4509 } else { 4766 } else {
4510 ret = -EINVAL; 4767 ret = -EINVAL;
4511 goto out; 4768 goto out;
4512 } 4769 }
4513 4770
4771 ba_bitmap = &wl->links[hlid].ba_bitmap;
4772
4514 ret = wl1271_ps_elp_wakeup(wl); 4773 ret = wl1271_ps_elp_wakeup(wl);
4515 if (ret < 0) 4774 if (ret < 0)
4516 goto out; 4775 goto out;
@@ -4664,12 +4923,23 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
4664 4923
4665 /* TODO: change mac80211 to pass vif as param */ 4924 /* TODO: change mac80211 to pass vif as param */
4666 wl12xx_for_each_wlvif_sta(wl, wlvif) { 4925 wl12xx_for_each_wlvif_sta(wl, wlvif) {
4667 ret = wl12xx_cmd_channel_switch(wl, wlvif, ch_switch); 4926 unsigned long delay_usec;
4927
4928 ret = wl->ops->channel_switch(wl, wlvif, ch_switch);
4929 if (ret)
4930 goto out_sleep;
4668 4931
4669 if (!ret) 4932 set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
4670 set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags); 4933
4934 /* indicate failure 5 seconds after channel switch time */
4935 delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) *
4936 ch_switch->count;
4937 ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work,
4938 usecs_to_jiffies(delay_usec) +
4939 msecs_to_jiffies(5000));
4671 } 4940 }
4672 4941
4942out_sleep:
4673 wl1271_ps_elp_sleep(wl); 4943 wl1271_ps_elp_sleep(wl);
4674 4944
4675out: 4945out:
@@ -4683,6 +4953,144 @@ static void wlcore_op_flush(struct ieee80211_hw *hw, bool drop)
4683 wl1271_tx_flush(wl); 4953 wl1271_tx_flush(wl);
4684} 4954}
4685 4955
4956static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw,
4957 struct ieee80211_vif *vif,
4958 struct ieee80211_channel *chan,
4959 int duration)
4960{
4961 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4962 struct wl1271 *wl = hw->priv;
4963 int channel, ret = 0;
4964
4965 channel = ieee80211_frequency_to_channel(chan->center_freq);
4966
4967 wl1271_debug(DEBUG_MAC80211, "mac80211 roc %d (%d)",
4968 channel, wlvif->role_id);
4969
4970 mutex_lock(&wl->mutex);
4971
4972 if (unlikely(wl->state != WLCORE_STATE_ON))
4973 goto out;
4974
4975 /* return EBUSY if we can't ROC right now */
4976 if (WARN_ON(wl->roc_vif ||
4977 find_first_bit(wl->roc_map,
4978 WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES)) {
4979 ret = -EBUSY;
4980 goto out;
4981 }
4982
4983 ret = wl1271_ps_elp_wakeup(wl);
4984 if (ret < 0)
4985 goto out;
4986
4987 ret = wl12xx_start_dev(wl, wlvif, chan->band, channel);
4988 if (ret < 0)
4989 goto out_sleep;
4990
4991 wl->roc_vif = vif;
4992 ieee80211_queue_delayed_work(hw, &wl->roc_complete_work,
4993 msecs_to_jiffies(duration));
4994out_sleep:
4995 wl1271_ps_elp_sleep(wl);
4996out:
4997 mutex_unlock(&wl->mutex);
4998 return ret;
4999}
5000
5001static int __wlcore_roc_completed(struct wl1271 *wl)
5002{
5003 struct wl12xx_vif *wlvif;
5004 int ret;
5005
5006 /* already completed */
5007 if (unlikely(!wl->roc_vif))
5008 return 0;
5009
5010 wlvif = wl12xx_vif_to_data(wl->roc_vif);
5011
5012 if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
5013 return -EBUSY;
5014
5015 ret = wl12xx_stop_dev(wl, wlvif);
5016 if (ret < 0)
5017 return ret;
5018
5019 wl->roc_vif = NULL;
5020
5021 return 0;
5022}
5023
5024static int wlcore_roc_completed(struct wl1271 *wl)
5025{
5026 int ret;
5027
5028 wl1271_debug(DEBUG_MAC80211, "roc complete");
5029
5030 mutex_lock(&wl->mutex);
5031
5032 if (unlikely(wl->state != WLCORE_STATE_ON)) {
5033 ret = -EBUSY;
5034 goto out;
5035 }
5036
5037 ret = wl1271_ps_elp_wakeup(wl);
5038 if (ret < 0)
5039 goto out;
5040
5041 ret = __wlcore_roc_completed(wl);
5042
5043 wl1271_ps_elp_sleep(wl);
5044out:
5045 mutex_unlock(&wl->mutex);
5046
5047 return ret;
5048}
5049
5050static void wlcore_roc_complete_work(struct work_struct *work)
5051{
5052 struct delayed_work *dwork;
5053 struct wl1271 *wl;
5054 int ret;
5055
5056 dwork = container_of(work, struct delayed_work, work);
5057 wl = container_of(dwork, struct wl1271, roc_complete_work);
5058
5059 ret = wlcore_roc_completed(wl);
5060 if (!ret)
5061 ieee80211_remain_on_channel_expired(wl->hw);
5062}
5063
5064static int wlcore_op_cancel_remain_on_channel(struct ieee80211_hw *hw)
5065{
5066 struct wl1271 *wl = hw->priv;
5067
5068 wl1271_debug(DEBUG_MAC80211, "mac80211 croc");
5069
5070 /* TODO: per-vif */
5071 wl1271_tx_flush(wl);
5072
5073 /*
5074 * we can't just flush_work here, because it might deadlock
5075 * (as we might get called from the same workqueue)
5076 */
5077 cancel_delayed_work_sync(&wl->roc_complete_work);
5078 wlcore_roc_completed(wl);
5079
5080 return 0;
5081}
5082
5083static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
5084 struct ieee80211_vif *vif,
5085 struct ieee80211_sta *sta,
5086 u32 changed)
5087{
5088 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5089 struct wl1271 *wl = hw->priv;
5090
5091 wlcore_hw_sta_rc_update(wl, wlvif, sta, changed);
5092}
5093
4686static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) 5094static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
4687{ 5095{
4688 struct wl1271 *wl = hw->priv; 5096 struct wl1271 *wl = hw->priv;
@@ -4746,20 +5154,20 @@ static struct ieee80211_rate wl1271_rates[] = {
4746 5154
4747/* can't be const, mac80211 writes to this */ 5155/* can't be const, mac80211 writes to this */
4748static struct ieee80211_channel wl1271_channels[] = { 5156static struct ieee80211_channel wl1271_channels[] = {
4749 { .hw_value = 1, .center_freq = 2412, .max_power = 25 }, 5157 { .hw_value = 1, .center_freq = 2412, .max_power = WLCORE_MAX_TXPWR },
4750 { .hw_value = 2, .center_freq = 2417, .max_power = 25 }, 5158 { .hw_value = 2, .center_freq = 2417, .max_power = WLCORE_MAX_TXPWR },
4751 { .hw_value = 3, .center_freq = 2422, .max_power = 25 }, 5159 { .hw_value = 3, .center_freq = 2422, .max_power = WLCORE_MAX_TXPWR },
4752 { .hw_value = 4, .center_freq = 2427, .max_power = 25 }, 5160 { .hw_value = 4, .center_freq = 2427, .max_power = WLCORE_MAX_TXPWR },
4753 { .hw_value = 5, .center_freq = 2432, .max_power = 25 }, 5161 { .hw_value = 5, .center_freq = 2432, .max_power = WLCORE_MAX_TXPWR },
4754 { .hw_value = 6, .center_freq = 2437, .max_power = 25 }, 5162 { .hw_value = 6, .center_freq = 2437, .max_power = WLCORE_MAX_TXPWR },
4755 { .hw_value = 7, .center_freq = 2442, .max_power = 25 }, 5163 { .hw_value = 7, .center_freq = 2442, .max_power = WLCORE_MAX_TXPWR },
4756 { .hw_value = 8, .center_freq = 2447, .max_power = 25 }, 5164 { .hw_value = 8, .center_freq = 2447, .max_power = WLCORE_MAX_TXPWR },
4757 { .hw_value = 9, .center_freq = 2452, .max_power = 25 }, 5165 { .hw_value = 9, .center_freq = 2452, .max_power = WLCORE_MAX_TXPWR },
4758 { .hw_value = 10, .center_freq = 2457, .max_power = 25 }, 5166 { .hw_value = 10, .center_freq = 2457, .max_power = WLCORE_MAX_TXPWR },
4759 { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, 5167 { .hw_value = 11, .center_freq = 2462, .max_power = WLCORE_MAX_TXPWR },
4760 { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, 5168 { .hw_value = 12, .center_freq = 2467, .max_power = WLCORE_MAX_TXPWR },
4761 { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, 5169 { .hw_value = 13, .center_freq = 2472, .max_power = WLCORE_MAX_TXPWR },
4762 { .hw_value = 14, .center_freq = 2484, .max_power = 25 }, 5170 { .hw_value = 14, .center_freq = 2484, .max_power = WLCORE_MAX_TXPWR },
4763}; 5171};
4764 5172
4765/* can't be const, mac80211 writes to this */ 5173/* can't be const, mac80211 writes to this */
@@ -4800,40 +5208,40 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = {
4800 5208
4801/* 5 GHz band channels for WL1273 */ 5209/* 5 GHz band channels for WL1273 */
4802static struct ieee80211_channel wl1271_channels_5ghz[] = { 5210static struct ieee80211_channel wl1271_channels_5ghz[] = {
4803 { .hw_value = 7, .center_freq = 5035, .max_power = 25 }, 5211 { .hw_value = 7, .center_freq = 5035, .max_power = WLCORE_MAX_TXPWR },
4804 { .hw_value = 8, .center_freq = 5040, .max_power = 25 }, 5212 { .hw_value = 8, .center_freq = 5040, .max_power = WLCORE_MAX_TXPWR },
4805 { .hw_value = 9, .center_freq = 5045, .max_power = 25 }, 5213 { .hw_value = 9, .center_freq = 5045, .max_power = WLCORE_MAX_TXPWR },
4806 { .hw_value = 11, .center_freq = 5055, .max_power = 25 }, 5214 { .hw_value = 11, .center_freq = 5055, .max_power = WLCORE_MAX_TXPWR },
4807 { .hw_value = 12, .center_freq = 5060, .max_power = 25 }, 5215 { .hw_value = 12, .center_freq = 5060, .max_power = WLCORE_MAX_TXPWR },
4808 { .hw_value = 16, .center_freq = 5080, .max_power = 25 }, 5216 { .hw_value = 16, .center_freq = 5080, .max_power = WLCORE_MAX_TXPWR },
4809 { .hw_value = 34, .center_freq = 5170, .max_power = 25 }, 5217 { .hw_value = 34, .center_freq = 5170, .max_power = WLCORE_MAX_TXPWR },
4810 { .hw_value = 36, .center_freq = 5180, .max_power = 25 }, 5218 { .hw_value = 36, .center_freq = 5180, .max_power = WLCORE_MAX_TXPWR },
4811 { .hw_value = 38, .center_freq = 5190, .max_power = 25 }, 5219 { .hw_value = 38, .center_freq = 5190, .max_power = WLCORE_MAX_TXPWR },
4812 { .hw_value = 40, .center_freq = 5200, .max_power = 25 }, 5220 { .hw_value = 40, .center_freq = 5200, .max_power = WLCORE_MAX_TXPWR },
4813 { .hw_value = 42, .center_freq = 5210, .max_power = 25 }, 5221 { .hw_value = 42, .center_freq = 5210, .max_power = WLCORE_MAX_TXPWR },
4814 { .hw_value = 44, .center_freq = 5220, .max_power = 25 }, 5222 { .hw_value = 44, .center_freq = 5220, .max_power = WLCORE_MAX_TXPWR },
4815 { .hw_value = 46, .center_freq = 5230, .max_power = 25 }, 5223 { .hw_value = 46, .center_freq = 5230, .max_power = WLCORE_MAX_TXPWR },
4816 { .hw_value = 48, .center_freq = 5240, .max_power = 25 }, 5224 { .hw_value = 48, .center_freq = 5240, .max_power = WLCORE_MAX_TXPWR },
4817 { .hw_value = 52, .center_freq = 5260, .max_power = 25 }, 5225 { .hw_value = 52, .center_freq = 5260, .max_power = WLCORE_MAX_TXPWR },
4818 { .hw_value = 56, .center_freq = 5280, .max_power = 25 }, 5226 { .hw_value = 56, .center_freq = 5280, .max_power = WLCORE_MAX_TXPWR },
4819 { .hw_value = 60, .center_freq = 5300, .max_power = 25 }, 5227 { .hw_value = 60, .center_freq = 5300, .max_power = WLCORE_MAX_TXPWR },
4820 { .hw_value = 64, .center_freq = 5320, .max_power = 25 }, 5228 { .hw_value = 64, .center_freq = 5320, .max_power = WLCORE_MAX_TXPWR },
4821 { .hw_value = 100, .center_freq = 5500, .max_power = 25 }, 5229 { .hw_value = 100, .center_freq = 5500, .max_power = WLCORE_MAX_TXPWR },
4822 { .hw_value = 104, .center_freq = 5520, .max_power = 25 }, 5230 { .hw_value = 104, .center_freq = 5520, .max_power = WLCORE_MAX_TXPWR },
4823 { .hw_value = 108, .center_freq = 5540, .max_power = 25 }, 5231 { .hw_value = 108, .center_freq = 5540, .max_power = WLCORE_MAX_TXPWR },
4824 { .hw_value = 112, .center_freq = 5560, .max_power = 25 }, 5232 { .hw_value = 112, .center_freq = 5560, .max_power = WLCORE_MAX_TXPWR },
4825 { .hw_value = 116, .center_freq = 5580, .max_power = 25 }, 5233 { .hw_value = 116, .center_freq = 5580, .max_power = WLCORE_MAX_TXPWR },
4826 { .hw_value = 120, .center_freq = 5600, .max_power = 25 }, 5234 { .hw_value = 120, .center_freq = 5600, .max_power = WLCORE_MAX_TXPWR },
4827 { .hw_value = 124, .center_freq = 5620, .max_power = 25 }, 5235 { .hw_value = 124, .center_freq = 5620, .max_power = WLCORE_MAX_TXPWR },
4828 { .hw_value = 128, .center_freq = 5640, .max_power = 25 }, 5236 { .hw_value = 128, .center_freq = 5640, .max_power = WLCORE_MAX_TXPWR },
4829 { .hw_value = 132, .center_freq = 5660, .max_power = 25 }, 5237 { .hw_value = 132, .center_freq = 5660, .max_power = WLCORE_MAX_TXPWR },
4830 { .hw_value = 136, .center_freq = 5680, .max_power = 25 }, 5238 { .hw_value = 136, .center_freq = 5680, .max_power = WLCORE_MAX_TXPWR },
4831 { .hw_value = 140, .center_freq = 5700, .max_power = 25 }, 5239 { .hw_value = 140, .center_freq = 5700, .max_power = WLCORE_MAX_TXPWR },
4832 { .hw_value = 149, .center_freq = 5745, .max_power = 25 }, 5240 { .hw_value = 149, .center_freq = 5745, .max_power = WLCORE_MAX_TXPWR },
4833 { .hw_value = 153, .center_freq = 5765, .max_power = 25 }, 5241 { .hw_value = 153, .center_freq = 5765, .max_power = WLCORE_MAX_TXPWR },
4834 { .hw_value = 157, .center_freq = 5785, .max_power = 25 }, 5242 { .hw_value = 157, .center_freq = 5785, .max_power = WLCORE_MAX_TXPWR },
4835 { .hw_value = 161, .center_freq = 5805, .max_power = 25 }, 5243 { .hw_value = 161, .center_freq = 5805, .max_power = WLCORE_MAX_TXPWR },
4836 { .hw_value = 165, .center_freq = 5825, .max_power = 25 }, 5244 { .hw_value = 165, .center_freq = 5825, .max_power = WLCORE_MAX_TXPWR },
4837}; 5245};
4838 5246
4839static struct ieee80211_supported_band wl1271_band_5ghz = { 5247static struct ieee80211_supported_band wl1271_band_5ghz = {
@@ -4874,6 +5282,14 @@ static const struct ieee80211_ops wl1271_ops = {
4874 .set_bitrate_mask = wl12xx_set_bitrate_mask, 5282 .set_bitrate_mask = wl12xx_set_bitrate_mask,
4875 .channel_switch = wl12xx_op_channel_switch, 5283 .channel_switch = wl12xx_op_channel_switch,
4876 .flush = wlcore_op_flush, 5284 .flush = wlcore_op_flush,
5285 .remain_on_channel = wlcore_op_remain_on_channel,
5286 .cancel_remain_on_channel = wlcore_op_cancel_remain_on_channel,
5287 .add_chanctx = wlcore_op_add_chanctx,
5288 .remove_chanctx = wlcore_op_remove_chanctx,
5289 .change_chanctx = wlcore_op_change_chanctx,
5290 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
5291 .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx,
5292 .sta_rc_update = wlcore_op_sta_rc_update,
4877 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 5293 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
4878}; 5294};
4879 5295
@@ -5043,34 +5459,6 @@ static struct bin_attribute fwlog_attr = {
5043 .read = wl1271_sysfs_read_fwlog, 5459 .read = wl1271_sysfs_read_fwlog,
5044}; 5460};
5045 5461
5046static void wl1271_connection_loss_work(struct work_struct *work)
5047{
5048 struct delayed_work *dwork;
5049 struct wl1271 *wl;
5050 struct ieee80211_vif *vif;
5051 struct wl12xx_vif *wlvif;
5052
5053 dwork = container_of(work, struct delayed_work, work);
5054 wl = container_of(dwork, struct wl1271, connection_loss_work);
5055
5056 wl1271_info("Connection loss work.");
5057
5058 mutex_lock(&wl->mutex);
5059
5060 if (unlikely(wl->state != WLCORE_STATE_ON))
5061 goto out;
5062
5063 /* Call mac80211 connection loss */
5064 wl12xx_for_each_wlvif_sta(wl, wlvif) {
5065 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
5066 goto out;
5067 vif = wl12xx_wlvif_to_vif(wlvif);
5068 ieee80211_connection_loss(vif);
5069 }
5070out:
5071 mutex_unlock(&wl->mutex);
5072}
5073
5074static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic) 5462static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic)
5075{ 5463{
5076 int i; 5464 int i;
@@ -5116,7 +5504,7 @@ static int wl12xx_get_hw_info(struct wl1271 *wl)
5116 5504
5117 ret = wl12xx_set_power_on(wl); 5505 ret = wl12xx_set_power_on(wl);
5118 if (ret < 0) 5506 if (ret < 0)
5119 goto out; 5507 return ret;
5120 5508
5121 ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &wl->chip.id); 5509 ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &wl->chip.id);
5122 if (ret < 0) 5510 if (ret < 0)
@@ -5206,10 +5594,9 @@ static const struct ieee80211_iface_limit wlcore_iface_limits[] = {
5206 }, 5594 },
5207}; 5595};
5208 5596
5209static const struct ieee80211_iface_combination 5597static struct ieee80211_iface_combination
5210wlcore_iface_combinations[] = { 5598wlcore_iface_combinations[] = {
5211 { 5599 {
5212 .num_different_channels = 1,
5213 .max_interfaces = 3, 5600 .max_interfaces = 3,
5214 .limits = wlcore_iface_limits, 5601 .limits = wlcore_iface_limits,
5215 .n_limits = ARRAY_SIZE(wlcore_iface_limits), 5602 .n_limits = ARRAY_SIZE(wlcore_iface_limits),
@@ -5218,6 +5605,7 @@ wlcore_iface_combinations[] = {
5218 5605
5219static int wl1271_init_ieee80211(struct wl1271 *wl) 5606static int wl1271_init_ieee80211(struct wl1271 *wl)
5220{ 5607{
5608 int i;
5221 static const u32 cipher_suites[] = { 5609 static const u32 cipher_suites[] = {
5222 WLAN_CIPHER_SUITE_WEP40, 5610 WLAN_CIPHER_SUITE_WEP40,
5223 WLAN_CIPHER_SUITE_WEP104, 5611 WLAN_CIPHER_SUITE_WEP104,
@@ -5248,7 +5636,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5248 IEEE80211_HW_AP_LINK_PS | 5636 IEEE80211_HW_AP_LINK_PS |
5249 IEEE80211_HW_AMPDU_AGGREGATION | 5637 IEEE80211_HW_AMPDU_AGGREGATION |
5250 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | 5638 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
5251 IEEE80211_HW_SCAN_WHILE_IDLE; 5639 IEEE80211_HW_SCAN_WHILE_IDLE |
5640 IEEE80211_HW_QUEUE_CONTROL;
5252 5641
5253 wl->hw->wiphy->cipher_suites = cipher_suites; 5642 wl->hw->wiphy->cipher_suites = cipher_suites;
5254 wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 5643 wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
@@ -5270,6 +5659,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5270 wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE - 5659 wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
5271 sizeof(struct ieee80211_header); 5660 sizeof(struct ieee80211_header);
5272 5661
5662 wl->hw->wiphy->max_remain_on_channel_duration = 5000;
5663
5273 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD | 5664 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD |
5274 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 5665 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
5275 5666
@@ -5278,6 +5669,22 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5278 ARRAY_SIZE(wl1271_channels_5ghz) > 5669 ARRAY_SIZE(wl1271_channels_5ghz) >
5279 WL1271_MAX_CHANNELS); 5670 WL1271_MAX_CHANNELS);
5280 /* 5671 /*
5672 * clear channel flags from the previous usage
5673 * and restore max_power & max_antenna_gain values.
5674 */
5675 for (i = 0; i < ARRAY_SIZE(wl1271_channels); i++) {
5676 wl1271_band_2ghz.channels[i].flags = 0;
5677 wl1271_band_2ghz.channels[i].max_power = WLCORE_MAX_TXPWR;
5678 wl1271_band_2ghz.channels[i].max_antenna_gain = 0;
5679 }
5680
5681 for (i = 0; i < ARRAY_SIZE(wl1271_channels_5ghz); i++) {
5682 wl1271_band_5ghz.channels[i].flags = 0;
5683 wl1271_band_5ghz.channels[i].max_power = WLCORE_MAX_TXPWR;
5684 wl1271_band_5ghz.channels[i].max_antenna_gain = 0;
5685 }
5686
5687 /*
5281 * We keep local copies of the band structs because we need to 5688 * We keep local copies of the band structs because we need to
5282 * modify them on a per-device basis. 5689 * modify them on a per-device basis.
5283 */ 5690 */
@@ -5297,7 +5704,14 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5297 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 5704 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
5298 &wl->bands[IEEE80211_BAND_5GHZ]; 5705 &wl->bands[IEEE80211_BAND_5GHZ];
5299 5706
5300 wl->hw->queues = 4; 5707 /*
5708 * allow 4 queues per mac address we support +
5709 * 1 cab queue per mac + one global offchannel Tx queue
5710 */
5711 wl->hw->queues = (NUM_TX_QUEUES + 1) * WLCORE_NUM_MAC_ADDRESSES + 1;
5712
5713 /* the last queue is the offchannel queue */
5714 wl->hw->offchannel_tx_hw_queue = wl->hw->queues - 1;
5301 wl->hw->max_rates = 1; 5715 wl->hw->max_rates = 1;
5302 5716
5303 wl->hw->wiphy->reg_notifier = wl1271_reg_notify; 5717 wl->hw->wiphy->reg_notifier = wl1271_reg_notify;
@@ -5310,6 +5724,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5310 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; 5724 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
5311 5725
5312 /* allowed interface combinations */ 5726 /* allowed interface combinations */
5727 wlcore_iface_combinations[0].num_different_channels = wl->num_channels;
5313 wl->hw->wiphy->iface_combinations = wlcore_iface_combinations; 5728 wl->hw->wiphy->iface_combinations = wlcore_iface_combinations;
5314 wl->hw->wiphy->n_iface_combinations = 5729 wl->hw->wiphy->n_iface_combinations =
5315 ARRAY_SIZE(wlcore_iface_combinations); 5730 ARRAY_SIZE(wlcore_iface_combinations);
@@ -5326,7 +5741,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5326 5741
5327#define WL1271_DEFAULT_CHANNEL 0 5742#define WL1271_DEFAULT_CHANNEL 0
5328 5743
5329struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size) 5744struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
5745 u32 mbox_size)
5330{ 5746{
5331 struct ieee80211_hw *hw; 5747 struct ieee80211_hw *hw;
5332 struct wl1271 *wl; 5748 struct wl1271 *wl;
@@ -5368,9 +5784,8 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size)
5368 INIT_WORK(&wl->tx_work, wl1271_tx_work); 5784 INIT_WORK(&wl->tx_work, wl1271_tx_work);
5369 INIT_WORK(&wl->recovery_work, wl1271_recovery_work); 5785 INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
5370 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); 5786 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
5787 INIT_DELAYED_WORK(&wl->roc_complete_work, wlcore_roc_complete_work);
5371 INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work); 5788 INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work);
5372 INIT_DELAYED_WORK(&wl->connection_loss_work,
5373 wl1271_connection_loss_work);
5374 5789
5375 wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); 5790 wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
5376 if (!wl->freezable_wq) { 5791 if (!wl->freezable_wq) {
@@ -5386,14 +5801,15 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size)
5386 wl->flags = 0; 5801 wl->flags = 0;
5387 wl->sg_enabled = true; 5802 wl->sg_enabled = true;
5388 wl->sleep_auth = WL1271_PSM_ILLEGAL; 5803 wl->sleep_auth = WL1271_PSM_ILLEGAL;
5804 wl->recovery_count = 0;
5389 wl->hw_pg_ver = -1; 5805 wl->hw_pg_ver = -1;
5390 wl->ap_ps_map = 0; 5806 wl->ap_ps_map = 0;
5391 wl->ap_fw_ps_map = 0; 5807 wl->ap_fw_ps_map = 0;
5392 wl->quirks = 0; 5808 wl->quirks = 0;
5393 wl->platform_quirks = 0; 5809 wl->platform_quirks = 0;
5394 wl->sched_scanning = false;
5395 wl->system_hlid = WL12XX_SYSTEM_HLID; 5810 wl->system_hlid = WL12XX_SYSTEM_HLID;
5396 wl->active_sta_count = 0; 5811 wl->active_sta_count = 0;
5812 wl->active_link_count = 0;
5397 wl->fwlog_size = 0; 5813 wl->fwlog_size = 0;
5398 init_waitqueue_head(&wl->fwlog_waitq); 5814 init_waitqueue_head(&wl->fwlog_waitq);
5399 5815
@@ -5433,14 +5849,24 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size)
5433 goto err_dummy_packet; 5849 goto err_dummy_packet;
5434 } 5850 }
5435 5851
5436 wl->mbox = kmalloc(sizeof(*wl->mbox), GFP_KERNEL | GFP_DMA); 5852 wl->mbox_size = mbox_size;
5853 wl->mbox = kmalloc(wl->mbox_size, GFP_KERNEL | GFP_DMA);
5437 if (!wl->mbox) { 5854 if (!wl->mbox) {
5438 ret = -ENOMEM; 5855 ret = -ENOMEM;
5439 goto err_fwlog; 5856 goto err_fwlog;
5440 } 5857 }
5441 5858
5859 wl->buffer_32 = kmalloc(sizeof(*wl->buffer_32), GFP_KERNEL);
5860 if (!wl->buffer_32) {
5861 ret = -ENOMEM;
5862 goto err_mbox;
5863 }
5864
5442 return hw; 5865 return hw;
5443 5866
5867err_mbox:
5868 kfree(wl->mbox);
5869
5444err_fwlog: 5870err_fwlog:
5445 free_page((unsigned long)wl->fwlog); 5871 free_page((unsigned long)wl->fwlog);
5446 5872
@@ -5479,6 +5905,8 @@ int wlcore_free_hw(struct wl1271 *wl)
5479 device_remove_file(wl->dev, &dev_attr_hw_pg_ver); 5905 device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
5480 5906
5481 device_remove_file(wl->dev, &dev_attr_bt_coex_state); 5907 device_remove_file(wl->dev, &dev_attr_bt_coex_state);
5908 kfree(wl->buffer_32);
5909 kfree(wl->mbox);
5482 free_page((unsigned long)wl->fwlog); 5910 free_page((unsigned long)wl->fwlog);
5483 dev_kfree_skb(wl->dummy_packet); 5911 dev_kfree_skb(wl->dummy_packet);
5484 free_pages((unsigned long)wl->aggr_buf, get_order(wl->aggr_buf_size)); 5912 free_pages((unsigned long)wl->aggr_buf, get_order(wl->aggr_buf_size));
@@ -5535,7 +5963,8 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
5535{ 5963{
5536 struct wl1271 *wl = context; 5964 struct wl1271 *wl = context;
5537 struct platform_device *pdev = wl->pdev; 5965 struct platform_device *pdev = wl->pdev;
5538 struct wl12xx_platform_data *pdata = pdev->dev.platform_data; 5966 struct wlcore_platdev_data *pdev_data = pdev->dev.platform_data;
5967 struct wl12xx_platform_data *pdata = pdev_data->pdata;
5539 unsigned long irqflags; 5968 unsigned long irqflags;
5540 int ret; 5969 int ret;
5541 5970
@@ -5564,8 +5993,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
5564 5993
5565 wl->irq = platform_get_irq(pdev, 0); 5994 wl->irq = platform_get_irq(pdev, 0);
5566 wl->platform_quirks = pdata->platform_quirks; 5995 wl->platform_quirks = pdata->platform_quirks;
5567 wl->set_power = pdata->set_power; 5996 wl->if_ops = pdev_data->if_ops;
5568 wl->if_ops = pdata->ops;
5569 5997
5570 if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) 5998 if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
5571 irqflags = IRQF_TRIGGER_RISING; 5999 irqflags = IRQF_TRIGGER_RISING;
@@ -5711,10 +6139,10 @@ module_param_named(fwlog, fwlog_param, charp, 0);
5711MODULE_PARM_DESC(fwlog, 6139MODULE_PARM_DESC(fwlog,
5712 "FW logger options: continuous, ondemand, dbgpins or disable"); 6140 "FW logger options: continuous, ondemand, dbgpins or disable");
5713 6141
5714module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR); 6142module_param(bug_on_recovery, int, S_IRUSR | S_IWUSR);
5715MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); 6143MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery");
5716 6144
5717module_param(no_recovery, bool, S_IRUSR | S_IWUSR); 6145module_param(no_recovery, int, S_IRUSR | S_IWUSR);
5718MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck."); 6146MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck.");
5719 6147
5720MODULE_LICENSE("GPL"); 6148MODULE_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 646f703ae739..198028df6f4b 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -217,7 +217,7 @@ static struct wl1271_if_operations sdio_ops = {
217static int wl1271_probe(struct sdio_func *func, 217static int wl1271_probe(struct sdio_func *func,
218 const struct sdio_device_id *id) 218 const struct sdio_device_id *id)
219{ 219{
220 struct wl12xx_platform_data *wlan_data; 220 struct wlcore_platdev_data *pdev_data;
221 struct wl12xx_sdio_glue *glue; 221 struct wl12xx_sdio_glue *glue;
222 struct resource res[1]; 222 struct resource res[1];
223 mmc_pm_flag_t mmcflags; 223 mmc_pm_flag_t mmcflags;
@@ -228,10 +228,18 @@ static int wl1271_probe(struct sdio_func *func,
228 if (func->num != 0x02) 228 if (func->num != 0x02)
229 return -ENODEV; 229 return -ENODEV;
230 230
231 pdev_data = kzalloc(sizeof(*pdev_data), GFP_KERNEL);
232 if (!pdev_data) {
233 dev_err(&func->dev, "can't allocate platdev_data\n");
234 goto out;
235 }
236
237 pdev_data->if_ops = &sdio_ops;
238
231 glue = kzalloc(sizeof(*glue), GFP_KERNEL); 239 glue = kzalloc(sizeof(*glue), GFP_KERNEL);
232 if (!glue) { 240 if (!glue) {
233 dev_err(&func->dev, "can't allocate glue\n"); 241 dev_err(&func->dev, "can't allocate glue\n");
234 goto out; 242 goto out_free_pdev_data;
235 } 243 }
236 244
237 glue->dev = &func->dev; 245 glue->dev = &func->dev;
@@ -242,9 +250,9 @@ static int wl1271_probe(struct sdio_func *func,
242 /* Use block mode for transferring over one block size of data */ 250 /* Use block mode for transferring over one block size of data */
243 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; 251 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
244 252
245 wlan_data = wl12xx_get_platform_data(); 253 pdev_data->pdata = wl12xx_get_platform_data();
246 if (IS_ERR(wlan_data)) { 254 if (IS_ERR(pdev_data->pdata)) {
247 ret = PTR_ERR(wlan_data); 255 ret = PTR_ERR(pdev_data->pdata);
248 dev_err(glue->dev, "missing wlan platform data: %d\n", ret); 256 dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
249 goto out_free_glue; 257 goto out_free_glue;
250 } 258 }
@@ -254,9 +262,7 @@ static int wl1271_probe(struct sdio_func *func,
254 dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags); 262 dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
255 263
256 if (mmcflags & MMC_PM_KEEP_POWER) 264 if (mmcflags & MMC_PM_KEEP_POWER)
257 wlan_data->pwr_in_suspend = true; 265 pdev_data->pdata->pwr_in_suspend = true;
258
259 wlan_data->ops = &sdio_ops;
260 266
261 sdio_set_drvdata(func, glue); 267 sdio_set_drvdata(func, glue);
262 268
@@ -274,7 +280,7 @@ static int wl1271_probe(struct sdio_func *func,
274 else 280 else
275 chip_family = "wl12xx"; 281 chip_family = "wl12xx";
276 282
277 glue->core = platform_device_alloc(chip_family, -1); 283 glue->core = platform_device_alloc(chip_family, PLATFORM_DEVID_AUTO);
278 if (!glue->core) { 284 if (!glue->core) {
279 dev_err(glue->dev, "can't allocate platform_device"); 285 dev_err(glue->dev, "can't allocate platform_device");
280 ret = -ENOMEM; 286 ret = -ENOMEM;
@@ -285,7 +291,7 @@ static int wl1271_probe(struct sdio_func *func,
285 291
286 memset(res, 0x00, sizeof(res)); 292 memset(res, 0x00, sizeof(res));
287 293
288 res[0].start = wlan_data->irq; 294 res[0].start = pdev_data->pdata->irq;
289 res[0].flags = IORESOURCE_IRQ; 295 res[0].flags = IORESOURCE_IRQ;
290 res[0].name = "irq"; 296 res[0].name = "irq";
291 297
@@ -295,8 +301,8 @@ static int wl1271_probe(struct sdio_func *func,
295 goto out_dev_put; 301 goto out_dev_put;
296 } 302 }
297 303
298 ret = platform_device_add_data(glue->core, wlan_data, 304 ret = platform_device_add_data(glue->core, pdev_data,
299 sizeof(*wlan_data)); 305 sizeof(*pdev_data));
300 if (ret) { 306 if (ret) {
301 dev_err(glue->dev, "can't add platform data\n"); 307 dev_err(glue->dev, "can't add platform data\n");
302 goto out_dev_put; 308 goto out_dev_put;
@@ -315,6 +321,9 @@ out_dev_put:
315out_free_glue: 321out_free_glue:
316 kfree(glue); 322 kfree(glue);
317 323
324out_free_pdev_data:
325 kfree(pdev_data);
326
318out: 327out:
319 return ret; 328 return ret;
320} 329}
@@ -326,8 +335,7 @@ static void wl1271_remove(struct sdio_func *func)
326 /* Undo decrement done above in wl1271_probe */ 335 /* Undo decrement done above in wl1271_probe */
327 pm_runtime_get_noresume(&func->dev); 336 pm_runtime_get_noresume(&func->dev);
328 337
329 platform_device_del(glue->core); 338 platform_device_unregister(glue->core);
330 platform_device_put(glue->core);
331 kfree(glue); 339 kfree(glue);
332} 340}
333 341
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index f06f4770ce02..5ad2e100e59b 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -270,7 +270,7 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
270 void *buf, size_t len, bool fixed) 270 void *buf, size_t len, bool fixed)
271{ 271{
272 struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); 272 struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
273 struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; 273 struct spi_transfer t[2 * (WSPI_MAX_NUM_OF_CHUNKS + 1)];
274 struct spi_message m; 274 struct spi_message m;
275 u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; 275 u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
276 u32 *cmd; 276 u32 *cmd;
@@ -327,22 +327,29 @@ static struct wl1271_if_operations spi_ops = {
327static int wl1271_probe(struct spi_device *spi) 327static int wl1271_probe(struct spi_device *spi)
328{ 328{
329 struct wl12xx_spi_glue *glue; 329 struct wl12xx_spi_glue *glue;
330 struct wl12xx_platform_data *pdata; 330 struct wlcore_platdev_data *pdev_data;
331 struct resource res[1]; 331 struct resource res[1];
332 int ret = -ENOMEM; 332 int ret = -ENOMEM;
333 333
334 pdata = spi->dev.platform_data; 334 pdev_data = kzalloc(sizeof(*pdev_data), GFP_KERNEL);
335 if (!pdata) { 335 if (!pdev_data) {
336 dev_err(&spi->dev, "can't allocate platdev_data\n");
337 goto out;
338 }
339
340 pdev_data->pdata = spi->dev.platform_data;
341 if (!pdev_data->pdata) {
336 dev_err(&spi->dev, "no platform data\n"); 342 dev_err(&spi->dev, "no platform data\n");
337 return -ENODEV; 343 ret = -ENODEV;
344 goto out_free_pdev_data;
338 } 345 }
339 346
340 pdata->ops = &spi_ops; 347 pdev_data->if_ops = &spi_ops;
341 348
342 glue = kzalloc(sizeof(*glue), GFP_KERNEL); 349 glue = kzalloc(sizeof(*glue), GFP_KERNEL);
343 if (!glue) { 350 if (!glue) {
344 dev_err(&spi->dev, "can't allocate glue\n"); 351 dev_err(&spi->dev, "can't allocate glue\n");
345 goto out; 352 goto out_free_pdev_data;
346 } 353 }
347 354
348 glue->dev = &spi->dev; 355 glue->dev = &spi->dev;
@@ -359,7 +366,7 @@ static int wl1271_probe(struct spi_device *spi)
359 goto out_free_glue; 366 goto out_free_glue;
360 } 367 }
361 368
362 glue->core = platform_device_alloc("wl12xx", -1); 369 glue->core = platform_device_alloc("wl12xx", PLATFORM_DEVID_AUTO);
363 if (!glue->core) { 370 if (!glue->core) {
364 dev_err(glue->dev, "can't allocate platform_device\n"); 371 dev_err(glue->dev, "can't allocate platform_device\n");
365 ret = -ENOMEM; 372 ret = -ENOMEM;
@@ -380,7 +387,8 @@ static int wl1271_probe(struct spi_device *spi)
380 goto out_dev_put; 387 goto out_dev_put;
381 } 388 }
382 389
383 ret = platform_device_add_data(glue->core, pdata, sizeof(*pdata)); 390 ret = platform_device_add_data(glue->core, pdev_data,
391 sizeof(*pdev_data));
384 if (ret) { 392 if (ret) {
385 dev_err(glue->dev, "can't add platform data\n"); 393 dev_err(glue->dev, "can't add platform data\n");
386 goto out_dev_put; 394 goto out_dev_put;
@@ -399,6 +407,10 @@ out_dev_put:
399 407
400out_free_glue: 408out_free_glue:
401 kfree(glue); 409 kfree(glue);
410
411out_free_pdev_data:
412 kfree(pdev_data);
413
402out: 414out:
403 return ret; 415 return ret;
404} 416}
@@ -407,8 +419,7 @@ static int wl1271_remove(struct spi_device *spi)
407{ 419{
408 struct wl12xx_spi_glue *glue = spi_get_drvdata(spi); 420 struct wl12xx_spi_glue *glue = spi_get_drvdata(spi);
409 421
410 platform_device_del(glue->core); 422 platform_device_unregister(glue->core);
411 platform_device_put(glue->core);
412 kfree(glue); 423 kfree(glue);
413 424
414 return 0; 425 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..af9fecaefc30 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 {
@@ -157,7 +183,6 @@ struct wl1271 {
157 183
158 struct wl1271_if_operations *if_ops; 184 struct wl1271_if_operations *if_ops;
159 185
160 void (*set_power)(bool enable);
161 int irq; 186 int irq;
162 187
163 spinlock_t wl_lock; 188 spinlock_t wl_lock;
@@ -202,6 +227,8 @@ struct wl1271 {
202 unsigned long klv_templates_map[ 227 unsigned long klv_templates_map[
203 BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)]; 228 BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)];
204 229
230 u8 session_ids[WL12XX_MAX_LINKS];
231
205 struct list_head wlvif_list; 232 struct list_head wlvif_list;
206 233
207 u8 sta_count; 234 u8 sta_count;
@@ -227,7 +254,8 @@ struct wl1271 {
227 254
228 /* Frames scheduled for transmission, not handled yet */ 255 /* Frames scheduled for transmission, not handled yet */
229 int tx_queue_count[NUM_TX_QUEUES]; 256 int tx_queue_count[NUM_TX_QUEUES];
230 unsigned long queue_stop_reasons[NUM_TX_QUEUES]; 257 unsigned long queue_stop_reasons[
258 NUM_TX_QUEUES * WLCORE_NUM_MAC_ADDRESSES];
231 259
232 /* Frames received, not handled yet by mac80211 */ 260 /* Frames received, not handled yet by mac80211 */
233 struct sk_buff_head deferred_rx_queue; 261 struct sk_buff_head deferred_rx_queue;
@@ -269,24 +297,30 @@ struct wl1271 {
269 struct work_struct recovery_work; 297 struct work_struct recovery_work;
270 bool watchdog_recovery; 298 bool watchdog_recovery;
271 299
300 /* Reg domain last configuration */
301 u32 reg_ch_conf_last[2];
302 /* Reg domain pending configuration */
303 u32 reg_ch_conf_pending[2];
304
272 /* Pointer that holds DMA-friendly block for the mailbox */ 305 /* Pointer that holds DMA-friendly block for the mailbox */
273 struct event_mailbox *mbox; 306 void *mbox;
274 307
275 /* The mbox event mask */ 308 /* The mbox event mask */
276 u32 event_mask; 309 u32 event_mask;
277 310
278 /* Mailbox pointers */ 311 /* Mailbox pointers */
312 u32 mbox_size;
279 u32 mbox_ptr[2]; 313 u32 mbox_ptr[2];
280 314
281 /* Are we currently scanning */ 315 /* Are we currently scanning */
282 struct ieee80211_vif *scan_vif; 316 struct wl12xx_vif *scan_wlvif;
283 struct wl1271_scan scan; 317 struct wl1271_scan scan;
284 struct delayed_work scan_complete_work; 318 struct delayed_work scan_complete_work;
285 319
286 /* Connection loss work */ 320 struct ieee80211_vif *roc_vif;
287 struct delayed_work connection_loss_work; 321 struct delayed_work roc_complete_work;
288 322
289 bool sched_scanning; 323 struct wl12xx_vif *sched_vif;
290 324
291 /* The current band */ 325 /* The current band */
292 enum ieee80211_band band; 326 enum ieee80211_band band;
@@ -299,7 +333,7 @@ struct wl1271 {
299 333
300 struct wl1271_stats stats; 334 struct wl1271_stats stats;
301 335
302 __le32 buffer_32; 336 __le32 *buffer_32;
303 u32 buffer_cmd; 337 u32 buffer_cmd;
304 u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; 338 u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
305 339
@@ -314,6 +348,8 @@ struct wl1271 {
314 348
315 bool enable_11a; 349 bool enable_11a;
316 350
351 int recovery_count;
352
317 /* Most recently reported noise in dBm */ 353 /* Most recently reported noise in dBm */
318 s8 noise; 354 s8 noise;
319 355
@@ -333,6 +369,12 @@ struct wl1271 {
333 */ 369 */
334 struct wl1271_link links[WL12XX_MAX_LINKS]; 370 struct wl1271_link links[WL12XX_MAX_LINKS];
335 371
372 /* number of currently active links */
373 int active_link_count;
374
375 /* Fast/slow links bitmap according to FW */
376 u32 fw_fast_lnk_map;
377
336 /* AP-mode - a bitmap of links currently in PS mode according to FW */ 378 /* AP-mode - a bitmap of links currently in PS mode according to FW */
337 u32 ap_fw_ps_map; 379 u32 ap_fw_ps_map;
338 380
@@ -367,6 +409,12 @@ struct wl1271 {
367 const char *sr_fw_name; 409 const char *sr_fw_name;
368 const char *mr_fw_name; 410 const char *mr_fw_name;
369 411
412 u8 scan_templ_id_2_4;
413 u8 scan_templ_id_5;
414 u8 sched_scan_templ_id_2_4;
415 u8 sched_scan_templ_id_5;
416 u8 max_channels_5;
417
370 /* per-chip-family private structure */ 418 /* per-chip-family private structure */
371 void *priv; 419 void *priv;
372 420
@@ -408,20 +456,28 @@ struct wl1271 {
408 /* the number of allocated MAC addresses in this chip */ 456 /* the number of allocated MAC addresses in this chip */
409 int num_mac_addr; 457 int num_mac_addr;
410 458
411 /* the minimum FW version required for the driver to work */ 459 /* minimum FW version required for the driver to work in single-role */
412 unsigned int min_fw_ver[NUM_FW_VER]; 460 unsigned int min_sr_fw_ver[NUM_FW_VER];
461
462 /* minimum FW version required for the driver to work in multi-role */
463 unsigned int min_mr_fw_ver[NUM_FW_VER];
413 464
414 struct completion nvs_loading_complete; 465 struct completion nvs_loading_complete;
466
467 /* number of concurrent channels the HW supports */
468 u32 num_channels;
415}; 469};
416 470
417int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); 471int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
418int wlcore_remove(struct platform_device *pdev); 472int wlcore_remove(struct platform_device *pdev);
419struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size); 473struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
474 u32 mbox_size);
420int wlcore_free_hw(struct wl1271 *wl); 475int wlcore_free_hw(struct wl1271 *wl);
421int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, 476int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
422 struct ieee80211_vif *vif, 477 struct ieee80211_vif *vif,
423 struct ieee80211_sta *sta, 478 struct ieee80211_sta *sta,
424 struct ieee80211_key_conf *key_conf); 479 struct ieee80211_key_conf *key_conf);
480void wlcore_regdomain_config(struct wl1271 *wl);
425 481
426static inline void 482static inline void
427wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band, 483wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band,
@@ -430,16 +486,27 @@ wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band,
430 memcpy(&wl->ht_cap[band], ht_cap, sizeof(*ht_cap)); 486 memcpy(&wl->ht_cap[band], ht_cap, sizeof(*ht_cap));
431} 487}
432 488
489/* Tell wlcore not to care about this element when checking the version */
490#define WLCORE_FW_VER_IGNORE -1
491
433static inline void 492static inline void
434wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip, 493wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip,
435 unsigned int iftype, unsigned int major, 494 unsigned int iftype_sr, unsigned int major_sr,
436 unsigned int subtype, unsigned int minor) 495 unsigned int subtype_sr, unsigned int minor_sr,
496 unsigned int iftype_mr, unsigned int major_mr,
497 unsigned int subtype_mr, unsigned int minor_mr)
437{ 498{
438 wl->min_fw_ver[FW_VER_CHIP] = chip; 499 wl->min_sr_fw_ver[FW_VER_CHIP] = chip;
439 wl->min_fw_ver[FW_VER_IF_TYPE] = iftype; 500 wl->min_sr_fw_ver[FW_VER_IF_TYPE] = iftype_sr;
440 wl->min_fw_ver[FW_VER_MAJOR] = major; 501 wl->min_sr_fw_ver[FW_VER_MAJOR] = major_sr;
441 wl->min_fw_ver[FW_VER_SUBTYPE] = subtype; 502 wl->min_sr_fw_ver[FW_VER_SUBTYPE] = subtype_sr;
442 wl->min_fw_ver[FW_VER_MINOR] = minor; 503 wl->min_sr_fw_ver[FW_VER_MINOR] = minor_sr;
504
505 wl->min_mr_fw_ver[FW_VER_CHIP] = chip;
506 wl->min_mr_fw_ver[FW_VER_IF_TYPE] = iftype_mr;
507 wl->min_mr_fw_ver[FW_VER_MAJOR] = major_mr;
508 wl->min_mr_fw_ver[FW_VER_SUBTYPE] = subtype_mr;
509 wl->min_mr_fw_ver[FW_VER_MINOR] = minor_mr;
443} 510}
444 511
445/* Firmware image load chunk size */ 512/* Firmware image load chunk size */
@@ -450,6 +517,9 @@ wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip,
450/* Each RX/TX transaction requires an end-of-transaction transfer */ 517/* Each RX/TX transaction requires an end-of-transaction transfer */
451#define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0) 518#define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0)
452 519
520/* the first start_role(sta) sometimes doesn't work on wl12xx */
521#define WLCORE_QUIRK_START_STA_FAILS BIT(1)
522
453/* wl127x and SPI don't support SDIO block size alignment */ 523/* wl127x and SPI don't support SDIO block size alignment */
454#define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2) 524#define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2)
455 525
@@ -462,9 +532,6 @@ wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip,
462/* Older firmwares use an old NVS format */ 532/* Older firmwares use an old NVS format */
463#define WLCORE_QUIRK_LEGACY_NVS BIT(5) 533#define WLCORE_QUIRK_LEGACY_NVS BIT(5)
464 534
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 */ 535/* pad only the last frame in the aggregate buffer */
469#define WLCORE_QUIRK_TX_PAD_LAST_FRAME BIT(7) 536#define WLCORE_QUIRK_TX_PAD_LAST_FRAME BIT(7)
470 537
@@ -477,11 +544,11 @@ wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip,
477/* separate probe response templates for one-shot and sched scans */ 544/* separate probe response templates for one-shot and sched scans */
478#define WLCORE_QUIRK_DUAL_PROBE_TMPL BIT(10) 545#define WLCORE_QUIRK_DUAL_PROBE_TMPL BIT(10)
479 546
480/* TODO: move to the lower drivers when all usages are abstracted */ 547/* Firmware requires reg domain configuration for active calibration */
481#define CHIP_ID_1271_PG10 (0x4030101) 548#define WLCORE_QUIRK_REGDOMAIN_CONF BIT(11)
482#define CHIP_ID_1271_PG20 (0x4030111) 549
483#define CHIP_ID_1283_PG10 (0x05030101) 550/* The FW only support a zero session id for AP */
484#define CHIP_ID_1283_PG20 (0x05030111) 551#define WLCORE_QUIRK_AP_ZERO_SESSION_ID BIT(12)
485 552
486/* TODO: move all these common registers and values elsewhere */ 553/* TODO: move all these common registers and values elsewhere */
487#define HW_ACCESS_ELP_CTRL_REG 0x1FFFC 554#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 6678d4b18611..c845b0ef7f4b 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_BUSINFO_LEN]; 114 char fw_ver_str[ETHTOOL_BUSINFO_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 */
@@ -214,6 +206,11 @@ struct wl1271_if_operations {
214 void (*set_block_size) (struct device *child, unsigned int blksz); 206 void (*set_block_size) (struct device *child, unsigned int blksz);
215}; 207};
216 208
209struct wlcore_platdev_data {
210 struct wl12xx_platform_data *pdata;
211 struct wl1271_if_operations *if_ops;
212};
213
217#define MAX_NUM_KEYS 14 214#define MAX_NUM_KEYS 14
218#define MAX_KEY_SIZE 32 215#define MAX_KEY_SIZE 32
219 216
@@ -260,6 +257,8 @@ enum wl12xx_vif_flags {
260 WLVIF_FLAG_IN_USE, 257 WLVIF_FLAG_IN_USE,
261}; 258};
262 259
260struct wl12xx_vif;
261
263struct wl1271_link { 262struct wl1271_link {
264 /* AP-mode - TX queue per AC in link */ 263 /* AP-mode - TX queue per AC in link */
265 struct sk_buff_head tx_queue[NUM_TX_QUEUES]; 264 struct sk_buff_head tx_queue[NUM_TX_QUEUES];
@@ -272,6 +271,9 @@ struct wl1271_link {
272 271
273 /* bitmap of TIDs where RX BA sessions are active for this link */ 272 /* bitmap of TIDs where RX BA sessions are active for this link */
274 u8 ba_bitmap; 273 u8 ba_bitmap;
274
275 /* The wlvif this link belongs to. Might be null for global links */
276 struct wl12xx_vif *wlvif;
275}; 277};
276 278
277#define WL1271_MAX_RX_FILTERS 5 279#define WL1271_MAX_RX_FILTERS 5
@@ -315,6 +317,7 @@ struct wl12xx_rx_filter {
315 317
316struct wl1271_station { 318struct wl1271_station {
317 u8 hlid; 319 u8 hlid;
320 bool in_connection;
318}; 321};
319 322
320struct wl12xx_vif { 323struct wl12xx_vif {
@@ -332,7 +335,6 @@ struct wl12xx_vif {
332 union { 335 union {
333 struct { 336 struct {
334 u8 hlid; 337 u8 hlid;
335 u8 ba_rx_bitmap;
336 338
337 u8 basic_rate_idx; 339 u8 basic_rate_idx;
338 u8 ap_rate_idx; 340 u8 ap_rate_idx;
@@ -341,6 +343,8 @@ struct wl12xx_vif {
341 u8 klv_template_id; 343 u8 klv_template_id;
342 344
343 bool qos; 345 bool qos;
346 /* channel type we started the STA role with */
347 enum nl80211_channel_type role_chan_type;
344 } sta; 348 } sta;
345 struct { 349 struct {
346 u8 global_hlid; 350 u8 global_hlid;
@@ -362,6 +366,9 @@ struct wl12xx_vif {
362 /* the hlid of the last transmitted skb */ 366 /* the hlid of the last transmitted skb */
363 int last_tx_hlid; 367 int last_tx_hlid;
364 368
369 /* counters of packets per AC, across all links in the vif */
370 int tx_queue_count[NUM_TX_QUEUES];
371
365 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; 372 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
366 373
367 u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; 374 u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
@@ -396,9 +403,6 @@ struct wl12xx_vif {
396 /* Our association ID */ 403 /* Our association ID */
397 u16 aid; 404 u16 aid;
398 405
399 /* Session counter for the chipset */
400 int session_counter;
401
402 /* retry counter for PSM entries */ 406 /* retry counter for PSM entries */
403 u8 psm_entry_retry; 407 u8 psm_entry_retry;
404 408
@@ -416,11 +420,28 @@ struct wl12xx_vif {
416 bool ba_support; 420 bool ba_support;
417 bool ba_allowed; 421 bool ba_allowed;
418 422
423 bool wmm_enabled;
424
419 /* Rx Streaming */ 425 /* Rx Streaming */
420 struct work_struct rx_streaming_enable_work; 426 struct work_struct rx_streaming_enable_work;
421 struct work_struct rx_streaming_disable_work; 427 struct work_struct rx_streaming_disable_work;
422 struct timer_list rx_streaming_timer; 428 struct timer_list rx_streaming_timer;
423 429
430 struct delayed_work channel_switch_work;
431 struct delayed_work connection_loss_work;
432
433 /* number of in connection stations */
434 int inconn_count;
435
436 /*
437 * This vif's queues are mapped to mac80211 HW queues as:
438 * VO - hw_queue_base
439 * VI - hw_queue_base + 1
440 * BE - hw_queue_base + 2
441 * BK - hw_queue_base + 3
442 */
443 int hw_queue_base;
444
424 /* 445 /*
425 * This struct must be last! 446 * This struct must be last!
426 * data that has to be saved acrossed reconfigs (e.g. recovery) 447 * data that has to be saved acrossed reconfigs (e.g. recovery)
@@ -443,6 +464,7 @@ struct wl12xx_vif {
443 464
444static inline struct wl12xx_vif *wl12xx_vif_to_data(struct ieee80211_vif *vif) 465static inline struct wl12xx_vif *wl12xx_vif_to_data(struct ieee80211_vif *vif)
445{ 466{
467 WARN_ON(!vif);
446 return (struct wl12xx_vif *)vif->drv_priv; 468 return (struct wl12xx_vif *)vif->drv_priv;
447} 469}
448 470
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index 80c728b28828..e57034971ccc 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -27,5 +27,6 @@ config NFC_WILINK
27 into the kernel or say M to compile it as module. 27 into the kernel or say M to compile it as module.
28 28
29source "drivers/nfc/pn544/Kconfig" 29source "drivers/nfc/pn544/Kconfig"
30source "drivers/nfc/microread/Kconfig"
30 31
31endmenu 32endmenu
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index 574bbc04d97a..a189ada0926a 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -3,6 +3,7 @@
3# 3#
4 4
5obj-$(CONFIG_NFC_PN544) += pn544/ 5obj-$(CONFIG_NFC_PN544) += pn544/
6obj-$(CONFIG_NFC_MICROREAD) += microread/
6obj-$(CONFIG_NFC_PN533) += pn533.o 7obj-$(CONFIG_NFC_PN533) += pn533.o
7obj-$(CONFIG_NFC_WILINK) += nfcwilink.o 8obj-$(CONFIG_NFC_WILINK) += nfcwilink.o
8 9
diff --git a/drivers/nfc/microread/Kconfig b/drivers/nfc/microread/Kconfig
new file mode 100644
index 000000000000..572305be6e37
--- /dev/null
+++ b/drivers/nfc/microread/Kconfig
@@ -0,0 +1,35 @@
1config NFC_MICROREAD
2 tristate "Inside Secure microread NFC driver"
3 depends on NFC_HCI
4 select CRC_CCITT
5 default n
6 ---help---
7 This module contains the main code for Inside Secure microread
8 NFC chipsets. It implements the chipset HCI logic and hooks into
9 the NFC kernel APIs. Physical layers will register against it.
10
11 To compile this driver as a module, choose m here. The module will
12 be called microread.
13 Say N if unsure.
14
15config NFC_MICROREAD_I2C
16 tristate "NFC Microread i2c support"
17 depends on NFC_MICROREAD && I2C && NFC_SHDLC
18 ---help---
19 This module adds support for the i2c interface of adapters using
20 Inside microread chipsets. Select this if your platform is using
21 the i2c bus.
22
23 If you choose to build a module, it'll be called microread_i2c.
24 Say N if unsure.
25
26config NFC_MICROREAD_MEI
27 tristate "NFC Microread MEI support"
28 depends on NFC_MICROREAD && INTEL_MEI_BUS_NFC
29 ---help---
30 This module adds support for the mei interface of adapters using
31 Inside microread chipsets. Select this if your microread chipset
32 is handled by Intel's Management Engine Interface on your platform.
33
34 If you choose to build a module, it'll be called microread_mei.
35 Say N if unsure.
diff --git a/drivers/nfc/microread/Makefile b/drivers/nfc/microread/Makefile
new file mode 100644
index 000000000000..755c24cba253
--- /dev/null
+++ b/drivers/nfc/microread/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for Microread HCI based NFC driver
3#
4
5microread_i2c-objs = i2c.o
6microread_mei-objs = mei.o
7
8obj-$(CONFIG_NFC_MICROREAD) += microread.o
9obj-$(CONFIG_NFC_MICROREAD_I2C) += microread_i2c.o
10obj-$(CONFIG_NFC_MICROREAD_MEI) += microread_mei.o
diff --git a/drivers/nfc/microread/i2c.c b/drivers/nfc/microread/i2c.c
new file mode 100644
index 000000000000..101089495bf8
--- /dev/null
+++ b/drivers/nfc/microread/i2c.c
@@ -0,0 +1,340 @@
1/*
2 * HCI based Driver for Inside Secure microread NFC Chip - i2c layer
3 *
4 * Copyright (C) 2013 Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions 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,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU 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
17 * Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/i2c.h>
23#include <linux/delay.h>
24#include <linux/slab.h>
25#include <linux/interrupt.h>
26#include <linux/gpio.h>
27
28#include <linux/nfc.h>
29#include <net/nfc/hci.h>
30#include <net/nfc/llc.h>
31
32#include "microread.h"
33
34#define MICROREAD_I2C_DRIVER_NAME "microread"
35
36#define MICROREAD_I2C_FRAME_HEADROOM 1
37#define MICROREAD_I2C_FRAME_TAILROOM 1
38
39/* framing in HCI mode */
40#define MICROREAD_I2C_LLC_LEN 1
41#define MICROREAD_I2C_LLC_CRC 1
42#define MICROREAD_I2C_LLC_LEN_CRC (MICROREAD_I2C_LLC_LEN + \
43 MICROREAD_I2C_LLC_CRC)
44#define MICROREAD_I2C_LLC_MIN_SIZE (1 + MICROREAD_I2C_LLC_LEN_CRC)
45#define MICROREAD_I2C_LLC_MAX_PAYLOAD 29
46#define MICROREAD_I2C_LLC_MAX_SIZE (MICROREAD_I2C_LLC_LEN_CRC + 1 + \
47 MICROREAD_I2C_LLC_MAX_PAYLOAD)
48
49struct microread_i2c_phy {
50 struct i2c_client *i2c_dev;
51 struct nfc_hci_dev *hdev;
52
53 int irq;
54
55 int hard_fault; /*
56 * < 0 if hardware error occured (e.g. i2c err)
57 * and prevents normal operation.
58 */
59};
60
61#define I2C_DUMP_SKB(info, skb) \
62do { \
63 pr_debug("%s:\n", info); \
64 print_hex_dump(KERN_DEBUG, "i2c: ", DUMP_PREFIX_OFFSET, \
65 16, 1, (skb)->data, (skb)->len, 0); \
66} while (0)
67
68static void microread_i2c_add_len_crc(struct sk_buff *skb)
69{
70 int i;
71 u8 crc = 0;
72 int len;
73
74 len = skb->len;
75 *skb_push(skb, 1) = len;
76
77 for (i = 0; i < skb->len; i++)
78 crc = crc ^ skb->data[i];
79
80 *skb_put(skb, 1) = crc;
81}
82
83static void microread_i2c_remove_len_crc(struct sk_buff *skb)
84{
85 skb_pull(skb, MICROREAD_I2C_FRAME_HEADROOM);
86 skb_trim(skb, MICROREAD_I2C_FRAME_TAILROOM);
87}
88
89static int check_crc(struct sk_buff *skb)
90{
91 int i;
92 u8 crc = 0;
93
94 for (i = 0; i < skb->len - 1; i++)
95 crc = crc ^ skb->data[i];
96
97 if (crc != skb->data[skb->len-1]) {
98 pr_err(MICROREAD_I2C_DRIVER_NAME
99 ": CRC error 0x%x != 0x%x\n",
100 crc, skb->data[skb->len-1]);
101
102 pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__);
103
104 return -EPERM;
105 }
106
107 return 0;
108}
109
110static int microread_i2c_enable(void *phy_id)
111{
112 return 0;
113}
114
115static void microread_i2c_disable(void *phy_id)
116{
117 return;
118}
119
120static int microread_i2c_write(void *phy_id, struct sk_buff *skb)
121{
122 int r;
123 struct microread_i2c_phy *phy = phy_id;
124 struct i2c_client *client = phy->i2c_dev;
125
126 if (phy->hard_fault != 0)
127 return phy->hard_fault;
128
129 usleep_range(3000, 6000);
130
131 microread_i2c_add_len_crc(skb);
132
133 I2C_DUMP_SKB("i2c frame written", skb);
134
135 r = i2c_master_send(client, skb->data, skb->len);
136
137 if (r == -EREMOTEIO) { /* Retry, chip was in standby */
138 usleep_range(6000, 10000);
139 r = i2c_master_send(client, skb->data, skb->len);
140 }
141
142 if (r >= 0) {
143 if (r != skb->len)
144 r = -EREMOTEIO;
145 else
146 r = 0;
147 }
148
149 microread_i2c_remove_len_crc(skb);
150
151 return r;
152}
153
154
155static int microread_i2c_read(struct microread_i2c_phy *phy,
156 struct sk_buff **skb)
157{
158 int r;
159 u8 len;
160 u8 tmp[MICROREAD_I2C_LLC_MAX_SIZE - 1];
161 struct i2c_client *client = phy->i2c_dev;
162
163 pr_debug("%s\n", __func__);
164
165 r = i2c_master_recv(client, &len, 1);
166 if (r != 1) {
167 dev_err(&client->dev, "cannot read len byte\n");
168 return -EREMOTEIO;
169 }
170
171 if ((len < MICROREAD_I2C_LLC_MIN_SIZE) ||
172 (len > MICROREAD_I2C_LLC_MAX_SIZE)) {
173 dev_err(&client->dev, "invalid len byte\n");
174 pr_err("invalid len byte\n");
175 r = -EBADMSG;
176 goto flush;
177 }
178
179 *skb = alloc_skb(1 + len, GFP_KERNEL);
180 if (*skb == NULL) {
181 r = -ENOMEM;
182 goto flush;
183 }
184
185 *skb_put(*skb, 1) = len;
186
187 r = i2c_master_recv(client, skb_put(*skb, len), len);
188 if (r != len) {
189 kfree_skb(*skb);
190 return -EREMOTEIO;
191 }
192
193 I2C_DUMP_SKB("cc frame read", *skb);
194
195 r = check_crc(*skb);
196 if (r != 0) {
197 kfree_skb(*skb);
198 r = -EBADMSG;
199 goto flush;
200 }
201
202 skb_pull(*skb, 1);
203 skb_trim(*skb, (*skb)->len - MICROREAD_I2C_FRAME_TAILROOM);
204
205 usleep_range(3000, 6000);
206
207 return 0;
208
209flush:
210 if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0)
211 r = -EREMOTEIO;
212
213 usleep_range(3000, 6000);
214
215 return r;
216}
217
218static irqreturn_t microread_i2c_irq_thread_fn(int irq, void *phy_id)
219{
220 struct microread_i2c_phy *phy = phy_id;
221 struct i2c_client *client;
222 struct sk_buff *skb = NULL;
223 int r;
224
225 if (!phy || irq != phy->i2c_dev->irq) {
226 WARN_ON_ONCE(1);
227 return IRQ_NONE;
228 }
229
230 client = phy->i2c_dev;
231 dev_dbg(&client->dev, "IRQ\n");
232
233 if (phy->hard_fault != 0)
234 return IRQ_HANDLED;
235
236 r = microread_i2c_read(phy, &skb);
237 if (r == -EREMOTEIO) {
238 phy->hard_fault = r;
239
240 nfc_hci_recv_frame(phy->hdev, NULL);
241
242 return IRQ_HANDLED;
243 } else if ((r == -ENOMEM) || (r == -EBADMSG)) {
244 return IRQ_HANDLED;
245 }
246
247 nfc_hci_recv_frame(phy->hdev, skb);
248
249 return IRQ_HANDLED;
250}
251
252static struct nfc_phy_ops i2c_phy_ops = {
253 .write = microread_i2c_write,
254 .enable = microread_i2c_enable,
255 .disable = microread_i2c_disable,
256};
257
258static int microread_i2c_probe(struct i2c_client *client,
259 const struct i2c_device_id *id)
260{
261 struct microread_i2c_phy *phy;
262 struct microread_nfc_platform_data *pdata =
263 dev_get_platdata(&client->dev);
264 int r;
265
266 dev_dbg(&client->dev, "client %p", client);
267
268 if (!pdata) {
269 dev_err(&client->dev, "client %p: missing platform data",
270 client);
271 return -EINVAL;
272 }
273
274 phy = devm_kzalloc(&client->dev, sizeof(struct microread_i2c_phy),
275 GFP_KERNEL);
276 if (!phy) {
277 dev_err(&client->dev, "Can't allocate microread phy");
278 return -ENOMEM;
279 }
280
281 i2c_set_clientdata(client, phy);
282 phy->i2c_dev = client;
283
284 r = request_threaded_irq(client->irq, NULL, microread_i2c_irq_thread_fn,
285 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
286 MICROREAD_I2C_DRIVER_NAME, phy);
287 if (r) {
288 dev_err(&client->dev, "Unable to register IRQ handler");
289 return r;
290 }
291
292 r = microread_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME,
293 MICROREAD_I2C_FRAME_HEADROOM,
294 MICROREAD_I2C_FRAME_TAILROOM,
295 MICROREAD_I2C_LLC_MAX_PAYLOAD, &phy->hdev);
296 if (r < 0)
297 goto err_irq;
298
299 dev_info(&client->dev, "Probed");
300
301 return 0;
302
303err_irq:
304 free_irq(client->irq, phy);
305
306 return r;
307}
308
309static int microread_i2c_remove(struct i2c_client *client)
310{
311 struct microread_i2c_phy *phy = i2c_get_clientdata(client);
312
313 dev_dbg(&client->dev, "%s\n", __func__);
314
315 microread_remove(phy->hdev);
316
317 free_irq(client->irq, phy);
318
319 return 0;
320}
321
322static struct i2c_device_id microread_i2c_id[] = {
323 { MICROREAD_I2C_DRIVER_NAME, 0},
324 { }
325};
326MODULE_DEVICE_TABLE(i2c, microread_i2c_id);
327
328static struct i2c_driver microread_i2c_driver = {
329 .driver = {
330 .name = MICROREAD_I2C_DRIVER_NAME,
331 },
332 .probe = microread_i2c_probe,
333 .remove = microread_i2c_remove,
334 .id_table = microread_i2c_id,
335};
336
337module_i2c_driver(microread_i2c_driver);
338
339MODULE_LICENSE("GPL");
340MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/nfc/microread/mei.c b/drivers/nfc/microread/mei.c
new file mode 100644
index 000000000000..c078e56d7d14
--- /dev/null
+++ b/drivers/nfc/microread/mei.c
@@ -0,0 +1,241 @@
1/*
2 * HCI based Driver for Inside Secure microread NFC Chip
3 *
4 * Copyright (C) 2013 Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions 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,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU 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
17 * Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/interrupt.h>
24#include <linux/gpio.h>
25#include <linux/mei_bus.h>
26
27#include <linux/nfc.h>
28#include <net/nfc/hci.h>
29#include <net/nfc/llc.h>
30
31#include "microread.h"
32
33#define MICROREAD_DRIVER_NAME "microread"
34
35#define MICROREAD_UUID UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, 0x94, \
36 0xd4, 0x50, 0x26, 0x67, 0x23, 0x77, 0x5c)
37
38struct mei_nfc_hdr {
39 u8 cmd;
40 u8 status;
41 u16 req_id;
42 u32 reserved;
43 u16 data_size;
44} __attribute__((packed));
45
46#define MEI_NFC_HEADER_SIZE 10
47#define MEI_NFC_MAX_HCI_PAYLOAD 300
48#define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD)
49
50struct microread_mei_phy {
51 struct mei_bus_client *client;
52 struct nfc_hci_dev *hdev;
53
54 int powered;
55
56 int hard_fault; /*
57 * < 0 if hardware error occured (e.g. i2c err)
58 * and prevents normal operation.
59 */
60};
61
62#define MEI_DUMP_SKB_IN(info, skb) \
63do { \
64 pr_debug("%s:\n", info); \
65 print_hex_dump(KERN_DEBUG, "mei in : ", DUMP_PREFIX_OFFSET, \
66 16, 1, (skb)->data, (skb)->len, 0); \
67} while (0)
68
69#define MEI_DUMP_SKB_OUT(info, skb) \
70do { \
71 pr_debug("%s:\n", info); \
72 print_hex_dump(KERN_DEBUG, "mei out: ", DUMP_PREFIX_OFFSET, \
73 16, 1, (skb)->data, (skb)->len, 0); \
74} while (0)
75
76static int microread_mei_enable(void *phy_id)
77{
78 struct microread_mei_phy *phy = phy_id;
79
80 pr_info(DRIVER_DESC ": %s\n", __func__);
81
82 phy->powered = 1;
83
84 return 0;
85}
86
87static void microread_mei_disable(void *phy_id)
88{
89 struct microread_mei_phy *phy = phy_id;
90
91 pr_info(DRIVER_DESC ": %s\n", __func__);
92
93 phy->powered = 0;
94}
95
96/*
97 * Writing a frame must not return the number of written bytes.
98 * It must return either zero for success, or <0 for error.
99 * In addition, it must not alter the skb
100 */
101static int microread_mei_write(void *phy_id, struct sk_buff *skb)
102{
103 struct microread_mei_phy *phy = phy_id;
104 int r;
105
106 MEI_DUMP_SKB_OUT("mei frame sent", skb);
107
108 r = mei_bus_send(phy->client, skb->data, skb->len);
109 if (r > 0)
110 r = 0;
111
112 return r;
113}
114
115static void microread_event_cb(struct mei_bus_client *client, u32 events,
116 void *context)
117{
118 struct microread_mei_phy *phy = context;
119
120 if (phy->hard_fault != 0)
121 return;
122
123 if (events & BIT(MEI_BUS_EVENT_RX)) {
124 struct sk_buff *skb;
125 int reply_size;
126
127 skb = alloc_skb(MEI_NFC_MAX_READ, GFP_KERNEL);
128 if (!skb)
129 return;
130
131 reply_size = mei_bus_recv(client, skb->data, MEI_NFC_MAX_READ);
132 if (reply_size < MEI_NFC_HEADER_SIZE) {
133 kfree(skb);
134 return;
135 }
136
137 skb_put(skb, reply_size);
138 skb_pull(skb, MEI_NFC_HEADER_SIZE);
139
140 MEI_DUMP_SKB_IN("mei frame read", skb);
141
142 nfc_hci_recv_frame(phy->hdev, skb);
143 }
144}
145
146static struct nfc_phy_ops mei_phy_ops = {
147 .write = microread_mei_write,
148 .enable = microread_mei_enable,
149 .disable = microread_mei_disable,
150};
151
152static int microread_mei_probe(struct mei_bus_client *client)
153{
154 struct microread_mei_phy *phy;
155 int r;
156
157 pr_info("Probing NFC microread\n");
158
159 phy = kzalloc(sizeof(struct microread_mei_phy), GFP_KERNEL);
160 if (!phy) {
161 pr_err("Cannot allocate memory for microread mei phy.\n");
162 return -ENOMEM;
163 }
164
165 phy->client = client;
166 mei_bus_set_clientdata(client, phy);
167
168 r = mei_bus_register_event_cb(client, microread_event_cb, phy);
169 if (r) {
170 pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n");
171 goto err_out;
172 }
173
174 r = microread_probe(phy, &mei_phy_ops, LLC_NOP_NAME,
175 MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD,
176 &phy->hdev);
177 if (r < 0)
178 goto err_out;
179
180 return 0;
181
182err_out:
183 kfree(phy);
184
185 return r;
186}
187
188static int microread_mei_remove(struct mei_bus_client *client)
189{
190 struct microread_mei_phy *phy = mei_bus_get_clientdata(client);
191
192 pr_info("Removing microread\n");
193
194 microread_remove(phy->hdev);
195
196 if (phy->powered)
197 microread_mei_disable(phy);
198
199 kfree(phy);
200
201 return 0;
202}
203
204static struct mei_bus_driver microread_driver = {
205 .driver = {
206 .name = MICROREAD_DRIVER_NAME,
207 },
208 .id = {
209 .name = MICROREAD_DRIVER_NAME,
210 .uuid = MICROREAD_UUID,
211 },
212
213 .probe = microread_mei_probe,
214 .remove = microread_mei_remove,
215};
216
217static int microread_mei_init(void)
218{
219 int r;
220
221 pr_debug(DRIVER_DESC ": %s\n", __func__);
222
223 r = mei_driver_register(&microread_driver);
224 if (r) {
225 pr_err(MICROREAD_DRIVER_NAME ": driver registration failed\n");
226 return r;
227 }
228
229 return 0;
230}
231
232static void microread_mei_exit(void)
233{
234 mei_driver_unregister(&microread_driver);
235}
236
237module_init(microread_mei_init);
238module_exit(microread_mei_exit);
239
240MODULE_LICENSE("GPL");
241MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/nfc/microread/microread.c b/drivers/nfc/microread/microread.c
new file mode 100644
index 000000000000..3420d833db17
--- /dev/null
+++ b/drivers/nfc/microread/microread.c
@@ -0,0 +1,728 @@
1/*
2 * HCI based Driver for Inside Secure microread NFC Chip
3 *
4 * Copyright (C) 2013 Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions 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,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU 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
17 * Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/delay.h>
23#include <linux/slab.h>
24#include <linux/crc-ccitt.h>
25
26#include <linux/nfc.h>
27#include <net/nfc/nfc.h>
28#include <net/nfc/hci.h>
29#include <net/nfc/llc.h>
30
31#include "microread.h"
32
33/* Proprietary gates, events, commands and registers */
34/* Admin */
35#define MICROREAD_GATE_ID_ADM NFC_HCI_ADMIN_GATE
36#define MICROREAD_GATE_ID_MGT 0x01
37#define MICROREAD_GATE_ID_OS 0x02
38#define MICROREAD_GATE_ID_TESTRF 0x03
39#define MICROREAD_GATE_ID_LOOPBACK NFC_HCI_LOOPBACK_GATE
40#define MICROREAD_GATE_ID_IDT NFC_HCI_ID_MGMT_GATE
41#define MICROREAD_GATE_ID_LMS NFC_HCI_LINK_MGMT_GATE
42
43/* Reader */
44#define MICROREAD_GATE_ID_MREAD_GEN 0x10
45#define MICROREAD_GATE_ID_MREAD_ISO_B NFC_HCI_RF_READER_B_GATE
46#define MICROREAD_GATE_ID_MREAD_NFC_T1 0x12
47#define MICROREAD_GATE_ID_MREAD_ISO_A NFC_HCI_RF_READER_A_GATE
48#define MICROREAD_GATE_ID_MREAD_NFC_T3 0x14
49#define MICROREAD_GATE_ID_MREAD_ISO_15_3 0x15
50#define MICROREAD_GATE_ID_MREAD_ISO_15_2 0x16
51#define MICROREAD_GATE_ID_MREAD_ISO_B_3 0x17
52#define MICROREAD_GATE_ID_MREAD_BPRIME 0x18
53#define MICROREAD_GATE_ID_MREAD_ISO_A_3 0x19
54
55/* Card */
56#define MICROREAD_GATE_ID_MCARD_GEN 0x20
57#define MICROREAD_GATE_ID_MCARD_ISO_B 0x21
58#define MICROREAD_GATE_ID_MCARD_BPRIME 0x22
59#define MICROREAD_GATE_ID_MCARD_ISO_A 0x23
60#define MICROREAD_GATE_ID_MCARD_NFC_T3 0x24
61#define MICROREAD_GATE_ID_MCARD_ISO_15_3 0x25
62#define MICROREAD_GATE_ID_MCARD_ISO_15_2 0x26
63#define MICROREAD_GATE_ID_MCARD_ISO_B_2 0x27
64#define MICROREAD_GATE_ID_MCARD_ISO_CUSTOM 0x28
65#define MICROREAD_GATE_ID_SECURE_ELEMENT 0x2F
66
67/* P2P */
68#define MICROREAD_GATE_ID_P2P_GEN 0x30
69#define MICROREAD_GATE_ID_P2P_TARGET 0x31
70#define MICROREAD_PAR_P2P_TARGET_MODE 0x01
71#define MICROREAD_PAR_P2P_TARGET_GT 0x04
72#define MICROREAD_GATE_ID_P2P_INITIATOR 0x32
73#define MICROREAD_PAR_P2P_INITIATOR_GI 0x01
74#define MICROREAD_PAR_P2P_INITIATOR_GT 0x03
75
76/* Those pipes are created/opened by default in the chip */
77#define MICROREAD_PIPE_ID_LMS 0x00
78#define MICROREAD_PIPE_ID_ADMIN 0x01
79#define MICROREAD_PIPE_ID_MGT 0x02
80#define MICROREAD_PIPE_ID_OS 0x03
81#define MICROREAD_PIPE_ID_HDS_LOOPBACK 0x04
82#define MICROREAD_PIPE_ID_HDS_IDT 0x05
83#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_B 0x08
84#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_BPRIME 0x09
85#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_A 0x0A
86#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_15_3 0x0B
87#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_15_2 0x0C
88#define MICROREAD_PIPE_ID_HDS_MCARD_NFC_T3 0x0D
89#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_B_2 0x0E
90#define MICROREAD_PIPE_ID_HDS_MCARD_CUSTOM 0x0F
91#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_B 0x10
92#define MICROREAD_PIPE_ID_HDS_MREAD_NFC_T1 0x11
93#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_A 0x12
94#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_15_3 0x13
95#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_15_2 0x14
96#define MICROREAD_PIPE_ID_HDS_MREAD_NFC_T3 0x15
97#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_B_3 0x16
98#define MICROREAD_PIPE_ID_HDS_MREAD_BPRIME 0x17
99#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_A_3 0x18
100#define MICROREAD_PIPE_ID_HDS_MREAD_GEN 0x1B
101#define MICROREAD_PIPE_ID_HDS_STACKED_ELEMENT 0x1C
102#define MICROREAD_PIPE_ID_HDS_INSTANCES 0x1D
103#define MICROREAD_PIPE_ID_HDS_TESTRF 0x1E
104#define MICROREAD_PIPE_ID_HDS_P2P_TARGET 0x1F
105#define MICROREAD_PIPE_ID_HDS_P2P_INITIATOR 0x20
106
107/* Events */
108#define MICROREAD_EVT_MREAD_DISCOVERY_OCCURED NFC_HCI_EVT_TARGET_DISCOVERED
109#define MICROREAD_EVT_MREAD_CARD_FOUND 0x3D
110#define MICROREAD_EMCF_A_ATQA 0
111#define MICROREAD_EMCF_A_SAK 2
112#define MICROREAD_EMCF_A_LEN 3
113#define MICROREAD_EMCF_A_UID 4
114#define MICROREAD_EMCF_A3_ATQA 0
115#define MICROREAD_EMCF_A3_SAK 2
116#define MICROREAD_EMCF_A3_LEN 3
117#define MICROREAD_EMCF_A3_UID 4
118#define MICROREAD_EMCF_B_UID 0
119#define MICROREAD_EMCF_T1_ATQA 0
120#define MICROREAD_EMCF_T1_UID 4
121#define MICROREAD_EMCF_T3_UID 0
122#define MICROREAD_EVT_MREAD_DISCOVERY_START NFC_HCI_EVT_READER_REQUESTED
123#define MICROREAD_EVT_MREAD_DISCOVERY_START_SOME 0x3E
124#define MICROREAD_EVT_MREAD_DISCOVERY_STOP NFC_HCI_EVT_END_OPERATION
125#define MICROREAD_EVT_MREAD_SIM_REQUESTS 0x3F
126#define MICROREAD_EVT_MCARD_EXCHANGE NFC_HCI_EVT_TARGET_DISCOVERED
127#define MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF 0x20
128#define MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_FROM_RF 0x21
129#define MICROREAD_EVT_MCARD_FIELD_ON 0x11
130#define MICROREAD_EVT_P2P_TARGET_ACTIVATED 0x13
131#define MICROREAD_EVT_P2P_TARGET_DEACTIVATED 0x12
132#define MICROREAD_EVT_MCARD_FIELD_OFF 0x14
133
134/* Commands */
135#define MICROREAD_CMD_MREAD_EXCHANGE 0x10
136#define MICROREAD_CMD_MREAD_SUBSCRIBE 0x3F
137
138/* Hosts IDs */
139#define MICROREAD_ELT_ID_HDS NFC_HCI_TERMINAL_HOST_ID
140#define MICROREAD_ELT_ID_SIM NFC_HCI_UICC_HOST_ID
141#define MICROREAD_ELT_ID_SE1 0x03
142#define MICROREAD_ELT_ID_SE2 0x04
143#define MICROREAD_ELT_ID_SE3 0x05
144
145static struct nfc_hci_gate microread_gates[] = {
146 {MICROREAD_GATE_ID_ADM, MICROREAD_PIPE_ID_ADMIN},
147 {MICROREAD_GATE_ID_LOOPBACK, MICROREAD_PIPE_ID_HDS_LOOPBACK},
148 {MICROREAD_GATE_ID_IDT, MICROREAD_PIPE_ID_HDS_IDT},
149 {MICROREAD_GATE_ID_LMS, MICROREAD_PIPE_ID_LMS},
150 {MICROREAD_GATE_ID_MREAD_ISO_B, MICROREAD_PIPE_ID_HDS_MREAD_ISO_B},
151 {MICROREAD_GATE_ID_MREAD_ISO_A, MICROREAD_PIPE_ID_HDS_MREAD_ISO_A},
152 {MICROREAD_GATE_ID_MREAD_ISO_A_3, MICROREAD_PIPE_ID_HDS_MREAD_ISO_A_3},
153 {MICROREAD_GATE_ID_MGT, MICROREAD_PIPE_ID_MGT},
154 {MICROREAD_GATE_ID_OS, MICROREAD_PIPE_ID_OS},
155 {MICROREAD_GATE_ID_MREAD_NFC_T1, MICROREAD_PIPE_ID_HDS_MREAD_NFC_T1},
156 {MICROREAD_GATE_ID_MREAD_NFC_T3, MICROREAD_PIPE_ID_HDS_MREAD_NFC_T3},
157 {MICROREAD_GATE_ID_P2P_TARGET, MICROREAD_PIPE_ID_HDS_P2P_TARGET},
158 {MICROREAD_GATE_ID_P2P_INITIATOR, MICROREAD_PIPE_ID_HDS_P2P_INITIATOR}
159};
160
161/* Largest headroom needed for outgoing custom commands */
162#define MICROREAD_CMDS_HEADROOM 2
163#define MICROREAD_CMD_TAILROOM 2
164
165struct microread_info {
166 struct nfc_phy_ops *phy_ops;
167 void *phy_id;
168
169 struct nfc_hci_dev *hdev;
170
171 int async_cb_type;
172 data_exchange_cb_t async_cb;
173 void *async_cb_context;
174};
175
176static int microread_open(struct nfc_hci_dev *hdev)
177{
178 struct microread_info *info = nfc_hci_get_clientdata(hdev);
179
180 return info->phy_ops->enable(info->phy_id);
181}
182
183static void microread_close(struct nfc_hci_dev *hdev)
184{
185 struct microread_info *info = nfc_hci_get_clientdata(hdev);
186
187 info->phy_ops->disable(info->phy_id);
188}
189
190static int microread_hci_ready(struct nfc_hci_dev *hdev)
191{
192 int r;
193 u8 param[4];
194
195 param[0] = 0x03;
196 r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_A,
197 MICROREAD_CMD_MREAD_SUBSCRIBE, param, 1, NULL);
198 if (r)
199 return r;
200
201 r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_A_3,
202 MICROREAD_CMD_MREAD_SUBSCRIBE, NULL, 0, NULL);
203 if (r)
204 return r;
205
206 param[0] = 0x00;
207 param[1] = 0x03;
208 param[2] = 0x00;
209 r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_B,
210 MICROREAD_CMD_MREAD_SUBSCRIBE, param, 3, NULL);
211 if (r)
212 return r;
213
214 r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_NFC_T1,
215 MICROREAD_CMD_MREAD_SUBSCRIBE, NULL, 0, NULL);
216 if (r)
217 return r;
218
219 param[0] = 0xFF;
220 param[1] = 0xFF;
221 param[2] = 0x00;
222 param[3] = 0x00;
223 r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_NFC_T3,
224 MICROREAD_CMD_MREAD_SUBSCRIBE, param, 4, NULL);
225
226 return r;
227}
228
229static int microread_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb)
230{
231 struct microread_info *info = nfc_hci_get_clientdata(hdev);
232
233 return info->phy_ops->write(info->phy_id, skb);
234}
235
236static int microread_start_poll(struct nfc_hci_dev *hdev,
237 u32 im_protocols, u32 tm_protocols)
238{
239 int r;
240
241 u8 param[2];
242 u8 mode;
243
244 param[0] = 0x00;
245 param[1] = 0x00;
246
247 if (im_protocols & NFC_PROTO_ISO14443_MASK)
248 param[0] |= (1 << 2);
249
250 if (im_protocols & NFC_PROTO_ISO14443_B_MASK)
251 param[0] |= 1;
252
253 if (im_protocols & NFC_PROTO_MIFARE_MASK)
254 param[1] |= 1;
255
256 if (im_protocols & NFC_PROTO_JEWEL_MASK)
257 param[0] |= (1 << 1);
258
259 if (im_protocols & NFC_PROTO_FELICA_MASK)
260 param[0] |= (1 << 5);
261
262 if (im_protocols & NFC_PROTO_NFC_DEP_MASK)
263 param[1] |= (1 << 1);
264
265 if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
266 hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
267 &hdev->gb_len);
268 if (hdev->gb == NULL || hdev->gb_len == 0) {
269 im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
270 tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
271 }
272 }
273
274 r = nfc_hci_send_event(hdev, MICROREAD_GATE_ID_MREAD_ISO_A,
275 MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL, 0);
276 if (r)
277 return r;
278
279 mode = 0xff;
280 r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET,
281 MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1);
282 if (r)
283 return r;
284
285 if (im_protocols & NFC_PROTO_NFC_DEP_MASK) {
286 r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_INITIATOR,
287 MICROREAD_PAR_P2P_INITIATOR_GI,
288 hdev->gb, hdev->gb_len);
289 if (r)
290 return r;
291 }
292
293 if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
294 r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET,
295 MICROREAD_PAR_P2P_TARGET_GT,
296 hdev->gb, hdev->gb_len);
297 if (r)
298 return r;
299
300 mode = 0x02;
301 r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET,
302 MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1);
303 if (r)
304 return r;
305 }
306
307 return nfc_hci_send_event(hdev, MICROREAD_GATE_ID_MREAD_ISO_A,
308 MICROREAD_EVT_MREAD_DISCOVERY_START_SOME,
309 param, 2);
310}
311
312static int microread_dep_link_up(struct nfc_hci_dev *hdev,
313 struct nfc_target *target, u8 comm_mode,
314 u8 *gb, size_t gb_len)
315{
316 struct sk_buff *rgb_skb = NULL;
317 int r;
318
319 r = nfc_hci_get_param(hdev, target->hci_reader_gate,
320 MICROREAD_PAR_P2P_INITIATOR_GT, &rgb_skb);
321 if (r < 0)
322 return r;
323
324 if (rgb_skb->len == 0 || rgb_skb->len > NFC_GB_MAXSIZE) {
325 r = -EPROTO;
326 goto exit;
327 }
328
329 r = nfc_set_remote_general_bytes(hdev->ndev, rgb_skb->data,
330 rgb_skb->len);
331 if (r == 0)
332 r = nfc_dep_link_is_up(hdev->ndev, target->idx, comm_mode,
333 NFC_RF_INITIATOR);
334exit:
335 kfree_skb(rgb_skb);
336
337 return r;
338}
339
340static int microread_dep_link_down(struct nfc_hci_dev *hdev)
341{
342 return nfc_hci_send_event(hdev, MICROREAD_GATE_ID_P2P_INITIATOR,
343 MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL, 0);
344}
345
346static int microread_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
347 struct nfc_target *target)
348{
349 switch (gate) {
350 case MICROREAD_GATE_ID_P2P_INITIATOR:
351 target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
352 break;
353 default:
354 return -EPROTO;
355 }
356
357 return 0;
358}
359
360static int microread_complete_target_discovered(struct nfc_hci_dev *hdev,
361 u8 gate,
362 struct nfc_target *target)
363{
364 return 0;
365}
366
367#define MICROREAD_CB_TYPE_READER_ALL 1
368
369static void microread_im_transceive_cb(void *context, struct sk_buff *skb,
370 int err)
371{
372 struct microread_info *info = context;
373
374 switch (info->async_cb_type) {
375 case MICROREAD_CB_TYPE_READER_ALL:
376 if (err == 0) {
377 if (skb->len == 0) {
378 err = -EPROTO;
379 kfree_skb(skb);
380 info->async_cb(info->async_cb_context, NULL,
381 -EPROTO);
382 return;
383 }
384
385 if (skb->data[skb->len - 1] != 0) {
386 err = nfc_hci_result_to_errno(
387 skb->data[skb->len - 1]);
388 kfree_skb(skb);
389 info->async_cb(info->async_cb_context, NULL,
390 err);
391 return;
392 }
393
394 skb_trim(skb, skb->len - 1); /* RF Error ind. */
395 }
396 info->async_cb(info->async_cb_context, skb, err);
397 break;
398 default:
399 if (err == 0)
400 kfree_skb(skb);
401 break;
402 }
403}
404
405/*
406 * Returns:
407 * <= 0: driver handled the data exchange
408 * 1: driver doesn't especially handle, please do standard processing
409 */
410static int microread_im_transceive(struct nfc_hci_dev *hdev,
411 struct nfc_target *target,
412 struct sk_buff *skb, data_exchange_cb_t cb,
413 void *cb_context)
414{
415 struct microread_info *info = nfc_hci_get_clientdata(hdev);
416 u8 control_bits;
417 u16 crc;
418
419 pr_info("data exchange to gate 0x%x\n", target->hci_reader_gate);
420
421 if (target->hci_reader_gate == MICROREAD_GATE_ID_P2P_INITIATOR) {
422 *skb_push(skb, 1) = 0;
423
424 return nfc_hci_send_event(hdev, target->hci_reader_gate,
425 MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF,
426 skb->data, skb->len);
427 }
428
429 switch (target->hci_reader_gate) {
430 case MICROREAD_GATE_ID_MREAD_ISO_A:
431 control_bits = 0xCB;
432 break;
433 case MICROREAD_GATE_ID_MREAD_ISO_A_3:
434 control_bits = 0xCB;
435 break;
436 case MICROREAD_GATE_ID_MREAD_ISO_B:
437 control_bits = 0xCB;
438 break;
439 case MICROREAD_GATE_ID_MREAD_NFC_T1:
440 control_bits = 0x1B;
441
442 crc = crc_ccitt(0xffff, skb->data, skb->len);
443 crc = ~crc;
444 *skb_put(skb, 1) = crc & 0xff;
445 *skb_put(skb, 1) = crc >> 8;
446 break;
447 case MICROREAD_GATE_ID_MREAD_NFC_T3:
448 control_bits = 0xDB;
449 break;
450 default:
451 pr_info("Abort im_transceive to invalid gate 0x%x\n",
452 target->hci_reader_gate);
453 return 1;
454 }
455
456 *skb_push(skb, 1) = control_bits;
457
458 info->async_cb_type = MICROREAD_CB_TYPE_READER_ALL;
459 info->async_cb = cb;
460 info->async_cb_context = cb_context;
461
462 return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
463 MICROREAD_CMD_MREAD_EXCHANGE,
464 skb->data, skb->len,
465 microread_im_transceive_cb, info);
466}
467
468static int microread_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
469{
470 int r;
471
472 r = nfc_hci_send_event(hdev, MICROREAD_GATE_ID_P2P_TARGET,
473 MICROREAD_EVT_MCARD_EXCHANGE,
474 skb->data, skb->len);
475
476 kfree_skb(skb);
477
478 return r;
479}
480
481static void microread_target_discovered(struct nfc_hci_dev *hdev, u8 gate,
482 struct sk_buff *skb)
483{
484 struct nfc_target *targets;
485 int r = 0;
486
487 pr_info("target discovered to gate 0x%x\n", gate);
488
489 targets = kzalloc(sizeof(struct nfc_target), GFP_KERNEL);
490 if (targets == NULL) {
491 r = -ENOMEM;
492 goto exit;
493 }
494
495 targets->hci_reader_gate = gate;
496
497 switch (gate) {
498 case MICROREAD_GATE_ID_MREAD_ISO_A:
499 targets->supported_protocols =
500 nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A_SAK]);
501 targets->sens_res =
502 be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A_ATQA]);
503 targets->sel_res = skb->data[MICROREAD_EMCF_A_SAK];
504 memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A_UID],
505 skb->data[MICROREAD_EMCF_A_LEN]);
506 targets->nfcid1_len = skb->data[MICROREAD_EMCF_A_LEN];
507 break;
508 case MICROREAD_GATE_ID_MREAD_ISO_A_3:
509 targets->supported_protocols =
510 nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A3_SAK]);
511 targets->sens_res =
512 be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A3_ATQA]);
513 targets->sel_res = skb->data[MICROREAD_EMCF_A3_SAK];
514 memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A3_UID],
515 skb->data[MICROREAD_EMCF_A3_LEN]);
516 targets->nfcid1_len = skb->data[MICROREAD_EMCF_A3_LEN];
517 break;
518 case MICROREAD_GATE_ID_MREAD_ISO_B:
519 targets->supported_protocols = NFC_PROTO_ISO14443_B_MASK;
520 memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_B_UID], 4);
521 targets->nfcid1_len = 4;
522 break;
523 case MICROREAD_GATE_ID_MREAD_NFC_T1:
524 targets->supported_protocols = NFC_PROTO_JEWEL_MASK;
525 targets->sens_res =
526 le16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_T1_ATQA]);
527 memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T1_UID], 4);
528 targets->nfcid1_len = 4;
529 break;
530 case MICROREAD_GATE_ID_MREAD_NFC_T3:
531 targets->supported_protocols = NFC_PROTO_FELICA_MASK;
532 memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T3_UID], 8);
533 targets->nfcid1_len = 8;
534 break;
535 default:
536 pr_info("discard target discovered to gate 0x%x\n", gate);
537 goto exit_free;
538 }
539
540 r = nfc_targets_found(hdev->ndev, targets, 1);
541
542exit_free:
543 kfree(targets);
544
545exit:
546 kfree_skb(skb);
547
548 if (r)
549 pr_err("Failed to handle discovered target err=%d", r);
550}
551
552static int microread_event_received(struct nfc_hci_dev *hdev, u8 gate,
553 u8 event, struct sk_buff *skb)
554{
555 int r;
556 u8 mode;
557
558 pr_info("Microread received event 0x%x to gate 0x%x\n", event, gate);
559
560 switch (event) {
561 case MICROREAD_EVT_MREAD_CARD_FOUND:
562 microread_target_discovered(hdev, gate, skb);
563 return 0;
564
565 case MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_FROM_RF:
566 if (skb->len < 1) {
567 kfree_skb(skb);
568 return -EPROTO;
569 }
570
571 if (skb->data[skb->len - 1]) {
572 kfree_skb(skb);
573 return -EIO;
574 }
575
576 skb_trim(skb, skb->len - 1);
577
578 r = nfc_tm_data_received(hdev->ndev, skb);
579 break;
580
581 case MICROREAD_EVT_MCARD_FIELD_ON:
582 case MICROREAD_EVT_MCARD_FIELD_OFF:
583 kfree_skb(skb);
584 return 0;
585
586 case MICROREAD_EVT_P2P_TARGET_ACTIVATED:
587 r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK,
588 NFC_COMM_PASSIVE, skb->data,
589 skb->len);
590
591 kfree_skb(skb);
592 break;
593
594 case MICROREAD_EVT_MCARD_EXCHANGE:
595 if (skb->len < 1) {
596 kfree_skb(skb);
597 return -EPROTO;
598 }
599
600 if (skb->data[skb->len-1]) {
601 kfree_skb(skb);
602 return -EIO;
603 }
604
605 skb_trim(skb, skb->len - 1);
606
607 r = nfc_tm_data_received(hdev->ndev, skb);
608 break;
609
610 case MICROREAD_EVT_P2P_TARGET_DEACTIVATED:
611 kfree_skb(skb);
612
613 mode = 0xff;
614 r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET,
615 MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1);
616 if (r)
617 break;
618
619 r = nfc_hci_send_event(hdev, gate,
620 MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL,
621 0);
622 break;
623
624 default:
625 return 1;
626 }
627
628 return r;
629}
630
631static struct nfc_hci_ops microread_hci_ops = {
632 .open = microread_open,
633 .close = microread_close,
634 .hci_ready = microread_hci_ready,
635 .xmit = microread_xmit,
636 .start_poll = microread_start_poll,
637 .dep_link_up = microread_dep_link_up,
638 .dep_link_down = microread_dep_link_down,
639 .target_from_gate = microread_target_from_gate,
640 .complete_target_discovered = microread_complete_target_discovered,
641 .im_transceive = microread_im_transceive,
642 .tm_send = microread_tm_send,
643 .check_presence = NULL,
644 .event_received = microread_event_received,
645};
646
647int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
648 int phy_headroom, int phy_tailroom, int phy_payload,
649 struct nfc_hci_dev **hdev)
650{
651 struct microread_info *info;
652 unsigned long quirks = 0;
653 u32 protocols, se;
654 struct nfc_hci_init_data init_data;
655 int r;
656
657 info = kzalloc(sizeof(struct microread_info), GFP_KERNEL);
658 if (!info) {
659 pr_err("Cannot allocate memory for microread_info.\n");
660 r = -ENOMEM;
661 goto err_info_alloc;
662 }
663
664 info->phy_ops = phy_ops;
665 info->phy_id = phy_id;
666
667 init_data.gate_count = ARRAY_SIZE(microread_gates);
668 memcpy(init_data.gates, microread_gates, sizeof(microread_gates));
669
670 strcpy(init_data.session_id, "MICROREA");
671
672 set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks);
673
674 protocols = NFC_PROTO_JEWEL_MASK |
675 NFC_PROTO_MIFARE_MASK |
676 NFC_PROTO_FELICA_MASK |
677 NFC_PROTO_ISO14443_MASK |
678 NFC_PROTO_ISO14443_B_MASK |
679 NFC_PROTO_NFC_DEP_MASK;
680
681 se = NFC_SE_UICC | NFC_SE_EMBEDDED;
682
683 info->hdev = nfc_hci_allocate_device(&microread_hci_ops, &init_data,
684 quirks, protocols, se, llc_name,
685 phy_headroom +
686 MICROREAD_CMDS_HEADROOM,
687 phy_tailroom +
688 MICROREAD_CMD_TAILROOM,
689 phy_payload);
690 if (!info->hdev) {
691 pr_err("Cannot allocate nfc hdev.\n");
692 r = -ENOMEM;
693 goto err_alloc_hdev;
694 }
695
696 nfc_hci_set_clientdata(info->hdev, info);
697
698 r = nfc_hci_register_device(info->hdev);
699 if (r)
700 goto err_regdev;
701
702 *hdev = info->hdev;
703
704 return 0;
705
706err_regdev:
707 nfc_hci_free_device(info->hdev);
708
709err_alloc_hdev:
710 kfree(info);
711
712err_info_alloc:
713 return r;
714}
715EXPORT_SYMBOL(microread_probe);
716
717void microread_remove(struct nfc_hci_dev *hdev)
718{
719 struct microread_info *info = nfc_hci_get_clientdata(hdev);
720
721 nfc_hci_unregister_device(hdev);
722 nfc_hci_free_device(hdev);
723 kfree(info);
724}
725EXPORT_SYMBOL(microread_remove);
726
727MODULE_LICENSE("GPL");
728MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/nfc/microread/microread.h b/drivers/nfc/microread/microread.h
new file mode 100644
index 000000000000..64b447a1c5bf
--- /dev/null
+++ b/drivers/nfc/microread/microread.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2011 - 2012 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#ifndef __LOCAL_MICROREAD_H_
21#define __LOCAL_MICROREAD_H_
22
23#include <net/nfc/hci.h>
24
25#define DRIVER_DESC "NFC driver for microread"
26
27int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
28 int phy_headroom, int phy_tailroom, int phy_payload,
29 struct nfc_hci_dev **hdev);
30
31void microread_remove(struct nfc_hci_dev *hdev);
32
33#endif /* __LOCAL_MICROREAD_H_ */
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c
index f696318cfb51..f0f6763d67ae 100644
--- a/drivers/nfc/pn533.c
+++ b/drivers/nfc/pn533.c
@@ -219,7 +219,7 @@ struct pn533_poll_modulations {
219 u8 len; 219 u8 len;
220}; 220};
221 221
222const struct pn533_poll_modulations poll_mod[] = { 222static const struct pn533_poll_modulations poll_mod[] = {
223 [PN533_POLL_MOD_106KBPS_A] = { 223 [PN533_POLL_MOD_106KBPS_A] = {
224 .data = { 224 .data = {
225 .maxtg = 1, 225 .maxtg = 1,
@@ -485,7 +485,7 @@ static u8 pn533_get_cmd_code(void *frame)
485 return PN533_FRAME_CMD(f); 485 return PN533_FRAME_CMD(f);
486} 486}
487 487
488struct pn533_frame_ops pn533_std_frame_ops = { 488static struct pn533_frame_ops pn533_std_frame_ops = {
489 .tx_frame_init = pn533_tx_frame_init, 489 .tx_frame_init = pn533_tx_frame_init,
490 .tx_frame_finish = pn533_tx_frame_finish, 490 .tx_frame_finish = pn533_tx_frame_finish,
491 .tx_update_payload_len = pn533_tx_update_payload_len, 491 .tx_update_payload_len = pn533_tx_update_payload_len,
@@ -532,7 +532,6 @@ static void pn533_recv_response(struct urb *urb)
532 urb->status); 532 urb->status);
533 dev->wq_in_error = urb->status; 533 dev->wq_in_error = urb->status;
534 goto sched_wq; 534 goto sched_wq;
535 break;
536 case -ESHUTDOWN: 535 case -ESHUTDOWN:
537 default: 536 default:
538 nfc_dev_err(&dev->interface->dev, 537 nfc_dev_err(&dev->interface->dev,
@@ -589,7 +588,6 @@ static void pn533_recv_ack(struct urb *urb)
589 urb->status); 588 urb->status);
590 dev->wq_in_error = urb->status; 589 dev->wq_in_error = urb->status;
591 goto sched_wq; 590 goto sched_wq;
592 break;
593 case -ESHUTDOWN: 591 case -ESHUTDOWN:
594 default: 592 default:
595 nfc_dev_err(&dev->interface->dev, 593 nfc_dev_err(&dev->interface->dev,
@@ -1380,7 +1378,7 @@ static struct sk_buff *pn533_alloc_poll_tg_frame(struct pn533 *dev)
1380 return NULL; 1378 return NULL;
1381 1379
1382 /* DEP support only */ 1380 /* DEP support only */
1383 *skb_put(skb, 1) |= PN533_INIT_TARGET_DEP; 1381 *skb_put(skb, 1) = PN533_INIT_TARGET_DEP;
1384 1382
1385 /* MIFARE params */ 1383 /* MIFARE params */
1386 memcpy(skb_put(skb, 6), mifare_params, 6); 1384 memcpy(skb_put(skb, 6), mifare_params, 6);
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 c82c5c95fe85..db7705743a8f 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);
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 9a0e3fa3ca95..6a299f416288 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -27,7 +27,7 @@
27#define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */ 27#define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
28#define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */ 28#define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
29#define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */ 29#define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
30#define BCMA_CC_FLASHT_NFLASH 0x00000200 /* NAND flash */ 30#define BCMA_CC_FLASHT_NAND 0x00000300 /* NAND flash */
31#define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */ 31#define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
32#define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */ 32#define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
33#define BCMA_PLLTYPE_NONE 0x00000000 33#define BCMA_PLLTYPE_NONE 0x00000000
diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h
index 0d1ea297851a..fb61f3fb4ddb 100644
--- a/include/linux/bcma/bcma_driver_mips.h
+++ b/include/linux/bcma/bcma_driver_mips.h
@@ -42,13 +42,18 @@ struct bcma_drv_mips {
42#ifdef CONFIG_BCMA_DRIVER_MIPS 42#ifdef CONFIG_BCMA_DRIVER_MIPS
43extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); 43extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
44extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); 44extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore);
45
46extern unsigned int bcma_core_irq(struct bcma_device *core);
45#else 47#else
46static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { } 48static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
47static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { } 49static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { }
50
51static inline unsigned int bcma_core_irq(struct bcma_device *core)
52{
53 return 0;
54}
48#endif 55#endif
49 56
50extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore); 57extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
51 58
52extern unsigned int bcma_core_irq(struct bcma_device *core);
53
54#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */ 59#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
diff --git a/include/linux/platform_data/microread.h b/include/linux/platform_data/microread.h
new file mode 100644
index 000000000000..cfda59b226ee
--- /dev/null
+++ b/include/linux/platform_data/microread.h
@@ -0,0 +1,35 @@
1/*
2 * Driver include for the PN544 NFC chip.
3 *
4 * Copyright (C) 2011 Tieto Poland
5 * Copyright (C) 2012 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef _MICROREAD_H
22#define _MICROREAD_H
23
24#include <linux/i2c.h>
25
26#define MICROREAD_DRIVER_NAME "microread"
27
28/* board config platform data for microread */
29struct microread_nfc_platform_data {
30 unsigned int rst_gpio;
31 unsigned int irq_gpio;
32 unsigned int ioh_gpio;
33};
34
35#endif /* _MICROREAD_H */
diff --git a/include/linux/ssb/ssb_driver_mips.h b/include/linux/ssb/ssb_driver_mips.h
index 07a9c7a2e088..afe79d40a99e 100644
--- a/include/linux/ssb/ssb_driver_mips.h
+++ b/include/linux/ssb/ssb_driver_mips.h
@@ -45,6 +45,11 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore)
45{ 45{
46} 46}
47 47
48static inline unsigned int ssb_mips_irq(struct ssb_device *dev)
49{
50 return 0;
51}
52
48#endif /* CONFIG_SSB_DRIVER_MIPS */ 53#endif /* CONFIG_SSB_DRIVER_MIPS */
49 54
50#endif /* LINUX_SSB_MIPSCORE_H_ */ 55#endif /* LINUX_SSB_MIPSCORE_H_ */
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index 0d6373195d32..a54fe82e704b 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -24,6 +24,8 @@
24#ifndef _LINUX_WL12XX_H 24#ifndef _LINUX_WL12XX_H
25#define _LINUX_WL12XX_H 25#define _LINUX_WL12XX_H
26 26
27#include <linux/err.h>
28
27/* Reference clock values */ 29/* Reference clock values */
28enum { 30enum {
29 WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */ 31 WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */
@@ -55,17 +57,17 @@ struct wl12xx_platform_data {
55 int board_tcxo_clock; 57 int board_tcxo_clock;
56 unsigned long platform_quirks; 58 unsigned long platform_quirks;
57 bool pwr_in_suspend; 59 bool pwr_in_suspend;
58
59 struct wl1271_if_operations *ops;
60}; 60};
61 61
62/* Platform does not support level trigger interrupts */ 62/* Platform does not support level trigger interrupts */
63#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0) 63#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0)
64 64
65#ifdef CONFIG_WL12XX_PLATFORM_DATA 65#ifdef CONFIG_WILINK_PLATFORM_DATA
66 66
67int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); 67int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
68 68
69struct wl12xx_platform_data *wl12xx_get_platform_data(void);
70
69#else 71#else
70 72
71static inline 73static inline
@@ -74,8 +76,12 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
74 return -ENOSYS; 76 return -ENOSYS;
75} 77}
76 78
77#endif 79static inline
80struct wl12xx_platform_data *wl12xx_get_platform_data(void)
81{
82 return ERR_PTR(-ENODATA);
83}
78 84
79struct wl12xx_platform_data *wl12xx_get_platform_data(void); 85#endif
80 86
81#endif 87#endif
diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h
index 42f21766c538..487b54c1308f 100644
--- a/include/net/bluetooth/a2mp.h
+++ b/include/net/bluetooth/a2mp.h
@@ -23,6 +23,7 @@ enum amp_mgr_state {
23 READ_LOC_AMP_INFO, 23 READ_LOC_AMP_INFO,
24 READ_LOC_AMP_ASSOC, 24 READ_LOC_AMP_ASSOC,
25 READ_LOC_AMP_ASSOC_FINAL, 25 READ_LOC_AMP_ASSOC_FINAL,
26 WRITE_REMOTE_AMP_ASSOC,
26}; 27};
27 28
28struct amp_mgr { 29struct amp_mgr {
@@ -33,7 +34,7 @@ struct amp_mgr {
33 struct kref kref; 34 struct kref kref;
34 __u8 ident; 35 __u8 ident;
35 __u8 handle; 36 __u8 handle;
36 enum amp_mgr_state state; 37 unsigned long state;
37 unsigned long flags; 38 unsigned long flags;
38 39
39 struct list_head amp_ctrls; 40 struct list_head amp_ctrls;
@@ -144,5 +145,6 @@ void a2mp_discover_amp(struct l2cap_chan *chan);
144void a2mp_send_getinfo_rsp(struct hci_dev *hdev); 145void a2mp_send_getinfo_rsp(struct hci_dev *hdev);
145void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status); 146void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status);
146void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status); 147void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status);
148void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status);
147 149
148#endif /* __A2MP_H */ 150#endif /* __A2MP_H */
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 2554b3f5222a..9531beee09b5 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -166,6 +166,29 @@ typedef struct {
166#define BDADDR_LE_PUBLIC 0x01 166#define BDADDR_LE_PUBLIC 0x01
167#define BDADDR_LE_RANDOM 0x02 167#define BDADDR_LE_RANDOM 0x02
168 168
169static inline bool bdaddr_type_is_valid(__u8 type)
170{
171 switch (type) {
172 case BDADDR_BREDR:
173 case BDADDR_LE_PUBLIC:
174 case BDADDR_LE_RANDOM:
175 return true;
176 }
177
178 return false;
179}
180
181static inline bool bdaddr_type_is_le(__u8 type)
182{
183 switch (type) {
184 case BDADDR_LE_PUBLIC:
185 case BDADDR_LE_RANDOM:
186 return true;
187 }
188
189 return false;
190}
191
169#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0} }) 192#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0} })
170#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} }) 193#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} })
171 194
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 45eee08157bb..7f12c25f1fca 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -943,6 +943,12 @@ struct hci_rp_le_read_buffer_size {
943 __u8 le_max_pkt; 943 __u8 le_max_pkt;
944} __packed; 944} __packed;
945 945
946#define HCI_OP_LE_READ_LOCAL_FEATURES 0x2003
947struct hci_rp_le_read_local_features {
948 __u8 status;
949 __u8 features[8];
950} __packed;
951
946#define HCI_OP_LE_READ_ADV_TX_POWER 0x2007 952#define HCI_OP_LE_READ_ADV_TX_POWER 0x2007
947struct hci_rp_le_read_adv_tx_power { 953struct hci_rp_le_read_adv_tx_power {
948 __u8 status; 954 __u8 status;
@@ -995,6 +1001,12 @@ struct hci_cp_le_create_conn {
995 1001
996#define HCI_OP_LE_CREATE_CONN_CANCEL 0x200e 1002#define HCI_OP_LE_CREATE_CONN_CANCEL 0x200e
997 1003
1004#define HCI_OP_LE_READ_WHITE_LIST_SIZE 0x200f
1005struct hci_rp_le_read_white_list_size {
1006 __u8 status;
1007 __u8 size;
1008} __packed;
1009
998#define HCI_OP_LE_CONN_UPDATE 0x2013 1010#define HCI_OP_LE_CONN_UPDATE 0x2013
999struct hci_cp_le_conn_update { 1011struct hci_cp_le_conn_update {
1000 __le16 handle; 1012 __le16 handle;
@@ -1033,6 +1045,12 @@ struct hci_rp_le_ltk_neg_reply {
1033 __le16 handle; 1045 __le16 handle;
1034} __packed; 1046} __packed;
1035 1047
1048#define HCI_OP_LE_READ_SUPPORTED_STATES 0x201c
1049struct hci_rp_le_read_supported_states {
1050 __u8 status;
1051 __u8 le_states[8];
1052} __packed;
1053
1036/* ---- HCI Events ---- */ 1054/* ---- HCI Events ---- */
1037#define HCI_EV_INQUIRY_COMPLETE 0x01 1055#define HCI_EV_INQUIRY_COMPLETE 0x01
1038 1056
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 014a2eaa5389..90cf75afcb02 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -86,6 +86,7 @@ struct bdaddr_list {
86struct bt_uuid { 86struct bt_uuid {
87 struct list_head list; 87 struct list_head list;
88 u8 uuid[16]; 88 u8 uuid[16];
89 u8 size;
89 u8 svc_hint; 90 u8 svc_hint;
90}; 91};
91 92
@@ -152,6 +153,9 @@ struct hci_dev {
152 __u8 minor_class; 153 __u8 minor_class;
153 __u8 features[8]; 154 __u8 features[8];
154 __u8 host_features[8]; 155 __u8 host_features[8];
156 __u8 le_features[8];
157 __u8 le_white_list_size;
158 __u8 le_states[8];
155 __u8 commands[64]; 159 __u8 commands[64];
156 __u8 hci_ver; 160 __u8 hci_ver;
157 __u16 hci_rev; 161 __u16 hci_rev;
@@ -216,6 +220,7 @@ struct hci_dev {
216 unsigned long le_last_tx; 220 unsigned long le_last_tx;
217 221
218 struct workqueue_struct *workqueue; 222 struct workqueue_struct *workqueue;
223 struct workqueue_struct *req_workqueue;
219 224
220 struct work_struct power_on; 225 struct work_struct power_on;
221 struct delayed_work power_off; 226 struct delayed_work power_off;
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 7588ef44ebaf..cdd33021f831 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -496,7 +496,6 @@ struct l2cap_chan {
496 __u16 frames_sent; 496 __u16 frames_sent;
497 __u16 unacked_frames; 497 __u16 unacked_frames;
498 __u8 retry_count; 498 __u8 retry_count;
499 __u16 srej_queue_next;
500 __u16 sdu_len; 499 __u16 sdu_len;
501 struct sk_buff *sdu; 500 struct sk_buff *sdu;
502 struct sk_buff *sdu_last_frag; 501 struct sk_buff *sdu_last_frag;
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 2f67d5ecc907..eb0f4b16ff09 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -290,7 +290,7 @@ static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb,
290 goto done; 290 goto done;
291 } 291 }
292 292
293 mgr->state = READ_LOC_AMP_INFO; 293 set_bit(READ_LOC_AMP_INFO, &mgr->state);
294 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 294 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
295 295
296done: 296done:
@@ -499,8 +499,16 @@ send_rsp:
499 if (hdev) 499 if (hdev)
500 hci_dev_put(hdev); 500 hci_dev_put(hdev);
501 501
502 a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, hdr->ident, sizeof(rsp), 502 /* Reply error now and success after HCI Write Remote AMP Assoc
503 &rsp); 503 command complete with success status
504 */
505 if (rsp.status != A2MP_STATUS_SUCCESS) {
506 a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, hdr->ident,
507 sizeof(rsp), &rsp);
508 } else {
509 set_bit(WRITE_REMOTE_AMP_ASSOC, &mgr->state);
510 mgr->ident = hdr->ident;
511 }
504 512
505 skb_pull(skb, le16_to_cpu(hdr->len)); 513 skb_pull(skb, le16_to_cpu(hdr->len));
506 return 0; 514 return 0;
@@ -840,7 +848,7 @@ struct amp_mgr *amp_mgr_lookup_by_state(u8 state)
840 848
841 mutex_lock(&amp_mgr_list_lock); 849 mutex_lock(&amp_mgr_list_lock);
842 list_for_each_entry(mgr, &amp_mgr_list, list) { 850 list_for_each_entry(mgr, &amp_mgr_list, list) {
843 if (mgr->state == state) { 851 if (test_and_clear_bit(state, &mgr->state)) {
844 amp_mgr_get(mgr); 852 amp_mgr_get(mgr);
845 mutex_unlock(&amp_mgr_list_lock); 853 mutex_unlock(&amp_mgr_list_lock);
846 return mgr; 854 return mgr;
@@ -949,6 +957,32 @@ clean:
949 kfree(req); 957 kfree(req);
950} 958}
951 959
960void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status)
961{
962 struct amp_mgr *mgr;
963 struct a2mp_physlink_rsp rsp;
964 struct hci_conn *hs_hcon;
965
966 mgr = amp_mgr_lookup_by_state(WRITE_REMOTE_AMP_ASSOC);
967 if (!mgr)
968 return;
969
970 hs_hcon = hci_conn_hash_lookup_state(hdev, AMP_LINK, BT_CONNECT);
971 if (!hs_hcon) {
972 rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION;
973 } else {
974 rsp.remote_id = hs_hcon->remote_id;
975 rsp.status = A2MP_STATUS_SUCCESS;
976 }
977
978 BT_DBG("%s mgr %p hs_hcon %p status %u", hdev->name, mgr, hs_hcon,
979 status);
980
981 rsp.local_id = hdev->id;
982 a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, mgr->ident, sizeof(rsp), &rsp);
983 amp_mgr_put(mgr);
984}
985
952void a2mp_discover_amp(struct l2cap_chan *chan) 986void a2mp_discover_amp(struct l2cap_chan *chan)
953{ 987{
954 struct l2cap_conn *conn = chan->conn; 988 struct l2cap_conn *conn = chan->conn;
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 1b0d92c0643a..d459ed43c779 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -236,7 +236,7 @@ void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr)
236 236
237 cp.max_len = cpu_to_le16(hdev->amp_assoc_size); 237 cp.max_len = cpu_to_le16(hdev->amp_assoc_size);
238 238
239 mgr->state = READ_LOC_AMP_ASSOC; 239 set_bit(READ_LOC_AMP_ASSOC, &mgr->state);
240 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); 240 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp);
241} 241}
242 242
@@ -250,7 +250,7 @@ void amp_read_loc_assoc_final_data(struct hci_dev *hdev,
250 cp.len_so_far = cpu_to_le16(0); 250 cp.len_so_far = cpu_to_le16(0);
251 cp.max_len = cpu_to_le16(hdev->amp_assoc_size); 251 cp.max_len = cpu_to_le16(hdev->amp_assoc_size);
252 252
253 mgr->state = READ_LOC_AMP_ASSOC_FINAL; 253 set_bit(READ_LOC_AMP_ASSOC_FINAL, &mgr->state);
254 254
255 /* Read Local AMP Assoc final link information data */ 255 /* Read Local AMP Assoc final link information data */
256 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); 256 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp);
@@ -317,7 +317,9 @@ void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle)
317 if (!hcon) 317 if (!hcon)
318 return; 318 return;
319 319
320 amp_write_rem_assoc_frag(hdev, hcon); 320 /* Send A2MP create phylink rsp when all fragments are written */
321 if (amp_write_rem_assoc_frag(hdev, hcon))
322 a2mp_send_create_phy_link_rsp(hdev, 0);
321} 323}
322 324
323void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle) 325void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle)
@@ -403,26 +405,20 @@ void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon)
403 405
404void amp_create_logical_link(struct l2cap_chan *chan) 406void amp_create_logical_link(struct l2cap_chan *chan)
405{ 407{
408 struct hci_conn *hs_hcon = chan->hs_hcon;
406 struct hci_cp_create_accept_logical_link cp; 409 struct hci_cp_create_accept_logical_link cp;
407 struct hci_conn *hcon;
408 struct hci_dev *hdev; 410 struct hci_dev *hdev;
409 411
410 BT_DBG("chan %p", chan); 412 BT_DBG("chan %p hs_hcon %p dst %pMR", chan, hs_hcon, chan->conn->dst);
411 413
412 if (!chan->hs_hcon) 414 if (!hs_hcon)
413 return; 415 return;
414 416
415 hdev = hci_dev_hold(chan->hs_hcon->hdev); 417 hdev = hci_dev_hold(chan->hs_hcon->hdev);
416 if (!hdev) 418 if (!hdev)
417 return; 419 return;
418 420
419 BT_DBG("chan %p dst %pMR", chan, chan->conn->dst); 421 cp.phy_handle = hs_hcon->handle;
420
421 hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, chan->conn->dst);
422 if (!hcon)
423 goto done;
424
425 cp.phy_handle = hcon->handle;
426 422
427 cp.tx_flow_spec.id = chan->local_id; 423 cp.tx_flow_spec.id = chan->local_id;
428 cp.tx_flow_spec.stype = chan->local_stype; 424 cp.tx_flow_spec.stype = chan->local_stype;
@@ -438,14 +434,13 @@ void amp_create_logical_link(struct l2cap_chan *chan)
438 cp.rx_flow_spec.acc_lat = cpu_to_le32(chan->remote_acc_lat); 434 cp.rx_flow_spec.acc_lat = cpu_to_le32(chan->remote_acc_lat);
439 cp.rx_flow_spec.flush_to = cpu_to_le32(chan->remote_flush_to); 435 cp.rx_flow_spec.flush_to = cpu_to_le32(chan->remote_flush_to);
440 436
441 if (hcon->out) 437 if (hs_hcon->out)
442 hci_send_cmd(hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp), 438 hci_send_cmd(hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp),
443 &cp); 439 &cp);
444 else 440 else
445 hci_send_cmd(hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp), 441 hci_send_cmd(hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp),
446 &cp); 442 &cp);
447 443
448done:
449 hci_dev_put(hdev); 444 hci_dev_put(hdev);
450} 445}
451 446
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index a5b639702637..e430b1abcd2f 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -33,7 +33,6 @@
33 33
34#include <net/bluetooth/bluetooth.h> 34#include <net/bluetooth/bluetooth.h>
35#include <net/bluetooth/hci_core.h> 35#include <net/bluetooth/hci_core.h>
36#include <net/bluetooth/l2cap.h>
37 36
38#include "bnep.h" 37#include "bnep.h"
39 38
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 0f78e34220c9..22e77a786545 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1146,7 +1146,8 @@ static void hci_power_on(struct work_struct *work)
1146 return; 1146 return;
1147 1147
1148 if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1148 if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1149 schedule_delayed_work(&hdev->power_off, HCI_AUTO_OFF_TIMEOUT); 1149 queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
1150 HCI_AUTO_OFF_TIMEOUT);
1150 1151
1151 if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) 1152 if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1152 mgmt_index_added(hdev); 1153 mgmt_index_added(hdev);
@@ -1182,14 +1183,10 @@ static void hci_discov_off(struct work_struct *work)
1182 1183
1183int hci_uuids_clear(struct hci_dev *hdev) 1184int hci_uuids_clear(struct hci_dev *hdev)
1184{ 1185{
1185 struct list_head *p, *n; 1186 struct bt_uuid *uuid, *tmp;
1186
1187 list_for_each_safe(p, n, &hdev->uuids) {
1188 struct bt_uuid *uuid;
1189 1187
1190 uuid = list_entry(p, struct bt_uuid, list); 1188 list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
1191 1189 list_del(&uuid->list);
1192 list_del(p);
1193 kfree(uuid); 1190 kfree(uuid);
1194 } 1191 }
1195 1192
@@ -1621,8 +1618,8 @@ static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
1621 if (err < 0) 1618 if (err < 0)
1622 return err; 1619 return err;
1623 1620
1624 schedule_delayed_work(&hdev->le_scan_disable, 1621 queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable,
1625 msecs_to_jiffies(timeout)); 1622 msecs_to_jiffies(timeout));
1626 1623
1627 return 0; 1624 return 0;
1628} 1625}
@@ -1799,6 +1796,15 @@ int hci_register_dev(struct hci_dev *hdev)
1799 goto err; 1796 goto err;
1800 } 1797 }
1801 1798
1799 hdev->req_workqueue = alloc_workqueue(hdev->name,
1800 WQ_HIGHPRI | WQ_UNBOUND |
1801 WQ_MEM_RECLAIM, 1);
1802 if (!hdev->req_workqueue) {
1803 destroy_workqueue(hdev->workqueue);
1804 error = -ENOMEM;
1805 goto err;
1806 }
1807
1802 error = hci_add_sysfs(hdev); 1808 error = hci_add_sysfs(hdev);
1803 if (error < 0) 1809 if (error < 0)
1804 goto err_wqueue; 1810 goto err_wqueue;
@@ -1821,12 +1827,13 @@ int hci_register_dev(struct hci_dev *hdev)
1821 hci_notify(hdev, HCI_DEV_REG); 1827 hci_notify(hdev, HCI_DEV_REG);
1822 hci_dev_hold(hdev); 1828 hci_dev_hold(hdev);
1823 1829
1824 schedule_work(&hdev->power_on); 1830 queue_work(hdev->req_workqueue, &hdev->power_on);
1825 1831
1826 return id; 1832 return id;
1827 1833
1828err_wqueue: 1834err_wqueue:
1829 destroy_workqueue(hdev->workqueue); 1835 destroy_workqueue(hdev->workqueue);
1836 destroy_workqueue(hdev->req_workqueue);
1830err: 1837err:
1831 ida_simple_remove(&hci_index_ida, hdev->id); 1838 ida_simple_remove(&hci_index_ida, hdev->id);
1832 write_lock(&hci_dev_list_lock); 1839 write_lock(&hci_dev_list_lock);
@@ -1880,6 +1887,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
1880 hci_del_sysfs(hdev); 1887 hci_del_sysfs(hdev);
1881 1888
1882 destroy_workqueue(hdev->workqueue); 1889 destroy_workqueue(hdev->workqueue);
1890 destroy_workqueue(hdev->req_workqueue);
1883 1891
1884 hci_dev_lock(hdev); 1892 hci_dev_lock(hdev);
1885 hci_blacklist_clear(hdev); 1893 hci_blacklist_clear(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 81b44481d0d9..477726a63512 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -609,8 +609,17 @@ static void le_setup(struct hci_dev *hdev)
609 /* Read LE Buffer Size */ 609 /* Read LE Buffer Size */
610 hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 610 hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
611 611
612 /* Read LE Local Supported Features */
613 hci_send_cmd(hdev, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
614
612 /* Read LE Advertising Channel TX Power */ 615 /* Read LE Advertising Channel TX Power */
613 hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 616 hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
617
618 /* Read LE White List Size */
619 hci_send_cmd(hdev, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
620
621 /* Read LE Supported States */
622 hci_send_cmd(hdev, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
614} 623}
615 624
616static void hci_setup(struct hci_dev *hdev) 625static void hci_setup(struct hci_dev *hdev)
@@ -1090,6 +1099,19 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
1090 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); 1099 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
1091} 1100}
1092 1101
1102static void hci_cc_le_read_local_features(struct hci_dev *hdev,
1103 struct sk_buff *skb)
1104{
1105 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
1106
1107 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1108
1109 if (!rp->status)
1110 memcpy(hdev->le_features, rp->features, 8);
1111
1112 hci_req_complete(hdev, HCI_OP_LE_READ_LOCAL_FEATURES, rp->status);
1113}
1114
1093static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, 1115static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
1094 struct sk_buff *skb) 1116 struct sk_buff *skb)
1095{ 1117{
@@ -1290,6 +1312,19 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1290 } 1312 }
1291} 1313}
1292 1314
1315static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1316 struct sk_buff *skb)
1317{
1318 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1319
1320 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1321
1322 if (!rp->status)
1323 hdev->le_white_list_size = rp->size;
1324
1325 hci_req_complete(hdev, HCI_OP_LE_READ_WHITE_LIST_SIZE, rp->status);
1326}
1327
1293static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb) 1328static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1294{ 1329{
1295 struct hci_rp_le_ltk_reply *rp = (void *) skb->data; 1330 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
@@ -1314,6 +1349,19 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1314 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status); 1349 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1315} 1350}
1316 1351
1352static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1353 struct sk_buff *skb)
1354{
1355 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1356
1357 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1358
1359 if (!rp->status)
1360 memcpy(hdev->le_states, rp->le_states, 8);
1361
1362 hci_req_complete(hdev, HCI_OP_LE_READ_SUPPORTED_STATES, rp->status);
1363}
1364
1317static void hci_cc_write_le_host_supported(struct hci_dev *hdev, 1365static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1318 struct sk_buff *skb) 1366 struct sk_buff *skb)
1319{ 1367{
@@ -2628,6 +2676,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2628 hci_cc_le_read_buffer_size(hdev, skb); 2676 hci_cc_le_read_buffer_size(hdev, skb);
2629 break; 2677 break;
2630 2678
2679 case HCI_OP_LE_READ_LOCAL_FEATURES:
2680 hci_cc_le_read_local_features(hdev, skb);
2681 break;
2682
2631 case HCI_OP_LE_READ_ADV_TX_POWER: 2683 case HCI_OP_LE_READ_ADV_TX_POWER:
2632 hci_cc_le_read_adv_tx_power(hdev, skb); 2684 hci_cc_le_read_adv_tx_power(hdev, skb);
2633 break; 2685 break;
@@ -2664,6 +2716,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2664 hci_cc_le_set_scan_enable(hdev, skb); 2716 hci_cc_le_set_scan_enable(hdev, skb);
2665 break; 2717 break;
2666 2718
2719 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2720 hci_cc_le_read_white_list_size(hdev, skb);
2721 break;
2722
2667 case HCI_OP_LE_LTK_REPLY: 2723 case HCI_OP_LE_LTK_REPLY:
2668 hci_cc_le_ltk_reply(hdev, skb); 2724 hci_cc_le_ltk_reply(hdev, skb);
2669 break; 2725 break;
@@ -2672,6 +2728,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2672 hci_cc_le_ltk_neg_reply(hdev, skb); 2728 hci_cc_le_ltk_neg_reply(hdev, skb);
2673 break; 2729 break;
2674 2730
2731 case HCI_OP_LE_READ_SUPPORTED_STATES:
2732 hci_cc_le_read_supported_states(hdev, skb);
2733 break;
2734
2675 case HCI_OP_WRITE_LE_HOST_SUPPORTED: 2735 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2676 hci_cc_write_le_host_supported(hdev, skb); 2736 hci_cc_write_le_host_supported(hdev, skb);
2677 break; 2737 break;
@@ -3928,8 +3988,6 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
3928 void *ptr = &skb->data[1]; 3988 void *ptr = &skb->data[1];
3929 s8 rssi; 3989 s8 rssi;
3930 3990
3931 hci_dev_lock(hdev);
3932
3933 while (num_reports--) { 3991 while (num_reports--) {
3934 struct hci_ev_le_advertising_info *ev = ptr; 3992 struct hci_ev_le_advertising_info *ev = ptr;
3935 3993
@@ -3939,8 +3997,6 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
3939 3997
3940 ptr += sizeof(*ev) + ev->length + 1; 3998 ptr += sizeof(*ev) + ev->length + 1;
3941 } 3999 }
3942
3943 hci_dev_unlock(hdev);
3944} 4000}
3945 4001
3946static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 4002static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 55cceee02a84..23b4e242a31a 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -2,6 +2,7 @@
2 2
3#include <linux/debugfs.h> 3#include <linux/debugfs.h>
4#include <linux/module.h> 4#include <linux/module.h>
5#include <asm/unaligned.h>
5 6
6#include <net/bluetooth/bluetooth.h> 7#include <net/bluetooth/bluetooth.h>
7#include <net/bluetooth/hci_core.h> 8#include <net/bluetooth/hci_core.h>
@@ -461,19 +462,18 @@ static const struct file_operations blacklist_fops = {
461 462
462static void print_bt_uuid(struct seq_file *f, u8 *uuid) 463static void print_bt_uuid(struct seq_file *f, u8 *uuid)
463{ 464{
464 __be32 data0, data4; 465 u32 data0, data5;
465 __be16 data1, data2, data3, data5; 466 u16 data1, data2, data3, data4;
466 467
467 memcpy(&data0, &uuid[0], 4); 468 data5 = get_unaligned_le32(uuid);
468 memcpy(&data1, &uuid[4], 2); 469 data4 = get_unaligned_le16(uuid + 4);
469 memcpy(&data2, &uuid[6], 2); 470 data3 = get_unaligned_le16(uuid + 6);
470 memcpy(&data3, &uuid[8], 2); 471 data2 = get_unaligned_le16(uuid + 8);
471 memcpy(&data4, &uuid[10], 4); 472 data1 = get_unaligned_le16(uuid + 10);
472 memcpy(&data5, &uuid[14], 2); 473 data0 = get_unaligned_le32(uuid + 12);
473 474
474 seq_printf(f, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x\n", 475 seq_printf(f, "%.8x-%.4x-%.4x-%.4x-%.4x%.8x\n",
475 ntohl(data0), ntohs(data1), ntohs(data2), ntohs(data3), 476 data0, data1, data2, data3, data4, data5);
476 ntohl(data4), ntohs(data5));
477} 477}
478 478
479static int uuids_show(struct seq_file *f, void *p) 479static int uuids_show(struct seq_file *f, void *p)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 22e658322845..7c7e9321f1ea 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1527,17 +1527,12 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1527 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); 1527 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
1528 1528
1529 switch (hcon->type) { 1529 switch (hcon->type) {
1530 case AMP_LINK:
1531 conn->mtu = hcon->hdev->block_mtu;
1532 break;
1533
1534 case LE_LINK: 1530 case LE_LINK:
1535 if (hcon->hdev->le_mtu) { 1531 if (hcon->hdev->le_mtu) {
1536 conn->mtu = hcon->hdev->le_mtu; 1532 conn->mtu = hcon->hdev->le_mtu;
1537 break; 1533 break;
1538 } 1534 }
1539 /* fall through */ 1535 /* fall through */
1540
1541 default: 1536 default:
1542 conn->mtu = hcon->hdev->acl_mtu; 1537 conn->mtu = hcon->hdev->acl_mtu;
1543 break; 1538 break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f559b966279c..39395c7144aa 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -35,7 +35,7 @@
35bool enable_hs; 35bool enable_hs;
36 36
37#define MGMT_VERSION 1 37#define MGMT_VERSION 1
38#define MGMT_REVISION 2 38#define MGMT_REVISION 3
39 39
40static const u16 mgmt_commands[] = { 40static const u16 mgmt_commands[] = {
41 MGMT_OP_READ_INDEX_LIST, 41 MGMT_OP_READ_INDEX_LIST,
@@ -435,35 +435,117 @@ static u32 get_current_settings(struct hci_dev *hdev)
435 435
436#define PNP_INFO_SVCLASS_ID 0x1200 436#define PNP_INFO_SVCLASS_ID 0x1200
437 437
438static u8 bluetooth_base_uuid[] = { 438static u8 *create_uuid16_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
439 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 439{
440 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 440 u8 *ptr = data, *uuids_start = NULL;
441}; 441 struct bt_uuid *uuid;
442
443 if (len < 4)
444 return ptr;
445
446 list_for_each_entry(uuid, &hdev->uuids, list) {
447 u16 uuid16;
448
449 if (uuid->size != 16)
450 continue;
451
452 uuid16 = get_unaligned_le16(&uuid->uuid[12]);
453 if (uuid16 < 0x1100)
454 continue;
455
456 if (uuid16 == PNP_INFO_SVCLASS_ID)
457 continue;
442 458
443static u16 get_uuid16(u8 *uuid128) 459 if (!uuids_start) {
460 uuids_start = ptr;
461 uuids_start[0] = 1;
462 uuids_start[1] = EIR_UUID16_ALL;
463 ptr += 2;
464 }
465
466 /* Stop if not enough space to put next UUID */
467 if ((ptr - data) + sizeof(u16) > len) {
468 uuids_start[1] = EIR_UUID16_SOME;
469 break;
470 }
471
472 *ptr++ = (uuid16 & 0x00ff);
473 *ptr++ = (uuid16 & 0xff00) >> 8;
474 uuids_start[0] += sizeof(uuid16);
475 }
476
477 return ptr;
478}
479
480static u8 *create_uuid32_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
444{ 481{
445 u32 val; 482 u8 *ptr = data, *uuids_start = NULL;
446 int i; 483 struct bt_uuid *uuid;
484
485 if (len < 6)
486 return ptr;
447 487
448 for (i = 0; i < 12; i++) { 488 list_for_each_entry(uuid, &hdev->uuids, list) {
449 if (bluetooth_base_uuid[i] != uuid128[i]) 489 if (uuid->size != 32)
450 return 0; 490 continue;
491
492 if (!uuids_start) {
493 uuids_start = ptr;
494 uuids_start[0] = 1;
495 uuids_start[1] = EIR_UUID32_ALL;
496 ptr += 2;
497 }
498
499 /* Stop if not enough space to put next UUID */
500 if ((ptr - data) + sizeof(u32) > len) {
501 uuids_start[1] = EIR_UUID32_SOME;
502 break;
503 }
504
505 memcpy(ptr, &uuid->uuid[12], sizeof(u32));
506 ptr += sizeof(u32);
507 uuids_start[0] += sizeof(u32);
451 } 508 }
452 509
453 val = get_unaligned_le32(&uuid128[12]); 510 return ptr;
454 if (val > 0xffff) 511}
455 return 0; 512
513static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
514{
515 u8 *ptr = data, *uuids_start = NULL;
516 struct bt_uuid *uuid;
517
518 if (len < 18)
519 return ptr;
456 520
457 return (u16) val; 521 list_for_each_entry(uuid, &hdev->uuids, list) {
522 if (uuid->size != 128)
523 continue;
524
525 if (!uuids_start) {
526 uuids_start = ptr;
527 uuids_start[0] = 1;
528 uuids_start[1] = EIR_UUID128_ALL;
529 ptr += 2;
530 }
531
532 /* Stop if not enough space to put next UUID */
533 if ((ptr - data) + 16 > len) {
534 uuids_start[1] = EIR_UUID128_SOME;
535 break;
536 }
537
538 memcpy(ptr, uuid->uuid, 16);
539 ptr += 16;
540 uuids_start[0] += 16;
541 }
542
543 return ptr;
458} 544}
459 545
460static void create_eir(struct hci_dev *hdev, u8 *data) 546static void create_eir(struct hci_dev *hdev, u8 *data)
461{ 547{
462 u8 *ptr = data; 548 u8 *ptr = data;
463 u16 eir_len = 0;
464 u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)];
465 int i, truncated = 0;
466 struct bt_uuid *uuid;
467 size_t name_len; 549 size_t name_len;
468 550
469 name_len = strlen(hdev->dev_name); 551 name_len = strlen(hdev->dev_name);
@@ -481,7 +563,6 @@ static void create_eir(struct hci_dev *hdev, u8 *data)
481 563
482 memcpy(ptr + 2, hdev->dev_name, name_len); 564 memcpy(ptr + 2, hdev->dev_name, name_len);
483 565
484 eir_len += (name_len + 2);
485 ptr += (name_len + 2); 566 ptr += (name_len + 2);
486 } 567 }
487 568
@@ -490,7 +571,6 @@ static void create_eir(struct hci_dev *hdev, u8 *data)
490 ptr[1] = EIR_TX_POWER; 571 ptr[1] = EIR_TX_POWER;
491 ptr[2] = (u8) hdev->inq_tx_power; 572 ptr[2] = (u8) hdev->inq_tx_power;
492 573
493 eir_len += 3;
494 ptr += 3; 574 ptr += 3;
495 } 575 }
496 576
@@ -503,60 +583,12 @@ static void create_eir(struct hci_dev *hdev, u8 *data)
503 put_unaligned_le16(hdev->devid_product, ptr + 6); 583 put_unaligned_le16(hdev->devid_product, ptr + 6);
504 put_unaligned_le16(hdev->devid_version, ptr + 8); 584 put_unaligned_le16(hdev->devid_version, ptr + 8);
505 585
506 eir_len += 10;
507 ptr += 10; 586 ptr += 10;
508 } 587 }
509 588
510 memset(uuid16_list, 0, sizeof(uuid16_list)); 589 ptr = create_uuid16_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
511 590 ptr = create_uuid32_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
512 /* Group all UUID16 types */ 591 ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
513 list_for_each_entry(uuid, &hdev->uuids, list) {
514 u16 uuid16;
515
516 uuid16 = get_uuid16(uuid->uuid);
517 if (uuid16 == 0)
518 return;
519
520 if (uuid16 < 0x1100)
521 continue;
522
523 if (uuid16 == PNP_INFO_SVCLASS_ID)
524 continue;
525
526 /* Stop if not enough space to put next UUID */
527 if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) {
528 truncated = 1;
529 break;
530 }
531
532 /* Check for duplicates */
533 for (i = 0; uuid16_list[i] != 0; i++)
534 if (uuid16_list[i] == uuid16)
535 break;
536
537 if (uuid16_list[i] == 0) {
538 uuid16_list[i] = uuid16;
539 eir_len += sizeof(u16);
540 }
541 }
542
543 if (uuid16_list[0] != 0) {
544 u8 *length = ptr;
545
546 /* EIR Data type */
547 ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
548
549 ptr += 2;
550 eir_len += 2;
551
552 for (i = 0; uuid16_list[i] != 0; i++) {
553 *ptr++ = (uuid16_list[i] & 0x00ff);
554 *ptr++ = (uuid16_list[i] & 0xff00) >> 8;
555 }
556
557 /* EIR Data length */
558 *length = (i * sizeof(u16)) + 1;
559 }
560} 592}
561 593
562static int update_eir(struct hci_dev *hdev) 594static int update_eir(struct hci_dev *hdev)
@@ -728,13 +760,9 @@ static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev,
728 void *data), 760 void *data),
729 void *data) 761 void *data)
730{ 762{
731 struct list_head *p, *n; 763 struct pending_cmd *cmd, *tmp;
732
733 list_for_each_safe(p, n, &hdev->mgmt_pending) {
734 struct pending_cmd *cmd;
735
736 cmd = list_entry(p, struct pending_cmd, list);
737 764
765 list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
738 if (opcode > 0 && cmd->opcode != opcode) 766 if (opcode > 0 && cmd->opcode != opcode)
739 continue; 767 continue;
740 768
@@ -777,14 +805,19 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
777 805
778 BT_DBG("request for %s", hdev->name); 806 BT_DBG("request for %s", hdev->name);
779 807
808 if (cp->val != 0x00 && cp->val != 0x01)
809 return cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
810 MGMT_STATUS_INVALID_PARAMS);
811
780 hci_dev_lock(hdev); 812 hci_dev_lock(hdev);
781 813
782 if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 814 if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
783 cancel_delayed_work(&hdev->power_off); 815 cancel_delayed_work(&hdev->power_off);
784 816
785 if (cp->val) { 817 if (cp->val) {
786 err = send_settings_rsp(sk, MGMT_OP_SET_POWERED, hdev); 818 mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev,
787 mgmt_powered(hdev, 1); 819 data, len);
820 err = mgmt_powered(hdev, 1);
788 goto failed; 821 goto failed;
789 } 822 }
790 } 823 }
@@ -807,9 +840,9 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
807 } 840 }
808 841
809 if (cp->val) 842 if (cp->val)
810 schedule_work(&hdev->power_on); 843 queue_work(hdev->req_workqueue, &hdev->power_on);
811 else 844 else
812 schedule_work(&hdev->power_off.work); 845 queue_work(hdev->req_workqueue, &hdev->power_off.work);
813 846
814 err = 0; 847 err = 0;
815 848
@@ -872,6 +905,10 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
872 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, 905 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
873 MGMT_STATUS_NOT_SUPPORTED); 906 MGMT_STATUS_NOT_SUPPORTED);
874 907
908 if (cp->val != 0x00 && cp->val != 0x01)
909 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
910 MGMT_STATUS_INVALID_PARAMS);
911
875 timeout = __le16_to_cpu(cp->timeout); 912 timeout = __le16_to_cpu(cp->timeout);
876 if (!cp->val && timeout > 0) 913 if (!cp->val && timeout > 0)
877 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, 914 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
@@ -971,6 +1008,10 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
971 return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, 1008 return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
972 MGMT_STATUS_NOT_SUPPORTED); 1009 MGMT_STATUS_NOT_SUPPORTED);
973 1010
1011 if (cp->val != 0x00 && cp->val != 0x01)
1012 return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
1013 MGMT_STATUS_INVALID_PARAMS);
1014
974 hci_dev_lock(hdev); 1015 hci_dev_lock(hdev);
975 1016
976 if (!hdev_is_powered(hdev)) { 1017 if (!hdev_is_powered(hdev)) {
@@ -1041,6 +1082,10 @@ static int set_pairable(struct sock *sk, struct hci_dev *hdev, void *data,
1041 1082
1042 BT_DBG("request for %s", hdev->name); 1083 BT_DBG("request for %s", hdev->name);
1043 1084
1085 if (cp->val != 0x00 && cp->val != 0x01)
1086 return cmd_status(sk, hdev->id, MGMT_OP_SET_PAIRABLE,
1087 MGMT_STATUS_INVALID_PARAMS);
1088
1044 hci_dev_lock(hdev); 1089 hci_dev_lock(hdev);
1045 1090
1046 if (cp->val) 1091 if (cp->val)
@@ -1073,6 +1118,10 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data,
1073 return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, 1118 return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
1074 MGMT_STATUS_NOT_SUPPORTED); 1119 MGMT_STATUS_NOT_SUPPORTED);
1075 1120
1121 if (cp->val != 0x00 && cp->val != 0x01)
1122 return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
1123 MGMT_STATUS_INVALID_PARAMS);
1124
1076 hci_dev_lock(hdev); 1125 hci_dev_lock(hdev);
1077 1126
1078 if (!hdev_is_powered(hdev)) { 1127 if (!hdev_is_powered(hdev)) {
@@ -1133,13 +1182,15 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1133 1182
1134 BT_DBG("request for %s", hdev->name); 1183 BT_DBG("request for %s", hdev->name);
1135 1184
1136 hci_dev_lock(hdev); 1185 if (!lmp_ssp_capable(hdev))
1186 return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
1187 MGMT_STATUS_NOT_SUPPORTED);
1137 1188
1138 if (!lmp_ssp_capable(hdev)) { 1189 if (cp->val != 0x00 && cp->val != 0x01)
1139 err = cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, 1190 return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
1140 MGMT_STATUS_NOT_SUPPORTED); 1191 MGMT_STATUS_INVALID_PARAMS);
1141 goto failed; 1192
1142 } 1193 hci_dev_lock(hdev);
1143 1194
1144 val = !!cp->val; 1195 val = !!cp->val;
1145 1196
@@ -1199,6 +1250,10 @@ static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1199 return cmd_status(sk, hdev->id, MGMT_OP_SET_HS, 1250 return cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
1200 MGMT_STATUS_NOT_SUPPORTED); 1251 MGMT_STATUS_NOT_SUPPORTED);
1201 1252
1253 if (cp->val != 0x00 && cp->val != 0x01)
1254 return cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
1255 MGMT_STATUS_INVALID_PARAMS);
1256
1202 if (cp->val) 1257 if (cp->val)
1203 set_bit(HCI_HS_ENABLED, &hdev->dev_flags); 1258 set_bit(HCI_HS_ENABLED, &hdev->dev_flags);
1204 else 1259 else
@@ -1217,13 +1272,15 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1217 1272
1218 BT_DBG("request for %s", hdev->name); 1273 BT_DBG("request for %s", hdev->name);
1219 1274
1220 hci_dev_lock(hdev); 1275 if (!lmp_le_capable(hdev))
1276 return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
1277 MGMT_STATUS_NOT_SUPPORTED);
1221 1278
1222 if (!lmp_le_capable(hdev)) { 1279 if (cp->val != 0x00 && cp->val != 0x01)
1223 err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE, 1280 return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
1224 MGMT_STATUS_NOT_SUPPORTED); 1281 MGMT_STATUS_INVALID_PARAMS);
1225 goto unlock; 1282
1226 } 1283 hci_dev_lock(hdev);
1227 1284
1228 val = !!cp->val; 1285 val = !!cp->val;
1229 enabled = lmp_host_le_capable(hdev); 1286 enabled = lmp_host_le_capable(hdev);
@@ -1275,6 +1332,25 @@ unlock:
1275 return err; 1332 return err;
1276} 1333}
1277 1334
1335static const u8 bluetooth_base_uuid[] = {
1336 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
1337 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1338};
1339
1340static u8 get_uuid_size(const u8 *uuid)
1341{
1342 u32 val;
1343
1344 if (memcmp(uuid, bluetooth_base_uuid, 12))
1345 return 128;
1346
1347 val = get_unaligned_le32(&uuid[12]);
1348 if (val > 0xffff)
1349 return 32;
1350
1351 return 16;
1352}
1353
1278static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) 1354static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1279{ 1355{
1280 struct mgmt_cp_add_uuid *cp = data; 1356 struct mgmt_cp_add_uuid *cp = data;
@@ -1300,8 +1376,9 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1300 1376
1301 memcpy(uuid->uuid, cp->uuid, 16); 1377 memcpy(uuid->uuid, cp->uuid, 16);
1302 uuid->svc_hint = cp->svc_hint; 1378 uuid->svc_hint = cp->svc_hint;
1379 uuid->size = get_uuid_size(cp->uuid);
1303 1380
1304 list_add(&uuid->list, &hdev->uuids); 1381 list_add_tail(&uuid->list, &hdev->uuids);
1305 1382
1306 err = update_class(hdev); 1383 err = update_class(hdev);
1307 if (err < 0) 1384 if (err < 0)
@@ -1332,7 +1409,8 @@ static bool enable_service_cache(struct hci_dev *hdev)
1332 return false; 1409 return false;
1333 1410
1334 if (!test_and_set_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) { 1411 if (!test_and_set_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) {
1335 schedule_delayed_work(&hdev->service_cache, CACHE_TIMEOUT); 1412 queue_delayed_work(hdev->workqueue, &hdev->service_cache,
1413 CACHE_TIMEOUT);
1336 return true; 1414 return true;
1337 } 1415 }
1338 1416
@@ -1344,7 +1422,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
1344{ 1422{
1345 struct mgmt_cp_remove_uuid *cp = data; 1423 struct mgmt_cp_remove_uuid *cp = data;
1346 struct pending_cmd *cmd; 1424 struct pending_cmd *cmd;
1347 struct list_head *p, *n; 1425 struct bt_uuid *match, *tmp;
1348 u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1426 u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1349 int err, found; 1427 int err, found;
1350 1428
@@ -1372,9 +1450,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
1372 1450
1373 found = 0; 1451 found = 0;
1374 1452
1375 list_for_each_safe(p, n, &hdev->uuids) { 1453 list_for_each_entry_safe(match, tmp, &hdev->uuids, list) {
1376 struct bt_uuid *match = list_entry(p, struct bt_uuid, list);
1377
1378 if (memcmp(match->uuid, cp->uuid, 16) != 0) 1454 if (memcmp(match->uuid, cp->uuid, 16) != 0)
1379 continue; 1455 continue;
1380 1456
@@ -1422,13 +1498,19 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
1422 1498
1423 BT_DBG("request for %s", hdev->name); 1499 BT_DBG("request for %s", hdev->name);
1424 1500
1425 hci_dev_lock(hdev); 1501 if (!lmp_bredr_capable(hdev))
1502 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
1503 MGMT_STATUS_NOT_SUPPORTED);
1426 1504
1427 if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { 1505 if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags))
1428 err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 1506 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
1429 MGMT_STATUS_BUSY); 1507 MGMT_STATUS_BUSY);
1430 goto unlock; 1508
1431 } 1509 if ((cp->minor & 0x03) != 0 || (cp->major & 0xe0) != 0)
1510 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
1511 MGMT_STATUS_INVALID_PARAMS);
1512
1513 hci_dev_lock(hdev);
1432 1514
1433 hdev->major_class = cp->major; 1515 hdev->major_class = cp->major;
1434 hdev->minor_class = cp->minor; 1516 hdev->minor_class = cp->minor;
@@ -1483,9 +1565,21 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
1483 MGMT_STATUS_INVALID_PARAMS); 1565 MGMT_STATUS_INVALID_PARAMS);
1484 } 1566 }
1485 1567
1568 if (cp->debug_keys != 0x00 && cp->debug_keys != 0x01)
1569 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
1570 MGMT_STATUS_INVALID_PARAMS);
1571
1486 BT_DBG("%s debug_keys %u key_count %u", hdev->name, cp->debug_keys, 1572 BT_DBG("%s debug_keys %u key_count %u", hdev->name, cp->debug_keys,
1487 key_count); 1573 key_count);
1488 1574
1575 for (i = 0; i < key_count; i++) {
1576 struct mgmt_link_key_info *key = &cp->keys[i];
1577
1578 if (key->addr.type != BDADDR_BREDR)
1579 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
1580 MGMT_STATUS_INVALID_PARAMS);
1581 }
1582
1489 hci_dev_lock(hdev); 1583 hci_dev_lock(hdev);
1490 1584
1491 hci_link_keys_clear(hdev); 1585 hci_link_keys_clear(hdev);
@@ -1533,12 +1627,22 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
1533 struct hci_conn *conn; 1627 struct hci_conn *conn;
1534 int err; 1628 int err;
1535 1629
1536 hci_dev_lock(hdev);
1537
1538 memset(&rp, 0, sizeof(rp)); 1630 memset(&rp, 0, sizeof(rp));
1539 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr); 1631 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1540 rp.addr.type = cp->addr.type; 1632 rp.addr.type = cp->addr.type;
1541 1633
1634 if (!bdaddr_type_is_valid(cp->addr.type))
1635 return cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
1636 MGMT_STATUS_INVALID_PARAMS,
1637 &rp, sizeof(rp));
1638
1639 if (cp->disconnect != 0x00 && cp->disconnect != 0x01)
1640 return cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
1641 MGMT_STATUS_INVALID_PARAMS,
1642 &rp, sizeof(rp));
1643
1644 hci_dev_lock(hdev);
1645
1542 if (!hdev_is_powered(hdev)) { 1646 if (!hdev_is_powered(hdev)) {
1543 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 1647 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
1544 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp)); 1648 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
@@ -1596,6 +1700,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
1596 u16 len) 1700 u16 len)
1597{ 1701{
1598 struct mgmt_cp_disconnect *cp = data; 1702 struct mgmt_cp_disconnect *cp = data;
1703 struct mgmt_rp_disconnect rp;
1599 struct hci_cp_disconnect dc; 1704 struct hci_cp_disconnect dc;
1600 struct pending_cmd *cmd; 1705 struct pending_cmd *cmd;
1601 struct hci_conn *conn; 1706 struct hci_conn *conn;
@@ -1603,17 +1708,26 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
1603 1708
1604 BT_DBG(""); 1709 BT_DBG("");
1605 1710
1711 memset(&rp, 0, sizeof(rp));
1712 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1713 rp.addr.type = cp->addr.type;
1714
1715 if (!bdaddr_type_is_valid(cp->addr.type))
1716 return cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1717 MGMT_STATUS_INVALID_PARAMS,
1718 &rp, sizeof(rp));
1719
1606 hci_dev_lock(hdev); 1720 hci_dev_lock(hdev);
1607 1721
1608 if (!test_bit(HCI_UP, &hdev->flags)) { 1722 if (!test_bit(HCI_UP, &hdev->flags)) {
1609 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1723 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1610 MGMT_STATUS_NOT_POWERED); 1724 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
1611 goto failed; 1725 goto failed;
1612 } 1726 }
1613 1727
1614 if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) { 1728 if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) {
1615 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1729 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1616 MGMT_STATUS_BUSY); 1730 MGMT_STATUS_BUSY, &rp, sizeof(rp));
1617 goto failed; 1731 goto failed;
1618 } 1732 }
1619 1733
@@ -1624,8 +1738,8 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
1624 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); 1738 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
1625 1739
1626 if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) { 1740 if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) {
1627 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1741 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1628 MGMT_STATUS_NOT_CONNECTED); 1742 MGMT_STATUS_NOT_CONNECTED, &rp, sizeof(rp));
1629 goto failed; 1743 goto failed;
1630 } 1744 }
1631 1745
@@ -1903,11 +2017,20 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
1903 2017
1904 BT_DBG(""); 2018 BT_DBG("");
1905 2019
2020 memset(&rp, 0, sizeof(rp));
2021 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
2022 rp.addr.type = cp->addr.type;
2023
2024 if (!bdaddr_type_is_valid(cp->addr.type))
2025 return cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
2026 MGMT_STATUS_INVALID_PARAMS,
2027 &rp, sizeof(rp));
2028
1906 hci_dev_lock(hdev); 2029 hci_dev_lock(hdev);
1907 2030
1908 if (!hdev_is_powered(hdev)) { 2031 if (!hdev_is_powered(hdev)) {
1909 err = cmd_status(sk, hdev->id, MGMT_OP_PAIR_DEVICE, 2032 err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
1910 MGMT_STATUS_NOT_POWERED); 2033 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
1911 goto unlock; 2034 goto unlock;
1912 } 2035 }
1913 2036
@@ -1924,10 +2047,6 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
1924 conn = hci_connect(hdev, LE_LINK, &cp->addr.bdaddr, 2047 conn = hci_connect(hdev, LE_LINK, &cp->addr.bdaddr,
1925 cp->addr.type, sec_level, auth_type); 2048 cp->addr.type, sec_level, auth_type);
1926 2049
1927 memset(&rp, 0, sizeof(rp));
1928 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1929 rp.addr.type = cp->addr.type;
1930
1931 if (IS_ERR(conn)) { 2050 if (IS_ERR(conn)) {
1932 int status; 2051 int status;
1933 2052
@@ -2254,24 +2373,16 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
2254 2373
2255 hci_dev_lock(hdev); 2374 hci_dev_lock(hdev);
2256 2375
2257 if (!hdev_is_powered(hdev)) {
2258 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
2259 MGMT_STATUS_NOT_POWERED, &cp->addr,
2260 sizeof(cp->addr));
2261 goto unlock;
2262 }
2263
2264 err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash, 2376 err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash,
2265 cp->randomizer); 2377 cp->randomizer);
2266 if (err < 0) 2378 if (err < 0)
2267 status = MGMT_STATUS_FAILED; 2379 status = MGMT_STATUS_FAILED;
2268 else 2380 else
2269 status = 0; 2381 status = MGMT_STATUS_SUCCESS;
2270 2382
2271 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status, 2383 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status,
2272 &cp->addr, sizeof(cp->addr)); 2384 &cp->addr, sizeof(cp->addr));
2273 2385
2274unlock:
2275 hci_dev_unlock(hdev); 2386 hci_dev_unlock(hdev);
2276 return err; 2387 return err;
2277} 2388}
@@ -2287,24 +2398,15 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
2287 2398
2288 hci_dev_lock(hdev); 2399 hci_dev_lock(hdev);
2289 2400
2290 if (!hdev_is_powered(hdev)) {
2291 err = cmd_complete(sk, hdev->id,
2292 MGMT_OP_REMOVE_REMOTE_OOB_DATA,
2293 MGMT_STATUS_NOT_POWERED, &cp->addr,
2294 sizeof(cp->addr));
2295 goto unlock;
2296 }
2297
2298 err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr); 2401 err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr);
2299 if (err < 0) 2402 if (err < 0)
2300 status = MGMT_STATUS_INVALID_PARAMS; 2403 status = MGMT_STATUS_INVALID_PARAMS;
2301 else 2404 else
2302 status = 0; 2405 status = MGMT_STATUS_SUCCESS;
2303 2406
2304 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA, 2407 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
2305 status, &cp->addr, sizeof(cp->addr)); 2408 status, &cp->addr, sizeof(cp->addr));
2306 2409
2307unlock:
2308 hci_dev_unlock(hdev); 2410 hci_dev_unlock(hdev);
2309 return err; 2411 return err;
2310} 2412}
@@ -2365,31 +2467,45 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
2365 2467
2366 switch (hdev->discovery.type) { 2468 switch (hdev->discovery.type) {
2367 case DISCOV_TYPE_BREDR: 2469 case DISCOV_TYPE_BREDR:
2368 if (lmp_bredr_capable(hdev)) 2470 if (!lmp_bredr_capable(hdev)) {
2369 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR); 2471 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2370 else 2472 MGMT_STATUS_NOT_SUPPORTED);
2371 err = -ENOTSUPP; 2473 mgmt_pending_remove(cmd);
2474 goto failed;
2475 }
2476
2477 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
2372 break; 2478 break;
2373 2479
2374 case DISCOV_TYPE_LE: 2480 case DISCOV_TYPE_LE:
2375 if (lmp_host_le_capable(hdev)) 2481 if (!lmp_host_le_capable(hdev)) {
2376 err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT, 2482 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2377 LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY); 2483 MGMT_STATUS_NOT_SUPPORTED);
2378 else 2484 mgmt_pending_remove(cmd);
2379 err = -ENOTSUPP; 2485 goto failed;
2486 }
2487
2488 err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT,
2489 LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY);
2380 break; 2490 break;
2381 2491
2382 case DISCOV_TYPE_INTERLEAVED: 2492 case DISCOV_TYPE_INTERLEAVED:
2383 if (lmp_host_le_capable(hdev) && lmp_bredr_capable(hdev)) 2493 if (!lmp_host_le_capable(hdev) || !lmp_bredr_capable(hdev)) {
2384 err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT, 2494 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2385 LE_SCAN_WIN, 2495 MGMT_STATUS_NOT_SUPPORTED);
2386 LE_SCAN_TIMEOUT_BREDR_LE); 2496 mgmt_pending_remove(cmd);
2387 else 2497 goto failed;
2388 err = -ENOTSUPP; 2498 }
2499
2500 err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT, LE_SCAN_WIN,
2501 LE_SCAN_TIMEOUT_BREDR_LE);
2389 break; 2502 break;
2390 2503
2391 default: 2504 default:
2392 err = -EINVAL; 2505 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2506 MGMT_STATUS_INVALID_PARAMS);
2507 mgmt_pending_remove(cmd);
2508 goto failed;
2393 } 2509 }
2394 2510
2395 if (err < 0) 2511 if (err < 0)
@@ -2510,7 +2626,8 @@ static int confirm_name(struct sock *sk, struct hci_dev *hdev, void *data,
2510 hci_inquiry_cache_update_resolve(hdev, e); 2626 hci_inquiry_cache_update_resolve(hdev, e);
2511 } 2627 }
2512 2628
2513 err = 0; 2629 err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, 0, &cp->addr,
2630 sizeof(cp->addr));
2514 2631
2515failed: 2632failed:
2516 hci_dev_unlock(hdev); 2633 hci_dev_unlock(hdev);
@@ -2526,13 +2643,18 @@ static int block_device(struct sock *sk, struct hci_dev *hdev, void *data,
2526 2643
2527 BT_DBG("%s", hdev->name); 2644 BT_DBG("%s", hdev->name);
2528 2645
2646 if (!bdaddr_type_is_valid(cp->addr.type))
2647 return cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE,
2648 MGMT_STATUS_INVALID_PARAMS,
2649 &cp->addr, sizeof(cp->addr));
2650
2529 hci_dev_lock(hdev); 2651 hci_dev_lock(hdev);
2530 2652
2531 err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type); 2653 err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type);
2532 if (err < 0) 2654 if (err < 0)
2533 status = MGMT_STATUS_FAILED; 2655 status = MGMT_STATUS_FAILED;
2534 else 2656 else
2535 status = 0; 2657 status = MGMT_STATUS_SUCCESS;
2536 2658
2537 err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status, 2659 err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status,
2538 &cp->addr, sizeof(cp->addr)); 2660 &cp->addr, sizeof(cp->addr));
@@ -2551,13 +2673,18 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data,
2551 2673
2552 BT_DBG("%s", hdev->name); 2674 BT_DBG("%s", hdev->name);
2553 2675
2676 if (!bdaddr_type_is_valid(cp->addr.type))
2677 return cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE,
2678 MGMT_STATUS_INVALID_PARAMS,
2679 &cp->addr, sizeof(cp->addr));
2680
2554 hci_dev_lock(hdev); 2681 hci_dev_lock(hdev);
2555 2682
2556 err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type); 2683 err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type);
2557 if (err < 0) 2684 if (err < 0)
2558 status = MGMT_STATUS_INVALID_PARAMS; 2685 status = MGMT_STATUS_INVALID_PARAMS;
2559 else 2686 else
2560 status = 0; 2687 status = MGMT_STATUS_SUCCESS;
2561 2688
2562 err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status, 2689 err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status,
2563 &cp->addr, sizeof(cp->addr)); 2690 &cp->addr, sizeof(cp->addr));
@@ -2612,6 +2739,10 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
2612 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, 2739 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2613 MGMT_STATUS_NOT_SUPPORTED); 2740 MGMT_STATUS_NOT_SUPPORTED);
2614 2741
2742 if (cp->val != 0x00 && cp->val != 0x01)
2743 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2744 MGMT_STATUS_INVALID_PARAMS);
2745
2615 if (!hdev_is_powered(hdev)) 2746 if (!hdev_is_powered(hdev))
2616 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, 2747 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2617 MGMT_STATUS_NOT_POWERED); 2748 MGMT_STATUS_NOT_POWERED);
@@ -2659,12 +2790,23 @@ done:
2659 return err; 2790 return err;
2660} 2791}
2661 2792
2793static bool ltk_is_valid(struct mgmt_ltk_info *key)
2794{
2795 if (key->authenticated != 0x00 && key->authenticated != 0x01)
2796 return false;
2797 if (key->master != 0x00 && key->master != 0x01)
2798 return false;
2799 if (!bdaddr_type_is_le(key->addr.type))
2800 return false;
2801 return true;
2802}
2803
2662static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, 2804static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
2663 void *cp_data, u16 len) 2805 void *cp_data, u16 len)
2664{ 2806{
2665 struct mgmt_cp_load_long_term_keys *cp = cp_data; 2807 struct mgmt_cp_load_long_term_keys *cp = cp_data;
2666 u16 key_count, expected_len; 2808 u16 key_count, expected_len;
2667 int i; 2809 int i, err;
2668 2810
2669 key_count = __le16_to_cpu(cp->key_count); 2811 key_count = __le16_to_cpu(cp->key_count);
2670 2812
@@ -2674,11 +2816,20 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
2674 BT_ERR("load_keys: expected %u bytes, got %u bytes", 2816 BT_ERR("load_keys: expected %u bytes, got %u bytes",
2675 len, expected_len); 2817 len, expected_len);
2676 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 2818 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
2677 EINVAL); 2819 MGMT_STATUS_INVALID_PARAMS);
2678 } 2820 }
2679 2821
2680 BT_DBG("%s key_count %u", hdev->name, key_count); 2822 BT_DBG("%s key_count %u", hdev->name, key_count);
2681 2823
2824 for (i = 0; i < key_count; i++) {
2825 struct mgmt_ltk_info *key = &cp->keys[i];
2826
2827 if (!ltk_is_valid(key))
2828 return cmd_status(sk, hdev->id,
2829 MGMT_OP_LOAD_LONG_TERM_KEYS,
2830 MGMT_STATUS_INVALID_PARAMS);
2831 }
2832
2682 hci_dev_lock(hdev); 2833 hci_dev_lock(hdev);
2683 2834
2684 hci_smp_ltks_clear(hdev); 2835 hci_smp_ltks_clear(hdev);
@@ -2698,9 +2849,12 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
2698 key->enc_size, key->ediv, key->rand); 2849 key->enc_size, key->ediv, key->rand);
2699 } 2850 }
2700 2851
2852 err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0,
2853 NULL, 0);
2854
2701 hci_dev_unlock(hdev); 2855 hci_dev_unlock(hdev);
2702 2856
2703 return 0; 2857 return err;
2704} 2858}
2705 2859
2706static const struct mgmt_handler { 2860static const struct mgmt_handler {
@@ -2915,6 +3069,8 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
2915 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); 3069 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
2916 3070
2917 if (powered) { 3071 if (powered) {
3072 u8 link_sec;
3073
2918 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && 3074 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
2919 !lmp_host_ssp_capable(hdev)) { 3075 !lmp_host_ssp_capable(hdev)) {
2920 u8 ssp = 1; 3076 u8 ssp = 1;
@@ -2938,6 +3094,11 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
2938 sizeof(cp), &cp); 3094 sizeof(cp), &cp);
2939 } 3095 }
2940 3096
3097 link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
3098 if (link_sec != test_bit(HCI_AUTH, &hdev->flags))
3099 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
3100 sizeof(link_sec), &link_sec);
3101
2941 if (lmp_bredr_capable(hdev)) { 3102 if (lmp_bredr_capable(hdev)) {
2942 set_bredr_scan(hdev); 3103 set_bredr_scan(hdev);
2943 update_class(hdev); 3104 update_class(hdev);
@@ -2946,7 +3107,13 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
2946 } 3107 }
2947 } else { 3108 } else {
2948 u8 status = MGMT_STATUS_NOT_POWERED; 3109 u8 status = MGMT_STATUS_NOT_POWERED;
3110 u8 zero_cod[] = { 0, 0, 0 };
3111
2949 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); 3112 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
3113
3114 if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0)
3115 mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
3116 zero_cod, sizeof(zero_cod), NULL);
2950 } 3117 }
2951 3118
2952 err = new_settings(hdev, match.sk); 3119 err = new_settings(hdev, match.sk);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 57f250c20e39..b5178d62064e 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -900,8 +900,6 @@ static void sco_conn_ready(struct sco_conn *conn)
900 900
901 BT_DBG("conn %p", conn); 901 BT_DBG("conn %p", conn);
902 902
903 sco_conn_lock(conn);
904
905 if (sk) { 903 if (sk) {
906 sco_sock_clear_timer(sk); 904 sco_sock_clear_timer(sk);
907 bh_lock_sock(sk); 905 bh_lock_sock(sk);
@@ -909,9 +907,13 @@ static void sco_conn_ready(struct sco_conn *conn)
909 sk->sk_state_change(sk); 907 sk->sk_state_change(sk);
910 bh_unlock_sock(sk); 908 bh_unlock_sock(sk);
911 } else { 909 } else {
910 sco_conn_lock(conn);
911
912 parent = sco_get_sock_listen(conn->src); 912 parent = sco_get_sock_listen(conn->src);
913 if (!parent) 913 if (!parent) {
914 goto done; 914 sco_conn_unlock(conn);
915 return;
916 }
915 917
916 bh_lock_sock(parent); 918 bh_lock_sock(parent);
917 919
@@ -919,7 +921,8 @@ static void sco_conn_ready(struct sco_conn *conn)
919 BTPROTO_SCO, GFP_ATOMIC); 921 BTPROTO_SCO, GFP_ATOMIC);
920 if (!sk) { 922 if (!sk) {
921 bh_unlock_sock(parent); 923 bh_unlock_sock(parent);
922 goto done; 924 sco_conn_unlock(conn);
925 return;
923 } 926 }
924 927
925 sco_sock_init(sk, parent); 928 sco_sock_init(sk, parent);
@@ -939,10 +942,9 @@ static void sco_conn_ready(struct sco_conn *conn)
939 parent->sk_data_ready(parent, 1); 942 parent->sk_data_ready(parent, 1);
940 943
941 bh_unlock_sock(parent); 944 bh_unlock_sock(parent);
942 }
943 945
944done: 946 sco_conn_unlock(conn);
945 sco_conn_unlock(conn); 947 }
946} 948}
947 949
948/* ----- SCO interface with lower layer (HCI) ----- */ 950/* ----- SCO interface with lower layer (HCI) ----- */
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 85bc75c38dea..746f5a2f9804 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -549,14 +549,13 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
549 pr_err("No LLCP device\n"); 549 pr_err("No LLCP device\n");
550 return -ENODEV; 550 return -ENODEV;
551 } 551 }
552 if (gb_len < 3)
553 return -EINVAL;
552 554
553 memset(local->remote_gb, 0, NFC_MAX_GT_LEN); 555 memset(local->remote_gb, 0, NFC_MAX_GT_LEN);
554 memcpy(local->remote_gb, gb, gb_len); 556 memcpy(local->remote_gb, gb, gb_len);
555 local->remote_gb_len = gb_len; 557 local->remote_gb_len = gb_len;
556 558
557 if (local->remote_gb == NULL || local->remote_gb_len == 0)
558 return -ENODEV;
559
560 if (memcmp(local->remote_gb, llcp_magic, 3)) { 559 if (memcmp(local->remote_gb, llcp_magic, 3)) {
561 pr_err("MAC does not support LLCP\n"); 560 pr_err("MAC does not support LLCP\n");
562 return -EINVAL; 561 return -EINVAL;