aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-04-18 14:17:13 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-18 14:27:48 -0400
commit59ef43e681d103a51c3727dad0315e093f07ec61 (patch)
tree87f6320f1440ce3ce6c0c15ad3cef8bc98186f88 /drivers/net/wireless
parent91fbe33034c184c6a60e31c2207a2f7ec2f180dc (diff)
parentb5abcf0219263f4e961dca71cbe26e06c5b0ee68 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/iwlwifi/iwl-testmode.c include/net/nfc/nfc.h net/nfc/netlink.c net/wireless/nl80211.c
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/Kconfig3
-rw-r--r--drivers/net/wireless/Makefile4
-rw-r--r--drivers/net/wireless/adm8211.c17
-rw-r--r--drivers/net/wireless/at76c50x-usb.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/pci.c27
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c9
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c8
-rw-r--r--drivers/net/wireless/ath/ath6kl/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c417
-rw-r--r--drivers/net/wireless/ath/ath6kl/common.h4
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.c30
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h34
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c6
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif-ops.h34
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.h6
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc-ops.h113
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.h98
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_mbox.c (renamed from drivers/net/wireless/ath/ath6kl/htc.c)85
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_pipe.c1713
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c57
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c23
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c785
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c80
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h40
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c52
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c188
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h23
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c40
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c38
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c54
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c11
-rw-r--r--drivers/net/wireless/atmel.c3
-rw-r--r--drivers/net/wireless/atmel_pci.c13
-rw-r--r--drivers/net/wireless/b43/xmit.c3
-rw-r--r--drivers/net/wireless/b43legacy/main.c2
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c127
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.c36
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c41
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h40
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c3
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c16
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c16
-rw-r--r--drivers/net/wireless/ipw2x00/ipw.h23
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c7
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c7
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig29
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c117
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c120
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c274
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c229
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-devices.c756
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c100
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c68
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c289
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c339
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c146
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c305
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h183
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h227
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c711
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h86
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c146
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h86
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c70
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c220
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-mac80211.c125
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-op-mode.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-pci.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c62
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-shared.h227
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c83
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie.c122
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-ucode.c14
-rw-r--r--drivers/net/wireless/libertas/Makefile1
-rw-r--r--drivers/net/wireless/libertas/decl.h11
-rw-r--r--drivers/net/wireless/libertas/dev.h10
-rw-r--r--drivers/net/wireless/libertas/firmware.c222
-rw-r--r--drivers/net/wireless/libertas/if_cs.c10
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c229
-rw-r--r--drivers/net/wireless/libertas/if_spi.c11
-rw-r--r--drivers/net/wireless/libertas/if_usb.c265
-rw-r--r--drivers/net/wireless/libertas/main.c117
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c1
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c31
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c31
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c2
-rw-r--r--drivers/net/wireless/mwifiex/fw.h3
-rw-r--r--drivers/net/wireless/mwifiex/init.c2
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h3
-rw-r--r--drivers/net/wireless/mwifiex/join.c50
-rw-r--r--drivers/net/wireless/mwifiex/main.c106
-rw-r--r--drivers/net/wireless/mwifiex/main.h20
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c3
-rw-r--r--drivers/net/wireless/mwifiex/scan.c63
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c3
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c87
-rw-r--r--drivers/net/wireless/mwl8k.c13
-rw-r--r--drivers/net/wireless/orinoco/fw.c7
-rw-r--r--drivers/net/wireless/p54/p54pci.c13
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c13
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c13
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c36
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c28
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c13
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c13
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/dev.c1
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c19
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/def.h16
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.c19
-rw-r--r--drivers/net/wireless/ti/Kconfig14
-rw-r--r--drivers/net/wireless/ti/Makefile4
-rw-r--r--drivers/net/wireless/ti/wl1251/Kconfig (renamed from drivers/net/wireless/wl1251/Kconfig)0
-rw-r--r--drivers/net/wireless/ti/wl1251/Makefile (renamed from drivers/net/wireless/wl1251/Makefile)0
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.c (renamed from drivers/net/wireless/wl1251/acx.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.h (renamed from drivers/net/wireless/wl1251/acx.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/boot.c (renamed from drivers/net/wireless/wl1251/boot.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/boot.h (renamed from drivers/net/wireless/wl1251/boot.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/cmd.c (renamed from drivers/net/wireless/wl1251/cmd.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/cmd.h (renamed from drivers/net/wireless/wl1251/cmd.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/debugfs.c (renamed from drivers/net/wireless/wl1251/debugfs.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/debugfs.h (renamed from drivers/net/wireless/wl1251/debugfs.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/event.c (renamed from drivers/net/wireless/wl1251/event.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/event.h (renamed from drivers/net/wireless/wl1251/event.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/init.c (renamed from drivers/net/wireless/wl1251/init.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/init.h (renamed from drivers/net/wireless/wl1251/init.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/io.c (renamed from drivers/net/wireless/wl1251/io.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/io.h (renamed from drivers/net/wireless/wl1251/io.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c (renamed from drivers/net/wireless/wl1251/main.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/ps.c (renamed from drivers/net/wireless/wl1251/ps.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/ps.h (renamed from drivers/net/wireless/wl1251/ps.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/reg.h (renamed from drivers/net/wireless/wl1251/reg.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/rx.c (renamed from drivers/net/wireless/wl1251/rx.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/rx.h (renamed from drivers/net/wireless/wl1251/rx.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/sdio.c (renamed from drivers/net/wireless/wl1251/sdio.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.c (renamed from drivers/net/wireless/wl1251/spi.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.h (renamed from drivers/net/wireless/wl1251/spi.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/tx.c (renamed from drivers/net/wireless/wl1251/tx.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/tx.h (renamed from drivers/net/wireless/wl1251/tx.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/wl1251.h (renamed from drivers/net/wireless/wl1251/wl1251.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/wl12xx_80211.h (renamed from drivers/net/wireless/wl1251/wl12xx_80211.h)0
-rw-r--r--drivers/net/wireless/ti/wl12xx/Kconfig8
-rw-r--r--drivers/net/wireless/ti/wl12xx/Makefile3
-rw-r--r--drivers/net/wireless/ti/wl12xx/acx.c53
-rw-r--r--drivers/net/wireless/ti/wl12xx/acx.h36
-rw-r--r--drivers/net/wireless/ti/wl12xx/cmd.c254
-rw-r--r--drivers/net/wireless/ti/wl12xx/cmd.h112
-rw-r--r--drivers/net/wireless/ti/wl12xx/conf.h50
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c1388
-rw-r--r--drivers/net/wireless/ti/wl12xx/reg.h (renamed from drivers/net/wireless/wl12xx/reg.h)315
-rw-r--r--drivers/net/wireless/ti/wl12xx/wl12xx.h31
-rw-r--r--drivers/net/wireless/ti/wlcore/Kconfig41
-rw-r--r--drivers/net/wireless/ti/wlcore/Makefile15
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.c (renamed from drivers/net/wireless/wl12xx/acx.c)42
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.h (renamed from drivers/net/wireless/wl12xx/acx.h)10
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.c443
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.h54
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c (renamed from drivers/net/wireless/wl12xx/cmd.c)285
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h (renamed from drivers/net/wireless/wl12xx/cmd.h)98
-rw-r--r--drivers/net/wireless/ti/wlcore/conf.h (renamed from drivers/net/wireless/wl12xx/conf.h)85
-rw-r--r--drivers/net/wireless/ti/wlcore/debug.h (renamed from drivers/net/wireless/wl12xx/debug.h)1
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c (renamed from drivers/net/wireless/wl12xx/debugfs.c)3
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.h (renamed from drivers/net/wireless/wl12xx/debugfs.h)2
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c (renamed from drivers/net/wireless/wl12xx/event.c)31
-rw-r--r--drivers/net/wireless/ti/wlcore/event.h (renamed from drivers/net/wireless/wl12xx/event.h)3
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h122
-rw-r--r--drivers/net/wireless/ti/wlcore/ini.h (renamed from drivers/net/wireless/wl12xx/ini.h)0
-rw-r--r--drivers/net/wireless/ti/wlcore/init.c (renamed from drivers/net/wireless/wl12xx/init.c)66
-rw-r--r--drivers/net/wireless/ti/wlcore/init.h (renamed from drivers/net/wireless/wl12xx/init.h)2
-rw-r--r--drivers/net/wireless/ti/wlcore/io.c (renamed from drivers/net/wireless/wl12xx/io.c)191
-rw-r--r--drivers/net/wireless/ti/wlcore/io.h (renamed from drivers/net/wireless/wl12xx/io.h)88
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c (renamed from drivers/net/wireless/wl12xx/main.c)821
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.c (renamed from drivers/net/wireless/wl12xx/ps.c)8
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.h (renamed from drivers/net/wireless/wl12xx/ps.h)2
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.c (renamed from drivers/net/wireless/wl12xx/rx.c)130
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.h (renamed from drivers/net/wireless/wl12xx/rx.h)12
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.c (renamed from drivers/net/wireless/wl12xx/scan.c)30
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.h (renamed from drivers/net/wireless/wl12xx/scan.h)4
-rw-r--r--drivers/net/wireless/ti/wlcore/sdio.c (renamed from drivers/net/wireless/wl12xx/sdio.c)6
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c (renamed from drivers/net/wireless/wl12xx/spi.c)4
-rw-r--r--drivers/net/wireless/ti/wlcore/testmode.c (renamed from drivers/net/wireless/wl12xx/testmode.c)3
-rw-r--r--drivers/net/wireless/ti/wlcore/testmode.h (renamed from drivers/net/wireless/wl12xx/testmode.h)0
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c (renamed from drivers/net/wireless/wl12xx/tx.c)125
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.h (renamed from drivers/net/wireless/wl12xx/tx.h)7
-rw-r--r--drivers/net/wireless/ti/wlcore/wl12xx.h (renamed from drivers/net/wireless/wl12xx/wl12xx.h)271
-rw-r--r--drivers/net/wireless/ti/wlcore/wl12xx_80211.h (renamed from drivers/net/wireless/wl12xx/wl12xx_80211.h)0
-rw-r--r--drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c (renamed from drivers/net/wireless/wl12xx/wl12xx_platform_data.c)0
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h448
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig48
-rw-r--r--drivers/net/wireless/wl12xx/Makefile15
-rw-r--r--drivers/net/wireless/wl12xx/boot.c786
-rw-r--r--drivers/net/wireless/wl12xx/boot.h120
244 files changed, 11021 insertions, 7053 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index abd3b71cd4ab..5f58fa53238c 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -282,8 +282,7 @@ source "drivers/net/wireless/orinoco/Kconfig"
282source "drivers/net/wireless/p54/Kconfig" 282source "drivers/net/wireless/p54/Kconfig"
283source "drivers/net/wireless/rt2x00/Kconfig" 283source "drivers/net/wireless/rt2x00/Kconfig"
284source "drivers/net/wireless/rtlwifi/Kconfig" 284source "drivers/net/wireless/rtlwifi/Kconfig"
285source "drivers/net/wireless/wl1251/Kconfig" 285source "drivers/net/wireless/ti/Kconfig"
286source "drivers/net/wireless/wl12xx/Kconfig"
287source "drivers/net/wireless/zd1211rw/Kconfig" 286source "drivers/net/wireless/zd1211rw/Kconfig"
288source "drivers/net/wireless/mwifiex/Kconfig" 287source "drivers/net/wireless/mwifiex/Kconfig"
289 288
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 98db76196b59..0ce218b931d4 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -51,9 +51,7 @@ obj-$(CONFIG_ATH_COMMON) += ath/
51 51
52obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o 52obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
53 53
54obj-$(CONFIG_WL1251) += wl1251/ 54obj-$(CONFIG_WL_TI) += ti/
55obj-$(CONFIG_WL12XX) += wl12xx/
56obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/
57 55
58obj-$(CONFIG_IWM) += iwmc3200wifi/ 56obj-$(CONFIG_IWM) += iwmc3200wifi/
59 57
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index f5ce5623da99..0ac09a2bd144 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1991,19 +1991,4 @@ static struct pci_driver adm8211_driver = {
1991#endif /* CONFIG_PM */ 1991#endif /* CONFIG_PM */
1992}; 1992};
1993 1993
1994 1994module_pci_driver(adm8211_driver);
1995
1996static int __init adm8211_init(void)
1997{
1998 return pci_register_driver(&adm8211_driver);
1999}
2000
2001
2002static void __exit adm8211_exit(void)
2003{
2004 pci_unregister_driver(&adm8211_driver);
2005}
2006
2007
2008module_init(adm8211_init);
2009module_exit(adm8211_exit);
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 4045e5ab0555..faa8bcb4aac1 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -2512,10 +2512,8 @@ static void __exit at76_mod_exit(void)
2512 2512
2513 printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n"); 2513 printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
2514 usb_deregister(&at76_driver); 2514 usb_deregister(&at76_driver);
2515 for (i = 0; i < ARRAY_SIZE(firmwares); i++) { 2515 for (i = 0; i < ARRAY_SIZE(firmwares); i++)
2516 if (firmwares[i].fw) 2516 release_firmware(firmwares[i].fw);
2517 release_firmware(firmwares[i].fw);
2518 }
2519 led_trigger_unregister_simple(ledtrig_tx); 2517 led_trigger_unregister_simple(ledtrig_tx);
2520} 2518}
2521 2519
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 55ef93dd7438..64a453a6dfe4 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1527,7 +1527,7 @@ void ath5k_eeprom_detach(struct ath5k_hw *ah);
1527 1527
1528/* Protocol Control Unit Functions */ 1528/* Protocol Control Unit Functions */
1529/* Helpers */ 1529/* Helpers */
1530int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, 1530int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, enum ieee80211_band band,
1531 int len, struct ieee80211_rate *rate, bool shortpre); 1531 int len, struct ieee80211_rate *rate, bool shortpre);
1532unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); 1532unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah);
1533unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); 1533unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 3007bba12d94..49e3b19cf781 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1170,7 +1170,7 @@ ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb,
1170 1170
1171 if (ieee80211_is_beacon(mgmt->frame_control) && 1171 if (ieee80211_is_beacon(mgmt->frame_control) &&
1172 le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && 1172 le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
1173 memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) { 1173 compare_ether_addr(mgmt->bssid, common->curbssid) == 0) {
1174 /* 1174 /*
1175 * Received an IBSS beacon with the same BSSID. Hardware *must* 1175 * Received an IBSS beacon with the same BSSID. Hardware *must*
1176 * have updated the local TSF. We have to work around various 1176 * have updated the local TSF. We have to work around various
@@ -1234,7 +1234,7 @@ ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi)
1234 1234
1235 /* only beacons from our BSSID */ 1235 /* only beacons from our BSSID */
1236 if (!ieee80211_is_beacon(mgmt->frame_control) || 1236 if (!ieee80211_is_beacon(mgmt->frame_control) ||
1237 memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0) 1237 compare_ether_addr(mgmt->bssid, common->curbssid) != 0)
1238 return; 1238 return;
1239 1239
1240 ewma_add(&ah->ah_beacon_rssi_avg, rssi); 1240 ewma_add(&ah->ah_beacon_rssi_avg, rssi);
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
index 53424e8e6d82..dff48fbc63bf 100644
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -47,6 +47,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
47 { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ 47 { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
48 { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ 48 { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
49 { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ 49 { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
50 { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */
50 { 0 } 51 { 0 }
51}; 52};
52MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); 53MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
@@ -339,28 +340,4 @@ static struct pci_driver ath5k_pci_driver = {
339 .driver.pm = ATH5K_PM_OPS, 340 .driver.pm = ATH5K_PM_OPS,
340}; 341};
341 342
342/* 343module_pci_driver(ath5k_pci_driver);
343 * Module init/exit functions
344 */
345static int __init
346init_ath5k_pci(void)
347{
348 int ret;
349
350 ret = pci_register_driver(&ath5k_pci_driver);
351 if (ret) {
352 pr_err("pci: can't register pci driver\n");
353 return ret;
354 }
355
356 return 0;
357}
358
359static void __exit
360exit_ath5k_pci(void)
361{
362 pci_unregister_driver(&ath5k_pci_driver);
363}
364
365module_init(init_ath5k_pci);
366module_exit(exit_ath5k_pci);
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index cebfd6fd31d3..1f16b4227d8f 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -110,7 +110,7 @@ static const unsigned int ack_rates_high[] =
110 * bwmodes. 110 * bwmodes.
111 */ 111 */
112int 112int
113ath5k_hw_get_frame_duration(struct ath5k_hw *ah, 113ath5k_hw_get_frame_duration(struct ath5k_hw *ah, enum ieee80211_band band,
114 int len, struct ieee80211_rate *rate, bool shortpre) 114 int len, struct ieee80211_rate *rate, bool shortpre)
115{ 115{
116 int sifs, preamble, plcp_bits, sym_time; 116 int sifs, preamble, plcp_bits, sym_time;
@@ -120,7 +120,7 @@ ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
120 /* Fallback */ 120 /* Fallback */
121 if (!ah->ah_bwmode) { 121 if (!ah->ah_bwmode) {
122 __le16 raw_dur = ieee80211_generic_frame_duration(ah->hw, 122 __le16 raw_dur = ieee80211_generic_frame_duration(ah->hw,
123 NULL, len, rate); 123 NULL, band, len, rate);
124 124
125 /* subtract difference between long and short preamble */ 125 /* subtract difference between long and short preamble */
126 dur = le16_to_cpu(raw_dur); 126 dur = le16_to_cpu(raw_dur);
@@ -302,14 +302,15 @@ ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
302 * actual rate for this rate. See mac80211 tx.c 302 * actual rate for this rate. See mac80211 tx.c
303 * ieee80211_duration() for a brief description of 303 * ieee80211_duration() for a brief description of
304 * what rate we should choose to TX ACKs. */ 304 * what rate we should choose to TX ACKs. */
305 tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); 305 tx_time = ath5k_hw_get_frame_duration(ah, band, 10,
306 rate, false);
306 307
307 ath5k_hw_reg_write(ah, tx_time, reg); 308 ath5k_hw_reg_write(ah, tx_time, reg);
308 309
309 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) 310 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
310 continue; 311 continue;
311 312
312 tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true); 313 tx_time = ath5k_hw_get_frame_duration(ah, band, 10, rate, true);
313 ath5k_hw_reg_write(ah, tx_time, 314 ath5k_hw_reg_write(ah, tx_time,
314 reg + (AR5K_SET_SHORT_PREAMBLE << 2)); 315 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
315 } 316 }
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index a6de200538c3..65fe929529a8 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -565,6 +565,7 @@ ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
565int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) 565int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
566{ 566{
567 struct ieee80211_channel *channel = ah->ah_current_channel; 567 struct ieee80211_channel *channel = ah->ah_current_channel;
568 enum ieee80211_band band;
568 struct ieee80211_rate *rate; 569 struct ieee80211_rate *rate;
569 u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock; 570 u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
570 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); 571 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
@@ -600,11 +601,12 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
600 * Also we have different lowest rate for 802.11a 601 * Also we have different lowest rate for 802.11a
601 */ 602 */
602 if (channel->band == IEEE80211_BAND_5GHZ) 603 if (channel->band == IEEE80211_BAND_5GHZ)
603 rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0]; 604 band = IEEE80211_BAND_5GHZ;
604 else 605 else
605 rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; 606 band = IEEE80211_BAND_2GHZ;
606 607
607 ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); 608 rate = &ah->sbands[band].bitrates[0];
609 ack_tx_time = ath5k_hw_get_frame_duration(ah, band, 10, rate, false);
608 610
609 /* ack_tx_time includes an SIFS already */ 611 /* ack_tx_time includes an SIFS already */
610 eifs = ack_tx_time + sifs + 2 * slot_time; 612 eifs = ack_tx_time + sifs + 2 * slot_time;
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
index 85746c3eb027..8cae8886f17d 100644
--- a/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -25,7 +25,8 @@
25obj-$(CONFIG_ATH6KL) += ath6kl_core.o 25obj-$(CONFIG_ATH6KL) += ath6kl_core.o
26ath6kl_core-y += debug.o 26ath6kl_core-y += debug.o
27ath6kl_core-y += hif.o 27ath6kl_core-y += hif.o
28ath6kl_core-y += htc.o 28ath6kl_core-y += htc_mbox.o
29ath6kl_core-y += htc_pipe.o
29ath6kl_core-y += bmi.o 30ath6kl_core-y += bmi.o
30ath6kl_core-y += cfg80211.o 31ath6kl_core-y += cfg80211.o
31ath6kl_core-y += init.o 32ath6kl_core-y += init.o
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index bdcc68fb1e37..28a65d3a03d0 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -51,6 +51,8 @@
51 .max_power = 30, \ 51 .max_power = 30, \
52} 52}
53 53
54#define DEFAULT_BG_SCAN_PERIOD 60
55
54static struct ieee80211_rate ath6kl_rates[] = { 56static struct ieee80211_rate ath6kl_rates[] = {
55 RATETAB_ENT(10, 0x1, 0), 57 RATETAB_ENT(10, 0x1, 0),
56 RATETAB_ENT(20, 0x2, 0), 58 RATETAB_ENT(20, 0x2, 0),
@@ -71,7 +73,8 @@ static struct ieee80211_rate ath6kl_rates[] = {
71#define ath6kl_g_rates (ath6kl_rates + 0) 73#define ath6kl_g_rates (ath6kl_rates + 0)
72#define ath6kl_g_rates_size 12 74#define ath6kl_g_rates_size 12
73 75
74#define ath6kl_g_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ 76#define ath6kl_g_htcap IEEE80211_HT_CAP_SGI_20
77#define ath6kl_a_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
75 IEEE80211_HT_CAP_SGI_20 | \ 78 IEEE80211_HT_CAP_SGI_20 | \
76 IEEE80211_HT_CAP_SGI_40) 79 IEEE80211_HT_CAP_SGI_40)
77 80
@@ -128,7 +131,7 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = {
128 .channels = ath6kl_5ghz_a_channels, 131 .channels = ath6kl_5ghz_a_channels,
129 .n_bitrates = ath6kl_a_rates_size, 132 .n_bitrates = ath6kl_a_rates_size,
130 .bitrates = ath6kl_a_rates, 133 .bitrates = ath6kl_a_rates,
131 .ht_cap.cap = ath6kl_g_htcap, 134 .ht_cap.cap = ath6kl_a_htcap,
132 .ht_cap.ht_supported = true, 135 .ht_cap.ht_supported = true,
133}; 136};
134 137
@@ -609,6 +612,17 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
609 vif->req_bssid, vif->ch_hint, 612 vif->req_bssid, vif->ch_hint,
610 ar->connect_ctrl_flags, nw_subtype); 613 ar->connect_ctrl_flags, nw_subtype);
611 614
615 /* disable background scan if period is 0 */
616 if (sme->bg_scan_period == 0)
617 sme->bg_scan_period = 0xffff;
618
619 /* configure default value if not specified */
620 if (sme->bg_scan_period == -1)
621 sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
622
623 ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
624 sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
625
612 up(&ar->sem); 626 up(&ar->sem);
613 627
614 if (status == -EINVAL) { 628 if (status == -EINVAL) {
@@ -943,6 +957,8 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
943 if (test_bit(CONNECTED, &vif->flags)) 957 if (test_bit(CONNECTED, &vif->flags))
944 force_fg_scan = 1; 958 force_fg_scan = 1;
945 959
960 vif->scan_req = request;
961
946 if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, 962 if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
947 ar->fw_capabilities)) { 963 ar->fw_capabilities)) {
948 /* 964 /*
@@ -965,10 +981,10 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
965 ATH6KL_FG_SCAN_INTERVAL, 981 ATH6KL_FG_SCAN_INTERVAL,
966 n_channels, channels); 982 n_channels, channels);
967 } 983 }
968 if (ret) 984 if (ret) {
969 ath6kl_err("wmi_startscan_cmd failed\n"); 985 ath6kl_err("wmi_startscan_cmd failed\n");
970 else 986 vif->scan_req = NULL;
971 vif->scan_req = request; 987 }
972 988
973 kfree(channels); 989 kfree(channels);
974 990
@@ -1438,9 +1454,38 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1438 struct vif_params *params) 1454 struct vif_params *params)
1439{ 1455{
1440 struct ath6kl_vif *vif = netdev_priv(ndev); 1456 struct ath6kl_vif *vif = netdev_priv(ndev);
1457 int i;
1441 1458
1442 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type); 1459 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1443 1460
1461 /*
1462 * Don't bring up p2p on an interface which is not initialized
1463 * for p2p operation where fw does not have capability to switch
1464 * dynamically between non-p2p and p2p type interface.
1465 */
1466 if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
1467 vif->ar->fw_capabilities) &&
1468 (type == NL80211_IFTYPE_P2P_CLIENT ||
1469 type == NL80211_IFTYPE_P2P_GO)) {
1470 if (vif->ar->vif_max == 1) {
1471 if (vif->fw_vif_idx != 0)
1472 return -EINVAL;
1473 else
1474 goto set_iface_type;
1475 }
1476
1477 for (i = vif->ar->max_norm_iface; i < vif->ar->vif_max; i++) {
1478 if (i == vif->fw_vif_idx)
1479 break;
1480 }
1481
1482 if (i == vif->ar->vif_max) {
1483 ath6kl_err("Invalid interface to bring up P2P\n");
1484 return -EINVAL;
1485 }
1486 }
1487
1488set_iface_type:
1444 switch (type) { 1489 switch (type) {
1445 case NL80211_IFTYPE_STATION: 1490 case NL80211_IFTYPE_STATION:
1446 vif->next_mode = INFRA_NETWORK; 1491 vif->next_mode = INFRA_NETWORK;
@@ -1926,12 +1971,61 @@ static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
1926 return 0; 1971 return 0;
1927} 1972}
1928 1973
1974static int is_hsleep_mode_procsed(struct ath6kl_vif *vif)
1975{
1976 return test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
1977}
1978
1979static bool is_ctrl_ep_empty(struct ath6kl *ar)
1980{
1981 return !ar->tx_pending[ar->ctrl_ep];
1982}
1983
1984static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
1985{
1986 int ret, left;
1987
1988 clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
1989
1990 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
1991 ATH6KL_HOST_MODE_ASLEEP);
1992 if (ret)
1993 return ret;
1994
1995 left = wait_event_interruptible_timeout(ar->event_wq,
1996 is_hsleep_mode_procsed(vif),
1997 WMI_TIMEOUT);
1998 if (left == 0) {
1999 ath6kl_warn("timeout, didn't get host sleep cmd processed event\n");
2000 ret = -ETIMEDOUT;
2001 } else if (left < 0) {
2002 ath6kl_warn("error while waiting for host sleep cmd processed event %d\n",
2003 left);
2004 ret = left;
2005 }
2006
2007 if (ar->tx_pending[ar->ctrl_ep]) {
2008 left = wait_event_interruptible_timeout(ar->event_wq,
2009 is_ctrl_ep_empty(ar),
2010 WMI_TIMEOUT);
2011 if (left == 0) {
2012 ath6kl_warn("clear wmi ctrl data timeout\n");
2013 ret = -ETIMEDOUT;
2014 } else if (left < 0) {
2015 ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2016 ret = left;
2017 }
2018 }
2019
2020 return ret;
2021}
2022
1929static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) 2023static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
1930{ 2024{
1931 struct in_device *in_dev; 2025 struct in_device *in_dev;
1932 struct in_ifaddr *ifa; 2026 struct in_ifaddr *ifa;
1933 struct ath6kl_vif *vif; 2027 struct ath6kl_vif *vif;
1934 int ret, left; 2028 int ret;
1935 u32 filter = 0; 2029 u32 filter = 0;
1936 u16 i, bmiss_time; 2030 u16 i, bmiss_time;
1937 u8 index = 0; 2031 u8 index = 0;
@@ -2032,39 +2126,11 @@ skip_arp:
2032 if (ret) 2126 if (ret)
2033 return ret; 2127 return ret;
2034 2128
2035 clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags); 2129 ret = ath6kl_cfg80211_host_sleep(ar, vif);
2036
2037 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2038 ATH6KL_HOST_MODE_ASLEEP);
2039 if (ret) 2130 if (ret)
2040 return ret; 2131 return ret;
2041 2132
2042 left = wait_event_interruptible_timeout(ar->event_wq, 2133 return 0;
2043 test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags),
2044 WMI_TIMEOUT);
2045 if (left == 0) {
2046 ath6kl_warn("timeout, didn't get host sleep cmd "
2047 "processed event\n");
2048 ret = -ETIMEDOUT;
2049 } else if (left < 0) {
2050 ath6kl_warn("error while waiting for host sleep cmd "
2051 "processed event %d\n", left);
2052 ret = left;
2053 }
2054
2055 if (ar->tx_pending[ar->ctrl_ep]) {
2056 left = wait_event_interruptible_timeout(ar->event_wq,
2057 ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
2058 if (left == 0) {
2059 ath6kl_warn("clear wmi ctrl data timeout\n");
2060 ret = -ETIMEDOUT;
2061 } else if (left < 0) {
2062 ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2063 ret = left;
2064 }
2065 }
2066
2067 return ret;
2068} 2134}
2069 2135
2070static int ath6kl_wow_resume(struct ath6kl *ar) 2136static int ath6kl_wow_resume(struct ath6kl *ar)
@@ -2111,10 +2177,82 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
2111 return 0; 2177 return 0;
2112} 2178}
2113 2179
2180static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2181{
2182 struct ath6kl_vif *vif;
2183 int ret;
2184
2185 vif = ath6kl_vif_first(ar);
2186 if (!vif)
2187 return -EIO;
2188
2189 if (!ath6kl_cfg80211_ready(vif))
2190 return -EIO;
2191
2192 ath6kl_cfg80211_stop_all(ar);
2193
2194 /* Save the current power mode before enabling power save */
2195 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2196
2197 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2198 if (ret)
2199 return ret;
2200
2201 /* Disable WOW mode */
2202 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2203 ATH6KL_WOW_MODE_DISABLE,
2204 0, 0);
2205 if (ret)
2206 return ret;
2207
2208 /* Flush all non control pkts in TX path */
2209 ath6kl_tx_data_cleanup(ar);
2210
2211 ret = ath6kl_cfg80211_host_sleep(ar, vif);
2212 if (ret)
2213 return ret;
2214
2215 return 0;
2216}
2217
2218static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
2219{
2220 struct ath6kl_vif *vif;
2221 int ret;
2222
2223 vif = ath6kl_vif_first(ar);
2224
2225 if (!vif)
2226 return -EIO;
2227
2228 if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2229 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2230 ar->wmi->saved_pwr_mode);
2231 if (ret)
2232 return ret;
2233 }
2234
2235 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2236 ATH6KL_HOST_MODE_AWAKE);
2237 if (ret)
2238 return ret;
2239
2240 ar->state = ATH6KL_STATE_ON;
2241
2242 /* Reset scan parameter to default values */
2243 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2244 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2245 if (ret)
2246 return ret;
2247
2248 return 0;
2249}
2250
2114int ath6kl_cfg80211_suspend(struct ath6kl *ar, 2251int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2115 enum ath6kl_cfg_suspend_mode mode, 2252 enum ath6kl_cfg_suspend_mode mode,
2116 struct cfg80211_wowlan *wow) 2253 struct cfg80211_wowlan *wow)
2117{ 2254{
2255 struct ath6kl_vif *vif;
2118 enum ath6kl_state prev_state; 2256 enum ath6kl_state prev_state;
2119 int ret; 2257 int ret;
2120 2258
@@ -2139,15 +2277,12 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2139 2277
2140 case ATH6KL_CFG_SUSPEND_DEEPSLEEP: 2278 case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
2141 2279
2142 ath6kl_cfg80211_stop_all(ar); 2280 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep suspend\n");
2143
2144 /* save the current power mode before enabling power save */
2145 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2146 2281
2147 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER); 2282 ret = ath6kl_cfg80211_deepsleep_suspend(ar);
2148 if (ret) { 2283 if (ret) {
2149 ath6kl_warn("wmi powermode command failed during suspend: %d\n", 2284 ath6kl_err("deepsleep suspend failed: %d\n", ret);
2150 ret); 2285 return ret;
2151 } 2286 }
2152 2287
2153 ar->state = ATH6KL_STATE_DEEPSLEEP; 2288 ar->state = ATH6KL_STATE_DEEPSLEEP;
@@ -2187,6 +2322,9 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2187 break; 2322 break;
2188 } 2323 }
2189 2324
2325 list_for_each_entry(vif, &ar->vif_list, list)
2326 ath6kl_cfg80211_scan_complete_event(vif, true);
2327
2190 return 0; 2328 return 0;
2191} 2329}
2192EXPORT_SYMBOL(ath6kl_cfg80211_suspend); 2330EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
@@ -2208,17 +2346,13 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
2208 break; 2346 break;
2209 2347
2210 case ATH6KL_STATE_DEEPSLEEP: 2348 case ATH6KL_STATE_DEEPSLEEP:
2211 if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) { 2349 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
2212 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2213 ar->wmi->saved_pwr_mode);
2214 if (ret) {
2215 ath6kl_warn("wmi powermode command failed during resume: %d\n",
2216 ret);
2217 }
2218 }
2219
2220 ar->state = ATH6KL_STATE_ON;
2221 2350
2351 ret = ath6kl_cfg80211_deepsleep_resume(ar);
2352 if (ret) {
2353 ath6kl_warn("deep sleep resume failed: %d\n", ret);
2354 return ret;
2355 }
2222 break; 2356 break;
2223 2357
2224 case ATH6KL_STATE_CUTPOWER: 2358 case ATH6KL_STATE_CUTPOWER:
@@ -2292,31 +2426,25 @@ void ath6kl_check_wow_status(struct ath6kl *ar)
2292} 2426}
2293#endif 2427#endif
2294 2428
2295static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, 2429static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band,
2296 struct ieee80211_channel *chan, 2430 bool ht_enable)
2297 enum nl80211_channel_type channel_type)
2298{ 2431{
2299 struct ath6kl_vif *vif; 2432 struct ath6kl_htcap *htcap = &vif->htcap;
2300
2301 /*
2302 * 'dev' could be NULL if a channel change is required for the hardware
2303 * device itself, instead of a particular VIF.
2304 *
2305 * FIXME: To be handled properly when monitor mode is supported.
2306 */
2307 if (!dev)
2308 return -EBUSY;
2309
2310 vif = netdev_priv(dev);
2311 2433
2312 if (!ath6kl_cfg80211_ready(vif)) 2434 if (htcap->ht_enable == ht_enable)
2313 return -EIO; 2435 return 0;
2314 2436
2315 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n", 2437 if (ht_enable) {
2316 __func__, chan->center_freq, chan->hw_value); 2438 /* Set default ht capabilities */
2317 vif->next_chan = chan->center_freq; 2439 htcap->ht_enable = true;
2440 htcap->cap_info = (band == IEEE80211_BAND_2GHZ) ?
2441 ath6kl_g_htcap : ath6kl_a_htcap;
2442 htcap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
2443 } else /* Disable ht */
2444 memset(htcap, 0, sizeof(*htcap));
2318 2445
2319 return 0; 2446 return ath6kl_wmi_set_htcap_cmd(vif->ar->wmi, vif->fw_vif_idx,
2447 band, htcap);
2320} 2448}
2321 2449
2322static bool ath6kl_is_p2p_ie(const u8 *pos) 2450static bool ath6kl_is_p2p_ie(const u8 *pos)
@@ -2393,6 +2521,81 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif,
2393 return 0; 2521 return 0;
2394} 2522}
2395 2523
2524static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
2525 struct ieee80211_channel *chan,
2526 enum nl80211_channel_type channel_type)
2527{
2528 struct ath6kl_vif *vif;
2529
2530 /*
2531 * 'dev' could be NULL if a channel change is required for the hardware
2532 * device itself, instead of a particular VIF.
2533 *
2534 * FIXME: To be handled properly when monitor mode is supported.
2535 */
2536 if (!dev)
2537 return -EBUSY;
2538
2539 vif = netdev_priv(dev);
2540
2541 if (!ath6kl_cfg80211_ready(vif))
2542 return -EIO;
2543
2544 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
2545 __func__, chan->center_freq, chan->hw_value);
2546 vif->next_chan = chan->center_freq;
2547 vif->next_ch_type = channel_type;
2548 vif->next_ch_band = chan->band;
2549
2550 return 0;
2551}
2552
2553static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
2554 u8 *rsn_capab)
2555{
2556 const u8 *rsn_ie;
2557 size_t rsn_ie_len;
2558 u16 cnt;
2559
2560 if (!beacon->tail)
2561 return -EINVAL;
2562
2563 rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, beacon->tail, beacon->tail_len);
2564 if (!rsn_ie)
2565 return -EINVAL;
2566
2567 rsn_ie_len = *(rsn_ie + 1);
2568 /* skip element id and length */
2569 rsn_ie += 2;
2570
2571 /* skip version, group cipher */
2572 if (rsn_ie_len < 6)
2573 return -EINVAL;
2574 rsn_ie += 6;
2575 rsn_ie_len -= 6;
2576
2577 /* skip pairwise cipher suite */
2578 if (rsn_ie_len < 2)
2579 return -EINVAL;
2580 cnt = *((u16 *) rsn_ie);
2581 rsn_ie += (2 + cnt * 4);
2582 rsn_ie_len -= (2 + cnt * 4);
2583
2584 /* skip akm suite */
2585 if (rsn_ie_len < 2)
2586 return -EINVAL;
2587 cnt = *((u16 *) rsn_ie);
2588 rsn_ie += (2 + cnt * 4);
2589 rsn_ie_len -= (2 + cnt * 4);
2590
2591 if (rsn_ie_len < 2)
2592 return -EINVAL;
2593
2594 memcpy(rsn_capab, rsn_ie, 2);
2595
2596 return 0;
2597}
2598
2396static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, 2599static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2397 struct cfg80211_ap_settings *info) 2600 struct cfg80211_ap_settings *info)
2398{ 2601{
@@ -2405,6 +2608,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2405 struct wmi_connect_cmd p; 2608 struct wmi_connect_cmd p;
2406 int res; 2609 int res;
2407 int i, ret; 2610 int i, ret;
2611 u16 rsn_capab = 0;
2408 2612
2409 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__); 2613 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2410 2614
@@ -2534,6 +2738,34 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2534 p.nw_subtype = SUBTYPE_NONE; 2738 p.nw_subtype = SUBTYPE_NONE;
2535 } 2739 }
2536 2740
2741 if (info->inactivity_timeout) {
2742 res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
2743 info->inactivity_timeout);
2744 if (res < 0)
2745 return res;
2746 }
2747
2748 if (ath6kl_set_htcap(vif, vif->next_ch_band,
2749 vif->next_ch_type != NL80211_CHAN_NO_HT))
2750 return -EIO;
2751
2752 /*
2753 * Get the PTKSA replay counter in the RSN IE. Supplicant
2754 * will use the RSN IE in M3 message and firmware has to
2755 * advertise the same in beacon/probe response. Send
2756 * the complete RSN IE capability field to firmware
2757 */
2758 if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
2759 test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
2760 ar->fw_capabilities)) {
2761 res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
2762 WLAN_EID_RSN, WMI_RSN_IE_CAPB,
2763 (const u8 *) &rsn_capab,
2764 sizeof(rsn_capab));
2765 if (res < 0)
2766 return res;
2767 }
2768
2537 res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p); 2769 res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2538 if (res < 0) 2770 if (res < 0)
2539 return res; 2771 return res;
@@ -2568,6 +2800,13 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
2568 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); 2800 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2569 clear_bit(CONNECTED, &vif->flags); 2801 clear_bit(CONNECTED, &vif->flags);
2570 2802
2803 /* Restore ht setting in firmware */
2804 if (ath6kl_set_htcap(vif, IEEE80211_BAND_2GHZ, true))
2805 return -EIO;
2806
2807 if (ath6kl_set_htcap(vif, IEEE80211_BAND_5GHZ, true))
2808 return -EIO;
2809
2571 return 0; 2810 return 0;
2572} 2811}
2573 2812
@@ -2749,6 +2988,21 @@ static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
2749 return false; 2988 return false;
2750} 2989}
2751 2990
2991/* Check if SSID length is greater than DIRECT- */
2992static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
2993{
2994 const struct ieee80211_mgmt *mgmt;
2995 mgmt = (const struct ieee80211_mgmt *) buf;
2996
2997 /* variable[1] contains the SSID tag length */
2998 if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
2999 (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
3000 return true;
3001 }
3002
3003 return false;
3004}
3005
2752static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, 3006static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
2753 struct ieee80211_channel *chan, bool offchan, 3007 struct ieee80211_channel *chan, bool offchan,
2754 enum nl80211_channel_type channel_type, 3008 enum nl80211_channel_type channel_type,
@@ -2763,11 +3017,11 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
2763 bool more_data, queued; 3017 bool more_data, queued;
2764 3018
2765 mgmt = (const struct ieee80211_mgmt *) buf; 3019 mgmt = (const struct ieee80211_mgmt *) buf;
2766 if (buf + len >= mgmt->u.probe_resp.variable && 3020 if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
2767 vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) && 3021 ieee80211_is_probe_resp(mgmt->frame_control) &&
2768 ieee80211_is_probe_resp(mgmt->frame_control)) { 3022 ath6kl_is_p2p_go_ssid(buf, len)) {
2769 /* 3023 /*
2770 * Send Probe Response frame in AP mode using a separate WMI 3024 * Send Probe Response frame in GO mode using a separate WMI
2771 * command to allow the target to fill in the generic IEs. 3025 * command to allow the target to fill in the generic IEs.
2772 */ 3026 */
2773 *cookie = 0; /* TX status not supported */ 3027 *cookie = 0; /* TX status not supported */
@@ -2835,6 +3089,8 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
2835 if (vif->sme_state != SME_DISCONNECTED) 3089 if (vif->sme_state != SME_DISCONNECTED)
2836 return -EBUSY; 3090 return -EBUSY;
2837 3091
3092 ath6kl_cfg80211_scan_complete_event(vif, true);
3093
2838 for (i = 0; i < ar->wiphy->max_sched_scan_ssids; i++) { 3094 for (i = 0; i < ar->wiphy->max_sched_scan_ssids; i++) {
2839 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, 3095 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
2840 i, DISABLE_SSID_FLAG, 3096 i, DISABLE_SSID_FLAG,
@@ -3096,6 +3352,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
3096 vif->next_mode = nw_type; 3352 vif->next_mode = nw_type;
3097 vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; 3353 vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3098 vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; 3354 vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3355 vif->htcap.ht_enable = true;
3099 3356
3100 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); 3357 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
3101 if (fw_vif_idx != 0) 3358 if (fw_vif_idx != 0)
@@ -3183,6 +3440,10 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3183 if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) 3440 if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
3184 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 3441 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3185 3442
3443 if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
3444 ar->fw_capabilities))
3445 ar->wiphy->features = NL80211_FEATURE_INACTIVITY_TIMER;
3446
3186 ar->wiphy->probe_resp_offload = 3447 ar->wiphy->probe_resp_offload =
3187 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | 3448 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3188 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | 3449 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
index a60e78c0472f..98a886154d9c 100644
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -22,7 +22,8 @@
22 22
23#define ATH6KL_MAX_IE 256 23#define ATH6KL_MAX_IE 256
24 24
25extern int ath6kl_printk(const char *level, const char *fmt, ...); 25extern __printf(2, 3)
26int ath6kl_printk(const char *level, const char *fmt, ...);
26 27
27/* 28/*
28 * Reflects the version of binary interface exposed by ATH6KL target 29 * Reflects the version of binary interface exposed by ATH6KL target
@@ -77,6 +78,7 @@ enum crypto_type {
77 78
78struct htc_endpoint_credit_dist; 79struct htc_endpoint_credit_dist;
79struct ath6kl; 80struct ath6kl;
81struct ath6kl_htcap;
80enum htc_credit_dist_reason; 82enum htc_credit_dist_reason;
81struct ath6kl_htc_credit_info; 83struct ath6kl_htc_credit_info;
82 84
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
index 45e641f3a41b..fdb3b1decc76 100644
--- a/drivers/net/wireless/ath/ath6kl/core.c
+++ b/drivers/net/wireless/ath/ath6kl/core.c
@@ -20,9 +20,11 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/moduleparam.h> 21#include <linux/moduleparam.h>
22#include <linux/export.h> 22#include <linux/export.h>
23#include <linux/vmalloc.h>
23 24
24#include "debug.h" 25#include "debug.h"
25#include "hif-ops.h" 26#include "hif-ops.h"
27#include "htc-ops.h"
26#include "cfg80211.h" 28#include "cfg80211.h"
27 29
28unsigned int debug_mask; 30unsigned int debug_mask;
@@ -39,12 +41,36 @@ module_param(uart_debug, uint, 0644);
39module_param(ath6kl_p2p, uint, 0644); 41module_param(ath6kl_p2p, uint, 0644);
40module_param(testmode, uint, 0644); 42module_param(testmode, uint, 0644);
41 43
42int ath6kl_core_init(struct ath6kl *ar) 44void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb)
45{
46 ath6kl_htc_tx_complete(ar, skb);
47}
48EXPORT_SYMBOL(ath6kl_core_tx_complete);
49
50void ath6kl_core_rx_complete(struct ath6kl *ar, struct sk_buff *skb, u8 pipe)
51{
52 ath6kl_htc_rx_complete(ar, skb, pipe);
53}
54EXPORT_SYMBOL(ath6kl_core_rx_complete);
55
56int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
43{ 57{
44 struct ath6kl_bmi_target_info targ_info; 58 struct ath6kl_bmi_target_info targ_info;
45 struct net_device *ndev; 59 struct net_device *ndev;
46 int ret = 0, i; 60 int ret = 0, i;
47 61
62 switch (htc_type) {
63 case ATH6KL_HTC_TYPE_MBOX:
64 ath6kl_htc_mbox_attach(ar);
65 break;
66 case ATH6KL_HTC_TYPE_PIPE:
67 ath6kl_htc_pipe_attach(ar);
68 break;
69 default:
70 WARN_ON(1);
71 return -ENOMEM;
72 }
73
48 ar->ath6kl_wq = create_singlethread_workqueue("ath6kl"); 74 ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
49 if (!ar->ath6kl_wq) 75 if (!ar->ath6kl_wq)
50 return -ENOMEM; 76 return -ENOMEM;
@@ -280,7 +306,7 @@ void ath6kl_core_cleanup(struct ath6kl *ar)
280 306
281 kfree(ar->fw_board); 307 kfree(ar->fw_board);
282 kfree(ar->fw_otp); 308 kfree(ar->fw_otp);
283 kfree(ar->fw); 309 vfree(ar->fw);
284 kfree(ar->fw_patch); 310 kfree(ar->fw_patch);
285 kfree(ar->fw_testscript); 311 kfree(ar->fw_testscript);
286 312
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index f1dd8906be45..9d67964a51dd 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -91,6 +91,15 @@ enum ath6kl_fw_capability {
91 */ 91 */
92 ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, 92 ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
93 93
94 /*
95 * Firmware has support to cleanup inactive stations
96 * in AP mode.
97 */
98 ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
99
100 /* Firmware has support to override rsn cap of rsn ie */
101 ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
102
94 /* this needs to be last */ 103 /* this needs to be last */
95 ATH6KL_FW_CAPABILITY_MAX, 104 ATH6KL_FW_CAPABILITY_MAX,
96}; 105};
@@ -205,6 +214,8 @@ struct ath6kl_fw_ie {
205#define ATH6KL_CONF_ENABLE_TX_BURST BIT(3) 214#define ATH6KL_CONF_ENABLE_TX_BURST BIT(3)
206#define ATH6KL_CONF_UART_DEBUG BIT(4) 215#define ATH6KL_CONF_UART_DEBUG BIT(4)
207 216
217#define P2P_WILDCARD_SSID_LEN 7 /* DIRECT- */
218
208enum wlan_low_pwr_state { 219enum wlan_low_pwr_state {
209 WLAN_POWER_STATE_ON, 220 WLAN_POWER_STATE_ON,
210 WLAN_POWER_STATE_CUT_PWR, 221 WLAN_POWER_STATE_CUT_PWR,
@@ -454,6 +465,11 @@ enum ath6kl_hif_type {
454 ATH6KL_HIF_TYPE_USB, 465 ATH6KL_HIF_TYPE_USB,
455}; 466};
456 467
468enum ath6kl_htc_type {
469 ATH6KL_HTC_TYPE_MBOX,
470 ATH6KL_HTC_TYPE_PIPE,
471};
472
457/* Max number of filters that hw supports */ 473/* Max number of filters that hw supports */
458#define ATH6K_MAX_MC_FILTERS_PER_LIST 7 474#define ATH6K_MAX_MC_FILTERS_PER_LIST 7
459struct ath6kl_mc_filter { 475struct ath6kl_mc_filter {
@@ -461,6 +477,12 @@ struct ath6kl_mc_filter {
461 char hw_addr[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE]; 477 char hw_addr[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
462}; 478};
463 479
480struct ath6kl_htcap {
481 bool ht_enable;
482 u8 ampdu_factor;
483 unsigned short cap_info;
484};
485
464/* 486/*
465 * Driver's maximum limit, note that some firmwares support only one vif 487 * Driver's maximum limit, note that some firmwares support only one vif
466 * and the runtime (current) limit must be checked from ar->vif_max. 488 * and the runtime (current) limit must be checked from ar->vif_max.
@@ -509,6 +531,7 @@ struct ath6kl_vif {
509 struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1]; 531 struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
510 struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1]; 532 struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
511 struct aggr_info *aggr_cntxt; 533 struct aggr_info *aggr_cntxt;
534 struct ath6kl_htcap htcap;
512 535
513 struct timer_list disconnect_timer; 536 struct timer_list disconnect_timer;
514 struct timer_list sched_scan_timer; 537 struct timer_list sched_scan_timer;
@@ -521,6 +544,8 @@ struct ath6kl_vif {
521 u32 send_action_id; 544 u32 send_action_id;
522 bool probe_req_report; 545 bool probe_req_report;
523 u16 next_chan; 546 u16 next_chan;
547 enum nl80211_channel_type next_ch_type;
548 enum ieee80211_band next_ch_band;
524 u16 assoc_bss_beacon_int; 549 u16 assoc_bss_beacon_int;
525 u16 listen_intvl_t; 550 u16 listen_intvl_t;
526 u16 bmiss_time_t; 551 u16 bmiss_time_t;
@@ -568,6 +593,7 @@ struct ath6kl {
568 593
569 struct ath6kl_bmi bmi; 594 struct ath6kl_bmi bmi;
570 const struct ath6kl_hif_ops *hif_ops; 595 const struct ath6kl_hif_ops *hif_ops;
596 const struct ath6kl_htc_ops *htc_ops;
571 struct wmi *wmi; 597 struct wmi *wmi;
572 int tx_pending[ENDPOINT_MAX]; 598 int tx_pending[ENDPOINT_MAX];
573 int total_tx_data_pend; 599 int total_tx_data_pend;
@@ -746,7 +772,8 @@ void init_netdev(struct net_device *dev);
746void ath6kl_cookie_init(struct ath6kl *ar); 772void ath6kl_cookie_init(struct ath6kl *ar);
747void ath6kl_cookie_cleanup(struct ath6kl *ar); 773void ath6kl_cookie_cleanup(struct ath6kl *ar);
748void ath6kl_rx(struct htc_target *target, struct htc_packet *packet); 774void ath6kl_rx(struct htc_target *target, struct htc_packet *packet);
749void ath6kl_tx_complete(void *context, struct list_head *packet_queue); 775void ath6kl_tx_complete(struct htc_target *context,
776 struct list_head *packet_queue);
750enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, 777enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
751 struct htc_packet *packet); 778 struct htc_packet *packet);
752void ath6kl_stop_txrx(struct ath6kl *ar); 779void ath6kl_stop_txrx(struct ath6kl *ar);
@@ -821,8 +848,11 @@ int ath6kl_init_hw_params(struct ath6kl *ar);
821 848
822void ath6kl_check_wow_status(struct ath6kl *ar); 849void ath6kl_check_wow_status(struct ath6kl *ar);
823 850
851void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb);
852void ath6kl_core_rx_complete(struct ath6kl *ar, struct sk_buff *skb, u8 pipe);
853
824struct ath6kl *ath6kl_core_create(struct device *dev); 854struct ath6kl *ath6kl_core_create(struct device *dev);
825int ath6kl_core_init(struct ath6kl *ar); 855int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type);
826void ath6kl_core_cleanup(struct ath6kl *ar); 856void ath6kl_core_cleanup(struct ath6kl *ar);
827void ath6kl_core_destroy(struct ath6kl *ar); 857void ath6kl_core_destroy(struct ath6kl *ar);
828 858
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index d01403a263ff..1b76aff78508 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -616,6 +616,12 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
616 "Num disconnects", tgt_stats->cs_discon_cnt); 616 "Num disconnects", tgt_stats->cs_discon_cnt);
617 len += scnprintf(buf + len, buf_len - len, "%20s %10d\n", 617 len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
618 "Beacon avg rssi", tgt_stats->cs_ave_beacon_rssi); 618 "Beacon avg rssi", tgt_stats->cs_ave_beacon_rssi);
619 len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
620 "ARP pkt received", tgt_stats->arp_received);
621 len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
622 "ARP pkt matched", tgt_stats->arp_matched);
623 len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
624 "ARP pkt replied", tgt_stats->arp_replied);
619 625
620 if (len > buf_len) 626 if (len > buf_len)
621 len = buf_len; 627 len = buf_len;
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index 1803a0baae82..49639d8266c2 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -43,6 +43,7 @@ enum ATH6K_DEBUG_MASK {
43 ATH6KL_DBG_WMI_DUMP = BIT(19), 43 ATH6KL_DBG_WMI_DUMP = BIT(19),
44 ATH6KL_DBG_SUSPEND = BIT(20), 44 ATH6KL_DBG_SUSPEND = BIT(20),
45 ATH6KL_DBG_USB = BIT(21), 45 ATH6KL_DBG_USB = BIT(21),
46 ATH6KL_DBG_USB_BULK = BIT(22),
46 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ 47 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
47}; 48};
48 49
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h
index fd84086638e3..8c9e72d5250d 100644
--- a/drivers/net/wireless/ath/ath6kl/hif-ops.h
+++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h
@@ -150,4 +150,38 @@ static inline void ath6kl_hif_stop(struct ath6kl *ar)
150 ar->hif_ops->stop(ar); 150 ar->hif_ops->stop(ar);
151} 151}
152 152
153static inline int ath6kl_hif_pipe_send(struct ath6kl *ar,
154 u8 pipe, struct sk_buff *hdr_buf,
155 struct sk_buff *buf)
156{
157 ath6kl_dbg(ATH6KL_DBG_HIF, "hif pipe send\n");
158
159 return ar->hif_ops->pipe_send(ar, pipe, hdr_buf, buf);
160}
161
162static inline void ath6kl_hif_pipe_get_default(struct ath6kl *ar,
163 u8 *ul_pipe, u8 *dl_pipe)
164{
165 ath6kl_dbg(ATH6KL_DBG_HIF, "hif pipe get default\n");
166
167 ar->hif_ops->pipe_get_default(ar, ul_pipe, dl_pipe);
168}
169
170static inline int ath6kl_hif_pipe_map_service(struct ath6kl *ar,
171 u16 service_id, u8 *ul_pipe,
172 u8 *dl_pipe)
173{
174 ath6kl_dbg(ATH6KL_DBG_HIF, "hif pipe get default\n");
175
176 return ar->hif_ops->pipe_map_service(ar, service_id, ul_pipe, dl_pipe);
177}
178
179static inline u16 ath6kl_hif_pipe_get_free_queue_number(struct ath6kl *ar,
180 u8 pipe)
181{
182 ath6kl_dbg(ATH6KL_DBG_HIF, "hif pipe get free queue number\n");
183
184 return ar->hif_ops->pipe_get_free_queue_number(ar, pipe);
185}
186
153#endif 187#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
index 20ed6b73517b..61f6b21fb0ae 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.h
+++ b/drivers/net/wireless/ath/ath6kl/hif.h
@@ -256,6 +256,12 @@ struct ath6kl_hif_ops {
256 int (*power_on)(struct ath6kl *ar); 256 int (*power_on)(struct ath6kl *ar);
257 int (*power_off)(struct ath6kl *ar); 257 int (*power_off)(struct ath6kl *ar);
258 void (*stop)(struct ath6kl *ar); 258 void (*stop)(struct ath6kl *ar);
259 int (*pipe_send)(struct ath6kl *ar, u8 pipe, struct sk_buff *hdr_buf,
260 struct sk_buff *buf);
261 void (*pipe_get_default)(struct ath6kl *ar, u8 *pipe_ul, u8 *pipe_dl);
262 int (*pipe_map_service)(struct ath6kl *ar, u16 service_id, u8 *pipe_ul,
263 u8 *pipe_dl);
264 u16 (*pipe_get_free_queue_number)(struct ath6kl *ar, u8 pipe);
259}; 265};
260 266
261int ath6kl_hif_setup(struct ath6kl_device *dev); 267int ath6kl_hif_setup(struct ath6kl_device *dev);
diff --git a/drivers/net/wireless/ath/ath6kl/htc-ops.h b/drivers/net/wireless/ath/ath6kl/htc-ops.h
new file mode 100644
index 000000000000..2d4eed55cfd1
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/htc-ops.h
@@ -0,0 +1,113 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
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
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_OPS_H
18#define HTC_OPS_H
19
20#include "htc.h"
21#include "debug.h"
22
23static inline void *ath6kl_htc_create(struct ath6kl *ar)
24{
25 return ar->htc_ops->create(ar);
26}
27
28static inline int ath6kl_htc_wait_target(struct htc_target *target)
29{
30 return target->dev->ar->htc_ops->wait_target(target);
31}
32
33static inline int ath6kl_htc_start(struct htc_target *target)
34{
35 return target->dev->ar->htc_ops->start(target);
36}
37
38static inline int ath6kl_htc_conn_service(struct htc_target *target,
39 struct htc_service_connect_req *req,
40 struct htc_service_connect_resp *resp)
41{
42 return target->dev->ar->htc_ops->conn_service(target, req, resp);
43}
44
45static inline int ath6kl_htc_tx(struct htc_target *target,
46 struct htc_packet *packet)
47{
48 return target->dev->ar->htc_ops->tx(target, packet);
49}
50
51static inline void ath6kl_htc_stop(struct htc_target *target)
52{
53 return target->dev->ar->htc_ops->stop(target);
54}
55
56static inline void ath6kl_htc_cleanup(struct htc_target *target)
57{
58 return target->dev->ar->htc_ops->cleanup(target);
59}
60
61static inline void ath6kl_htc_flush_txep(struct htc_target *target,
62 enum htc_endpoint_id endpoint,
63 u16 tag)
64{
65 return target->dev->ar->htc_ops->flush_txep(target, endpoint, tag);
66}
67
68static inline void ath6kl_htc_flush_rx_buf(struct htc_target *target)
69{
70 return target->dev->ar->htc_ops->flush_rx_buf(target);
71}
72
73static inline void ath6kl_htc_activity_changed(struct htc_target *target,
74 enum htc_endpoint_id endpoint,
75 bool active)
76{
77 return target->dev->ar->htc_ops->activity_changed(target, endpoint,
78 active);
79}
80
81static inline int ath6kl_htc_get_rxbuf_num(struct htc_target *target,
82 enum htc_endpoint_id endpoint)
83{
84 return target->dev->ar->htc_ops->get_rxbuf_num(target, endpoint);
85}
86
87static inline int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
88 struct list_head *pktq)
89{
90 return target->dev->ar->htc_ops->add_rxbuf_multiple(target, pktq);
91}
92
93static inline int ath6kl_htc_credit_setup(struct htc_target *target,
94 struct ath6kl_htc_credit_info *info)
95{
96 return target->dev->ar->htc_ops->credit_setup(target, info);
97}
98
99static inline void ath6kl_htc_tx_complete(struct ath6kl *ar,
100 struct sk_buff *skb)
101{
102 ar->htc_ops->tx_complete(ar, skb);
103}
104
105
106static inline void ath6kl_htc_rx_complete(struct ath6kl *ar,
107 struct sk_buff *skb, u8 pipe)
108{
109 ar->htc_ops->rx_complete(ar, skb, pipe);
110}
111
112
113#endif
diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h
index 5027ccc36b62..a2c8ff809793 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.h
+++ b/drivers/net/wireless/ath/ath6kl/htc.h
@@ -25,6 +25,7 @@
25/* send direction */ 25/* send direction */
26#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0) 26#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
27#define HTC_FLAGS_SEND_BUNDLE (1 << 1) 27#define HTC_FLAGS_SEND_BUNDLE (1 << 1)
28#define HTC_FLAGS_TX_FIXUP_NETBUF (1 << 2)
28 29
29/* receive direction */ 30/* receive direction */
30#define HTC_FLG_RX_UNUSED (1 << 0) 31#define HTC_FLG_RX_UNUSED (1 << 0)
@@ -56,6 +57,10 @@
56#define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT 0x2 57#define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT 0x2
57#define HTC_CONN_FLGS_REDUCE_CRED_DRIB 0x4 58#define HTC_CONN_FLGS_REDUCE_CRED_DRIB 0x4
58#define HTC_CONN_FLGS_THRESH_MASK 0x3 59#define HTC_CONN_FLGS_THRESH_MASK 0x3
60/* disable credit flow control on a specific service */
61#define HTC_CONN_FLGS_DISABLE_CRED_FLOW_CTRL (1 << 3)
62#define HTC_CONN_FLGS_SET_RECV_ALLOC_SHIFT 8
63#define HTC_CONN_FLGS_SET_RECV_ALLOC_MASK 0xFF00
59 64
60/* connect response status codes */ 65/* connect response status codes */
61#define HTC_SERVICE_SUCCESS 0 66#define HTC_SERVICE_SUCCESS 0
@@ -75,6 +80,7 @@
75#define HTC_RECORD_LOOKAHEAD_BUNDLE 3 80#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
76 81
77#define HTC_SETUP_COMP_FLG_RX_BNDL_EN (1 << 0) 82#define HTC_SETUP_COMP_FLG_RX_BNDL_EN (1 << 0)
83#define HTC_SETUP_COMP_FLG_DISABLE_TX_CREDIT_FLOW (1 << 1)
78 84
79#define MAKE_SERVICE_ID(group, index) \ 85#define MAKE_SERVICE_ID(group, index) \
80 (int)(((int)group << 8) | (int)(index)) 86 (int)(((int)group << 8) | (int)(index))
@@ -109,6 +115,8 @@
109 115
110/* HTC operational parameters */ 116/* HTC operational parameters */
111#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */ 117#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
118#define HTC_TARGET_RESPONSE_POLL_WAIT 10
119#define HTC_TARGET_RESPONSE_POLL_COUNT 200
112#define HTC_TARGET_DEBUG_INTR_MASK 0x01 120#define HTC_TARGET_DEBUG_INTR_MASK 0x01
113#define HTC_TARGET_CREDIT_INTR_MASK 0xF0 121#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
114 122
@@ -128,6 +136,7 @@
128 136
129#define HTC_RECV_WAIT_BUFFERS (1 << 0) 137#define HTC_RECV_WAIT_BUFFERS (1 << 0)
130#define HTC_OP_STATE_STOPPING (1 << 0) 138#define HTC_OP_STATE_STOPPING (1 << 0)
139#define HTC_OP_STATE_SETUP_COMPLETE (1 << 1)
131 140
132/* 141/*
133 * The frame header length and message formats defined herein were selected 142 * The frame header length and message formats defined herein were selected
@@ -311,6 +320,14 @@ struct htc_packet {
311 320
312 void (*completion) (struct htc_target *, struct htc_packet *); 321 void (*completion) (struct htc_target *, struct htc_packet *);
313 struct htc_target *context; 322 struct htc_target *context;
323
324 /*
325 * optimization for network-oriented data, the HTC packet
326 * can pass the network buffer corresponding to the HTC packet
327 * lower layers may optimized the transfer knowing this is
328 * a network buffer
329 */
330 struct sk_buff *skb;
314}; 331};
315 332
316enum htc_send_full_action { 333enum htc_send_full_action {
@@ -319,12 +336,14 @@ enum htc_send_full_action {
319}; 336};
320 337
321struct htc_ep_callbacks { 338struct htc_ep_callbacks {
339 void (*tx_complete) (struct htc_target *, struct htc_packet *);
322 void (*rx) (struct htc_target *, struct htc_packet *); 340 void (*rx) (struct htc_target *, struct htc_packet *);
323 void (*rx_refill) (struct htc_target *, enum htc_endpoint_id endpoint); 341 void (*rx_refill) (struct htc_target *, enum htc_endpoint_id endpoint);
324 enum htc_send_full_action (*tx_full) (struct htc_target *, 342 enum htc_send_full_action (*tx_full) (struct htc_target *,
325 struct htc_packet *); 343 struct htc_packet *);
326 struct htc_packet *(*rx_allocthresh) (struct htc_target *, 344 struct htc_packet *(*rx_allocthresh) (struct htc_target *,
327 enum htc_endpoint_id, int); 345 enum htc_endpoint_id, int);
346 void (*tx_comp_multi) (struct htc_target *, struct list_head *);
328 int rx_alloc_thresh; 347 int rx_alloc_thresh;
329 int rx_refill_thresh; 348 int rx_refill_thresh;
330}; 349};
@@ -502,6 +521,13 @@ struct htc_endpoint {
502 u32 conn_flags; 521 u32 conn_flags;
503 struct htc_endpoint_stats ep_st; 522 struct htc_endpoint_stats ep_st;
504 u16 tx_drop_packet_threshold; 523 u16 tx_drop_packet_threshold;
524
525 struct {
526 u8 pipeid_ul;
527 u8 pipeid_dl;
528 struct list_head tx_lookup_queue;
529 bool tx_credit_flow_enabled;
530 } pipe;
505}; 531};
506 532
507struct htc_control_buffer { 533struct htc_control_buffer {
@@ -509,6 +535,42 @@ struct htc_control_buffer {
509 u8 *buf; 535 u8 *buf;
510}; 536};
511 537
538struct htc_pipe_txcredit_alloc {
539 u16 service_id;
540 u8 credit_alloc;
541};
542
543enum htc_send_queue_result {
544 HTC_SEND_QUEUE_OK = 0, /* packet was queued */
545 HTC_SEND_QUEUE_DROP = 1, /* this packet should be dropped */
546};
547
548struct ath6kl_htc_ops {
549 void* (*create)(struct ath6kl *ar);
550 int (*wait_target)(struct htc_target *target);
551 int (*start)(struct htc_target *target);
552 int (*conn_service)(struct htc_target *target,
553 struct htc_service_connect_req *req,
554 struct htc_service_connect_resp *resp);
555 int (*tx)(struct htc_target *target, struct htc_packet *packet);
556 void (*stop)(struct htc_target *target);
557 void (*cleanup)(struct htc_target *target);
558 void (*flush_txep)(struct htc_target *target,
559 enum htc_endpoint_id endpoint, u16 tag);
560 void (*flush_rx_buf)(struct htc_target *target);
561 void (*activity_changed)(struct htc_target *target,
562 enum htc_endpoint_id endpoint,
563 bool active);
564 int (*get_rxbuf_num)(struct htc_target *target,
565 enum htc_endpoint_id endpoint);
566 int (*add_rxbuf_multiple)(struct htc_target *target,
567 struct list_head *pktq);
568 int (*credit_setup)(struct htc_target *target,
569 struct ath6kl_htc_credit_info *cred_info);
570 int (*tx_complete)(struct ath6kl *ar, struct sk_buff *skb);
571 int (*rx_complete)(struct ath6kl *ar, struct sk_buff *skb, u8 pipe);
572};
573
512struct ath6kl_device; 574struct ath6kl_device;
513 575
514/* our HTC target state */ 576/* our HTC target state */
@@ -557,36 +619,19 @@ struct htc_target {
557 619
558 /* counts the number of Tx without bundling continously per AC */ 620 /* counts the number of Tx without bundling continously per AC */
559 u32 ac_tx_count[WMM_NUM_AC]; 621 u32 ac_tx_count[WMM_NUM_AC];
622
623 struct {
624 struct htc_packet *htc_packet_pool;
625 u8 ctrl_response_buf[HTC_MAX_CTRL_MSG_LEN];
626 int ctrl_response_len;
627 bool ctrl_response_valid;
628 struct htc_pipe_txcredit_alloc txcredit_alloc[ENDPOINT_MAX];
629 } pipe;
560}; 630};
561 631
562void *ath6kl_htc_create(struct ath6kl *ar);
563void ath6kl_htc_set_credit_dist(struct htc_target *target,
564 struct ath6kl_htc_credit_info *cred_info,
565 u16 svc_pri_order[], int len);
566int ath6kl_htc_wait_target(struct htc_target *target);
567int ath6kl_htc_start(struct htc_target *target);
568int ath6kl_htc_conn_service(struct htc_target *target,
569 struct htc_service_connect_req *req,
570 struct htc_service_connect_resp *resp);
571int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet);
572void ath6kl_htc_stop(struct htc_target *target);
573void ath6kl_htc_cleanup(struct htc_target *target);
574void ath6kl_htc_flush_txep(struct htc_target *target,
575 enum htc_endpoint_id endpoint, u16 tag);
576void ath6kl_htc_flush_rx_buf(struct htc_target *target);
577void ath6kl_htc_indicate_activity_change(struct htc_target *target,
578 enum htc_endpoint_id endpoint,
579 bool active);
580int ath6kl_htc_get_rxbuf_num(struct htc_target *target,
581 enum htc_endpoint_id endpoint);
582int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
583 struct list_head *pktq);
584int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, 632int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
585 u32 msg_look_ahead, int *n_pkts); 633 u32 msg_look_ahead, int *n_pkts);
586 634
587int ath6kl_credit_setup(void *htc_handle,
588 struct ath6kl_htc_credit_info *cred_info);
589
590static inline void set_htc_pkt_info(struct htc_packet *packet, void *context, 635static inline void set_htc_pkt_info(struct htc_packet *packet, void *context,
591 u8 *buf, unsigned int len, 636 u8 *buf, unsigned int len,
592 enum htc_endpoint_id eid, u16 tag) 637 enum htc_endpoint_id eid, u16 tag)
@@ -626,4 +671,7 @@ static inline int get_queue_depth(struct list_head *queue)
626 return depth; 671 return depth;
627} 672}
628 673
674void ath6kl_htc_pipe_attach(struct ath6kl *ar);
675void ath6kl_htc_mbox_attach(struct ath6kl *ar);
676
629#endif 677#endif
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index 4849d99cce77..065e61516d7a 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -23,6 +23,14 @@
23 23
24#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) 24#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
25 25
26static void ath6kl_htc_mbox_cleanup(struct htc_target *target);
27static void ath6kl_htc_mbox_stop(struct htc_target *target);
28static int ath6kl_htc_mbox_add_rxbuf_multiple(struct htc_target *target,
29 struct list_head *pkt_queue);
30static void ath6kl_htc_set_credit_dist(struct htc_target *target,
31 struct ath6kl_htc_credit_info *cred_info,
32 u16 svc_pri_order[], int len);
33
26/* threshold to re-enable Tx bundling for an AC*/ 34/* threshold to re-enable Tx bundling for an AC*/
27#define TX_RESUME_BUNDLE_THRESHOLD 1500 35#define TX_RESUME_BUNDLE_THRESHOLD 1500
28 36
@@ -130,8 +138,8 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
130} 138}
131 139
132/* initialize and setup credit distribution */ 140/* initialize and setup credit distribution */
133int ath6kl_credit_setup(void *htc_handle, 141static int ath6kl_htc_mbox_credit_setup(struct htc_target *htc_target,
134 struct ath6kl_htc_credit_info *cred_info) 142 struct ath6kl_htc_credit_info *cred_info)
135{ 143{
136 u16 servicepriority[5]; 144 u16 servicepriority[5];
137 145
@@ -144,7 +152,7 @@ int ath6kl_credit_setup(void *htc_handle,
144 servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */ 152 servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
145 153
146 /* set priority list */ 154 /* set priority list */
147 ath6kl_htc_set_credit_dist(htc_handle, cred_info, servicepriority, 5); 155 ath6kl_htc_set_credit_dist(htc_target, cred_info, servicepriority, 5);
148 156
149 return 0; 157 return 0;
150} 158}
@@ -432,7 +440,7 @@ static void htc_tx_complete(struct htc_endpoint *endpoint,
432 "htc tx complete ep %d pkts %d\n", 440 "htc tx complete ep %d pkts %d\n",
433 endpoint->eid, get_queue_depth(txq)); 441 endpoint->eid, get_queue_depth(txq));
434 442
435 ath6kl_tx_complete(endpoint->target->dev->ar, txq); 443 ath6kl_tx_complete(endpoint->target, txq);
436} 444}
437 445
438static void htc_tx_comp_handler(struct htc_target *target, 446static void htc_tx_comp_handler(struct htc_target *target,
@@ -1065,7 +1073,7 @@ static int htc_setup_tx_complete(struct htc_target *target)
1065 return status; 1073 return status;
1066} 1074}
1067 1075
1068void ath6kl_htc_set_credit_dist(struct htc_target *target, 1076static void ath6kl_htc_set_credit_dist(struct htc_target *target,
1069 struct ath6kl_htc_credit_info *credit_info, 1077 struct ath6kl_htc_credit_info *credit_info,
1070 u16 srvc_pri_order[], int list_len) 1078 u16 srvc_pri_order[], int list_len)
1071{ 1079{
@@ -1093,7 +1101,8 @@ void ath6kl_htc_set_credit_dist(struct htc_target *target,
1093 } 1101 }
1094} 1102}
1095 1103
1096int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet) 1104static int ath6kl_htc_mbox_tx(struct htc_target *target,
1105 struct htc_packet *packet)
1097{ 1106{
1098 struct htc_endpoint *endpoint; 1107 struct htc_endpoint *endpoint;
1099 struct list_head queue; 1108 struct list_head queue;
@@ -1121,7 +1130,7 @@ int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet)
1121} 1130}
1122 1131
1123/* flush endpoint TX queue */ 1132/* flush endpoint TX queue */
1124void ath6kl_htc_flush_txep(struct htc_target *target, 1133static void ath6kl_htc_mbox_flush_txep(struct htc_target *target,
1125 enum htc_endpoint_id eid, u16 tag) 1134 enum htc_endpoint_id eid, u16 tag)
1126{ 1135{
1127 struct htc_packet *packet, *tmp_pkt; 1136 struct htc_packet *packet, *tmp_pkt;
@@ -1173,12 +1182,13 @@ static void ath6kl_htc_flush_txep_all(struct htc_target *target)
1173 if (endpoint->svc_id == 0) 1182 if (endpoint->svc_id == 0)
1174 /* not in use.. */ 1183 /* not in use.. */
1175 continue; 1184 continue;
1176 ath6kl_htc_flush_txep(target, i, HTC_TX_PACKET_TAG_ALL); 1185 ath6kl_htc_mbox_flush_txep(target, i, HTC_TX_PACKET_TAG_ALL);
1177 } 1186 }
1178} 1187}
1179 1188
1180void ath6kl_htc_indicate_activity_change(struct htc_target *target, 1189static void ath6kl_htc_mbox_activity_changed(struct htc_target *target,
1181 enum htc_endpoint_id eid, bool active) 1190 enum htc_endpoint_id eid,
1191 bool active)
1182{ 1192{
1183 struct htc_endpoint *endpoint = &target->endpoint[eid]; 1193 struct htc_endpoint *endpoint = &target->endpoint[eid];
1184 bool dist = false; 1194 bool dist = false;
@@ -1246,7 +1256,7 @@ static int htc_add_rxbuf(struct htc_target *target, struct htc_packet *packet)
1246 1256
1247 INIT_LIST_HEAD(&queue); 1257 INIT_LIST_HEAD(&queue);
1248 list_add_tail(&packet->list, &queue); 1258 list_add_tail(&packet->list, &queue);
1249 return ath6kl_htc_add_rxbuf_multiple(target, &queue); 1259 return ath6kl_htc_mbox_add_rxbuf_multiple(target, &queue);
1250} 1260}
1251 1261
1252static void htc_reclaim_rxbuf(struct htc_target *target, 1262static void htc_reclaim_rxbuf(struct htc_target *target,
@@ -1353,7 +1363,9 @@ static int ath6kl_htc_rx_setup(struct htc_target *target,
1353 sizeof(*htc_hdr)); 1363 sizeof(*htc_hdr));
1354 1364
1355 if (!htc_valid_rx_frame_len(target, ep->eid, full_len)) { 1365 if (!htc_valid_rx_frame_len(target, ep->eid, full_len)) {
1356 ath6kl_warn("Rx buffer requested with invalid length\n"); 1366 ath6kl_warn("Rx buffer requested with invalid length htc_hdr:eid %d, flags 0x%x, len %d\n",
1367 htc_hdr->eid, htc_hdr->flags,
1368 le16_to_cpu(htc_hdr->payld_len));
1357 return -EINVAL; 1369 return -EINVAL;
1358 } 1370 }
1359 1371
@@ -2288,7 +2300,7 @@ fail_ctrl_rx:
2288 return NULL; 2300 return NULL;
2289} 2301}
2290 2302
2291int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, 2303static int ath6kl_htc_mbox_add_rxbuf_multiple(struct htc_target *target,
2292 struct list_head *pkt_queue) 2304 struct list_head *pkt_queue)
2293{ 2305{
2294 struct htc_endpoint *endpoint; 2306 struct htc_endpoint *endpoint;
@@ -2350,7 +2362,7 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
2350 return status; 2362 return status;
2351} 2363}
2352 2364
2353void ath6kl_htc_flush_rx_buf(struct htc_target *target) 2365static void ath6kl_htc_mbox_flush_rx_buf(struct htc_target *target)
2354{ 2366{
2355 struct htc_endpoint *endpoint; 2367 struct htc_endpoint *endpoint;
2356 struct htc_packet *packet, *tmp_pkt; 2368 struct htc_packet *packet, *tmp_pkt;
@@ -2392,7 +2404,7 @@ void ath6kl_htc_flush_rx_buf(struct htc_target *target)
2392 } 2404 }
2393} 2405}
2394 2406
2395int ath6kl_htc_conn_service(struct htc_target *target, 2407static int ath6kl_htc_mbox_conn_service(struct htc_target *target,
2396 struct htc_service_connect_req *conn_req, 2408 struct htc_service_connect_req *conn_req,
2397 struct htc_service_connect_resp *conn_resp) 2409 struct htc_service_connect_resp *conn_resp)
2398{ 2410{
@@ -2564,7 +2576,7 @@ static void reset_ep_state(struct htc_target *target)
2564 INIT_LIST_HEAD(&target->cred_dist_list); 2576 INIT_LIST_HEAD(&target->cred_dist_list);
2565} 2577}
2566 2578
2567int ath6kl_htc_get_rxbuf_num(struct htc_target *target, 2579static int ath6kl_htc_mbox_get_rxbuf_num(struct htc_target *target,
2568 enum htc_endpoint_id endpoint) 2580 enum htc_endpoint_id endpoint)
2569{ 2581{
2570 int num; 2582 int num;
@@ -2624,7 +2636,7 @@ static void htc_setup_msg_bndl(struct htc_target *target)
2624 } 2636 }
2625} 2637}
2626 2638
2627int ath6kl_htc_wait_target(struct htc_target *target) 2639static int ath6kl_htc_mbox_wait_target(struct htc_target *target)
2628{ 2640{
2629 struct htc_packet *packet = NULL; 2641 struct htc_packet *packet = NULL;
2630 struct htc_ready_ext_msg *rdy_msg; 2642 struct htc_ready_ext_msg *rdy_msg;
@@ -2693,12 +2705,12 @@ int ath6kl_htc_wait_target(struct htc_target *target)
2693 connect.svc_id = HTC_CTRL_RSVD_SVC; 2705 connect.svc_id = HTC_CTRL_RSVD_SVC;
2694 2706
2695 /* connect fake service */ 2707 /* connect fake service */
2696 status = ath6kl_htc_conn_service((void *)target, &connect, &resp); 2708 status = ath6kl_htc_mbox_conn_service((void *)target, &connect, &resp);
2697 2709
2698 if (status) 2710 if (status)
2699 /* 2711 /*
2700 * FIXME: this call doesn't make sense, the caller should 2712 * FIXME: this call doesn't make sense, the caller should
2701 * call ath6kl_htc_cleanup() when it wants remove htc 2713 * call ath6kl_htc_mbox_cleanup() when it wants remove htc
2702 */ 2714 */
2703 ath6kl_hif_cleanup_scatter(target->dev->ar); 2715 ath6kl_hif_cleanup_scatter(target->dev->ar);
2704 2716
@@ -2715,7 +2727,7 @@ fail_wait_target:
2715 * Start HTC, enable interrupts and let the target know 2727 * Start HTC, enable interrupts and let the target know
2716 * host has finished setup. 2728 * host has finished setup.
2717 */ 2729 */
2718int ath6kl_htc_start(struct htc_target *target) 2730static int ath6kl_htc_mbox_start(struct htc_target *target)
2719{ 2731{
2720 struct htc_packet *packet; 2732 struct htc_packet *packet;
2721 int status; 2733 int status;
@@ -2752,7 +2764,7 @@ int ath6kl_htc_start(struct htc_target *target)
2752 status = ath6kl_hif_unmask_intrs(target->dev); 2764 status = ath6kl_hif_unmask_intrs(target->dev);
2753 2765
2754 if (status) 2766 if (status)
2755 ath6kl_htc_stop(target); 2767 ath6kl_htc_mbox_stop(target);
2756 2768
2757 return status; 2769 return status;
2758} 2770}
@@ -2796,7 +2808,7 @@ static int ath6kl_htc_reset(struct htc_target *target)
2796} 2808}
2797 2809
2798/* htc_stop: stop interrupt reception, and flush all queued buffers */ 2810/* htc_stop: stop interrupt reception, and flush all queued buffers */
2799void ath6kl_htc_stop(struct htc_target *target) 2811static void ath6kl_htc_mbox_stop(struct htc_target *target)
2800{ 2812{
2801 spin_lock_bh(&target->htc_lock); 2813 spin_lock_bh(&target->htc_lock);
2802 target->htc_flags |= HTC_OP_STATE_STOPPING; 2814 target->htc_flags |= HTC_OP_STATE_STOPPING;
@@ -2811,12 +2823,12 @@ void ath6kl_htc_stop(struct htc_target *target)
2811 2823
2812 ath6kl_htc_flush_txep_all(target); 2824 ath6kl_htc_flush_txep_all(target);
2813 2825
2814 ath6kl_htc_flush_rx_buf(target); 2826 ath6kl_htc_mbox_flush_rx_buf(target);
2815 2827
2816 ath6kl_htc_reset(target); 2828 ath6kl_htc_reset(target);
2817} 2829}
2818 2830
2819void *ath6kl_htc_create(struct ath6kl *ar) 2831static void *ath6kl_htc_mbox_create(struct ath6kl *ar)
2820{ 2832{
2821 struct htc_target *target = NULL; 2833 struct htc_target *target = NULL;
2822 int status = 0; 2834 int status = 0;
@@ -2857,13 +2869,13 @@ void *ath6kl_htc_create(struct ath6kl *ar)
2857 return target; 2869 return target;
2858 2870
2859err_htc_cleanup: 2871err_htc_cleanup:
2860 ath6kl_htc_cleanup(target); 2872 ath6kl_htc_mbox_cleanup(target);
2861 2873
2862 return NULL; 2874 return NULL;
2863} 2875}
2864 2876
2865/* cleanup the HTC instance */ 2877/* cleanup the HTC instance */
2866void ath6kl_htc_cleanup(struct htc_target *target) 2878static void ath6kl_htc_mbox_cleanup(struct htc_target *target)
2867{ 2879{
2868 struct htc_packet *packet, *tmp_packet; 2880 struct htc_packet *packet, *tmp_packet;
2869 2881
@@ -2888,3 +2900,24 @@ void ath6kl_htc_cleanup(struct htc_target *target)
2888 kfree(target->dev); 2900 kfree(target->dev);
2889 kfree(target); 2901 kfree(target);
2890} 2902}
2903
2904static const struct ath6kl_htc_ops ath6kl_htc_mbox_ops = {
2905 .create = ath6kl_htc_mbox_create,
2906 .wait_target = ath6kl_htc_mbox_wait_target,
2907 .start = ath6kl_htc_mbox_start,
2908 .conn_service = ath6kl_htc_mbox_conn_service,
2909 .tx = ath6kl_htc_mbox_tx,
2910 .stop = ath6kl_htc_mbox_stop,
2911 .cleanup = ath6kl_htc_mbox_cleanup,
2912 .flush_txep = ath6kl_htc_mbox_flush_txep,
2913 .flush_rx_buf = ath6kl_htc_mbox_flush_rx_buf,
2914 .activity_changed = ath6kl_htc_mbox_activity_changed,
2915 .get_rxbuf_num = ath6kl_htc_mbox_get_rxbuf_num,
2916 .add_rxbuf_multiple = ath6kl_htc_mbox_add_rxbuf_multiple,
2917 .credit_setup = ath6kl_htc_mbox_credit_setup,
2918};
2919
2920void ath6kl_htc_mbox_attach(struct ath6kl *ar)
2921{
2922 ar->htc_ops = &ath6kl_htc_mbox_ops;
2923}
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
new file mode 100644
index 000000000000..b277b3446882
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
@@ -0,0 +1,1713 @@
1/*
2 * Copyright (c) 2007-2011 Atheros Communications Inc.
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
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18#include "debug.h"
19#include "hif-ops.h"
20
21#define HTC_PACKET_CONTAINER_ALLOCATION 32
22#define HTC_CONTROL_BUFFER_SIZE (HTC_MAX_CTRL_MSG_LEN + HTC_HDR_LENGTH)
23
24static int ath6kl_htc_pipe_tx(struct htc_target *handle,
25 struct htc_packet *packet);
26static void ath6kl_htc_pipe_cleanup(struct htc_target *handle);
27
28/* htc pipe tx path */
29static inline void restore_tx_packet(struct htc_packet *packet)
30{
31 if (packet->info.tx.flags & HTC_FLAGS_TX_FIXUP_NETBUF) {
32 skb_pull(packet->skb, sizeof(struct htc_frame_hdr));
33 packet->info.tx.flags &= ~HTC_FLAGS_TX_FIXUP_NETBUF;
34 }
35}
36
37static void do_send_completion(struct htc_endpoint *ep,
38 struct list_head *queue_to_indicate)
39{
40 struct htc_packet *packet;
41
42 if (list_empty(queue_to_indicate)) {
43 /* nothing to indicate */
44 return;
45 }
46
47 if (ep->ep_cb.tx_comp_multi != NULL) {
48 ath6kl_dbg(ATH6KL_DBG_HTC,
49 "%s: calling ep %d, send complete multiple callback (%d pkts)\n",
50 __func__, ep->eid,
51 get_queue_depth(queue_to_indicate));
52 /*
53 * a multiple send complete handler is being used,
54 * pass the queue to the handler
55 */
56 ep->ep_cb.tx_comp_multi(ep->target, queue_to_indicate);
57 /*
58 * all packets are now owned by the callback,
59 * reset queue to be safe
60 */
61 INIT_LIST_HEAD(queue_to_indicate);
62 } else {
63 /* using legacy EpTxComplete */
64 do {
65 packet = list_first_entry(queue_to_indicate,
66 struct htc_packet, list);
67
68 list_del(&packet->list);
69 ath6kl_dbg(ATH6KL_DBG_HTC,
70 "%s: calling ep %d send complete callback on packet 0x%p\n",
71 __func__, ep->eid, packet);
72 ep->ep_cb.tx_complete(ep->target, packet);
73 } while (!list_empty(queue_to_indicate));
74 }
75}
76
77static void send_packet_completion(struct htc_target *target,
78 struct htc_packet *packet)
79{
80 struct htc_endpoint *ep = &target->endpoint[packet->endpoint];
81 struct list_head container;
82
83 restore_tx_packet(packet);
84 INIT_LIST_HEAD(&container);
85 list_add_tail(&packet->list, &container);
86
87 /* do completion */
88 do_send_completion(ep, &container);
89}
90
91static void get_htc_packet_credit_based(struct htc_target *target,
92 struct htc_endpoint *ep,
93 struct list_head *queue)
94{
95 int credits_required;
96 int remainder;
97 u8 send_flags;
98 struct htc_packet *packet;
99 unsigned int transfer_len;
100
101 /* NOTE : the TX lock is held when this function is called */
102
103 /* loop until we can grab as many packets out of the queue as we can */
104 while (true) {
105 send_flags = 0;
106 if (list_empty(&ep->txq))
107 break;
108
109 /* get packet at head, but don't remove it */
110 packet = list_first_entry(&ep->txq, struct htc_packet, list);
111 if (packet == NULL)
112 break;
113
114 ath6kl_dbg(ATH6KL_DBG_HTC,
115 "%s: got head packet:0x%p , queue depth: %d\n",
116 __func__, packet, get_queue_depth(&ep->txq));
117
118 transfer_len = packet->act_len + HTC_HDR_LENGTH;
119
120 if (transfer_len <= target->tgt_cred_sz) {
121 credits_required = 1;
122 } else {
123 /* figure out how many credits this message requires */
124 credits_required = transfer_len / target->tgt_cred_sz;
125 remainder = transfer_len % target->tgt_cred_sz;
126
127 if (remainder)
128 credits_required++;
129 }
130
131 ath6kl_dbg(ATH6KL_DBG_HTC, "%s: creds required:%d got:%d\n",
132 __func__, credits_required, ep->cred_dist.credits);
133
134 if (ep->eid == ENDPOINT_0) {
135 /*
136 * endpoint 0 is special, it always has a credit and
137 * does not require credit based flow control
138 */
139 credits_required = 0;
140
141 } else {
142
143 if (ep->cred_dist.credits < credits_required)
144 break;
145
146 ep->cred_dist.credits -= credits_required;
147 ep->ep_st.cred_cosumd += credits_required;
148
149 /* check if we need credits back from the target */
150 if (ep->cred_dist.credits <
151 ep->cred_dist.cred_per_msg) {
152 /* tell the target we need credits ASAP! */
153 send_flags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
154 ep->ep_st.cred_low_indicate += 1;
155 ath6kl_dbg(ATH6KL_DBG_HTC,
156 "%s: host needs credits\n",
157 __func__);
158 }
159 }
160
161 /* now we can fully dequeue */
162 packet = list_first_entry(&ep->txq, struct htc_packet, list);
163
164 list_del(&packet->list);
165 /* save the number of credits this packet consumed */
166 packet->info.tx.cred_used = credits_required;
167 /* save send flags */
168 packet->info.tx.flags = send_flags;
169 packet->info.tx.seqno = ep->seqno;
170 ep->seqno++;
171 /* queue this packet into the caller's queue */
172 list_add_tail(&packet->list, queue);
173 }
174
175}
176
177static void get_htc_packet(struct htc_target *target,
178 struct htc_endpoint *ep,
179 struct list_head *queue, int resources)
180{
181 struct htc_packet *packet;
182
183 /* NOTE : the TX lock is held when this function is called */
184
185 /* loop until we can grab as many packets out of the queue as we can */
186 while (resources) {
187 if (list_empty(&ep->txq))
188 break;
189
190 packet = list_first_entry(&ep->txq, struct htc_packet, list);
191 list_del(&packet->list);
192
193 ath6kl_dbg(ATH6KL_DBG_HTC,
194 "%s: got packet:0x%p , new queue depth: %d\n",
195 __func__, packet, get_queue_depth(&ep->txq));
196 packet->info.tx.seqno = ep->seqno;
197 packet->info.tx.flags = 0;
198 packet->info.tx.cred_used = 0;
199 ep->seqno++;
200
201 /* queue this packet into the caller's queue */
202 list_add_tail(&packet->list, queue);
203 resources--;
204 }
205}
206
207static int htc_issue_packets(struct htc_target *target,
208 struct htc_endpoint *ep,
209 struct list_head *pkt_queue)
210{
211 int status = 0;
212 u16 payload_len;
213 struct sk_buff *skb;
214 struct htc_frame_hdr *htc_hdr;
215 struct htc_packet *packet;
216
217 ath6kl_dbg(ATH6KL_DBG_HTC,
218 "%s: queue: 0x%p, pkts %d\n", __func__,
219 pkt_queue, get_queue_depth(pkt_queue));
220
221 while (!list_empty(pkt_queue)) {
222 packet = list_first_entry(pkt_queue, struct htc_packet, list);
223 list_del(&packet->list);
224
225 skb = packet->skb;
226 if (!skb) {
227 WARN_ON_ONCE(1);
228 status = -EINVAL;
229 break;
230 }
231
232 payload_len = packet->act_len;
233
234 /* setup HTC frame header */
235 htc_hdr = (struct htc_frame_hdr *) skb_push(skb,
236 sizeof(*htc_hdr));
237 if (!htc_hdr) {
238 WARN_ON_ONCE(1);
239 status = -EINVAL;
240 break;
241 }
242
243 packet->info.tx.flags |= HTC_FLAGS_TX_FIXUP_NETBUF;
244
245 /* Endianess? */
246 put_unaligned((u16) payload_len, &htc_hdr->payld_len);
247 htc_hdr->flags = packet->info.tx.flags;
248 htc_hdr->eid = (u8) packet->endpoint;
249 htc_hdr->ctrl[0] = 0;
250 htc_hdr->ctrl[1] = (u8) packet->info.tx.seqno;
251
252 spin_lock_bh(&target->tx_lock);
253
254 /* store in look up queue to match completions */
255 list_add_tail(&packet->list, &ep->pipe.tx_lookup_queue);
256 ep->ep_st.tx_issued += 1;
257 spin_unlock_bh(&target->tx_lock);
258
259 status = ath6kl_hif_pipe_send(target->dev->ar,
260 ep->pipe.pipeid_ul, NULL, skb);
261
262 if (status != 0) {
263 if (status != -ENOMEM) {
264 /* TODO: if more than 1 endpoint maps to the
265 * same PipeID, it is possible to run out of
266 * resources in the HIF layer.
267 * Don't emit the error
268 */
269 ath6kl_dbg(ATH6KL_DBG_HTC,
270 "%s: failed status:%d\n",
271 __func__, status);
272 }
273 spin_lock_bh(&target->tx_lock);
274 list_del(&packet->list);
275
276 /* reclaim credits */
277 ep->cred_dist.credits += packet->info.tx.cred_used;
278 spin_unlock_bh(&target->tx_lock);
279
280 /* put it back into the callers queue */
281 list_add(&packet->list, pkt_queue);
282 break;
283 }
284
285 }
286
287 if (status != 0) {
288 while (!list_empty(pkt_queue)) {
289 if (status != -ENOMEM) {
290 ath6kl_dbg(ATH6KL_DBG_HTC,
291 "%s: failed pkt:0x%p status:%d\n",
292 __func__, packet, status);
293 }
294
295 packet = list_first_entry(pkt_queue,
296 struct htc_packet, list);
297 list_del(&packet->list);
298 packet->status = status;
299 send_packet_completion(target, packet);
300 }
301 }
302
303 return status;
304}
305
306static enum htc_send_queue_result htc_try_send(struct htc_target *target,
307 struct htc_endpoint *ep,
308 struct list_head *txq)
309{
310 struct list_head send_queue; /* temp queue to hold packets */
311 struct htc_packet *packet, *tmp_pkt;
312 struct ath6kl *ar = target->dev->ar;
313 enum htc_send_full_action action;
314 int tx_resources, overflow, txqueue_depth, i, good_pkts;
315 u8 pipeid;
316
317 ath6kl_dbg(ATH6KL_DBG_HTC, "%s: (queue:0x%p depth:%d)\n",
318 __func__, txq,
319 (txq == NULL) ? 0 : get_queue_depth(txq));
320
321 /* init the local send queue */
322 INIT_LIST_HEAD(&send_queue);
323
324 /*
325 * txq equals to NULL means
326 * caller didn't provide a queue, just wants us to
327 * check queues and send
328 */
329 if (txq != NULL) {
330 if (list_empty(txq)) {
331 /* empty queue */
332 return HTC_SEND_QUEUE_DROP;
333 }
334
335 spin_lock_bh(&target->tx_lock);
336 txqueue_depth = get_queue_depth(&ep->txq);
337 spin_unlock_bh(&target->tx_lock);
338
339 if (txqueue_depth >= ep->max_txq_depth) {
340 /* we've already overflowed */
341 overflow = get_queue_depth(txq);
342 } else {
343 /* get how much we will overflow by */
344 overflow = txqueue_depth;
345 overflow += get_queue_depth(txq);
346 /* get how much we will overflow the TX queue by */
347 overflow -= ep->max_txq_depth;
348 }
349
350 /* if overflow is negative or zero, we are okay */
351 if (overflow > 0) {
352 ath6kl_dbg(ATH6KL_DBG_HTC,
353 "%s: Endpoint %d, TX queue will overflow :%d, Tx Depth:%d, Max:%d\n",
354 __func__, ep->eid, overflow, txqueue_depth,
355 ep->max_txq_depth);
356 }
357 if ((overflow <= 0) ||
358 (ep->ep_cb.tx_full == NULL)) {
359 /*
360 * all packets will fit or caller did not provide send
361 * full indication handler -- just move all of them
362 * to the local send_queue object
363 */
364 list_splice_tail_init(txq, &send_queue);
365 } else {
366 good_pkts = get_queue_depth(txq) - overflow;
367 if (good_pkts < 0) {
368 WARN_ON_ONCE(1);
369 return HTC_SEND_QUEUE_DROP;
370 }
371
372 /* we have overflowed, and a callback is provided */
373 /* dequeue all non-overflow packets to the sendqueue */
374 for (i = 0; i < good_pkts; i++) {
375 /* pop off caller's queue */
376 packet = list_first_entry(txq,
377 struct htc_packet,
378 list);
379 list_del(&packet->list);
380 /* insert into local queue */
381 list_add_tail(&packet->list, &send_queue);
382 }
383
384 /*
385 * the caller's queue has all the packets that won't fit
386 * walk through the caller's queue and indicate each to
387 * the send full handler
388 */
389 list_for_each_entry_safe(packet, tmp_pkt,
390 txq, list) {
391
392 ath6kl_dbg(ATH6KL_DBG_HTC,
393 "%s: Indicat overflowed TX pkts: %p\n",
394 __func__, packet);
395 action = ep->ep_cb.tx_full(ep->target, packet);
396 if (action == HTC_SEND_FULL_DROP) {
397 /* callback wants the packet dropped */
398 ep->ep_st.tx_dropped += 1;
399
400 /* leave this one in the caller's queue
401 * for cleanup */
402 } else {
403 /* callback wants to keep this packet,
404 * remove from caller's queue */
405 list_del(&packet->list);
406 /* put it in the send queue */
407 list_add_tail(&packet->list,
408 &send_queue);
409 }
410
411 }
412
413 if (list_empty(&send_queue)) {
414 /* no packets made it in, caller will cleanup */
415 return HTC_SEND_QUEUE_DROP;
416 }
417 }
418 }
419
420 if (!ep->pipe.tx_credit_flow_enabled) {
421 tx_resources =
422 ath6kl_hif_pipe_get_free_queue_number(ar,
423 ep->pipe.pipeid_ul);
424 } else {
425 tx_resources = 0;
426 }
427
428 spin_lock_bh(&target->tx_lock);
429 if (!list_empty(&send_queue)) {
430 /* transfer packets to tail */
431 list_splice_tail_init(&send_queue, &ep->txq);
432 if (!list_empty(&send_queue)) {
433 WARN_ON_ONCE(1);
434 spin_unlock_bh(&target->tx_lock);
435 return HTC_SEND_QUEUE_DROP;
436 }
437 INIT_LIST_HEAD(&send_queue);
438 }
439
440 /* increment tx processing count on entry */
441 ep->tx_proc_cnt++;
442
443 if (ep->tx_proc_cnt > 1) {
444 /*
445 * Another thread or task is draining the TX queues on this
446 * endpoint that thread will reset the tx processing count
447 * when the queue is drained.
448 */
449 ep->tx_proc_cnt--;
450 spin_unlock_bh(&target->tx_lock);
451 return HTC_SEND_QUEUE_OK;
452 }
453
454 /***** beyond this point only 1 thread may enter ******/
455
456 /*
457 * Now drain the endpoint TX queue for transmission as long as we have
458 * enough transmit resources.
459 */
460 while (true) {
461
462 if (get_queue_depth(&ep->txq) == 0)
463 break;
464
465 if (ep->pipe.tx_credit_flow_enabled) {
466 /*
467 * Credit based mechanism provides flow control
468 * based on target transmit resource availability,
469 * we assume that the HIF layer will always have
470 * bus resources greater than target transmit
471 * resources.
472 */
473 get_htc_packet_credit_based(target, ep, &send_queue);
474 } else {
475 /*
476 * Get all packets for this endpoint that we can
477 * for this pass.
478 */
479 get_htc_packet(target, ep, &send_queue, tx_resources);
480 }
481
482 if (get_queue_depth(&send_queue) == 0) {
483 /*
484 * Didn't get packets due to out of resources or TX
485 * queue was drained.
486 */
487 break;
488 }
489
490 spin_unlock_bh(&target->tx_lock);
491
492 /* send what we can */
493 htc_issue_packets(target, ep, &send_queue);
494
495 if (!ep->pipe.tx_credit_flow_enabled) {
496 pipeid = ep->pipe.pipeid_ul;
497 tx_resources =
498 ath6kl_hif_pipe_get_free_queue_number(ar, pipeid);
499 }
500
501 spin_lock_bh(&target->tx_lock);
502
503 }
504 /* done with this endpoint, we can clear the count */
505 ep->tx_proc_cnt = 0;
506 spin_unlock_bh(&target->tx_lock);
507
508 return HTC_SEND_QUEUE_OK;
509}
510
511/* htc control packet manipulation */
512static void destroy_htc_txctrl_packet(struct htc_packet *packet)
513{
514 struct sk_buff *skb;
515 skb = packet->skb;
516 if (skb != NULL)
517 dev_kfree_skb(skb);
518
519 kfree(packet);
520}
521
522static struct htc_packet *build_htc_txctrl_packet(void)
523{
524 struct htc_packet *packet = NULL;
525 struct sk_buff *skb;
526
527 packet = kzalloc(sizeof(struct htc_packet), GFP_KERNEL);
528 if (packet == NULL)
529 return NULL;
530
531 skb = __dev_alloc_skb(HTC_CONTROL_BUFFER_SIZE, GFP_KERNEL);
532
533 if (skb == NULL) {
534 kfree(packet);
535 return NULL;
536 }
537 packet->skb = skb;
538
539 return packet;
540}
541
542static void htc_free_txctrl_packet(struct htc_target *target,
543 struct htc_packet *packet)
544{
545 destroy_htc_txctrl_packet(packet);
546}
547
548static struct htc_packet *htc_alloc_txctrl_packet(struct htc_target *target)
549{
550 return build_htc_txctrl_packet();
551}
552
553static void htc_txctrl_complete(struct htc_target *target,
554 struct htc_packet *packet)
555{
556 htc_free_txctrl_packet(target, packet);
557}
558
559#define MAX_MESSAGE_SIZE 1536
560
561static int htc_setup_target_buffer_assignments(struct htc_target *target)
562{
563 int status, credits, credit_per_maxmsg, i;
564 struct htc_pipe_txcredit_alloc *entry;
565 unsigned int hif_usbaudioclass = 0;
566
567 credit_per_maxmsg = MAX_MESSAGE_SIZE / target->tgt_cred_sz;
568 if (MAX_MESSAGE_SIZE % target->tgt_cred_sz)
569 credit_per_maxmsg++;
570
571 /* TODO, this should be configured by the caller! */
572
573 credits = target->tgt_creds;
574 entry = &target->pipe.txcredit_alloc[0];
575
576 status = -ENOMEM;
577
578 /* FIXME: hif_usbaudioclass is always zero */
579 if (hif_usbaudioclass) {
580 ath6kl_dbg(ATH6KL_DBG_HTC,
581 "%s: For USB Audio Class- Total:%d\n",
582 __func__, credits);
583 entry++;
584 entry++;
585 /* Setup VO Service To have Max Credits */
586 entry->service_id = WMI_DATA_VO_SVC;
587 entry->credit_alloc = (credits - 6);
588 if (entry->credit_alloc == 0)
589 entry->credit_alloc++;
590
591 credits -= (int) entry->credit_alloc;
592 if (credits <= 0)
593 return status;
594
595 entry++;
596 entry->service_id = WMI_CONTROL_SVC;
597 entry->credit_alloc = credit_per_maxmsg;
598 credits -= (int) entry->credit_alloc;
599 if (credits <= 0)
600 return status;
601
602 /* leftovers go to best effort */
603 entry++;
604 entry++;
605 entry->service_id = WMI_DATA_BE_SVC;
606 entry->credit_alloc = (u8) credits;
607 status = 0;
608 } else {
609 entry++;
610 entry->service_id = WMI_DATA_VI_SVC;
611 entry->credit_alloc = credits / 4;
612 if (entry->credit_alloc == 0)
613 entry->credit_alloc++;
614
615 credits -= (int) entry->credit_alloc;
616 if (credits <= 0)
617 return status;
618
619 entry++;
620 entry->service_id = WMI_DATA_VO_SVC;
621 entry->credit_alloc = credits / 4;
622 if (entry->credit_alloc == 0)
623 entry->credit_alloc++;
624
625 credits -= (int) entry->credit_alloc;
626 if (credits <= 0)
627 return status;
628
629 entry++;
630 entry->service_id = WMI_CONTROL_SVC;
631 entry->credit_alloc = credit_per_maxmsg;
632 credits -= (int) entry->credit_alloc;
633 if (credits <= 0)
634 return status;
635
636 entry++;
637 entry->service_id = WMI_DATA_BK_SVC;
638 entry->credit_alloc = credit_per_maxmsg;
639 credits -= (int) entry->credit_alloc;
640 if (credits <= 0)
641 return status;
642
643 /* leftovers go to best effort */
644 entry++;
645 entry->service_id = WMI_DATA_BE_SVC;
646 entry->credit_alloc = (u8) credits;
647 status = 0;
648 }
649
650 if (status == 0) {
651 for (i = 0; i < ENDPOINT_MAX; i++) {
652 if (target->pipe.txcredit_alloc[i].service_id != 0) {
653 ath6kl_dbg(ATH6KL_DBG_HTC,
654 "HTC Service Index : %d TX : 0x%2.2X : alloc:%d\n",
655 i,
656 target->pipe.txcredit_alloc[i].
657 service_id,
658 target->pipe.txcredit_alloc[i].
659 credit_alloc);
660 }
661 }
662 }
663 return status;
664}
665
666/* process credit reports and call distribution function */
667static void htc_process_credit_report(struct htc_target *target,
668 struct htc_credit_report *rpt,
669 int num_entries,
670 enum htc_endpoint_id from_ep)
671{
672 int total_credits = 0, i;
673 struct htc_endpoint *ep;
674
675 /* lock out TX while we update credits */
676 spin_lock_bh(&target->tx_lock);
677
678 for (i = 0; i < num_entries; i++, rpt++) {
679 if (rpt->eid >= ENDPOINT_MAX) {
680 WARN_ON_ONCE(1);
681 spin_unlock_bh(&target->tx_lock);
682 return;
683 }
684
685 ep = &target->endpoint[rpt->eid];
686 ep->cred_dist.credits += rpt->credits;
687
688 if (ep->cred_dist.credits && get_queue_depth(&ep->txq)) {
689 spin_unlock_bh(&target->tx_lock);
690 htc_try_send(target, ep, NULL);
691 spin_lock_bh(&target->tx_lock);
692 }
693
694 total_credits += rpt->credits;
695 }
696 ath6kl_dbg(ATH6KL_DBG_HTC,
697 "Report indicated %d credits to distribute\n",
698 total_credits);
699
700 spin_unlock_bh(&target->tx_lock);
701}
702
703/* flush endpoint TX queue */
704static void htc_flush_tx_endpoint(struct htc_target *target,
705 struct htc_endpoint *ep, u16 tag)
706{
707 struct htc_packet *packet;
708
709 spin_lock_bh(&target->tx_lock);
710 while (get_queue_depth(&ep->txq)) {
711 packet = list_first_entry(&ep->txq, struct htc_packet, list);
712 list_del(&packet->list);
713 packet->status = 0;
714 send_packet_completion(target, packet);
715 }
716 spin_unlock_bh(&target->tx_lock);
717}
718
719/*
720 * In the adapted HIF layer, struct sk_buff * are passed between HIF and HTC,
721 * since upper layers expects struct htc_packet containers we use the completed
722 * skb and lookup it's corresponding HTC packet buffer from a lookup list.
723 * This is extra overhead that can be fixed by re-aligning HIF interfaces with
724 * HTC.
725 */
726static struct htc_packet *htc_lookup_tx_packet(struct htc_target *target,
727 struct htc_endpoint *ep,
728 struct sk_buff *skb)
729{
730 struct htc_packet *packet, *tmp_pkt, *found_packet = NULL;
731
732 spin_lock_bh(&target->tx_lock);
733
734 /*
735 * interate from the front of tx lookup queue
736 * this lookup should be fast since lower layers completes in-order and
737 * so the completed packet should be at the head of the list generally
738 */
739 list_for_each_entry_safe(packet, tmp_pkt, &ep->pipe.tx_lookup_queue,
740 list) {
741 /* check for removal */
742 if (skb == packet->skb) {
743 /* found it */
744 list_del(&packet->list);
745 found_packet = packet;
746 break;
747 }
748 }
749
750 spin_unlock_bh(&target->tx_lock);
751
752 return found_packet;
753}
754
755static int ath6kl_htc_pipe_tx_complete(struct ath6kl *ar, struct sk_buff *skb)
756{
757 struct htc_target *target = ar->htc_target;
758 struct htc_frame_hdr *htc_hdr;
759 struct htc_endpoint *ep;
760 struct htc_packet *packet;
761 u8 ep_id, *netdata;
762 u32 netlen;
763
764 netdata = skb->data;
765 netlen = skb->len;
766
767 htc_hdr = (struct htc_frame_hdr *) netdata;
768
769 ep_id = htc_hdr->eid;
770 ep = &target->endpoint[ep_id];
771
772 packet = htc_lookup_tx_packet(target, ep, skb);
773 if (packet == NULL) {
774 /* may have already been flushed and freed */
775 ath6kl_err("HTC TX lookup failed!\n");
776 } else {
777 /* will be giving this buffer back to upper layers */
778 packet->status = 0;
779 send_packet_completion(target, packet);
780 }
781 skb = NULL;
782
783 if (!ep->pipe.tx_credit_flow_enabled) {
784 /*
785 * note: when using TX credit flow, the re-checking of queues
786 * happens when credits flow back from the target. in the
787 * non-TX credit case, we recheck after the packet completes
788 */
789 htc_try_send(target, ep, NULL);
790 }
791
792 return 0;
793}
794
795static int htc_send_packets_multiple(struct htc_target *target,
796 struct list_head *pkt_queue)
797{
798 struct htc_endpoint *ep;
799 struct htc_packet *packet, *tmp_pkt;
800
801 if (list_empty(pkt_queue))
802 return -EINVAL;
803
804 /* get first packet to find out which ep the packets will go into */
805 packet = list_first_entry(pkt_queue, struct htc_packet, list);
806 if (packet == NULL)
807 return -EINVAL;
808
809 if (packet->endpoint >= ENDPOINT_MAX) {
810 WARN_ON_ONCE(1);
811 return -EINVAL;
812 }
813 ep = &target->endpoint[packet->endpoint];
814
815 htc_try_send(target, ep, pkt_queue);
816
817 /* do completion on any packets that couldn't get in */
818 if (!list_empty(pkt_queue)) {
819 list_for_each_entry_safe(packet, tmp_pkt, pkt_queue, list) {
820 packet->status = -ENOMEM;
821 }
822
823 do_send_completion(ep, pkt_queue);
824 }
825
826 return 0;
827}
828
829/* htc pipe rx path */
830static struct htc_packet *alloc_htc_packet_container(struct htc_target *target)
831{
832 struct htc_packet *packet;
833 spin_lock_bh(&target->rx_lock);
834
835 if (target->pipe.htc_packet_pool == NULL) {
836 spin_unlock_bh(&target->rx_lock);
837 return NULL;
838 }
839
840 packet = target->pipe.htc_packet_pool;
841 target->pipe.htc_packet_pool = (struct htc_packet *) packet->list.next;
842
843 spin_unlock_bh(&target->rx_lock);
844
845 packet->list.next = NULL;
846 return packet;
847}
848
849static void free_htc_packet_container(struct htc_target *target,
850 struct htc_packet *packet)
851{
852 struct list_head *lh;
853
854 spin_lock_bh(&target->rx_lock);
855
856 if (target->pipe.htc_packet_pool == NULL) {
857 target->pipe.htc_packet_pool = packet;
858 packet->list.next = NULL;
859 } else {
860 lh = (struct list_head *) target->pipe.htc_packet_pool;
861 packet->list.next = lh;
862 target->pipe.htc_packet_pool = packet;
863 }
864
865 spin_unlock_bh(&target->rx_lock);
866}
867
868static int htc_process_trailer(struct htc_target *target, u8 *buffer,
869 int len, enum htc_endpoint_id from_ep)
870{
871 struct htc_credit_report *report;
872 struct htc_record_hdr *record;
873 u8 *record_buf, *orig_buf;
874 int orig_len, status;
875
876 orig_buf = buffer;
877 orig_len = len;
878 status = 0;
879
880 while (len > 0) {
881 if (len < sizeof(struct htc_record_hdr)) {
882 status = -EINVAL;
883 break;
884 }
885
886 /* these are byte aligned structs */
887 record = (struct htc_record_hdr *) buffer;
888 len -= sizeof(struct htc_record_hdr);
889 buffer += sizeof(struct htc_record_hdr);
890
891 if (record->len > len) {
892 /* no room left in buffer for record */
893 ath6kl_dbg(ATH6KL_DBG_HTC,
894 "invalid length: %d (id:%d) buffer has: %d bytes left\n",
895 record->len, record->rec_id, len);
896 status = -EINVAL;
897 break;
898 }
899
900 /* start of record follows the header */
901 record_buf = buffer;
902
903 switch (record->rec_id) {
904 case HTC_RECORD_CREDITS:
905 if (record->len < sizeof(struct htc_credit_report)) {
906 WARN_ON_ONCE(1);
907 return -EINVAL;
908 }
909
910 report = (struct htc_credit_report *) record_buf;
911 htc_process_credit_report(target, report,
912 record->len / sizeof(*report),
913 from_ep);
914 break;
915 default:
916 ath6kl_dbg(ATH6KL_DBG_HTC,
917 "unhandled record: id:%d length:%d\n",
918 record->rec_id, record->len);
919 break;
920 }
921
922 if (status != 0)
923 break;
924
925 /* advance buffer past this record for next time around */
926 buffer += record->len;
927 len -= record->len;
928 }
929
930 return status;
931}
932
933static void do_recv_completion(struct htc_endpoint *ep,
934 struct list_head *queue_to_indicate)
935{
936 struct htc_packet *packet;
937
938 if (list_empty(queue_to_indicate)) {
939 /* nothing to indicate */
940 return;
941 }
942
943 /* using legacy EpRecv */
944 while (!list_empty(queue_to_indicate)) {
945 packet = list_first_entry(queue_to_indicate,
946 struct htc_packet, list);
947 list_del(&packet->list);
948 ep->ep_cb.rx(ep->target, packet);
949 }
950
951 return;
952}
953
954static void recv_packet_completion(struct htc_target *target,
955 struct htc_endpoint *ep,
956 struct htc_packet *packet)
957{
958 struct list_head container;
959 INIT_LIST_HEAD(&container);
960 list_add_tail(&packet->list, &container);
961
962 /* do completion */
963 do_recv_completion(ep, &container);
964}
965
966static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
967 u8 pipeid)
968{
969 struct htc_target *target = ar->htc_target;
970 u8 *netdata, *trailer, hdr_info;
971 struct htc_frame_hdr *htc_hdr;
972 u32 netlen, trailerlen = 0;
973 struct htc_packet *packet;
974 struct htc_endpoint *ep;
975 u16 payload_len;
976 int status = 0;
977
978 netdata = skb->data;
979 netlen = skb->len;
980
981 htc_hdr = (struct htc_frame_hdr *) netdata;
982
983 ep = &target->endpoint[htc_hdr->eid];
984
985 if (htc_hdr->eid >= ENDPOINT_MAX) {
986 ath6kl_dbg(ATH6KL_DBG_HTC,
987 "HTC Rx: invalid EndpointID=%d\n",
988 htc_hdr->eid);
989 status = -EINVAL;
990 goto free_skb;
991 }
992
993 payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len));
994
995 if (netlen < (payload_len + HTC_HDR_LENGTH)) {
996 ath6kl_dbg(ATH6KL_DBG_HTC,
997 "HTC Rx: insufficient length, got:%d expected =%u\n",
998 netlen, payload_len + HTC_HDR_LENGTH);
999 status = -EINVAL;
1000 goto free_skb;
1001 }
1002
1003 /* get flags to check for trailer */
1004 hdr_info = htc_hdr->flags;
1005 if (hdr_info & HTC_FLG_RX_TRAILER) {
1006 /* extract the trailer length */
1007 hdr_info = htc_hdr->ctrl[0];
1008 if ((hdr_info < sizeof(struct htc_record_hdr)) ||
1009 (hdr_info > payload_len)) {
1010 ath6kl_dbg(ATH6KL_DBG_HTC,
1011 "invalid header: payloadlen should be %d, CB[0]: %d\n",
1012 payload_len, hdr_info);
1013 status = -EINVAL;
1014 goto free_skb;
1015 }
1016
1017 trailerlen = hdr_info;
1018 /* process trailer after hdr/apps payload */
1019 trailer = (u8 *) htc_hdr + HTC_HDR_LENGTH +
1020 payload_len - hdr_info;
1021 status = htc_process_trailer(target, trailer, hdr_info,
1022 htc_hdr->eid);
1023 if (status != 0)
1024 goto free_skb;
1025 }
1026
1027 if (((int) payload_len - (int) trailerlen) <= 0) {
1028 /* zero length packet with trailer, just drop these */
1029 goto free_skb;
1030 }
1031
1032 if (htc_hdr->eid == ENDPOINT_0) {
1033 /* handle HTC control message */
1034 if (target->htc_flags & HTC_OP_STATE_SETUP_COMPLETE) {
1035 /*
1036 * fatal: target should not send unsolicited
1037 * messageson the endpoint 0
1038 */
1039 ath6kl_dbg(ATH6KL_DBG_HTC,
1040 "HTC ignores Rx Ctrl after setup complete\n");
1041 status = -EINVAL;
1042 goto free_skb;
1043 }
1044
1045 /* remove HTC header */
1046 skb_pull(skb, HTC_HDR_LENGTH);
1047
1048 netdata = skb->data;
1049 netlen = skb->len;
1050
1051 spin_lock_bh(&target->rx_lock);
1052
1053 target->pipe.ctrl_response_valid = true;
1054 target->pipe.ctrl_response_len = min_t(int, netlen,
1055 HTC_MAX_CTRL_MSG_LEN);
1056 memcpy(target->pipe.ctrl_response_buf, netdata,
1057 target->pipe.ctrl_response_len);
1058
1059 spin_unlock_bh(&target->rx_lock);
1060
1061 dev_kfree_skb(skb);
1062 skb = NULL;
1063 goto free_skb;
1064 }
1065
1066 /*
1067 * TODO: the message based HIF architecture allocates net bufs
1068 * for recv packets since it bridges that HIF to upper layers,
1069 * which expects HTC packets, we form the packets here
1070 */
1071 packet = alloc_htc_packet_container(target);
1072 if (packet == NULL) {
1073 status = -ENOMEM;
1074 goto free_skb;
1075 }
1076
1077 packet->status = 0;
1078 packet->endpoint = htc_hdr->eid;
1079 packet->pkt_cntxt = skb;
1080
1081 /* TODO: for backwards compatibility */
1082 packet->buf = skb_push(skb, 0) + HTC_HDR_LENGTH;
1083 packet->act_len = netlen - HTC_HDR_LENGTH - trailerlen;
1084
1085 /*
1086 * TODO: this is a hack because the driver layer will set the
1087 * actual len of the skb again which will just double the len
1088 */
1089 skb_trim(skb, 0);
1090
1091 recv_packet_completion(target, ep, packet);
1092
1093 /* recover the packet container */
1094 free_htc_packet_container(target, packet);
1095 skb = NULL;
1096
1097free_skb:
1098 if (skb != NULL)
1099 dev_kfree_skb(skb);
1100
1101 return status;
1102
1103}
1104
1105static void htc_flush_rx_queue(struct htc_target *target,
1106 struct htc_endpoint *ep)
1107{
1108 struct list_head container;
1109 struct htc_packet *packet;
1110
1111 spin_lock_bh(&target->rx_lock);
1112
1113 while (1) {
1114 if (list_empty(&ep->rx_bufq))
1115 break;
1116
1117 packet = list_first_entry(&ep->rx_bufq,
1118 struct htc_packet, list);
1119 list_del(&packet->list);
1120
1121 spin_unlock_bh(&target->rx_lock);
1122 packet->status = -ECANCELED;
1123 packet->act_len = 0;
1124
1125 ath6kl_dbg(ATH6KL_DBG_HTC,
1126 "Flushing RX packet:0x%p, length:%d, ep:%d\n",
1127 packet, packet->buf_len,
1128 packet->endpoint);
1129
1130 INIT_LIST_HEAD(&container);
1131 list_add_tail(&packet->list, &container);
1132
1133 /* give the packet back */
1134 do_recv_completion(ep, &container);
1135 spin_lock_bh(&target->rx_lock);
1136 }
1137
1138 spin_unlock_bh(&target->rx_lock);
1139}
1140
1141/* polling routine to wait for a control packet to be received */
1142static int htc_wait_recv_ctrl_message(struct htc_target *target)
1143{
1144 int count = HTC_TARGET_RESPONSE_POLL_COUNT;
1145
1146 while (count > 0) {
1147 spin_lock_bh(&target->rx_lock);
1148
1149 if (target->pipe.ctrl_response_valid) {
1150 target->pipe.ctrl_response_valid = false;
1151 spin_unlock_bh(&target->rx_lock);
1152 break;
1153 }
1154
1155 spin_unlock_bh(&target->rx_lock);
1156
1157 count--;
1158
1159 msleep_interruptible(HTC_TARGET_RESPONSE_POLL_WAIT);
1160 }
1161
1162 if (count <= 0) {
1163 ath6kl_dbg(ATH6KL_DBG_HTC, "%s: Timeout!\n", __func__);
1164 return -ECOMM;
1165 }
1166
1167 return 0;
1168}
1169
1170static void htc_rxctrl_complete(struct htc_target *context,
1171 struct htc_packet *packet)
1172{
1173 /* TODO, can't really receive HTC control messages yet.... */
1174 ath6kl_dbg(ATH6KL_DBG_HTC, "%s: invalid call function\n", __func__);
1175}
1176
1177/* htc pipe initialization */
1178static void reset_endpoint_states(struct htc_target *target)
1179{
1180 struct htc_endpoint *ep;
1181 int i;
1182
1183 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
1184 ep = &target->endpoint[i];
1185 ep->svc_id = 0;
1186 ep->len_max = 0;
1187 ep->max_txq_depth = 0;
1188 ep->eid = i;
1189 INIT_LIST_HEAD(&ep->txq);
1190 INIT_LIST_HEAD(&ep->pipe.tx_lookup_queue);
1191 INIT_LIST_HEAD(&ep->rx_bufq);
1192 ep->target = target;
1193 ep->pipe.tx_credit_flow_enabled = (bool) 1; /* FIXME */
1194 }
1195}
1196
1197/* start HTC, this is called after all services are connected */
1198static int htc_config_target_hif_pipe(struct htc_target *target)
1199{
1200 return 0;
1201}
1202
1203/* htc service functions */
1204static u8 htc_get_credit_alloc(struct htc_target *target, u16 service_id)
1205{
1206 u8 allocation = 0;
1207 int i;
1208
1209 for (i = 0; i < ENDPOINT_MAX; i++) {
1210 if (target->pipe.txcredit_alloc[i].service_id == service_id)
1211 allocation =
1212 target->pipe.txcredit_alloc[i].credit_alloc;
1213 }
1214
1215 if (allocation == 0) {
1216 ath6kl_dbg(ATH6KL_DBG_HTC,
1217 "HTC Service TX : 0x%2.2X : allocation is zero!\n",
1218 service_id);
1219 }
1220
1221 return allocation;
1222}
1223
1224static int ath6kl_htc_pipe_conn_service(struct htc_target *target,
1225 struct htc_service_connect_req *conn_req,
1226 struct htc_service_connect_resp *conn_resp)
1227{
1228 struct ath6kl *ar = target->dev->ar;
1229 struct htc_packet *packet = NULL;
1230 struct htc_conn_service_resp *resp_msg;
1231 struct htc_conn_service_msg *conn_msg;
1232 enum htc_endpoint_id assigned_epid = ENDPOINT_MAX;
1233 bool disable_credit_flowctrl = false;
1234 unsigned int max_msg_size = 0;
1235 struct htc_endpoint *ep;
1236 int length, status = 0;
1237 struct sk_buff *skb;
1238 u8 tx_alloc;
1239 u16 flags;
1240
1241 if (conn_req->svc_id == 0) {
1242 WARN_ON_ONCE(1);
1243 status = -EINVAL;
1244 goto free_packet;
1245 }
1246
1247 if (conn_req->svc_id == HTC_CTRL_RSVD_SVC) {
1248 /* special case for pseudo control service */
1249 assigned_epid = ENDPOINT_0;
1250 max_msg_size = HTC_MAX_CTRL_MSG_LEN;
1251 tx_alloc = 0;
1252
1253 } else {
1254
1255 tx_alloc = htc_get_credit_alloc(target, conn_req->svc_id);
1256 if (tx_alloc == 0) {
1257 status = -ENOMEM;
1258 goto free_packet;
1259 }
1260
1261 /* allocate a packet to send to the target */
1262 packet = htc_alloc_txctrl_packet(target);
1263
1264 if (packet == NULL) {
1265 WARN_ON_ONCE(1);
1266 status = -ENOMEM;
1267 goto free_packet;
1268 }
1269
1270 skb = packet->skb;
1271 length = sizeof(struct htc_conn_service_msg);
1272
1273 /* assemble connect service message */
1274 conn_msg = (struct htc_conn_service_msg *) skb_put(skb,
1275 length);
1276 if (conn_msg == NULL) {
1277 WARN_ON_ONCE(1);
1278 status = -EINVAL;
1279 goto free_packet;
1280 }
1281
1282 memset(conn_msg, 0,
1283 sizeof(struct htc_conn_service_msg));
1284 conn_msg->msg_id = cpu_to_le16(HTC_MSG_CONN_SVC_ID);
1285 conn_msg->svc_id = cpu_to_le16(conn_req->svc_id);
1286 conn_msg->conn_flags = cpu_to_le16(conn_req->conn_flags &
1287 ~HTC_CONN_FLGS_SET_RECV_ALLOC_MASK);
1288
1289 /* tell target desired recv alloc for this ep */
1290 flags = tx_alloc << HTC_CONN_FLGS_SET_RECV_ALLOC_SHIFT;
1291 conn_msg->conn_flags |= cpu_to_le16(flags);
1292
1293 if (conn_req->conn_flags &
1294 HTC_CONN_FLGS_DISABLE_CRED_FLOW_CTRL) {
1295 disable_credit_flowctrl = true;
1296 }
1297
1298 set_htc_pkt_info(packet, NULL, (u8 *) conn_msg,
1299 length,
1300 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
1301
1302 status = ath6kl_htc_pipe_tx(target, packet);
1303
1304 /* we don't own it anymore */
1305 packet = NULL;
1306 if (status != 0)
1307 goto free_packet;
1308
1309 /* wait for response */
1310 status = htc_wait_recv_ctrl_message(target);
1311 if (status != 0)
1312 goto free_packet;
1313
1314 /* we controlled the buffer creation so it has to be
1315 * properly aligned
1316 */
1317 resp_msg = (struct htc_conn_service_resp *)
1318 target->pipe.ctrl_response_buf;
1319
1320 if (resp_msg->msg_id != cpu_to_le16(HTC_MSG_CONN_SVC_RESP_ID) ||
1321 (target->pipe.ctrl_response_len < sizeof(*resp_msg))) {
1322 /* this message is not valid */
1323 WARN_ON_ONCE(1);
1324 status = -EINVAL;
1325 goto free_packet;
1326 }
1327
1328 ath6kl_dbg(ATH6KL_DBG_TRC,
1329 "%s: service 0x%X conn resp: status: %d ep: %d\n",
1330 __func__, resp_msg->svc_id, resp_msg->status,
1331 resp_msg->eid);
1332
1333 conn_resp->resp_code = resp_msg->status;
1334 /* check response status */
1335 if (resp_msg->status != HTC_SERVICE_SUCCESS) {
1336 ath6kl_dbg(ATH6KL_DBG_HTC,
1337 "Target failed service 0x%X connect request (status:%d)\n",
1338 resp_msg->svc_id, resp_msg->status);
1339 status = -EINVAL;
1340 goto free_packet;
1341 }
1342
1343 assigned_epid = (enum htc_endpoint_id) resp_msg->eid;
1344 max_msg_size = le16_to_cpu(resp_msg->max_msg_sz);
1345 }
1346
1347 /* the rest are parameter checks so set the error status */
1348 status = -EINVAL;
1349
1350 if (assigned_epid >= ENDPOINT_MAX) {
1351 WARN_ON_ONCE(1);
1352 goto free_packet;
1353 }
1354
1355 if (max_msg_size == 0) {
1356 WARN_ON_ONCE(1);
1357 goto free_packet;
1358 }
1359
1360 ep = &target->endpoint[assigned_epid];
1361 ep->eid = assigned_epid;
1362 if (ep->svc_id != 0) {
1363 /* endpoint already in use! */
1364 WARN_ON_ONCE(1);
1365 goto free_packet;
1366 }
1367
1368 /* return assigned endpoint to caller */
1369 conn_resp->endpoint = assigned_epid;
1370 conn_resp->len_max = max_msg_size;
1371
1372 /* setup the endpoint */
1373 ep->svc_id = conn_req->svc_id; /* this marks ep in use */
1374 ep->max_txq_depth = conn_req->max_txq_depth;
1375 ep->len_max = max_msg_size;
1376 ep->cred_dist.credits = tx_alloc;
1377 ep->cred_dist.cred_sz = target->tgt_cred_sz;
1378 ep->cred_dist.cred_per_msg = max_msg_size / target->tgt_cred_sz;
1379 if (max_msg_size % target->tgt_cred_sz)
1380 ep->cred_dist.cred_per_msg++;
1381
1382 /* copy all the callbacks */
1383 ep->ep_cb = conn_req->ep_cb;
1384
1385 status = ath6kl_hif_pipe_map_service(ar, ep->svc_id,
1386 &ep->pipe.pipeid_ul,
1387 &ep->pipe.pipeid_dl);
1388 if (status != 0)
1389 goto free_packet;
1390
1391 ath6kl_dbg(ATH6KL_DBG_HTC,
1392 "SVC Ready: 0x%4.4X: ULpipe:%d DLpipe:%d id:%d\n",
1393 ep->svc_id, ep->pipe.pipeid_ul,
1394 ep->pipe.pipeid_dl, ep->eid);
1395
1396 if (disable_credit_flowctrl && ep->pipe.tx_credit_flow_enabled) {
1397 ep->pipe.tx_credit_flow_enabled = false;
1398 ath6kl_dbg(ATH6KL_DBG_HTC,
1399 "SVC: 0x%4.4X ep:%d TX flow control off\n",
1400 ep->svc_id, assigned_epid);
1401 }
1402
1403free_packet:
1404 if (packet != NULL)
1405 htc_free_txctrl_packet(target, packet);
1406 return status;
1407}
1408
1409/* htc export functions */
1410static void *ath6kl_htc_pipe_create(struct ath6kl *ar)
1411{
1412 int status = 0;
1413 struct htc_endpoint *ep = NULL;
1414 struct htc_target *target = NULL;
1415 struct htc_packet *packet;
1416 int i;
1417
1418 target = kzalloc(sizeof(struct htc_target), GFP_KERNEL);
1419 if (target == NULL) {
1420 ath6kl_err("htc create unable to allocate memory\n");
1421 status = -ENOMEM;
1422 goto fail_htc_create;
1423 }
1424
1425 spin_lock_init(&target->htc_lock);
1426 spin_lock_init(&target->rx_lock);
1427 spin_lock_init(&target->tx_lock);
1428
1429 reset_endpoint_states(target);
1430
1431 for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) {
1432 packet = kzalloc(sizeof(struct htc_packet), GFP_KERNEL);
1433
1434 if (packet != NULL)
1435 free_htc_packet_container(target, packet);
1436 }
1437
1438 target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL);
1439 if (!target->dev) {
1440 ath6kl_err("unable to allocate memory\n");
1441 status = -ENOMEM;
1442 goto fail_htc_create;
1443 }
1444 target->dev->ar = ar;
1445 target->dev->htc_cnxt = target;
1446
1447 /* Get HIF default pipe for HTC message exchange */
1448 ep = &target->endpoint[ENDPOINT_0];
1449
1450 ath6kl_hif_pipe_get_default(ar, &ep->pipe.pipeid_ul,
1451 &ep->pipe.pipeid_dl);
1452
1453 return target;
1454
1455fail_htc_create:
1456 if (status != 0) {
1457 if (target != NULL)
1458 ath6kl_htc_pipe_cleanup(target);
1459
1460 target = NULL;
1461 }
1462 return target;
1463}
1464
1465/* cleanup the HTC instance */
1466static void ath6kl_htc_pipe_cleanup(struct htc_target *target)
1467{
1468 struct htc_packet *packet;
1469
1470 while (true) {
1471 packet = alloc_htc_packet_container(target);
1472 if (packet == NULL)
1473 break;
1474 kfree(packet);
1475 }
1476
1477 kfree(target->dev);
1478
1479 /* kfree our instance */
1480 kfree(target);
1481}
1482
1483static int ath6kl_htc_pipe_start(struct htc_target *target)
1484{
1485 struct sk_buff *skb;
1486 struct htc_setup_comp_ext_msg *setup;
1487 struct htc_packet *packet;
1488
1489 htc_config_target_hif_pipe(target);
1490
1491 /* allocate a buffer to send */
1492 packet = htc_alloc_txctrl_packet(target);
1493 if (packet == NULL) {
1494 WARN_ON_ONCE(1);
1495 return -ENOMEM;
1496 }
1497
1498 skb = packet->skb;
1499
1500 /* assemble setup complete message */
1501 setup = (struct htc_setup_comp_ext_msg *) skb_put(skb,
1502 sizeof(*setup));
1503 memset(setup, 0, sizeof(struct htc_setup_comp_ext_msg));
1504 setup->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_EX_ID);
1505
1506 ath6kl_dbg(ATH6KL_DBG_HTC, "HTC using TX credit flow control\n");
1507
1508 set_htc_pkt_info(packet, NULL, (u8 *) setup,
1509 sizeof(struct htc_setup_comp_ext_msg),
1510 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
1511
1512 target->htc_flags |= HTC_OP_STATE_SETUP_COMPLETE;
1513
1514 return ath6kl_htc_pipe_tx(target, packet);
1515}
1516
1517static void ath6kl_htc_pipe_stop(struct htc_target *target)
1518{
1519 int i;
1520 struct htc_endpoint *ep;
1521
1522 /* cleanup endpoints */
1523 for (i = 0; i < ENDPOINT_MAX; i++) {
1524 ep = &target->endpoint[i];
1525 htc_flush_rx_queue(target, ep);
1526 htc_flush_tx_endpoint(target, ep, HTC_TX_PACKET_TAG_ALL);
1527 }
1528
1529 reset_endpoint_states(target);
1530 target->htc_flags &= ~HTC_OP_STATE_SETUP_COMPLETE;
1531}
1532
1533static int ath6kl_htc_pipe_get_rxbuf_num(struct htc_target *target,
1534 enum htc_endpoint_id endpoint)
1535{
1536 int num;
1537
1538 spin_lock_bh(&target->rx_lock);
1539 num = get_queue_depth(&(target->endpoint[endpoint].rx_bufq));
1540 spin_unlock_bh(&target->rx_lock);
1541
1542 return num;
1543}
1544
1545static int ath6kl_htc_pipe_tx(struct htc_target *target,
1546 struct htc_packet *packet)
1547{
1548 struct list_head queue;
1549
1550 ath6kl_dbg(ATH6KL_DBG_HTC,
1551 "%s: endPointId: %d, buffer: 0x%p, length: %d\n",
1552 __func__, packet->endpoint, packet->buf,
1553 packet->act_len);
1554
1555 INIT_LIST_HEAD(&queue);
1556 list_add_tail(&packet->list, &queue);
1557
1558 return htc_send_packets_multiple(target, &queue);
1559}
1560
1561static int ath6kl_htc_pipe_wait_target(struct htc_target *target)
1562{
1563 struct htc_ready_ext_msg *ready_msg;
1564 struct htc_service_connect_req connect;
1565 struct htc_service_connect_resp resp;
1566 int status = 0;
1567
1568 status = htc_wait_recv_ctrl_message(target);
1569
1570 if (status != 0)
1571 return status;
1572
1573 if (target->pipe.ctrl_response_len < sizeof(*ready_msg)) {
1574 ath6kl_dbg(ATH6KL_DBG_HTC, "invalid htc ready msg len:%d!\n",
1575 target->pipe.ctrl_response_len);
1576 return -ECOMM;
1577 }
1578
1579 ready_msg = (struct htc_ready_ext_msg *) target->pipe.ctrl_response_buf;
1580
1581 if (ready_msg->ver2_0_info.msg_id != cpu_to_le16(HTC_MSG_READY_ID)) {
1582 ath6kl_dbg(ATH6KL_DBG_HTC, "invalid htc ready msg : 0x%X !\n",
1583 ready_msg->ver2_0_info.msg_id);
1584 return -ECOMM;
1585 }
1586
1587 ath6kl_dbg(ATH6KL_DBG_HTC,
1588 "Target Ready! : transmit resources : %d size:%d\n",
1589 ready_msg->ver2_0_info.cred_cnt,
1590 ready_msg->ver2_0_info.cred_sz);
1591
1592 target->tgt_creds = le16_to_cpu(ready_msg->ver2_0_info.cred_cnt);
1593 target->tgt_cred_sz = le16_to_cpu(ready_msg->ver2_0_info.cred_sz);
1594
1595 if ((target->tgt_creds == 0) || (target->tgt_cred_sz == 0))
1596 return -ECOMM;
1597
1598 htc_setup_target_buffer_assignments(target);
1599
1600 /* setup our pseudo HTC control endpoint connection */
1601 memset(&connect, 0, sizeof(connect));
1602 memset(&resp, 0, sizeof(resp));
1603 connect.ep_cb.tx_complete = htc_txctrl_complete;
1604 connect.ep_cb.rx = htc_rxctrl_complete;
1605 connect.max_txq_depth = NUM_CONTROL_TX_BUFFERS;
1606 connect.svc_id = HTC_CTRL_RSVD_SVC;
1607
1608 /* connect fake service */
1609 status = ath6kl_htc_pipe_conn_service(target, &connect, &resp);
1610
1611 return status;
1612}
1613
1614static void ath6kl_htc_pipe_flush_txep(struct htc_target *target,
1615 enum htc_endpoint_id endpoint, u16 tag)
1616{
1617 struct htc_endpoint *ep = &target->endpoint[endpoint];
1618
1619 if (ep->svc_id == 0) {
1620 WARN_ON_ONCE(1);
1621 /* not in use.. */
1622 return;
1623 }
1624
1625 htc_flush_tx_endpoint(target, ep, tag);
1626}
1627
1628static int ath6kl_htc_pipe_add_rxbuf_multiple(struct htc_target *target,
1629 struct list_head *pkt_queue)
1630{
1631 struct htc_packet *packet, *tmp_pkt, *first;
1632 struct htc_endpoint *ep;
1633 int status = 0;
1634
1635 if (list_empty(pkt_queue))
1636 return -EINVAL;
1637
1638 first = list_first_entry(pkt_queue, struct htc_packet, list);
1639 if (first == NULL) {
1640 WARN_ON_ONCE(1);
1641 return -EINVAL;
1642 }
1643
1644 if (first->endpoint >= ENDPOINT_MAX) {
1645 WARN_ON_ONCE(1);
1646 return -EINVAL;
1647 }
1648
1649 ath6kl_dbg(ATH6KL_DBG_HTC, "%s: epid: %d, cnt:%d, len: %d\n",
1650 __func__, first->endpoint, get_queue_depth(pkt_queue),
1651 first->buf_len);
1652
1653 ep = &target->endpoint[first->endpoint];
1654
1655 spin_lock_bh(&target->rx_lock);
1656
1657 /* store receive packets */
1658 list_splice_tail_init(pkt_queue, &ep->rx_bufq);
1659
1660 spin_unlock_bh(&target->rx_lock);
1661
1662 if (status != 0) {
1663 /* walk through queue and mark each one canceled */
1664 list_for_each_entry_safe(packet, tmp_pkt, pkt_queue, list) {
1665 packet->status = -ECANCELED;
1666 }
1667
1668 do_recv_completion(ep, pkt_queue);
1669 }
1670
1671 return status;
1672}
1673
1674static void ath6kl_htc_pipe_activity_changed(struct htc_target *target,
1675 enum htc_endpoint_id ep,
1676 bool active)
1677{
1678 /* TODO */
1679}
1680
1681static void ath6kl_htc_pipe_flush_rx_buf(struct htc_target *target)
1682{
1683 /* TODO */
1684}
1685
1686static int ath6kl_htc_pipe_credit_setup(struct htc_target *target,
1687 struct ath6kl_htc_credit_info *info)
1688{
1689 return 0;
1690}
1691
1692static const struct ath6kl_htc_ops ath6kl_htc_pipe_ops = {
1693 .create = ath6kl_htc_pipe_create,
1694 .wait_target = ath6kl_htc_pipe_wait_target,
1695 .start = ath6kl_htc_pipe_start,
1696 .conn_service = ath6kl_htc_pipe_conn_service,
1697 .tx = ath6kl_htc_pipe_tx,
1698 .stop = ath6kl_htc_pipe_stop,
1699 .cleanup = ath6kl_htc_pipe_cleanup,
1700 .flush_txep = ath6kl_htc_pipe_flush_txep,
1701 .flush_rx_buf = ath6kl_htc_pipe_flush_rx_buf,
1702 .activity_changed = ath6kl_htc_pipe_activity_changed,
1703 .get_rxbuf_num = ath6kl_htc_pipe_get_rxbuf_num,
1704 .add_rxbuf_multiple = ath6kl_htc_pipe_add_rxbuf_multiple,
1705 .credit_setup = ath6kl_htc_pipe_credit_setup,
1706 .tx_complete = ath6kl_htc_pipe_tx_complete,
1707 .rx_complete = ath6kl_htc_pipe_rx_complete,
1708};
1709
1710void ath6kl_htc_pipe_attach(struct ath6kl *ar)
1711{
1712 ar->htc_ops = &ath6kl_htc_pipe_ops;
1713}
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index eb7cc2f5b96f..29ef50ea07d5 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -23,12 +23,14 @@
23#include <linux/export.h> 23#include <linux/export.h>
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/mmc/sdio_func.h> 25#include <linux/mmc/sdio_func.h>
26#include <linux/vmalloc.h>
26 27
27#include "core.h" 28#include "core.h"
28#include "cfg80211.h" 29#include "cfg80211.h"
29#include "target.h" 30#include "target.h"
30#include "debug.h" 31#include "debug.h"
31#include "hif-ops.h" 32#include "hif-ops.h"
33#include "htc-ops.h"
32 34
33static const struct ath6kl_hw hw_list[] = { 35static const struct ath6kl_hw hw_list[] = {
34 { 36 {
@@ -258,6 +260,7 @@ static int ath6kl_init_service_ep(struct ath6kl *ar)
258 memset(&connect, 0, sizeof(connect)); 260 memset(&connect, 0, sizeof(connect));
259 261
260 /* these fields are the same for all service endpoints */ 262 /* these fields are the same for all service endpoints */
263 connect.ep_cb.tx_comp_multi = ath6kl_tx_complete;
261 connect.ep_cb.rx = ath6kl_rx; 264 connect.ep_cb.rx = ath6kl_rx;
262 connect.ep_cb.rx_refill = ath6kl_rx_refill; 265 connect.ep_cb.rx_refill = ath6kl_rx_refill;
263 connect.ep_cb.tx_full = ath6kl_tx_queue_full; 266 connect.ep_cb.tx_full = ath6kl_tx_queue_full;
@@ -487,22 +490,31 @@ int ath6kl_configure_target(struct ath6kl *ar)
487 fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS); 490 fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS);
488 491
489 /* 492 /*
490 * By default, submodes : 493 * Submodes when fw does not support dynamic interface
494 * switching:
491 * vif[0] - AP/STA/IBSS 495 * vif[0] - AP/STA/IBSS
492 * vif[1] - "P2P dev"/"P2P GO"/"P2P Client" 496 * vif[1] - "P2P dev"/"P2P GO"/"P2P Client"
493 * vif[2] - "P2P dev"/"P2P GO"/"P2P Client" 497 * vif[2] - "P2P dev"/"P2P GO"/"P2P Client"
498 * Otherwise, All the interface are initialized to p2p dev.
494 */ 499 */
495 500
496 for (i = 0; i < ar->max_norm_iface; i++) 501 if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
497 fw_submode |= HI_OPTION_FW_SUBMODE_NONE << 502 ar->fw_capabilities)) {
498 (i * HI_OPTION_FW_SUBMODE_BITS); 503 for (i = 0; i < ar->vif_max; i++)
504 fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV <<
505 (i * HI_OPTION_FW_SUBMODE_BITS);
506 } else {
507 for (i = 0; i < ar->max_norm_iface; i++)
508 fw_submode |= HI_OPTION_FW_SUBMODE_NONE <<
509 (i * HI_OPTION_FW_SUBMODE_BITS);
499 510
500 for (i = ar->max_norm_iface; i < ar->vif_max; i++) 511 for (i = ar->max_norm_iface; i < ar->vif_max; i++)
501 fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV << 512 fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV <<
502 (i * HI_OPTION_FW_SUBMODE_BITS); 513 (i * HI_OPTION_FW_SUBMODE_BITS);
503 514
504 if (ar->p2p && ar->vif_max == 1) 515 if (ar->p2p && ar->vif_max == 1)
505 fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; 516 fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV;
517 }
506 518
507 if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest, 519 if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest,
508 HTC_PROTOCOL_VERSION) != 0) { 520 HTC_PROTOCOL_VERSION) != 0) {
@@ -541,18 +553,20 @@ int ath6kl_configure_target(struct ath6kl *ar)
541 * but possible in theory. 553 * but possible in theory.
542 */ 554 */
543 555
544 param = ar->hw.board_ext_data_addr; 556 if (ar->target_type == TARGET_TYPE_AR6003) {
545 ram_reserved_size = ar->hw.reserved_ram_size; 557 param = ar->hw.board_ext_data_addr;
558 ram_reserved_size = ar->hw.reserved_ram_size;
546 559
547 if (ath6kl_bmi_write_hi32(ar, hi_board_ext_data, param) != 0) { 560 if (ath6kl_bmi_write_hi32(ar, hi_board_ext_data, param) != 0) {
548 ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n"); 561 ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
549 return -EIO; 562 return -EIO;
550 } 563 }
551 564
552 if (ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 565 if (ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz,
553 ram_reserved_size) != 0) { 566 ram_reserved_size) != 0) {
554 ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n"); 567 ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
555 return -EIO; 568 return -EIO;
569 }
556 } 570 }
557 571
558 /* set the block size for the target */ 572 /* set the block size for the target */
@@ -926,13 +940,14 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
926 if (ar->fw != NULL) 940 if (ar->fw != NULL)
927 break; 941 break;
928 942
929 ar->fw = kmemdup(data, ie_len, GFP_KERNEL); 943 ar->fw = vmalloc(ie_len);
930 944
931 if (ar->fw == NULL) { 945 if (ar->fw == NULL) {
932 ret = -ENOMEM; 946 ret = -ENOMEM;
933 goto out; 947 goto out;
934 } 948 }
935 949
950 memcpy(ar->fw, data, ie_len);
936 ar->fw_len = ie_len; 951 ar->fw_len = ie_len;
937 break; 952 break;
938 case ATH6KL_FW_IE_PATCH_IMAGE: 953 case ATH6KL_FW_IE_PATCH_IMAGE:
@@ -1509,7 +1524,7 @@ int ath6kl_init_hw_start(struct ath6kl *ar)
1509 } 1524 }
1510 1525
1511 /* setup credit distribution */ 1526 /* setup credit distribution */
1512 ath6kl_credit_setup(ar->htc_target, &ar->credit_state_info); 1527 ath6kl_htc_credit_setup(ar->htc_target, &ar->credit_state_info);
1513 1528
1514 /* start HTC */ 1529 /* start HTC */
1515 ret = ath6kl_htc_start(ar->htc_target); 1530 ret = ath6kl_htc_start(ar->htc_target);
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 07071fce8a0e..4d818f96c415 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -758,6 +758,10 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
758 stats->wow_evt_discarded += 758 stats->wow_evt_discarded +=
759 le16_to_cpu(tgt_stats->wow_stats.wow_evt_discarded); 759 le16_to_cpu(tgt_stats->wow_stats.wow_evt_discarded);
760 760
761 stats->arp_received = le32_to_cpu(tgt_stats->arp_stats.arp_received);
762 stats->arp_replied = le32_to_cpu(tgt_stats->arp_stats.arp_replied);
763 stats->arp_matched = le32_to_cpu(tgt_stats->arp_stats.arp_matched);
764
761 if (test_bit(STATS_UPDATE_PEND, &vif->flags)) { 765 if (test_bit(STATS_UPDATE_PEND, &vif->flags)) {
762 clear_bit(STATS_UPDATE_PEND, &vif->flags); 766 clear_bit(STATS_UPDATE_PEND, &vif->flags);
763 wake_up(&ar->event_wq); 767 wake_up(&ar->event_wq);
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 53528648b425..44ea7a742101 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -1362,7 +1362,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
1362 goto err_core_alloc; 1362 goto err_core_alloc;
1363 } 1363 }
1364 1364
1365 ret = ath6kl_core_init(ar); 1365 ret = ath6kl_core_init(ar, ATH6KL_HTC_TYPE_MBOX);
1366 if (ret) { 1366 if (ret) {
1367 ath6kl_err("Failed to init ath6kl core\n"); 1367 ath6kl_err("Failed to init ath6kl core\n");
1368 goto err_core_alloc; 1368 goto err_core_alloc;
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 521f0be990f1..82f2f5cb475b 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -19,6 +19,7 @@
19 19
20#include "core.h" 20#include "core.h"
21#include "debug.h" 21#include "debug.h"
22#include "htc-ops.h"
22 23
23/* 24/*
24 * tid - tid_mux0..tid_mux3 25 * tid - tid_mux0..tid_mux3
@@ -324,6 +325,7 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
324 cookie->map_no = 0; 325 cookie->map_no = 0;
325 set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len, 326 set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
326 eid, ATH6KL_CONTROL_PKT_TAG); 327 eid, ATH6KL_CONTROL_PKT_TAG);
328 cookie->htc_pkt.skb = skb;
327 329
328 /* 330 /*
329 * This interface is asynchronous, if there is an error, cleanup 331 * This interface is asynchronous, if there is an error, cleanup
@@ -492,6 +494,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
492 cookie->map_no = map_no; 494 cookie->map_no = map_no;
493 set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len, 495 set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
494 eid, htc_tag); 496 eid, htc_tag);
497 cookie->htc_pkt.skb = skb;
495 498
496 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "tx ", 499 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "tx ",
497 skb->data, skb->len); 500 skb->data, skb->len);
@@ -572,7 +575,7 @@ void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active)
572 575
573notify_htc: 576notify_htc:
574 /* notify HTC, this may cause credit distribution changes */ 577 /* notify HTC, this may cause credit distribution changes */
575 ath6kl_htc_indicate_activity_change(ar->htc_target, eid, active); 578 ath6kl_htc_activity_changed(ar->htc_target, eid, active);
576} 579}
577 580
578enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, 581enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
@@ -668,9 +671,10 @@ static void ath6kl_tx_clear_node_map(struct ath6kl_vif *vif,
668 } 671 }
669} 672}
670 673
671void ath6kl_tx_complete(void *context, struct list_head *packet_queue) 674void ath6kl_tx_complete(struct htc_target *target,
675 struct list_head *packet_queue)
672{ 676{
673 struct ath6kl *ar = context; 677 struct ath6kl *ar = target->dev->ar;
674 struct sk_buff_head skb_queue; 678 struct sk_buff_head skb_queue;
675 struct htc_packet *packet; 679 struct htc_packet *packet;
676 struct sk_buff *skb; 680 struct sk_buff *skb;
@@ -889,6 +893,7 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
889 skb->data = PTR_ALIGN(skb->data - 4, 4); 893 skb->data = PTR_ALIGN(skb->data - 4, 4);
890 set_htc_rxpkt_info(packet, skb, skb->data, 894 set_htc_rxpkt_info(packet, skb, skb->data,
891 ATH6KL_BUFFER_SIZE, endpoint); 895 ATH6KL_BUFFER_SIZE, endpoint);
896 packet->skb = skb;
892 list_add_tail(&packet->list, &queue); 897 list_add_tail(&packet->list, &queue);
893 } 898 }
894 899
@@ -911,6 +916,8 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
911 skb->data = PTR_ALIGN(skb->data - 4, 4); 916 skb->data = PTR_ALIGN(skb->data - 4, 4);
912 set_htc_rxpkt_info(packet, skb, skb->data, 917 set_htc_rxpkt_info(packet, skb, skb->data,
913 ATH6KL_AMSDU_BUFFER_SIZE, 0); 918 ATH6KL_AMSDU_BUFFER_SIZE, 0);
919 packet->skb = skb;
920
914 spin_lock_bh(&ar->lock); 921 spin_lock_bh(&ar->lock);
915 list_add_tail(&packet->list, &ar->amsdu_rx_buffer_queue); 922 list_add_tail(&packet->list, &ar->amsdu_rx_buffer_queue);
916 spin_unlock_bh(&ar->lock); 923 spin_unlock_bh(&ar->lock);
@@ -1283,6 +1290,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1283 struct wmi_data_hdr *dhdr; 1290 struct wmi_data_hdr *dhdr;
1284 int min_hdr_len; 1291 int min_hdr_len;
1285 u8 meta_type, dot11_hdr = 0; 1292 u8 meta_type, dot11_hdr = 0;
1293 u8 pad_before_data_start;
1286 int status = packet->status; 1294 int status = packet->status;
1287 enum htc_endpoint_id ept = packet->endpoint; 1295 enum htc_endpoint_id ept = packet->endpoint;
1288 bool is_amsdu, prev_ps, ps_state = false; 1296 bool is_amsdu, prev_ps, ps_state = false;
@@ -1494,6 +1502,10 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1494 seq_no = wmi_data_hdr_get_seqno(dhdr); 1502 seq_no = wmi_data_hdr_get_seqno(dhdr);
1495 meta_type = wmi_data_hdr_get_meta(dhdr); 1503 meta_type = wmi_data_hdr_get_meta(dhdr);
1496 dot11_hdr = wmi_data_hdr_get_dot11(dhdr); 1504 dot11_hdr = wmi_data_hdr_get_dot11(dhdr);
1505 pad_before_data_start =
1506 (le16_to_cpu(dhdr->info3) >> WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT)
1507 & WMI_DATA_HDR_PAD_BEFORE_DATA_MASK;
1508
1497 skb_pull(skb, sizeof(struct wmi_data_hdr)); 1509 skb_pull(skb, sizeof(struct wmi_data_hdr));
1498 1510
1499 switch (meta_type) { 1511 switch (meta_type) {
@@ -1512,6 +1524,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1512 break; 1524 break;
1513 } 1525 }
1514 1526
1527 skb_pull(skb, pad_before_data_start);
1528
1515 if (dot11_hdr) 1529 if (dot11_hdr)
1516 status = ath6kl_wmi_dot11_hdr_remove(ar->wmi, skb); 1530 status = ath6kl_wmi_dot11_hdr_remove(ar->wmi, skb);
1517 else if (!is_amsdu) 1531 else if (!is_amsdu)
@@ -1581,7 +1595,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1581 /* aggregation code will handle the skb */ 1595 /* aggregation code will handle the skb */
1582 return; 1596 return;
1583 } 1597 }
1584 } 1598 } else if (!is_broadcast_ether_addr(datap->h_dest))
1599 vif->net_stats.multicast++;
1585 1600
1586 ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); 1601 ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb);
1587} 1602}
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index 325b1224c2b1..ec7f1f5fd1ca 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -21,15 +21,77 @@
21#include "debug.h" 21#include "debug.h"
22#include "core.h" 22#include "core.h"
23 23
24/* constants */
25#define TX_URB_COUNT 32
26#define RX_URB_COUNT 32
27#define ATH6KL_USB_RX_BUFFER_SIZE 1700
28
29/* tx/rx pipes for usb */
30enum ATH6KL_USB_PIPE_ID {
31 ATH6KL_USB_PIPE_TX_CTRL = 0,
32 ATH6KL_USB_PIPE_TX_DATA_LP,
33 ATH6KL_USB_PIPE_TX_DATA_MP,
34 ATH6KL_USB_PIPE_TX_DATA_HP,
35 ATH6KL_USB_PIPE_RX_CTRL,
36 ATH6KL_USB_PIPE_RX_DATA,
37 ATH6KL_USB_PIPE_RX_DATA2,
38 ATH6KL_USB_PIPE_RX_INT,
39 ATH6KL_USB_PIPE_MAX
40};
41
42#define ATH6KL_USB_PIPE_INVALID ATH6KL_USB_PIPE_MAX
43
44struct ath6kl_usb_pipe {
45 struct list_head urb_list_head;
46 struct usb_anchor urb_submitted;
47 u32 urb_alloc;
48 u32 urb_cnt;
49 u32 urb_cnt_thresh;
50 unsigned int usb_pipe_handle;
51 u32 flags;
52 u8 ep_address;
53 u8 logical_pipe_num;
54 struct ath6kl_usb *ar_usb;
55 u16 max_packet_size;
56 struct work_struct io_complete_work;
57 struct sk_buff_head io_comp_queue;
58 struct usb_endpoint_descriptor *ep_desc;
59};
60
61#define ATH6KL_USB_PIPE_FLAG_TX (1 << 0)
62
24/* usb device object */ 63/* usb device object */
25struct ath6kl_usb { 64struct ath6kl_usb {
65 /* protects pipe->urb_list_head and pipe->urb_cnt */
66 spinlock_t cs_lock;
67
26 struct usb_device *udev; 68 struct usb_device *udev;
27 struct usb_interface *interface; 69 struct usb_interface *interface;
70 struct ath6kl_usb_pipe pipes[ATH6KL_USB_PIPE_MAX];
28 u8 *diag_cmd_buffer; 71 u8 *diag_cmd_buffer;
29 u8 *diag_resp_buffer; 72 u8 *diag_resp_buffer;
30 struct ath6kl *ar; 73 struct ath6kl *ar;
31}; 74};
32 75
76/* usb urb object */
77struct ath6kl_urb_context {
78 struct list_head link;
79 struct ath6kl_usb_pipe *pipe;
80 struct sk_buff *skb;
81 struct ath6kl *ar;
82};
83
84/* USB endpoint definitions */
85#define ATH6KL_USB_EP_ADDR_APP_CTRL_IN 0x81
86#define ATH6KL_USB_EP_ADDR_APP_DATA_IN 0x82
87#define ATH6KL_USB_EP_ADDR_APP_DATA2_IN 0x83
88#define ATH6KL_USB_EP_ADDR_APP_INT_IN 0x84
89
90#define ATH6KL_USB_EP_ADDR_APP_CTRL_OUT 0x01
91#define ATH6KL_USB_EP_ADDR_APP_DATA_LP_OUT 0x02
92#define ATH6KL_USB_EP_ADDR_APP_DATA_MP_OUT 0x03
93#define ATH6KL_USB_EP_ADDR_APP_DATA_HP_OUT 0x04
94
33/* diagnostic command defnitions */ 95/* diagnostic command defnitions */
34#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD 1 96#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD 1
35#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP 2 97#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP 2
@@ -55,11 +117,493 @@ struct ath6kl_usb_ctrl_diag_resp_read {
55 __le32 value; 117 __le32 value;
56} __packed; 118} __packed;
57 119
120/* function declarations */
121static void ath6kl_usb_recv_complete(struct urb *urb);
122
123#define ATH6KL_USB_IS_BULK_EP(attr) (((attr) & 3) == 0x02)
124#define ATH6KL_USB_IS_INT_EP(attr) (((attr) & 3) == 0x03)
125#define ATH6KL_USB_IS_ISOC_EP(attr) (((attr) & 3) == 0x01)
126#define ATH6KL_USB_IS_DIR_IN(addr) ((addr) & 0x80)
127
128/* pipe/urb operations */
129static struct ath6kl_urb_context *
130ath6kl_usb_alloc_urb_from_pipe(struct ath6kl_usb_pipe *pipe)
131{
132 struct ath6kl_urb_context *urb_context = NULL;
133 unsigned long flags;
134
135 spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags);
136 if (!list_empty(&pipe->urb_list_head)) {
137 urb_context =
138 list_first_entry(&pipe->urb_list_head,
139 struct ath6kl_urb_context, link);
140 list_del(&urb_context->link);
141 pipe->urb_cnt--;
142 }
143 spin_unlock_irqrestore(&pipe->ar_usb->cs_lock, flags);
144
145 return urb_context;
146}
147
148static void ath6kl_usb_free_urb_to_pipe(struct ath6kl_usb_pipe *pipe,
149 struct ath6kl_urb_context *urb_context)
150{
151 unsigned long flags;
152
153 spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags);
154 pipe->urb_cnt++;
155
156 list_add(&urb_context->link, &pipe->urb_list_head);
157 spin_unlock_irqrestore(&pipe->ar_usb->cs_lock, flags);
158}
159
160static void ath6kl_usb_cleanup_recv_urb(struct ath6kl_urb_context *urb_context)
161{
162 if (urb_context->skb != NULL) {
163 dev_kfree_skb(urb_context->skb);
164 urb_context->skb = NULL;
165 }
166
167 ath6kl_usb_free_urb_to_pipe(urb_context->pipe, urb_context);
168}
169
170static inline struct ath6kl_usb *ath6kl_usb_priv(struct ath6kl *ar)
171{
172 return ar->hif_priv;
173}
174
175/* pipe resource allocation/cleanup */
176static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe,
177 int urb_cnt)
178{
179 struct ath6kl_urb_context *urb_context;
180 int status = 0, i;
181
182 INIT_LIST_HEAD(&pipe->urb_list_head);
183 init_usb_anchor(&pipe->urb_submitted);
184
185 for (i = 0; i < urb_cnt; i++) {
186 urb_context = kzalloc(sizeof(struct ath6kl_urb_context),
187 GFP_KERNEL);
188 if (urb_context == NULL)
189 /* FIXME: set status to -ENOMEM */
190 break;
191
192 urb_context->pipe = pipe;
193
194 /*
195 * we are only allocate the urb contexts here, the actual URB
196 * is allocated from the kernel as needed to do a transaction
197 */
198 pipe->urb_alloc++;
199 ath6kl_usb_free_urb_to_pipe(pipe, urb_context);
200 }
201
202 ath6kl_dbg(ATH6KL_DBG_USB,
203 "ath6kl usb: alloc resources lpipe:%d hpipe:0x%X urbs:%d\n",
204 pipe->logical_pipe_num, pipe->usb_pipe_handle,
205 pipe->urb_alloc);
206
207 return status;
208}
209
210static void ath6kl_usb_free_pipe_resources(struct ath6kl_usb_pipe *pipe)
211{
212 struct ath6kl_urb_context *urb_context;
213
214 if (pipe->ar_usb == NULL) {
215 /* nothing allocated for this pipe */
216 return;
217 }
218
219 ath6kl_dbg(ATH6KL_DBG_USB,
220 "ath6kl usb: free resources lpipe:%d"
221 "hpipe:0x%X urbs:%d avail:%d\n",
222 pipe->logical_pipe_num, pipe->usb_pipe_handle,
223 pipe->urb_alloc, pipe->urb_cnt);
224
225 if (pipe->urb_alloc != pipe->urb_cnt) {
226 ath6kl_dbg(ATH6KL_DBG_USB,
227 "ath6kl usb: urb leak! lpipe:%d"
228 "hpipe:0x%X urbs:%d avail:%d\n",
229 pipe->logical_pipe_num, pipe->usb_pipe_handle,
230 pipe->urb_alloc, pipe->urb_cnt);
231 }
232
233 while (true) {
234 urb_context = ath6kl_usb_alloc_urb_from_pipe(pipe);
235 if (urb_context == NULL)
236 break;
237 kfree(urb_context);
238 }
239
240}
241
242static void ath6kl_usb_cleanup_pipe_resources(struct ath6kl_usb *ar_usb)
243{
244 int i;
245
246 for (i = 0; i < ATH6KL_USB_PIPE_MAX; i++)
247 ath6kl_usb_free_pipe_resources(&ar_usb->pipes[i]);
248
249}
250
251static u8 ath6kl_usb_get_logical_pipe_num(struct ath6kl_usb *ar_usb,
252 u8 ep_address, int *urb_count)
253{
254 u8 pipe_num = ATH6KL_USB_PIPE_INVALID;
255
256 switch (ep_address) {
257 case ATH6KL_USB_EP_ADDR_APP_CTRL_IN:
258 pipe_num = ATH6KL_USB_PIPE_RX_CTRL;
259 *urb_count = RX_URB_COUNT;
260 break;
261 case ATH6KL_USB_EP_ADDR_APP_DATA_IN:
262 pipe_num = ATH6KL_USB_PIPE_RX_DATA;
263 *urb_count = RX_URB_COUNT;
264 break;
265 case ATH6KL_USB_EP_ADDR_APP_INT_IN:
266 pipe_num = ATH6KL_USB_PIPE_RX_INT;
267 *urb_count = RX_URB_COUNT;
268 break;
269 case ATH6KL_USB_EP_ADDR_APP_DATA2_IN:
270 pipe_num = ATH6KL_USB_PIPE_RX_DATA2;
271 *urb_count = RX_URB_COUNT;
272 break;
273 case ATH6KL_USB_EP_ADDR_APP_CTRL_OUT:
274 pipe_num = ATH6KL_USB_PIPE_TX_CTRL;
275 *urb_count = TX_URB_COUNT;
276 break;
277 case ATH6KL_USB_EP_ADDR_APP_DATA_LP_OUT:
278 pipe_num = ATH6KL_USB_PIPE_TX_DATA_LP;
279 *urb_count = TX_URB_COUNT;
280 break;
281 case ATH6KL_USB_EP_ADDR_APP_DATA_MP_OUT:
282 pipe_num = ATH6KL_USB_PIPE_TX_DATA_MP;
283 *urb_count = TX_URB_COUNT;
284 break;
285 case ATH6KL_USB_EP_ADDR_APP_DATA_HP_OUT:
286 pipe_num = ATH6KL_USB_PIPE_TX_DATA_HP;
287 *urb_count = TX_URB_COUNT;
288 break;
289 default:
290 /* note: there may be endpoints not currently used */
291 break;
292 }
293
294 return pipe_num;
295}
296
297static int ath6kl_usb_setup_pipe_resources(struct ath6kl_usb *ar_usb)
298{
299 struct usb_interface *interface = ar_usb->interface;
300 struct usb_host_interface *iface_desc = interface->cur_altsetting;
301 struct usb_endpoint_descriptor *endpoint;
302 struct ath6kl_usb_pipe *pipe;
303 int i, urbcount, status = 0;
304 u8 pipe_num;
305
306 ath6kl_dbg(ATH6KL_DBG_USB, "setting up USB Pipes using interface\n");
307
308 /* walk decriptors and setup pipes */
309 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
310 endpoint = &iface_desc->endpoint[i].desc;
311
312 if (ATH6KL_USB_IS_BULK_EP(endpoint->bmAttributes)) {
313 ath6kl_dbg(ATH6KL_DBG_USB,
314 "%s Bulk Ep:0x%2.2X maxpktsz:%d\n",
315 ATH6KL_USB_IS_DIR_IN
316 (endpoint->bEndpointAddress) ?
317 "RX" : "TX", endpoint->bEndpointAddress,
318 le16_to_cpu(endpoint->wMaxPacketSize));
319 } else if (ATH6KL_USB_IS_INT_EP(endpoint->bmAttributes)) {
320 ath6kl_dbg(ATH6KL_DBG_USB,
321 "%s Int Ep:0x%2.2X maxpktsz:%d interval:%d\n",
322 ATH6KL_USB_IS_DIR_IN
323 (endpoint->bEndpointAddress) ?
324 "RX" : "TX", endpoint->bEndpointAddress,
325 le16_to_cpu(endpoint->wMaxPacketSize),
326 endpoint->bInterval);
327 } else if (ATH6KL_USB_IS_ISOC_EP(endpoint->bmAttributes)) {
328 /* TODO for ISO */
329 ath6kl_dbg(ATH6KL_DBG_USB,
330 "%s ISOC Ep:0x%2.2X maxpktsz:%d interval:%d\n",
331 ATH6KL_USB_IS_DIR_IN
332 (endpoint->bEndpointAddress) ?
333 "RX" : "TX", endpoint->bEndpointAddress,
334 le16_to_cpu(endpoint->wMaxPacketSize),
335 endpoint->bInterval);
336 }
337 urbcount = 0;
338
339 pipe_num =
340 ath6kl_usb_get_logical_pipe_num(ar_usb,
341 endpoint->bEndpointAddress,
342 &urbcount);
343 if (pipe_num == ATH6KL_USB_PIPE_INVALID)
344 continue;
345
346 pipe = &ar_usb->pipes[pipe_num];
347 if (pipe->ar_usb != NULL) {
348 /* hmmm..pipe was already setup */
349 continue;
350 }
351
352 pipe->ar_usb = ar_usb;
353 pipe->logical_pipe_num = pipe_num;
354 pipe->ep_address = endpoint->bEndpointAddress;
355 pipe->max_packet_size = le16_to_cpu(endpoint->wMaxPacketSize);
356
357 if (ATH6KL_USB_IS_BULK_EP(endpoint->bmAttributes)) {
358 if (ATH6KL_USB_IS_DIR_IN(pipe->ep_address)) {
359 pipe->usb_pipe_handle =
360 usb_rcvbulkpipe(ar_usb->udev,
361 pipe->ep_address);
362 } else {
363 pipe->usb_pipe_handle =
364 usb_sndbulkpipe(ar_usb->udev,
365 pipe->ep_address);
366 }
367 } else if (ATH6KL_USB_IS_INT_EP(endpoint->bmAttributes)) {
368 if (ATH6KL_USB_IS_DIR_IN(pipe->ep_address)) {
369 pipe->usb_pipe_handle =
370 usb_rcvintpipe(ar_usb->udev,
371 pipe->ep_address);
372 } else {
373 pipe->usb_pipe_handle =
374 usb_sndintpipe(ar_usb->udev,
375 pipe->ep_address);
376 }
377 } else if (ATH6KL_USB_IS_ISOC_EP(endpoint->bmAttributes)) {
378 /* TODO for ISO */
379 if (ATH6KL_USB_IS_DIR_IN(pipe->ep_address)) {
380 pipe->usb_pipe_handle =
381 usb_rcvisocpipe(ar_usb->udev,
382 pipe->ep_address);
383 } else {
384 pipe->usb_pipe_handle =
385 usb_sndisocpipe(ar_usb->udev,
386 pipe->ep_address);
387 }
388 }
389
390 pipe->ep_desc = endpoint;
391
392 if (!ATH6KL_USB_IS_DIR_IN(pipe->ep_address))
393 pipe->flags |= ATH6KL_USB_PIPE_FLAG_TX;
394
395 status = ath6kl_usb_alloc_pipe_resources(pipe, urbcount);
396 if (status != 0)
397 break;
398 }
399
400 return status;
401}
402
403/* pipe operations */
404static void ath6kl_usb_post_recv_transfers(struct ath6kl_usb_pipe *recv_pipe,
405 int buffer_length)
406{
407 struct ath6kl_urb_context *urb_context;
408 struct urb *urb;
409 int usb_status;
410
411 while (true) {
412 urb_context = ath6kl_usb_alloc_urb_from_pipe(recv_pipe);
413 if (urb_context == NULL)
414 break;
415
416 urb_context->skb = dev_alloc_skb(buffer_length);
417 if (urb_context->skb == NULL)
418 goto err_cleanup_urb;
419
420 urb = usb_alloc_urb(0, GFP_ATOMIC);
421 if (urb == NULL)
422 goto err_cleanup_urb;
423
424 usb_fill_bulk_urb(urb,
425 recv_pipe->ar_usb->udev,
426 recv_pipe->usb_pipe_handle,
427 urb_context->skb->data,
428 buffer_length,
429 ath6kl_usb_recv_complete, urb_context);
430
431 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
432 "ath6kl usb: bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes buf:0x%p\n",
433 recv_pipe->logical_pipe_num,
434 recv_pipe->usb_pipe_handle, recv_pipe->ep_address,
435 buffer_length, urb_context->skb);
436
437 usb_anchor_urb(urb, &recv_pipe->urb_submitted);
438 usb_status = usb_submit_urb(urb, GFP_ATOMIC);
439
440 if (usb_status) {
441 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
442 "ath6kl usb : usb bulk recv failed %d\n",
443 usb_status);
444 usb_unanchor_urb(urb);
445 usb_free_urb(urb);
446 goto err_cleanup_urb;
447 }
448 usb_free_urb(urb);
449 }
450 return;
451
452err_cleanup_urb:
453 ath6kl_usb_cleanup_recv_urb(urb_context);
454 return;
455}
456
457static void ath6kl_usb_flush_all(struct ath6kl_usb *ar_usb)
458{
459 int i;
460
461 for (i = 0; i < ATH6KL_USB_PIPE_MAX; i++) {
462 if (ar_usb->pipes[i].ar_usb != NULL)
463 usb_kill_anchored_urbs(&ar_usb->pipes[i].urb_submitted);
464 }
465
466 /*
467 * Flushing any pending I/O may schedule work this call will block
468 * until all scheduled work runs to completion.
469 */
470 flush_scheduled_work();
471}
472
473static void ath6kl_usb_start_recv_pipes(struct ath6kl_usb *ar_usb)
474{
475 /*
476 * note: control pipe is no longer used
477 * ar_usb->pipes[ATH6KL_USB_PIPE_RX_CTRL].urb_cnt_thresh =
478 * ar_usb->pipes[ATH6KL_USB_PIPE_RX_CTRL].urb_alloc/2;
479 * ath6kl_usb_post_recv_transfers(&ar_usb->
480 * pipes[ATH6KL_USB_PIPE_RX_CTRL],
481 * ATH6KL_USB_RX_BUFFER_SIZE);
482 */
483
484 ar_usb->pipes[ATH6KL_USB_PIPE_RX_DATA].urb_cnt_thresh =
485 ar_usb->pipes[ATH6KL_USB_PIPE_RX_DATA].urb_alloc / 2;
486 ath6kl_usb_post_recv_transfers(&ar_usb->pipes[ATH6KL_USB_PIPE_RX_DATA],
487 ATH6KL_USB_RX_BUFFER_SIZE);
488}
489
490/* hif usb rx/tx completion functions */
491static void ath6kl_usb_recv_complete(struct urb *urb)
492{
493 struct ath6kl_urb_context *urb_context = urb->context;
494 struct ath6kl_usb_pipe *pipe = urb_context->pipe;
495 struct sk_buff *skb = NULL;
496 int status = 0;
497
498 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
499 "%s: recv pipe: %d, stat:%d, len:%d urb:0x%p\n", __func__,
500 pipe->logical_pipe_num, urb->status, urb->actual_length,
501 urb);
502
503 if (urb->status != 0) {
504 status = -EIO;
505 switch (urb->status) {
506 case -ECONNRESET:
507 case -ENOENT:
508 case -ESHUTDOWN:
509 /*
510 * no need to spew these errors when device
511 * removed or urb killed due to driver shutdown
512 */
513 status = -ECANCELED;
514 break;
515 default:
516 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
517 "%s recv pipe: %d (ep:0x%2.2X), failed:%d\n",
518 __func__, pipe->logical_pipe_num,
519 pipe->ep_address, urb->status);
520 break;
521 }
522 goto cleanup_recv_urb;
523 }
524
525 if (urb->actual_length == 0)
526 goto cleanup_recv_urb;
527
528 skb = urb_context->skb;
529
530 /* we are going to pass it up */
531 urb_context->skb = NULL;
532 skb_put(skb, urb->actual_length);
533
534 /* note: queue implements a lock */
535 skb_queue_tail(&pipe->io_comp_queue, skb);
536 schedule_work(&pipe->io_complete_work);
537
538cleanup_recv_urb:
539 ath6kl_usb_cleanup_recv_urb(urb_context);
540
541 if (status == 0 &&
542 pipe->urb_cnt >= pipe->urb_cnt_thresh) {
543 /* our free urbs are piling up, post more transfers */
544 ath6kl_usb_post_recv_transfers(pipe, ATH6KL_USB_RX_BUFFER_SIZE);
545 }
546}
547
548static void ath6kl_usb_usb_transmit_complete(struct urb *urb)
549{
550 struct ath6kl_urb_context *urb_context = urb->context;
551 struct ath6kl_usb_pipe *pipe = urb_context->pipe;
552 struct sk_buff *skb;
553
554 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
555 "%s: pipe: %d, stat:%d, len:%d\n",
556 __func__, pipe->logical_pipe_num, urb->status,
557 urb->actual_length);
558
559 if (urb->status != 0) {
560 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
561 "%s: pipe: %d, failed:%d\n",
562 __func__, pipe->logical_pipe_num, urb->status);
563 }
564
565 skb = urb_context->skb;
566 urb_context->skb = NULL;
567 ath6kl_usb_free_urb_to_pipe(urb_context->pipe, urb_context);
568
569 /* note: queue implements a lock */
570 skb_queue_tail(&pipe->io_comp_queue, skb);
571 schedule_work(&pipe->io_complete_work);
572}
573
574static void ath6kl_usb_io_comp_work(struct work_struct *work)
575{
576 struct ath6kl_usb_pipe *pipe = container_of(work,
577 struct ath6kl_usb_pipe,
578 io_complete_work);
579 struct ath6kl_usb *ar_usb;
580 struct sk_buff *skb;
581
582 ar_usb = pipe->ar_usb;
583
584 while ((skb = skb_dequeue(&pipe->io_comp_queue))) {
585 if (pipe->flags & ATH6KL_USB_PIPE_FLAG_TX) {
586 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
587 "ath6kl usb xmit callback buf:0x%p\n", skb);
588 ath6kl_core_tx_complete(ar_usb->ar, skb);
589 } else {
590 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
591 "ath6kl usb recv callback buf:0x%p\n", skb);
592 ath6kl_core_rx_complete(ar_usb->ar, skb,
593 pipe->logical_pipe_num);
594 }
595 }
596}
597
58#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)) 598#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write))
59#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read)) 599#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read))
60 600
61static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb) 601static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb)
62{ 602{
603 ath6kl_usb_flush_all(ar_usb);
604
605 ath6kl_usb_cleanup_pipe_resources(ar_usb);
606
63 usb_set_intfdata(ar_usb->interface, NULL); 607 usb_set_intfdata(ar_usb->interface, NULL);
64 608
65 kfree(ar_usb->diag_cmd_buffer); 609 kfree(ar_usb->diag_cmd_buffer);
@@ -70,19 +614,28 @@ static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb)
70 614
71static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface) 615static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface)
72{ 616{
73 struct ath6kl_usb *ar_usb = NULL;
74 struct usb_device *dev = interface_to_usbdev(interface); 617 struct usb_device *dev = interface_to_usbdev(interface);
618 struct ath6kl_usb *ar_usb;
619 struct ath6kl_usb_pipe *pipe;
75 int status = 0; 620 int status = 0;
621 int i;
76 622
77 ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL); 623 ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL);
78 if (ar_usb == NULL) 624 if (ar_usb == NULL)
79 goto fail_ath6kl_usb_create; 625 goto fail_ath6kl_usb_create;
80 626
81 memset(ar_usb, 0, sizeof(struct ath6kl_usb));
82 usb_set_intfdata(interface, ar_usb); 627 usb_set_intfdata(interface, ar_usb);
628 spin_lock_init(&(ar_usb->cs_lock));
83 ar_usb->udev = dev; 629 ar_usb->udev = dev;
84 ar_usb->interface = interface; 630 ar_usb->interface = interface;
85 631
632 for (i = 0; i < ATH6KL_USB_PIPE_MAX; i++) {
633 pipe = &ar_usb->pipes[i];
634 INIT_WORK(&pipe->io_complete_work,
635 ath6kl_usb_io_comp_work);
636 skb_queue_head_init(&pipe->io_comp_queue);
637 }
638
86 ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL); 639 ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL);
87 if (ar_usb->diag_cmd_buffer == NULL) { 640 if (ar_usb->diag_cmd_buffer == NULL) {
88 status = -ENOMEM; 641 status = -ENOMEM;
@@ -96,6 +649,8 @@ static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface)
96 goto fail_ath6kl_usb_create; 649 goto fail_ath6kl_usb_create;
97 } 650 }
98 651
652 status = ath6kl_usb_setup_pipe_resources(ar_usb);
653
99fail_ath6kl_usb_create: 654fail_ath6kl_usb_create:
100 if (status != 0) { 655 if (status != 0) {
101 ath6kl_usb_destroy(ar_usb); 656 ath6kl_usb_destroy(ar_usb);
@@ -114,11 +669,177 @@ static void ath6kl_usb_device_detached(struct usb_interface *interface)
114 669
115 ath6kl_stop_txrx(ar_usb->ar); 670 ath6kl_stop_txrx(ar_usb->ar);
116 671
672 /* Delay to wait for the target to reboot */
673 mdelay(20);
117 ath6kl_core_cleanup(ar_usb->ar); 674 ath6kl_core_cleanup(ar_usb->ar);
118
119 ath6kl_usb_destroy(ar_usb); 675 ath6kl_usb_destroy(ar_usb);
120} 676}
121 677
678/* exported hif usb APIs for htc pipe */
679static void hif_start(struct ath6kl *ar)
680{
681 struct ath6kl_usb *device = ath6kl_usb_priv(ar);
682 int i;
683
684 ath6kl_usb_start_recv_pipes(device);
685
686 /* set the TX resource avail threshold for each TX pipe */
687 for (i = ATH6KL_USB_PIPE_TX_CTRL;
688 i <= ATH6KL_USB_PIPE_TX_DATA_HP; i++) {
689 device->pipes[i].urb_cnt_thresh =
690 device->pipes[i].urb_alloc / 2;
691 }
692}
693
694static int ath6kl_usb_send(struct ath6kl *ar, u8 PipeID,
695 struct sk_buff *hdr_skb, struct sk_buff *skb)
696{
697 struct ath6kl_usb *device = ath6kl_usb_priv(ar);
698 struct ath6kl_usb_pipe *pipe = &device->pipes[PipeID];
699 struct ath6kl_urb_context *urb_context;
700 int usb_status, status = 0;
701 struct urb *urb;
702 u8 *data;
703 u32 len;
704
705 ath6kl_dbg(ATH6KL_DBG_USB_BULK, "+%s pipe : %d, buf:0x%p\n",
706 __func__, PipeID, skb);
707
708 urb_context = ath6kl_usb_alloc_urb_from_pipe(pipe);
709
710 if (urb_context == NULL) {
711 /*
712 * TODO: it is possible to run out of urbs if
713 * 2 endpoints map to the same pipe ID
714 */
715 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
716 "%s pipe:%d no urbs left. URB Cnt : %d\n",
717 __func__, PipeID, pipe->urb_cnt);
718 status = -ENOMEM;
719 goto fail_hif_send;
720 }
721
722 urb_context->skb = skb;
723
724 data = skb->data;
725 len = skb->len;
726
727 urb = usb_alloc_urb(0, GFP_ATOMIC);
728 if (urb == NULL) {
729 status = -ENOMEM;
730 ath6kl_usb_free_urb_to_pipe(urb_context->pipe,
731 urb_context);
732 goto fail_hif_send;
733 }
734
735 usb_fill_bulk_urb(urb,
736 device->udev,
737 pipe->usb_pipe_handle,
738 data,
739 len,
740 ath6kl_usb_usb_transmit_complete, urb_context);
741
742 if ((len % pipe->max_packet_size) == 0) {
743 /* hit a max packet boundary on this pipe */
744 urb->transfer_flags |= URB_ZERO_PACKET;
745 }
746
747 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
748 "athusb bulk send submit:%d, 0x%X (ep:0x%2.2X), %d bytes\n",
749 pipe->logical_pipe_num, pipe->usb_pipe_handle,
750 pipe->ep_address, len);
751
752 usb_anchor_urb(urb, &pipe->urb_submitted);
753 usb_status = usb_submit_urb(urb, GFP_ATOMIC);
754
755 if (usb_status) {
756 ath6kl_dbg(ATH6KL_DBG_USB_BULK,
757 "ath6kl usb : usb bulk transmit failed %d\n",
758 usb_status);
759 usb_unanchor_urb(urb);
760 ath6kl_usb_free_urb_to_pipe(urb_context->pipe,
761 urb_context);
762 status = -EINVAL;
763 }
764 usb_free_urb(urb);
765
766fail_hif_send:
767 return status;
768}
769
770static void hif_stop(struct ath6kl *ar)
771{
772 struct ath6kl_usb *device = ath6kl_usb_priv(ar);
773
774 ath6kl_usb_flush_all(device);
775}
776
777static void ath6kl_usb_get_default_pipe(struct ath6kl *ar,
778 u8 *ul_pipe, u8 *dl_pipe)
779{
780 *ul_pipe = ATH6KL_USB_PIPE_TX_CTRL;
781 *dl_pipe = ATH6KL_USB_PIPE_RX_CTRL;
782}
783
784static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
785 u8 *ul_pipe, u8 *dl_pipe)
786{
787 int status = 0;
788
789 switch (svc_id) {
790 case HTC_CTRL_RSVD_SVC:
791 case WMI_CONTROL_SVC:
792 *ul_pipe = ATH6KL_USB_PIPE_TX_CTRL;
793 /* due to large control packets, shift to data pipe */
794 *dl_pipe = ATH6KL_USB_PIPE_RX_DATA;
795 break;
796 case WMI_DATA_BE_SVC:
797 case WMI_DATA_BK_SVC:
798 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
799 /*
800 * Disable rxdata2 directly, it will be enabled
801 * if FW enable rxdata2
802 */
803 *dl_pipe = ATH6KL_USB_PIPE_RX_DATA;
804 break;
805 case WMI_DATA_VI_SVC:
806 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
807 /*
808 * Disable rxdata2 directly, it will be enabled
809 * if FW enable rxdata2
810 */
811 *dl_pipe = ATH6KL_USB_PIPE_RX_DATA;
812 break;
813 case WMI_DATA_VO_SVC:
814 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_HP;
815 /*
816 * Disable rxdata2 directly, it will be enabled
817 * if FW enable rxdata2
818 */
819 *dl_pipe = ATH6KL_USB_PIPE_RX_DATA;
820 break;
821 default:
822 status = -EPERM;
823 break;
824 }
825
826 return status;
827}
828
829static u16 ath6kl_usb_get_free_queue_number(struct ath6kl *ar, u8 pipe_id)
830{
831 struct ath6kl_usb *device = ath6kl_usb_priv(ar);
832
833 return device->pipes[pipe_id].urb_cnt;
834}
835
836static void hif_detach_htc(struct ath6kl *ar)
837{
838 struct ath6kl_usb *device = ath6kl_usb_priv(ar);
839
840 ath6kl_usb_flush_all(device);
841}
842
122static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb, 843static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
123 u8 req, u16 value, u16 index, void *data, 844 u8 req, u16 value, u16 index, void *data,
124 u32 size) 845 u32 size)
@@ -301,14 +1022,21 @@ static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
301 1022
302static int ath6kl_usb_power_on(struct ath6kl *ar) 1023static int ath6kl_usb_power_on(struct ath6kl *ar)
303{ 1024{
1025 hif_start(ar);
304 return 0; 1026 return 0;
305} 1027}
306 1028
307static int ath6kl_usb_power_off(struct ath6kl *ar) 1029static int ath6kl_usb_power_off(struct ath6kl *ar)
308{ 1030{
1031 hif_detach_htc(ar);
309 return 0; 1032 return 0;
310} 1033}
311 1034
1035static void ath6kl_usb_stop(struct ath6kl *ar)
1036{
1037 hif_stop(ar);
1038}
1039
312static const struct ath6kl_hif_ops ath6kl_usb_ops = { 1040static const struct ath6kl_hif_ops ath6kl_usb_ops = {
313 .diag_read32 = ath6kl_usb_diag_read32, 1041 .diag_read32 = ath6kl_usb_diag_read32,
314 .diag_write32 = ath6kl_usb_diag_write32, 1042 .diag_write32 = ath6kl_usb_diag_write32,
@@ -316,6 +1044,11 @@ static const struct ath6kl_hif_ops ath6kl_usb_ops = {
316 .bmi_write = ath6kl_usb_bmi_write, 1044 .bmi_write = ath6kl_usb_bmi_write,
317 .power_on = ath6kl_usb_power_on, 1045 .power_on = ath6kl_usb_power_on,
318 .power_off = ath6kl_usb_power_off, 1046 .power_off = ath6kl_usb_power_off,
1047 .stop = ath6kl_usb_stop,
1048 .pipe_send = ath6kl_usb_send,
1049 .pipe_get_default = ath6kl_usb_get_default_pipe,
1050 .pipe_map_service = ath6kl_usb_map_service_pipe,
1051 .pipe_get_free_queue_number = ath6kl_usb_get_free_queue_number,
319}; 1052};
320 1053
321/* ath6kl usb driver registered functions */ 1054/* ath6kl usb driver registered functions */
@@ -368,7 +1101,7 @@ static int ath6kl_usb_probe(struct usb_interface *interface,
368 1101
369 ar_usb->ar = ar; 1102 ar_usb->ar = ar;
370 1103
371 ret = ath6kl_core_init(ar); 1104 ret = ath6kl_core_init(ar, ATH6KL_HTC_TYPE_PIPE);
372 if (ret) { 1105 if (ret) {
373 ath6kl_err("Failed to init ath6kl core: %d\n", ret); 1106 ath6kl_err("Failed to init ath6kl core: %d\n", ret);
374 goto err_core_free; 1107 goto err_core_free;
@@ -392,6 +1125,46 @@ static void ath6kl_usb_remove(struct usb_interface *interface)
392 ath6kl_usb_device_detached(interface); 1125 ath6kl_usb_device_detached(interface);
393} 1126}
394 1127
1128#ifdef CONFIG_PM
1129
1130static int ath6kl_usb_suspend(struct usb_interface *interface,
1131 pm_message_t message)
1132{
1133 struct ath6kl_usb *device;
1134 device = usb_get_intfdata(interface);
1135
1136 ath6kl_usb_flush_all(device);
1137 return 0;
1138}
1139
1140static int ath6kl_usb_resume(struct usb_interface *interface)
1141{
1142 struct ath6kl_usb *device;
1143 device = usb_get_intfdata(interface);
1144
1145 ath6kl_usb_post_recv_transfers(&device->pipes[ATH6KL_USB_PIPE_RX_DATA],
1146 ATH6KL_USB_RX_BUFFER_SIZE);
1147 ath6kl_usb_post_recv_transfers(&device->pipes[ATH6KL_USB_PIPE_RX_DATA2],
1148 ATH6KL_USB_RX_BUFFER_SIZE);
1149
1150 return 0;
1151}
1152
1153static int ath6kl_usb_reset_resume(struct usb_interface *intf)
1154{
1155 if (usb_get_intfdata(intf))
1156 ath6kl_usb_remove(intf);
1157 return 0;
1158}
1159
1160#else
1161
1162#define ath6kl_usb_suspend NULL
1163#define ath6kl_usb_resume NULL
1164#define ath6kl_usb_reset_resume NULL
1165
1166#endif
1167
395/* table of devices that work with this driver */ 1168/* table of devices that work with this driver */
396static struct usb_device_id ath6kl_usb_ids[] = { 1169static struct usb_device_id ath6kl_usb_ids[] = {
397 {USB_DEVICE(0x0cf3, 0x9374)}, 1170 {USB_DEVICE(0x0cf3, 0x9374)},
@@ -403,8 +1176,12 @@ MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids);
403static struct usb_driver ath6kl_usb_driver = { 1176static struct usb_driver ath6kl_usb_driver = {
404 .name = "ath6kl_usb", 1177 .name = "ath6kl_usb",
405 .probe = ath6kl_usb_probe, 1178 .probe = ath6kl_usb_probe,
1179 .suspend = ath6kl_usb_suspend,
1180 .resume = ath6kl_usb_resume,
1181 .reset_resume = ath6kl_usb_reset_resume,
406 .disconnect = ath6kl_usb_remove, 1182 .disconnect = ath6kl_usb_remove,
407 .id_table = ath6kl_usb_ids, 1183 .id_table = ath6kl_usb_ids,
1184 .supports_autosuspend = true,
408}; 1185};
409 1186
410static int ath6kl_usb_init(void) 1187static int ath6kl_usb_init(void)
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 2b442332cd0f..7c8a9977faf5 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -2882,6 +2882,43 @@ int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx,
2882 return ret; 2882 return ret;
2883} 2883}
2884 2884
2885int ath6kl_wmi_set_htcap_cmd(struct wmi *wmi, u8 if_idx,
2886 enum ieee80211_band band,
2887 struct ath6kl_htcap *htcap)
2888{
2889 struct sk_buff *skb;
2890 struct wmi_set_htcap_cmd *cmd;
2891
2892 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2893 if (!skb)
2894 return -ENOMEM;
2895
2896 cmd = (struct wmi_set_htcap_cmd *) skb->data;
2897
2898 /*
2899 * NOTE: Band in firmware matches enum ieee80211_band, it is unlikely
2900 * this will be changed in firmware. If at all there is any change in
2901 * band value, the host needs to be fixed.
2902 */
2903 cmd->band = band;
2904 cmd->ht_enable = !!htcap->ht_enable;
2905 cmd->ht20_sgi = !!(htcap->cap_info & IEEE80211_HT_CAP_SGI_20);
2906 cmd->ht40_supported =
2907 !!(htcap->cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
2908 cmd->ht40_sgi = !!(htcap->cap_info & IEEE80211_HT_CAP_SGI_40);
2909 cmd->intolerant_40mhz =
2910 !!(htcap->cap_info & IEEE80211_HT_CAP_40MHZ_INTOLERANT);
2911 cmd->max_ampdu_len_exp = htcap->ampdu_factor;
2912
2913 ath6kl_dbg(ATH6KL_DBG_WMI,
2914 "Set htcap: band:%d ht_enable:%d 40mhz:%d sgi_20mhz:%d sgi_40mhz:%d 40mhz_intolerant:%d ampdu_len_exp:%d\n",
2915 cmd->band, cmd->ht_enable, cmd->ht40_supported,
2916 cmd->ht20_sgi, cmd->ht40_sgi, cmd->intolerant_40mhz,
2917 cmd->max_ampdu_len_exp);
2918 return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_HT_CAP_CMDID,
2919 NO_SYNC_WMIFLAG);
2920}
2921
2885int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len) 2922int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len)
2886{ 2923{
2887 struct sk_buff *skb; 2924 struct sk_buff *skb;
@@ -3032,6 +3069,9 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
3032 cm->reason = cpu_to_le16(reason); 3069 cm->reason = cpu_to_le16(reason);
3033 cm->cmd = cmd; 3070 cm->cmd = cmd;
3034 3071
3072 ath6kl_dbg(ATH6KL_DBG_WMI, "ap_set_mlme: cmd=%d reason=%d\n", cm->cmd,
3073 cm->reason);
3074
3035 return ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_SET_MLME_CMDID, 3075 return ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_SET_MLME_CMDID,
3036 NO_SYNC_WMIFLAG); 3076 NO_SYNC_WMIFLAG);
3037} 3077}
@@ -3181,6 +3221,29 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
3181 NO_SYNC_WMIFLAG); 3221 NO_SYNC_WMIFLAG);
3182} 3222}
3183 3223
3224int ath6kl_wmi_set_ie_cmd(struct wmi *wmi, u8 if_idx, u8 ie_id, u8 ie_field,
3225 const u8 *ie_info, u8 ie_len)
3226{
3227 struct sk_buff *skb;
3228 struct wmi_set_ie_cmd *p;
3229
3230 skb = ath6kl_wmi_get_new_buf(sizeof(*p) + ie_len);
3231 if (!skb)
3232 return -ENOMEM;
3233
3234 ath6kl_dbg(ATH6KL_DBG_WMI, "set_ie_cmd: ie_id=%u ie_ie_field=%u ie_len=%u\n",
3235 ie_id, ie_field, ie_len);
3236 p = (struct wmi_set_ie_cmd *) skb->data;
3237 p->ie_id = ie_id;
3238 p->ie_field = ie_field;
3239 p->ie_len = ie_len;
3240 if (ie_info && ie_len > 0)
3241 memcpy(p->ie_info, ie_info, ie_len);
3242
3243 return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_IE_CMDID,
3244 NO_SYNC_WMIFLAG);
3245}
3246
3184int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable) 3247int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable)
3185{ 3248{
3186 struct sk_buff *skb; 3249 struct sk_buff *skb;
@@ -3392,6 +3455,23 @@ int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx)
3392 WMI_CANCEL_REMAIN_ON_CHNL_CMDID); 3455 WMI_CANCEL_REMAIN_ON_CHNL_CMDID);
3393} 3456}
3394 3457
3458int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout)
3459{
3460 struct sk_buff *skb;
3461 struct wmi_set_inact_period_cmd *cmd;
3462
3463 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
3464 if (!skb)
3465 return -ENOMEM;
3466
3467 cmd = (struct wmi_set_inact_period_cmd *) skb->data;
3468 cmd->inact_period = cpu_to_le32(inact_timeout);
3469 cmd->num_null_func = 0;
3470
3471 return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_CONN_INACT_CMDID,
3472 NO_SYNC_WMIFLAG);
3473}
3474
3395static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) 3475static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
3396{ 3476{
3397 struct wmix_cmd_hdr *cmd; 3477 struct wmix_cmd_hdr *cmd;
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 4092e3e80790..d3d2ab5c1689 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -182,6 +182,9 @@ enum wmi_data_hdr_flags {
182#define WMI_DATA_HDR_META_MASK 0x7 182#define WMI_DATA_HDR_META_MASK 0x7
183#define WMI_DATA_HDR_META_SHIFT 13 183#define WMI_DATA_HDR_META_SHIFT 13
184 184
185#define WMI_DATA_HDR_PAD_BEFORE_DATA_MASK 0xFF
186#define WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT 0x8
187
185/* Macros for operating on WMI_DATA_HDR (info3) field */ 188/* Macros for operating on WMI_DATA_HDR (info3) field */
186#define WMI_DATA_HDR_IF_IDX_MASK 0xF 189#define WMI_DATA_HDR_IF_IDX_MASK 0xF
187 190
@@ -423,6 +426,7 @@ enum wmi_cmd_id {
423 WMI_SET_FRAMERATES_CMDID, 426 WMI_SET_FRAMERATES_CMDID,
424 WMI_SET_AP_PS_CMDID, 427 WMI_SET_AP_PS_CMDID,
425 WMI_SET_QOS_SUPP_CMDID, 428 WMI_SET_QOS_SUPP_CMDID,
429 WMI_SET_IE_CMDID,
426 430
427 /* WMI_THIN_RESERVED_... mark the start and end 431 /* WMI_THIN_RESERVED_... mark the start and end
428 * values for WMI_THIN_RESERVED command IDs. These 432 * values for WMI_THIN_RESERVED command IDs. These
@@ -629,6 +633,11 @@ enum wmi_mgmt_frame_type {
629 WMI_NUM_MGMT_FRAME 633 WMI_NUM_MGMT_FRAME
630}; 634};
631 635
636enum wmi_ie_field_type {
637 WMI_RSN_IE_CAPB = 0x1,
638 WMI_IE_FULL = 0xFF, /* indicats full IE */
639};
640
632/* WMI_CONNECT_CMDID */ 641/* WMI_CONNECT_CMDID */
633enum network_type { 642enum network_type {
634 INFRA_NETWORK = 0x01, 643 INFRA_NETWORK = 0x01,
@@ -1268,6 +1277,16 @@ struct wmi_mcast_filter_add_del_cmd {
1268 u8 mcast_mac[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE]; 1277 u8 mcast_mac[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
1269} __packed; 1278} __packed;
1270 1279
1280struct wmi_set_htcap_cmd {
1281 u8 band;
1282 u8 ht_enable;
1283 u8 ht40_supported;
1284 u8 ht20_sgi;
1285 u8 ht40_sgi;
1286 u8 intolerant_40mhz;
1287 u8 max_ampdu_len_exp;
1288} __packed;
1289
1271/* Command Replies */ 1290/* Command Replies */
1272 1291
1273/* WMI_GET_CHANNEL_LIST_CMDID reply */ 1292/* WMI_GET_CHANNEL_LIST_CMDID reply */
@@ -1913,6 +1932,14 @@ struct wmi_set_appie_cmd {
1913 u8 ie_info[0]; 1932 u8 ie_info[0];
1914} __packed; 1933} __packed;
1915 1934
1935struct wmi_set_ie_cmd {
1936 u8 ie_id;
1937 u8 ie_field; /* enum wmi_ie_field_type */
1938 u8 ie_len;
1939 u8 reserved;
1940 u8 ie_info[0];
1941} __packed;
1942
1916/* Notify the WSC registration status to the target */ 1943/* Notify the WSC registration status to the target */
1917#define WSC_REG_ACTIVE 1 1944#define WSC_REG_ACTIVE 1
1918#define WSC_REG_INACTIVE 0 1945#define WSC_REG_INACTIVE 0
@@ -2141,6 +2168,11 @@ struct wmi_ap_hidden_ssid_cmd {
2141 u8 hidden_ssid; 2168 u8 hidden_ssid;
2142} __packed; 2169} __packed;
2143 2170
2171struct wmi_set_inact_period_cmd {
2172 __le32 inact_period;
2173 u8 num_null_func;
2174} __packed;
2175
2144/* AP mode events */ 2176/* AP mode events */
2145struct wmi_ap_set_apsd_cmd { 2177struct wmi_ap_set_apsd_cmd {
2146 u8 enable; 2178 u8 enable;
@@ -2465,6 +2497,9 @@ int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi);
2465int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, u8 if_idx, enum wmi_txop_cfg cfg); 2497int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, u8 if_idx, enum wmi_txop_cfg cfg);
2466int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx, 2498int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx,
2467 u8 keep_alive_intvl); 2499 u8 keep_alive_intvl);
2500int ath6kl_wmi_set_htcap_cmd(struct wmi *wmi, u8 if_idx,
2501 enum ieee80211_band band,
2502 struct ath6kl_htcap *htcap);
2468int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len); 2503int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
2469 2504
2470s32 ath6kl_wmi_get_rate(s8 rate_index); 2505s32 ath6kl_wmi_get_rate(s8 rate_index);
@@ -2515,6 +2550,9 @@ int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 if_idx,
2515int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, 2550int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
2516 const u8 *ie, u8 ie_len); 2551 const u8 *ie, u8 ie_len);
2517 2552
2553int ath6kl_wmi_set_ie_cmd(struct wmi *wmi, u8 if_idx, u8 ie_id, u8 ie_field,
2554 const u8 *ie_info, u8 ie_len);
2555
2518/* P2P */ 2556/* P2P */
2519int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable); 2557int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable);
2520 2558
@@ -2538,6 +2576,8 @@ int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx);
2538int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, 2576int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
2539 const u8 *ie, u8 ie_len); 2577 const u8 *ie, u8 ie_len);
2540 2578
2579int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout);
2580
2541void ath6kl_wmi_sscan_timer(unsigned long ptr); 2581void ath6kl_wmi_sscan_timer(unsigned long ptr);
2542 2582
2543struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx); 2583struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx);
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 47a9fb4a116a..b4c77f9d7470 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -274,7 +274,9 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
274 aniState->rssiThrLow, aniState->rssiThrHigh); 274 aniState->rssiThrLow, aniState->rssiThrHigh);
275 275
276 if (aniState->update_ani) 276 if (aniState->update_ani)
277 aniState->ofdmNoiseImmunityLevel = immunityLevel; 277 aniState->ofdmNoiseImmunityLevel =
278 (immunityLevel > ATH9K_ANI_OFDM_DEF_LEVEL) ?
279 immunityLevel : ATH9K_ANI_OFDM_DEF_LEVEL;
278 280
279 entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; 281 entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
280 entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; 282 entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
@@ -340,7 +342,9 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
340 immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; 342 immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
341 343
342 if (aniState->update_ani) 344 if (aniState->update_ani)
343 aniState->cckNoiseImmunityLevel = immunityLevel; 345 aniState->cckNoiseImmunityLevel =
346 (immunityLevel > ATH9K_ANI_CCK_DEF_LEVEL) ?
347 immunityLevel : ATH9K_ANI_CCK_DEF_LEVEL;
344 348
345 entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; 349 entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
346 entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; 350 entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 52ff5caf2d0b..de30cb34b8f3 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -245,7 +245,6 @@ static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
245 REG_WRITE(ah, AR_PHY(0x37), reg32); 245 REG_WRITE(ah, AR_PHY(0x37), reg32);
246 246
247 ah->curchan = chan; 247 ah->curchan = chan;
248 ah->curchan_rad_index = -1;
249 248
250 return 0; 249 return 0;
251} 250}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index aa2abaf31cba..8d78253c26ce 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -136,6 +136,7 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
136 } 136 }
137 137
138 if (sync_cause) { 138 if (sync_cause) {
139 ath9k_debug_sync_cause(common, sync_cause);
139 fatal_int = 140 fatal_int =
140 (sync_cause & 141 (sync_cause &
141 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) 142 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index 3cbbb033fcea..846dd7974eb8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -152,7 +152,6 @@ static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
152 REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); 152 REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
153 153
154 ah->curchan = chan; 154 ah->curchan = chan;
155 ah->curchan_rad_index = -1;
156 155
157 return 0; 156 return 0;
158} 157}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 6bb4db052bb0..1188db205e32 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -30,11 +30,6 @@
30#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) 30#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
31#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) 31#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
32#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) 32#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
33#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
34#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
35#define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */
36#define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */
37#define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */
38 33
39#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 34#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
40#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 35#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
@@ -2936,15 +2931,6 @@ static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2936#undef N_LOOP 2931#undef N_LOOP
2937} 2932}
2938 2933
2939
2940static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
2941{
2942 if (fbin == AR5416_BCHAN_UNUSED)
2943 return fbin;
2944
2945 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
2946}
2947
2948static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) 2934static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2949{ 2935{
2950 return 0; 2936 return 0;
@@ -4070,7 +4056,7 @@ static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4070 * targetpower piers stored on eeprom 4056 * targetpower piers stored on eeprom
4071 */ 4057 */
4072 for (i = 0; i < numPiers; i++) { 4058 for (i = 0; i < numPiers; i++) {
4073 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); 4059 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4074 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; 4060 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4075 } 4061 }
4076 4062
@@ -4106,7 +4092,7 @@ static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4106 * from targetpower piers stored on eeprom 4092 * from targetpower piers stored on eeprom
4107 */ 4093 */
4108 for (i = 0; i < numPiers; i++) { 4094 for (i = 0; i < numPiers; i++) {
4109 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); 4095 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4110 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; 4096 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4111 } 4097 }
4112 4098
@@ -4142,7 +4128,7 @@ static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4142 * targetpower piers stored on eeprom 4128 * targetpower piers stored on eeprom
4143 */ 4129 */
4144 for (i = 0; i < numPiers; i++) { 4130 for (i = 0; i < numPiers; i++) {
4145 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); 4131 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4146 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; 4132 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4147 } 4133 }
4148 4134
@@ -4167,7 +4153,7 @@ static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4167 * targetpower piers stored on eeprom 4153 * targetpower piers stored on eeprom
4168 */ 4154 */
4169 for (i = 0; i < numPiers; i++) { 4155 for (i = 0; i < numPiers; i++) {
4170 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1); 4156 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4171 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; 4157 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4172 } 4158 }
4173 4159
@@ -4464,7 +4450,7 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4464 is2GHz = 1; 4450 is2GHz = 1;
4465 } 4451 }
4466 4452
4467 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz); 4453 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4468 *pcorrection = pCalPierStruct->refPower; 4454 *pcorrection = pCalPierStruct->refPower;
4469 *ptemperature = pCalPierStruct->tempMeas; 4455 *ptemperature = pCalPierStruct->tempMeas;
4470 *pvoltage = pCalPierStruct->voltMeas; 4456 *pvoltage = pCalPierStruct->voltMeas;
@@ -4789,30 +4775,8 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4789 bool is2ghz = IS_CHAN_2GHZ(chan); 4775 bool is2ghz = IS_CHAN_2GHZ(chan);
4790 4776
4791 ath9k_hw_get_channel_centers(ah, chan, &centers); 4777 ath9k_hw_get_channel_centers(ah, chan, &centers);
4792 scaledPower = powerLimit - antenna_reduction; 4778 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
4793 4779 antenna_reduction);
4794 /*
4795 * Reduce scaled Power by number of chains active to get
4796 * to per chain tx power level
4797 */
4798 switch (ar5416_get_ntxchains(ah->txchainmask)) {
4799 case 1:
4800 break;
4801 case 2:
4802 if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
4803 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
4804 else
4805 scaledPower = 0;
4806 break;
4807 case 3:
4808 if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
4809 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
4810 else
4811 scaledPower = 0;
4812 break;
4813 }
4814
4815 scaledPower = max((u16)0, scaledPower);
4816 4780
4817 /* 4781 /*
4818 * Get target powers from EEPROM - our baseline for TX Power 4782 * Get target powers from EEPROM - our baseline for TX Power
@@ -5060,8 +5024,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5060 i, targetPowerValT2[i]); 5024 i, targetPowerValT2[i]);
5061 } 5025 }
5062 5026
5063 ah->txpower_limit = regulatory->max_power_level;
5064
5065 /* Write target power array to registers */ 5027 /* Write target power array to registers */
5066 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); 5028 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5067 ar9003_hw_calibration_apply(ah, chan->channel); 5029 ar9003_hw_calibration_apply(ah, chan->channel);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index bb223fe82816..2505ac44f0c1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -42,7 +42,6 @@
42#define AR9300_EEPMISC_WOW 0x02 42#define AR9300_EEPMISC_WOW 0x02
43#define AR9300_CUSTOMER_DATA_SIZE 20 43#define AR9300_CUSTOMER_DATA_SIZE 20
44 44
45#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
46#define AR9300_MAX_CHAINS 3 45#define AR9300_MAX_CHAINS 3
47#define AR9300_ANT_16S 25 46#define AR9300_ANT_16S 25
48#define AR9300_FUTURE_MODAL_SZ 6 47#define AR9300_FUTURE_MODAL_SZ 6
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 0f56e322dd3b..a0e3394b10dc 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -305,11 +305,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
305 ar9462_common_rx_gain_table_2p0, 305 ar9462_common_rx_gain_table_2p0,
306 ARRAY_SIZE(ar9462_common_rx_gain_table_2p0), 2); 306 ARRAY_SIZE(ar9462_common_rx_gain_table_2p0), 2);
307 307
308 INIT_INI_ARRAY(&ah->ini_BTCOEX_MAX_TXPWR,
309 ar9462_2p0_BTCOEX_MAX_TXPWR_table,
310 ARRAY_SIZE(ar9462_2p0_BTCOEX_MAX_TXPWR_table),
311 2);
312
313 /* Awake -> Sleep Setting */ 308 /* Awake -> Sleep Setting */
314 INIT_INI_ARRAY(&ah->iniPcieSerdes, 309 INIT_INI_ARRAY(&ah->iniPcieSerdes,
315 PCIE_PLL_ON_CREQ_DIS_L1_2P0, 310 PCIE_PLL_ON_CREQ_DIS_L1_2P0,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index a66a13b76848..d9e0824af093 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -306,6 +306,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
306 ar9003_mci_get_isr(ah, masked); 306 ar9003_mci_get_isr(ah, masked);
307 307
308 if (sync_cause) { 308 if (sync_cause) {
309 ath9k_debug_sync_cause(common, sync_cause);
310
309 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { 311 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
310 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); 312 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
311 REG_WRITE(ah, AR_RC, 0); 313 REG_WRITE(ah, AR_RC, 0);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 79070bf04eab..bbda25f4e9f0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -152,7 +152,6 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
152 REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32); 152 REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
153 153
154 ah->curchan = chan; 154 ah->curchan = chan;
155 ah->curchan_rad_index = -1;
156 155
157 return 0; 156 return 0;
158} 157}
@@ -209,11 +208,12 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
209 continue; 208 continue;
210 negative = 0; 209 negative = 0;
211 if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) 210 if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah))
212 cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], 211 cur_bb_spur = ath9k_hw_fbin2freq(spur_fbin_ptr[i],
213 IS_CHAN_2GHZ(chan)) - synth_freq; 212 IS_CHAN_2GHZ(chan));
214 else 213 else
215 cur_bb_spur = spur_freq[i] - synth_freq; 214 cur_bb_spur = spur_freq[i];
216 215
216 cur_bb_spur -= synth_freq;
217 if (cur_bb_spur < 0) { 217 if (cur_bb_spur < 0) {
218 negative = 1; 218 negative = 1;
219 cur_bb_spur = -cur_bb_spur; 219 cur_bb_spur = -cur_bb_spur;
@@ -443,7 +443,8 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah,
443 ar9003_hw_spur_ofdm_clear(ah); 443 ar9003_hw_spur_ofdm_clear(ah);
444 444
445 for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) { 445 for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) {
446 freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; 446 freq_offset = ath9k_hw_fbin2freq(spurChansPtr[i], mode);
447 freq_offset -= synth_freq;
447 if (abs(freq_offset) < range) { 448 if (abs(freq_offset) < range) {
448 ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); 449 ar9003_hw_spur_ofdm_work(ah, chan, freq_offset);
449 break; 450 break;
@@ -684,9 +685,6 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
684 685
685 REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); 686 REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites);
686 687
687 if (AR_SREV_9462(ah))
688 ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1);
689
690 if (chan->channel == 2484) 688 if (chan->channel == 2484)
691 ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); 689 ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1);
692 690
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index b6ba1e8149be..1d6658e139b5 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -1115,9 +1115,9 @@ static const u32 ar9462_2p0_mac_core[][2] = {
1115 {0x000081f8, 0x00000000}, 1115 {0x000081f8, 0x00000000},
1116 {0x000081fc, 0x00000000}, 1116 {0x000081fc, 0x00000000},
1117 {0x00008240, 0x00100000}, 1117 {0x00008240, 0x00100000},
1118 {0x00008244, 0x0010f400}, 1118 {0x00008244, 0x0010f424},
1119 {0x00008248, 0x00000800}, 1119 {0x00008248, 0x00000800},
1120 {0x0000824c, 0x0001e800}, 1120 {0x0000824c, 0x0001e848},
1121 {0x00008250, 0x00000000}, 1121 {0x00008250, 0x00000000},
1122 {0x00008254, 0x00000000}, 1122 {0x00008254, 0x00000000},
1123 {0x00008258, 0x00000000}, 1123 {0x00008258, 0x00000000},
@@ -1448,16 +1448,4 @@ static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = {
1448 {0x0000b1fc, 0x00000196}, 1448 {0x0000b1fc, 0x00000196},
1449}; 1449};
1450 1450
1451static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
1452 /* Addr allmodes */
1453 {0x000018c0, 0x10101010},
1454 {0x000018c4, 0x10101010},
1455 {0x000018c8, 0x10101010},
1456 {0x000018cc, 0x10101010},
1457 {0x000018d0, 0x10101010},
1458 {0x000018d4, 0x10101010},
1459 {0x000018d8, 0x10101010},
1460 {0x000018dc, 0x10101010},
1461};
1462
1463#endif /* INITVALS_9462_2P0_H */ 1451#endif /* INITVALS_9462_2P0_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0a37631390db..a277cf6f339d 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -370,7 +370,7 @@ struct ath_vif {
370 * number of beacon intervals, the game's up. 370 * number of beacon intervals, the game's up.
371 */ 371 */
372#define BSTUCK_THRESH 9 372#define BSTUCK_THRESH 9
373#define ATH_BCBUF 4 373#define ATH_BCBUF 8
374#define ATH_DEFAULT_BINTVAL 100 /* TU */ 374#define ATH_DEFAULT_BINTVAL 100 /* TU */
375#define ATH_DEFAULT_BMISS_LIMIT 10 375#define ATH_DEFAULT_BMISS_LIMIT 10
376#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) 376#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 626418222c85..702e5abc38b2 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -91,7 +91,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
91 info.txpower = MAX_RATE_POWER; 91 info.txpower = MAX_RATE_POWER;
92 info.keyix = ATH9K_TXKEYIX_INVALID; 92 info.keyix = ATH9K_TXKEYIX_INVALID;
93 info.keytype = ATH9K_KEY_TYPE_CLEAR; 93 info.keytype = ATH9K_KEY_TYPE_CLEAR;
94 info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_INTREQ; 94 info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_CLRDMASK;
95 95
96 info.buf_addr[0] = bf->bf_buf_addr; 96 info.buf_addr[0] = bf->bf_buf_addr;
97 info.buf_len[0] = roundup(skb->len, 4); 97 info.buf_len[0] = roundup(skb->len, 4);
@@ -359,6 +359,11 @@ void ath_beacon_tasklet(unsigned long data)
359 int slot; 359 int slot;
360 u32 bfaddr, bc = 0; 360 u32 bfaddr, bc = 0;
361 361
362 if (work_pending(&sc->hw_reset_work)) {
363 ath_dbg(common, RESET,
364 "reset work is pending, skip beaconing now\n");
365 return;
366 }
362 /* 367 /*
363 * Check if the previous beacon has gone out. If 368 * Check if the previous beacon has gone out. If
364 * not don't try to post another, skip this period 369 * not don't try to post another, skip this period
@@ -369,6 +374,9 @@ void ath_beacon_tasklet(unsigned long data)
369 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { 374 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
370 sc->beacon.bmisscnt++; 375 sc->beacon.bmisscnt++;
371 376
377 if (!ath9k_hw_check_alive(ah))
378 ieee80211_queue_work(sc->hw, &sc->hw_check_work);
379
372 if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { 380 if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
373 ath_dbg(common, BSTUCK, 381 ath_dbg(common, BSTUCK,
374 "missed %u consecutive beacons\n", 382 "missed %u consecutive beacons\n",
@@ -378,6 +386,7 @@ void ath_beacon_tasklet(unsigned long data)
378 ath9k_hw_bstuck_nfcal(ah); 386 ath9k_hw_bstuck_nfcal(ah);
379 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { 387 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
380 ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); 388 ath_dbg(common, BSTUCK, "beacon is officially stuck\n");
389 sc->beacon.bmisscnt = 0;
381 sc->sc_flags |= SC_OP_TSF_RESET; 390 sc->sc_flags |= SC_OP_TSF_RESET;
382 ieee80211_queue_work(sc->hw, &sc->hw_reset_work); 391 ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
383 } 392 }
@@ -650,6 +659,8 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
650 u32 tsf, intval, nexttbtt; 659 u32 tsf, intval, nexttbtt;
651 660
652 ath9k_reset_beacon_status(sc); 661 ath9k_reset_beacon_status(sc);
662 if (!(sc->sc_flags & SC_OP_BEACONS))
663 ath9k_hw_settsf64(ah, sc->beacon.bc_tstamp);
653 664
654 intval = TU_TO_USEC(conf->beacon_interval); 665 intval = TU_TO_USEC(conf->beacon_interval);
655 tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval); 666 tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 04edce941cb7..fde700c4e490 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -380,63 +380,75 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
380 size_t count, loff_t *ppos) 380 size_t count, loff_t *ppos)
381{ 381{
382 struct ath_softc *sc = file->private_data; 382 struct ath_softc *sc = file->private_data;
383 char buf[512];
384 unsigned int len = 0; 383 unsigned int len = 0;
384 int rv;
385 int mxlen = 4000;
386 char *buf = kmalloc(mxlen, GFP_KERNEL);
387 if (!buf)
388 return -ENOMEM;
389
390#define PR_IS(a, s) \
391 do { \
392 len += snprintf(buf + len, mxlen - len, \
393 "%21s: %10u\n", a, \
394 sc->debug.stats.istats.s); \
395 } while (0)
385 396
386 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { 397 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
387 len += snprintf(buf + len, sizeof(buf) - len, 398 PR_IS("RXLP", rxlp);
388 "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp); 399 PR_IS("RXHP", rxhp);
389 len += snprintf(buf + len, sizeof(buf) - len, 400 PR_IS("WATHDOG", bb_watchdog);
390 "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
391 len += snprintf(buf + len, sizeof(buf) - len,
392 "%8s: %10u\n", "WATCHDOG",
393 sc->debug.stats.istats.bb_watchdog);
394 } else { 401 } else {
395 len += snprintf(buf + len, sizeof(buf) - len, 402 PR_IS("RX", rxok);
396 "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
397 } 403 }
398 len += snprintf(buf + len, sizeof(buf) - len, 404 PR_IS("RXEOL", rxeol);
399 "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol); 405 PR_IS("RXORN", rxorn);
400 len += snprintf(buf + len, sizeof(buf) - len, 406 PR_IS("TX", txok);
401 "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn); 407 PR_IS("TXURN", txurn);
402 len += snprintf(buf + len, sizeof(buf) - len, 408 PR_IS("MIB", mib);
403 "%8s: %10u\n", "TX", sc->debug.stats.istats.txok); 409 PR_IS("RXPHY", rxphyerr);
404 len += snprintf(buf + len, sizeof(buf) - len, 410 PR_IS("RXKCM", rx_keycache_miss);
405 "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn); 411 PR_IS("SWBA", swba);
406 len += snprintf(buf + len, sizeof(buf) - len, 412 PR_IS("BMISS", bmiss);
407 "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib); 413 PR_IS("BNR", bnr);
408 len += snprintf(buf + len, sizeof(buf) - len, 414 PR_IS("CST", cst);
409 "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr); 415 PR_IS("GTT", gtt);
410 len += snprintf(buf + len, sizeof(buf) - len, 416 PR_IS("TIM", tim);
411 "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss); 417 PR_IS("CABEND", cabend);
412 len += snprintf(buf + len, sizeof(buf) - len, 418 PR_IS("DTIMSYNC", dtimsync);
413 "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba); 419 PR_IS("DTIM", dtim);
414 len += snprintf(buf + len, sizeof(buf) - len, 420 PR_IS("TSFOOR", tsfoor);
415 "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss); 421 PR_IS("TOTAL", total);
416 len += snprintf(buf + len, sizeof(buf) - len, 422
417 "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr); 423 len += snprintf(buf + len, mxlen - len,
418 len += snprintf(buf + len, sizeof(buf) - len, 424 "SYNC_CAUSE stats:\n");
419 "%8s: %10u\n", "CST", sc->debug.stats.istats.cst); 425
420 len += snprintf(buf + len, sizeof(buf) - len, 426 PR_IS("Sync-All", sync_cause_all);
421 "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt); 427 PR_IS("RTC-IRQ", sync_rtc_irq);
422 len += snprintf(buf + len, sizeof(buf) - len, 428 PR_IS("MAC-IRQ", sync_mac_irq);
423 "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim); 429 PR_IS("EEPROM-Illegal-Access", eeprom_illegal_access);
424 len += snprintf(buf + len, sizeof(buf) - len, 430 PR_IS("APB-Timeout", apb_timeout);
425 "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend); 431 PR_IS("PCI-Mode-Conflict", pci_mode_conflict);
426 len += snprintf(buf + len, sizeof(buf) - len, 432 PR_IS("HOST1-Fatal", host1_fatal);
427 "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync); 433 PR_IS("HOST1-Perr", host1_perr);
428 len += snprintf(buf + len, sizeof(buf) - len, 434 PR_IS("TRCV-FIFO-Perr", trcv_fifo_perr);
429 "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim); 435 PR_IS("RADM-CPL-EP", radm_cpl_ep);
430 len += snprintf(buf + len, sizeof(buf) - len, 436 PR_IS("RADM-CPL-DLLP-Abort", radm_cpl_dllp_abort);
431 "%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor); 437 PR_IS("RADM-CPL-TLP-Abort", radm_cpl_tlp_abort);
432 len += snprintf(buf + len, sizeof(buf) - len, 438 PR_IS("RADM-CPL-ECRC-Err", radm_cpl_ecrc_err);
433 "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); 439 PR_IS("RADM-CPL-Timeout", radm_cpl_timeout);
434 440 PR_IS("Local-Bus-Timeout", local_timeout);
435 441 PR_IS("PM-Access", pm_access);
436 if (len > sizeof(buf)) 442 PR_IS("MAC-Awake", mac_awake);
437 len = sizeof(buf); 443 PR_IS("MAC-Asleep", mac_asleep);
438 444 PR_IS("MAC-Sleep-Access", mac_sleep_access);
439 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 445
446 if (len > mxlen)
447 len = mxlen;
448
449 rv = simple_read_from_buffer(user_buf, count, ppos, buf, len);
450 kfree(buf);
451 return rv;
440} 452}
441 453
442static const struct file_operations fops_interrupt = { 454static const struct file_operations fops_interrupt = {
@@ -881,6 +893,13 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
881 len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \ 893 len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \
882 sc->debug.stats.rxstats.phy_err_stats[p]); 894 sc->debug.stats.rxstats.phy_err_stats[p]);
883 895
896#define RXS_ERR(s, e) \
897 do { \
898 len += snprintf(buf + len, size - len, \
899 "%22s : %10u\n", s, \
900 sc->debug.stats.rxstats.e); \
901 } while (0)
902
884 struct ath_softc *sc = file->private_data; 903 struct ath_softc *sc = file->private_data;
885 char *buf; 904 char *buf;
886 unsigned int len = 0, size = 1600; 905 unsigned int len = 0, size = 1600;
@@ -890,42 +909,18 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
890 if (buf == NULL) 909 if (buf == NULL)
891 return -ENOMEM; 910 return -ENOMEM;
892 911
893 len += snprintf(buf + len, size - len, 912 RXS_ERR("CRC ERR", crc_err);
894 "%22s : %10u\n", "CRC ERR", 913 RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err);
895 sc->debug.stats.rxstats.crc_err); 914 RXS_ERR("PHY ERR", phy_err);
896 len += snprintf(buf + len, size - len, 915 RXS_ERR("MIC ERR", mic_err);
897 "%22s : %10u\n", "DECRYPT CRC ERR", 916 RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err);
898 sc->debug.stats.rxstats.decrypt_crc_err); 917 RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err);
899 len += snprintf(buf + len, size - len, 918 RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
900 "%22s : %10u\n", "PHY ERR", 919 RXS_ERR("RX-LENGTH-ERR", rx_len_err);
901 sc->debug.stats.rxstats.phy_err); 920 RXS_ERR("RX-OOM-ERR", rx_oom_err);
902 len += snprintf(buf + len, size - len, 921 RXS_ERR("RX-RATE-ERR", rx_rate_err);
903 "%22s : %10u\n", "MIC ERR", 922 RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
904 sc->debug.stats.rxstats.mic_err); 923 RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
905 len += snprintf(buf + len, size - len,
906 "%22s : %10u\n", "PRE-DELIM CRC ERR",
907 sc->debug.stats.rxstats.pre_delim_crc_err);
908 len += snprintf(buf + len, size - len,
909 "%22s : %10u\n", "POST-DELIM CRC ERR",
910 sc->debug.stats.rxstats.post_delim_crc_err);
911 len += snprintf(buf + len, size - len,
912 "%22s : %10u\n", "DECRYPT BUSY ERR",
913 sc->debug.stats.rxstats.decrypt_busy_err);
914 len += snprintf(buf + len, size - len,
915 "%22s : %10u\n", "RX-LENGTH-ERR",
916 sc->debug.stats.rxstats.rx_len_err);
917 len += snprintf(buf + len, size - len,
918 "%22s : %10u\n", "RX-OOM-ERR",
919 sc->debug.stats.rxstats.rx_oom_err);
920 len += snprintf(buf + len, size - len,
921 "%22s : %10u\n", "RX-RATE-ERR",
922 sc->debug.stats.rxstats.rx_rate_err);
923 len += snprintf(buf + len, size - len,
924 "%22s : %10u\n", "RX-DROP-RXFLUSH",
925 sc->debug.stats.rxstats.rx_drop_rxflush);
926 len += snprintf(buf + len, size - len,
927 "%22s : %10u\n", "RX-TOO-MANY-FRAGS",
928 sc->debug.stats.rxstats.rx_too_many_frags_err);
929 924
930 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); 925 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
931 PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING); 926 PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
@@ -954,18 +949,10 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
954 PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); 949 PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
955 PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); 950 PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
956 951
957 len += snprintf(buf + len, size - len, 952 RXS_ERR("RX-Pkts-All", rx_pkts_all);
958 "%22s : %10u\n", "RX-Pkts-All", 953 RXS_ERR("RX-Bytes-All", rx_bytes_all);
959 sc->debug.stats.rxstats.rx_pkts_all); 954 RXS_ERR("RX-Beacons", rx_beacons);
960 len += snprintf(buf + len, size - len, 955 RXS_ERR("RX-Frags", rx_frags);
961 "%22s : %10u\n", "RX-Bytes-All",
962 sc->debug.stats.rxstats.rx_bytes_all);
963 len += snprintf(buf + len, size - len,
964 "%22s : %10u\n", "RX-Beacons",
965 sc->debug.stats.rxstats.rx_beacons);
966 len += snprintf(buf + len, size - len,
967 "%22s : %10u\n", "RX-Frags",
968 sc->debug.stats.rxstats.rx_frags);
969 956
970 if (len > size) 957 if (len > size)
971 len = size; 958 len = size;
@@ -975,6 +962,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
975 962
976 return retval; 963 return retval;
977 964
965#undef RXS_ERR
978#undef PHY_ERR 966#undef PHY_ERR
979} 967}
980 968
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 17f6cc27af32..c34da09d9103 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -60,6 +60,7 @@ struct ath_buf;
60 * @tsfoor: TSF out of range, indicates that the corrected TSF received 60 * @tsfoor: TSF out of range, indicates that the corrected TSF received
61 * from a beacon differs from the PCU's internal TSF by more than a 61 * from a beacon differs from the PCU's internal TSF by more than a
62 * (programmable) threshold 62 * (programmable) threshold
63 * @local_timeout: Internal bus timeout.
63 */ 64 */
64struct ath_interrupt_stats { 65struct ath_interrupt_stats {
65 u32 total; 66 u32 total;
@@ -85,8 +86,30 @@ struct ath_interrupt_stats {
85 u32 dtim; 86 u32 dtim;
86 u32 bb_watchdog; 87 u32 bb_watchdog;
87 u32 tsfoor; 88 u32 tsfoor;
89
90 /* Sync-cause stats */
91 u32 sync_cause_all;
92 u32 sync_rtc_irq;
93 u32 sync_mac_irq;
94 u32 eeprom_illegal_access;
95 u32 apb_timeout;
96 u32 pci_mode_conflict;
97 u32 host1_fatal;
98 u32 host1_perr;
99 u32 trcv_fifo_perr;
100 u32 radm_cpl_ep;
101 u32 radm_cpl_dllp_abort;
102 u32 radm_cpl_tlp_abort;
103 u32 radm_cpl_ecrc_err;
104 u32 radm_cpl_timeout;
105 u32 local_timeout;
106 u32 pm_access;
107 u32 mac_awake;
108 u32 mac_asleep;
109 u32 mac_sleep_access;
88}; 110};
89 111
112
90/** 113/**
91 * struct ath_tx_stats - Statistics about TX 114 * struct ath_tx_stats - Statistics about TX
92 * @tx_pkts_all: No. of total frames transmitted, including ones that 115 * @tx_pkts_all: No. of total frames transmitted, including ones that
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index c43523233319..0512397a293c 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -16,14 +16,6 @@
16 16
17#include "hw.h" 17#include "hw.h"
18 18
19static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
20{
21 if (fbin == AR5416_BCHAN_UNUSED)
22 return fbin;
23
24 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
25}
26
27void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val) 19void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
28{ 20{
29 REG_WRITE(ah, reg, val); 21 REG_WRITE(ah, reg, val);
@@ -290,6 +282,34 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
290 return twiceMaxEdgePower; 282 return twiceMaxEdgePower;
291} 283}
292 284
285u16 ath9k_hw_get_scaled_power(struct ath_hw *ah, u16 power_limit,
286 u8 antenna_reduction)
287{
288 u16 reduction = antenna_reduction;
289
290 /*
291 * Reduce scaled Power by number of chains active
292 * to get the per chain tx power level.
293 */
294 switch (ar5416_get_ntxchains(ah->txchainmask)) {
295 case 1:
296 break;
297 case 2:
298 reduction += POWER_CORRECTION_FOR_TWO_CHAIN;
299 break;
300 case 3:
301 reduction += POWER_CORRECTION_FOR_THREE_CHAIN;
302 break;
303 }
304
305 if (power_limit > reduction)
306 power_limit -= reduction;
307 else
308 power_limit = 0;
309
310 return power_limit;
311}
312
293void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah) 313void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
294{ 314{
295 struct ath_common *common = ath9k_hw_common(ah); 315 struct ath_common *common = ath9k_hw_common(ah);
@@ -299,10 +319,10 @@ void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
299 case 1: 319 case 1:
300 break; 320 break;
301 case 2: 321 case 2:
302 regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; 322 regulatory->max_power_level += POWER_CORRECTION_FOR_TWO_CHAIN;
303 break; 323 break;
304 case 3: 324 case 3:
305 regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; 325 regulatory->max_power_level += POWER_CORRECTION_FOR_THREE_CHAIN;
306 break; 326 break;
307 default: 327 default:
308 ath_dbg(common, EEPROM, "Invalid chainmask configuration\n"); 328 ath_dbg(common, EEPROM, "Invalid chainmask configuration\n");
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 5ff7ab965120..33acb920ed3f 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -79,8 +79,8 @@
79#define SUB_NUM_CTL_MODES_AT_5G_40 2 79#define SUB_NUM_CTL_MODES_AT_5G_40 2
80#define SUB_NUM_CTL_MODES_AT_2G_40 3 80#define SUB_NUM_CTL_MODES_AT_2G_40 3
81 81
82#define INCREASE_MAXPOW_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 82#define POWER_CORRECTION_FOR_TWO_CHAIN 6 /* 10*log10(2)*2 */
83#define INCREASE_MAXPOW_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ 83#define POWER_CORRECTION_FOR_THREE_CHAIN 10 /* 10*log10(3)*2 */
84 84
85/* 85/*
86 * For AR9285 and later chipsets, the following bits are not being programmed 86 * For AR9285 and later chipsets, the following bits are not being programmed
@@ -686,6 +686,8 @@ void ath9k_hw_get_target_powers(struct ath_hw *ah,
686 u16 numRates, bool isHt40Target); 686 u16 numRates, bool isHt40Target);
687u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, 687u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
688 bool is2GHz, int num_band_edges); 688 bool is2GHz, int num_band_edges);
689u16 ath9k_hw_get_scaled_power(struct ath_hw *ah, u16 power_limit,
690 u8 antenna_reduction);
689void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah); 691void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah);
690int ath9k_hw_eeprom_init(struct ath_hw *ah); 692int ath9k_hw_eeprom_init(struct ath_hw *ah);
691 693
@@ -697,6 +699,14 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
697 u16 *pPdGainBoundaries, u8 *pPDADCValues, 699 u16 *pPdGainBoundaries, u8 *pPDADCValues,
698 u16 numXpdGains); 700 u16 numXpdGains);
699 701
702static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
703{
704 if (fbin == AR5416_BCHAN_UNUSED)
705 return fbin;
706
707 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
708}
709
700#define ar5416_get_ntxchains(_txchainmask) \ 710#define ar5416_get_ntxchains(_txchainmask) \
701 (((_txchainmask >> 2) & 1) + \ 711 (((_txchainmask >> 2) & 1) + \
702 ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) 712 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index f272236d8053..5ab0e6ed4655 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -564,9 +564,6 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
564 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ 564 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
565 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) 565 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
566 566
567#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
568#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
569
570 u16 twiceMaxEdgePower; 567 u16 twiceMaxEdgePower;
571 int i; 568 int i;
572 struct cal_ctl_data_ar9287 *rep; 569 struct cal_ctl_data_ar9287 *rep;
@@ -591,29 +588,8 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
591 tx_chainmask = ah->txchainmask; 588 tx_chainmask = ah->txchainmask;
592 589
593 ath9k_hw_get_channel_centers(ah, chan, &centers); 590 ath9k_hw_get_channel_centers(ah, chan, &centers);
594 scaledPower = powerLimit - antenna_reduction; 591 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
595 592 antenna_reduction);
596 /*
597 * Reduce scaled Power by number of chains active
598 * to get the per chain tx power level.
599 */
600 switch (ar5416_get_ntxchains(tx_chainmask)) {
601 case 1:
602 break;
603 case 2:
604 if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
605 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
606 else
607 scaledPower = 0;
608 break;
609 case 3:
610 if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
611 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
612 else
613 scaledPower = 0;
614 break;
615 }
616 scaledPower = max((u16)0, scaledPower);
617 593
618 /* 594 /*
619 * Get TX power from EEPROM. 595 * Get TX power from EEPROM.
@@ -786,8 +762,6 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
786 762
787#undef CMP_CTL 763#undef CMP_CTL
788#undef CMP_NO_CTL 764#undef CMP_NO_CTL
789#undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
790#undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
791} 765}
792 766
793static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, 767static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 619b95d764ff..b5fba8b18b8b 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -991,9 +991,6 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
991 u16 antenna_reduction, 991 u16 antenna_reduction,
992 u16 powerLimit) 992 u16 powerLimit)
993{ 993{
994#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
995#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
996
997 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 994 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
998 u16 twiceMaxEdgePower; 995 u16 twiceMaxEdgePower;
999 int i; 996 int i;
@@ -1027,24 +1024,8 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
1027 1024
1028 ath9k_hw_get_channel_centers(ah, chan, &centers); 1025 ath9k_hw_get_channel_centers(ah, chan, &centers);
1029 1026
1030 scaledPower = powerLimit - antenna_reduction; 1027 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
1031 1028 antenna_reduction);
1032 switch (ar5416_get_ntxchains(tx_chainmask)) {
1033 case 1:
1034 break;
1035 case 2:
1036 if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
1037 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
1038 else
1039 scaledPower = 0;
1040 break;
1041 case 3:
1042 if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
1043 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
1044 else
1045 scaledPower = 0;
1046 break;
1047 }
1048 1029
1049 if (IS_CHAN_2GHZ(chan)) { 1030 if (IS_CHAN_2GHZ(chan)) {
1050 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - 1031 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
@@ -1263,20 +1244,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1263 regulatory->max_power_level = ratesArray[i]; 1244 regulatory->max_power_level = ratesArray[i];
1264 } 1245 }
1265 1246
1266 switch(ar5416_get_ntxchains(ah->txchainmask)) { 1247 ath9k_hw_update_regulatory_maxpower(ah);
1267 case 1:
1268 break;
1269 case 2:
1270 regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
1271 break;
1272 case 3:
1273 regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
1274 break;
1275 default:
1276 ath_dbg(ath9k_hw_common(ah), EEPROM,
1277 "Invalid chainmask configuration\n");
1278 break;
1279 }
1280 1248
1281 if (test) 1249 if (test)
1282 return; 1250 return;
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index fbe23de1297f..dd10f4ac03ef 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -41,6 +41,9 @@ void ath_init_leds(struct ath_softc *sc)
41{ 41{
42 int ret; 42 int ret;
43 43
44 if (AR_SREV_9100(sc->sc_ah))
45 return;
46
44 if (sc->sc_ah->led_pin < 0) { 47 if (sc->sc_ah->led_pin < 0) {
45 if (AR_SREV_9287(sc->sc_ah)) 48 if (AR_SREV_9287(sc->sc_ah))
46 sc->sc_ah->led_pin = ATH_LED_PIN_9287; 49 sc->sc_ah->led_pin = ATH_LED_PIN_9287;
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 424aabb2c730..f67cd952e741 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -53,6 +53,8 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
53 .driver_info = AR9280_USB }, /* SMC Networks */ 53 .driver_info = AR9280_USB }, /* SMC Networks */
54 { USB_DEVICE(0x0411, 0x017f), 54 { USB_DEVICE(0x0411, 0x017f),
55 .driver_info = AR9280_USB }, /* Sony UWA-BR100 */ 55 .driver_info = AR9280_USB }, /* Sony UWA-BR100 */
56 { USB_DEVICE(0x04da, 0x3904),
57 .driver_info = AR9280_USB },
56 58
57 { USB_DEVICE(0x0cf3, 0x20ff), 59 { USB_DEVICE(0x0cf3, 0x20ff),
58 .driver_info = STORAGE_DEVICE }, 60 .driver_info = STORAGE_DEVICE },
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index d1345a8a2b15..72c5bcd4886d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -24,6 +24,8 @@
24#include "rc.h" 24#include "rc.h"
25#include "ar9003_mac.h" 25#include "ar9003_mac.h"
26#include "ar9003_mci.h" 26#include "ar9003_mci.h"
27#include "debug.h"
28#include "ath9k.h"
27 29
28static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); 30static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
29 31
@@ -83,6 +85,53 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
83/* Helper Functions */ 85/* Helper Functions */
84/********************/ 86/********************/
85 87
88#ifdef CONFIG_ATH9K_DEBUGFS
89
90void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause)
91{
92 struct ath_softc *sc = common->priv;
93 if (sync_cause)
94 sc->debug.stats.istats.sync_cause_all++;
95 if (sync_cause & AR_INTR_SYNC_RTC_IRQ)
96 sc->debug.stats.istats.sync_rtc_irq++;
97 if (sync_cause & AR_INTR_SYNC_MAC_IRQ)
98 sc->debug.stats.istats.sync_mac_irq++;
99 if (sync_cause & AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS)
100 sc->debug.stats.istats.eeprom_illegal_access++;
101 if (sync_cause & AR_INTR_SYNC_APB_TIMEOUT)
102 sc->debug.stats.istats.apb_timeout++;
103 if (sync_cause & AR_INTR_SYNC_PCI_MODE_CONFLICT)
104 sc->debug.stats.istats.pci_mode_conflict++;
105 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL)
106 sc->debug.stats.istats.host1_fatal++;
107 if (sync_cause & AR_INTR_SYNC_HOST1_PERR)
108 sc->debug.stats.istats.host1_perr++;
109 if (sync_cause & AR_INTR_SYNC_TRCV_FIFO_PERR)
110 sc->debug.stats.istats.trcv_fifo_perr++;
111 if (sync_cause & AR_INTR_SYNC_RADM_CPL_EP)
112 sc->debug.stats.istats.radm_cpl_ep++;
113 if (sync_cause & AR_INTR_SYNC_RADM_CPL_DLLP_ABORT)
114 sc->debug.stats.istats.radm_cpl_dllp_abort++;
115 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TLP_ABORT)
116 sc->debug.stats.istats.radm_cpl_tlp_abort++;
117 if (sync_cause & AR_INTR_SYNC_RADM_CPL_ECRC_ERR)
118 sc->debug.stats.istats.radm_cpl_ecrc_err++;
119 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT)
120 sc->debug.stats.istats.radm_cpl_timeout++;
121 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
122 sc->debug.stats.istats.local_timeout++;
123 if (sync_cause & AR_INTR_SYNC_PM_ACCESS)
124 sc->debug.stats.istats.pm_access++;
125 if (sync_cause & AR_INTR_SYNC_MAC_AWAKE)
126 sc->debug.stats.istats.mac_awake++;
127 if (sync_cause & AR_INTR_SYNC_MAC_ASLEEP)
128 sc->debug.stats.istats.mac_asleep++;
129 if (sync_cause & AR_INTR_SYNC_MAC_SLEEP_ACCESS)
130 sc->debug.stats.istats.mac_sleep_access++;
131}
132#endif
133
134
86static void ath9k_hw_set_clockrate(struct ath_hw *ah) 135static void ath9k_hw_set_clockrate(struct ath_hw *ah)
87{ 136{
88 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 137 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
@@ -388,8 +437,8 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
388{ 437{
389 int i; 438 int i;
390 439
391 ah->config.dma_beacon_response_time = 2; 440 ah->config.dma_beacon_response_time = 1;
392 ah->config.sw_beacon_response_time = 10; 441 ah->config.sw_beacon_response_time = 6;
393 ah->config.additional_swba_backoff = 0; 442 ah->config.additional_swba_backoff = 0;
394 ah->config.ack_6mb = 0x0; 443 ah->config.ack_6mb = 0x0;
395 ah->config.cwm_ignore_extcca = 0; 444 ah->config.cwm_ignore_extcca = 0;
@@ -445,7 +494,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
445 AR_STA_ID1_MCAST_KSRCH; 494 AR_STA_ID1_MCAST_KSRCH;
446 if (AR_SREV_9100(ah)) 495 if (AR_SREV_9100(ah))
447 ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; 496 ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
448 ah->enable_32kHz_clock = DONT_USE_32KHZ;
449 ah->slottime = ATH9K_SLOT_TIME_9; 497 ah->slottime = ATH9K_SLOT_TIME_9;
450 ah->globaltxtimeout = (u32) -1; 498 ah->globaltxtimeout = (u32) -1;
451 ah->power_mode = ATH9K_PM_UNDEFINED; 499 ah->power_mode = ATH9K_PM_UNDEFINED;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index aa1680a0c7fd..dd4b8f4097c8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -708,7 +708,6 @@ struct ath_hw {
708 struct ar5416Stats stats; 708 struct ar5416Stats stats;
709 struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; 709 struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
710 710
711 int16_t curchan_rad_index;
712 enum ath9k_int imask; 711 enum ath9k_int imask;
713 u32 imrs2_reg; 712 u32 imrs2_reg;
714 u32 txok_interrupt_mask; 713 u32 txok_interrupt_mask;
@@ -762,11 +761,6 @@ struct ath_hw {
762 761
763 u32 sta_id1_defaults; 762 u32 sta_id1_defaults;
764 u32 misc_mode; 763 u32 misc_mode;
765 enum {
766 AUTO_32KHZ,
767 USE_32KHZ,
768 DONT_USE_32KHZ,
769 } enable_32kHz_clock;
770 764
771 /* Private to hardware code */ 765 /* Private to hardware code */
772 struct ath_hw_private_ops private_ops; 766 struct ath_hw_private_ops private_ops;
@@ -783,7 +777,6 @@ struct ath_hw {
783 u32 *analogBank7Data; 777 u32 *analogBank7Data;
784 u32 *bank6Temp; 778 u32 *bank6Temp;
785 779
786 u8 txpower_limit;
787 int coverage_class; 780 int coverage_class;
788 u32 slottime; 781 u32 slottime;
789 u32 globaltxtimeout; 782 u32 globaltxtimeout;
@@ -848,7 +841,6 @@ struct ath_hw {
848 struct ath_gen_timer_table hw_gen_timers; 841 struct ath_gen_timer_table hw_gen_timers;
849 842
850 struct ar9003_txs *ts_ring; 843 struct ar9003_txs *ts_ring;
851 void *ts_start;
852 u32 ts_paddr_start; 844 u32 ts_paddr_start;
853 u32 ts_paddr_end; 845 u32 ts_paddr_end;
854 u16 ts_tail; 846 u16 ts_tail;
@@ -915,7 +907,6 @@ static inline u8 get_streams(int mask)
915} 907}
916 908
917/* Initialization, Detach, Reset */ 909/* Initialization, Detach, Reset */
918const char *ath9k_hw_probe(u16 vendorid, u16 devid);
919void ath9k_hw_deinit(struct ath_hw *ah); 910void ath9k_hw_deinit(struct ath_hw *ah);
920int ath9k_hw_init(struct ath_hw *ah); 911int ath9k_hw_init(struct ath_hw *ah);
921int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 912int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
@@ -965,6 +956,12 @@ bool ath9k_hw_check_alive(struct ath_hw *ah);
965 956
966bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); 957bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
967 958
959#ifdef CONFIG_ATH9K_DEBUGFS
960void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause);
961#else
962static void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause) {}
963#endif
964
968/* Generic hw timer primitives */ 965/* Generic hw timer primitives */
969struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, 966struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
970 void (*trigger)(void *), 967 void (*trigger)(void *),
@@ -1011,7 +1008,6 @@ int ar9003_paprd_create_curve(struct ath_hw *ah,
1011int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); 1008int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
1012int ar9003_paprd_init_table(struct ath_hw *ah); 1009int ar9003_paprd_init_table(struct ath_hw *ah);
1013bool ar9003_paprd_is_done(struct ath_hw *ah); 1010bool ar9003_paprd_is_done(struct ath_hw *ah);
1014void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains);
1015 1011
1016/* Hardware family op attach helpers */ 1012/* Hardware family op attach helpers */
1017void ar5008_hw_attach_phy_ops(struct ath_hw *ah); 1013void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c8d123957188..384e5c498440 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -692,17 +692,6 @@ void ath9k_tasklet(unsigned long data)
692 goto out; 692 goto out;
693 } 693 }
694 694
695 /*
696 * Only run the baseband hang check if beacons stop working in AP or
697 * IBSS mode, because it has a high false positive rate. For station
698 * mode it should not be necessary, since the upper layers will detect
699 * this through a beacon miss automatically and the following channel
700 * change will trigger a hardware reset anyway
701 */
702 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0 &&
703 !ath9k_hw_check_alive(ah))
704 ieee80211_queue_work(sc->hw, &sc->hw_check_work);
705
706 if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { 695 if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
707 /* 696 /*
708 * TSF sync does not look correct; remain awake to sync with 697 * TSF sync does not look correct; remain awake to sync with
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 6c87a823f5a9..d07c0301da6a 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -3989,8 +3989,7 @@ static int reset_atmel_card(struct net_device *dev)
3989 atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000); 3989 atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3990 } 3990 }
3991 3991
3992 if (fw_entry) 3992 release_firmware(fw_entry);
3993 release_firmware(fw_entry);
3994 } 3993 }
3995 3994
3996 err = atmel_wakeup_firmware(priv); 3995 err = atmel_wakeup_firmware(priv);
diff --git a/drivers/net/wireless/atmel_pci.c b/drivers/net/wireless/atmel_pci.c
index 9ab1192004c0..51e33b53386e 100644
--- a/drivers/net/wireless/atmel_pci.c
+++ b/drivers/net/wireless/atmel_pci.c
@@ -74,15 +74,4 @@ static void __devexit atmel_pci_remove(struct pci_dev *pdev)
74 stop_atmel_card(pci_get_drvdata(pdev)); 74 stop_atmel_card(pci_get_drvdata(pdev));
75} 75}
76 76
77static int __init atmel_init_module(void) 77module_pci_driver(atmel_driver);
78{
79 return pci_register_driver(&atmel_driver);
80}
81
82static void __exit atmel_cleanup_module(void)
83{
84 pci_unregister_driver(&atmel_driver);
85}
86
87module_init(atmel_init_module);
88module_exit(atmel_cleanup_module);
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index cba413536270..b31ccc02fa21 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -290,7 +290,8 @@ int b43_generate_txhdr(struct b43_wldev *dev,
290 txhdr->dur_fb = wlhdr->duration_id; 290 txhdr->dur_fb = wlhdr->duration_id;
291 } else { 291 } else {
292 txhdr->dur_fb = ieee80211_generic_frame_duration( 292 txhdr->dur_fb = ieee80211_generic_frame_duration(
293 dev->wl->hw, info->control.vif, fragment_len, fbrate); 293 dev->wl->hw, info->control.vif, info->band,
294 fragment_len, fbrate);
294 } 295 }
295 296
296 plcp_fragment_len = fragment_len + FCS_LEN; 297 plcp_fragment_len = fragment_len + FCS_LEN;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index df7e16dfb36c..1be214b815fb 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -1056,6 +1056,7 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
1056 b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value); 1056 b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value);
1057 dur = ieee80211_generic_frame_duration(dev->wl->hw, 1057 dur = ieee80211_generic_frame_duration(dev->wl->hw,
1058 dev->wl->vif, 1058 dev->wl->vif,
1059 IEEE80211_BAND_2GHZ,
1059 size, 1060 size,
1060 rate); 1061 rate);
1061 /* Write PLCP in two parts and timing for packet transfer */ 1062 /* Write PLCP in two parts and timing for packet transfer */
@@ -1121,6 +1122,7 @@ static const u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev,
1121 IEEE80211_STYPE_PROBE_RESP); 1122 IEEE80211_STYPE_PROBE_RESP);
1122 dur = ieee80211_generic_frame_duration(dev->wl->hw, 1123 dur = ieee80211_generic_frame_duration(dev->wl->hw,
1123 dev->wl->vif, 1124 dev->wl->vif,
1125 IEEE80211_BAND_2GHZ,
1124 *dest_size, 1126 *dest_size,
1125 rate); 1127 rate);
1126 hdr->duration_id = dur; 1128 hdr->duration_id = dur;
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index e6c573af494d..a8012f2749ee 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -228,6 +228,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
228 } else { 228 } else {
229 txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, 229 txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
230 info->control.vif, 230 info->control.vif,
231 info->band,
231 fragment_len, 232 fragment_len,
232 rate_fb); 233 rate_fb);
233 } 234 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 07686a748d3c..9f637014486e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -632,7 +632,6 @@ extern const struct bcmevent_name bcmevent_names[];
632extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, 632extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
633 char *buf, uint len); 633 char *buf, uint len);
634 634
635extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx);
636extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); 635extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
637 636
638extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len); 637extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
index b3e3b7f25d82..a5c15cac5e7d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -421,6 +421,7 @@ int brcmf_proto_hdrpull(struct device *dev, int *ifidx,
421 pktbuf->priority = h->priority & BDC_PRIORITY_MASK; 421 pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
422 422
423 skb_pull(pktbuf, BDC_HEADER_LEN); 423 skb_pull(pktbuf, BDC_HEADER_LEN);
424 skb_pull(pktbuf, h->data_offset << 2);
424 425
425 return 0; 426 return 0;
426} 427}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 4187435220f3..236cb9fa460c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -799,7 +799,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
799{ 799{
800 char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for 800 char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for
801 "event_msgs" + '\0' + bitvec */ 801 "event_msgs" + '\0' + bitvec */
802 uint up = 0;
803 char buf[128], *ptr; 802 char buf[128], *ptr;
804 u32 dongle_align = drvr->bus_if->align; 803 u32 dongle_align = drvr->bus_if->align;
805 u32 glom = 0; 804 u32 glom = 0;
@@ -853,9 +852,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
853 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, 852 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
854 sizeof(iovbuf)); 853 sizeof(iovbuf));
855 854
856 /* Force STA UP */
857 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up));
858
859 /* Setup event_msgs */ 855 /* Setup event_msgs */
860 brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, 856 brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
861 iovbuf, sizeof(iovbuf)); 857 iovbuf, sizeof(iovbuf));
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 2a1e5ae0c402..8933f9b31a9a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -799,6 +799,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
799 struct brcmf_bus *bus_if = drvr->bus_if; 799 struct brcmf_bus *bus_if = drvr->bus_if;
800 u32 toe_ol; 800 u32 toe_ol;
801 s32 ret = 0; 801 s32 ret = 0;
802 uint up = 0;
802 803
803 brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); 804 brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
804 805
@@ -822,6 +823,10 @@ static int brcmf_netdev_open(struct net_device *ndev)
822 drvr->iflist[ifp->idx]->ndev->features &= 823 drvr->iflist[ifp->idx]->ndev->features &=
823 ~NETIF_F_IP_CSUM; 824 ~NETIF_F_IP_CSUM;
824 } 825 }
826
827 /* make sure RF is ready for work */
828 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up));
829
825 /* Allow transmit calls */ 830 /* Allow transmit calls */
826 netif_start_queue(ndev); 831 netif_start_queue(ndev);
827 drvr->bus_if->drvr_up = true; 832 drvr->bus_if->drvr_up = true;
@@ -843,6 +848,63 @@ static const struct net_device_ops brcmf_netdev_ops_pri = {
843 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list 848 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
844}; 849};
845 850
851static int brcmf_net_attach(struct brcmf_if *ifp)
852{
853 struct brcmf_pub *drvr = ifp->drvr;
854 struct net_device *ndev;
855 u8 temp_addr[ETH_ALEN];
856
857 brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
858
859 ndev = drvr->iflist[ifp->idx]->ndev;
860 ndev->netdev_ops = &brcmf_netdev_ops_pri;
861
862 /*
863 * determine mac address to use
864 */
865 if (is_valid_ether_addr(ifp->mac_addr))
866 memcpy(temp_addr, ifp->mac_addr, ETH_ALEN);
867 else
868 memcpy(temp_addr, drvr->mac, ETH_ALEN);
869
870 if (ifp->idx == 1) {
871 brcmf_dbg(TRACE, "ACCESS POINT MAC:\n");
872 /* ACCESSPOINT INTERFACE CASE */
873 temp_addr[0] |= 0X02; /* set bit 2 ,
874 - Locally Administered address */
875
876 }
877 ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
878 ndev->ethtool_ops = &brcmf_ethtool_ops;
879
880 drvr->rxsz = ndev->mtu + ndev->hard_header_len +
881 drvr->hdrlen;
882
883 memcpy(ndev->dev_addr, temp_addr, ETH_ALEN);
884
885 /* attach to cfg80211 for primary interface */
886 if (!ifp->idx) {
887 drvr->config = brcmf_cfg80211_attach(ndev, drvr->dev, drvr);
888 if (drvr->config == NULL) {
889 brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
890 goto fail;
891 }
892 }
893
894 if (register_netdev(ndev) != 0) {
895 brcmf_dbg(ERROR, "couldn't register the net device\n");
896 goto fail;
897 }
898
899 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
900
901 return 0;
902
903fail:
904 ndev->netdev_ops = NULL;
905 return -EBADE;
906}
907
846int 908int
847brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr) 909brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr)
848{ 910{
@@ -882,7 +944,7 @@ brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr)
882 if (mac_addr != NULL) 944 if (mac_addr != NULL)
883 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); 945 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
884 946
885 if (brcmf_net_attach(drvr, ifp->idx)) { 947 if (brcmf_net_attach(ifp)) {
886 brcmf_dbg(ERROR, "brcmf_net_attach failed"); 948 brcmf_dbg(ERROR, "brcmf_net_attach failed");
887 free_netdev(ifp->ndev); 949 free_netdev(ifp->ndev);
888 drvr->iflist[ifidx] = NULL; 950 drvr->iflist[ifidx] = NULL;
@@ -1016,69 +1078,16 @@ int brcmf_bus_start(struct device *dev)
1016 if (ret < 0) 1078 if (ret < 0)
1017 return ret; 1079 return ret;
1018 1080
1081 /* add primary networking interface */
1082 ret = brcmf_add_if(dev, 0, "wlan%d", drvr->mac);
1083 if (ret < 0)
1084 return ret;
1085
1019 /* signal bus ready */ 1086 /* signal bus ready */
1020 bus_if->state = BRCMF_BUS_DATA; 1087 bus_if->state = BRCMF_BUS_DATA;
1021 return 0; 1088 return 0;
1022} 1089}
1023 1090
1024int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
1025{
1026 struct net_device *ndev;
1027 u8 temp_addr[ETH_ALEN] = {
1028 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33};
1029
1030 brcmf_dbg(TRACE, "ifidx %d\n", ifidx);
1031
1032 ndev = drvr->iflist[ifidx]->ndev;
1033 ndev->netdev_ops = &brcmf_netdev_ops_pri;
1034
1035 /*
1036 * We have to use the primary MAC for virtual interfaces
1037 */
1038 if (ifidx != 0) {
1039 /* for virtual interfaces use the primary MAC */
1040 memcpy(temp_addr, drvr->mac, ETH_ALEN);
1041
1042 }
1043
1044 if (ifidx == 1) {
1045 brcmf_dbg(TRACE, "ACCESS POINT MAC:\n");
1046 /* ACCESSPOINT INTERFACE CASE */
1047 temp_addr[0] |= 0X02; /* set bit 2 ,
1048 - Locally Administered address */
1049
1050 }
1051 ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
1052 ndev->ethtool_ops = &brcmf_ethtool_ops;
1053
1054 drvr->rxsz = ndev->mtu + ndev->hard_header_len +
1055 drvr->hdrlen;
1056
1057 memcpy(ndev->dev_addr, temp_addr, ETH_ALEN);
1058
1059 /* attach to cfg80211 for primary interface */
1060 if (!ifidx) {
1061 drvr->config = brcmf_cfg80211_attach(ndev, drvr->dev, drvr);
1062 if (drvr->config == NULL) {
1063 brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
1064 goto fail;
1065 }
1066 }
1067
1068 if (register_netdev(ndev) != 0) {
1069 brcmf_dbg(ERROR, "couldn't register the net device\n");
1070 goto fail;
1071 }
1072
1073 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
1074
1075 return 0;
1076
1077fail:
1078 ndev->netdev_ops = NULL;
1079 return -EBADE;
1080}
1081
1082static void brcmf_bus_detach(struct brcmf_pub *drvr) 1091static void brcmf_bus_detach(struct brcmf_pub *drvr)
1083{ 1092{
1084 brcmf_dbg(TRACE, "Enter\n"); 1093 brcmf_dbg(TRACE, "Enter\n");
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 2bf5dda29291..a83fbea04c04 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -3948,12 +3948,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3948 } 3948 }
3949 } 3949 }
3950 3950
3951 /* add interface and open for business */
3952 if (brcmf_add_if(bus->sdiodev->dev, 0, "wlan%d", NULL)) {
3953 brcmf_dbg(ERROR, "Add primary net device interface failed!!\n");
3954 goto fail;
3955 }
3956
3957 return bus; 3951 return bus;
3958 3952
3959fail: 3953fail:
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 82364223e817..1d67ecf681b7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -1383,14 +1383,6 @@ static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
1383 goto fail; 1383 goto fail;
1384 } 1384 }
1385 1385
1386 /* add interface and open for business */
1387 ret = brcmf_add_if(dev, 0, "wlan%d", NULL);
1388 if (ret) {
1389 brcmf_dbg(ERROR, "Add primary net device interface failed!!\n");
1390 brcmf_detach(dev);
1391 goto fail;
1392 }
1393
1394 return 0; 1386 return 0;
1395fail: 1387fail:
1396 /* Release resources in reverse order */ 1388 /* Release resources in reverse order */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
index 55e9f45fce22..0efe88e25a9a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
@@ -628,6 +628,40 @@ brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode,
628 return false; 628 return false;
629} 629}
630 630
631/*
632 * Indicates whether the country provided is valid to pass
633 * to cfg80211 or not.
634 *
635 * returns true if valid; false if not.
636 */
637static bool brcms_c_country_valid(const char *ccode)
638{
639 /*
640 * only allow ascii alpha uppercase for the first 2
641 * chars.
642 */
643 if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A &&
644 (0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A &&
645 ccode[2] == '\0'))
646 return false;
647
648 /*
649 * do not match ISO 3166-1 user assigned country codes
650 * that may be in the driver table
651 */
652 if (!strcmp("AA", ccode) || /* AA */
653 !strcmp("ZZ", ccode) || /* ZZ */
654 ccode[0] == 'X' || /* XA - XZ */
655 (ccode[0] == 'Q' && /* QM - QZ */
656 (ccode[1] >= 'M' && ccode[1] <= 'Z')))
657 return false;
658
659 if (!strcmp("NA", ccode))
660 return false;
661
662 return true;
663}
664
631/* Lookup a country info structure from a null terminated country 665/* Lookup a country info structure from a null terminated country
632 * abbreviation and regrev directly with no translation. 666 * abbreviation and regrev directly with no translation.
633 */ 667 */
@@ -1089,7 +1123,7 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
1089 1123
1090 /* store the country code for passing up as a regulatory hint */ 1124 /* store the country code for passing up as a regulatory hint */
1091 ccode = getvar(wlc->hw->sih, BRCMS_SROM_CCODE); 1125 ccode = getvar(wlc->hw->sih, BRCMS_SROM_CCODE);
1092 if (ccode) 1126 if (ccode && brcms_c_country_valid(ccode))
1093 strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); 1127 strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
1094 1128
1095 /* 1129 /*
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 569ab8abd2a1..aa15558f75c8 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -1069,11 +1069,7 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
1069 wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status" 1069 wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
1070 "%d\n", __func__, err); 1070 "%d\n", __func__, err);
1071 1071
1072 if (wl->pub->srom_ccode[0]) 1072 if (wl->pub->srom_ccode[0] && brcms_set_hint(wl, wl->pub->srom_ccode))
1073 err = brcms_set_hint(wl, wl->pub->srom_ccode);
1074 else
1075 err = brcms_set_hint(wl, "US");
1076 if (err)
1077 wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n", 1073 wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n",
1078 __func__, err); 1074 __func__, err);
1079 1075
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index ce8562aa5db0..0fce56235f38 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -207,8 +207,7 @@ static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = {
207}; 207};
208 208
209static const u16 iqcal_gainparams_numgains_lcnphy[1] = { 209static const u16 iqcal_gainparams_numgains_lcnphy[1] = {
210 sizeof(tbl_iqcal_gainparams_lcnphy_2G) / 210 ARRAY_SIZE(tbl_iqcal_gainparams_lcnphy_2G),
211 sizeof(*tbl_iqcal_gainparams_lcnphy_2G),
212}; 211};
213 212
214static const struct lcnphy_sfo_cfg lcnphy_sfo_cfg[] = { 213static const struct lcnphy_sfo_cfg lcnphy_sfo_cfg[] = {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
index 39095741fd05..812b6e38526e 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
@@ -16353,11 +16353,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
16353 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, 16353 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
16354 rfseq_rx2tx_events_rev3_ipa, 16354 rfseq_rx2tx_events_rev3_ipa,
16355 rfseq_rx2tx_dlys_rev3_ipa, 16355 rfseq_rx2tx_dlys_rev3_ipa,
16356 sizeof 16356 ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
16357 (rfseq_rx2tx_events_rev3_ipa) /
16358 sizeof
16359 (rfseq_rx2tx_events_rev3_ipa
16360 [0]));
16361 16357
16362 mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14)); 16358 mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
16363 mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14)); 16359 mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
@@ -16858,18 +16854,13 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
16858 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, 16854 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
16859 rfseq_tx2rx_events_rev3, 16855 rfseq_tx2rx_events_rev3,
16860 rfseq_tx2rx_dlys_rev3, 16856 rfseq_tx2rx_dlys_rev3,
16861 sizeof(rfseq_tx2rx_events_rev3) / 16857 ARRAY_SIZE(rfseq_tx2rx_events_rev3));
16862 sizeof(rfseq_tx2rx_events_rev3[0]));
16863 16858
16864 if (PHY_IPA(pi)) 16859 if (PHY_IPA(pi))
16865 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, 16860 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
16866 rfseq_rx2tx_events_rev3_ipa, 16861 rfseq_rx2tx_events_rev3_ipa,
16867 rfseq_rx2tx_dlys_rev3_ipa, 16862 rfseq_rx2tx_dlys_rev3_ipa,
16868 sizeof 16863 ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
16869 (rfseq_rx2tx_events_rev3_ipa) /
16870 sizeof
16871 (rfseq_rx2tx_events_rev3_ipa
16872 [0]));
16873 16864
16874 if ((pi->sh->hw_phyrxchain != 0x3) && 16865 if ((pi->sh->hw_phyrxchain != 0x3) &&
16875 (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) { 16866 (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
@@ -16885,8 +16876,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
16885 pi, NPHY_RFSEQ_RX2TX, 16876 pi, NPHY_RFSEQ_RX2TX,
16886 rfseq_rx2tx_events_rev3, 16877 rfseq_rx2tx_events_rev3,
16887 rfseq_rx2tx_dlys_rev3, 16878 rfseq_rx2tx_dlys_rev3,
16888 sizeof(rfseq_rx2tx_events_rev3) / 16879 ARRAY_SIZE(rfseq_rx2tx_events_rev3));
16889 sizeof(rfseq_rx2tx_events_rev3[0]));
16890 } 16880 }
16891 16881
16892 if (CHSPEC_IS2G(pi->radio_chanspec)) 16882 if (CHSPEC_IS2G(pi->radio_chanspec))
@@ -17209,13 +17199,11 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
17209 17199
17210 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events, 17200 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
17211 rfseq_rx2tx_dlys, 17201 rfseq_rx2tx_dlys,
17212 sizeof(rfseq_rx2tx_events) / 17202 ARRAY_SIZE(rfseq_rx2tx_events));
17213 sizeof(rfseq_rx2tx_events[0]));
17214 17203
17215 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events, 17204 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
17216 rfseq_tx2rx_dlys, 17205 rfseq_tx2rx_dlys,
17217 sizeof(rfseq_tx2rx_events) / 17206 ARRAY_SIZE(rfseq_tx2rx_events));
17218 sizeof(rfseq_tx2rx_events[0]));
17219 17207
17220 wlc_phy_workarounds_nphy_gainctrl(pi); 17208 wlc_phy_workarounds_nphy_gainctrl(pi);
17221 17209
@@ -19357,8 +19345,7 @@ static void wlc_phy_spurwar_nphy(struct brcms_phy *pi)
19357 } 19345 }
19358 19346
19359 if (isAdjustNoiseVar) { 19347 if (isAdjustNoiseVar) {
19360 numTonesAdjust = sizeof(nphy_adj_tone_id_buf) / 19348 numTonesAdjust = ARRAY_SIZE(nphy_adj_tone_id_buf);
19361 sizeof(nphy_adj_tone_id_buf[0]);
19362 19349
19363 wlc_phy_adjust_min_noisevar_nphy( 19350 wlc_phy_adjust_min_noisevar_nphy(
19364 pi, 19351 pi,
@@ -25204,32 +25191,26 @@ static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core)
25204 25191
25205 phy_a15 = pad_gain_codes_used_2057rev5; 25192 phy_a15 = pad_gain_codes_used_2057rev5;
25206 phy_a13 = 25193 phy_a13 =
25207 sizeof(pad_gain_codes_used_2057rev5) / 25194 ARRAY_SIZE(pad_gain_codes_used_2057rev5) - 1;
25208 sizeof(pad_gain_codes_used_2057rev5
25209 [0]) - 1;
25210 25195
25211 } else if ((pi->pubpi.radiorev == 7) 25196 } else if ((pi->pubpi.radiorev == 7)
25212 || (pi->pubpi.radiorev == 8)) { 25197 || (pi->pubpi.radiorev == 8)) {
25213 25198
25214 phy_a15 = pad_gain_codes_used_2057rev7; 25199 phy_a15 = pad_gain_codes_used_2057rev7;
25215 phy_a13 = 25200 phy_a13 =
25216 sizeof(pad_gain_codes_used_2057rev7) / 25201 ARRAY_SIZE(pad_gain_codes_used_2057rev7) - 1;
25217 sizeof(pad_gain_codes_used_2057rev7
25218 [0]) - 1;
25219 25202
25220 } else { 25203 } else {
25221 25204
25222 phy_a15 = pad_all_gain_codes_2057; 25205 phy_a15 = pad_all_gain_codes_2057;
25223 phy_a13 = sizeof(pad_all_gain_codes_2057) / 25206 phy_a13 = ARRAY_SIZE(pad_all_gain_codes_2057) -
25224 sizeof(pad_all_gain_codes_2057[0]) -
25225 1; 25207 1;
25226 } 25208 }
25227 25209
25228 } else { 25210 } else {
25229 25211
25230 phy_a15 = pga_all_gain_codes_2057; 25212 phy_a15 = pga_all_gain_codes_2057;
25231 phy_a13 = sizeof(pga_all_gain_codes_2057) / 25213 phy_a13 = ARRAY_SIZE(pga_all_gain_codes_2057) - 1;
25232 sizeof(pga_all_gain_codes_2057[0]) - 1;
25233 } 25214 }
25234 25215
25235 phy_a14 = 0; 25216 phy_a14 = 0;
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
index 5fb17d53c9b2..333193f20e1c 100644
--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -17,17 +17,7 @@
17#ifndef _BRCM_HW_IDS_H_ 17#ifndef _BRCM_HW_IDS_H_
18#define _BRCM_HW_IDS_H_ 18#define _BRCM_HW_IDS_H_
19 19
20#define BCM4325_D11DUAL_ID 0x431b 20#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
21#define BCM4325_D11G_ID 0x431c
22#define BCM4325_D11A_ID 0x431d
23
24#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */
25#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */
26#define BCM4329_D11NDUAL_ID 0x432e
27
28#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */
29#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */
30#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */
31 21
32#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ 22#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */
33#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */ 23#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */
@@ -37,23 +27,15 @@
37#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */ 27#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */
38#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */ 28#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */
39 29
40#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ 30/* Chipcommon Core Chip IDs */
41 31#define BCM4313_CHIP_ID 0x4313
42/* Chip IDs */ 32#define BCM43224_CHIP_ID 43224
43#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */ 33#define BCM43225_CHIP_ID 43225
44#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */ 34#define BCM43235_CHIP_ID 43235
45 35#define BCM43236_CHIP_ID 43236
46#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */ 36#define BCM43238_CHIP_ID 43238
47#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */ 37#define BCM4329_CHIP_ID 0x4329
48#define BCM43421_CHIP_ID 43421 /* 43421 chipcommon chipid */ 38#define BCM4330_CHIP_ID 0x4330
49#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */ 39#define BCM4331_CHIP_ID 0x4331
50#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */
51#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */
52#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */
53#define BCM4325_CHIP_ID 0x4325 /* 4325 chipcommon chipid */
54#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */
55#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */
56#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */
57#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */
58 40
59#endif /* _BRCM_HW_IDS_H_ */ 41#endif /* _BRCM_HW_IDS_H_ */
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index bfa0d54221e8..627bc12074c7 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -244,8 +244,7 @@ u16 hostap_tx_callback_register(local_info_t *local,
244 unsigned long flags; 244 unsigned long flags;
245 struct hostap_tx_callback_info *entry; 245 struct hostap_tx_callback_info *entry;
246 246
247 entry = kmalloc(sizeof(*entry), 247 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
248 GFP_ATOMIC);
249 if (entry == NULL) 248 if (entry == NULL)
250 return 0; 249 return 0;
251 250
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 972a9c3af39e..05ca3402dca7 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -457,18 +457,4 @@ static struct pci_driver prism2_pci_driver = {
457#endif /* CONFIG_PM */ 457#endif /* CONFIG_PM */
458}; 458};
459 459
460 460module_pci_driver(prism2_pci_driver);
461static int __init init_prism2_pci(void)
462{
463 return pci_register_driver(&prism2_pci_driver);
464}
465
466
467static void __exit exit_prism2_pci(void)
468{
469 pci_unregister_driver(&prism2_pci_driver);
470}
471
472
473module_init(init_prism2_pci);
474module_exit(exit_prism2_pci);
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 33e79037770b..c3d067ee4db9 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -616,18 +616,4 @@ static struct pci_driver prism2_plx_driver = {
616 .remove = prism2_plx_remove, 616 .remove = prism2_plx_remove,
617}; 617};
618 618
619 619module_pci_driver(prism2_plx_driver);
620static int __init init_prism2_plx(void)
621{
622 return pci_register_driver(&prism2_plx_driver);
623}
624
625
626static void __exit exit_prism2_plx(void)
627{
628 pci_unregister_driver(&prism2_plx_driver);
629}
630
631
632module_init(init_prism2_plx);
633module_exit(exit_prism2_plx);
diff --git a/drivers/net/wireless/ipw2x00/ipw.h b/drivers/net/wireless/ipw2x00/ipw.h
new file mode 100644
index 000000000000..4007bf5ed6f3
--- /dev/null
+++ b/drivers/net/wireless/ipw2x00/ipw.h
@@ -0,0 +1,23 @@
1/*
2 * Intel Pro/Wireless 2100, 2200BG, 2915ABG network connection driver
3 *
4 * Copyright 2012 Stanislav Yakovlev <stas.yakovlev@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __IPW_H__
12#define __IPW_H__
13
14#include <linux/ieee80211.h>
15
16static const u32 ipw_cipher_suites[] = {
17 WLAN_CIPHER_SUITE_WEP40,
18 WLAN_CIPHER_SUITE_WEP104,
19 WLAN_CIPHER_SUITE_TKIP,
20 WLAN_CIPHER_SUITE_CCMP,
21};
22
23#endif
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 2662d46134d0..c72136c07774 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -166,6 +166,7 @@ that only one external action is invoked at a time.
166#include <net/lib80211.h> 166#include <net/lib80211.h>
167 167
168#include "ipw2100.h" 168#include "ipw2100.h"
169#include "ipw.h"
169 170
170#define IPW2100_VERSION "git-1.2.2" 171#define IPW2100_VERSION "git-1.2.2"
171 172
@@ -1958,6 +1959,9 @@ static int ipw2100_wdev_init(struct net_device *dev)
1958 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band; 1959 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
1959 } 1960 }
1960 1961
1962 wdev->wiphy->cipher_suites = ipw_cipher_suites;
1963 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites);
1964
1961 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); 1965 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
1962 if (wiphy_register(wdev->wiphy)) { 1966 if (wiphy_register(wdev->wiphy)) {
1963 ipw2100_down(priv); 1967 ipw2100_down(priv);
@@ -8503,8 +8507,7 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
8503 struct ipw2100_fw *fw) 8507 struct ipw2100_fw *fw)
8504{ 8508{
8505 fw->version = 0; 8509 fw->version = 0;
8506 if (fw->fw_entry) 8510 release_firmware(fw->fw_entry);
8507 release_firmware(fw->fw_entry);
8508 fw->fw_entry = NULL; 8511 fw->fw_entry = NULL;
8509} 8512}
8510 8513
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 809b7a70974b..d57522c64073 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -34,6 +34,7 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <net/cfg80211-wext.h> 35#include <net/cfg80211-wext.h>
36#include "ipw2200.h" 36#include "ipw2200.h"
37#include "ipw.h"
37 38
38 39
39#ifndef KBUILD_EXTMOD 40#ifndef KBUILD_EXTMOD
@@ -3657,8 +3658,7 @@ static int ipw_load(struct ipw_priv *priv)
3657 priv->rxq = NULL; 3658 priv->rxq = NULL;
3658 } 3659 }
3659 ipw_tx_queue_free(priv); 3660 ipw_tx_queue_free(priv);
3660 if (raw) 3661 release_firmware(raw);
3661 release_firmware(raw);
3662#ifdef CONFIG_PM 3662#ifdef CONFIG_PM
3663 fw_loaded = 0; 3663 fw_loaded = 0;
3664 raw = NULL; 3664 raw = NULL;
@@ -11533,6 +11533,9 @@ static int ipw_wdev_init(struct net_device *dev)
11533 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band; 11533 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
11534 } 11534 }
11535 11535
11536 wdev->wiphy->cipher_suites = ipw_cipher_suites;
11537 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites);
11538
11536 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); 11539 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
11537 11540
11538 /* With that information in place, we can now register the wiphy... */ 11541 /* With that information in place, we can now register the wiphy... */
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 565611eef0d4..db6c6e528022 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -113,20 +113,21 @@ config IWLWIFI_DEVICE_TESTMODE
113 generic netlink message via NL80211_TESTMODE channel. 113 generic netlink message via NL80211_TESTMODE channel.
114 114
115config IWLWIFI_P2P 115config IWLWIFI_P2P
116 bool "iwlwifi experimental P2P support" 116 def_bool y
117 depends on IWLWIFI 117 bool "iwlwifi experimental P2P support"
118 help 118 depends on IWLWIFI
119 This option enables experimental P2P support for some devices 119 help
120 based on microcode support. Since P2P support is still under 120 This option enables experimental P2P support for some devices
121 development, this option may even enable it for some devices 121 based on microcode support. Since P2P support is still under
122 now that turn out to not support it in the future due to 122 development, this option may even enable it for some devices
123 microcode restrictions. 123 now that turn out to not support it in the future due to
124 124 microcode restrictions.
125 To determine if your microcode supports the experimental P2P 125
126 offered by this option, check if the driver advertises AP 126 To determine if your microcode supports the experimental P2P
127 support when it is loaded. 127 offered by this option, check if the driver advertises AP
128 128 support when it is loaded.
129 Say Y only if you want to experiment with P2P. 129
130 Say Y only if you want to experiment with P2P.
130 131
131config IWLWIFI_EXPERIMENTAL_MFP 132config IWLWIFI_EXPERIMENTAL_MFP
132 bool "support MFP (802.11w) even if uCode doesn't advertise" 133 bool "support MFP (802.11w) even if uCode doesn't advertise"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index c7c4a995dfe5..f2cd67874cf4 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -7,7 +7,7 @@ iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o
7 7
8iwlwifi-objs += iwl-core.o iwl-eeprom.o iwl-power.o 8iwlwifi-objs += iwl-core.o iwl-eeprom.o iwl-power.o
9iwlwifi-objs += iwl-scan.o iwl-led.o 9iwlwifi-objs += iwl-scan.o iwl-led.o
10iwlwifi-objs += iwl-agn-rxon.o 10iwlwifi-objs += iwl-agn-rxon.o iwl-agn-devices.o
11iwlwifi-objs += iwl-5000.o 11iwlwifi-objs += iwl-5000.o
12iwlwifi-objs += iwl-6000.o 12iwlwifi-objs += iwl-6000.o
13iwlwifi-objs += iwl-1000.o 13iwlwifi-objs += iwl-1000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 95c59e39b803..e9006078f4e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -24,26 +24,11 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/skbuff.h>
32#include <linux/netdevice.h>
33#include <net/mac80211.h>
34#include <linux/etherdevice.h>
35#include <asm/unaligned.h>
36#include <linux/stringify.h> 28#include <linux/stringify.h>
37 29#include "iwl-config.h"
38#include "iwl-eeprom.h"
39#include "iwl-dev.h"
40#include "iwl-core.h"
41#include "iwl-io.h"
42#include "iwl-agn.h"
43#include "iwl-agn-hw.h"
44#include "iwl-shared.h"
45#include "iwl-cfg.h" 30#include "iwl-cfg.h"
46#include "iwl-prph.h" 31#include "iwl-dev.h" /* still needed */
47 32
48/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
49#define IWL1000_UCODE_API_MAX 6 34#define IWL1000_UCODE_API_MAX 6
@@ -64,97 +49,6 @@
64#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode" 49#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode"
65 50
66 51
67/*
68 * For 1000, use advance thermal throttling critical temperature threshold,
69 * but legacy thermal management implementation for now.
70 * This is for the reason of 1000 uCode using advance thermal throttling API
71 * but not implement ct_kill_exit based on ct_kill exit temperature
72 * so the thermal throttling will still based on legacy thermal throttling
73 * management.
74 * The code here need to be modified once 1000 uCode has the advanced thermal
75 * throttling algorithm in place
76 */
77static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
78{
79 /* want Celsius */
80 hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
81 hw_params(priv).ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
82}
83
84/* NIC configuration for 1000 series */
85static void iwl1000_nic_config(struct iwl_priv *priv)
86{
87 /* set CSR_HW_CONFIG_REG for uCode use */
88 iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
89 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
90 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
91
92 /* Setting digital SVR for 1000 card to 1.32V */
93 /* locking is acquired in iwl_set_bits_mask_prph() function */
94 iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG,
95 APMG_SVR_DIGITAL_VOLTAGE_1_32,
96 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
97}
98
99static const struct iwl_sensitivity_ranges iwl1000_sensitivity = {
100 .min_nrg_cck = 95,
101 .auto_corr_min_ofdm = 90,
102 .auto_corr_min_ofdm_mrc = 170,
103 .auto_corr_min_ofdm_x1 = 120,
104 .auto_corr_min_ofdm_mrc_x1 = 240,
105
106 .auto_corr_max_ofdm = 120,
107 .auto_corr_max_ofdm_mrc = 210,
108 .auto_corr_max_ofdm_x1 = 155,
109 .auto_corr_max_ofdm_mrc_x1 = 290,
110
111 .auto_corr_min_cck = 125,
112 .auto_corr_max_cck = 200,
113 .auto_corr_min_cck_mrc = 170,
114 .auto_corr_max_cck_mrc = 400,
115 .nrg_th_cck = 95,
116 .nrg_th_ofdm = 95,
117
118 .barker_corr_th_min = 190,
119 .barker_corr_th_min_mrc = 390,
120 .nrg_th_cca = 62,
121};
122
123static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
124{
125 hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ);
126
127 hw_params(priv).tx_chains_num =
128 num_of_ant(hw_params(priv).valid_tx_ant);
129 if (cfg(priv)->rx_with_siso_diversity)
130 hw_params(priv).rx_chains_num = 1;
131 else
132 hw_params(priv).rx_chains_num =
133 num_of_ant(hw_params(priv).valid_rx_ant);
134
135 iwl1000_set_ct_threshold(priv);
136
137 /* Set initial sensitivity parameters */
138 hw_params(priv).sens = &iwl1000_sensitivity;
139}
140
141static struct iwl_lib_ops iwl1000_lib = {
142 .set_hw_params = iwl1000_hw_set_hw_params,
143 .nic_config = iwl1000_nic_config,
144 .eeprom_ops = {
145 .regulatory_bands = {
146 EEPROM_REG_BAND_1_CHANNELS,
147 EEPROM_REG_BAND_2_CHANNELS,
148 EEPROM_REG_BAND_3_CHANNELS,
149 EEPROM_REG_BAND_4_CHANNELS,
150 EEPROM_REG_BAND_5_CHANNELS,
151 EEPROM_REG_BAND_24_HT40_CHANNELS,
152 EEPROM_REGULATORY_BAND_NO_HT40,
153 },
154 },
155 .temperature = iwlagn_temperature,
156};
157
158static const struct iwl_base_params iwl1000_base_params = { 52static const struct iwl_base_params iwl1000_base_params = {
159 .num_of_queues = IWLAGN_NUM_QUEUES, 53 .num_of_queues = IWLAGN_NUM_QUEUES,
160 .eeprom_size = OTP_LOW_IMAGE_SIZE, 54 .eeprom_size = OTP_LOW_IMAGE_SIZE,
@@ -165,9 +59,8 @@ static const struct iwl_base_params iwl1000_base_params = {
165 .support_ct_kill_exit = true, 59 .support_ct_kill_exit = true,
166 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, 60 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
167 .chain_noise_scale = 1000, 61 .chain_noise_scale = 1000,
168 .wd_timeout = IWL_DEF_WD_TIMEOUT, 62 .wd_timeout = IWL_WATCHHDOG_DISABLED,
169 .max_event_log_size = 128, 63 .max_event_log_size = 128,
170 .wd_disable = true,
171}; 64};
172 65
173static const struct iwl_ht_params iwl1000_ht_params = { 66static const struct iwl_ht_params iwl1000_ht_params = {
@@ -181,11 +74,11 @@ static const struct iwl_ht_params iwl1000_ht_params = {
181 .ucode_api_max = IWL1000_UCODE_API_MAX, \ 74 .ucode_api_max = IWL1000_UCODE_API_MAX, \
182 .ucode_api_ok = IWL1000_UCODE_API_OK, \ 75 .ucode_api_ok = IWL1000_UCODE_API_OK, \
183 .ucode_api_min = IWL1000_UCODE_API_MIN, \ 76 .ucode_api_min = IWL1000_UCODE_API_MIN, \
77 .device_family = IWL_DEVICE_FAMILY_1000, \
184 .max_inst_size = IWLAGN_RTC_INST_SIZE, \ 78 .max_inst_size = IWLAGN_RTC_INST_SIZE, \
185 .max_data_size = IWLAGN_RTC_DATA_SIZE, \ 79 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
186 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ 80 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
187 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ 81 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
188 .lib = &iwl1000_lib, \
189 .base_params = &iwl1000_base_params, \ 82 .base_params = &iwl1000_base_params, \
190 .led_mode = IWL_LED_BLINK 83 .led_mode = IWL_LED_BLINK
191 84
@@ -205,11 +98,11 @@ const struct iwl_cfg iwl1000_bg_cfg = {
205 .ucode_api_max = IWL100_UCODE_API_MAX, \ 98 .ucode_api_max = IWL100_UCODE_API_MAX, \
206 .ucode_api_ok = IWL100_UCODE_API_OK, \ 99 .ucode_api_ok = IWL100_UCODE_API_OK, \
207 .ucode_api_min = IWL100_UCODE_API_MIN, \ 100 .ucode_api_min = IWL100_UCODE_API_MIN, \
101 .device_family = IWL_DEVICE_FAMILY_100, \
208 .max_inst_size = IWLAGN_RTC_INST_SIZE, \ 102 .max_inst_size = IWLAGN_RTC_INST_SIZE, \
209 .max_data_size = IWLAGN_RTC_DATA_SIZE, \ 103 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
210 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ 104 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
211 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ 105 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
212 .lib = &iwl1000_lib, \
213 .base_params = &iwl1000_base_params, \ 106 .base_params = &iwl1000_base_params, \
214 .led_mode = IWL_LED_RF_STATE, \ 107 .led_mode = IWL_LED_RF_STATE, \
215 .rx_with_siso_diversity = true 108 .rx_with_siso_diversity = true
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index e1329a13f0fd..3d4a36cf0408 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -24,25 +24,11 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/skbuff.h>
32#include <linux/netdevice.h>
33#include <net/mac80211.h>
34#include <linux/etherdevice.h>
35#include <asm/unaligned.h>
36#include <linux/stringify.h> 28#include <linux/stringify.h>
37 29#include "iwl-config.h"
38#include "iwl-eeprom.h"
39#include "iwl-dev.h"
40#include "iwl-core.h"
41#include "iwl-io.h"
42#include "iwl-agn.h"
43#include "iwl-agn-hw.h"
44#include "iwl-shared.h"
45#include "iwl-cfg.h" 30#include "iwl-cfg.h"
31#include "iwl-dev.h" /* still needed */
46 32
47/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
48#define IWL2030_UCODE_API_MAX 6 34#define IWL2030_UCODE_API_MAX 6
@@ -74,100 +60,6 @@
74#define IWL135_FW_PRE "iwlwifi-135-" 60#define IWL135_FW_PRE "iwlwifi-135-"
75#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode" 61#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode"
76 62
77static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
78{
79 /* want Celsius */
80 hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD;
81 hw_params(priv).ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
82}
83
84/* NIC configuration for 2000 series */
85static void iwl2000_nic_config(struct iwl_priv *priv)
86{
87 iwl_rf_config(priv);
88
89 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
90 CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
91}
92
93static const struct iwl_sensitivity_ranges iwl2000_sensitivity = {
94 .min_nrg_cck = 97,
95 .auto_corr_min_ofdm = 80,
96 .auto_corr_min_ofdm_mrc = 128,
97 .auto_corr_min_ofdm_x1 = 105,
98 .auto_corr_min_ofdm_mrc_x1 = 192,
99
100 .auto_corr_max_ofdm = 145,
101 .auto_corr_max_ofdm_mrc = 232,
102 .auto_corr_max_ofdm_x1 = 110,
103 .auto_corr_max_ofdm_mrc_x1 = 232,
104
105 .auto_corr_min_cck = 125,
106 .auto_corr_max_cck = 175,
107 .auto_corr_min_cck_mrc = 160,
108 .auto_corr_max_cck_mrc = 310,
109 .nrg_th_cck = 97,
110 .nrg_th_ofdm = 100,
111
112 .barker_corr_th_min = 190,
113 .barker_corr_th_min_mrc = 390,
114 .nrg_th_cca = 62,
115};
116
117static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
118{
119 hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ);
120
121 hw_params(priv).tx_chains_num =
122 num_of_ant(hw_params(priv).valid_tx_ant);
123 if (cfg(priv)->rx_with_siso_diversity)
124 hw_params(priv).rx_chains_num = 1;
125 else
126 hw_params(priv).rx_chains_num =
127 num_of_ant(hw_params(priv).valid_rx_ant);
128
129 iwl2000_set_ct_threshold(priv);
130
131 /* Set initial sensitivity parameters */
132 hw_params(priv).sens = &iwl2000_sensitivity;
133}
134
135static struct iwl_lib_ops iwl2000_lib = {
136 .set_hw_params = iwl2000_hw_set_hw_params,
137 .nic_config = iwl2000_nic_config,
138 .eeprom_ops = {
139 .regulatory_bands = {
140 EEPROM_REG_BAND_1_CHANNELS,
141 EEPROM_REG_BAND_2_CHANNELS,
142 EEPROM_REG_BAND_3_CHANNELS,
143 EEPROM_REG_BAND_4_CHANNELS,
144 EEPROM_REG_BAND_5_CHANNELS,
145 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
146 EEPROM_REGULATORY_BAND_NO_HT40,
147 },
148 .enhanced_txpower = true,
149 },
150 .temperature = iwlagn_temperature,
151};
152
153static struct iwl_lib_ops iwl2030_lib = {
154 .set_hw_params = iwl2000_hw_set_hw_params,
155 .nic_config = iwl2000_nic_config,
156 .eeprom_ops = {
157 .regulatory_bands = {
158 EEPROM_REG_BAND_1_CHANNELS,
159 EEPROM_REG_BAND_2_CHANNELS,
160 EEPROM_REG_BAND_3_CHANNELS,
161 EEPROM_REG_BAND_4_CHANNELS,
162 EEPROM_REG_BAND_5_CHANNELS,
163 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
164 EEPROM_REGULATORY_BAND_NO_HT40,
165 },
166 .enhanced_txpower = true,
167 },
168 .temperature = iwlagn_temperature,
169};
170
171static const struct iwl_base_params iwl2000_base_params = { 63static const struct iwl_base_params iwl2000_base_params = {
172 .eeprom_size = OTP_LOW_IMAGE_SIZE, 64 .eeprom_size = OTP_LOW_IMAGE_SIZE,
173 .num_of_queues = IWLAGN_NUM_QUEUES, 65 .num_of_queues = IWLAGN_NUM_QUEUES,
@@ -223,11 +115,11 @@ static const struct iwl_bt_params iwl2030_bt_params = {
223 .ucode_api_max = IWL2000_UCODE_API_MAX, \ 115 .ucode_api_max = IWL2000_UCODE_API_MAX, \
224 .ucode_api_ok = IWL2000_UCODE_API_OK, \ 116 .ucode_api_ok = IWL2000_UCODE_API_OK, \
225 .ucode_api_min = IWL2000_UCODE_API_MIN, \ 117 .ucode_api_min = IWL2000_UCODE_API_MIN, \
118 .device_family = IWL_DEVICE_FAMILY_2000, \
226 .max_inst_size = IWL60_RTC_INST_SIZE, \ 119 .max_inst_size = IWL60_RTC_INST_SIZE, \
227 .max_data_size = IWL60_RTC_DATA_SIZE, \ 120 .max_data_size = IWL60_RTC_DATA_SIZE, \
228 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 121 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
229 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 122 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
230 .lib = &iwl2000_lib, \
231 .base_params = &iwl2000_base_params, \ 123 .base_params = &iwl2000_base_params, \
232 .need_temp_offset_calib = true, \ 124 .need_temp_offset_calib = true, \
233 .temp_offset_v2 = true, \ 125 .temp_offset_v2 = true, \
@@ -250,11 +142,11 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = {
250 .ucode_api_max = IWL2030_UCODE_API_MAX, \ 142 .ucode_api_max = IWL2030_UCODE_API_MAX, \
251 .ucode_api_ok = IWL2030_UCODE_API_OK, \ 143 .ucode_api_ok = IWL2030_UCODE_API_OK, \
252 .ucode_api_min = IWL2030_UCODE_API_MIN, \ 144 .ucode_api_min = IWL2030_UCODE_API_MIN, \
145 .device_family = IWL_DEVICE_FAMILY_2030, \
253 .max_inst_size = IWL60_RTC_INST_SIZE, \ 146 .max_inst_size = IWL60_RTC_INST_SIZE, \
254 .max_data_size = IWL60_RTC_DATA_SIZE, \ 147 .max_data_size = IWL60_RTC_DATA_SIZE, \
255 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 148 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
256 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 149 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
257 .lib = &iwl2030_lib, \
258 .base_params = &iwl2030_base_params, \ 150 .base_params = &iwl2030_base_params, \
259 .bt_params = &iwl2030_bt_params, \ 151 .bt_params = &iwl2030_bt_params, \
260 .need_temp_offset_calib = true, \ 152 .need_temp_offset_calib = true, \
@@ -273,11 +165,11 @@ const struct iwl_cfg iwl2030_2bgn_cfg = {
273 .ucode_api_max = IWL105_UCODE_API_MAX, \ 165 .ucode_api_max = IWL105_UCODE_API_MAX, \
274 .ucode_api_ok = IWL105_UCODE_API_OK, \ 166 .ucode_api_ok = IWL105_UCODE_API_OK, \
275 .ucode_api_min = IWL105_UCODE_API_MIN, \ 167 .ucode_api_min = IWL105_UCODE_API_MIN, \
168 .device_family = IWL_DEVICE_FAMILY_105, \
276 .max_inst_size = IWL60_RTC_INST_SIZE, \ 169 .max_inst_size = IWL60_RTC_INST_SIZE, \
277 .max_data_size = IWL60_RTC_DATA_SIZE, \ 170 .max_data_size = IWL60_RTC_DATA_SIZE, \
278 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 171 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
279 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 172 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
280 .lib = &iwl2000_lib, \
281 .base_params = &iwl2000_base_params, \ 173 .base_params = &iwl2000_base_params, \
282 .need_temp_offset_calib = true, \ 174 .need_temp_offset_calib = true, \
283 .temp_offset_v2 = true, \ 175 .temp_offset_v2 = true, \
@@ -302,11 +194,11 @@ const struct iwl_cfg iwl105_bgn_d_cfg = {
302 .ucode_api_max = IWL135_UCODE_API_MAX, \ 194 .ucode_api_max = IWL135_UCODE_API_MAX, \
303 .ucode_api_ok = IWL135_UCODE_API_OK, \ 195 .ucode_api_ok = IWL135_UCODE_API_OK, \
304 .ucode_api_min = IWL135_UCODE_API_MIN, \ 196 .ucode_api_min = IWL135_UCODE_API_MIN, \
197 .device_family = IWL_DEVICE_FAMILY_135, \
305 .max_inst_size = IWL60_RTC_INST_SIZE, \ 198 .max_inst_size = IWL60_RTC_INST_SIZE, \
306 .max_data_size = IWL60_RTC_DATA_SIZE, \ 199 .max_data_size = IWL60_RTC_DATA_SIZE, \
307 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 200 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
308 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 201 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
309 .lib = &iwl2030_lib, \
310 .base_params = &iwl2030_base_params, \ 202 .base_params = &iwl2030_base_params, \
311 .bt_params = &iwl2030_bt_params, \ 203 .bt_params = &iwl2030_bt_params, \
312 .need_temp_offset_calib = true, \ 204 .need_temp_offset_calib = true, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 34bc8dd0064b..ffa9ac5fe086 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -24,28 +24,11 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/sched.h>
32#include <linux/skbuff.h>
33#include <linux/netdevice.h>
34#include <net/mac80211.h>
35#include <linux/etherdevice.h>
36#include <asm/unaligned.h>
37#include <linux/stringify.h> 28#include <linux/stringify.h>
38 29#include "iwl-config.h"
39#include "iwl-eeprom.h"
40#include "iwl-dev.h"
41#include "iwl-core.h"
42#include "iwl-io.h"
43#include "iwl-agn.h"
44#include "iwl-agn-hw.h"
45#include "iwl-trans.h"
46#include "iwl-shared.h"
47#include "iwl-cfg.h" 30#include "iwl-cfg.h"
48#include "iwl-prph.h" 31#include "iwl-dev.h" /* still needed */
49 32
50/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
51#define IWL5000_UCODE_API_MAX 5 34#define IWL5000_UCODE_API_MAX 5
@@ -61,250 +44,6 @@
61#define IWL5150_FW_PRE "iwlwifi-5150-" 44#define IWL5150_FW_PRE "iwlwifi-5150-"
62#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode" 45#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode"
63 46
64/* NIC configuration for 5000 series */
65static void iwl5000_nic_config(struct iwl_priv *priv)
66{
67 iwl_rf_config(priv);
68
69 /* W/A : NIC is stuck in a reset state after Early PCIe power off
70 * (PCIe power is lost before PERST# is asserted),
71 * causing ME FW to lose ownership and not being able to obtain it back.
72 */
73 iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG,
74 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
75 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
76}
77
78static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
79 .min_nrg_cck = 100,
80 .auto_corr_min_ofdm = 90,
81 .auto_corr_min_ofdm_mrc = 170,
82 .auto_corr_min_ofdm_x1 = 105,
83 .auto_corr_min_ofdm_mrc_x1 = 220,
84
85 .auto_corr_max_ofdm = 120,
86 .auto_corr_max_ofdm_mrc = 210,
87 .auto_corr_max_ofdm_x1 = 120,
88 .auto_corr_max_ofdm_mrc_x1 = 240,
89
90 .auto_corr_min_cck = 125,
91 .auto_corr_max_cck = 200,
92 .auto_corr_min_cck_mrc = 200,
93 .auto_corr_max_cck_mrc = 400,
94 .nrg_th_cck = 100,
95 .nrg_th_ofdm = 100,
96
97 .barker_corr_th_min = 190,
98 .barker_corr_th_min_mrc = 390,
99 .nrg_th_cca = 62,
100};
101
102static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
103 .min_nrg_cck = 95,
104 .auto_corr_min_ofdm = 90,
105 .auto_corr_min_ofdm_mrc = 170,
106 .auto_corr_min_ofdm_x1 = 105,
107 .auto_corr_min_ofdm_mrc_x1 = 220,
108
109 .auto_corr_max_ofdm = 120,
110 .auto_corr_max_ofdm_mrc = 210,
111 /* max = min for performance bug in 5150 DSP */
112 .auto_corr_max_ofdm_x1 = 105,
113 .auto_corr_max_ofdm_mrc_x1 = 220,
114
115 .auto_corr_min_cck = 125,
116 .auto_corr_max_cck = 200,
117 .auto_corr_min_cck_mrc = 170,
118 .auto_corr_max_cck_mrc = 400,
119 .nrg_th_cck = 95,
120 .nrg_th_ofdm = 95,
121
122 .barker_corr_th_min = 190,
123 .barker_corr_th_min_mrc = 390,
124 .nrg_th_cca = 62,
125};
126
127#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
128
129static s32 iwl_temp_calib_to_offset(struct iwl_shared *shrd)
130{
131 u16 temperature, voltage;
132 __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(shrd,
133 EEPROM_KELVIN_TEMPERATURE);
134
135 temperature = le16_to_cpu(temp_calib[0]);
136 voltage = le16_to_cpu(temp_calib[1]);
137
138 /* offset = temp - volt / coeff */
139 return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
140}
141
142static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
143{
144 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
145 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) -
146 iwl_temp_calib_to_offset(priv->shrd);
147
148 hw_params(priv).ct_kill_threshold = threshold * volt2temp_coef;
149}
150
151static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
152{
153 /* want Celsius */
154 hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
155}
156
157static void iwl5000_hw_set_hw_params(struct iwl_priv *priv)
158{
159 hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
160 BIT(IEEE80211_BAND_5GHZ);
161
162 hw_params(priv).tx_chains_num =
163 num_of_ant(hw_params(priv).valid_tx_ant);
164 hw_params(priv).rx_chains_num =
165 num_of_ant(hw_params(priv).valid_rx_ant);
166
167 iwl5000_set_ct_threshold(priv);
168
169 /* Set initial sensitivity parameters */
170 hw_params(priv).sens = &iwl5000_sensitivity;
171}
172
173static void iwl5150_hw_set_hw_params(struct iwl_priv *priv)
174{
175 hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
176 BIT(IEEE80211_BAND_5GHZ);
177
178 hw_params(priv).tx_chains_num =
179 num_of_ant(hw_params(priv).valid_tx_ant);
180 hw_params(priv).rx_chains_num =
181 num_of_ant(hw_params(priv).valid_rx_ant);
182
183 iwl5150_set_ct_threshold(priv);
184
185 /* Set initial sensitivity parameters */
186 hw_params(priv).sens = &iwl5150_sensitivity;
187}
188
189static void iwl5150_temperature(struct iwl_priv *priv)
190{
191 u32 vt = 0;
192 s32 offset = iwl_temp_calib_to_offset(priv->shrd);
193
194 vt = le32_to_cpu(priv->statistics.common.temperature);
195 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
196 /* now vt hold the temperature in Kelvin */
197 priv->temperature = KELVIN_TO_CELSIUS(vt);
198 iwl_tt_handler(priv);
199}
200
201static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
202 struct ieee80211_channel_switch *ch_switch)
203{
204 /*
205 * MULTI-FIXME
206 * See iwlagn_mac_channel_switch.
207 */
208 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
209 struct iwl5000_channel_switch_cmd cmd;
210 const struct iwl_channel_info *ch_info;
211 u32 switch_time_in_usec, ucode_switch_time;
212 u16 ch;
213 u32 tsf_low;
214 u8 switch_count;
215 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
216 struct ieee80211_vif *vif = ctx->vif;
217 struct iwl_host_cmd hcmd = {
218 .id = REPLY_CHANNEL_SWITCH,
219 .len = { sizeof(cmd), },
220 .flags = CMD_SYNC,
221 .data = { &cmd, },
222 };
223
224 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
225 ch = ch_switch->channel->hw_value;
226 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
227 ctx->active.channel, ch);
228 cmd.channel = cpu_to_le16(ch);
229 cmd.rxon_flags = ctx->staging.flags;
230 cmd.rxon_filter_flags = ctx->staging.filter_flags;
231 switch_count = ch_switch->count;
232 tsf_low = ch_switch->timestamp & 0x0ffffffff;
233 /*
234 * calculate the ucode channel switch time
235 * adding TSF as one of the factor for when to switch
236 */
237 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
238 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
239 beacon_interval)) {
240 switch_count -= (priv->ucode_beacon_time -
241 tsf_low) / beacon_interval;
242 } else
243 switch_count = 0;
244 }
245 if (switch_count <= 1)
246 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
247 else {
248 switch_time_in_usec =
249 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
250 ucode_switch_time = iwl_usecs_to_beacons(priv,
251 switch_time_in_usec,
252 beacon_interval);
253 cmd.switch_time = iwl_add_beacon_time(priv,
254 priv->ucode_beacon_time,
255 ucode_switch_time,
256 beacon_interval);
257 }
258 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
259 cmd.switch_time);
260 ch_info = iwl_get_channel_info(priv, priv->band, ch);
261 if (ch_info)
262 cmd.expect_beacon = is_channel_radar(ch_info);
263 else {
264 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
265 ctx->active.channel, ch);
266 return -EFAULT;
267 }
268
269 return iwl_dvm_send_cmd(priv, &hcmd);
270}
271
272static struct iwl_lib_ops iwl5000_lib = {
273 .set_hw_params = iwl5000_hw_set_hw_params,
274 .set_channel_switch = iwl5000_hw_channel_switch,
275 .nic_config = iwl5000_nic_config,
276 .eeprom_ops = {
277 .regulatory_bands = {
278 EEPROM_REG_BAND_1_CHANNELS,
279 EEPROM_REG_BAND_2_CHANNELS,
280 EEPROM_REG_BAND_3_CHANNELS,
281 EEPROM_REG_BAND_4_CHANNELS,
282 EEPROM_REG_BAND_5_CHANNELS,
283 EEPROM_REG_BAND_24_HT40_CHANNELS,
284 EEPROM_REG_BAND_52_HT40_CHANNELS
285 },
286 },
287 .temperature = iwlagn_temperature,
288};
289
290static struct iwl_lib_ops iwl5150_lib = {
291 .set_hw_params = iwl5150_hw_set_hw_params,
292 .set_channel_switch = iwl5000_hw_channel_switch,
293 .nic_config = iwl5000_nic_config,
294 .eeprom_ops = {
295 .regulatory_bands = {
296 EEPROM_REG_BAND_1_CHANNELS,
297 EEPROM_REG_BAND_2_CHANNELS,
298 EEPROM_REG_BAND_3_CHANNELS,
299 EEPROM_REG_BAND_4_CHANNELS,
300 EEPROM_REG_BAND_5_CHANNELS,
301 EEPROM_REG_BAND_24_HT40_CHANNELS,
302 EEPROM_REG_BAND_52_HT40_CHANNELS
303 },
304 },
305 .temperature = iwl5150_temperature,
306};
307
308static const struct iwl_base_params iwl5000_base_params = { 47static const struct iwl_base_params iwl5000_base_params = {
309 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, 48 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
310 .num_of_queues = IWLAGN_NUM_QUEUES, 49 .num_of_queues = IWLAGN_NUM_QUEUES,
@@ -312,10 +51,9 @@ static const struct iwl_base_params iwl5000_base_params = {
312 .led_compensation = 51, 51 .led_compensation = 51,
313 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 52 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
314 .chain_noise_scale = 1000, 53 .chain_noise_scale = 1000,
315 .wd_timeout = IWL_LONG_WD_TIMEOUT, 54 .wd_timeout = IWL_WATCHHDOG_DISABLED,
316 .max_event_log_size = 512, 55 .max_event_log_size = 512,
317 .no_idle_support = true, 56 .no_idle_support = true,
318 .wd_disable = true,
319}; 57};
320 58
321static const struct iwl_ht_params iwl5000_ht_params = { 59static const struct iwl_ht_params iwl5000_ht_params = {
@@ -326,11 +64,11 @@ static const struct iwl_ht_params iwl5000_ht_params = {
326 .fw_name_pre = IWL5000_FW_PRE, \ 64 .fw_name_pre = IWL5000_FW_PRE, \
327 .ucode_api_max = IWL5000_UCODE_API_MAX, \ 65 .ucode_api_max = IWL5000_UCODE_API_MAX, \
328 .ucode_api_min = IWL5000_UCODE_API_MIN, \ 66 .ucode_api_min = IWL5000_UCODE_API_MIN, \
67 .device_family = IWL_DEVICE_FAMILY_5000, \
329 .max_inst_size = IWLAGN_RTC_INST_SIZE, \ 68 .max_inst_size = IWLAGN_RTC_INST_SIZE, \
330 .max_data_size = IWLAGN_RTC_DATA_SIZE, \ 69 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
331 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ 70 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
332 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ 71 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
333 .lib = &iwl5000_lib, \
334 .base_params = &iwl5000_base_params, \ 72 .base_params = &iwl5000_base_params, \
335 .led_mode = IWL_LED_BLINK 73 .led_mode = IWL_LED_BLINK
336 74
@@ -371,11 +109,11 @@ const struct iwl_cfg iwl5350_agn_cfg = {
371 .fw_name_pre = IWL5000_FW_PRE, 109 .fw_name_pre = IWL5000_FW_PRE,
372 .ucode_api_max = IWL5000_UCODE_API_MAX, 110 .ucode_api_max = IWL5000_UCODE_API_MAX,
373 .ucode_api_min = IWL5000_UCODE_API_MIN, 111 .ucode_api_min = IWL5000_UCODE_API_MIN,
112 .device_family = IWL_DEVICE_FAMILY_5000,
374 .max_inst_size = IWLAGN_RTC_INST_SIZE, 113 .max_inst_size = IWLAGN_RTC_INST_SIZE,
375 .max_data_size = IWLAGN_RTC_DATA_SIZE, 114 .max_data_size = IWLAGN_RTC_DATA_SIZE,
376 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 115 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
377 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 116 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
378 .lib = &iwl5000_lib,
379 .base_params = &iwl5000_base_params, 117 .base_params = &iwl5000_base_params,
380 .ht_params = &iwl5000_ht_params, 118 .ht_params = &iwl5000_ht_params,
381 .led_mode = IWL_LED_BLINK, 119 .led_mode = IWL_LED_BLINK,
@@ -386,11 +124,11 @@ const struct iwl_cfg iwl5350_agn_cfg = {
386 .fw_name_pre = IWL5150_FW_PRE, \ 124 .fw_name_pre = IWL5150_FW_PRE, \
387 .ucode_api_max = IWL5150_UCODE_API_MAX, \ 125 .ucode_api_max = IWL5150_UCODE_API_MAX, \
388 .ucode_api_min = IWL5150_UCODE_API_MIN, \ 126 .ucode_api_min = IWL5150_UCODE_API_MIN, \
127 .device_family = IWL_DEVICE_FAMILY_5150, \
389 .max_inst_size = IWLAGN_RTC_INST_SIZE, \ 128 .max_inst_size = IWLAGN_RTC_INST_SIZE, \
390 .max_data_size = IWLAGN_RTC_DATA_SIZE, \ 129 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
391 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ 130 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
392 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ 131 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
393 .lib = &iwl5150_lib, \
394 .base_params = &iwl5000_base_params, \ 132 .base_params = &iwl5000_base_params, \
395 .no_xtal_calib = true, \ 133 .no_xtal_calib = true, \
396 .led_mode = IWL_LED_BLINK, \ 134 .led_mode = IWL_LED_BLINK, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 7075570a0f2c..00da2520a4b7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -24,26 +24,11 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/skbuff.h>
32#include <linux/netdevice.h>
33#include <net/mac80211.h>
34#include <linux/etherdevice.h>
35#include <asm/unaligned.h>
36#include <linux/stringify.h> 28#include <linux/stringify.h>
37 29#include "iwl-config.h"
38#include "iwl-eeprom.h"
39#include "iwl-dev.h"
40#include "iwl-core.h"
41#include "iwl-io.h"
42#include "iwl-agn.h"
43#include "iwl-agn-hw.h"
44#include "iwl-trans.h"
45#include "iwl-shared.h"
46#include "iwl-cfg.h" 30#include "iwl-cfg.h"
31#include "iwl-dev.h" /* still needed */
47 32
48/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
49#define IWL6000_UCODE_API_MAX 6 34#define IWL6000_UCODE_API_MAX 6
@@ -71,201 +56,6 @@
71#define IWL6030_FW_PRE "iwlwifi-6000g2b-" 56#define IWL6030_FW_PRE "iwlwifi-6000g2b-"
72#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode" 57#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
73 58
74static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
75{
76 /* want Celsius */
77 hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD;
78 hw_params(priv).ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
79}
80
81static void iwl6050_additional_nic_config(struct iwl_priv *priv)
82{
83 /* Indicate calibration version to uCode. */
84 if (iwl_eeprom_calib_version(priv->shrd) >= 6)
85 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
86 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
87}
88
89static void iwl6150_additional_nic_config(struct iwl_priv *priv)
90{
91 /* Indicate calibration version to uCode. */
92 if (iwl_eeprom_calib_version(priv->shrd) >= 6)
93 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
94 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
95 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
96 CSR_GP_DRIVER_REG_BIT_6050_1x2);
97}
98
99static void iwl6000i_additional_nic_config(struct iwl_priv *priv)
100{
101 /* 2x2 IPA phy type */
102 iwl_write32(trans(priv), CSR_GP_DRIVER_REG,
103 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
104}
105
106/* NIC configuration for 6000 series */
107static void iwl6000_nic_config(struct iwl_priv *priv)
108{
109 iwl_rf_config(priv);
110
111 /* do additional nic configuration if needed */
112 if (cfg(priv)->additional_nic_config)
113 cfg(priv)->additional_nic_config(priv);
114}
115
116static const struct iwl_sensitivity_ranges iwl6000_sensitivity = {
117 .min_nrg_cck = 110,
118 .auto_corr_min_ofdm = 80,
119 .auto_corr_min_ofdm_mrc = 128,
120 .auto_corr_min_ofdm_x1 = 105,
121 .auto_corr_min_ofdm_mrc_x1 = 192,
122
123 .auto_corr_max_ofdm = 145,
124 .auto_corr_max_ofdm_mrc = 232,
125 .auto_corr_max_ofdm_x1 = 110,
126 .auto_corr_max_ofdm_mrc_x1 = 232,
127
128 .auto_corr_min_cck = 125,
129 .auto_corr_max_cck = 175,
130 .auto_corr_min_cck_mrc = 160,
131 .auto_corr_max_cck_mrc = 310,
132 .nrg_th_cck = 110,
133 .nrg_th_ofdm = 110,
134
135 .barker_corr_th_min = 190,
136 .barker_corr_th_min_mrc = 336,
137 .nrg_th_cca = 62,
138};
139
140static void iwl6000_hw_set_hw_params(struct iwl_priv *priv)
141{
142 hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
143 BIT(IEEE80211_BAND_5GHZ);
144
145 hw_params(priv).tx_chains_num =
146 num_of_ant(hw_params(priv).valid_tx_ant);
147 if (cfg(priv)->rx_with_siso_diversity)
148 hw_params(priv).rx_chains_num = 1;
149 else
150 hw_params(priv).rx_chains_num =
151 num_of_ant(hw_params(priv).valid_rx_ant);
152
153 iwl6000_set_ct_threshold(priv);
154
155 /* Set initial sensitivity parameters */
156 hw_params(priv).sens = &iwl6000_sensitivity;
157
158}
159
160static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
161 struct ieee80211_channel_switch *ch_switch)
162{
163 /*
164 * MULTI-FIXME
165 * See iwlagn_mac_channel_switch.
166 */
167 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
168 struct iwl6000_channel_switch_cmd cmd;
169 const struct iwl_channel_info *ch_info;
170 u32 switch_time_in_usec, ucode_switch_time;
171 u16 ch;
172 u32 tsf_low;
173 u8 switch_count;
174 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
175 struct ieee80211_vif *vif = ctx->vif;
176 struct iwl_host_cmd hcmd = {
177 .id = REPLY_CHANNEL_SWITCH,
178 .len = { sizeof(cmd), },
179 .flags = CMD_SYNC,
180 .data = { &cmd, },
181 };
182
183 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
184 ch = ch_switch->channel->hw_value;
185 IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
186 ctx->active.channel, ch);
187 cmd.channel = cpu_to_le16(ch);
188 cmd.rxon_flags = ctx->staging.flags;
189 cmd.rxon_filter_flags = ctx->staging.filter_flags;
190 switch_count = ch_switch->count;
191 tsf_low = ch_switch->timestamp & 0x0ffffffff;
192 /*
193 * calculate the ucode channel switch time
194 * adding TSF as one of the factor for when to switch
195 */
196 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
197 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
198 beacon_interval)) {
199 switch_count -= (priv->ucode_beacon_time -
200 tsf_low) / beacon_interval;
201 } else
202 switch_count = 0;
203 }
204 if (switch_count <= 1)
205 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
206 else {
207 switch_time_in_usec =
208 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
209 ucode_switch_time = iwl_usecs_to_beacons(priv,
210 switch_time_in_usec,
211 beacon_interval);
212 cmd.switch_time = iwl_add_beacon_time(priv,
213 priv->ucode_beacon_time,
214 ucode_switch_time,
215 beacon_interval);
216 }
217 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
218 cmd.switch_time);
219 ch_info = iwl_get_channel_info(priv, priv->band, ch);
220 if (ch_info)
221 cmd.expect_beacon = is_channel_radar(ch_info);
222 else {
223 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
224 ctx->active.channel, ch);
225 return -EFAULT;
226 }
227
228 return iwl_dvm_send_cmd(priv, &hcmd);
229}
230
231static struct iwl_lib_ops iwl6000_lib = {
232 .set_hw_params = iwl6000_hw_set_hw_params,
233 .set_channel_switch = iwl6000_hw_channel_switch,
234 .nic_config = iwl6000_nic_config,
235 .eeprom_ops = {
236 .regulatory_bands = {
237 EEPROM_REG_BAND_1_CHANNELS,
238 EEPROM_REG_BAND_2_CHANNELS,
239 EEPROM_REG_BAND_3_CHANNELS,
240 EEPROM_REG_BAND_4_CHANNELS,
241 EEPROM_REG_BAND_5_CHANNELS,
242 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
243 EEPROM_REG_BAND_52_HT40_CHANNELS
244 },
245 .enhanced_txpower = true,
246 },
247 .temperature = iwlagn_temperature,
248};
249
250static struct iwl_lib_ops iwl6030_lib = {
251 .set_hw_params = iwl6000_hw_set_hw_params,
252 .set_channel_switch = iwl6000_hw_channel_switch,
253 .nic_config = iwl6000_nic_config,
254 .eeprom_ops = {
255 .regulatory_bands = {
256 EEPROM_REG_BAND_1_CHANNELS,
257 EEPROM_REG_BAND_2_CHANNELS,
258 EEPROM_REG_BAND_3_CHANNELS,
259 EEPROM_REG_BAND_4_CHANNELS,
260 EEPROM_REG_BAND_5_CHANNELS,
261 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
262 EEPROM_REG_BAND_52_HT40_CHANNELS
263 },
264 .enhanced_txpower = true,
265 },
266 .temperature = iwlagn_temperature,
267};
268
269static const struct iwl_base_params iwl6000_base_params = { 59static const struct iwl_base_params iwl6000_base_params = {
270 .eeprom_size = OTP_LOW_IMAGE_SIZE, 60 .eeprom_size = OTP_LOW_IMAGE_SIZE,
271 .num_of_queues = IWLAGN_NUM_QUEUES, 61 .num_of_queues = IWLAGN_NUM_QUEUES,
@@ -333,11 +123,11 @@ static const struct iwl_bt_params iwl6000_bt_params = {
333 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ 123 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
334 .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ 124 .ucode_api_ok = IWL6000G2_UCODE_API_OK, \
335 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ 125 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
126 .device_family = IWL_DEVICE_FAMILY_6005, \
336 .max_inst_size = IWL60_RTC_INST_SIZE, \ 127 .max_inst_size = IWL60_RTC_INST_SIZE, \
337 .max_data_size = IWL60_RTC_DATA_SIZE, \ 128 .max_data_size = IWL60_RTC_DATA_SIZE, \
338 .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ 129 .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \
339 .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ 130 .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
340 .lib = &iwl6000_lib, \
341 .base_params = &iwl6000_g2_base_params, \ 131 .base_params = &iwl6000_g2_base_params, \
342 .need_temp_offset_calib = true, \ 132 .need_temp_offset_calib = true, \
343 .led_mode = IWL_LED_RF_STATE 133 .led_mode = IWL_LED_RF_STATE
@@ -387,11 +177,11 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
387 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ 177 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
388 .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ 178 .ucode_api_ok = IWL6000G2_UCODE_API_OK, \
389 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ 179 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
180 .device_family = IWL_DEVICE_FAMILY_6030, \
390 .max_inst_size = IWL60_RTC_INST_SIZE, \ 181 .max_inst_size = IWL60_RTC_INST_SIZE, \
391 .max_data_size = IWL60_RTC_DATA_SIZE, \ 182 .max_data_size = IWL60_RTC_DATA_SIZE, \
392 .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ 183 .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \
393 .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ 184 .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
394 .lib = &iwl6030_lib, \
395 .base_params = &iwl6000_g2_base_params, \ 185 .base_params = &iwl6000_g2_base_params, \
396 .bt_params = &iwl6000_bt_params, \ 186 .bt_params = &iwl6000_bt_params, \
397 .need_temp_offset_calib = true, \ 187 .need_temp_offset_calib = true, \
@@ -458,14 +248,13 @@ const struct iwl_cfg iwl130_bg_cfg = {
458 .ucode_api_max = IWL6000_UCODE_API_MAX, \ 248 .ucode_api_max = IWL6000_UCODE_API_MAX, \
459 .ucode_api_ok = IWL6000_UCODE_API_OK, \ 249 .ucode_api_ok = IWL6000_UCODE_API_OK, \
460 .ucode_api_min = IWL6000_UCODE_API_MIN, \ 250 .ucode_api_min = IWL6000_UCODE_API_MIN, \
251 .device_family = IWL_DEVICE_FAMILY_6000i, \
461 .max_inst_size = IWL60_RTC_INST_SIZE, \ 252 .max_inst_size = IWL60_RTC_INST_SIZE, \
462 .max_data_size = IWL60_RTC_DATA_SIZE, \ 253 .max_data_size = IWL60_RTC_DATA_SIZE, \
463 .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ 254 .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \
464 .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ 255 .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \
465 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ 256 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
466 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ 257 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
467 .lib = &iwl6000_lib, \
468 .additional_nic_config = iwl6000i_additional_nic_config,\
469 .base_params = &iwl6000_base_params, \ 258 .base_params = &iwl6000_base_params, \
470 .led_mode = IWL_LED_BLINK 259 .led_mode = IWL_LED_BLINK
471 260
@@ -489,12 +278,11 @@ const struct iwl_cfg iwl6000i_2bg_cfg = {
489 .fw_name_pre = IWL6050_FW_PRE, \ 278 .fw_name_pre = IWL6050_FW_PRE, \
490 .ucode_api_max = IWL6050_UCODE_API_MAX, \ 279 .ucode_api_max = IWL6050_UCODE_API_MAX, \
491 .ucode_api_min = IWL6050_UCODE_API_MIN, \ 280 .ucode_api_min = IWL6050_UCODE_API_MIN, \
281 .device_family = IWL_DEVICE_FAMILY_6050, \
492 .max_inst_size = IWL60_RTC_INST_SIZE, \ 282 .max_inst_size = IWL60_RTC_INST_SIZE, \
493 .max_data_size = IWL60_RTC_DATA_SIZE, \ 283 .max_data_size = IWL60_RTC_DATA_SIZE, \
494 .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ 284 .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \
495 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ 285 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \
496 .lib = &iwl6000_lib, \
497 .additional_nic_config = iwl6050_additional_nic_config, \
498 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ 286 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \
499 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ 287 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
500 .base_params = &iwl6050_base_params, \ 288 .base_params = &iwl6050_base_params, \
@@ -516,10 +304,9 @@ const struct iwl_cfg iwl6050_2abg_cfg = {
516 .fw_name_pre = IWL6050_FW_PRE, \ 304 .fw_name_pre = IWL6050_FW_PRE, \
517 .ucode_api_max = IWL6050_UCODE_API_MAX, \ 305 .ucode_api_max = IWL6050_UCODE_API_MAX, \
518 .ucode_api_min = IWL6050_UCODE_API_MIN, \ 306 .ucode_api_min = IWL6050_UCODE_API_MIN, \
307 .device_family = IWL_DEVICE_FAMILY_6150, \
519 .max_inst_size = IWL60_RTC_INST_SIZE, \ 308 .max_inst_size = IWL60_RTC_INST_SIZE, \
520 .max_data_size = IWL60_RTC_DATA_SIZE, \ 309 .max_data_size = IWL60_RTC_DATA_SIZE, \
521 .lib = &iwl6000_lib, \
522 .additional_nic_config = iwl6150_additional_nic_config, \
523 .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ 310 .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \
524 .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ 311 .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \
525 .base_params = &iwl6050_base_params, \ 312 .base_params = &iwl6050_base_params, \
@@ -543,11 +330,11 @@ const struct iwl_cfg iwl6000_3agn_cfg = {
543 .ucode_api_max = IWL6000_UCODE_API_MAX, 330 .ucode_api_max = IWL6000_UCODE_API_MAX,
544 .ucode_api_ok = IWL6000_UCODE_API_OK, 331 .ucode_api_ok = IWL6000_UCODE_API_OK,
545 .ucode_api_min = IWL6000_UCODE_API_MIN, 332 .ucode_api_min = IWL6000_UCODE_API_MIN,
333 .device_family = IWL_DEVICE_FAMILY_6000,
546 .max_inst_size = IWL60_RTC_INST_SIZE, 334 .max_inst_size = IWL60_RTC_INST_SIZE,
547 .max_data_size = IWL60_RTC_DATA_SIZE, 335 .max_data_size = IWL60_RTC_DATA_SIZE,
548 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 336 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
549 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, 337 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
550 .lib = &iwl6000_lib,
551 .base_params = &iwl6000_base_params, 338 .base_params = &iwl6000_base_params,
552 .ht_params = &iwl6000_ht_params, 339 .ht_params = &iwl6000_ht_params,
553 .led_mode = IWL_LED_BLINK, 340 .led_mode = IWL_LED_BLINK,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 84cbe7bb504c..61c243f7395f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -190,7 +190,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
190 u32 max_false_alarms = MAX_FA_CCK * rx_enable_time; 190 u32 max_false_alarms = MAX_FA_CCK * rx_enable_time;
191 u32 min_false_alarms = MIN_FA_CCK * rx_enable_time; 191 u32 min_false_alarms = MIN_FA_CCK * rx_enable_time;
192 struct iwl_sensitivity_data *data = NULL; 192 struct iwl_sensitivity_data *data = NULL;
193 const struct iwl_sensitivity_ranges *ranges = hw_params(priv).sens; 193 const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens;
194 194
195 data = &(priv->sensitivity_data); 195 data = &(priv->sensitivity_data);
196 196
@@ -373,7 +373,7 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
373 u32 max_false_alarms = MAX_FA_OFDM * rx_enable_time; 373 u32 max_false_alarms = MAX_FA_OFDM * rx_enable_time;
374 u32 min_false_alarms = MIN_FA_OFDM * rx_enable_time; 374 u32 min_false_alarms = MIN_FA_OFDM * rx_enable_time;
375 struct iwl_sensitivity_data *data = NULL; 375 struct iwl_sensitivity_data *data = NULL;
376 const struct iwl_sensitivity_ranges *ranges = hw_params(priv).sens; 376 const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens;
377 377
378 data = &(priv->sensitivity_data); 378 data = &(priv->sensitivity_data);
379 379
@@ -597,9 +597,9 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
597 int ret = 0; 597 int ret = 0;
598 int i; 598 int i;
599 struct iwl_sensitivity_data *data = NULL; 599 struct iwl_sensitivity_data *data = NULL;
600 const struct iwl_sensitivity_ranges *ranges = hw_params(priv).sens; 600 const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens;
601 601
602 if (priv->disable_sens_cal) 602 if (priv->calib_disabled & IWL_SENSITIVITY_CALIB_DISABLED)
603 return; 603 return;
604 604
605 IWL_DEBUG_CALIB(priv, "Start iwl_init_sensitivity\n"); 605 IWL_DEBUG_CALIB(priv, "Start iwl_init_sensitivity\n");
@@ -663,7 +663,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
663 struct statistics_rx_phy *ofdm, *cck; 663 struct statistics_rx_phy *ofdm, *cck;
664 struct statistics_general_data statis; 664 struct statistics_general_data statis;
665 665
666 if (priv->disable_sens_cal) 666 if (priv->calib_disabled & IWL_SENSITIVITY_CALIB_DISABLED)
667 return; 667 return;
668 668
669 data = &(priv->sensitivity_data); 669 data = &(priv->sensitivity_data);
@@ -833,28 +833,28 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
833 * To be safe, simply mask out any chains that we know 833 * To be safe, simply mask out any chains that we know
834 * are not on the device. 834 * are not on the device.
835 */ 835 */
836 active_chains &= hw_params(priv).valid_rx_ant; 836 active_chains &= priv->hw_params.valid_rx_ant;
837 837
838 num_tx_chains = 0; 838 num_tx_chains = 0;
839 for (i = 0; i < NUM_RX_CHAINS; i++) { 839 for (i = 0; i < NUM_RX_CHAINS; i++) {
840 /* loops on all the bits of 840 /* loops on all the bits of
841 * priv->hw_setting.valid_tx_ant */ 841 * priv->hw_setting.valid_tx_ant */
842 u8 ant_msk = (1 << i); 842 u8 ant_msk = (1 << i);
843 if (!(hw_params(priv).valid_tx_ant & ant_msk)) 843 if (!(priv->hw_params.valid_tx_ant & ant_msk))
844 continue; 844 continue;
845 845
846 num_tx_chains++; 846 num_tx_chains++;
847 if (data->disconn_array[i] == 0) 847 if (data->disconn_array[i] == 0)
848 /* there is a Tx antenna connected */ 848 /* there is a Tx antenna connected */
849 break; 849 break;
850 if (num_tx_chains == hw_params(priv).tx_chains_num && 850 if (num_tx_chains == priv->hw_params.tx_chains_num &&
851 data->disconn_array[i]) { 851 data->disconn_array[i]) {
852 /* 852 /*
853 * If all chains are disconnected 853 * If all chains are disconnected
854 * connect the first valid tx chain 854 * connect the first valid tx chain
855 */ 855 */
856 first_chain = 856 first_chain =
857 find_first_chain(hw_params(priv).valid_tx_ant); 857 find_first_chain(priv->hw_params.valid_tx_ant);
858 data->disconn_array[first_chain] = 0; 858 data->disconn_array[first_chain] = 0;
859 active_chains |= BIT(first_chain); 859 active_chains |= BIT(first_chain);
860 IWL_DEBUG_CALIB(priv, 860 IWL_DEBUG_CALIB(priv,
@@ -864,13 +864,13 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
864 } 864 }
865 } 865 }
866 866
867 if (active_chains != hw_params(priv).valid_rx_ant && 867 if (active_chains != priv->hw_params.valid_rx_ant &&
868 active_chains != priv->chain_noise_data.active_chains) 868 active_chains != priv->chain_noise_data.active_chains)
869 IWL_DEBUG_CALIB(priv, 869 IWL_DEBUG_CALIB(priv,
870 "Detected that not all antennas are connected! " 870 "Detected that not all antennas are connected! "
871 "Connected: %#x, valid: %#x.\n", 871 "Connected: %#x, valid: %#x.\n",
872 active_chains, 872 active_chains,
873 hw_params(priv).valid_rx_ant); 873 priv->hw_params.valid_rx_ant);
874 874
875 /* Save for use within RXON, TX, SCAN commands, etc. */ 875 /* Save for use within RXON, TX, SCAN commands, etc. */
876 data->active_chains = active_chains; 876 data->active_chains = active_chains;
@@ -970,7 +970,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
970 */ 970 */
971 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 971 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
972 972
973 if (priv->disable_chain_noise_cal) 973 if (priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED)
974 return; 974 return;
975 975
976 data = &(priv->chain_noise_data); 976 data = &(priv->chain_noise_data);
@@ -1055,7 +1055,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
1055 cfg(priv)->bt_params->advanced_bt_coexist) { 1055 cfg(priv)->bt_params->advanced_bt_coexist) {
1056 /* Disable disconnected antenna algorithm for advanced 1056 /* Disable disconnected antenna algorithm for advanced
1057 bt coex, assuming valid antennas are connected */ 1057 bt coex, assuming valid antennas are connected */
1058 data->active_chains = hw_params(priv).valid_rx_ant; 1058 data->active_chains = priv->hw_params.valid_rx_ant;
1059 for (i = 0; i < NUM_RX_CHAINS; i++) 1059 for (i = 0; i < NUM_RX_CHAINS; i++)
1060 if (!(data->active_chains & (1<<i))) 1060 if (!(data->active_chains & (1<<i)))
1061 data->disconn_array[i] = 1; 1061 data->disconn_array[i] = 1;
@@ -1085,7 +1085,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
1085 min_average_noise, min_average_noise_antenna_i); 1085 min_average_noise, min_average_noise_antenna_i);
1086 1086
1087 iwlagn_gain_computation(priv, average_noise, 1087 iwlagn_gain_computation(priv, average_noise,
1088 find_first_chain(hw_params(priv).valid_rx_ant)); 1088 find_first_chain(priv->hw_params.valid_rx_ant));
1089 1089
1090 /* Some power changes may have been made during the calibration. 1090 /* Some power changes may have been made during the calibration.
1091 * Update and commit the RXON 1091 * Update and commit the RXON
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c b/drivers/net/wireless/iwlwifi/iwl-agn-devices.c
new file mode 100644
index 000000000000..08718caf4aa9
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-devices.c
@@ -0,0 +1,756 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2008 - 2012 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/*
28 * DVM device-specific data & functions
29 */
30#include "iwl-core.h"
31#include "iwl-agn.h"
32#include "iwl-dev.h"
33#include "iwl-commands.h"
34#include "iwl-io.h"
35#include "iwl-prph.h"
36
37/*
38 * 1000 series
39 * ===========
40 */
41
42/*
43 * For 1000, use advance thermal throttling critical temperature threshold,
44 * but legacy thermal management implementation for now.
45 * This is for the reason of 1000 uCode using advance thermal throttling API
46 * but not implement ct_kill_exit based on ct_kill exit temperature
47 * so the thermal throttling will still based on legacy thermal throttling
48 * management.
49 * The code here need to be modified once 1000 uCode has the advanced thermal
50 * throttling algorithm in place
51 */
52static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
53{
54 /* want Celsius */
55 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
56 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
57}
58
59/* NIC configuration for 1000 series */
60static void iwl1000_nic_config(struct iwl_priv *priv)
61{
62 /* set CSR_HW_CONFIG_REG for uCode use */
63 iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
64 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
65 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
66
67 /* Setting digital SVR for 1000 card to 1.32V */
68 /* locking is acquired in iwl_set_bits_mask_prph() function */
69 iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG,
70 APMG_SVR_DIGITAL_VOLTAGE_1_32,
71 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
72}
73
74/**
75 * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time
76 * @priv -- pointer to iwl_priv data structure
77 * @tsf_bits -- number of bits need to shift for masking)
78 */
79static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv,
80 u16 tsf_bits)
81{
82 return (1 << tsf_bits) - 1;
83}
84
85/**
86 * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time
87 * @priv -- pointer to iwl_priv data structure
88 * @tsf_bits -- number of bits need to shift for masking)
89 */
90static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv,
91 u16 tsf_bits)
92{
93 return ((1 << (32 - tsf_bits)) - 1) << tsf_bits;
94}
95
96/*
97 * extended beacon time format
98 * time in usec will be changed into a 32-bit value in extended:internal format
99 * the extended part is the beacon counts
100 * the internal part is the time in usec within one beacon interval
101 */
102static u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec,
103 u32 beacon_interval)
104{
105 u32 quot;
106 u32 rem;
107 u32 interval = beacon_interval * TIME_UNIT;
108
109 if (!interval || !usec)
110 return 0;
111
112 quot = (usec / interval) &
113 (iwl_beacon_time_mask_high(priv, IWLAGN_EXT_BEACON_TIME_POS) >>
114 IWLAGN_EXT_BEACON_TIME_POS);
115 rem = (usec % interval) & iwl_beacon_time_mask_low(priv,
116 IWLAGN_EXT_BEACON_TIME_POS);
117
118 return (quot << IWLAGN_EXT_BEACON_TIME_POS) + rem;
119}
120
121/* base is usually what we get from ucode with each received frame,
122 * the same as HW timer counter counting down
123 */
124static __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
125 u32 addon, u32 beacon_interval)
126{
127 u32 base_low = base & iwl_beacon_time_mask_low(priv,
128 IWLAGN_EXT_BEACON_TIME_POS);
129 u32 addon_low = addon & iwl_beacon_time_mask_low(priv,
130 IWLAGN_EXT_BEACON_TIME_POS);
131 u32 interval = beacon_interval * TIME_UNIT;
132 u32 res = (base & iwl_beacon_time_mask_high(priv,
133 IWLAGN_EXT_BEACON_TIME_POS)) +
134 (addon & iwl_beacon_time_mask_high(priv,
135 IWLAGN_EXT_BEACON_TIME_POS));
136
137 if (base_low > addon_low)
138 res += base_low - addon_low;
139 else if (base_low < addon_low) {
140 res += interval + base_low - addon_low;
141 res += (1 << IWLAGN_EXT_BEACON_TIME_POS);
142 } else
143 res += (1 << IWLAGN_EXT_BEACON_TIME_POS);
144
145 return cpu_to_le32(res);
146}
147
148static const struct iwl_sensitivity_ranges iwl1000_sensitivity = {
149 .min_nrg_cck = 95,
150 .auto_corr_min_ofdm = 90,
151 .auto_corr_min_ofdm_mrc = 170,
152 .auto_corr_min_ofdm_x1 = 120,
153 .auto_corr_min_ofdm_mrc_x1 = 240,
154
155 .auto_corr_max_ofdm = 120,
156 .auto_corr_max_ofdm_mrc = 210,
157 .auto_corr_max_ofdm_x1 = 155,
158 .auto_corr_max_ofdm_mrc_x1 = 290,
159
160 .auto_corr_min_cck = 125,
161 .auto_corr_max_cck = 200,
162 .auto_corr_min_cck_mrc = 170,
163 .auto_corr_max_cck_mrc = 400,
164 .nrg_th_cck = 95,
165 .nrg_th_ofdm = 95,
166
167 .barker_corr_th_min = 190,
168 .barker_corr_th_min_mrc = 390,
169 .nrg_th_cca = 62,
170};
171
172static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
173{
174 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ);
175
176 priv->hw_params.tx_chains_num =
177 num_of_ant(priv->hw_params.valid_tx_ant);
178 if (cfg(priv)->rx_with_siso_diversity)
179 priv->hw_params.rx_chains_num = 1;
180 else
181 priv->hw_params.rx_chains_num =
182 num_of_ant(priv->hw_params.valid_rx_ant);
183
184 iwl1000_set_ct_threshold(priv);
185
186 /* Set initial sensitivity parameters */
187 priv->hw_params.sens = &iwl1000_sensitivity;
188}
189
190struct iwl_lib_ops iwl1000_lib = {
191 .set_hw_params = iwl1000_hw_set_hw_params,
192 .nic_config = iwl1000_nic_config,
193 .eeprom_ops = {
194 .regulatory_bands = {
195 EEPROM_REG_BAND_1_CHANNELS,
196 EEPROM_REG_BAND_2_CHANNELS,
197 EEPROM_REG_BAND_3_CHANNELS,
198 EEPROM_REG_BAND_4_CHANNELS,
199 EEPROM_REG_BAND_5_CHANNELS,
200 EEPROM_REG_BAND_24_HT40_CHANNELS,
201 EEPROM_REGULATORY_BAND_NO_HT40,
202 },
203 },
204 .temperature = iwlagn_temperature,
205};
206
207
208/*
209 * 2000 series
210 * ===========
211 */
212
213static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
214{
215 /* want Celsius */
216 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
217 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
218}
219
220/* NIC configuration for 2000 series */
221static void iwl2000_nic_config(struct iwl_priv *priv)
222{
223 iwl_rf_config(priv);
224
225 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
226 CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
227}
228
229static const struct iwl_sensitivity_ranges iwl2000_sensitivity = {
230 .min_nrg_cck = 97,
231 .auto_corr_min_ofdm = 80,
232 .auto_corr_min_ofdm_mrc = 128,
233 .auto_corr_min_ofdm_x1 = 105,
234 .auto_corr_min_ofdm_mrc_x1 = 192,
235
236 .auto_corr_max_ofdm = 145,
237 .auto_corr_max_ofdm_mrc = 232,
238 .auto_corr_max_ofdm_x1 = 110,
239 .auto_corr_max_ofdm_mrc_x1 = 232,
240
241 .auto_corr_min_cck = 125,
242 .auto_corr_max_cck = 175,
243 .auto_corr_min_cck_mrc = 160,
244 .auto_corr_max_cck_mrc = 310,
245 .nrg_th_cck = 97,
246 .nrg_th_ofdm = 100,
247
248 .barker_corr_th_min = 190,
249 .barker_corr_th_min_mrc = 390,
250 .nrg_th_cca = 62,
251};
252
253static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
254{
255 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ);
256
257 priv->hw_params.tx_chains_num =
258 num_of_ant(priv->hw_params.valid_tx_ant);
259 if (cfg(priv)->rx_with_siso_diversity)
260 priv->hw_params.rx_chains_num = 1;
261 else
262 priv->hw_params.rx_chains_num =
263 num_of_ant(priv->hw_params.valid_rx_ant);
264
265 iwl2000_set_ct_threshold(priv);
266
267 /* Set initial sensitivity parameters */
268 priv->hw_params.sens = &iwl2000_sensitivity;
269}
270
271struct iwl_lib_ops iwl2000_lib = {
272 .set_hw_params = iwl2000_hw_set_hw_params,
273 .nic_config = iwl2000_nic_config,
274 .eeprom_ops = {
275 .regulatory_bands = {
276 EEPROM_REG_BAND_1_CHANNELS,
277 EEPROM_REG_BAND_2_CHANNELS,
278 EEPROM_REG_BAND_3_CHANNELS,
279 EEPROM_REG_BAND_4_CHANNELS,
280 EEPROM_REG_BAND_5_CHANNELS,
281 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
282 EEPROM_REGULATORY_BAND_NO_HT40,
283 },
284 .enhanced_txpower = true,
285 },
286 .temperature = iwlagn_temperature,
287};
288
289struct iwl_lib_ops iwl2030_lib = {
290 .set_hw_params = iwl2000_hw_set_hw_params,
291 .nic_config = iwl2000_nic_config,
292 .eeprom_ops = {
293 .regulatory_bands = {
294 EEPROM_REG_BAND_1_CHANNELS,
295 EEPROM_REG_BAND_2_CHANNELS,
296 EEPROM_REG_BAND_3_CHANNELS,
297 EEPROM_REG_BAND_4_CHANNELS,
298 EEPROM_REG_BAND_5_CHANNELS,
299 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
300 EEPROM_REGULATORY_BAND_NO_HT40,
301 },
302 .enhanced_txpower = true,
303 },
304 .temperature = iwlagn_temperature,
305};
306
307/*
308 * 5000 series
309 * ===========
310 */
311
312/* NIC configuration for 5000 series */
313static void iwl5000_nic_config(struct iwl_priv *priv)
314{
315 iwl_rf_config(priv);
316
317 /* W/A : NIC is stuck in a reset state after Early PCIe power off
318 * (PCIe power is lost before PERST# is asserted),
319 * causing ME FW to lose ownership and not being able to obtain it back.
320 */
321 iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG,
322 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
323 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
324}
325
326static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
327 .min_nrg_cck = 100,
328 .auto_corr_min_ofdm = 90,
329 .auto_corr_min_ofdm_mrc = 170,
330 .auto_corr_min_ofdm_x1 = 105,
331 .auto_corr_min_ofdm_mrc_x1 = 220,
332
333 .auto_corr_max_ofdm = 120,
334 .auto_corr_max_ofdm_mrc = 210,
335 .auto_corr_max_ofdm_x1 = 120,
336 .auto_corr_max_ofdm_mrc_x1 = 240,
337
338 .auto_corr_min_cck = 125,
339 .auto_corr_max_cck = 200,
340 .auto_corr_min_cck_mrc = 200,
341 .auto_corr_max_cck_mrc = 400,
342 .nrg_th_cck = 100,
343 .nrg_th_ofdm = 100,
344
345 .barker_corr_th_min = 190,
346 .barker_corr_th_min_mrc = 390,
347 .nrg_th_cca = 62,
348};
349
350static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
351 .min_nrg_cck = 95,
352 .auto_corr_min_ofdm = 90,
353 .auto_corr_min_ofdm_mrc = 170,
354 .auto_corr_min_ofdm_x1 = 105,
355 .auto_corr_min_ofdm_mrc_x1 = 220,
356
357 .auto_corr_max_ofdm = 120,
358 .auto_corr_max_ofdm_mrc = 210,
359 /* max = min for performance bug in 5150 DSP */
360 .auto_corr_max_ofdm_x1 = 105,
361 .auto_corr_max_ofdm_mrc_x1 = 220,
362
363 .auto_corr_min_cck = 125,
364 .auto_corr_max_cck = 200,
365 .auto_corr_min_cck_mrc = 170,
366 .auto_corr_max_cck_mrc = 400,
367 .nrg_th_cck = 95,
368 .nrg_th_ofdm = 95,
369
370 .barker_corr_th_min = 190,
371 .barker_corr_th_min_mrc = 390,
372 .nrg_th_cca = 62,
373};
374
375#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
376
377static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
378{
379 u16 temperature, voltage;
380 __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv,
381 EEPROM_KELVIN_TEMPERATURE);
382
383 temperature = le16_to_cpu(temp_calib[0]);
384 voltage = le16_to_cpu(temp_calib[1]);
385
386 /* offset = temp - volt / coeff */
387 return (s32)(temperature -
388 voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
389}
390
391static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
392{
393 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
394 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) -
395 iwl_temp_calib_to_offset(priv);
396
397 priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef;
398}
399
400static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
401{
402 /* want Celsius */
403 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
404}
405
406static void iwl5000_hw_set_hw_params(struct iwl_priv *priv)
407{
408 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
409 BIT(IEEE80211_BAND_5GHZ);
410
411 priv->hw_params.tx_chains_num =
412 num_of_ant(priv->hw_params.valid_tx_ant);
413 priv->hw_params.rx_chains_num =
414 num_of_ant(priv->hw_params.valid_rx_ant);
415
416 iwl5000_set_ct_threshold(priv);
417
418 /* Set initial sensitivity parameters */
419 priv->hw_params.sens = &iwl5000_sensitivity;
420}
421
422static void iwl5150_hw_set_hw_params(struct iwl_priv *priv)
423{
424 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
425 BIT(IEEE80211_BAND_5GHZ);
426
427 priv->hw_params.tx_chains_num =
428 num_of_ant(priv->hw_params.valid_tx_ant);
429 priv->hw_params.rx_chains_num =
430 num_of_ant(priv->hw_params.valid_rx_ant);
431
432 iwl5150_set_ct_threshold(priv);
433
434 /* Set initial sensitivity parameters */
435 priv->hw_params.sens = &iwl5150_sensitivity;
436}
437
438static void iwl5150_temperature(struct iwl_priv *priv)
439{
440 u32 vt = 0;
441 s32 offset = iwl_temp_calib_to_offset(priv);
442
443 vt = le32_to_cpu(priv->statistics.common.temperature);
444 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
445 /* now vt hold the temperature in Kelvin */
446 priv->temperature = KELVIN_TO_CELSIUS(vt);
447 iwl_tt_handler(priv);
448}
449
450static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
451 struct ieee80211_channel_switch *ch_switch)
452{
453 /*
454 * MULTI-FIXME
455 * See iwlagn_mac_channel_switch.
456 */
457 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
458 struct iwl5000_channel_switch_cmd cmd;
459 const struct iwl_channel_info *ch_info;
460 u32 switch_time_in_usec, ucode_switch_time;
461 u16 ch;
462 u32 tsf_low;
463 u8 switch_count;
464 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
465 struct ieee80211_vif *vif = ctx->vif;
466 struct iwl_host_cmd hcmd = {
467 .id = REPLY_CHANNEL_SWITCH,
468 .len = { sizeof(cmd), },
469 .flags = CMD_SYNC,
470 .data = { &cmd, },
471 };
472
473 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
474 ch = ch_switch->channel->hw_value;
475 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
476 ctx->active.channel, ch);
477 cmd.channel = cpu_to_le16(ch);
478 cmd.rxon_flags = ctx->staging.flags;
479 cmd.rxon_filter_flags = ctx->staging.filter_flags;
480 switch_count = ch_switch->count;
481 tsf_low = ch_switch->timestamp & 0x0ffffffff;
482 /*
483 * calculate the ucode channel switch time
484 * adding TSF as one of the factor for when to switch
485 */
486 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
487 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
488 beacon_interval)) {
489 switch_count -= (priv->ucode_beacon_time -
490 tsf_low) / beacon_interval;
491 } else
492 switch_count = 0;
493 }
494 if (switch_count <= 1)
495 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
496 else {
497 switch_time_in_usec =
498 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
499 ucode_switch_time = iwl_usecs_to_beacons(priv,
500 switch_time_in_usec,
501 beacon_interval);
502 cmd.switch_time = iwl_add_beacon_time(priv,
503 priv->ucode_beacon_time,
504 ucode_switch_time,
505 beacon_interval);
506 }
507 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
508 cmd.switch_time);
509 ch_info = iwl_get_channel_info(priv, priv->band, ch);
510 if (ch_info)
511 cmd.expect_beacon = is_channel_radar(ch_info);
512 else {
513 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
514 ctx->active.channel, ch);
515 return -EFAULT;
516 }
517
518 return iwl_dvm_send_cmd(priv, &hcmd);
519}
520
521struct iwl_lib_ops iwl5000_lib = {
522 .set_hw_params = iwl5000_hw_set_hw_params,
523 .set_channel_switch = iwl5000_hw_channel_switch,
524 .nic_config = iwl5000_nic_config,
525 .eeprom_ops = {
526 .regulatory_bands = {
527 EEPROM_REG_BAND_1_CHANNELS,
528 EEPROM_REG_BAND_2_CHANNELS,
529 EEPROM_REG_BAND_3_CHANNELS,
530 EEPROM_REG_BAND_4_CHANNELS,
531 EEPROM_REG_BAND_5_CHANNELS,
532 EEPROM_REG_BAND_24_HT40_CHANNELS,
533 EEPROM_REG_BAND_52_HT40_CHANNELS
534 },
535 },
536 .temperature = iwlagn_temperature,
537};
538
539struct iwl_lib_ops iwl5150_lib = {
540 .set_hw_params = iwl5150_hw_set_hw_params,
541 .set_channel_switch = iwl5000_hw_channel_switch,
542 .nic_config = iwl5000_nic_config,
543 .eeprom_ops = {
544 .regulatory_bands = {
545 EEPROM_REG_BAND_1_CHANNELS,
546 EEPROM_REG_BAND_2_CHANNELS,
547 EEPROM_REG_BAND_3_CHANNELS,
548 EEPROM_REG_BAND_4_CHANNELS,
549 EEPROM_REG_BAND_5_CHANNELS,
550 EEPROM_REG_BAND_24_HT40_CHANNELS,
551 EEPROM_REG_BAND_52_HT40_CHANNELS
552 },
553 },
554 .temperature = iwl5150_temperature,
555};
556
557
558
559/*
560 * 6000 series
561 * ===========
562 */
563
564static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
565{
566 /* want Celsius */
567 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
568 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
569}
570
571/* NIC configuration for 6000 series */
572static void iwl6000_nic_config(struct iwl_priv *priv)
573{
574 iwl_rf_config(priv);
575
576 switch (cfg(priv)->device_family) {
577 case IWL_DEVICE_FAMILY_6005:
578 case IWL_DEVICE_FAMILY_6030:
579 case IWL_DEVICE_FAMILY_6000:
580 break;
581 case IWL_DEVICE_FAMILY_6000i:
582 /* 2x2 IPA phy type */
583 iwl_write32(trans(priv), CSR_GP_DRIVER_REG,
584 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
585 break;
586 case IWL_DEVICE_FAMILY_6050:
587 /* Indicate calibration version to uCode. */
588 if (iwl_eeprom_calib_version(priv) >= 6)
589 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
590 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
591 break;
592 case IWL_DEVICE_FAMILY_6150:
593 /* Indicate calibration version to uCode. */
594 if (iwl_eeprom_calib_version(priv) >= 6)
595 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
596 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
597 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
598 CSR_GP_DRIVER_REG_BIT_6050_1x2);
599 break;
600 default:
601 WARN_ON(1);
602 }
603}
604
605static const struct iwl_sensitivity_ranges iwl6000_sensitivity = {
606 .min_nrg_cck = 110,
607 .auto_corr_min_ofdm = 80,
608 .auto_corr_min_ofdm_mrc = 128,
609 .auto_corr_min_ofdm_x1 = 105,
610 .auto_corr_min_ofdm_mrc_x1 = 192,
611
612 .auto_corr_max_ofdm = 145,
613 .auto_corr_max_ofdm_mrc = 232,
614 .auto_corr_max_ofdm_x1 = 110,
615 .auto_corr_max_ofdm_mrc_x1 = 232,
616
617 .auto_corr_min_cck = 125,
618 .auto_corr_max_cck = 175,
619 .auto_corr_min_cck_mrc = 160,
620 .auto_corr_max_cck_mrc = 310,
621 .nrg_th_cck = 110,
622 .nrg_th_ofdm = 110,
623
624 .barker_corr_th_min = 190,
625 .barker_corr_th_min_mrc = 336,
626 .nrg_th_cca = 62,
627};
628
629static void iwl6000_hw_set_hw_params(struct iwl_priv *priv)
630{
631 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
632 BIT(IEEE80211_BAND_5GHZ);
633
634 priv->hw_params.tx_chains_num =
635 num_of_ant(priv->hw_params.valid_tx_ant);
636 if (cfg(priv)->rx_with_siso_diversity)
637 priv->hw_params.rx_chains_num = 1;
638 else
639 priv->hw_params.rx_chains_num =
640 num_of_ant(priv->hw_params.valid_rx_ant);
641
642 iwl6000_set_ct_threshold(priv);
643
644 /* Set initial sensitivity parameters */
645 priv->hw_params.sens = &iwl6000_sensitivity;
646
647}
648
649static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
650 struct ieee80211_channel_switch *ch_switch)
651{
652 /*
653 * MULTI-FIXME
654 * See iwlagn_mac_channel_switch.
655 */
656 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
657 struct iwl6000_channel_switch_cmd cmd;
658 const struct iwl_channel_info *ch_info;
659 u32 switch_time_in_usec, ucode_switch_time;
660 u16 ch;
661 u32 tsf_low;
662 u8 switch_count;
663 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
664 struct ieee80211_vif *vif = ctx->vif;
665 struct iwl_host_cmd hcmd = {
666 .id = REPLY_CHANNEL_SWITCH,
667 .len = { sizeof(cmd), },
668 .flags = CMD_SYNC,
669 .data = { &cmd, },
670 };
671
672 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
673 ch = ch_switch->channel->hw_value;
674 IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
675 ctx->active.channel, ch);
676 cmd.channel = cpu_to_le16(ch);
677 cmd.rxon_flags = ctx->staging.flags;
678 cmd.rxon_filter_flags = ctx->staging.filter_flags;
679 switch_count = ch_switch->count;
680 tsf_low = ch_switch->timestamp & 0x0ffffffff;
681 /*
682 * calculate the ucode channel switch time
683 * adding TSF as one of the factor for when to switch
684 */
685 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
686 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
687 beacon_interval)) {
688 switch_count -= (priv->ucode_beacon_time -
689 tsf_low) / beacon_interval;
690 } else
691 switch_count = 0;
692 }
693 if (switch_count <= 1)
694 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
695 else {
696 switch_time_in_usec =
697 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
698 ucode_switch_time = iwl_usecs_to_beacons(priv,
699 switch_time_in_usec,
700 beacon_interval);
701 cmd.switch_time = iwl_add_beacon_time(priv,
702 priv->ucode_beacon_time,
703 ucode_switch_time,
704 beacon_interval);
705 }
706 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
707 cmd.switch_time);
708 ch_info = iwl_get_channel_info(priv, priv->band, ch);
709 if (ch_info)
710 cmd.expect_beacon = is_channel_radar(ch_info);
711 else {
712 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
713 ctx->active.channel, ch);
714 return -EFAULT;
715 }
716
717 return iwl_dvm_send_cmd(priv, &hcmd);
718}
719
720struct iwl_lib_ops iwl6000_lib = {
721 .set_hw_params = iwl6000_hw_set_hw_params,
722 .set_channel_switch = iwl6000_hw_channel_switch,
723 .nic_config = iwl6000_nic_config,
724 .eeprom_ops = {
725 .regulatory_bands = {
726 EEPROM_REG_BAND_1_CHANNELS,
727 EEPROM_REG_BAND_2_CHANNELS,
728 EEPROM_REG_BAND_3_CHANNELS,
729 EEPROM_REG_BAND_4_CHANNELS,
730 EEPROM_REG_BAND_5_CHANNELS,
731 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
732 EEPROM_REG_BAND_52_HT40_CHANNELS
733 },
734 .enhanced_txpower = true,
735 },
736 .temperature = iwlagn_temperature,
737};
738
739struct iwl_lib_ops iwl6030_lib = {
740 .set_hw_params = iwl6000_hw_set_hw_params,
741 .set_channel_switch = iwl6000_hw_channel_switch,
742 .nic_config = iwl6000_nic_config,
743 .eeprom_ops = {
744 .regulatory_bands = {
745 EEPROM_REG_BAND_1_CHANNELS,
746 EEPROM_REG_BAND_2_CHANNELS,
747 EEPROM_REG_BAND_3_CHANNELS,
748 EEPROM_REG_BAND_4_CHANNELS,
749 EEPROM_REG_BAND_5_CHANNELS,
750 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
751 EEPROM_REG_BAND_52_HT40_CHANNELS
752 },
753 .enhanced_txpower = true,
754 },
755 .temperature = iwlagn_temperature,
756};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 4da4ab23cce7..4e0c248a0050 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -94,77 +94,13 @@ void iwlagn_temperature(struct iwl_priv *priv)
94 iwl_tt_handler(priv); 94 iwl_tt_handler(priv);
95} 95}
96 96
97u16 iwl_eeprom_calib_version(struct iwl_shared *shrd)
98{
99 struct iwl_eeprom_calib_hdr *hdr;
100
101 hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(shrd,
102 EEPROM_CALIB_ALL);
103 return hdr->version;
104
105}
106
107/*
108 * EEPROM
109 */
110static u32 eeprom_indirect_address(const struct iwl_shared *shrd, u32 address)
111{
112 u16 offset = 0;
113
114 if ((address & INDIRECT_ADDRESS) == 0)
115 return address;
116
117 switch (address & INDIRECT_TYPE_MSK) {
118 case INDIRECT_HOST:
119 offset = iwl_eeprom_query16(shrd, EEPROM_LINK_HOST);
120 break;
121 case INDIRECT_GENERAL:
122 offset = iwl_eeprom_query16(shrd, EEPROM_LINK_GENERAL);
123 break;
124 case INDIRECT_REGULATORY:
125 offset = iwl_eeprom_query16(shrd, EEPROM_LINK_REGULATORY);
126 break;
127 case INDIRECT_TXP_LIMIT:
128 offset = iwl_eeprom_query16(shrd, EEPROM_LINK_TXP_LIMIT);
129 break;
130 case INDIRECT_TXP_LIMIT_SIZE:
131 offset = iwl_eeprom_query16(shrd, EEPROM_LINK_TXP_LIMIT_SIZE);
132 break;
133 case INDIRECT_CALIBRATION:
134 offset = iwl_eeprom_query16(shrd, EEPROM_LINK_CALIBRATION);
135 break;
136 case INDIRECT_PROCESS_ADJST:
137 offset = iwl_eeprom_query16(shrd, EEPROM_LINK_PROCESS_ADJST);
138 break;
139 case INDIRECT_OTHERS:
140 offset = iwl_eeprom_query16(shrd, EEPROM_LINK_OTHERS);
141 break;
142 default:
143 IWL_ERR(shrd->trans, "illegal indirect type: 0x%X\n",
144 address & INDIRECT_TYPE_MSK);
145 break;
146 }
147
148 /* translate the offset from words to byte */
149 return (address & ADDRESS_MSK) + (offset << 1);
150}
151
152const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset)
153{
154 u32 address = eeprom_indirect_address(shrd, offset);
155 BUG_ON(address >= shrd->cfg->base_params->eeprom_size);
156 return &shrd->eeprom[address];
157}
158
159struct iwl_mod_params iwlagn_mod_params = { 97struct iwl_mod_params iwlagn_mod_params = {
160 .amsdu_size_8K = 1, 98 .amsdu_size_8K = 1,
161 .restart_fw = 1, 99 .restart_fw = 1,
162 .plcp_check = true, 100 .plcp_check = true,
163 .bt_coex_active = true, 101 .bt_coex_active = true,
164 .no_sleep_autoadjust = true,
165 .power_level = IWL_POWER_INDEX_1, 102 .power_level = IWL_POWER_INDEX_1,
166 .bt_ch_announce = true, 103 .bt_ch_announce = true,
167 .wanted_ucode_alternative = 1,
168 .auto_agg = true, 104 .auto_agg = true,
169 /* the rest are 0 by default */ 105 /* the rest are 0 by default */
170}; 106};
@@ -234,7 +170,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
234 IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | 170 IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK |
235 IWL_PAN_SCD_MULTICAST_MSK; 171 IWL_PAN_SCD_MULTICAST_MSK;
236 172
237 if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) 173 if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)
238 flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; 174 flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
239 175
240 IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", 176 IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
@@ -369,24 +305,30 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
369 .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT, 305 .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT,
370 .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT, 306 .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT,
371 }; 307 };
372 struct iwl6000_bt_cmd bt_cmd_6000; 308 struct iwl_bt_cmd_v1 bt_cmd_v1;
373 struct iwl2000_bt_cmd bt_cmd_2000; 309 struct iwl_bt_cmd_v2 bt_cmd_v2;
374 int ret; 310 int ret;
375 311
376 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != 312 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
377 sizeof(basic.bt3_lookup_table)); 313 sizeof(basic.bt3_lookup_table));
378 314
379 if (cfg(priv)->bt_params) { 315 if (cfg(priv)->bt_params) {
316 /*
317 * newer generation of devices (2000 series and newer)
318 * use the version 2 of the bt command
319 * we need to make sure sending the host command
320 * with correct data structure to avoid uCode assert
321 */
380 if (cfg(priv)->bt_params->bt_session_2) { 322 if (cfg(priv)->bt_params->bt_session_2) {
381 bt_cmd_2000.prio_boost = cpu_to_le32( 323 bt_cmd_v2.prio_boost = cpu_to_le32(
382 cfg(priv)->bt_params->bt_prio_boost); 324 cfg(priv)->bt_params->bt_prio_boost);
383 bt_cmd_2000.tx_prio_boost = 0; 325 bt_cmd_v2.tx_prio_boost = 0;
384 bt_cmd_2000.rx_prio_boost = 0; 326 bt_cmd_v2.rx_prio_boost = 0;
385 } else { 327 } else {
386 bt_cmd_6000.prio_boost = 328 bt_cmd_v1.prio_boost =
387 cfg(priv)->bt_params->bt_prio_boost; 329 cfg(priv)->bt_params->bt_prio_boost;
388 bt_cmd_6000.tx_prio_boost = 0; 330 bt_cmd_v1.tx_prio_boost = 0;
389 bt_cmd_6000.rx_prio_boost = 0; 331 bt_cmd_v1.rx_prio_boost = 0;
390 } 332 }
391 } else { 333 } else {
392 IWL_ERR(priv, "failed to construct BT Coex Config\n"); 334 IWL_ERR(priv, "failed to construct BT Coex Config\n");
@@ -433,15 +375,15 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
433 "full concurrency" : "3-wire"); 375 "full concurrency" : "3-wire");
434 376
435 if (cfg(priv)->bt_params->bt_session_2) { 377 if (cfg(priv)->bt_params->bt_session_2) {
436 memcpy(&bt_cmd_2000.basic, &basic, 378 memcpy(&bt_cmd_v2.basic, &basic,
437 sizeof(basic)); 379 sizeof(basic));
438 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, 380 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
439 CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); 381 CMD_SYNC, sizeof(bt_cmd_v2), &bt_cmd_v2);
440 } else { 382 } else {
441 memcpy(&bt_cmd_6000.basic, &basic, 383 memcpy(&bt_cmd_v1.basic, &basic,
442 sizeof(basic)); 384 sizeof(basic));
443 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, 385 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
444 CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); 386 CMD_SYNC, sizeof(bt_cmd_v1), &bt_cmd_v1);
445 } 387 }
446 if (ret) 388 if (ret)
447 IWL_ERR(priv, "failed to send BT Coex Config\n"); 389 IWL_ERR(priv, "failed to send BT Coex Config\n");
@@ -868,7 +810,7 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
868 if (priv->chain_noise_data.active_chains) 810 if (priv->chain_noise_data.active_chains)
869 active_chains = priv->chain_noise_data.active_chains; 811 active_chains = priv->chain_noise_data.active_chains;
870 else 812 else
871 active_chains = hw_params(priv).valid_rx_ant; 813 active_chains = priv->hw_params.valid_rx_ant;
872 814
873 if (cfg(priv)->bt_params && 815 if (cfg(priv)->bt_params &&
874 cfg(priv)->bt_params->advanced_bt_coexist && 816 cfg(priv)->bt_params->advanced_bt_coexist &&
@@ -1300,7 +1242,7 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1300 1242
1301 if (test_bit(STATUS_FW_ERROR, &priv->status)) { 1243 if (test_bit(STATUS_FW_ERROR, &priv->status)) {
1302 IWL_ERR(priv, "Command %s failed: FW Error\n", 1244 IWL_ERR(priv, "Command %s failed: FW Error\n",
1303 get_cmd_string(cmd->id)); 1245 iwl_dvm_get_cmd_string(cmd->id));
1304 return -EIO; 1246 return -EIO;
1305 } 1247 }
1306 1248
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index b936ae7e00a3..8b13b6cf940a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -819,7 +819,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
819 819
820 if (num_of_ant(tbl->ant_type) > 1) 820 if (num_of_ant(tbl->ant_type) > 1)
821 tbl->ant_type = 821 tbl->ant_type =
822 first_antenna(hw_params(priv).valid_tx_ant); 822 first_antenna(priv->hw_params.valid_tx_ant);
823 823
824 tbl->is_ht40 = 0; 824 tbl->is_ht40 = 0;
825 tbl->is_SGI = 0; 825 tbl->is_SGI = 0;
@@ -1291,7 +1291,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1291 return -1; 1291 return -1;
1292 1292
1293 /* Need both Tx chains/antennas to support MIMO */ 1293 /* Need both Tx chains/antennas to support MIMO */
1294 if (hw_params(priv).tx_chains_num < 2) 1294 if (priv->hw_params.tx_chains_num < 2)
1295 return -1; 1295 return -1;
1296 1296
1297 IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO2\n"); 1297 IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO2\n");
@@ -1347,7 +1347,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
1347 return -1; 1347 return -1;
1348 1348
1349 /* Need both Tx chains/antennas to support MIMO */ 1349 /* Need both Tx chains/antennas to support MIMO */
1350 if (hw_params(priv).tx_chains_num < 3) 1350 if (priv->hw_params.tx_chains_num < 3)
1351 return -1; 1351 return -1;
1352 1352
1353 IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO3\n"); 1353 IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO3\n");
@@ -1446,8 +1446,8 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1446 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1446 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1447 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1447 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1448 u8 start_action; 1448 u8 start_action;
1449 u8 valid_tx_ant = hw_params(priv).valid_tx_ant; 1449 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1450 u8 tx_chains_num = hw_params(priv).tx_chains_num; 1450 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1451 int ret = 0; 1451 int ret = 0;
1452 u8 update_search_tbl_counter = 0; 1452 u8 update_search_tbl_counter = 0;
1453 1453
@@ -1464,7 +1464,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1464 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: 1464 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1465 /* avoid antenna B and MIMO */ 1465 /* avoid antenna B and MIMO */
1466 valid_tx_ant = 1466 valid_tx_ant =
1467 first_antenna(hw_params(priv).valid_tx_ant); 1467 first_antenna(priv->hw_params.valid_tx_ant);
1468 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && 1468 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 &&
1469 tbl->action != IWL_LEGACY_SWITCH_SISO) 1469 tbl->action != IWL_LEGACY_SWITCH_SISO)
1470 tbl->action = IWL_LEGACY_SWITCH_SISO; 1470 tbl->action = IWL_LEGACY_SWITCH_SISO;
@@ -1488,7 +1488,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1488 else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) 1488 else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
1489 tbl->action = IWL_LEGACY_SWITCH_SISO; 1489 tbl->action = IWL_LEGACY_SWITCH_SISO;
1490 valid_tx_ant = 1490 valid_tx_ant =
1491 first_antenna(hw_params(priv).valid_tx_ant); 1491 first_antenna(priv->hw_params.valid_tx_ant);
1492 } 1492 }
1493 1493
1494 start_action = tbl->action; 1494 start_action = tbl->action;
@@ -1622,8 +1622,8 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1622 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1622 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1623 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1623 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1624 u8 start_action; 1624 u8 start_action;
1625 u8 valid_tx_ant = hw_params(priv).valid_tx_ant; 1625 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1626 u8 tx_chains_num = hw_params(priv).tx_chains_num; 1626 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1627 u8 update_search_tbl_counter = 0; 1627 u8 update_search_tbl_counter = 0;
1628 int ret; 1628 int ret;
1629 1629
@@ -1640,7 +1640,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1640 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: 1640 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1641 /* avoid antenna B and MIMO */ 1641 /* avoid antenna B and MIMO */
1642 valid_tx_ant = 1642 valid_tx_ant =
1643 first_antenna(hw_params(priv).valid_tx_ant); 1643 first_antenna(priv->hw_params.valid_tx_ant);
1644 if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) 1644 if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
1645 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1645 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1646 break; 1646 break;
@@ -1658,7 +1658,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1658 /* configure as 1x1 if bt full concurrency */ 1658 /* configure as 1x1 if bt full concurrency */
1659 if (priv->bt_full_concurrent) { 1659 if (priv->bt_full_concurrent) {
1660 valid_tx_ant = 1660 valid_tx_ant =
1661 first_antenna(hw_params(priv).valid_tx_ant); 1661 first_antenna(priv->hw_params.valid_tx_ant);
1662 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) 1662 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
1663 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1663 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1664 } 1664 }
@@ -1794,8 +1794,8 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1794 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1794 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1795 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1795 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1796 u8 start_action; 1796 u8 start_action;
1797 u8 valid_tx_ant = hw_params(priv).valid_tx_ant; 1797 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1798 u8 tx_chains_num = hw_params(priv).tx_chains_num; 1798 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1799 u8 update_search_tbl_counter = 0; 1799 u8 update_search_tbl_counter = 0;
1800 int ret; 1800 int ret;
1801 1801
@@ -1964,8 +1964,8 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1964 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1964 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1965 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1965 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1966 u8 start_action; 1966 u8 start_action;
1967 u8 valid_tx_ant = hw_params(priv).valid_tx_ant; 1967 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1968 u8 tx_chains_num = hw_params(priv).tx_chains_num; 1968 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1969 int ret; 1969 int ret;
1970 u8 update_search_tbl_counter = 0; 1970 u8 update_search_tbl_counter = 0;
1971 1971
@@ -2698,7 +2698,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2698 2698
2699 i = lq_sta->last_txrate_idx; 2699 i = lq_sta->last_txrate_idx;
2700 2700
2701 valid_tx_ant = hw_params(priv).valid_tx_ant; 2701 valid_tx_ant = priv->hw_params.valid_tx_ant;
2702 2702
2703 if (!lq_sta->search_better_tbl) 2703 if (!lq_sta->search_better_tbl)
2704 active_tbl = lq_sta->active_tbl; 2704 active_tbl = lq_sta->active_tbl;
@@ -2826,6 +2826,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2826 struct iwl_station_priv *sta_priv; 2826 struct iwl_station_priv *sta_priv;
2827 struct iwl_lq_sta *lq_sta; 2827 struct iwl_lq_sta *lq_sta;
2828 struct ieee80211_supported_band *sband; 2828 struct ieee80211_supported_band *sband;
2829 unsigned long supp; /* must be unsigned long for for_each_set_bit */
2829 2830
2830 sta_priv = (struct iwl_station_priv *) sta->drv_priv; 2831 sta_priv = (struct iwl_station_priv *) sta->drv_priv;
2831 lq_sta = &sta_priv->lq_sta; 2832 lq_sta = &sta_priv->lq_sta;
@@ -2855,8 +2856,15 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2855 lq_sta->max_rate_idx = -1; 2856 lq_sta->max_rate_idx = -1;
2856 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2857 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2857 lq_sta->is_green = rs_use_green(sta); 2858 lq_sta->is_green = rs_use_green(sta);
2858 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); 2859 lq_sta->band = sband->band;
2859 lq_sta->band = priv->band; 2860 /*
2861 * active legacy rates as per supported rates bitmap
2862 */
2863 supp = sta->supp_rates[sband->band];
2864 lq_sta->active_legacy_rate = 0;
2865 for_each_set_bit(i, &supp, BITS_PER_LONG)
2866 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value);
2867
2860 /* 2868 /*
2861 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), 2869 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
2862 * supp_rates[] does not; shift to convert format, force 9 MBits off. 2870 * supp_rates[] does not; shift to convert format, force 9 MBits off.
@@ -2884,15 +2892,15 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2884 2892
2885 /* These values will be overridden later */ 2893 /* These values will be overridden later */
2886 lq_sta->lq.general_params.single_stream_ant_msk = 2894 lq_sta->lq.general_params.single_stream_ant_msk =
2887 first_antenna(hw_params(priv).valid_tx_ant); 2895 first_antenna(priv->hw_params.valid_tx_ant);
2888 lq_sta->lq.general_params.dual_stream_ant_msk = 2896 lq_sta->lq.general_params.dual_stream_ant_msk =
2889 hw_params(priv).valid_tx_ant & 2897 priv->hw_params.valid_tx_ant &
2890 ~first_antenna(hw_params(priv).valid_tx_ant); 2898 ~first_antenna(priv->hw_params.valid_tx_ant);
2891 if (!lq_sta->lq.general_params.dual_stream_ant_msk) { 2899 if (!lq_sta->lq.general_params.dual_stream_ant_msk) {
2892 lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; 2900 lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;
2893 } else if (num_of_ant(hw_params(priv).valid_tx_ant) == 2) { 2901 } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
2894 lq_sta->lq.general_params.dual_stream_ant_msk = 2902 lq_sta->lq.general_params.dual_stream_ant_msk =
2895 hw_params(priv).valid_tx_ant; 2903 priv->hw_params.valid_tx_ant;
2896 } 2904 }
2897 2905
2898 /* as default allow aggregation for all tids */ 2906 /* as default allow aggregation for all tids */
@@ -2938,7 +2946,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2938 if (priv && priv->bt_full_concurrent) { 2946 if (priv && priv->bt_full_concurrent) {
2939 /* 1x1 only */ 2947 /* 1x1 only */
2940 tbl_type.ant_type = 2948 tbl_type.ant_type =
2941 first_antenna(hw_params(priv).valid_tx_ant); 2949 first_antenna(priv->hw_params.valid_tx_ant);
2942 } 2950 }
2943 2951
2944 /* How many times should we repeat the initial rate? */ 2952 /* How many times should we repeat the initial rate? */
@@ -2970,7 +2978,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2970 if (priv->bt_full_concurrent) 2978 if (priv->bt_full_concurrent)
2971 valid_tx_ant = ANT_A; 2979 valid_tx_ant = ANT_A;
2972 else 2980 else
2973 valid_tx_ant = hw_params(priv).valid_tx_ant; 2981 valid_tx_ant = priv->hw_params.valid_tx_ant;
2974 } 2982 }
2975 2983
2976 /* Fill rest of rate table */ 2984 /* Fill rest of rate table */
@@ -3004,7 +3012,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
3004 if (priv && priv->bt_full_concurrent) { 3012 if (priv && priv->bt_full_concurrent) {
3005 /* 1x1 only */ 3013 /* 1x1 only */
3006 tbl_type.ant_type = 3014 tbl_type.ant_type =
3007 first_antenna(hw_params(priv).valid_tx_ant); 3015 first_antenna(priv->hw_params.valid_tx_ant);
3008 } 3016 }
3009 3017
3010 /* Indicate to uCode which entries might be MIMO. 3018 /* Indicate to uCode which entries might be MIMO.
@@ -3091,7 +3099,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
3091 u8 ant_sel_tx; 3099 u8 ant_sel_tx;
3092 3100
3093 priv = lq_sta->drv; 3101 priv = lq_sta->drv;
3094 valid_tx_ant = hw_params(priv).valid_tx_ant; 3102 valid_tx_ant = priv->hw_params.valid_tx_ant;
3095 if (lq_sta->dbg_fixed_rate) { 3103 if (lq_sta->dbg_fixed_rate) {
3096 ant_sel_tx = 3104 ant_sel_tx =
3097 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) 3105 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
@@ -3162,9 +3170,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3162 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 3170 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
3163 lq_sta->dbg_fixed_rate); 3171 lq_sta->dbg_fixed_rate);
3164 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", 3172 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
3165 (hw_params(priv).valid_tx_ant & ANT_A) ? "ANT_A," : "", 3173 (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
3166 (hw_params(priv).valid_tx_ant & ANT_B) ? "ANT_B," : "", 3174 (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",
3167 (hw_params(priv).valid_tx_ant & ANT_C) ? "ANT_C" : ""); 3175 (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : "");
3168 desc += sprintf(buff+desc, "lq type %s\n", 3176 desc += sprintf(buff+desc, "lq type %s\n",
3169 (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); 3177 (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
3170 if (is_Ht(tbl->lq_type)) { 3178 if (is_Ht(tbl->lq_type)) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index e12f11d50b88..db6c90f6affe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -40,89 +40,86 @@
40#include "iwl-agn.h" 40#include "iwl-agn.h"
41#include "iwl-shared.h" 41#include "iwl-shared.h"
42 42
43const char *get_cmd_string(u8 cmd) 43#define IWL_CMD_ENTRY(x) [x] = #x
44{ 44
45 switch (cmd) { 45const char *iwl_dvm_cmd_strings[REPLY_MAX] = {
46 IWL_CMD(REPLY_ALIVE); 46 IWL_CMD_ENTRY(REPLY_ALIVE),
47 IWL_CMD(REPLY_ERROR); 47 IWL_CMD_ENTRY(REPLY_ERROR),
48 IWL_CMD(REPLY_ECHO); 48 IWL_CMD_ENTRY(REPLY_ECHO),
49 IWL_CMD(REPLY_RXON); 49 IWL_CMD_ENTRY(REPLY_RXON),
50 IWL_CMD(REPLY_RXON_ASSOC); 50 IWL_CMD_ENTRY(REPLY_RXON_ASSOC),
51 IWL_CMD(REPLY_QOS_PARAM); 51 IWL_CMD_ENTRY(REPLY_QOS_PARAM),
52 IWL_CMD(REPLY_RXON_TIMING); 52 IWL_CMD_ENTRY(REPLY_RXON_TIMING),
53 IWL_CMD(REPLY_ADD_STA); 53 IWL_CMD_ENTRY(REPLY_ADD_STA),
54 IWL_CMD(REPLY_REMOVE_STA); 54 IWL_CMD_ENTRY(REPLY_REMOVE_STA),
55 IWL_CMD(REPLY_REMOVE_ALL_STA); 55 IWL_CMD_ENTRY(REPLY_REMOVE_ALL_STA),
56 IWL_CMD(REPLY_TXFIFO_FLUSH); 56 IWL_CMD_ENTRY(REPLY_TXFIFO_FLUSH),
57 IWL_CMD(REPLY_WEPKEY); 57 IWL_CMD_ENTRY(REPLY_WEPKEY),
58 IWL_CMD(REPLY_TX); 58 IWL_CMD_ENTRY(REPLY_TX),
59 IWL_CMD(REPLY_LEDS_CMD); 59 IWL_CMD_ENTRY(REPLY_LEDS_CMD),
60 IWL_CMD(REPLY_TX_LINK_QUALITY_CMD); 60 IWL_CMD_ENTRY(REPLY_TX_LINK_QUALITY_CMD),
61 IWL_CMD(COEX_PRIORITY_TABLE_CMD); 61 IWL_CMD_ENTRY(COEX_PRIORITY_TABLE_CMD),
62 IWL_CMD(COEX_MEDIUM_NOTIFICATION); 62 IWL_CMD_ENTRY(COEX_MEDIUM_NOTIFICATION),
63 IWL_CMD(COEX_EVENT_CMD); 63 IWL_CMD_ENTRY(COEX_EVENT_CMD),
64 IWL_CMD(REPLY_QUIET_CMD); 64 IWL_CMD_ENTRY(REPLY_QUIET_CMD),
65 IWL_CMD(REPLY_CHANNEL_SWITCH); 65 IWL_CMD_ENTRY(REPLY_CHANNEL_SWITCH),
66 IWL_CMD(CHANNEL_SWITCH_NOTIFICATION); 66 IWL_CMD_ENTRY(CHANNEL_SWITCH_NOTIFICATION),
67 IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD); 67 IWL_CMD_ENTRY(REPLY_SPECTRUM_MEASUREMENT_CMD),
68 IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION); 68 IWL_CMD_ENTRY(SPECTRUM_MEASURE_NOTIFICATION),
69 IWL_CMD(POWER_TABLE_CMD); 69 IWL_CMD_ENTRY(POWER_TABLE_CMD),
70 IWL_CMD(PM_SLEEP_NOTIFICATION); 70 IWL_CMD_ENTRY(PM_SLEEP_NOTIFICATION),
71 IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC); 71 IWL_CMD_ENTRY(PM_DEBUG_STATISTIC_NOTIFIC),
72 IWL_CMD(REPLY_SCAN_CMD); 72 IWL_CMD_ENTRY(REPLY_SCAN_CMD),
73 IWL_CMD(REPLY_SCAN_ABORT_CMD); 73 IWL_CMD_ENTRY(REPLY_SCAN_ABORT_CMD),
74 IWL_CMD(SCAN_START_NOTIFICATION); 74 IWL_CMD_ENTRY(SCAN_START_NOTIFICATION),
75 IWL_CMD(SCAN_RESULTS_NOTIFICATION); 75 IWL_CMD_ENTRY(SCAN_RESULTS_NOTIFICATION),
76 IWL_CMD(SCAN_COMPLETE_NOTIFICATION); 76 IWL_CMD_ENTRY(SCAN_COMPLETE_NOTIFICATION),
77 IWL_CMD(BEACON_NOTIFICATION); 77 IWL_CMD_ENTRY(BEACON_NOTIFICATION),
78 IWL_CMD(REPLY_TX_BEACON); 78 IWL_CMD_ENTRY(REPLY_TX_BEACON),
79 IWL_CMD(WHO_IS_AWAKE_NOTIFICATION); 79 IWL_CMD_ENTRY(WHO_IS_AWAKE_NOTIFICATION),
80 IWL_CMD(QUIET_NOTIFICATION); 80 IWL_CMD_ENTRY(QUIET_NOTIFICATION),
81 IWL_CMD(REPLY_TX_PWR_TABLE_CMD); 81 IWL_CMD_ENTRY(REPLY_TX_PWR_TABLE_CMD),
82 IWL_CMD(MEASURE_ABORT_NOTIFICATION); 82 IWL_CMD_ENTRY(MEASURE_ABORT_NOTIFICATION),
83 IWL_CMD(REPLY_BT_CONFIG); 83 IWL_CMD_ENTRY(REPLY_BT_CONFIG),
84 IWL_CMD(REPLY_STATISTICS_CMD); 84 IWL_CMD_ENTRY(REPLY_STATISTICS_CMD),
85 IWL_CMD(STATISTICS_NOTIFICATION); 85 IWL_CMD_ENTRY(STATISTICS_NOTIFICATION),
86 IWL_CMD(REPLY_CARD_STATE_CMD); 86 IWL_CMD_ENTRY(REPLY_CARD_STATE_CMD),
87 IWL_CMD(CARD_STATE_NOTIFICATION); 87 IWL_CMD_ENTRY(CARD_STATE_NOTIFICATION),
88 IWL_CMD(MISSED_BEACONS_NOTIFICATION); 88 IWL_CMD_ENTRY(MISSED_BEACONS_NOTIFICATION),
89 IWL_CMD(REPLY_CT_KILL_CONFIG_CMD); 89 IWL_CMD_ENTRY(REPLY_CT_KILL_CONFIG_CMD),
90 IWL_CMD(SENSITIVITY_CMD); 90 IWL_CMD_ENTRY(SENSITIVITY_CMD),
91 IWL_CMD(REPLY_PHY_CALIBRATION_CMD); 91 IWL_CMD_ENTRY(REPLY_PHY_CALIBRATION_CMD),
92 IWL_CMD(REPLY_RX_PHY_CMD); 92 IWL_CMD_ENTRY(REPLY_RX_PHY_CMD),
93 IWL_CMD(REPLY_RX_MPDU_CMD); 93 IWL_CMD_ENTRY(REPLY_RX_MPDU_CMD),
94 IWL_CMD(REPLY_RX); 94 IWL_CMD_ENTRY(REPLY_RX),
95 IWL_CMD(REPLY_COMPRESSED_BA); 95 IWL_CMD_ENTRY(REPLY_COMPRESSED_BA),
96 IWL_CMD(CALIBRATION_CFG_CMD); 96 IWL_CMD_ENTRY(CALIBRATION_CFG_CMD),
97 IWL_CMD(CALIBRATION_RES_NOTIFICATION); 97 IWL_CMD_ENTRY(CALIBRATION_RES_NOTIFICATION),
98 IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION); 98 IWL_CMD_ENTRY(CALIBRATION_COMPLETE_NOTIFICATION),
99 IWL_CMD(REPLY_TX_POWER_DBM_CMD); 99 IWL_CMD_ENTRY(REPLY_TX_POWER_DBM_CMD),
100 IWL_CMD(TEMPERATURE_NOTIFICATION); 100 IWL_CMD_ENTRY(TEMPERATURE_NOTIFICATION),
101 IWL_CMD(TX_ANT_CONFIGURATION_CMD); 101 IWL_CMD_ENTRY(TX_ANT_CONFIGURATION_CMD),
102 IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF); 102 IWL_CMD_ENTRY(REPLY_BT_COEX_PROFILE_NOTIF),
103 IWL_CMD(REPLY_BT_COEX_PRIO_TABLE); 103 IWL_CMD_ENTRY(REPLY_BT_COEX_PRIO_TABLE),
104 IWL_CMD(REPLY_BT_COEX_PROT_ENV); 104 IWL_CMD_ENTRY(REPLY_BT_COEX_PROT_ENV),
105 IWL_CMD(REPLY_WIPAN_PARAMS); 105 IWL_CMD_ENTRY(REPLY_WIPAN_PARAMS),
106 IWL_CMD(REPLY_WIPAN_RXON); 106 IWL_CMD_ENTRY(REPLY_WIPAN_RXON),
107 IWL_CMD(REPLY_WIPAN_RXON_TIMING); 107 IWL_CMD_ENTRY(REPLY_WIPAN_RXON_TIMING),
108 IWL_CMD(REPLY_WIPAN_RXON_ASSOC); 108 IWL_CMD_ENTRY(REPLY_WIPAN_RXON_ASSOC),
109 IWL_CMD(REPLY_WIPAN_QOS_PARAM); 109 IWL_CMD_ENTRY(REPLY_WIPAN_QOS_PARAM),
110 IWL_CMD(REPLY_WIPAN_WEPKEY); 110 IWL_CMD_ENTRY(REPLY_WIPAN_WEPKEY),
111 IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); 111 IWL_CMD_ENTRY(REPLY_WIPAN_P2P_CHANNEL_SWITCH),
112 IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); 112 IWL_CMD_ENTRY(REPLY_WIPAN_NOA_NOTIFICATION),
113 IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE); 113 IWL_CMD_ENTRY(REPLY_WIPAN_DEACTIVATION_COMPLETE),
114 IWL_CMD(REPLY_WOWLAN_PATTERNS); 114 IWL_CMD_ENTRY(REPLY_WOWLAN_PATTERNS),
115 IWL_CMD(REPLY_WOWLAN_WAKEUP_FILTER); 115 IWL_CMD_ENTRY(REPLY_WOWLAN_WAKEUP_FILTER),
116 IWL_CMD(REPLY_WOWLAN_TSC_RSC_PARAMS); 116 IWL_CMD_ENTRY(REPLY_WOWLAN_TSC_RSC_PARAMS),
117 IWL_CMD(REPLY_WOWLAN_TKIP_PARAMS); 117 IWL_CMD_ENTRY(REPLY_WOWLAN_TKIP_PARAMS),
118 IWL_CMD(REPLY_WOWLAN_KEK_KCK_MATERIAL); 118 IWL_CMD_ENTRY(REPLY_WOWLAN_KEK_KCK_MATERIAL),
119 IWL_CMD(REPLY_WOWLAN_GET_STATUS); 119 IWL_CMD_ENTRY(REPLY_WOWLAN_GET_STATUS),
120 IWL_CMD(REPLY_D3_CONFIG); 120 IWL_CMD_ENTRY(REPLY_D3_CONFIG),
121 default: 121};
122 return "UNKNOWN"; 122#undef IWL_CMD_ENTRY
123
124 }
125}
126 123
127/****************************************************************************** 124/******************************************************************************
128 * 125 *
@@ -137,10 +134,9 @@ static int iwlagn_rx_reply_error(struct iwl_priv *priv,
137 struct iwl_rx_packet *pkt = rxb_addr(rxb); 134 struct iwl_rx_packet *pkt = rxb_addr(rxb);
138 struct iwl_error_resp *err_resp = (void *)pkt->data; 135 struct iwl_error_resp *err_resp = (void *)pkt->data;
139 136
140 IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " 137 IWL_ERR(priv, "Error Reply type 0x%08X cmd REPLY_ERROR (0x%02X) "
141 "seq 0x%04X ser 0x%08X\n", 138 "seq 0x%04X ser 0x%08X\n",
142 le32_to_cpu(err_resp->error_type), 139 le32_to_cpu(err_resp->error_type),
143 get_cmd_string(err_resp->cmd_id),
144 err_resp->cmd_id, 140 err_resp->cmd_id,
145 le16_to_cpu(err_resp->bad_cmd_seq_num), 141 le16_to_cpu(err_resp->bad_cmd_seq_num),
146 le32_to_cpu(err_resp->error_info)); 142 le32_to_cpu(err_resp->error_info));
@@ -216,8 +212,7 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
216 u32 __maybe_unused len = 212 u32 __maybe_unused len =
217 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 213 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
218 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " 214 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
219 "notification for %s:\n", len, 215 "notification for PM_DEBUG_STATISTIC_NOTIFIC:\n", len);
220 get_cmd_string(pkt->hdr.cmd));
221 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); 216 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len);
222 return 0; 217 return 0;
223} 218}
@@ -246,69 +241,6 @@ static int iwlagn_rx_beacon_notif(struct iwl_priv *priv,
246 return 0; 241 return 0;
247} 242}
248 243
249/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
250#define ACK_CNT_RATIO (50)
251#define BA_TIMEOUT_CNT (5)
252#define BA_TIMEOUT_MAX (16)
253
254/**
255 * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
256 *
257 * When the ACK count ratio is low and aggregated BA timeout retries exceeding
258 * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
259 * operation state.
260 */
261static bool iwlagn_good_ack_health(struct iwl_priv *priv,
262 struct statistics_tx *cur)
263{
264 int actual_delta, expected_delta, ba_timeout_delta;
265 struct statistics_tx *old;
266
267 if (priv->agg_tids_count)
268 return true;
269
270 lockdep_assert_held(&priv->statistics.lock);
271
272 old = &priv->statistics.tx;
273
274 actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
275 le32_to_cpu(old->actual_ack_cnt);
276 expected_delta = le32_to_cpu(cur->expected_ack_cnt) -
277 le32_to_cpu(old->expected_ack_cnt);
278
279 /* Values should not be negative, but we do not trust the firmware */
280 if (actual_delta <= 0 || expected_delta <= 0)
281 return true;
282
283 ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) -
284 le32_to_cpu(old->agg.ba_timeout);
285
286 if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO &&
287 ba_timeout_delta > BA_TIMEOUT_CNT) {
288 IWL_DEBUG_RADIO(priv,
289 "deltas: actual %d expected %d ba_timeout %d\n",
290 actual_delta, expected_delta, ba_timeout_delta);
291
292#ifdef CONFIG_IWLWIFI_DEBUGFS
293 /*
294 * This is ifdef'ed on DEBUGFS because otherwise the
295 * statistics aren't available. If DEBUGFS is set but
296 * DEBUG is not, these will just compile out.
297 */
298 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
299 priv->delta_stats.tx.rx_detected_cnt);
300 IWL_DEBUG_RADIO(priv,
301 "ack_or_ba_timeout_collision delta %d\n",
302 priv->delta_stats.tx.ack_or_ba_timeout_collision);
303#endif
304
305 if (ba_timeout_delta >= BA_TIMEOUT_MAX)
306 return false;
307 }
308
309 return true;
310}
311
312/** 244/**
313 * iwl_good_plcp_health - checks for plcp error. 245 * iwl_good_plcp_health - checks for plcp error.
314 * 246 *
@@ -347,6 +279,45 @@ static bool iwlagn_good_plcp_health(struct iwl_priv *priv,
347 return true; 279 return true;
348} 280}
349 281
282int iwl_force_rf_reset(struct iwl_priv *priv, bool external)
283{
284 struct iwl_rf_reset *rf_reset;
285
286 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
287 return -EAGAIN;
288
289 if (!iwl_is_any_associated(priv)) {
290 IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
291 return -ENOLINK;
292 }
293
294 rf_reset = &priv->rf_reset;
295 rf_reset->reset_request_count++;
296 if (!external && rf_reset->last_reset_jiffies &&
297 time_after(rf_reset->last_reset_jiffies +
298 IWL_DELAY_NEXT_FORCE_RF_RESET, jiffies)) {
299 IWL_DEBUG_INFO(priv, "RF reset rejected\n");
300 rf_reset->reset_reject_count++;
301 return -EAGAIN;
302 }
303 rf_reset->reset_success_count++;
304 rf_reset->last_reset_jiffies = jiffies;
305
306 /*
307 * There is no easy and better way to force reset the radio,
308 * the only known method is switching channel which will force to
309 * reset and tune the radio.
310 * Use internal short scan (single channel) operation to should
311 * achieve this objective.
312 * Driver should reset the radio when number of consecutive missed
313 * beacon, or any other uCode error condition detected.
314 */
315 IWL_DEBUG_INFO(priv, "perform radio reset.\n");
316 iwl_internal_short_hw_scan(priv);
317 return 0;
318}
319
320
350static void iwlagn_recover_from_statistics(struct iwl_priv *priv, 321static void iwlagn_recover_from_statistics(struct iwl_priv *priv,
351 struct statistics_rx_phy *cur_ofdm, 322 struct statistics_rx_phy *cur_ofdm,
352 struct statistics_rx_ht_phy *cur_ofdm_ht, 323 struct statistics_rx_ht_phy *cur_ofdm_ht,
@@ -368,15 +339,9 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv,
368 if (msecs < 99) 339 if (msecs < 99)
369 return; 340 return;
370 341
371 if (iwlagn_mod_params.ack_check && !iwlagn_good_ack_health(priv, tx)) {
372 IWL_ERR(priv, "low ack count detected, restart firmware\n");
373 if (!iwl_force_reset(priv, IWL_FW_RESET, false))
374 return;
375 }
376
377 if (iwlagn_mod_params.plcp_check && 342 if (iwlagn_mod_params.plcp_check &&
378 !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) 343 !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
379 iwl_force_reset(priv, IWL_RF_RESET, false); 344 iwl_force_rf_reset(priv, false);
380} 345}
381 346
382/* Calculate noise level, based on measurements during network silence just 347/* Calculate noise level, based on measurements during network silence just
@@ -589,8 +554,8 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
589 iwlagn_rx_calc_noise(priv); 554 iwlagn_rx_calc_noise(priv);
590 queue_work(priv->workqueue, &priv->run_time_calib_work); 555 queue_work(priv->workqueue, &priv->run_time_calib_work);
591 } 556 }
592 if (cfg(priv)->lib->temperature && change) 557 if (priv->lib->temperature && change)
593 cfg(priv)->lib->temperature(priv); 558 priv->lib->temperature(priv);
594 559
595 spin_unlock(&priv->statistics.lock); 560 spin_unlock(&priv->statistics.lock);
596 561
@@ -1182,9 +1147,9 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
1182 err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); 1147 err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
1183 } else { 1148 } else {
1184 /* No handling needed */ 1149 /* No handling needed */
1185 IWL_DEBUG_RX(priv, 1150 IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n",
1186 "No handler needed for %s, 0x%02x\n", 1151 iwl_dvm_get_cmd_string(pkt->hdr.cmd),
1187 get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); 1152 pkt->hdr.cmd);
1188 } 1153 }
1189 } 1154 }
1190 return err; 1155 return err;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 79d857d81b41..5c7bddd5cfef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -32,6 +32,78 @@
32#include "iwl-trans.h" 32#include "iwl-trans.h"
33#include "iwl-shared.h" 33#include "iwl-shared.h"
34 34
35/*
36 * initialize rxon structure with default values from eeprom
37 */
38void iwl_connection_init_rx_config(struct iwl_priv *priv,
39 struct iwl_rxon_context *ctx)
40{
41 const struct iwl_channel_info *ch_info;
42
43 memset(&ctx->staging, 0, sizeof(ctx->staging));
44
45 if (!ctx->vif) {
46 ctx->staging.dev_type = ctx->unused_devtype;
47 } else
48 switch (ctx->vif->type) {
49 case NL80211_IFTYPE_AP:
50 ctx->staging.dev_type = ctx->ap_devtype;
51 break;
52
53 case NL80211_IFTYPE_STATION:
54 ctx->staging.dev_type = ctx->station_devtype;
55 ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
56 break;
57
58 case NL80211_IFTYPE_ADHOC:
59 ctx->staging.dev_type = ctx->ibss_devtype;
60 ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
61 ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
62 RXON_FILTER_ACCEPT_GRP_MSK;
63 break;
64
65 default:
66 IWL_ERR(priv, "Unsupported interface type %d\n",
67 ctx->vif->type);
68 break;
69 }
70
71#if 0
72 /* TODO: Figure out when short_preamble would be set and cache from
73 * that */
74 if (!hw_to_local(priv->hw)->short_preamble)
75 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
76 else
77 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
78#endif
79
80 ch_info = iwl_get_channel_info(priv, priv->band,
81 le16_to_cpu(ctx->active.channel));
82
83 if (!ch_info)
84 ch_info = &priv->channel_info[0];
85
86 ctx->staging.channel = cpu_to_le16(ch_info->channel);
87 priv->band = ch_info->band;
88
89 iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);
90
91 ctx->staging.ofdm_basic_rates =
92 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
93 ctx->staging.cck_basic_rates =
94 (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
95
96 /* clear both MIX and PURE40 mode flag */
97 ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
98 RXON_FLG_CHANNEL_MODE_PURE_40);
99 if (ctx->vif)
100 memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
101
102 ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;
103 ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
104 ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff;
105}
106
35static int iwlagn_disable_bss(struct iwl_priv *priv, 107static int iwlagn_disable_bss(struct iwl_priv *priv,
36 struct iwl_rxon_context *ctx, 108 struct iwl_rxon_context *ctx,
37 struct iwl_rxon_cmd *send) 109 struct iwl_rxon_cmd *send)
@@ -105,8 +177,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv,
105 return ret; 177 return ret;
106} 178}
107 179
108static void iwlagn_update_qos(struct iwl_priv *priv, 180void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
109 struct iwl_rxon_context *ctx)
110{ 181{
111 int ret; 182 int ret;
112 183
@@ -133,8 +204,8 @@ static void iwlagn_update_qos(struct iwl_priv *priv,
133 IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n"); 204 IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n");
134} 205}
135 206
136static int iwlagn_update_beacon(struct iwl_priv *priv, 207int iwlagn_update_beacon(struct iwl_priv *priv,
137 struct ieee80211_vif *vif) 208 struct ieee80211_vif *vif)
138{ 209{
139 lockdep_assert_held(&priv->mutex); 210 lockdep_assert_held(&priv->mutex);
140 211
@@ -335,6 +406,64 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv,
335 return 0; 406 return 0;
336} 407}
337 408
409static int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
410{
411 int ret;
412 s8 prev_tx_power;
413 bool defer;
414 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
415
416 if (priv->calib_disabled & IWL_TX_POWER_CALIB_DISABLED)
417 return 0;
418
419 lockdep_assert_held(&priv->mutex);
420
421 if (priv->tx_power_user_lmt == tx_power && !force)
422 return 0;
423
424 if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
425 IWL_WARN(priv,
426 "Requested user TXPOWER %d below lower limit %d.\n",
427 tx_power,
428 IWLAGN_TX_POWER_TARGET_POWER_MIN);
429 return -EINVAL;
430 }
431
432 if (tx_power > priv->tx_power_device_lmt) {
433 IWL_WARN(priv,
434 "Requested user TXPOWER %d above upper limit %d.\n",
435 tx_power, priv->tx_power_device_lmt);
436 return -EINVAL;
437 }
438
439 if (!iwl_is_ready_rf(priv))
440 return -EIO;
441
442 /* scan complete and commit_rxon use tx_power_next value,
443 * it always need to be updated for newest request */
444 priv->tx_power_next = tx_power;
445
446 /* do not set tx power when scanning or channel changing */
447 defer = test_bit(STATUS_SCANNING, &priv->status) ||
448 memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging));
449 if (defer && !force) {
450 IWL_DEBUG_INFO(priv, "Deferring tx power set\n");
451 return 0;
452 }
453
454 prev_tx_power = priv->tx_power_user_lmt;
455 priv->tx_power_user_lmt = tx_power;
456
457 ret = iwlagn_send_tx_power(priv);
458
459 /* if fail to set tx_power, restore the orig. tx power */
460 if (ret) {
461 priv->tx_power_user_lmt = prev_tx_power;
462 priv->tx_power_next = prev_tx_power;
463 }
464 return ret;
465}
466
338static int iwlagn_rxon_connect(struct iwl_priv *priv, 467static int iwlagn_rxon_connect(struct iwl_priv *priv,
339 struct iwl_rxon_context *ctx) 468 struct iwl_rxon_context *ctx)
340{ 469{
@@ -501,6 +630,161 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
501 return ret; 630 return ret;
502} 631}
503 632
633static void _iwl_set_rxon_ht(struct iwl_priv *priv,
634 struct iwl_ht_config *ht_conf,
635 struct iwl_rxon_context *ctx)
636{
637 struct iwl_rxon_cmd *rxon = &ctx->staging;
638
639 if (!ctx->ht.enabled) {
640 rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
641 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
642 RXON_FLG_HT40_PROT_MSK |
643 RXON_FLG_HT_PROT_MSK);
644 return;
645 }
646
647 /* FIXME: if the definition of ht.protection changed, the "translation"
648 * will be needed for rxon->flags
649 */
650 rxon->flags |= cpu_to_le32(ctx->ht.protection <<
651 RXON_FLG_HT_OPERATING_MODE_POS);
652
653 /* Set up channel bandwidth:
654 * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
655 /* clear the HT channel mode before set the mode */
656 rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
657 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
658 if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) {
659 /* pure ht40 */
660 if (ctx->ht.protection ==
661 IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
662 rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
663 /*
664 * Note: control channel is opposite of extension
665 * channel
666 */
667 switch (ctx->ht.extension_chan_offset) {
668 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
669 rxon->flags &=
670 ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
671 break;
672 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
673 rxon->flags |=
674 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
675 break;
676 }
677 } else {
678 /*
679 * Note: control channel is opposite of extension
680 * channel
681 */
682 switch (ctx->ht.extension_chan_offset) {
683 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
684 rxon->flags &=
685 ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
686 rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
687 break;
688 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
689 rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
690 rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
691 break;
692 case IEEE80211_HT_PARAM_CHA_SEC_NONE:
693 default:
694 /*
695 * channel location only valid if in Mixed
696 * mode
697 */
698 IWL_ERR(priv,
699 "invalid extension channel offset\n");
700 break;
701 }
702 }
703 } else {
704 rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY;
705 }
706
707 iwlagn_set_rxon_chain(priv, ctx);
708
709 IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
710 "extension channel offset 0x%x\n",
711 le32_to_cpu(rxon->flags), ctx->ht.protection,
712 ctx->ht.extension_chan_offset);
713}
714
715void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
716{
717 struct iwl_rxon_context *ctx;
718
719 for_each_context(priv, ctx)
720 _iwl_set_rxon_ht(priv, ht_conf, ctx);
721}
722
723/**
724 * iwl_set_rxon_channel - Set the band and channel values in staging RXON
725 * @ch: requested channel as a pointer to struct ieee80211_channel
726
727 * NOTE: Does not commit to the hardware; it sets appropriate bit fields
728 * in the staging RXON flag structure based on the ch->band
729 */
730void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
731 struct iwl_rxon_context *ctx)
732{
733 enum ieee80211_band band = ch->band;
734 u16 channel = ch->hw_value;
735
736 if ((le16_to_cpu(ctx->staging.channel) == channel) &&
737 (priv->band == band))
738 return;
739
740 ctx->staging.channel = cpu_to_le16(channel);
741 if (band == IEEE80211_BAND_5GHZ)
742 ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
743 else
744 ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
745
746 priv->band = band;
747
748 IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
749
750}
751
752void iwl_set_flags_for_band(struct iwl_priv *priv,
753 struct iwl_rxon_context *ctx,
754 enum ieee80211_band band,
755 struct ieee80211_vif *vif)
756{
757 if (band == IEEE80211_BAND_5GHZ) {
758 ctx->staging.flags &=
759 ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
760 | RXON_FLG_CCK_MSK);
761 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
762 } else {
763 /* Copied from iwl_post_associate() */
764 if (vif && vif->bss_conf.use_short_slot)
765 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
766 else
767 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
768
769 ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
770 ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
771 ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
772 }
773}
774
775void iwl_set_rate(struct iwl_priv *priv)
776{
777 struct iwl_rxon_context *ctx;
778
779 for_each_context(priv, ctx) {
780 ctx->staging.cck_basic_rates =
781 (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
782
783 ctx->staging.ofdm_basic_rates =
784 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
785 }
786}
787
504static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, 788static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv,
505 struct iwl_rxon_context *ctx, int hw_decrypt) 789 struct iwl_rxon_context *ctx, int hw_decrypt)
506{ 790{
@@ -594,8 +878,8 @@ static int iwl_check_rxon_cmd(struct iwl_priv *priv,
594 * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that 878 * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
595 * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. 879 * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
596 */ 880 */
597static int iwl_full_rxon_required(struct iwl_priv *priv, 881int iwl_full_rxon_required(struct iwl_priv *priv,
598 struct iwl_rxon_context *ctx) 882 struct iwl_rxon_context *ctx)
599{ 883{
600 const struct iwl_rxon_cmd *staging = &ctx->staging; 884 const struct iwl_rxon_cmd *staging = &ctx->staging;
601 const struct iwl_rxon_cmd *active = &ctx->active; 885 const struct iwl_rxon_cmd *active = &ctx->active;
@@ -649,6 +933,33 @@ static int iwl_full_rxon_required(struct iwl_priv *priv,
649 return 0; 933 return 0;
650} 934}
651 935
936#ifdef CONFIG_IWLWIFI_DEBUG
937void iwl_print_rx_config_cmd(struct iwl_priv *priv,
938 enum iwl_rxon_context_id ctxid)
939{
940 struct iwl_rxon_context *ctx = &priv->contexts[ctxid];
941 struct iwl_rxon_cmd *rxon = &ctx->staging;
942
943 IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
944 iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
945 IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n",
946 le16_to_cpu(rxon->channel));
947 IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n",
948 le32_to_cpu(rxon->flags));
949 IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n",
950 le32_to_cpu(rxon->filter_flags));
951 IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type);
952 IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n",
953 rxon->ofdm_basic_rates);
954 IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n",
955 rxon->cck_basic_rates);
956 IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr);
957 IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
958 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n",
959 le16_to_cpu(rxon->assoc_id));
960}
961#endif
962
652/** 963/**
653 * iwlagn_commit_rxon - commit staging_rxon to hardware 964 * iwlagn_commit_rxon - commit staging_rxon to hardware
654 * 965 *
@@ -692,7 +1003,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
692 * force CTS-to-self frames protection if RTS-CTS is not preferred 1003 * force CTS-to-self frames protection if RTS-CTS is not preferred
693 * one aggregation protection method 1004 * one aggregation protection method
694 */ 1005 */
695 if (!hw_params(priv).use_rts_for_aggregation) 1006 if (!priv->hw_params.use_rts_for_aggregation)
696 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; 1007 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
697 1008
698 if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || 1009 if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
@@ -911,9 +1222,9 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
911 return ret; 1222 return ret;
912} 1223}
913 1224
914static void iwlagn_check_needed_chains(struct iwl_priv *priv, 1225void iwlagn_check_needed_chains(struct iwl_priv *priv,
915 struct iwl_rxon_context *ctx, 1226 struct iwl_rxon_context *ctx,
916 struct ieee80211_bss_conf *bss_conf) 1227 struct ieee80211_bss_conf *bss_conf)
917{ 1228{
918 struct ieee80211_vif *vif = ctx->vif; 1229 struct ieee80211_vif *vif = ctx->vif;
919 struct iwl_rxon_context *tmp; 1230 struct iwl_rxon_context *tmp;
@@ -1005,11 +1316,14 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv,
1005 ht_conf->single_chain_sufficient = !need_multiple; 1316 ht_conf->single_chain_sufficient = !need_multiple;
1006} 1317}
1007 1318
1008static void iwlagn_chain_noise_reset(struct iwl_priv *priv) 1319void iwlagn_chain_noise_reset(struct iwl_priv *priv)
1009{ 1320{
1010 struct iwl_chain_noise_data *data = &priv->chain_noise_data; 1321 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
1011 int ret; 1322 int ret;
1012 1323
1324 if (!(priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED))
1325 return;
1326
1013 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && 1327 if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
1014 iwl_is_any_associated(priv)) { 1328 iwl_is_any_associated(priv)) {
1015 struct iwl_calib_chain_noise_reset_cmd cmd; 1329 struct iwl_calib_chain_noise_reset_cmd cmd;
@@ -1162,8 +1476,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
1162 iwl_power_update_mode(priv, false); 1476 iwl_power_update_mode(priv, false);
1163 1477
1164 /* Enable RX differential gain and sensitivity calibrations */ 1478 /* Enable RX differential gain and sensitivity calibrations */
1165 if (!priv->disable_chain_noise_cal) 1479 iwlagn_chain_noise_reset(priv);
1166 iwlagn_chain_noise_reset(priv);
1167 priv->start_calib = 1; 1480 priv->start_calib = 1;
1168 } 1481 }
1169 1482
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index c4175603864b..0119e7a7b78d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -34,6 +34,8 @@
34#include "iwl-agn.h" 34#include "iwl-agn.h"
35#include "iwl-trans.h" 35#include "iwl-trans.h"
36 36
37const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
38
37static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) 39static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
38{ 40{
39 lockdep_assert_held(&priv->sta_lock); 41 lockdep_assert_held(&priv->sta_lock);
@@ -170,6 +172,50 @@ int iwl_send_add_sta(struct iwl_priv *priv,
170 return cmd.handler_status; 172 return cmd.handler_status;
171} 173}
172 174
175static bool iwl_is_channel_extension(struct iwl_priv *priv,
176 enum ieee80211_band band,
177 u16 channel, u8 extension_chan_offset)
178{
179 const struct iwl_channel_info *ch_info;
180
181 ch_info = iwl_get_channel_info(priv, band, channel);
182 if (!is_channel_valid(ch_info))
183 return false;
184
185 if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
186 return !(ch_info->ht40_extension_channel &
187 IEEE80211_CHAN_NO_HT40PLUS);
188 else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW)
189 return !(ch_info->ht40_extension_channel &
190 IEEE80211_CHAN_NO_HT40MINUS);
191
192 return false;
193}
194
195bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
196 struct iwl_rxon_context *ctx,
197 struct ieee80211_sta_ht_cap *ht_cap)
198{
199 if (!ctx->ht.enabled || !ctx->ht.is_40mhz)
200 return false;
201
202 /*
203 * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
204 * the bit will not set if it is pure 40MHz case
205 */
206 if (ht_cap && !ht_cap->ht_supported)
207 return false;
208
209#ifdef CONFIG_IWLWIFI_DEBUGFS
210 if (priv->disable_ht40)
211 return false;
212#endif
213
214 return iwl_is_channel_extension(priv, priv->band,
215 le16_to_cpu(ctx->staging.channel),
216 ctx->ht.extension_chan_offset);
217}
218
173static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, 219static void iwl_sta_calc_ht_flags(struct iwl_priv *priv,
174 struct ieee80211_sta *sta, 220 struct ieee80211_sta *sta,
175 struct iwl_rxon_context *ctx, 221 struct iwl_rxon_context *ctx,
@@ -581,6 +627,56 @@ void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
581 spin_unlock_bh(&priv->sta_lock); 627 spin_unlock_bh(&priv->sta_lock);
582} 628}
583 629
630static void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
631 u8 sta_id, struct iwl_link_quality_cmd *link_cmd)
632{
633 int i, r;
634 u32 rate_flags = 0;
635 __le32 rate_n_flags;
636
637 lockdep_assert_held(&priv->mutex);
638
639 memset(link_cmd, 0, sizeof(*link_cmd));
640
641 /* Set up the rate scaling to start at selected rate, fall back
642 * all the way down to 1M in IEEE order, and then spin on 1M */
643 if (priv->band == IEEE80211_BAND_5GHZ)
644 r = IWL_RATE_6M_INDEX;
645 else if (ctx && ctx->vif && ctx->vif->p2p)
646 r = IWL_RATE_6M_INDEX;
647 else
648 r = IWL_RATE_1M_INDEX;
649
650 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
651 rate_flags |= RATE_MCS_CCK_MSK;
652
653 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
654 RATE_MCS_ANT_POS;
655 rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
656 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
657 link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
658
659 link_cmd->general_params.single_stream_ant_msk =
660 first_antenna(priv->hw_params.valid_tx_ant);
661
662 link_cmd->general_params.dual_stream_ant_msk =
663 priv->hw_params.valid_tx_ant &
664 ~first_antenna(priv->hw_params.valid_tx_ant);
665 if (!link_cmd->general_params.dual_stream_ant_msk) {
666 link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
667 } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
668 link_cmd->general_params.dual_stream_ant_msk =
669 priv->hw_params.valid_tx_ant;
670 }
671
672 link_cmd->agg_params.agg_dis_start_th =
673 LINK_QUAL_AGG_DISABLE_START_DEF;
674 link_cmd->agg_params.agg_time_limit =
675 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
676
677 link_cmd->sta_id = sta_id;
678}
679
584/** 680/**
585 * iwl_clear_ucode_stations - clear ucode station table bits 681 * iwl_clear_ucode_stations - clear ucode station table bits
586 * 682 *
@@ -841,56 +937,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
841} 937}
842 938
843 939
844void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
845 u8 sta_id, struct iwl_link_quality_cmd *link_cmd)
846{
847 int i, r;
848 u32 rate_flags = 0;
849 __le32 rate_n_flags;
850
851 lockdep_assert_held(&priv->mutex);
852
853 memset(link_cmd, 0, sizeof(*link_cmd));
854
855 /* Set up the rate scaling to start at selected rate, fall back
856 * all the way down to 1M in IEEE order, and then spin on 1M */
857 if (priv->band == IEEE80211_BAND_5GHZ)
858 r = IWL_RATE_6M_INDEX;
859 else if (ctx && ctx->vif && ctx->vif->p2p)
860 r = IWL_RATE_6M_INDEX;
861 else
862 r = IWL_RATE_1M_INDEX;
863
864 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
865 rate_flags |= RATE_MCS_CCK_MSK;
866
867 rate_flags |= first_antenna(hw_params(priv).valid_tx_ant) <<
868 RATE_MCS_ANT_POS;
869 rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
870 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
871 link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
872
873 link_cmd->general_params.single_stream_ant_msk =
874 first_antenna(hw_params(priv).valid_tx_ant);
875
876 link_cmd->general_params.dual_stream_ant_msk =
877 hw_params(priv).valid_tx_ant &
878 ~first_antenna(hw_params(priv).valid_tx_ant);
879 if (!link_cmd->general_params.dual_stream_ant_msk) {
880 link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
881 } else if (num_of_ant(hw_params(priv).valid_tx_ant) == 2) {
882 link_cmd->general_params.dual_stream_ant_msk =
883 hw_params(priv).valid_tx_ant;
884 }
885
886 link_cmd->agg_params.agg_dis_start_th =
887 LINK_QUAL_AGG_DISABLE_START_DEF;
888 link_cmd->agg_params.agg_time_limit =
889 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
890
891 link_cmd->sta_id = sta_id;
892}
893
894static struct iwl_link_quality_cmd * 940static struct iwl_link_quality_cmd *
895iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 941iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
896 u8 sta_id) 942 u8 sta_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 697f2032bfd6..ad21b5ddf59d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -208,10 +208,10 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
208 priv->bt_full_concurrent) { 208 priv->bt_full_concurrent) {
209 /* operated as 1x1 in full concurrency mode */ 209 /* operated as 1x1 in full concurrency mode */
210 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, 210 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
211 first_antenna(hw_params(priv).valid_tx_ant)); 211 first_antenna(priv->hw_params.valid_tx_ant));
212 } else 212 } else
213 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, 213 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
214 hw_params(priv).valid_tx_ant); 214 priv->hw_params.valid_tx_ant);
215 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); 215 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
216 216
217 /* Set the rate in the TX cmd */ 217 /* Set the rate in the TX cmd */
@@ -689,7 +689,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
689 sta_priv->max_agg_bufsize = 689 sta_priv->max_agg_bufsize =
690 min(sta_priv->max_agg_bufsize, buf_size); 690 min(sta_priv->max_agg_bufsize, buf_size);
691 691
692 if (hw_params(priv).use_rts_for_aggregation) { 692 if (priv->hw_params.use_rts_for_aggregation) {
693 /* 693 /*
694 * switch to RTS/CTS if it is the prefer protection 694 * switch to RTS/CTS if it is the prefer protection
695 * method for HT traffic 695 * method for HT traffic
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 22c953d65be5..7db39866bdc4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -180,7 +180,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
180 rate = info->control.rates[0].idx; 180 rate = info->control.rates[0].idx;
181 181
182 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, 182 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
183 hw_params(priv).valid_tx_ant); 183 priv->hw_params.valid_tx_ant);
184 rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); 184 rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
185 185
186 /* In mac80211, rates for 5 GHz start at 0 */ 186 /* In mac80211, rates for 5 GHz start at 0 */
@@ -289,6 +289,25 @@ out:
289 mutex_unlock(&priv->mutex); 289 mutex_unlock(&priv->mutex);
290} 290}
291 291
292int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
293{
294 struct iwl_statistics_cmd statistics_cmd = {
295 .configuration_flags =
296 clear ? IWL_STATS_CONF_CLEAR_STATS : 0,
297 };
298
299 if (flags & CMD_ASYNC)
300 return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
301 CMD_ASYNC,
302 sizeof(struct iwl_statistics_cmd),
303 &statistics_cmd);
304 else
305 return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
306 CMD_SYNC,
307 sizeof(struct iwl_statistics_cmd),
308 &statistics_cmd);
309}
310
292/** 311/**
293 * iwl_bg_statistics_periodic - Timer callback to queue statistics 312 * iwl_bg_statistics_periodic - Timer callback to queue statistics
294 * 313 *
@@ -578,7 +597,7 @@ static const u8 iwlagn_pan_queue_to_ac[] = {
578 IEEE80211_AC_VO, 597 IEEE80211_AC_VO,
579}; 598};
580 599
581static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) 600void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
582{ 601{
583 int i; 602 int i;
584 603
@@ -645,7 +664,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
645 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); 664 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
646} 665}
647 666
648static void iwl_rf_kill_ct_config(struct iwl_priv *priv) 667void iwl_rf_kill_ct_config(struct iwl_priv *priv)
649{ 668{
650 struct iwl_ct_kill_config cmd; 669 struct iwl_ct_kill_config cmd;
651 struct iwl_ct_kill_throttling_config adv_cmd; 670 struct iwl_ct_kill_throttling_config adv_cmd;
@@ -658,9 +677,9 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
658 677
659 if (cfg(priv)->base_params->support_ct_kill_exit) { 678 if (cfg(priv)->base_params->support_ct_kill_exit) {
660 adv_cmd.critical_temperature_enter = 679 adv_cmd.critical_temperature_enter =
661 cpu_to_le32(hw_params(priv).ct_kill_threshold); 680 cpu_to_le32(priv->hw_params.ct_kill_threshold);
662 adv_cmd.critical_temperature_exit = 681 adv_cmd.critical_temperature_exit =
663 cpu_to_le32(hw_params(priv).ct_kill_exit_threshold); 682 cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
664 683
665 ret = iwl_dvm_send_cmd_pdu(priv, 684 ret = iwl_dvm_send_cmd_pdu(priv,
666 REPLY_CT_KILL_CONFIG_CMD, 685 REPLY_CT_KILL_CONFIG_CMD,
@@ -671,11 +690,11 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
671 IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " 690 IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
672 "succeeded, critical temperature enter is %d," 691 "succeeded, critical temperature enter is %d,"
673 "exit is %d\n", 692 "exit is %d\n",
674 hw_params(priv).ct_kill_threshold, 693 priv->hw_params.ct_kill_threshold,
675 hw_params(priv).ct_kill_exit_threshold); 694 priv->hw_params.ct_kill_exit_threshold);
676 } else { 695 } else {
677 cmd.critical_temperature_R = 696 cmd.critical_temperature_R =
678 cpu_to_le32(hw_params(priv).ct_kill_threshold); 697 cpu_to_le32(priv->hw_params.ct_kill_threshold);
679 698
680 ret = iwl_dvm_send_cmd_pdu(priv, 699 ret = iwl_dvm_send_cmd_pdu(priv,
681 REPLY_CT_KILL_CONFIG_CMD, 700 REPLY_CT_KILL_CONFIG_CMD,
@@ -686,7 +705,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
686 IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " 705 IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
687 "succeeded, " 706 "succeeded, "
688 "critical temperature is %d\n", 707 "critical temperature is %d\n",
689 hw_params(priv).ct_kill_threshold); 708 priv->hw_params.ct_kill_threshold);
690 } 709 }
691} 710}
692 711
@@ -726,6 +745,29 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
726 } 745 }
727} 746}
728 747
748void iwl_send_bt_config(struct iwl_priv *priv)
749{
750 struct iwl_bt_cmd bt_cmd = {
751 .lead_time = BT_LEAD_TIME_DEF,
752 .max_kill = BT_MAX_KILL_DEF,
753 .kill_ack_mask = 0,
754 .kill_cts_mask = 0,
755 };
756
757 if (!iwlagn_mod_params.bt_coex_active)
758 bt_cmd.flags = BT_COEX_DISABLE;
759 else
760 bt_cmd.flags = BT_COEX_ENABLE;
761
762 priv->bt_enable_flag = bt_cmd.flags;
763 IWL_DEBUG_INFO(priv, "BT coex %s\n",
764 (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
765
766 if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
767 CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd))
768 IWL_ERR(priv, "failed to send BT Coex Config\n");
769}
770
729/** 771/**
730 * iwl_alive_start - called after REPLY_ALIVE notification received 772 * iwl_alive_start - called after REPLY_ALIVE notification received
731 * from protocol/runtime uCode (initialization uCode's 773 * from protocol/runtime uCode (initialization uCode's
@@ -741,9 +783,6 @@ int iwl_alive_start(struct iwl_priv *priv)
741 /* After the ALIVE response, we can send host commands to the uCode */ 783 /* After the ALIVE response, we can send host commands to the uCode */
742 set_bit(STATUS_ALIVE, &priv->status); 784 set_bit(STATUS_ALIVE, &priv->status);
743 785
744 /* Enable watchdog to monitor the driver tx queues */
745 iwl_setup_watchdog(priv);
746
747 if (iwl_is_rfkill(priv)) 786 if (iwl_is_rfkill(priv))
748 return -ERFKILL; 787 return -ERFKILL;
749 788
@@ -793,10 +832,8 @@ int iwl_alive_start(struct iwl_priv *priv)
793 832
794 ieee80211_wake_queues(priv->hw); 833 ieee80211_wake_queues(priv->hw);
795 834
796 priv->active_rate = IWL_RATES_MASK;
797
798 /* Configure Tx antenna selection based on H/W config */ 835 /* Configure Tx antenna selection based on H/W config */
799 iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant); 836 iwlagn_send_tx_ant_config(priv, priv->hw_params.valid_tx_ant);
800 837
801 if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { 838 if (iwl_is_associated_ctx(ctx) && !priv->wowlan) {
802 struct iwl_rxon_cmd *active_rxon = 839 struct iwl_rxon_cmd *active_rxon =
@@ -887,10 +924,6 @@ void iwl_down(struct iwl_priv *priv)
887 exit_pending = 924 exit_pending =
888 test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); 925 test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
889 926
890 /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
891 * to prevent rearm timer */
892 del_timer_sync(&priv->watchdog);
893
894 iwl_clear_ucode_stations(priv, NULL); 927 iwl_clear_ucode_stations(priv, NULL);
895 iwl_dealloc_bcast_stations(priv); 928 iwl_dealloc_bcast_stations(priv);
896 iwl_clear_driver_stations(priv); 929 iwl_clear_driver_stations(priv);
@@ -1067,7 +1100,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work)
1067 * 1100 *
1068 *****************************************************************************/ 1101 *****************************************************************************/
1069 1102
1070static void iwl_setup_deferred_work(struct iwl_priv *priv) 1103void iwl_setup_deferred_work(struct iwl_priv *priv)
1071{ 1104{
1072 priv->workqueue = create_singlethread_workqueue(DRV_NAME); 1105 priv->workqueue = create_singlethread_workqueue(DRV_NAME);
1073 1106
@@ -1092,10 +1125,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
1092 init_timer(&priv->ucode_trace); 1125 init_timer(&priv->ucode_trace);
1093 priv->ucode_trace.data = (unsigned long)priv; 1126 priv->ucode_trace.data = (unsigned long)priv;
1094 priv->ucode_trace.function = iwl_bg_ucode_trace; 1127 priv->ucode_trace.function = iwl_bg_ucode_trace;
1095
1096 init_timer(&priv->watchdog);
1097 priv->watchdog.data = (unsigned long)priv;
1098 priv->watchdog.function = iwl_bg_watchdog;
1099} 1128}
1100 1129
1101void iwl_cancel_deferred_work(struct iwl_priv *priv) 1130void iwl_cancel_deferred_work(struct iwl_priv *priv)
@@ -1143,8 +1172,8 @@ static void iwl_init_ht_hw_capab(const struct iwl_priv *priv,
1143 enum ieee80211_band band) 1172 enum ieee80211_band band)
1144{ 1173{
1145 u16 max_bit_rate = 0; 1174 u16 max_bit_rate = 0;
1146 u8 rx_chains_num = hw_params(priv).rx_chains_num; 1175 u8 rx_chains_num = priv->hw_params.rx_chains_num;
1147 u8 tx_chains_num = hw_params(priv).tx_chains_num; 1176 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1148 1177
1149 ht_info->cap = 0; 1178 ht_info->cap = 0;
1150 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); 1179 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
@@ -1156,7 +1185,7 @@ static void iwl_init_ht_hw_capab(const struct iwl_priv *priv,
1156 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; 1185 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
1157 ht_info->cap |= IEEE80211_HT_CAP_SGI_20; 1186 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
1158 max_bit_rate = MAX_BIT_RATE_20_MHZ; 1187 max_bit_rate = MAX_BIT_RATE_20_MHZ;
1159 if (hw_params(priv).ht40_channel & BIT(band)) { 1188 if (priv->hw_params.ht40_channel & BIT(band)) {
1160 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 1189 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1161 ht_info->cap |= IEEE80211_HT_CAP_SGI_40; 1190 ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
1162 ht_info->mcs.rx_mask[4] = 0x01; 1191 ht_info->mcs.rx_mask[4] = 0x01;
@@ -1228,7 +1257,7 @@ static int iwl_init_geos(struct iwl_priv *priv)
1228 sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; 1257 sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
1229 sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; 1258 sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE;
1230 1259
1231 if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) 1260 if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)
1232 iwl_init_ht_hw_capab(priv, &sband->ht_cap, 1261 iwl_init_ht_hw_capab(priv, &sband->ht_cap,
1233 IEEE80211_BAND_5GHZ); 1262 IEEE80211_BAND_5GHZ);
1234 1263
@@ -1238,7 +1267,7 @@ static int iwl_init_geos(struct iwl_priv *priv)
1238 sband->bitrates = rates; 1267 sband->bitrates = rates;
1239 sband->n_bitrates = IWL_RATE_COUNT_LEGACY; 1268 sband->n_bitrates = IWL_RATE_COUNT_LEGACY;
1240 1269
1241 if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) 1270 if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)
1242 iwl_init_ht_hw_capab(priv, &sband->ht_cap, 1271 iwl_init_ht_hw_capab(priv, &sband->ht_cap,
1243 IEEE80211_BAND_2GHZ); 1272 IEEE80211_BAND_2GHZ);
1244 1273
@@ -1293,11 +1322,11 @@ static int iwl_init_geos(struct iwl_priv *priv)
1293 priv->tx_power_next = max_tx_power; 1322 priv->tx_power_next = max_tx_power;
1294 1323
1295 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && 1324 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
1296 hw_params(priv).sku & EEPROM_SKU_CAP_BAND_52GHZ) { 1325 priv->hw_params.sku & EEPROM_SKU_CAP_BAND_52GHZ) {
1297 IWL_INFO(priv, "Incorrectly detected BG card as ABG. " 1326 IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
1298 "Please send your %s to maintainer.\n", 1327 "Please send your %s to maintainer.\n",
1299 trans(priv)->hw_id_str); 1328 trans(priv)->hw_id_str);
1300 hw_params(priv).sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; 1329 priv->hw_params.sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
1301 } 1330 }
1302 1331
1303 IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", 1332 IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
@@ -1319,7 +1348,7 @@ static void iwl_free_geos(struct iwl_priv *priv)
1319 clear_bit(STATUS_GEO_CONFIGURED, &priv->status); 1348 clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
1320} 1349}
1321 1350
1322static int iwl_init_drv(struct iwl_priv *priv) 1351int iwl_init_drv(struct iwl_priv *priv)
1323{ 1352{
1324 int ret; 1353 int ret;
1325 1354
@@ -1343,12 +1372,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
1343 1372
1344 priv->ucode_owner = IWL_OWNERSHIP_DRIVER; 1373 priv->ucode_owner = IWL_OWNERSHIP_DRIVER;
1345 1374
1346 /* initialize force reset */
1347 priv->force_reset[IWL_RF_RESET].reset_duration =
1348 IWL_DELAY_NEXT_FORCE_RF_RESET;
1349 priv->force_reset[IWL_FW_RESET].reset_duration =
1350 IWL_DELAY_NEXT_FORCE_FW_RELOAD;
1351
1352 priv->rx_statistics_jiffies = jiffies; 1375 priv->rx_statistics_jiffies = jiffies;
1353 1376
1354 /* Choose which receivers/antennas to use */ 1377 /* Choose which receivers/antennas to use */
@@ -1388,7 +1411,7 @@ err:
1388 return ret; 1411 return ret;
1389} 1412}
1390 1413
1391static void iwl_uninit_drv(struct iwl_priv *priv) 1414void iwl_uninit_drv(struct iwl_priv *priv)
1392{ 1415{
1393 iwl_free_geos(priv); 1416 iwl_free_geos(priv);
1394 iwl_free_channel_map(priv); 1417 iwl_free_channel_map(priv);
@@ -1401,35 +1424,22 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
1401#endif 1424#endif
1402} 1425}
1403 1426
1404/* Size of one Rx buffer in host DRAM */ 1427void iwl_set_hw_params(struct iwl_priv *priv)
1405#define IWL_RX_BUF_SIZE_4K (4 * 1024)
1406#define IWL_RX_BUF_SIZE_8K (8 * 1024)
1407
1408static void iwl_set_hw_params(struct iwl_priv *priv)
1409{ 1428{
1410 if (cfg(priv)->ht_params) 1429 if (cfg(priv)->ht_params)
1411 hw_params(priv).use_rts_for_aggregation = 1430 priv->hw_params.use_rts_for_aggregation =
1412 cfg(priv)->ht_params->use_rts_for_aggregation; 1431 cfg(priv)->ht_params->use_rts_for_aggregation;
1413 1432
1414 if (iwlagn_mod_params.amsdu_size_8K)
1415 hw_params(priv).rx_page_order =
1416 get_order(IWL_RX_BUF_SIZE_8K);
1417 else
1418 hw_params(priv).rx_page_order =
1419 get_order(IWL_RX_BUF_SIZE_4K);
1420
1421 if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) 1433 if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
1422 hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE; 1434 priv->hw_params.sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
1423
1424 hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout;
1425 1435
1426 /* Device-specific setup */ 1436 /* Device-specific setup */
1427 cfg(priv)->lib->set_hw_params(priv); 1437 priv->lib->set_hw_params(priv);
1428} 1438}
1429 1439
1430 1440
1431 1441
1432static void iwl_debug_config(struct iwl_priv *priv) 1442void iwl_debug_config(struct iwl_priv *priv)
1433{ 1443{
1434 dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG " 1444 dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG "
1435#ifdef CONFIG_IWLWIFI_DEBUG 1445#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1501,6 +1511,42 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1501 priv->shrd = trans->shrd; 1511 priv->shrd = trans->shrd;
1502 priv->fw = fw; 1512 priv->fw = fw;
1503 1513
1514 switch (cfg(priv)->device_family) {
1515 case IWL_DEVICE_FAMILY_1000:
1516 case IWL_DEVICE_FAMILY_100:
1517 priv->lib = &iwl1000_lib;
1518 break;
1519 case IWL_DEVICE_FAMILY_2000:
1520 case IWL_DEVICE_FAMILY_105:
1521 priv->lib = &iwl2000_lib;
1522 break;
1523 case IWL_DEVICE_FAMILY_2030:
1524 case IWL_DEVICE_FAMILY_135:
1525 priv->lib = &iwl2030_lib;
1526 break;
1527 case IWL_DEVICE_FAMILY_5000:
1528 priv->lib = &iwl5000_lib;
1529 break;
1530 case IWL_DEVICE_FAMILY_5150:
1531 priv->lib = &iwl5150_lib;
1532 break;
1533 case IWL_DEVICE_FAMILY_6000:
1534 case IWL_DEVICE_FAMILY_6005:
1535 case IWL_DEVICE_FAMILY_6000i:
1536 case IWL_DEVICE_FAMILY_6050:
1537 case IWL_DEVICE_FAMILY_6150:
1538 priv->lib = &iwl6000_lib;
1539 break;
1540 case IWL_DEVICE_FAMILY_6030:
1541 priv->lib = &iwl6030_lib;
1542 break;
1543 default:
1544 break;
1545 }
1546
1547 if (WARN_ON(!priv->lib))
1548 goto out_free_traffic_mem;
1549
1504 /* 1550 /*
1505 * Populate the state variables that the transport layer needs 1551 * Populate the state variables that the transport layer needs
1506 * to know about. 1552 * to know about.
@@ -1508,11 +1554,18 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1508 trans_cfg.op_mode = op_mode; 1554 trans_cfg.op_mode = op_mode;
1509 trans_cfg.no_reclaim_cmds = no_reclaim_cmds; 1555 trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
1510 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); 1556 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
1557 trans_cfg.rx_buf_size_8k = iwlagn_mod_params.amsdu_size_8K;
1558 if (!iwlagn_mod_params.wd_disable)
1559 trans_cfg.queue_watchdog_timeout =
1560 cfg(priv)->base_params->wd_timeout;
1561 else
1562 trans_cfg.queue_watchdog_timeout = IWL_WATCHHDOG_DISABLED;
1563 trans_cfg.command_names = iwl_dvm_cmd_strings;
1511 1564
1512 ucode_flags = fw->ucode_capa.flags; 1565 ucode_flags = fw->ucode_capa.flags;
1513 1566
1514#ifndef CONFIG_IWLWIFI_P2P 1567#ifndef CONFIG_IWLWIFI_P2P
1515 ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; 1568 ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
1516#endif 1569#endif
1517 1570
1518 if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { 1571 if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) {
@@ -1574,11 +1627,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1574 if (iwl_trans_start_hw(trans(priv))) 1627 if (iwl_trans_start_hw(trans(priv)))
1575 goto out_free_traffic_mem; 1628 goto out_free_traffic_mem;
1576 1629
1577 /*****************
1578 * 3. Read EEPROM
1579 *****************/
1580 /* Read the EEPROM */ 1630 /* Read the EEPROM */
1581 if (iwl_eeprom_init(trans(priv), trans(priv)->hw_rev)) { 1631 if (iwl_eeprom_init(priv, trans(priv)->hw_rev)) {
1582 IWL_ERR(priv, "Unable to init EEPROM\n"); 1632 IWL_ERR(priv, "Unable to init EEPROM\n");
1583 goto out_free_traffic_mem; 1633 goto out_free_traffic_mem;
1584 } 1634 }
@@ -1592,11 +1642,11 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1592 goto out_free_eeprom; 1642 goto out_free_eeprom;
1593 1643
1594 /* extract MAC Address */ 1644 /* extract MAC Address */
1595 iwl_eeprom_get_mac(priv->shrd, priv->addresses[0].addr); 1645 iwl_eeprom_get_mac(priv, priv->addresses[0].addr);
1596 IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); 1646 IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
1597 priv->hw->wiphy->addresses = priv->addresses; 1647 priv->hw->wiphy->addresses = priv->addresses;
1598 priv->hw->wiphy->n_addresses = 1; 1648 priv->hw->wiphy->n_addresses = 1;
1599 num_mac = iwl_eeprom_query16(priv->shrd, EEPROM_NUM_MAC_ADDRESS); 1649 num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS);
1600 if (num_mac > 1) { 1650 if (num_mac > 1) {
1601 memcpy(priv->addresses[1].addr, priv->addresses[0].addr, 1651 memcpy(priv->addresses[1].addr, priv->addresses[0].addr,
1602 ETH_ALEN); 1652 ETH_ALEN);
@@ -1609,7 +1659,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1609 ************************/ 1659 ************************/
1610 iwl_set_hw_params(priv); 1660 iwl_set_hw_params(priv);
1611 1661
1612 if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) { 1662 if (!(priv->hw_params.sku & EEPROM_SKU_CAP_IPAN_ENABLE)) {
1613 IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN"); 1663 IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN");
1614 ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; 1664 ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
1615 /* 1665 /*
@@ -1694,7 +1744,7 @@ out_destroy_workqueue:
1694 priv->workqueue = NULL; 1744 priv->workqueue = NULL;
1695 iwl_uninit_drv(priv); 1745 iwl_uninit_drv(priv);
1696out_free_eeprom: 1746out_free_eeprom:
1697 iwl_eeprom_free(priv->shrd); 1747 iwl_eeprom_free(priv);
1698out_free_traffic_mem: 1748out_free_traffic_mem:
1699 iwl_free_traffic_mem(priv); 1749 iwl_free_traffic_mem(priv);
1700 ieee80211_free_hw(priv->hw); 1750 ieee80211_free_hw(priv->hw);
@@ -1703,7 +1753,7 @@ out:
1703 return op_mode; 1753 return op_mode;
1704} 1754}
1705 1755
1706static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) 1756void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
1707{ 1757{
1708 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); 1758 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
1709 1759
@@ -1720,7 +1770,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
1720 priv->ucode_loaded = false; 1770 priv->ucode_loaded = false;
1721 iwl_trans_stop_device(trans(priv)); 1771 iwl_trans_stop_device(trans(priv));
1722 1772
1723 iwl_eeprom_free(priv->shrd); 1773 iwl_eeprom_free(priv);
1724 1774
1725 /*netif_stop_queue(dev); */ 1775 /*netif_stop_queue(dev); */
1726 flush_workqueue(priv->workqueue); 1776 flush_workqueue(priv->workqueue);
@@ -1838,7 +1888,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
1838 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { 1888 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
1839 IWL_ERR(trans, "Start IWL Error Log Dump:\n"); 1889 IWL_ERR(trans, "Start IWL Error Log Dump:\n");
1840 IWL_ERR(trans, "Status: 0x%08lX, count: %d\n", 1890 IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
1841 priv->shrd->status, table.valid); 1891 priv->status, table.valid);
1842 } 1892 }
1843 1893
1844 trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, 1894 trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
@@ -2112,7 +2162,63 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2112 return pos; 2162 return pos;
2113} 2163}
2114 2164
2115static void iwl_nic_error(struct iwl_op_mode *op_mode) 2165static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
2166{
2167 unsigned int reload_msec;
2168 unsigned long reload_jiffies;
2169
2170#ifdef CONFIG_IWLWIFI_DEBUG
2171 if (iwl_have_debug_level(IWL_DL_FW_ERRORS))
2172 iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
2173#endif
2174
2175 /* uCode is no longer loaded. */
2176 priv->ucode_loaded = false;
2177
2178 /* Set the FW error flag -- cleared on iwl_down */
2179 set_bit(STATUS_FW_ERROR, &priv->status);
2180
2181 iwl_abort_notification_waits(&priv->notif_wait);
2182
2183 /* Keep the restart process from trying to send host
2184 * commands by clearing the ready bit */
2185 clear_bit(STATUS_READY, &priv->status);
2186
2187 wake_up(&trans(priv)->wait_command_queue);
2188
2189 if (!ondemand) {
2190 /*
2191 * If firmware keep reloading, then it indicate something
2192 * serious wrong and firmware having problem to recover
2193 * from it. Instead of keep trying which will fill the syslog
2194 * and hang the system, let's just stop it
2195 */
2196 reload_jiffies = jiffies;
2197 reload_msec = jiffies_to_msecs((long) reload_jiffies -
2198 (long) priv->reload_jiffies);
2199 priv->reload_jiffies = reload_jiffies;
2200 if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
2201 priv->reload_count++;
2202 if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
2203 IWL_ERR(priv, "BUG_ON, Stop restarting\n");
2204 return;
2205 }
2206 } else
2207 priv->reload_count = 0;
2208 }
2209
2210 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
2211 if (iwlagn_mod_params.restart_fw) {
2212 IWL_DEBUG_FW_ERRORS(priv,
2213 "Restarting adapter due to uCode error.\n");
2214 queue_work(priv->workqueue, &priv->restart);
2215 } else
2216 IWL_DEBUG_FW_ERRORS(priv,
2217 "Detected FW error, but not restarting\n");
2218 }
2219}
2220
2221void iwl_nic_error(struct iwl_op_mode *op_mode)
2116{ 2222{
2117 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); 2223 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2118 2224
@@ -2125,7 +2231,7 @@ static void iwl_nic_error(struct iwl_op_mode *op_mode)
2125 iwlagn_fw_error(priv, false); 2231 iwlagn_fw_error(priv, false);
2126} 2232}
2127 2233
2128static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) 2234void iwl_cmd_queue_full(struct iwl_op_mode *op_mode)
2129{ 2235{
2130 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); 2236 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2131 2237
@@ -2135,14 +2241,22 @@ static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode)
2135 } 2241 }
2136} 2242}
2137 2243
2138static void iwl_nic_config(struct iwl_op_mode *op_mode) 2244void iwl_nic_config(struct iwl_op_mode *op_mode)
2139{ 2245{
2140 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); 2246 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2141 2247
2142 cfg(priv)->lib->nic_config(priv); 2248 priv->lib->nic_config(priv);
2143} 2249}
2144 2250
2145static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) 2251static void iwl_wimax_active(struct iwl_op_mode *op_mode)
2252{
2253 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2254
2255 clear_bit(STATUS_READY, &priv->status);
2256 IWL_ERR(priv, "RF is used by WiMAX\n");
2257}
2258
2259void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
2146{ 2260{
2147 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); 2261 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2148 int ac = priv->queue_to_ac[queue]; 2262 int ac = priv->queue_to_ac[queue];
@@ -2161,7 +2275,7 @@ static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
2161 ieee80211_stop_queue(priv->hw, ac); 2275 ieee80211_stop_queue(priv->hw, ac);
2162} 2276}
2163 2277
2164static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) 2278void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
2165{ 2279{
2166 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); 2280 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2167 int ac = priv->queue_to_ac[queue]; 2281 int ac = priv->queue_to_ac[queue];
@@ -2201,6 +2315,27 @@ void iwlagn_lift_passive_no_rx(struct iwl_priv *priv)
2201 priv->passive_no_rx = false; 2315 priv->passive_no_rx = false;
2202} 2316}
2203 2317
2318void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
2319{
2320 struct ieee80211_tx_info *info;
2321
2322 info = IEEE80211_SKB_CB(skb);
2323 kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1]));
2324 dev_kfree_skb_any(skb);
2325}
2326
2327void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
2328{
2329 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2330
2331 if (state)
2332 set_bit(STATUS_RF_KILL_HW, &priv->status);
2333 else
2334 clear_bit(STATUS_RF_KILL_HW, &priv->status);
2335
2336 wiphy_rfkill_set_hw_state(priv->hw->wiphy, state);
2337}
2338
2204const struct iwl_op_mode_ops iwl_dvm_ops = { 2339const struct iwl_op_mode_ops iwl_dvm_ops = {
2205 .start = iwl_op_mode_dvm_start, 2340 .start = iwl_op_mode_dvm_start,
2206 .stop = iwl_op_mode_dvm_stop, 2341 .stop = iwl_op_mode_dvm_stop,
@@ -2212,6 +2347,7 @@ const struct iwl_op_mode_ops iwl_dvm_ops = {
2212 .nic_error = iwl_nic_error, 2347 .nic_error = iwl_nic_error,
2213 .cmd_queue_full = iwl_cmd_queue_full, 2348 .cmd_queue_full = iwl_cmd_queue_full,
2214 .nic_config = iwl_nic_config, 2349 .nic_config = iwl_nic_config,
2350 .wimax_active = iwl_wimax_active,
2215}; 2351};
2216 2352
2217/***************************************************************************** 2353/*****************************************************************************
@@ -2280,12 +2416,6 @@ MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
2280module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO); 2416module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
2281MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); 2417MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
2282 2418
2283module_param_named(ucode_alternative,
2284 iwlagn_mod_params.wanted_ucode_alternative,
2285 int, S_IRUGO);
2286MODULE_PARM_DESC(ucode_alternative,
2287 "specify ucode alternative to use from ucode file");
2288
2289module_param_named(antenna_coupling, iwlagn_mod_params.ant_coupling, 2419module_param_named(antenna_coupling, iwlagn_mod_params.ant_coupling,
2290 int, S_IRUGO); 2420 int, S_IRUGO);
2291MODULE_PARM_DESC(antenna_coupling, 2421MODULE_PARM_DESC(antenna_coupling,
@@ -2299,9 +2429,6 @@ MODULE_PARM_DESC(bt_ch_inhibition,
2299module_param_named(plcp_check, iwlagn_mod_params.plcp_check, bool, S_IRUGO); 2429module_param_named(plcp_check, iwlagn_mod_params.plcp_check, bool, S_IRUGO);
2300MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); 2430MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
2301 2431
2302module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO);
2303MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])");
2304
2305module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO); 2432module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO);
2306MODULE_PARM_DESC(wd_disable, 2433MODULE_PARM_DESC(wd_disable,
2307 "Disable stuck queue watchdog timer 0=system default, " 2434 "Disable stuck queue watchdog timer 0=system default, "
@@ -2345,13 +2472,3 @@ module_param_named(auto_agg, iwlagn_mod_params.auto_agg,
2345 bool, S_IRUGO); 2472 bool, S_IRUGO);
2346MODULE_PARM_DESC(auto_agg, 2473MODULE_PARM_DESC(auto_agg,
2347 "enable agg w/o check traffic load (default: enable)"); 2474 "enable agg w/o check traffic load (default: enable)");
2348
2349/*
2350 * For now, keep using power level 1 instead of automatically
2351 * adjusting ...
2352 */
2353module_param_named(no_sleep_autoadjust, iwlagn_mod_params.no_sleep_autoadjust,
2354 bool, S_IRUGO);
2355MODULE_PARM_DESC(no_sleep_autoadjust,
2356 "don't automatically adjust sleep level "
2357 "according to maximum network latency (default: true)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 51001622430b..20100c72ec6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -71,6 +71,34 @@
71/* AUX (TX during scan dwell) queue */ 71/* AUX (TX during scan dwell) queue */
72#define IWL_AUX_QUEUE 10 72#define IWL_AUX_QUEUE 10
73 73
74/* device operations */
75extern struct iwl_lib_ops iwl1000_lib;
76extern struct iwl_lib_ops iwl2000_lib;
77extern struct iwl_lib_ops iwl2030_lib;
78extern struct iwl_lib_ops iwl5000_lib;
79extern struct iwl_lib_ops iwl5150_lib;
80extern struct iwl_lib_ops iwl6000_lib;
81extern struct iwl_lib_ops iwl6030_lib;
82
83
84
85/*****************************************************
86* DRIVER STATUS FUNCTIONS
87******************************************************/
88#define STATUS_RF_KILL_HW 0
89#define STATUS_CT_KILL 1
90#define STATUS_ALIVE 2
91#define STATUS_READY 3
92#define STATUS_GEO_CONFIGURED 4
93#define STATUS_EXIT_PENDING 5
94#define STATUS_STATISTICS 6
95#define STATUS_SCANNING 7
96#define STATUS_SCAN_ABORTING 8
97#define STATUS_SCAN_HW 9
98#define STATUS_FW_ERROR 10
99#define STATUS_CHANNEL_SWITCH_PENDING 11
100#define STATUS_SCAN_COMPLETE 12
101#define STATUS_POWER_PMI 13
74 102
75struct iwl_ucode_capabilities; 103struct iwl_ucode_capabilities;
76 104
@@ -87,11 +115,9 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
87void iwl_down(struct iwl_priv *priv); 115void iwl_down(struct iwl_priv *priv);
88void iwl_cancel_deferred_work(struct iwl_priv *priv); 116void iwl_cancel_deferred_work(struct iwl_priv *priv);
89void iwlagn_prepare_restart(struct iwl_priv *priv); 117void iwlagn_prepare_restart(struct iwl_priv *priv);
90void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb);
91int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, 118int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode,
92 struct iwl_rx_cmd_buffer *rxb, 119 struct iwl_rx_cmd_buffer *rxb,
93 struct iwl_device_cmd *cmd); 120 struct iwl_device_cmd *cmd);
94void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state);
95 121
96bool iwl_check_for_ct_kill(struct iwl_priv *priv); 122bool iwl_check_for_ct_kill(struct iwl_priv *priv);
97 123
@@ -109,6 +135,8 @@ int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id,
109 u32 flags, u16 len, const void *data); 135 u32 flags, u16 len, const void *data);
110 136
111/* RXON */ 137/* RXON */
138void iwl_connection_init_rx_config(struct iwl_priv *priv,
139 struct iwl_rxon_context *ctx);
112int iwlagn_set_pan_params(struct iwl_priv *priv); 140int iwlagn_set_pan_params(struct iwl_priv *priv);
113int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 141int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
114void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 142void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
@@ -119,6 +147,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
119 u32 changes); 147 u32 changes);
120void iwlagn_config_ht40(struct ieee80211_conf *conf, 148void iwlagn_config_ht40(struct ieee80211_conf *conf,
121 struct iwl_rxon_context *ctx); 149 struct iwl_rxon_context *ctx);
150void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
151void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
152 struct iwl_rxon_context *ctx);
153void iwl_set_flags_for_band(struct iwl_priv *priv,
154 struct iwl_rxon_context *ctx,
155 enum ieee80211_band band,
156 struct ieee80211_vif *vif);
157void iwl_set_rate(struct iwl_priv *priv);
122 158
123/* uCode */ 159/* uCode */
124int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); 160int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
@@ -131,17 +167,25 @@ int iwl_send_calib_results(struct iwl_priv *priv);
131int iwl_calib_set(struct iwl_priv *priv, 167int iwl_calib_set(struct iwl_priv *priv,
132 const struct iwl_calib_hdr *cmd, int len); 168 const struct iwl_calib_hdr *cmd, int len);
133void iwl_calib_free_results(struct iwl_priv *priv); 169void iwl_calib_free_results(struct iwl_priv *priv);
134void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
135int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, 170int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
136 char **buf, bool display); 171 char **buf, bool display);
172int iwlagn_hw_valid_rtc_data_addr(u32 addr);
137 173
138/* lib */ 174/* lib */
139int iwlagn_send_tx_power(struct iwl_priv *priv); 175int iwlagn_send_tx_power(struct iwl_priv *priv);
140void iwlagn_temperature(struct iwl_priv *priv); 176void iwlagn_temperature(struct iwl_priv *priv);
141u16 iwl_eeprom_calib_version(struct iwl_shared *shrd);
142int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); 177int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
143void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); 178void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
144int iwlagn_send_beacon_cmd(struct iwl_priv *priv); 179int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
180int iwl_send_statistics_request(struct iwl_priv *priv,
181 u8 flags, bool clear);
182
183static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
184 struct iwl_priv *priv, enum ieee80211_band band)
185{
186 return priv->hw->wiphy->bands[band];
187}
188
145#ifdef CONFIG_PM_SLEEP 189#ifdef CONFIG_PM_SLEEP
146int iwlagn_send_patterns(struct iwl_priv *priv, 190int iwlagn_send_patterns(struct iwl_priv *priv,
147 struct cfg80211_wowlan *wowlan); 191 struct cfg80211_wowlan *wowlan);
@@ -151,6 +195,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan);
151/* rx */ 195/* rx */
152int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); 196int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
153void iwl_setup_rx_handlers(struct iwl_priv *priv); 197void iwl_setup_rx_handlers(struct iwl_priv *priv);
198void iwl_chswitch_done(struct iwl_priv *priv, bool is_success);
154 199
155 200
156/* tx */ 201/* tx */
@@ -195,6 +240,31 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
195/* scan */ 240/* scan */
196void iwlagn_post_scan(struct iwl_priv *priv); 241void iwlagn_post_scan(struct iwl_priv *priv);
197void iwlagn_disable_roc(struct iwl_priv *priv); 242void iwlagn_disable_roc(struct iwl_priv *priv);
243int iwl_force_rf_reset(struct iwl_priv *priv, bool external);
244void iwl_init_scan_params(struct iwl_priv *priv);
245int iwl_scan_cancel(struct iwl_priv *priv);
246void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
247void iwl_force_scan_end(struct iwl_priv *priv);
248void iwl_internal_short_hw_scan(struct iwl_priv *priv);
249void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
250void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
251void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
252int __must_check iwl_scan_initiate(struct iwl_priv *priv,
253 struct ieee80211_vif *vif,
254 enum iwl_scan_type scan_type,
255 enum ieee80211_band band);
256
257/* For faster active scanning, scan will move to the next channel if fewer than
258 * PLCP_QUIET_THRESH packets are heard on this channel within
259 * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
260 * time if it's a quiet channel (nothing responded to our probe, and there's
261 * no other traffic).
262 * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
263#define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */
264#define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */
265
266#define IWL_SCAN_CHECK_WATCHDOG (HZ * 7)
267
198 268
199/* bt coex */ 269/* bt coex */
200void iwlagn_send_advance_bt_config(struct iwl_priv *priv); 270void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
@@ -207,6 +277,12 @@ void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
207void iwlagn_bt_coex_rssi_monitor(struct iwl_priv *priv); 277void iwlagn_bt_coex_rssi_monitor(struct iwl_priv *priv);
208void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena); 278void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena);
209 279
280static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
281{
282 return cfg(priv)->bt_params &&
283 cfg(priv)->bt_params->advanced_bt_coexist;
284}
285
210#ifdef CONFIG_IWLWIFI_DEBUG 286#ifdef CONFIG_IWLWIFI_DEBUG
211const char *iwl_get_tx_fail_reason(u32 status); 287const char *iwl_get_tx_fail_reason(u32 status);
212const char *iwl_get_agg_tx_fail_reason(u16 status); 288const char *iwl_get_agg_tx_fail_reason(u16 status);
@@ -245,8 +321,6 @@ void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
245u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 321u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
246 const u8 *addr, bool is_ap, struct ieee80211_sta *sta); 322 const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
247 323
248void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
249 u8 sta_id, struct iwl_link_quality_cmd *link_cmd);
250int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 324int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
251 struct iwl_link_quality_cmd *lq, u8 flags, bool init); 325 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
252int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, 326int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
@@ -254,6 +328,9 @@ int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
254int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 328int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
255 struct ieee80211_sta *sta); 329 struct ieee80211_sta *sta);
256 330
331bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
332 struct iwl_rxon_context *ctx,
333 struct ieee80211_sta_ht_cap *ht_cap);
257 334
258static inline int iwl_sta_id(struct ieee80211_sta *sta) 335static inline int iwl_sta_id(struct ieee80211_sta *sta)
259{ 336{
@@ -311,9 +388,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
311 return cpu_to_le32(flags|(u32)rate); 388 return cpu_to_le32(flags|(u32)rate);
312} 389}
313 390
314/* eeprom */
315void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac);
316
317extern int iwl_alive_start(struct iwl_priv *priv); 391extern int iwl_alive_start(struct iwl_priv *priv);
318/* svtool */ 392/* svtool */
319#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE 393#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
@@ -421,4 +495,95 @@ do { \
421} while (0) 495} while (0)
422#endif /* CONFIG_IWLWIFI_DEBUG */ 496#endif /* CONFIG_IWLWIFI_DEBUG */
423 497
498extern const char *iwl_dvm_cmd_strings[REPLY_MAX];
499
500static inline const char *iwl_dvm_get_cmd_string(u8 cmd)
501{
502 const char *s = iwl_dvm_cmd_strings[cmd];
503 if (s)
504 return s;
505 return "UNKNOWN";
506}
507
508/* API method exported for mvm hybrid state */
509void iwl_setup_deferred_work(struct iwl_priv *priv);
510int iwl_send_wimax_coex(struct iwl_priv *priv);
511int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
512void iwl_debug_config(struct iwl_priv *priv);
513int iwl_alloc_traffic_mem(struct iwl_priv *priv);
514void iwl_set_hw_params(struct iwl_priv *priv);
515void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags);
516int iwl_init_drv(struct iwl_priv *priv);
517void iwl_uninit_drv(struct iwl_priv *priv);
518void iwl_send_bt_config(struct iwl_priv *priv);
519void iwl_rf_kill_ct_config(struct iwl_priv *priv);
520int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
521void iwl_teardown_interface(struct iwl_priv *priv,
522 struct ieee80211_vif *vif,
523 bool mode_change);
524int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
525void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
526void iwlagn_check_needed_chains(struct iwl_priv *priv,
527 struct iwl_rxon_context *ctx,
528 struct ieee80211_bss_conf *bss_conf);
529void iwlagn_chain_noise_reset(struct iwl_priv *priv);
530int iwlagn_update_beacon(struct iwl_priv *priv,
531 struct ieee80211_vif *vif);
532void iwl_tt_handler(struct iwl_priv *priv);
533void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode);
534void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue);
535void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state);
536void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb);
537void iwl_nic_error(struct iwl_op_mode *op_mode);
538void iwl_cmd_queue_full(struct iwl_op_mode *op_mode);
539void iwl_nic_config(struct iwl_op_mode *op_mode);
540int iwlagn_mac_set_tim(struct ieee80211_hw *hw,
541 struct ieee80211_sta *sta, bool set);
542void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
543 enum ieee80211_rssi_event rssi_event);
544int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw);
545int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw);
546void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop);
547void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue);
548void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
549 struct ieee80211_channel_switch *ch_switch);
550int iwlagn_mac_sta_state(struct ieee80211_hw *hw,
551 struct ieee80211_vif *vif,
552 struct ieee80211_sta *sta,
553 enum ieee80211_sta_state old_state,
554 enum ieee80211_sta_state new_state);
555int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
556 struct ieee80211_vif *vif,
557 enum ieee80211_ampdu_mlme_action action,
558 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
559 u8 buf_size);
560int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
561 struct ieee80211_vif *vif,
562 struct cfg80211_scan_request *req);
563void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
564 struct ieee80211_vif *vif,
565 enum sta_notify_cmd cmd,
566 struct ieee80211_sta *sta);
567void iwlagn_configure_filter(struct ieee80211_hw *hw,
568 unsigned int changed_flags,
569 unsigned int *total_flags,
570 u64 multicast);
571int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
572 struct ieee80211_vif *vif, u16 queue,
573 const struct ieee80211_tx_queue_params *params);
574void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
575 struct ieee80211_vif *vif,
576 struct cfg80211_gtk_rekey_data *data);
577void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
578 struct ieee80211_vif *vif,
579 struct ieee80211_key_conf *keyconf,
580 struct ieee80211_sta *sta,
581 u32 iv32, u16 *phase1key);
582int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
583 struct ieee80211_vif *vif,
584 struct ieee80211_sta *sta,
585 struct ieee80211_key_conf *key);
586void iwlagn_mac_stop(struct ieee80211_hw *hw);
587void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
588int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
424#endif /* __iwl_agn_h__ */ 589#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 9ed73e5154be..296347a8290f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1918,7 +1918,7 @@ struct iwl_basic_bt_cmd {
1918 __le16 valid; 1918 __le16 valid;
1919}; 1919};
1920 1920
1921struct iwl6000_bt_cmd { 1921struct iwl_bt_cmd_v1 {
1922 struct iwl_basic_bt_cmd basic; 1922 struct iwl_basic_bt_cmd basic;
1923 u8 prio_boost; 1923 u8 prio_boost;
1924 /* 1924 /*
@@ -1929,7 +1929,7 @@ struct iwl6000_bt_cmd {
1929 __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ 1929 __le16 rx_prio_boost; /* SW boost of WiFi rx priority */
1930}; 1930};
1931 1931
1932struct iwl2000_bt_cmd { 1932struct iwl_bt_cmd_v2 {
1933 struct iwl_basic_bt_cmd basic; 1933 struct iwl_basic_bt_cmd basic;
1934 __le32 prio_boost; 1934 __le32 prio_boost;
1935 /* 1935 /*
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
new file mode 100644
index 000000000000..47bfd5e59575
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -0,0 +1,227 @@
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 - 2012 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 - 2012 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 __IWL_CONFIG_H__
64#define __IWL_CONFIG_H__
65
66#include <linux/types.h>
67#include <net/mac80211.h>
68
69
70enum iwl_device_family {
71 IWL_DEVICE_FAMILY_UNDEFINED,
72 IWL_DEVICE_FAMILY_1000,
73 IWL_DEVICE_FAMILY_100,
74 IWL_DEVICE_FAMILY_2000,
75 IWL_DEVICE_FAMILY_2030,
76 IWL_DEVICE_FAMILY_105,
77 IWL_DEVICE_FAMILY_135,
78 IWL_DEVICE_FAMILY_5000,
79 IWL_DEVICE_FAMILY_5150,
80 IWL_DEVICE_FAMILY_6000,
81 IWL_DEVICE_FAMILY_6000i,
82 IWL_DEVICE_FAMILY_6005,
83 IWL_DEVICE_FAMILY_6030,
84 IWL_DEVICE_FAMILY_6050,
85 IWL_DEVICE_FAMILY_6150,
86};
87
88/*
89 * LED mode
90 * IWL_LED_DEFAULT: use device default
91 * IWL_LED_RF_STATE: turn LED on/off based on RF state
92 * LED ON = RF ON
93 * LED OFF = RF OFF
94 * IWL_LED_BLINK: adjust led blink rate based on blink table
95 * IWL_LED_DISABLE: led disabled
96 */
97enum iwl_led_mode {
98 IWL_LED_DEFAULT,
99 IWL_LED_RF_STATE,
100 IWL_LED_BLINK,
101 IWL_LED_DISABLE,
102};
103
104/*
105 * @max_ll_items: max number of OTP blocks
106 * @shadow_ram_support: shadow support for OTP memory
107 * @led_compensation: compensate on the led on/off time per HW according
108 * to the deviation to achieve the desired led frequency.
109 * The detail algorithm is described in iwl-led.c
110 * @chain_noise_num_beacons: number of beacons used to compute chain noise
111 * @adv_thermal_throttle: support advance thermal throttle
112 * @support_ct_kill_exit: support ct kill exit condition
113 * @plcp_delta_threshold: plcp error rate threshold used to trigger
114 * radio tuning when there is a high receiving plcp error rate
115 * @chain_noise_scale: default chain noise scale used for gain computation
116 * @wd_timeout: TX queues watchdog timeout
117 * @max_event_log_size: size of event log buffer size for ucode event logging
118 * @shadow_reg_enable: HW shadhow register bit
119 * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
120 * @no_idle_support: do not support idle mode
121 */
122struct iwl_base_params {
123 int eeprom_size;
124 int num_of_queues; /* def: HW dependent */
125 /* for iwl_apm_init() */
126 u32 pll_cfg_val;
127
128 const u16 max_ll_items;
129 const bool shadow_ram_support;
130 u16 led_compensation;
131 bool adv_thermal_throttle;
132 bool support_ct_kill_exit;
133 u8 plcp_delta_threshold;
134 s32 chain_noise_scale;
135 unsigned int wd_timeout;
136 u32 max_event_log_size;
137 const bool shadow_reg_enable;
138 const bool hd_v2;
139 const bool no_idle_support;
140};
141
142/*
143 * @advanced_bt_coexist: support advanced bt coexist
144 * @bt_init_traffic_load: specify initial bt traffic load
145 * @bt_prio_boost: default bt priority boost value
146 * @agg_time_limit: maximum number of uSec in aggregation
147 * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
148 */
149struct iwl_bt_params {
150 bool advanced_bt_coexist;
151 u8 bt_init_traffic_load;
152 u8 bt_prio_boost;
153 u16 agg_time_limit;
154 bool bt_sco_disable;
155 bool bt_session_2;
156};
157/*
158 * @use_rts_for_aggregation: use rts/cts protection for HT traffic
159 */
160struct iwl_ht_params {
161 const bool ht_greenfield_support; /* if used set to true */
162 bool use_rts_for_aggregation;
163 enum ieee80211_smps_mode smps_mode;
164};
165
166/**
167 * struct iwl_cfg
168 * @name: Offical name of the device
169 * @fw_name_pre: Firmware filename prefix. The api version and extension
170 * (.ucode) will be added to filename before loading from disk. The
171 * filename is constructed as fw_name_pre<api>.ucode.
172 * @ucode_api_max: Highest version of uCode API supported by driver.
173 * @ucode_api_ok: oldest version of the uCode API that is OK to load
174 * without a warning, for use in transitions
175 * @ucode_api_min: Lowest version of uCode API supported by driver.
176 * @max_inst_size: The maximal length of the fw inst section
177 * @max_data_size: The maximal length of the fw data section
178 * @valid_tx_ant: valid transmit antenna
179 * @valid_rx_ant: valid receive antenna
180 * @eeprom_ver: EEPROM version
181 * @eeprom_calib_ver: EEPROM calibration version
182 * @lib: pointer to the lib ops
183 * @base_params: pointer to basic parameters
184 * @ht_params: point to ht patameters
185 * @bt_params: pointer to bt parameters
186 * @need_temp_offset_calib: need to perform temperature offset calibration
187 * @no_xtal_calib: some devices do not need crystal calibration data,
188 * don't send it to those
189 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
190 * @adv_pm: advance power management
191 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
192 * @internal_wimax_coex: internal wifi/wimax combo device
193 * @temp_offset_v2: support v2 of temperature offset calibration
194 *
195 * We enable the driver to be backward compatible wrt. hardware features.
196 * API differences in uCode shouldn't be handled here but through TLVs
197 * and/or the uCode API version instead.
198 */
199struct iwl_cfg {
200 /* params specific to an individual device within a device family */
201 const char *name;
202 const char *fw_name_pre;
203 const unsigned int ucode_api_max;
204 const unsigned int ucode_api_ok;
205 const unsigned int ucode_api_min;
206 const enum iwl_device_family device_family;
207 const u32 max_data_size;
208 const u32 max_inst_size;
209 u8 valid_tx_ant;
210 u8 valid_rx_ant;
211 u16 eeprom_ver;
212 u16 eeprom_calib_ver;
213 /* params not likely to change within a device family */
214 const struct iwl_base_params *base_params;
215 /* params likely to change within a device family */
216 const struct iwl_ht_params *ht_params;
217 const struct iwl_bt_params *bt_params;
218 const bool need_temp_offset_calib; /* if used set to true */
219 const bool no_xtal_calib;
220 enum iwl_led_mode led_mode;
221 const bool adv_pm;
222 const bool rx_with_siso_diversity;
223 const bool internal_wimax_coex;
224 const bool temp_offset_v2;
225};
226
227#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 88ea31d9eb75..d7a8cde249ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -41,477 +41,6 @@
41#include "iwl-agn.h" 41#include "iwl-agn.h"
42#include "iwl-trans.h" 42#include "iwl-trans.h"
43 43
44const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
45
46static bool iwl_is_channel_extension(struct iwl_priv *priv,
47 enum ieee80211_band band,
48 u16 channel, u8 extension_chan_offset)
49{
50 const struct iwl_channel_info *ch_info;
51
52 ch_info = iwl_get_channel_info(priv, band, channel);
53 if (!is_channel_valid(ch_info))
54 return false;
55
56 if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
57 return !(ch_info->ht40_extension_channel &
58 IEEE80211_CHAN_NO_HT40PLUS);
59 else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW)
60 return !(ch_info->ht40_extension_channel &
61 IEEE80211_CHAN_NO_HT40MINUS);
62
63 return false;
64}
65
66bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
67 struct iwl_rxon_context *ctx,
68 struct ieee80211_sta_ht_cap *ht_cap)
69{
70 if (!ctx->ht.enabled || !ctx->ht.is_40mhz)
71 return false;
72
73 /*
74 * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
75 * the bit will not set if it is pure 40MHz case
76 */
77 if (ht_cap && !ht_cap->ht_supported)
78 return false;
79
80#ifdef CONFIG_IWLWIFI_DEBUGFS
81 if (priv->disable_ht40)
82 return false;
83#endif
84
85 return iwl_is_channel_extension(priv, priv->band,
86 le16_to_cpu(ctx->staging.channel),
87 ctx->ht.extension_chan_offset);
88}
89
90static void _iwl_set_rxon_ht(struct iwl_priv *priv,
91 struct iwl_ht_config *ht_conf,
92 struct iwl_rxon_context *ctx)
93{
94 struct iwl_rxon_cmd *rxon = &ctx->staging;
95
96 if (!ctx->ht.enabled) {
97 rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
98 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
99 RXON_FLG_HT40_PROT_MSK |
100 RXON_FLG_HT_PROT_MSK);
101 return;
102 }
103
104 /* FIXME: if the definition of ht.protection changed, the "translation"
105 * will be needed for rxon->flags
106 */
107 rxon->flags |= cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
108
109 /* Set up channel bandwidth:
110 * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
111 /* clear the HT channel mode before set the mode */
112 rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
113 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
114 if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) {
115 /* pure ht40 */
116 if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
117 rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
118 /* Note: control channel is opposite of extension channel */
119 switch (ctx->ht.extension_chan_offset) {
120 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
121 rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
122 break;
123 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
124 rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
125 break;
126 }
127 } else {
128 /* Note: control channel is opposite of extension channel */
129 switch (ctx->ht.extension_chan_offset) {
130 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
131 rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
132 rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
133 break;
134 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
135 rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
136 rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
137 break;
138 case IEEE80211_HT_PARAM_CHA_SEC_NONE:
139 default:
140 /* channel location only valid if in Mixed mode */
141 IWL_ERR(priv, "invalid extension channel offset\n");
142 break;
143 }
144 }
145 } else {
146 rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY;
147 }
148
149 iwlagn_set_rxon_chain(priv, ctx);
150
151 IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
152 "extension channel offset 0x%x\n",
153 le32_to_cpu(rxon->flags), ctx->ht.protection,
154 ctx->ht.extension_chan_offset);
155}
156
157void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
158{
159 struct iwl_rxon_context *ctx;
160
161 for_each_context(priv, ctx)
162 _iwl_set_rxon_ht(priv, ht_conf, ctx);
163}
164
165/**
166 * iwl_set_rxon_channel - Set the band and channel values in staging RXON
167 * @ch: requested channel as a pointer to struct ieee80211_channel
168
169 * NOTE: Does not commit to the hardware; it sets appropriate bit fields
170 * in the staging RXON flag structure based on the ch->band
171 */
172void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
173 struct iwl_rxon_context *ctx)
174{
175 enum ieee80211_band band = ch->band;
176 u16 channel = ch->hw_value;
177
178 if ((le16_to_cpu(ctx->staging.channel) == channel) &&
179 (priv->band == band))
180 return;
181
182 ctx->staging.channel = cpu_to_le16(channel);
183 if (band == IEEE80211_BAND_5GHZ)
184 ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
185 else
186 ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
187
188 priv->band = band;
189
190 IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
191
192}
193
194void iwl_set_flags_for_band(struct iwl_priv *priv,
195 struct iwl_rxon_context *ctx,
196 enum ieee80211_band band,
197 struct ieee80211_vif *vif)
198{
199 if (band == IEEE80211_BAND_5GHZ) {
200 ctx->staging.flags &=
201 ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
202 | RXON_FLG_CCK_MSK);
203 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
204 } else {
205 /* Copied from iwl_post_associate() */
206 if (vif && vif->bss_conf.use_short_slot)
207 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
208 else
209 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
210
211 ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
212 ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
213 ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
214 }
215}
216
217/*
218 * initialize rxon structure with default values from eeprom
219 */
220void iwl_connection_init_rx_config(struct iwl_priv *priv,
221 struct iwl_rxon_context *ctx)
222{
223 const struct iwl_channel_info *ch_info;
224
225 memset(&ctx->staging, 0, sizeof(ctx->staging));
226
227 if (!ctx->vif) {
228 ctx->staging.dev_type = ctx->unused_devtype;
229 } else switch (ctx->vif->type) {
230 case NL80211_IFTYPE_AP:
231 ctx->staging.dev_type = ctx->ap_devtype;
232 break;
233
234 case NL80211_IFTYPE_STATION:
235 ctx->staging.dev_type = ctx->station_devtype;
236 ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
237 break;
238
239 case NL80211_IFTYPE_ADHOC:
240 ctx->staging.dev_type = ctx->ibss_devtype;
241 ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
242 ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
243 RXON_FILTER_ACCEPT_GRP_MSK;
244 break;
245
246 default:
247 IWL_ERR(priv, "Unsupported interface type %d\n",
248 ctx->vif->type);
249 break;
250 }
251
252#if 0
253 /* TODO: Figure out when short_preamble would be set and cache from
254 * that */
255 if (!hw_to_local(priv->hw)->short_preamble)
256 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
257 else
258 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
259#endif
260
261 ch_info = iwl_get_channel_info(priv, priv->band,
262 le16_to_cpu(ctx->active.channel));
263
264 if (!ch_info)
265 ch_info = &priv->channel_info[0];
266
267 ctx->staging.channel = cpu_to_le16(ch_info->channel);
268 priv->band = ch_info->band;
269
270 iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);
271
272 ctx->staging.ofdm_basic_rates =
273 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
274 ctx->staging.cck_basic_rates =
275 (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
276
277 /* clear both MIX and PURE40 mode flag */
278 ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
279 RXON_FLG_CHANNEL_MODE_PURE_40);
280 if (ctx->vif)
281 memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
282
283 ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;
284 ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
285 ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff;
286}
287
288void iwl_set_rate(struct iwl_priv *priv)
289{
290 const struct ieee80211_supported_band *hw = NULL;
291 struct ieee80211_rate *rate;
292 struct iwl_rxon_context *ctx;
293 int i;
294
295 hw = iwl_get_hw_mode(priv, priv->band);
296 if (!hw) {
297 IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n");
298 return;
299 }
300
301 priv->active_rate = 0;
302
303 for (i = 0; i < hw->n_bitrates; i++) {
304 rate = &(hw->bitrates[i]);
305 if (rate->hw_value < IWL_RATE_COUNT_LEGACY)
306 priv->active_rate |= (1 << rate->hw_value);
307 }
308
309 IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate);
310
311 for_each_context(priv, ctx) {
312 ctx->staging.cck_basic_rates =
313 (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
314
315 ctx->staging.ofdm_basic_rates =
316 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
317 }
318}
319
320void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
321{
322 /*
323 * MULTI-FIXME
324 * See iwlagn_mac_channel_switch.
325 */
326 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
327
328 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
329 return;
330
331 if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
332 ieee80211_chswitch_done(ctx->vif, is_success);
333}
334
335#ifdef CONFIG_IWLWIFI_DEBUG
336void iwl_print_rx_config_cmd(struct iwl_priv *priv,
337 enum iwl_rxon_context_id ctxid)
338{
339 struct iwl_rxon_context *ctx = &priv->contexts[ctxid];
340 struct iwl_rxon_cmd *rxon = &ctx->staging;
341
342 IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
343 iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
344 IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
345 IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
346 IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n",
347 le32_to_cpu(rxon->filter_flags));
348 IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type);
349 IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n",
350 rxon->ofdm_basic_rates);
351 IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
352 IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr);
353 IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
354 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
355}
356#endif
357
358void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
359{
360 unsigned int reload_msec;
361 unsigned long reload_jiffies;
362
363#ifdef CONFIG_IWLWIFI_DEBUG
364 if (iwl_have_debug_level(IWL_DL_FW_ERRORS))
365 iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
366#endif
367
368 /* uCode is no longer loaded. */
369 priv->ucode_loaded = false;
370
371 /* Set the FW error flag -- cleared on iwl_down */
372 set_bit(STATUS_FW_ERROR, &priv->status);
373
374 /* Cancel currently queued command. */
375 clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status);
376
377 iwl_abort_notification_waits(&priv->notif_wait);
378
379 /* Keep the restart process from trying to send host
380 * commands by clearing the ready bit */
381 clear_bit(STATUS_READY, &priv->status);
382
383 wake_up(&trans(priv)->wait_command_queue);
384
385 if (!ondemand) {
386 /*
387 * If firmware keep reloading, then it indicate something
388 * serious wrong and firmware having problem to recover
389 * from it. Instead of keep trying which will fill the syslog
390 * and hang the system, let's just stop it
391 */
392 reload_jiffies = jiffies;
393 reload_msec = jiffies_to_msecs((long) reload_jiffies -
394 (long) priv->reload_jiffies);
395 priv->reload_jiffies = reload_jiffies;
396 if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
397 priv->reload_count++;
398 if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
399 IWL_ERR(priv, "BUG_ON, Stop restarting\n");
400 return;
401 }
402 } else
403 priv->reload_count = 0;
404 }
405
406 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
407 if (iwlagn_mod_params.restart_fw) {
408 IWL_DEBUG_FW_ERRORS(priv,
409 "Restarting adapter due to uCode error.\n");
410 queue_work(priv->workqueue, &priv->restart);
411 } else
412 IWL_DEBUG_FW_ERRORS(priv,
413 "Detected FW error, but not restarting\n");
414 }
415}
416
417int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
418{
419 int ret;
420 s8 prev_tx_power;
421 bool defer;
422 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
423
424 lockdep_assert_held(&priv->mutex);
425
426 if (priv->tx_power_user_lmt == tx_power && !force)
427 return 0;
428
429 if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
430 IWL_WARN(priv,
431 "Requested user TXPOWER %d below lower limit %d.\n",
432 tx_power,
433 IWLAGN_TX_POWER_TARGET_POWER_MIN);
434 return -EINVAL;
435 }
436
437 if (tx_power > priv->tx_power_device_lmt) {
438 IWL_WARN(priv,
439 "Requested user TXPOWER %d above upper limit %d.\n",
440 tx_power, priv->tx_power_device_lmt);
441 return -EINVAL;
442 }
443
444 if (!iwl_is_ready_rf(priv))
445 return -EIO;
446
447 /* scan complete and commit_rxon use tx_power_next value,
448 * it always need to be updated for newest request */
449 priv->tx_power_next = tx_power;
450
451 /* do not set tx power when scanning or channel changing */
452 defer = test_bit(STATUS_SCANNING, &priv->status) ||
453 memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging));
454 if (defer && !force) {
455 IWL_DEBUG_INFO(priv, "Deferring tx power set\n");
456 return 0;
457 }
458
459 prev_tx_power = priv->tx_power_user_lmt;
460 priv->tx_power_user_lmt = tx_power;
461
462 ret = iwlagn_send_tx_power(priv);
463
464 /* if fail to set tx_power, restore the orig. tx power */
465 if (ret) {
466 priv->tx_power_user_lmt = prev_tx_power;
467 priv->tx_power_next = prev_tx_power;
468 }
469 return ret;
470}
471
472void iwl_send_bt_config(struct iwl_priv *priv)
473{
474 struct iwl_bt_cmd bt_cmd = {
475 .lead_time = BT_LEAD_TIME_DEF,
476 .max_kill = BT_MAX_KILL_DEF,
477 .kill_ack_mask = 0,
478 .kill_cts_mask = 0,
479 };
480
481 if (!iwlagn_mod_params.bt_coex_active)
482 bt_cmd.flags = BT_COEX_DISABLE;
483 else
484 bt_cmd.flags = BT_COEX_ENABLE;
485
486 priv->bt_enable_flag = bt_cmd.flags;
487 IWL_DEBUG_INFO(priv, "BT coex %s\n",
488 (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
489
490 if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
491 CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd))
492 IWL_ERR(priv, "failed to send BT Coex Config\n");
493}
494
495int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
496{
497 struct iwl_statistics_cmd statistics_cmd = {
498 .configuration_flags =
499 clear ? IWL_STATS_CONF_CLEAR_STATS : 0,
500 };
501
502 if (flags & CMD_ASYNC)
503 return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
504 CMD_ASYNC,
505 sizeof(struct iwl_statistics_cmd),
506 &statistics_cmd);
507 else
508 return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
509 CMD_SYNC,
510 sizeof(struct iwl_statistics_cmd),
511 &statistics_cmd);
512}
513
514
515 44
516 45
517#ifdef CONFIG_IWLWIFI_DEBUGFS 46#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -611,6 +140,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
611 140
612const char *get_mgmt_string(int cmd) 141const char *get_mgmt_string(int cmd)
613{ 142{
143#define IWL_CMD(x) case x: return #x
614 switch (cmd) { 144 switch (cmd) {
615 IWL_CMD(MANAGEMENT_ASSOC_REQ); 145 IWL_CMD(MANAGEMENT_ASSOC_REQ);
616 IWL_CMD(MANAGEMENT_ASSOC_RESP); 146 IWL_CMD(MANAGEMENT_ASSOC_RESP);
@@ -628,10 +158,12 @@ const char *get_mgmt_string(int cmd)
628 return "UNKNOWN"; 158 return "UNKNOWN";
629 159
630 } 160 }
161#undef IWL_CMD
631} 162}
632 163
633const char *get_ctrl_string(int cmd) 164const char *get_ctrl_string(int cmd)
634{ 165{
166#define IWL_CMD(x) case x: return #x
635 switch (cmd) { 167 switch (cmd) {
636 IWL_CMD(CONTROL_BACK_REQ); 168 IWL_CMD(CONTROL_BACK_REQ);
637 IWL_CMD(CONTROL_BACK); 169 IWL_CMD(CONTROL_BACK);
@@ -645,6 +177,7 @@ const char *get_ctrl_string(int cmd)
645 return "UNKNOWN"; 177 return "UNKNOWN";
646 178
647 } 179 }
180#undef IWL_CMD
648} 181}
649 182
650void iwl_clear_traffic_stats(struct iwl_priv *priv) 183void iwl_clear_traffic_stats(struct iwl_priv *priv)
@@ -746,80 +279,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
746} 279}
747#endif 280#endif
748 281
749static void iwl_force_rf_reset(struct iwl_priv *priv)
750{
751 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
752 return;
753
754 if (!iwl_is_any_associated(priv)) {
755 IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
756 return;
757 }
758 /*
759 * There is no easy and better way to force reset the radio,
760 * the only known method is switching channel which will force to
761 * reset and tune the radio.
762 * Use internal short scan (single channel) operation to should
763 * achieve this objective.
764 * Driver should reset the radio when number of consecutive missed
765 * beacon, or any other uCode error condition detected.
766 */
767 IWL_DEBUG_INFO(priv, "perform radio reset.\n");
768 iwl_internal_short_hw_scan(priv);
769}
770
771
772int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
773{
774 struct iwl_force_reset *force_reset;
775
776 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
777 return -EINVAL;
778
779 if (mode >= IWL_MAX_FORCE_RESET) {
780 IWL_DEBUG_INFO(priv, "invalid reset request.\n");
781 return -EINVAL;
782 }
783 force_reset = &priv->force_reset[mode];
784 force_reset->reset_request_count++;
785 if (!external) {
786 if (force_reset->last_force_reset_jiffies &&
787 time_after(force_reset->last_force_reset_jiffies +
788 force_reset->reset_duration, jiffies)) {
789 IWL_DEBUG_INFO(priv, "force reset rejected\n");
790 force_reset->reset_reject_count++;
791 return -EAGAIN;
792 }
793 }
794 force_reset->reset_success_count++;
795 force_reset->last_force_reset_jiffies = jiffies;
796 IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode);
797 switch (mode) {
798 case IWL_RF_RESET:
799 iwl_force_rf_reset(priv);
800 break;
801 case IWL_FW_RESET:
802 /*
803 * if the request is from external(ex: debugfs),
804 * then always perform the request in regardless the module
805 * parameter setting
806 * if the request is from internal (uCode error or driver
807 * detect failure), then fw_restart module parameter
808 * need to be check before performing firmware reload
809 */
810 if (!external && !iwlagn_mod_params.restart_fw) {
811 IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
812 "module parameter setting\n");
813 break;
814 }
815 IWL_ERR(priv, "On demand firmware reload\n");
816 iwlagn_fw_error(priv, true);
817 break;
818 }
819 return 0;
820}
821
822
823int iwl_cmd_echo_test(struct iwl_priv *priv) 282int iwl_cmd_echo_test(struct iwl_priv *priv)
824{ 283{
825 int ret; 284 int ret;
@@ -836,165 +295,3 @@ int iwl_cmd_echo_test(struct iwl_priv *priv)
836 IWL_DEBUG_INFO(priv, "echo testing pass\n"); 295 IWL_DEBUG_INFO(priv, "echo testing pass\n");
837 return ret; 296 return ret;
838} 297}
839
840static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
841{
842 if (iwl_trans_check_stuck_queue(trans(priv), txq)) {
843 int ret;
844 ret = iwl_force_reset(priv, IWL_FW_RESET, false);
845 return (ret == -EAGAIN) ? 0 : 1;
846 }
847 return 0;
848}
849
850/*
851 * Making watchdog tick be a quarter of timeout assure we will
852 * discover the queue hung between timeout and 1.25*timeout
853 */
854#define IWL_WD_TICK(timeout) ((timeout) / 4)
855
856/*
857 * Watchdog timer callback, we check each tx queue for stuck, if if hung
858 * we reset the firmware. If everything is fine just rearm the timer.
859 */
860void iwl_bg_watchdog(unsigned long data)
861{
862 struct iwl_priv *priv = (struct iwl_priv *)data;
863 int cnt;
864 unsigned long timeout;
865
866 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
867 return;
868
869 if (iwl_is_rfkill(priv))
870 return;
871
872 timeout = hw_params(priv).wd_timeout;
873 if (timeout == 0)
874 return;
875
876 /* monitor and check for stuck queues */
877 for (cnt = 0; cnt < cfg(priv)->base_params->num_of_queues; cnt++)
878 if (iwl_check_stuck_queue(priv, cnt))
879 return;
880
881 mod_timer(&priv->watchdog, jiffies +
882 msecs_to_jiffies(IWL_WD_TICK(timeout)));
883}
884
885void iwl_setup_watchdog(struct iwl_priv *priv)
886{
887 unsigned int timeout = hw_params(priv).wd_timeout;
888
889 if (!iwlagn_mod_params.wd_disable) {
890 /* use system default */
891 if (timeout && !cfg(priv)->base_params->wd_disable)
892 mod_timer(&priv->watchdog,
893 jiffies +
894 msecs_to_jiffies(IWL_WD_TICK(timeout)));
895 else
896 del_timer(&priv->watchdog);
897 } else {
898 /* module parameter overwrite default configuration */
899 if (timeout && iwlagn_mod_params.wd_disable == 2)
900 mod_timer(&priv->watchdog,
901 jiffies +
902 msecs_to_jiffies(IWL_WD_TICK(timeout)));
903 else
904 del_timer(&priv->watchdog);
905 }
906}
907
908/**
909 * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time
910 * @priv -- pointer to iwl_priv data structure
911 * @tsf_bits -- number of bits need to shift for masking)
912 */
913static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv,
914 u16 tsf_bits)
915{
916 return (1 << tsf_bits) - 1;
917}
918
919/**
920 * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time
921 * @priv -- pointer to iwl_priv data structure
922 * @tsf_bits -- number of bits need to shift for masking)
923 */
924static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv,
925 u16 tsf_bits)
926{
927 return ((1 << (32 - tsf_bits)) - 1) << tsf_bits;
928}
929
930/*
931 * extended beacon time format
932 * time in usec will be changed into a 32-bit value in extended:internal format
933 * the extended part is the beacon counts
934 * the internal part is the time in usec within one beacon interval
935 */
936u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval)
937{
938 u32 quot;
939 u32 rem;
940 u32 interval = beacon_interval * TIME_UNIT;
941
942 if (!interval || !usec)
943 return 0;
944
945 quot = (usec / interval) &
946 (iwl_beacon_time_mask_high(priv, IWLAGN_EXT_BEACON_TIME_POS) >>
947 IWLAGN_EXT_BEACON_TIME_POS);
948 rem = (usec % interval) & iwl_beacon_time_mask_low(priv,
949 IWLAGN_EXT_BEACON_TIME_POS);
950
951 return (quot << IWLAGN_EXT_BEACON_TIME_POS) + rem;
952}
953
954/* base is usually what we get from ucode with each received frame,
955 * the same as HW timer counter counting down
956 */
957__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
958 u32 addon, u32 beacon_interval)
959{
960 u32 base_low = base & iwl_beacon_time_mask_low(priv,
961 IWLAGN_EXT_BEACON_TIME_POS);
962 u32 addon_low = addon & iwl_beacon_time_mask_low(priv,
963 IWLAGN_EXT_BEACON_TIME_POS);
964 u32 interval = beacon_interval * TIME_UNIT;
965 u32 res = (base & iwl_beacon_time_mask_high(priv,
966 IWLAGN_EXT_BEACON_TIME_POS)) +
967 (addon & iwl_beacon_time_mask_high(priv,
968 IWLAGN_EXT_BEACON_TIME_POS));
969
970 if (base_low > addon_low)
971 res += base_low - addon_low;
972 else if (base_low < addon_low) {
973 res += interval + base_low - addon_low;
974 res += (1 << IWLAGN_EXT_BEACON_TIME_POS);
975 } else
976 res += (1 << IWLAGN_EXT_BEACON_TIME_POS);
977
978 return cpu_to_le32(res);
979}
980
981void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
982{
983 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
984
985 if (state)
986 set_bit(STATUS_RF_KILL_HW, &priv->status);
987 else
988 clear_bit(STATUS_RF_KILL_HW, &priv->status);
989
990 wiphy_rfkill_set_hw_state(priv->hw->wiphy, state);
991}
992
993void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
994{
995 struct ieee80211_tx_info *info;
996
997 info = IEEE80211_SKB_CB(skb);
998 kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1]));
999 dev_kfree_skb_any(skb);
1000}
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7aa3060fc6b5..199a0c03774c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -74,38 +74,10 @@ struct iwl_cmd;
74 74
75#define TIME_UNIT 1024 75#define TIME_UNIT 1024
76 76
77struct iwl_lib_ops {
78 /* set hw dependent parameters */
79 void (*set_hw_params)(struct iwl_priv *priv);
80 int (*set_channel_switch)(struct iwl_priv *priv,
81 struct ieee80211_channel_switch *ch_switch);
82 /* device specific configuration */
83 void (*nic_config)(struct iwl_priv *priv);
84
85 /* eeprom operations (as defined in iwl-eeprom.h) */
86 struct iwl_eeprom_ops eeprom_ops;
87
88 /* temperature */
89 void (*temperature)(struct iwl_priv *priv);
90};
91
92/*************************** 77/***************************
93 * L i b * 78 * L i b *
94 ***************************/ 79 ***************************/
95 80
96void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
97 struct iwl_rxon_context *ctx);
98void iwl_set_flags_for_band(struct iwl_priv *priv,
99 struct iwl_rxon_context *ctx,
100 enum ieee80211_band band,
101 struct ieee80211_vif *vif);
102void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
103bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
104 struct iwl_rxon_context *ctx,
105 struct ieee80211_sta_ht_cap *ht_cap);
106void iwl_connection_init_rx_config(struct iwl_priv *priv,
107 struct iwl_rxon_context *ctx);
108void iwl_set_rate(struct iwl_priv *priv);
109int iwl_cmd_echo_test(struct iwl_priv *priv); 81int iwl_cmd_echo_test(struct iwl_priv *priv);
110#ifdef CONFIG_IWLWIFI_DEBUGFS 82#ifdef CONFIG_IWLWIFI_DEBUGFS
111int iwl_alloc_traffic_mem(struct iwl_priv *priv); 83int iwl_alloc_traffic_mem(struct iwl_priv *priv);
@@ -146,45 +118,9 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx,
146} 118}
147#endif 119#endif
148 120
149/*****************************************************
150* RX
151******************************************************/
152void iwl_chswitch_done(struct iwl_priv *priv, bool is_success);
153
154void iwl_setup_watchdog(struct iwl_priv *priv);
155/*****************************************************
156 * TX power
157 ****************************************************/
158int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
159
160/******************************************************************************* 121/*******************************************************************************
161 * Scanning 122 * Scanning
162 ******************************************************************************/ 123 ******************************************************************************/
163void iwl_init_scan_params(struct iwl_priv *priv);
164int iwl_scan_cancel(struct iwl_priv *priv);
165void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
166void iwl_force_scan_end(struct iwl_priv *priv);
167void iwl_internal_short_hw_scan(struct iwl_priv *priv);
168int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
169void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
170void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
171void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
172int __must_check iwl_scan_initiate(struct iwl_priv *priv,
173 struct ieee80211_vif *vif,
174 enum iwl_scan_type scan_type,
175 enum ieee80211_band band);
176
177/* For faster active scanning, scan will move to the next channel if fewer than
178 * PLCP_QUIET_THRESH packets are heard on this channel within
179 * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
180 * time if it's a quiet channel (nothing responded to our probe, and there's
181 * no other traffic).
182 * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
183#define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */
184#define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */
185
186#define IWL_SCAN_CHECK_WATCHDOG (HZ * 7)
187
188/* traffic log definitions */ 124/* traffic log definitions */
189#define IWL_TRAFFIC_ENTRIES (256) 125#define IWL_TRAFFIC_ENTRIES (256)
190#define IWL_TRAFFIC_ENTRY_SIZE (64) 126#define IWL_TRAFFIC_ENTRY_SIZE (64)
@@ -192,28 +128,6 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
192/***************************************************** 128/*****************************************************
193 * S e n d i n g H o s t C o m m a n d s * 129 * S e n d i n g H o s t C o m m a n d s *
194 *****************************************************/ 130 *****************************************************/
195
196void iwl_bg_watchdog(unsigned long data);
197u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval);
198__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
199 u32 addon, u32 beacon_interval);
200
201extern void iwl_send_bt_config(struct iwl_priv *priv);
202extern int iwl_send_statistics_request(struct iwl_priv *priv,
203 u8 flags, bool clear);
204
205static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
206 struct iwl_priv *priv, enum ieee80211_band band)
207{
208 return priv->hw->wiphy->bands[band];
209}
210
211static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
212{
213 return cfg(priv)->bt_params &&
214 cfg(priv)->bt_params->advanced_bt_coexist;
215}
216
217extern bool bt_siso_mode; 131extern bool bt_siso_mode;
218 132
219#endif /* __iwl_core_h__ */ 133#endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 5f96ce105f08..59750543fce7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -430,6 +430,9 @@
430#define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c) 430#define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c)
431#define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) 431#define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050)
432 432
433/* Used to enable DBGM */
434#define HBUS_TARG_TEST_REG (HBUS_BASE+0x05c)
435
433/* 436/*
434 * Per-Tx-queue write pointer (index, really!) 437 * Per-Tx-queue write pointer (index, really!)
435 * Indicates index to next TFD that driver will fill (1 past latest filled). 438 * Indicates index to next TFD that driver will fill (1 past latest filled).
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index d109d1bbb3a2..32834a797d11 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -416,7 +416,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
416 return -ENODATA; 416 return -ENODATA;
417 } 417 }
418 418
419 ptr = priv->shrd->eeprom; 419 ptr = priv->eeprom;
420 if (!ptr) { 420 if (!ptr) {
421 IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); 421 IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
422 return -ENOMEM; 422 return -ENOMEM;
@@ -428,10 +428,10 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
428 IWL_ERR(priv, "Can not allocate Buffer\n"); 428 IWL_ERR(priv, "Can not allocate Buffer\n");
429 return -ENOMEM; 429 return -ENOMEM;
430 } 430 }
431 eeprom_ver = iwl_eeprom_query16(priv->shrd, EEPROM_VERSION); 431 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
432 pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " 432 pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
433 "version: 0x%x\n", 433 "version: 0x%x\n",
434 (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) 434 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
435 ? "OTP" : "EEPROM", eeprom_ver); 435 ? "OTP" : "EEPROM", eeprom_ver);
436 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { 436 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
437 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); 437 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
@@ -526,8 +526,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
526 int pos = 0; 526 int pos = 0;
527 const size_t bufsz = sizeof(buf); 527 const size_t bufsz = sizeof(buf);
528 528
529 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
530 test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status));
531 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", 529 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
532 test_bit(STATUS_RF_KILL_HW, &priv->status)); 530 test_bit(STATUS_RF_KILL_HW, &priv->status));
533 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", 531 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
@@ -577,7 +575,7 @@ static ssize_t iwl_dbgfs_rx_handlers_read(struct file *file,
577 if (priv->rx_handlers_stats[cnt] > 0) 575 if (priv->rx_handlers_stats[cnt] > 0)
578 pos += scnprintf(buf + pos, bufsz - pos, 576 pos += scnprintf(buf + pos, bufsz - pos,
579 "\tRx handler[%36s]:\t\t %u\n", 577 "\tRx handler[%36s]:\t\t %u\n",
580 get_cmd_string(cnt), 578 iwl_dvm_get_cmd_string(cnt),
581 priv->rx_handlers_stats[cnt]); 579 priv->rx_handlers_stats[cnt]);
582 } 580 }
583 581
@@ -1541,17 +1539,17 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1541 if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { 1539 if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
1542 pos += scnprintf(buf + pos, bufsz - pos, 1540 pos += scnprintf(buf + pos, bufsz - pos,
1543 "tx power: (1/2 dB step)\n"); 1541 "tx power: (1/2 dB step)\n");
1544 if ((hw_params(priv).valid_tx_ant & ANT_A) && 1542 if ((priv->hw_params.valid_tx_ant & ANT_A) &&
1545 tx->tx_power.ant_a) 1543 tx->tx_power.ant_a)
1546 pos += scnprintf(buf + pos, bufsz - pos, 1544 pos += scnprintf(buf + pos, bufsz - pos,
1547 fmt_hex, "antenna A:", 1545 fmt_hex, "antenna A:",
1548 tx->tx_power.ant_a); 1546 tx->tx_power.ant_a);
1549 if ((hw_params(priv).valid_tx_ant & ANT_B) && 1547 if ((priv->hw_params.valid_tx_ant & ANT_B) &&
1550 tx->tx_power.ant_b) 1548 tx->tx_power.ant_b)
1551 pos += scnprintf(buf + pos, bufsz - pos, 1549 pos += scnprintf(buf + pos, bufsz - pos,
1552 fmt_hex, "antenna B:", 1550 fmt_hex, "antenna B:",
1553 tx->tx_power.ant_b); 1551 tx->tx_power.ant_b);
1554 if ((hw_params(priv).valid_tx_ant & ANT_C) && 1552 if ((priv->hw_params.valid_tx_ant & ANT_C) &&
1555 tx->tx_power.ant_c) 1553 tx->tx_power.ant_c)
1556 pos += scnprintf(buf + pos, bufsz - pos, 1554 pos += scnprintf(buf + pos, bufsz - pos,
1557 fmt_hex, "antenna C:", 1555 fmt_hex, "antenna C:",
@@ -2267,59 +2265,39 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
2267 return count; 2265 return count;
2268} 2266}
2269 2267
2270static ssize_t iwl_dbgfs_force_reset_read(struct file *file, 2268static ssize_t iwl_dbgfs_rf_reset_read(struct file *file,
2271 char __user *user_buf, 2269 char __user *user_buf,
2272 size_t count, loff_t *ppos) 2270 size_t count, loff_t *ppos)
2273{ 2271{
2274 struct iwl_priv *priv = file->private_data; 2272 struct iwl_priv *priv = file->private_data;
2275 int i, pos = 0; 2273 int pos = 0;
2276 char buf[300]; 2274 char buf[300];
2277 const size_t bufsz = sizeof(buf); 2275 const size_t bufsz = sizeof(buf);
2278 struct iwl_force_reset *force_reset; 2276 struct iwl_rf_reset *rf_reset = &priv->rf_reset;
2277
2278 pos += scnprintf(buf + pos, bufsz - pos,
2279 "RF reset statistics\n");
2280 pos += scnprintf(buf + pos, bufsz - pos,
2281 "\tnumber of reset request: %d\n",
2282 rf_reset->reset_request_count);
2283 pos += scnprintf(buf + pos, bufsz - pos,
2284 "\tnumber of reset request success: %d\n",
2285 rf_reset->reset_success_count);
2286 pos += scnprintf(buf + pos, bufsz - pos,
2287 "\tnumber of reset request reject: %d\n",
2288 rf_reset->reset_reject_count);
2279 2289
2280 for (i = 0; i < IWL_MAX_FORCE_RESET; i++) {
2281 force_reset = &priv->force_reset[i];
2282 pos += scnprintf(buf + pos, bufsz - pos,
2283 "Force reset method %d\n", i);
2284 pos += scnprintf(buf + pos, bufsz - pos,
2285 "\tnumber of reset request: %d\n",
2286 force_reset->reset_request_count);
2287 pos += scnprintf(buf + pos, bufsz - pos,
2288 "\tnumber of reset request success: %d\n",
2289 force_reset->reset_success_count);
2290 pos += scnprintf(buf + pos, bufsz - pos,
2291 "\tnumber of reset request reject: %d\n",
2292 force_reset->reset_reject_count);
2293 pos += scnprintf(buf + pos, bufsz - pos,
2294 "\treset duration: %lu\n",
2295 force_reset->reset_duration);
2296 }
2297 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2290 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2298} 2291}
2299 2292
2300static ssize_t iwl_dbgfs_force_reset_write(struct file *file, 2293static ssize_t iwl_dbgfs_rf_reset_write(struct file *file,
2301 const char __user *user_buf, 2294 const char __user *user_buf,
2302 size_t count, loff_t *ppos) { 2295 size_t count, loff_t *ppos) {
2303 2296
2304 struct iwl_priv *priv = file->private_data; 2297 struct iwl_priv *priv = file->private_data;
2305 char buf[8]; 2298 int ret;
2306 int buf_size;
2307 int reset, ret;
2308 2299
2309 memset(buf, 0, sizeof(buf)); 2300 ret = iwl_force_rf_reset(priv, true);
2310 buf_size = min(count, sizeof(buf) - 1);
2311 if (copy_from_user(buf, user_buf, buf_size))
2312 return -EFAULT;
2313 if (sscanf(buf, "%d", &reset) != 1)
2314 return -EINVAL;
2315 switch (reset) {
2316 case IWL_RF_RESET:
2317 case IWL_FW_RESET:
2318 ret = iwl_force_reset(priv, reset, true);
2319 break;
2320 default:
2321 return -EINVAL;
2322 }
2323 return ret ? ret : count; 2301 return ret ? ret : count;
2324} 2302}
2325 2303
@@ -2347,29 +2325,6 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
2347 return count; 2325 return count;
2348} 2326}
2349 2327
2350static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
2351 const char __user *user_buf,
2352 size_t count, loff_t *ppos)
2353{
2354 struct iwl_priv *priv = file->private_data;
2355 char buf[8];
2356 int buf_size;
2357 int timeout;
2358
2359 memset(buf, 0, sizeof(buf));
2360 buf_size = min(count, sizeof(buf) - 1);
2361 if (copy_from_user(buf, user_buf, buf_size))
2362 return -EFAULT;
2363 if (sscanf(buf, "%d", &timeout) != 1)
2364 return -EINVAL;
2365 if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT)
2366 timeout = IWL_DEF_WD_TIMEOUT;
2367
2368 hw_params(priv).wd_timeout = timeout;
2369 iwl_setup_watchdog(priv);
2370 return count;
2371}
2372
2373static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, 2328static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
2374 char __user *user_buf, 2329 char __user *user_buf,
2375 size_t count, loff_t *ppos) { 2330 size_t count, loff_t *ppos) {
@@ -2428,7 +2383,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
2428 if (cfg(priv)->ht_params) 2383 if (cfg(priv)->ht_params)
2429 pos += scnprintf(buf + pos, bufsz - pos, 2384 pos += scnprintf(buf + pos, bufsz - pos,
2430 "use %s for aggregation\n", 2385 "use %s for aggregation\n",
2431 (hw_params(priv).use_rts_for_aggregation) ? 2386 (priv->hw_params.use_rts_for_aggregation) ?
2432 "rts/cts" : "cts-to-self"); 2387 "rts/cts" : "cts-to-self");
2433 else 2388 else
2434 pos += scnprintf(buf + pos, bufsz - pos, "N/A"); 2389 pos += scnprintf(buf + pos, bufsz - pos, "N/A");
@@ -2455,9 +2410,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
2455 if (sscanf(buf, "%d", &rts) != 1) 2410 if (sscanf(buf, "%d", &rts) != 1)
2456 return -EINVAL; 2411 return -EINVAL;
2457 if (rts) 2412 if (rts)
2458 hw_params(priv).use_rts_for_aggregation = true; 2413 priv->hw_params.use_rts_for_aggregation = true;
2459 else 2414 else
2460 hw_params(priv).use_rts_for_aggregation = false; 2415 priv->hw_params.use_rts_for_aggregation = false;
2461 return count; 2416 return count;
2462} 2417}
2463 2418
@@ -2516,6 +2471,34 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
2516 return count; 2471 return count;
2517} 2472}
2518 2473
2474static ssize_t iwl_dbgfs_calib_disabled_read(struct file *file,
2475 char __user *user_buf,
2476 size_t count, loff_t *ppos)
2477{
2478 struct iwl_priv *priv = file->private_data;
2479 char buf[120];
2480 int pos = 0;
2481 const size_t bufsz = sizeof(buf);
2482
2483 pos += scnprintf(buf + pos, bufsz - pos,
2484 "Sensitivity calibrations %s\n",
2485 (priv->calib_disabled &
2486 IWL_SENSITIVITY_CALIB_DISABLED) ?
2487 "DISABLED" : "ENABLED");
2488 pos += scnprintf(buf + pos, bufsz - pos,
2489 "Chain noise calibrations %s\n",
2490 (priv->calib_disabled &
2491 IWL_CHAIN_NOISE_CALIB_DISABLED) ?
2492 "DISABLED" : "ENABLED");
2493 pos += scnprintf(buf + pos, bufsz - pos,
2494 "Tx power calibrations %s\n",
2495 (priv->calib_disabled &
2496 IWL_TX_POWER_CALIB_DISABLED) ?
2497 "DISABLED" : "ENABLED");
2498
2499 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2500}
2501
2519DEBUGFS_READ_FILE_OPS(rx_statistics); 2502DEBUGFS_READ_FILE_OPS(rx_statistics);
2520DEBUGFS_READ_FILE_OPS(tx_statistics); 2503DEBUGFS_READ_FILE_OPS(tx_statistics);
2521DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 2504DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -2530,17 +2513,17 @@ DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
2530DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); 2513DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
2531DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); 2514DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
2532DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); 2515DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
2533DEBUGFS_READ_WRITE_FILE_OPS(force_reset); 2516DEBUGFS_READ_WRITE_FILE_OPS(rf_reset);
2534DEBUGFS_READ_FILE_OPS(rxon_flags); 2517DEBUGFS_READ_FILE_OPS(rxon_flags);
2535DEBUGFS_READ_FILE_OPS(rxon_filter_flags); 2518DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
2536DEBUGFS_WRITE_FILE_OPS(txfifo_flush); 2519DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
2537DEBUGFS_READ_FILE_OPS(ucode_bt_stats); 2520DEBUGFS_READ_FILE_OPS(ucode_bt_stats);
2538DEBUGFS_WRITE_FILE_OPS(wd_timeout);
2539DEBUGFS_READ_FILE_OPS(bt_traffic); 2521DEBUGFS_READ_FILE_OPS(bt_traffic);
2540DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); 2522DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
2541DEBUGFS_READ_FILE_OPS(reply_tx_error); 2523DEBUGFS_READ_FILE_OPS(reply_tx_error);
2542DEBUGFS_WRITE_FILE_OPS(echo_test); 2524DEBUGFS_WRITE_FILE_OPS(echo_test);
2543DEBUGFS_READ_WRITE_FILE_OPS(log_event); 2525DEBUGFS_READ_WRITE_FILE_OPS(log_event);
2526DEBUGFS_READ_FILE_OPS(calib_disabled);
2544 2527
2545/* 2528/*
2546 * Create the debugfs files and directories 2529 * Create the debugfs files and directories
@@ -2589,7 +2572,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2589 DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); 2572 DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
2590 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); 2573 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
2591 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); 2574 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
2592 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); 2575 DEBUGFS_ADD_FILE(rf_reset, dir_debug, S_IWUSR | S_IRUSR);
2593 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); 2576 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
2594 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); 2577 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
2595 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); 2578 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
@@ -2602,17 +2585,14 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2602 DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); 2585 DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
2603 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); 2586 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
2604 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); 2587 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
2605 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
2606 DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); 2588 DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR);
2607 DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); 2589 DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR);
2608 2590
2609 if (iwl_advanced_bt_coexist(priv)) 2591 if (iwl_advanced_bt_coexist(priv))
2610 DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); 2592 DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
2611 2593
2612 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, 2594 /* Calibrations disabled/enabled status*/
2613 &priv->disable_sens_cal); 2595 DEBUGFS_ADD_FILE(calib_disabled, dir_rf, S_IRUSR);
2614 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
2615 &priv->disable_chain_noise_cal);
2616 2596
2617 if (iwl_trans_dbgfs_register(trans(priv), dir_debug)) 2597 if (iwl_trans_dbgfs_register(trans(priv), dir_debug))
2618 goto err; 2598 goto err;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 99be58940e27..c235a1ea71b4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -51,8 +51,6 @@
51#include "iwl-op-mode.h" 51#include "iwl-op-mode.h"
52#include "iwl-notif-wait.h" 52#include "iwl-notif-wait.h"
53 53
54struct iwl_tx_queue;
55
56/* CT-KILL constants */ 54/* CT-KILL constants */
57#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ 55#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */
58#define CT_KILL_THRESHOLD 114 /* in Celsius */ 56#define CT_KILL_THRESHOLD 114 /* in Celsius */
@@ -582,9 +580,9 @@ struct iwl_event_log {
582#define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0) 580#define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0)
583 581
584#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) 582#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3)
585#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
586 583
587/* TX queue watchdog timeouts in mSecs */ 584/* TX queue watchdog timeouts in mSecs */
585#define IWL_WATCHHDOG_DISABLED (0)
588#define IWL_DEF_WD_TIMEOUT (2000) 586#define IWL_DEF_WD_TIMEOUT (2000)
589#define IWL_LONG_WD_TIMEOUT (10000) 587#define IWL_LONG_WD_TIMEOUT (10000)
590#define IWL_MAX_WD_TIMEOUT (120000) 588#define IWL_MAX_WD_TIMEOUT (120000)
@@ -597,18 +595,11 @@ struct iwl_event_log {
597#define IWL_MAX_CONTINUE_RELOAD_CNT 4 595#define IWL_MAX_CONTINUE_RELOAD_CNT 4
598 596
599 597
600enum iwl_reset { 598struct iwl_rf_reset {
601 IWL_RF_RESET = 0,
602 IWL_FW_RESET,
603 IWL_MAX_FORCE_RESET,
604};
605
606struct iwl_force_reset {
607 int reset_request_count; 599 int reset_request_count;
608 int reset_success_count; 600 int reset_success_count;
609 int reset_reject_count; 601 int reset_reject_count;
610 unsigned long reset_duration; 602 unsigned long last_reset_jiffies;
611 unsigned long last_force_reset_jiffies;
612}; 603};
613 604
614/* extend beacon time format bit shifting */ 605/* extend beacon time format bit shifting */
@@ -680,6 +671,52 @@ enum iwl_scan_type {
680 IWL_SCAN_ROC, 671 IWL_SCAN_ROC,
681}; 672};
682 673
674/**
675 * struct iwl_hw_params
676 *
677 * Holds the module parameters
678 *
679 * @tx_chains_num: Number of TX chains
680 * @rx_chains_num: Number of RX chains
681 * @valid_tx_ant: usable antennas for TX
682 * @valid_rx_ant: usable antennas for RX
683 * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX)
684 * @sku: sku read from EEPROM
685 * @ct_kill_threshold: temperature threshold - in hw dependent unit
686 * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit
687 * relevant for 1000, 6000 and up
688 * @struct iwl_sensitivity_ranges: range of sensitivity values
689 * @use_rts_for_aggregation: use rts/cts protection for HT traffic
690 */
691struct iwl_hw_params {
692 u8 tx_chains_num;
693 u8 rx_chains_num;
694 u8 valid_tx_ant;
695 u8 valid_rx_ant;
696 u8 ht40_channel;
697 bool use_rts_for_aggregation;
698 u16 sku;
699 u32 ct_kill_threshold;
700 u32 ct_kill_exit_threshold;
701
702 const struct iwl_sensitivity_ranges *sens;
703};
704
705struct iwl_lib_ops {
706 /* set hw dependent parameters */
707 void (*set_hw_params)(struct iwl_priv *priv);
708 int (*set_channel_switch)(struct iwl_priv *priv,
709 struct ieee80211_channel_switch *ch_switch);
710 /* device specific configuration */
711 void (*nic_config)(struct iwl_priv *priv);
712
713 /* eeprom operations (as defined in iwl-eeprom.h) */
714 struct iwl_eeprom_ops eeprom_ops;
715
716 /* temperature */
717 void (*temperature)(struct iwl_priv *priv);
718};
719
683#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE 720#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
684struct iwl_testmode_trace { 721struct iwl_testmode_trace {
685 u32 buff_size; 722 u32 buff_size;
@@ -704,6 +741,14 @@ struct iwl_wipan_noa_data {
704 u8 data[]; 741 u8 data[];
705}; 742};
706 743
744/* Calibration disabling bit mask */
745#define IWL_SENSITIVITY_CALIB_DISABLED BIT(1)
746#define IWL_CHAIN_NOISE_CALIB_DISABLED BIT(2)
747#define IWL_TX_POWER_CALIB_DISABLED BIT(3)
748
749#define IWL_CALIB_ENABLE_ALL 0
750#define IWL_CALIB_DISABLE_ALL 0xFFFFFFFF
751
707#define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \ 752#define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \
708 ((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific)) 753 ((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific))
709 754
@@ -716,6 +761,7 @@ struct iwl_priv {
716 /*data shared among all the driver's layers */ 761 /*data shared among all the driver's layers */
717 struct iwl_shared *shrd; 762 struct iwl_shared *shrd;
718 const struct iwl_fw *fw; 763 const struct iwl_fw *fw;
764 const struct iwl_lib_ops *lib;
719 unsigned long status; 765 unsigned long status;
720 766
721 spinlock_t sta_lock; 767 spinlock_t sta_lock;
@@ -738,6 +784,8 @@ struct iwl_priv {
738 784
739 struct workqueue_struct *workqueue; 785 struct workqueue_struct *workqueue;
740 786
787 struct iwl_hw_params hw_params;
788
741 enum ieee80211_band band; 789 enum ieee80211_band band;
742 u8 valid_contexts; 790 u8 valid_contexts;
743 791
@@ -772,8 +820,8 @@ struct iwl_priv {
772 /*counters */ 820 /*counters */
773 u32 rx_handlers_stats[REPLY_MAX]; 821 u32 rx_handlers_stats[REPLY_MAX];
774 822
775 /* force reset */ 823 /* rf reset */
776 struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; 824 struct iwl_rf_reset rf_reset;
777 825
778 /* firmware reload counter and timestamp */ 826 /* firmware reload counter and timestamp */
779 unsigned long reload_jiffies; 827 unsigned long reload_jiffies;
@@ -819,8 +867,6 @@ struct iwl_priv {
819 867
820 __le16 switch_channel; 868 __le16 switch_channel;
821 869
822 u16 active_rate;
823
824 u8 start_calib; 870 u8 start_calib;
825 struct iwl_sensitivity_data sensitivity_data; 871 struct iwl_sensitivity_data sensitivity_data;
826 struct iwl_chain_noise_data chain_noise_data; 872 struct iwl_chain_noise_data chain_noise_data;
@@ -967,13 +1013,15 @@ struct iwl_priv {
967 void *wowlan_sram; 1013 void *wowlan_sram;
968#endif /* CONFIG_IWLWIFI_DEBUGFS */ 1014#endif /* CONFIG_IWLWIFI_DEBUGFS */
969 1015
1016 /* eeprom -- this is in the card's little endian byte order */
1017 u8 *eeprom;
1018 enum iwl_nvm_type nvm_device_type;
1019
970 struct work_struct txpower_work; 1020 struct work_struct txpower_work;
971 u32 disable_sens_cal; 1021 u32 calib_disabled;
972 u32 disable_chain_noise_cal;
973 struct work_struct run_time_calib_work; 1022 struct work_struct run_time_calib_work;
974 struct timer_list statistics_periodic; 1023 struct timer_list statistics_periodic;
975 struct timer_list ucode_trace; 1024 struct timer_list ucode_trace;
976 struct timer_list watchdog;
977 1025
978 struct iwl_event_log event_log; 1026 struct iwl_event_log event_log;
979 1027
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 6f312c77af5e..17485e715424 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -284,6 +284,7 @@ static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
284 284
285 sec->offset = le32_to_cpu(sec_parse->offset); 285 sec->offset = le32_to_cpu(sec_parse->offset);
286 sec->data = sec_parse->data; 286 sec->data = sec_parse->data;
287 sec->size = size - sizeof(sec_parse->offset);
287 288
288 ++img->sec_counter; 289 ++img->sec_counter;
289 290
@@ -414,9 +415,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
414 struct iwl_ucode_tlv *tlv; 415 struct iwl_ucode_tlv *tlv;
415 size_t len = ucode_raw->size; 416 size_t len = ucode_raw->size;
416 const u8 *data; 417 const u8 *data;
417 int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative;
418 int tmp;
419 u64 alternatives;
420 u32 tlv_len; 418 u32 tlv_len;
421 enum iwl_ucode_tlv_type tlv_type; 419 enum iwl_ucode_tlv_type tlv_type;
422 const u8 *tlv_data; 420 const u8 *tlv_data;
@@ -434,23 +432,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
434 return -EINVAL; 432 return -EINVAL;
435 } 433 }
436 434
437 /*
438 * Check which alternatives are present, and "downgrade"
439 * when the chosen alternative is not present, warning
440 * the user when that happens. Some files may not have
441 * any alternatives, so don't warn in that case.
442 */
443 alternatives = le64_to_cpu(ucode->alternatives);
444 tmp = wanted_alternative;
445 if (wanted_alternative > 63)
446 wanted_alternative = 63;
447 while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
448 wanted_alternative--;
449 if (wanted_alternative && wanted_alternative != tmp)
450 IWL_WARN(drv,
451 "uCode alternative %d not available, choosing %d\n",
452 tmp, wanted_alternative);
453
454 drv->fw.ucode_ver = le32_to_cpu(ucode->ver); 435 drv->fw.ucode_ver = le32_to_cpu(ucode->ver);
455 build = le32_to_cpu(ucode->build); 436 build = le32_to_cpu(ucode->build);
456 437
@@ -475,14 +456,11 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
475 len -= sizeof(*ucode); 456 len -= sizeof(*ucode);
476 457
477 while (len >= sizeof(*tlv)) { 458 while (len >= sizeof(*tlv)) {
478 u16 tlv_alt;
479
480 len -= sizeof(*tlv); 459 len -= sizeof(*tlv);
481 tlv = (void *)data; 460 tlv = (void *)data;
482 461
483 tlv_len = le32_to_cpu(tlv->length); 462 tlv_len = le32_to_cpu(tlv->length);
484 tlv_type = le16_to_cpu(tlv->type); 463 tlv_type = le32_to_cpu(tlv->type);
485 tlv_alt = le16_to_cpu(tlv->alternative);
486 tlv_data = tlv->data; 464 tlv_data = tlv->data;
487 465
488 if (len < tlv_len) { 466 if (len < tlv_len) {
@@ -493,14 +471,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
493 len -= ALIGN(tlv_len, 4); 471 len -= ALIGN(tlv_len, 4);
494 data += sizeof(*tlv) + ALIGN(tlv_len, 4); 472 data += sizeof(*tlv) + ALIGN(tlv_len, 4);
495 473
496 /*
497 * Alternative 0 is always valid.
498 *
499 * Skip alternative TLVs that are not selected.
500 */
501 if (tlv_alt != 0 && tlv_alt != wanted_alternative)
502 continue;
503
504 switch (tlv_type) { 474 switch (tlv_type) {
505 case IWL_UCODE_TLV_INST: 475 case IWL_UCODE_TLV_INST:
506 set_sec_data(pieces, IWL_UCODE_REGULAR, 476 set_sec_data(pieces, IWL_UCODE_REGULAR,
@@ -838,42 +808,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
838 IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); 808 IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version);
839 809
840 /* 810 /*
841 * For any of the failures below (before allocating pci memory)
842 * we will try to load a version with a smaller API -- maybe the
843 * user just got a corrupted version of the latest API.
844 */
845
846 IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n",
847 drv->fw.ucode_ver);
848 IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n",
849 get_sec_size(&pieces, IWL_UCODE_REGULAR,
850 IWL_UCODE_SECTION_INST));
851 IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n",
852 get_sec_size(&pieces, IWL_UCODE_REGULAR,
853 IWL_UCODE_SECTION_DATA));
854 IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n",
855 get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST));
856 IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n",
857 get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA));
858
859 /* Verify that uCode images will fit in card's SRAM */
860 if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) >
861 cfg->max_inst_size) {
862 IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n",
863 get_sec_size(&pieces, IWL_UCODE_REGULAR,
864 IWL_UCODE_SECTION_INST));
865 goto try_again;
866 }
867
868 if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) >
869 cfg->max_data_size) {
870 IWL_ERR(drv, "uCode data len %Zd too large to fit in\n",
871 get_sec_size(&pieces, IWL_UCODE_REGULAR,
872 IWL_UCODE_SECTION_DATA));
873 goto try_again;
874 }
875
876 /*
877 * In mvm uCode there is no difference between data and instructions 811 * In mvm uCode there is no difference between data and instructions
878 * sections. 812 * sections.
879 */ 813 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 23cea42b9495..a004431d1a60 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -187,33 +187,33 @@ static void iwl_eeprom_release_semaphore(struct iwl_trans *trans)
187 187
188} 188}
189 189
190static int iwl_eeprom_verify_signature(struct iwl_trans *trans) 190static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
191{ 191{
192 u32 gp = iwl_read32(trans, CSR_EEPROM_GP) & 192 u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP) &
193 CSR_EEPROM_GP_VALID_MSK; 193 CSR_EEPROM_GP_VALID_MSK;
194 int ret = 0; 194 int ret = 0;
195 195
196 IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp); 196 IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp);
197 switch (gp) { 197 switch (gp) {
198 case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: 198 case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP:
199 if (trans->nvm_device_type != NVM_DEVICE_TYPE_OTP) { 199 if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) {
200 IWL_ERR(trans, "EEPROM with bad signature: 0x%08x\n", 200 IWL_ERR(priv, "EEPROM with bad signature: 0x%08x\n",
201 gp); 201 gp);
202 ret = -ENOENT; 202 ret = -ENOENT;
203 } 203 }
204 break; 204 break;
205 case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: 205 case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K:
206 case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: 206 case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K:
207 if (trans->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { 207 if (priv->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) {
208 IWL_ERR(trans, "OTP with bad signature: 0x%08x\n", gp); 208 IWL_ERR(priv, "OTP with bad signature: 0x%08x\n", gp);
209 ret = -ENOENT; 209 ret = -ENOENT;
210 } 210 }
211 break; 211 break;
212 case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: 212 case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP:
213 default: 213 default:
214 IWL_ERR(trans, "bad EEPROM/OTP signature, type=%s, " 214 IWL_ERR(priv, "bad EEPROM/OTP signature, type=%s, "
215 "EEPROM_GP=0x%08x\n", 215 "EEPROM_GP=0x%08x\n",
216 (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) 216 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
217 ? "OTP" : "EEPROM", gp); 217 ? "OTP" : "EEPROM", gp);
218 ret = -ENOENT; 218 ret = -ENOENT;
219 break; 219 break;
@@ -221,11 +221,11 @@ static int iwl_eeprom_verify_signature(struct iwl_trans *trans)
221 return ret; 221 return ret;
222} 222}
223 223
224u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset) 224u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset)
225{ 225{
226 if (!shrd->eeprom) 226 if (!priv->eeprom)
227 return 0; 227 return 0;
228 return (u16)shrd->eeprom[offset] | ((u16)shrd->eeprom[offset + 1] << 8); 228 return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
229} 229}
230 230
231int iwl_eeprom_check_version(struct iwl_priv *priv) 231int iwl_eeprom_check_version(struct iwl_priv *priv)
@@ -233,8 +233,8 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
233 u16 eeprom_ver; 233 u16 eeprom_ver;
234 u16 calib_ver; 234 u16 calib_ver;
235 235
236 eeprom_ver = iwl_eeprom_query16(priv->shrd, EEPROM_VERSION); 236 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
237 calib_ver = iwl_eeprom_calib_version(priv->shrd); 237 calib_ver = iwl_eeprom_calib_version(priv);
238 238
239 if (eeprom_ver < cfg(priv)->eeprom_ver || 239 if (eeprom_ver < cfg(priv)->eeprom_ver ||
240 calib_ver < cfg(priv)->eeprom_calib_ver) 240 calib_ver < cfg(priv)->eeprom_calib_ver)
@@ -255,50 +255,107 @@ err:
255 255
256int iwl_eeprom_init_hw_params(struct iwl_priv *priv) 256int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
257{ 257{
258 struct iwl_shared *shrd = priv->shrd;
259 u16 radio_cfg; 258 u16 radio_cfg;
260 259
261 hw_params(priv).sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); 260 priv->hw_params.sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
262 if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE && 261 if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE &&
263 !cfg(priv)->ht_params) { 262 !cfg(priv)->ht_params) {
264 IWL_ERR(priv, "Invalid 11n configuration\n"); 263 IWL_ERR(priv, "Invalid 11n configuration\n");
265 return -EINVAL; 264 return -EINVAL;
266 } 265 }
267 266
268 if (!hw_params(priv).sku) { 267 if (!priv->hw_params.sku) {
269 IWL_ERR(priv, "Invalid device sku\n"); 268 IWL_ERR(priv, "Invalid device sku\n");
270 return -EINVAL; 269 return -EINVAL;
271 } 270 }
272 271
273 IWL_INFO(priv, "Device SKU: 0x%X\n", hw_params(priv).sku); 272 IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku);
274 273
275 radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); 274 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
276 275
277 hw_params(priv).valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); 276 priv->hw_params.valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
278 hw_params(priv).valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); 277 priv->hw_params.valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
279 278
280 /* check overrides (some devices have wrong EEPROM) */ 279 /* check overrides (some devices have wrong EEPROM) */
281 if (cfg(priv)->valid_tx_ant) 280 if (cfg(priv)->valid_tx_ant)
282 hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; 281 priv->hw_params.valid_tx_ant = cfg(priv)->valid_tx_ant;
283 if (cfg(priv)->valid_rx_ant) 282 if (cfg(priv)->valid_rx_ant)
284 hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; 283 priv->hw_params.valid_rx_ant = cfg(priv)->valid_rx_ant;
285 284
286 if (!hw_params(priv).valid_tx_ant || !hw_params(priv).valid_rx_ant) { 285 if (!priv->hw_params.valid_tx_ant || !priv->hw_params.valid_rx_ant) {
287 IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", 286 IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n",
288 hw_params(priv).valid_tx_ant, 287 priv->hw_params.valid_tx_ant,
289 hw_params(priv).valid_rx_ant); 288 priv->hw_params.valid_rx_ant);
290 return -EINVAL; 289 return -EINVAL;
291 } 290 }
292 291
293 IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", 292 IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n",
294 hw_params(priv).valid_tx_ant, hw_params(priv).valid_rx_ant); 293 priv->hw_params.valid_tx_ant, priv->hw_params.valid_rx_ant);
295 294
296 return 0; 295 return 0;
297} 296}
298 297
299void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac) 298u16 iwl_eeprom_calib_version(struct iwl_priv *priv)
300{ 299{
301 const u8 *addr = iwl_eeprom_query_addr(shrd, 300 struct iwl_eeprom_calib_hdr *hdr;
301
302 hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
303 EEPROM_CALIB_ALL);
304 return hdr->version;
305}
306
307static u32 eeprom_indirect_address(struct iwl_priv *priv, u32 address)
308{
309 u16 offset = 0;
310
311 if ((address & INDIRECT_ADDRESS) == 0)
312 return address;
313
314 switch (address & INDIRECT_TYPE_MSK) {
315 case INDIRECT_HOST:
316 offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST);
317 break;
318 case INDIRECT_GENERAL:
319 offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL);
320 break;
321 case INDIRECT_REGULATORY:
322 offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY);
323 break;
324 case INDIRECT_TXP_LIMIT:
325 offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT);
326 break;
327 case INDIRECT_TXP_LIMIT_SIZE:
328 offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE);
329 break;
330 case INDIRECT_CALIBRATION:
331 offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION);
332 break;
333 case INDIRECT_PROCESS_ADJST:
334 offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST);
335 break;
336 case INDIRECT_OTHERS:
337 offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS);
338 break;
339 default:
340 IWL_ERR(priv, "illegal indirect type: 0x%X\n",
341 address & INDIRECT_TYPE_MSK);
342 break;
343 }
344
345 /* translate the offset from words to byte */
346 return (address & ADDRESS_MSK) + (offset << 1);
347}
348
349const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset)
350{
351 u32 address = eeprom_indirect_address(priv, offset);
352 BUG_ON(address >= cfg(priv)->base_params->eeprom_size);
353 return &priv->eeprom[address];
354}
355
356void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac)
357{
358 const u8 *addr = iwl_eeprom_query_addr(priv,
302 EEPROM_MAC_ADDRESS); 359 EEPROM_MAC_ADDRESS);
303 memcpy(mac, addr, ETH_ALEN); 360 memcpy(mac, addr, ETH_ALEN);
304} 361}
@@ -591,7 +648,6 @@ iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv,
591 648
592static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) 649static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
593{ 650{
594 struct iwl_shared *shrd = priv->shrd;
595 struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; 651 struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
596 int idx, entries; 652 int idx, entries;
597 __le16 *txp_len; 653 __le16 *txp_len;
@@ -600,10 +656,10 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
600 BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); 656 BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8);
601 657
602 /* the length is in 16-bit words, but we want entries */ 658 /* the length is in 16-bit words, but we want entries */
603 txp_len = (__le16 *) iwl_eeprom_query_addr(shrd, EEPROM_TXP_SZ_OFFS); 659 txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS);
604 entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; 660 entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN;
605 661
606 txp_array = (void *) iwl_eeprom_query_addr(shrd, EEPROM_TXP_OFFS); 662 txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS);
607 663
608 for (idx = 0; idx < entries; idx++) { 664 for (idx = 0; idx < entries; idx++) {
609 txp = &txp_array[idx]; 665 txp = &txp_array[idx];
@@ -656,66 +712,66 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
656/** 712/**
657 * iwl_eeprom_init - read EEPROM contents 713 * iwl_eeprom_init - read EEPROM contents
658 * 714 *
659 * Load the EEPROM contents from adapter into shrd->eeprom 715 * Load the EEPROM contents from adapter into priv->eeprom
660 * 716 *
661 * NOTE: This routine uses the non-debug IO access functions. 717 * NOTE: This routine uses the non-debug IO access functions.
662 */ 718 */
663int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev) 719int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
664{ 720{
665 __le16 *e; 721 __le16 *e;
666 u32 gp = iwl_read32(trans, CSR_EEPROM_GP); 722 u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP);
667 int sz; 723 int sz;
668 int ret; 724 int ret;
669 u16 addr; 725 u16 addr;
670 u16 validblockaddr = 0; 726 u16 validblockaddr = 0;
671 u16 cache_addr = 0; 727 u16 cache_addr = 0;
672 728
673 trans->nvm_device_type = iwl_get_nvm_type(trans, hw_rev); 729 priv->nvm_device_type = iwl_get_nvm_type(trans(priv), hw_rev);
674 if (trans->nvm_device_type == -ENOENT) 730 if (priv->nvm_device_type == -ENOENT)
675 return -ENOENT; 731 return -ENOENT;
676 /* allocate eeprom */ 732 /* allocate eeprom */
677 sz = cfg(trans)->base_params->eeprom_size; 733 sz = cfg(priv)->base_params->eeprom_size;
678 IWL_DEBUG_EEPROM(trans, "NVM size = %d\n", sz); 734 IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz);
679 trans->shrd->eeprom = kzalloc(sz, GFP_KERNEL); 735 priv->eeprom = kzalloc(sz, GFP_KERNEL);
680 if (!trans->shrd->eeprom) { 736 if (!priv->eeprom) {
681 ret = -ENOMEM; 737 ret = -ENOMEM;
682 goto alloc_err; 738 goto alloc_err;
683 } 739 }
684 e = (__le16 *)trans->shrd->eeprom; 740 e = (__le16 *)priv->eeprom;
685 741
686 ret = iwl_eeprom_verify_signature(trans); 742 ret = iwl_eeprom_verify_signature(priv);
687 if (ret < 0) { 743 if (ret < 0) {
688 IWL_ERR(trans, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); 744 IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
689 ret = -ENOENT; 745 ret = -ENOENT;
690 goto err; 746 goto err;
691 } 747 }
692 748
693 /* Make sure driver (instead of uCode) is allowed to read EEPROM */ 749 /* Make sure driver (instead of uCode) is allowed to read EEPROM */
694 ret = iwl_eeprom_acquire_semaphore(trans); 750 ret = iwl_eeprom_acquire_semaphore(trans(priv));
695 if (ret < 0) { 751 if (ret < 0) {
696 IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n"); 752 IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
697 ret = -ENOENT; 753 ret = -ENOENT;
698 goto err; 754 goto err;
699 } 755 }
700 756
701 if (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) { 757 if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
702 758
703 ret = iwl_init_otp_access(trans); 759 ret = iwl_init_otp_access(trans(priv));
704 if (ret) { 760 if (ret) {
705 IWL_ERR(trans, "Failed to initialize OTP access.\n"); 761 IWL_ERR(priv, "Failed to initialize OTP access.\n");
706 ret = -ENOENT; 762 ret = -ENOENT;
707 goto done; 763 goto done;
708 } 764 }
709 iwl_write32(trans, CSR_EEPROM_GP, 765 iwl_write32(trans(priv), CSR_EEPROM_GP,
710 iwl_read32(trans, CSR_EEPROM_GP) & 766 iwl_read32(trans(priv), CSR_EEPROM_GP) &
711 ~CSR_EEPROM_GP_IF_OWNER_MSK); 767 ~CSR_EEPROM_GP_IF_OWNER_MSK);
712 768
713 iwl_set_bit(trans, CSR_OTP_GP_REG, 769 iwl_set_bit(trans(priv), CSR_OTP_GP_REG,
714 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | 770 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
715 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); 771 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
716 /* traversing the linked list if no shadow ram supported */ 772 /* traversing the linked list if no shadow ram supported */
717 if (!cfg(trans)->base_params->shadow_ram_support) { 773 if (!cfg(priv)->base_params->shadow_ram_support) {
718 if (iwl_find_otp_image(trans, &validblockaddr)) { 774 if (iwl_find_otp_image(trans(priv), &validblockaddr)) {
719 ret = -ENOENT; 775 ret = -ENOENT;
720 goto done; 776 goto done;
721 } 777 }
@@ -724,7 +780,8 @@ int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev)
724 addr += sizeof(u16)) { 780 addr += sizeof(u16)) {
725 __le16 eeprom_data; 781 __le16 eeprom_data;
726 782
727 ret = iwl_read_otp_word(trans, addr, &eeprom_data); 783 ret = iwl_read_otp_word(trans(priv), addr,
784 &eeprom_data);
728 if (ret) 785 if (ret)
729 goto done; 786 goto done;
730 e[cache_addr / 2] = eeprom_data; 787 e[cache_addr / 2] = eeprom_data;
@@ -735,94 +792,93 @@ int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev)
735 for (addr = 0; addr < sz; addr += sizeof(u16)) { 792 for (addr = 0; addr < sz; addr += sizeof(u16)) {
736 u32 r; 793 u32 r;
737 794
738 iwl_write32(trans, CSR_EEPROM_REG, 795 iwl_write32(trans(priv), CSR_EEPROM_REG,
739 CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 796 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
740 797
741 ret = iwl_poll_bit(trans, CSR_EEPROM_REG, 798 ret = iwl_poll_bit(trans(priv), CSR_EEPROM_REG,
742 CSR_EEPROM_REG_READ_VALID_MSK, 799 CSR_EEPROM_REG_READ_VALID_MSK,
743 CSR_EEPROM_REG_READ_VALID_MSK, 800 CSR_EEPROM_REG_READ_VALID_MSK,
744 IWL_EEPROM_ACCESS_TIMEOUT); 801 IWL_EEPROM_ACCESS_TIMEOUT);
745 if (ret < 0) { 802 if (ret < 0) {
746 IWL_ERR(trans, 803 IWL_ERR(priv,
747 "Time out reading EEPROM[%d]\n", addr); 804 "Time out reading EEPROM[%d]\n", addr);
748 goto done; 805 goto done;
749 } 806 }
750 r = iwl_read32(trans, CSR_EEPROM_REG); 807 r = iwl_read32(trans(priv), CSR_EEPROM_REG);
751 e[addr / 2] = cpu_to_le16(r >> 16); 808 e[addr / 2] = cpu_to_le16(r >> 16);
752 } 809 }
753 } 810 }
754 811
755 IWL_DEBUG_EEPROM(trans, "NVM Type: %s, version: 0x%x\n", 812 IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n",
756 (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) 813 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
757 ? "OTP" : "EEPROM", 814 ? "OTP" : "EEPROM",
758 iwl_eeprom_query16(trans->shrd, EEPROM_VERSION)); 815 iwl_eeprom_query16(priv, EEPROM_VERSION));
759 816
760 ret = 0; 817 ret = 0;
761done: 818done:
762 iwl_eeprom_release_semaphore(trans); 819 iwl_eeprom_release_semaphore(trans(priv));
763 820
764err: 821err:
765 if (ret) 822 if (ret)
766 iwl_eeprom_free(trans->shrd); 823 iwl_eeprom_free(priv);
767alloc_err: 824alloc_err:
768 return ret; 825 return ret;
769} 826}
770 827
771void iwl_eeprom_free(struct iwl_shared *shrd) 828void iwl_eeprom_free(struct iwl_priv *priv)
772{ 829{
773 kfree(shrd->eeprom); 830 kfree(priv->eeprom);
774 shrd->eeprom = NULL; 831 priv->eeprom = NULL;
775} 832}
776 833
777static void iwl_init_band_reference(const struct iwl_priv *priv, 834static void iwl_init_band_reference(struct iwl_priv *priv,
778 int eep_band, int *eeprom_ch_count, 835 int eep_band, int *eeprom_ch_count,
779 const struct iwl_eeprom_channel **eeprom_ch_info, 836 const struct iwl_eeprom_channel **eeprom_ch_info,
780 const u8 **eeprom_ch_index) 837 const u8 **eeprom_ch_index)
781{ 838{
782 struct iwl_shared *shrd = priv->shrd; 839 u32 offset = priv->lib->
783 u32 offset = cfg(priv)->lib->
784 eeprom_ops.regulatory_bands[eep_band - 1]; 840 eeprom_ops.regulatory_bands[eep_band - 1];
785 switch (eep_band) { 841 switch (eep_band) {
786 case 1: /* 2.4GHz band */ 842 case 1: /* 2.4GHz band */
787 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); 843 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1);
788 *eeprom_ch_info = (struct iwl_eeprom_channel *) 844 *eeprom_ch_info = (struct iwl_eeprom_channel *)
789 iwl_eeprom_query_addr(shrd, offset); 845 iwl_eeprom_query_addr(priv, offset);
790 *eeprom_ch_index = iwl_eeprom_band_1; 846 *eeprom_ch_index = iwl_eeprom_band_1;
791 break; 847 break;
792 case 2: /* 4.9GHz band */ 848 case 2: /* 4.9GHz band */
793 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); 849 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2);
794 *eeprom_ch_info = (struct iwl_eeprom_channel *) 850 *eeprom_ch_info = (struct iwl_eeprom_channel *)
795 iwl_eeprom_query_addr(shrd, offset); 851 iwl_eeprom_query_addr(priv, offset);
796 *eeprom_ch_index = iwl_eeprom_band_2; 852 *eeprom_ch_index = iwl_eeprom_band_2;
797 break; 853 break;
798 case 3: /* 5.2GHz band */ 854 case 3: /* 5.2GHz band */
799 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); 855 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3);
800 *eeprom_ch_info = (struct iwl_eeprom_channel *) 856 *eeprom_ch_info = (struct iwl_eeprom_channel *)
801 iwl_eeprom_query_addr(shrd, offset); 857 iwl_eeprom_query_addr(priv, offset);
802 *eeprom_ch_index = iwl_eeprom_band_3; 858 *eeprom_ch_index = iwl_eeprom_band_3;
803 break; 859 break;
804 case 4: /* 5.5GHz band */ 860 case 4: /* 5.5GHz band */
805 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); 861 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4);
806 *eeprom_ch_info = (struct iwl_eeprom_channel *) 862 *eeprom_ch_info = (struct iwl_eeprom_channel *)
807 iwl_eeprom_query_addr(shrd, offset); 863 iwl_eeprom_query_addr(priv, offset);
808 *eeprom_ch_index = iwl_eeprom_band_4; 864 *eeprom_ch_index = iwl_eeprom_band_4;
809 break; 865 break;
810 case 5: /* 5.7GHz band */ 866 case 5: /* 5.7GHz band */
811 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); 867 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5);
812 *eeprom_ch_info = (struct iwl_eeprom_channel *) 868 *eeprom_ch_info = (struct iwl_eeprom_channel *)
813 iwl_eeprom_query_addr(shrd, offset); 869 iwl_eeprom_query_addr(priv, offset);
814 *eeprom_ch_index = iwl_eeprom_band_5; 870 *eeprom_ch_index = iwl_eeprom_band_5;
815 break; 871 break;
816 case 6: /* 2.4GHz ht40 channels */ 872 case 6: /* 2.4GHz ht40 channels */
817 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); 873 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6);
818 *eeprom_ch_info = (struct iwl_eeprom_channel *) 874 *eeprom_ch_info = (struct iwl_eeprom_channel *)
819 iwl_eeprom_query_addr(shrd, offset); 875 iwl_eeprom_query_addr(priv, offset);
820 *eeprom_ch_index = iwl_eeprom_band_6; 876 *eeprom_ch_index = iwl_eeprom_band_6;
821 break; 877 break;
822 case 7: /* 5 GHz ht40 channels */ 878 case 7: /* 5 GHz ht40 channels */
823 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); 879 *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7);
824 *eeprom_ch_info = (struct iwl_eeprom_channel *) 880 *eeprom_ch_info = (struct iwl_eeprom_channel *)
825 iwl_eeprom_query_addr(shrd, offset); 881 iwl_eeprom_query_addr(priv, offset);
826 *eeprom_ch_index = iwl_eeprom_band_7; 882 *eeprom_ch_index = iwl_eeprom_band_7;
827 break; 883 break;
828 default: 884 default:
@@ -987,9 +1043,9 @@ int iwl_init_channel_map(struct iwl_priv *priv)
987 } 1043 }
988 1044
989 /* Check if we do have HT40 channels */ 1045 /* Check if we do have HT40 channels */
990 if (cfg(priv)->lib->eeprom_ops.regulatory_bands[5] == 1046 if (priv->lib->eeprom_ops.regulatory_bands[5] ==
991 EEPROM_REGULATORY_BAND_NO_HT40 && 1047 EEPROM_REGULATORY_BAND_NO_HT40 &&
992 cfg(priv)->lib->eeprom_ops.regulatory_bands[6] == 1048 priv->lib->eeprom_ops.regulatory_bands[6] ==
993 EEPROM_REGULATORY_BAND_NO_HT40) 1049 EEPROM_REGULATORY_BAND_NO_HT40)
994 return 0; 1050 return 0;
995 1051
@@ -1025,7 +1081,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
1025 * driver need to process addition information 1081 * driver need to process addition information
1026 * to determine the max channel tx power limits 1082 * to determine the max channel tx power limits
1027 */ 1083 */
1028 if (cfg(priv)->lib->eeprom_ops.enhanced_txpower) 1084 if (priv->lib->eeprom_ops.enhanced_txpower)
1029 iwl_eeprom_enhanced_txpower(priv); 1085 iwl_eeprom_enhanced_txpower(priv);
1030 1086
1031 return 0; 1087 return 0;
@@ -1072,7 +1128,7 @@ void iwl_rf_config(struct iwl_priv *priv)
1072{ 1128{
1073 u16 radio_cfg; 1129 u16 radio_cfg;
1074 1130
1075 radio_cfg = iwl_eeprom_query16(priv->shrd, EEPROM_RADIO_CONFIG); 1131 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
1076 1132
1077 /* write radio config values to register */ 1133 /* write radio config values to register */
1078 if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { 1134 if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index e4a758340996..b3a3b1f0fdc4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -66,8 +66,6 @@
66#include <net/mac80211.h> 66#include <net/mac80211.h>
67 67
68struct iwl_priv; 68struct iwl_priv;
69struct iwl_shared;
70struct iwl_trans;
71 69
72/* 70/*
73 * EEPROM access time values: 71 * EEPROM access time values:
@@ -306,12 +304,14 @@ struct iwl_eeprom_ops {
306}; 304};
307 305
308 306
309int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev); 307int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev);
310void iwl_eeprom_free(struct iwl_shared *shrd); 308void iwl_eeprom_free(struct iwl_priv *priv);
311int iwl_eeprom_check_version(struct iwl_priv *priv); 309int iwl_eeprom_check_version(struct iwl_priv *priv);
312int iwl_eeprom_init_hw_params(struct iwl_priv *priv); 310int iwl_eeprom_init_hw_params(struct iwl_priv *priv);
313const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset); 311u16 iwl_eeprom_calib_version(struct iwl_priv *priv);
314u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset); 312const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset);
313u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset);
314void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac);
315int iwl_init_channel_map(struct iwl_priv *priv); 315int iwl_init_channel_map(struct iwl_priv *priv);
316void iwl_free_channel_map(struct iwl_priv *priv); 316void iwl_free_channel_map(struct iwl_priv *priv);
317const struct iwl_channel_info *iwl_get_channel_info( 317const struct iwl_channel_info *iwl_get_channel_info(
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index c924ccb93c8c..e71564053e7f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -93,15 +93,7 @@ struct iwl_ucode_header {
93 * new TLV uCode file layout 93 * new TLV uCode file layout
94 * 94 *
95 * The new TLV file format contains TLVs, that each specify 95 * The new TLV file format contains TLVs, that each specify
96 * some piece of data. To facilitate "groups", for example 96 * some piece of data.
97 * different instruction image with different capabilities,
98 * bundled with the same init image, an alternative mechanism
99 * is provided:
100 * When the alternative field is 0, that means that the item
101 * is always valid. When it is non-zero, then it is only
102 * valid in conjunction with items of the same alternative,
103 * in which case the driver (user) selects one alternative
104 * to use.
105 */ 97 */
106 98
107enum iwl_ucode_tlv_type { 99enum iwl_ucode_tlv_type {
@@ -132,8 +124,7 @@ enum iwl_ucode_tlv_type {
132}; 124};
133 125
134struct iwl_ucode_tlv { 126struct iwl_ucode_tlv {
135 __le16 type; /* see above */ 127 __le32 type; /* see above */
136 __le16 alternative; /* see comment */
137 __le32 length; /* not including type/length fields */ 128 __le32 length; /* not including type/length fields */
138 u8 data[0]; 129 u8 data[0];
139}; 130};
@@ -152,7 +143,7 @@ struct iwl_tlv_ucode_header {
152 u8 human_readable[64]; 143 u8 human_readable[64];
153 __le32 ver; /* major/minor/API/serial */ 144 __le32 ver; /* major/minor/API/serial */
154 __le32 build; 145 __le32 build;
155 __le64 alternatives; /* bitmask of valid alternatives */ 146 __le64 ignore;
156 /* 147 /*
157 * The data contained herein has a TLV layout, 148 * The data contained herein has a TLV layout,
158 * see above for the TLV header and types. 149 * see above for the TLV header and types.
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
index f1c675a2a6f3..3f82ff4f3afe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c
+++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
@@ -160,7 +160,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
160 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 160 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
161 IEEE80211_HW_SCAN_WHILE_IDLE; 161 IEEE80211_HW_SCAN_WHILE_IDLE;
162 162
163 if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) 163 if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)
164 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 164 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
165 IEEE80211_HW_SUPPORTS_STATIC_SMPS; 165 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
166 166
@@ -333,7 +333,7 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
333 return 0; 333 return 0;
334} 334}
335 335
336static void iwlagn_mac_stop(struct ieee80211_hw *hw) 336void iwlagn_mac_stop(struct ieee80211_hw *hw)
337{ 337{
338 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 338 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
339 339
@@ -361,9 +361,9 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
361 IWL_DEBUG_MAC80211(priv, "leave\n"); 361 IWL_DEBUG_MAC80211(priv, "leave\n");
362} 362}
363 363
364static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, 364void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
365 struct ieee80211_vif *vif, 365 struct ieee80211_vif *vif,
366 struct cfg80211_gtk_rekey_data *data) 366 struct cfg80211_gtk_rekey_data *data)
367{ 367{
368 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 368 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
369 369
@@ -389,8 +389,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
389 389
390#ifdef CONFIG_PM_SLEEP 390#ifdef CONFIG_PM_SLEEP
391 391
392static int iwlagn_mac_suspend(struct ieee80211_hw *hw, 392int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
393 struct cfg80211_wowlan *wowlan)
394{ 393{
395 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 394 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
396 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 395 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
@@ -499,7 +498,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
499 498
500#endif 499#endif
501 500
502static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 501void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
503{ 502{
504 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 503 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
505 504
@@ -510,21 +509,21 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
510 dev_kfree_skb_any(skb); 509 dev_kfree_skb_any(skb);
511} 510}
512 511
513static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, 512void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
514 struct ieee80211_vif *vif, 513 struct ieee80211_vif *vif,
515 struct ieee80211_key_conf *keyconf, 514 struct ieee80211_key_conf *keyconf,
516 struct ieee80211_sta *sta, 515 struct ieee80211_sta *sta,
517 u32 iv32, u16 *phase1key) 516 u32 iv32, u16 *phase1key)
518{ 517{
519 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 518 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
520 519
521 iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); 520 iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key);
522} 521}
523 522
524static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 523int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
525 struct ieee80211_vif *vif, 524 struct ieee80211_vif *vif,
526 struct ieee80211_sta *sta, 525 struct ieee80211_sta *sta,
527 struct ieee80211_key_conf *key) 526 struct ieee80211_key_conf *key)
528{ 527{
529 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 528 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
530 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 529 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -624,11 +623,11 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
624 return ret; 623 return ret;
625} 624}
626 625
627static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, 626int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
628 struct ieee80211_vif *vif, 627 struct ieee80211_vif *vif,
629 enum ieee80211_ampdu_mlme_action action, 628 enum ieee80211_ampdu_mlme_action action,
630 struct ieee80211_sta *sta, u16 tid, u16 *ssn, 629 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
631 u8 buf_size) 630 u8 buf_size)
632{ 631{
633 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 632 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
634 int ret = -EINVAL; 633 int ret = -EINVAL;
@@ -637,7 +636,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
637 IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", 636 IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
638 sta->addr, tid); 637 sta->addr, tid);
639 638
640 if (!(hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)) 639 if (!(priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE))
641 return -EACCES; 640 return -EACCES;
642 641
643 IWL_DEBUG_MAC80211(priv, "enter\n"); 642 IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -671,7 +670,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
671 priv->agg_tids_count); 670 priv->agg_tids_count);
672 } 671 }
673 if (!priv->agg_tids_count && 672 if (!priv->agg_tids_count &&
674 hw_params(priv).use_rts_for_aggregation) { 673 priv->hw_params.use_rts_for_aggregation) {
675 /* 674 /*
676 * switch off RTS/CTS if it was previously enabled 675 * switch off RTS/CTS if it was previously enabled
677 */ 676 */
@@ -750,11 +749,11 @@ static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
750 return ret; 749 return ret;
751} 750}
752 751
753static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, 752int iwlagn_mac_sta_state(struct ieee80211_hw *hw,
754 struct ieee80211_vif *vif, 753 struct ieee80211_vif *vif,
755 struct ieee80211_sta *sta, 754 struct ieee80211_sta *sta,
756 enum ieee80211_sta_state old_state, 755 enum ieee80211_sta_state old_state,
757 enum ieee80211_sta_state new_state) 756 enum ieee80211_sta_state new_state)
758{ 757{
759 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 758 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
760 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 759 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -833,8 +832,8 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw,
833 return ret; 832 return ret;
834} 833}
835 834
836static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, 835void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
837 struct ieee80211_channel_switch *ch_switch) 836 struct ieee80211_channel_switch *ch_switch)
838{ 837{
839 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 838 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
840 const struct iwl_channel_info *ch_info; 839 const struct iwl_channel_info *ch_info;
@@ -867,7 +866,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
867 if (!iwl_is_associated_ctx(ctx)) 866 if (!iwl_is_associated_ctx(ctx))
868 goto out; 867 goto out;
869 868
870 if (!cfg(priv)->lib->set_channel_switch) 869 if (!priv->lib->set_channel_switch)
871 goto out; 870 goto out;
872 871
873 ch = channel->hw_value; 872 ch = channel->hw_value;
@@ -903,7 +902,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
903 */ 902 */
904 set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); 903 set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
905 priv->switch_channel = cpu_to_le16(ch); 904 priv->switch_channel = cpu_to_le16(ch);
906 if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { 905 if (priv->lib->set_channel_switch(priv, ch_switch)) {
907 clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); 906 clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
908 priv->switch_channel = 0; 907 priv->switch_channel = 0;
909 ieee80211_chswitch_done(ctx->vif, false); 908 ieee80211_chswitch_done(ctx->vif, false);
@@ -914,10 +913,25 @@ out:
914 IWL_DEBUG_MAC80211(priv, "leave\n"); 913 IWL_DEBUG_MAC80211(priv, "leave\n");
915} 914}
916 915
917static void iwlagn_configure_filter(struct ieee80211_hw *hw, 916void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
918 unsigned int changed_flags, 917{
919 unsigned int *total_flags, 918 /*
920 u64 multicast) 919 * MULTI-FIXME
920 * See iwlagn_mac_channel_switch.
921 */
922 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
923
924 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
925 return;
926
927 if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
928 ieee80211_chswitch_done(ctx->vif, is_success);
929}
930
931void iwlagn_configure_filter(struct ieee80211_hw *hw,
932 unsigned int changed_flags,
933 unsigned int *total_flags,
934 u64 multicast)
921{ 935{
922 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 936 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
923 __le32 filter_or = 0, filter_nand = 0; 937 __le32 filter_or = 0, filter_nand = 0;
@@ -964,7 +978,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
964 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; 978 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
965} 979}
966 980
967static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) 981void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
968{ 982{
969 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 983 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
970 984
@@ -1091,7 +1105,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
1091 return err; 1105 return err;
1092} 1106}
1093 1107
1094static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) 1108int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
1095{ 1109{
1096 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1110 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1097 1111
@@ -1108,8 +1122,8 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
1108 return 0; 1122 return 0;
1109} 1123}
1110 1124
1111static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, 1125void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
1112 enum ieee80211_rssi_event rssi_event) 1126 enum ieee80211_rssi_event rssi_event)
1113{ 1127{
1114 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1128 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1115 1129
@@ -1133,8 +1147,8 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
1133 IWL_DEBUG_MAC80211(priv, "leave\n"); 1147 IWL_DEBUG_MAC80211(priv, "leave\n");
1134} 1148}
1135 1149
1136static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, 1150int iwlagn_mac_set_tim(struct ieee80211_hw *hw,
1137 struct ieee80211_sta *sta, bool set) 1151 struct ieee80211_sta *sta, bool set)
1138{ 1152{
1139 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1153 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1140 1154
@@ -1143,9 +1157,9 @@ static int iwlagn_mac_set_tim(struct ieee80211_hw *hw,
1143 return 0; 1157 return 0;
1144} 1158}
1145 1159
1146static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, 1160int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
1147 struct ieee80211_vif *vif, u16 queue, 1161 struct ieee80211_vif *vif, u16 queue,
1148 const struct ieee80211_tx_queue_params *params) 1162 const struct ieee80211_tx_queue_params *params)
1149{ 1163{
1150 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1164 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1151 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 1165 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -1187,7 +1201,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
1187 return 0; 1201 return 0;
1188} 1202}
1189 1203
1190static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) 1204int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw)
1191{ 1205{
1192 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1206 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1193 1207
@@ -1203,8 +1217,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1203 return iwlagn_commit_rxon(priv, ctx); 1217 return iwlagn_commit_rxon(priv, ctx);
1204} 1218}
1205 1219
1206static int iwl_setup_interface(struct iwl_priv *priv, 1220int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1207 struct iwl_rxon_context *ctx)
1208{ 1221{
1209 struct ieee80211_vif *vif = ctx->vif; 1222 struct ieee80211_vif *vif = ctx->vif;
1210 int err; 1223 int err;
@@ -1307,9 +1320,9 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
1307 return err; 1320 return err;
1308} 1321}
1309 1322
1310static void iwl_teardown_interface(struct iwl_priv *priv, 1323void iwl_teardown_interface(struct iwl_priv *priv,
1311 struct ieee80211_vif *vif, 1324 struct ieee80211_vif *vif,
1312 bool mode_change) 1325 bool mode_change)
1313{ 1326{
1314 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); 1327 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1315 1328
@@ -1450,9 +1463,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
1450 return err; 1463 return err;
1451} 1464}
1452 1465
1453static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, 1466int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
1454 struct ieee80211_vif *vif, 1467 struct ieee80211_vif *vif,
1455 struct cfg80211_scan_request *req) 1468 struct cfg80211_scan_request *req)
1456{ 1469{
1457 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1470 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1458 int ret; 1471 int ret;
@@ -1507,7 +1520,7 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1507 iwl_send_add_sta(priv, &cmd, CMD_ASYNC); 1520 iwl_send_add_sta(priv, &cmd, CMD_ASYNC);
1508} 1521}
1509 1522
1510static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, 1523void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
1511 struct ieee80211_vif *vif, 1524 struct ieee80211_vif *vif,
1512 enum sta_notify_cmd cmd, 1525 enum sta_notify_cmd cmd,
1513 struct ieee80211_sta *sta) 1526 struct ieee80211_sta *sta)
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
index b1fd251e88d5..ca947aebb727 100644
--- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
@@ -125,6 +125,7 @@ struct iwl_fw;
125 * @cmd_queue_full: Called when the command queue gets full. Must be atomic. 125 * @cmd_queue_full: Called when the command queue gets full. Must be atomic.
126 * @nic_config: configure NIC, called before firmware is started. 126 * @nic_config: configure NIC, called before firmware is started.
127 * May sleep 127 * May sleep
128 * @wimax_active: invoked when WiMax becomes active. Must be atomic.
128 */ 129 */
129struct iwl_op_mode_ops { 130struct iwl_op_mode_ops {
130 struct iwl_op_mode *(*start)(struct iwl_trans *trans, 131 struct iwl_op_mode *(*start)(struct iwl_trans *trans,
@@ -139,6 +140,7 @@ struct iwl_op_mode_ops {
139 void (*nic_error)(struct iwl_op_mode *op_mode); 140 void (*nic_error)(struct iwl_op_mode *op_mode);
140 void (*cmd_queue_full)(struct iwl_op_mode *op_mode); 141 void (*cmd_queue_full)(struct iwl_op_mode *op_mode);
141 void (*nic_config)(struct iwl_op_mode *op_mode); 142 void (*nic_config)(struct iwl_op_mode *op_mode);
143 void (*wimax_active)(struct iwl_op_mode *op_mode);
142}; 144};
143 145
144/** 146/**
@@ -209,6 +211,11 @@ static inline void iwl_op_mode_nic_config(struct iwl_op_mode *op_mode)
209 op_mode->ops->nic_config(op_mode); 211 op_mode->ops->nic_config(op_mode);
210} 212}
211 213
214static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode)
215{
216 op_mode->ops->wimax_active(op_mode);
217}
218
212/***************************************************** 219/*****************************************************
213* Op mode layers implementations 220* Op mode layers implementations
214******************************************************/ 221******************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c
index f3e56b04d775..754001581340 100644
--- a/drivers/net/wireless/iwlwifi/iwl-pci.c
+++ b/drivers/net/wireless/iwlwifi/iwl-pci.c
@@ -67,10 +67,8 @@
67#include <linux/pci.h> 67#include <linux/pci.h>
68#include <linux/pci-aspm.h> 68#include <linux/pci-aspm.h>
69 69
70#include "iwl-io.h"
71#include "iwl-shared.h" 70#include "iwl-shared.h"
72#include "iwl-trans.h" 71#include "iwl-trans.h"
73#include "iwl-csr.h"
74#include "iwl-cfg.h" 72#include "iwl-cfg.h"
75#include "iwl-drv.h" 73#include "iwl-drv.h"
76#include "iwl-trans.h" 74#include "iwl-trans.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
index d65305d08ebf..1a791af82d15 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
@@ -228,8 +228,24 @@ static u16 channel_id_to_papd(u16 ch_id)
228 228
229static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id) 229static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id)
230{ 230{
231 /* TODO David*/ 231 struct iwl_phy_db_chg_txp *txp_chg;
232 return 0; 232 int i;
233 u8 ch_index = ch_id_to_ch_index(ch_id);
234 if (ch_index == 0xff)
235 return 0xff;
236
237 for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) {
238 txp_chg = (void *)phy_db->calib_ch_group_txp[i].data;
239 if (!txp_chg)
240 return 0xff;
241 /*
242 * Looking for the first channel group that its max channel is
243 * higher then wanted channel.
244 */
245 if (le16_to_cpu(txp_chg->max_channel_idx) >= ch_index)
246 return i;
247 }
248 return 0xff;
233} 249}
234 250
235int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, 251int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
index ba91a8b28398..5e86305de66a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
@@ -108,6 +108,12 @@ enum iwl_phy_db_section_type {
108 IWL_PHY_DB_MAX 108 IWL_PHY_DB_MAX
109}; 109};
110 110
111/* for parsing of tx power channel group data that comes from the firmware*/
112struct iwl_phy_db_chg_txp {
113 __le32 space;
114 __le16 max_channel_idx;
115} __packed;
116
111struct iwl_phy_db *iwl_phy_db_init(struct iwl_shared *shrd); 117struct iwl_phy_db *iwl_phy_db_init(struct iwl_shared *shrd);
112 118
113void iwl_phy_db_free(struct iwl_phy_db *phy_db); 119void iwl_phy_db_free(struct iwl_phy_db *phy_db);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 7bc7a82aba47..174a0f737214 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -268,61 +268,6 @@ static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv,
268 IWL_DEBUG_POWER(priv, "Sleep command for CAM\n"); 268 IWL_DEBUG_POWER(priv, "Sleep command for CAM\n");
269} 269}
270 270
271static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
272 struct iwl_powertable_cmd *cmd,
273 int dynps_ms, int wakeup_period)
274{
275 /*
276 * These are the original power level 3 sleep successions. The
277 * device may behave better with such succession and was also
278 * only tested with that. Just like the original sleep commands,
279 * also adjust the succession here to the wakeup_period below.
280 * The ranges are the same as for the sleep commands, 0-2, 3-9
281 * and >10, which is selected based on the DTIM interval for
282 * the sleep index but here we use the wakeup period since that
283 * is what we need to do for the latency requirements.
284 */
285 static const u8 slp_succ_r0[IWL_POWER_VEC_SIZE] = { 2, 2, 2, 2, 2 };
286 static const u8 slp_succ_r1[IWL_POWER_VEC_SIZE] = { 2, 4, 6, 7, 9 };
287 static const u8 slp_succ_r2[IWL_POWER_VEC_SIZE] = { 2, 7, 9, 9, 0xFF };
288 const u8 *slp_succ = slp_succ_r0;
289 int i;
290
291 if (wakeup_period > IWL_DTIM_RANGE_0_MAX)
292 slp_succ = slp_succ_r1;
293 if (wakeup_period > IWL_DTIM_RANGE_1_MAX)
294 slp_succ = slp_succ_r2;
295
296 memset(cmd, 0, sizeof(*cmd));
297
298 cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK |
299 IWL_POWER_FAST_PD; /* no use seeing frames for others */
300
301 if (priv->power_data.bus_pm)
302 cmd->flags |= IWL_POWER_PCI_PM_MSK;
303
304 if (cfg(priv)->base_params->shadow_reg_enable)
305 cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
306 else
307 cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
308
309 if (iwl_advanced_bt_coexist(priv)) {
310 if (!cfg(priv)->bt_params->bt_sco_disable)
311 cmd->flags |= IWL_POWER_BT_SCO_ENA;
312 else
313 cmd->flags &= ~IWL_POWER_BT_SCO_ENA;
314 }
315
316 cmd->rx_data_timeout = cpu_to_le32(1000 * dynps_ms);
317 cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms);
318
319 for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
320 cmd->sleep_interval[i] =
321 cpu_to_le32(min_t(int, slp_succ[i], wakeup_period));
322
323 IWL_DEBUG_POWER(priv, "Automatic sleep command\n");
324}
325
326static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) 271static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
327{ 272{
328 IWL_DEBUG_POWER(priv, "Sending power/sleep command\n"); 273 IWL_DEBUG_POWER(priv, "Sending power/sleep command\n");
@@ -363,7 +308,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
363 iwl_static_sleep_cmd(priv, cmd, 308 iwl_static_sleep_cmd(priv, cmd,
364 priv->power_data.debug_sleep_level_override, 309 priv->power_data.debug_sleep_level_override,
365 dtimper); 310 dtimper);
366 else if (iwlagn_mod_params.no_sleep_autoadjust) { 311 else {
367 if (iwlagn_mod_params.power_level > IWL_POWER_INDEX_1 && 312 if (iwlagn_mod_params.power_level > IWL_POWER_INDEX_1 &&
368 iwlagn_mod_params.power_level <= IWL_POWER_INDEX_5) 313 iwlagn_mod_params.power_level <= IWL_POWER_INDEX_5)
369 iwl_static_sleep_cmd(priv, cmd, 314 iwl_static_sleep_cmd(priv, cmd,
@@ -371,10 +316,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
371 else 316 else
372 iwl_static_sleep_cmd(priv, cmd, 317 iwl_static_sleep_cmd(priv, cmd,
373 IWL_POWER_INDEX_1, dtimper); 318 IWL_POWER_INDEX_1, dtimper);
374 } else 319 }
375 iwl_power_fill_sleep_cmd(priv, cmd,
376 priv->hw->conf.dynamic_ps_timeout,
377 priv->hw->conf.max_sleep_period);
378} 320}
379 321
380int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, 322int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index dcf5b12071b4..490a60d8ad7d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -673,12 +673,12 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
673 u16 rx_chain = 0; 673 u16 rx_chain = 0;
674 enum ieee80211_band band; 674 enum ieee80211_band band;
675 u8 n_probes = 0; 675 u8 n_probes = 0;
676 u8 rx_ant = hw_params(priv).valid_rx_ant; 676 u8 rx_ant = priv->hw_params.valid_rx_ant;
677 u8 rate; 677 u8 rate;
678 bool is_active = false; 678 bool is_active = false;
679 int chan_mod; 679 int chan_mod;
680 u8 active_chains; 680 u8 active_chains;
681 u8 scan_tx_antennas = hw_params(priv).valid_tx_ant; 681 u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
682 int ret; 682 int ret;
683 683
684 lockdep_assert_held(&priv->mutex); 684 lockdep_assert_held(&priv->mutex);
@@ -872,7 +872,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
872 872
873 /* MIMO is not used here, but value is required */ 873 /* MIMO is not used here, but value is required */
874 rx_chain |= 874 rx_chain |=
875 hw_params(priv).valid_rx_ant << RXON_RX_CHAIN_VALID_POS; 875 priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
876 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; 876 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
877 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; 877 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
878 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; 878 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
@@ -985,7 +985,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
985 985
986void iwl_init_scan_params(struct iwl_priv *priv) 986void iwl_init_scan_params(struct iwl_priv *priv)
987{ 987{
988 u8 ant_idx = fls(hw_params(priv).valid_tx_ant) - 1; 988 u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1;
989 if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) 989 if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ])
990 priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; 990 priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx;
991 if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) 991 if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ])
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h
index 983b41e43d4b..35bd83ce3dae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-shared.h
+++ b/drivers/net/wireless/iwlwifi/iwl-shared.h
@@ -70,6 +70,7 @@
70 70
71#include "iwl-commands.h" 71#include "iwl-commands.h"
72#include "iwl-fw.h" 72#include "iwl-fw.h"
73#include "iwl-config.h"
73 74
74/** 75/**
75 * DOC: shared area - role and goal 76 * DOC: shared area - role and goal
@@ -95,7 +96,6 @@
95 96
96struct iwl_priv; 97struct iwl_priv;
97struct iwl_trans; 98struct iwl_trans;
98struct iwl_sensitivity_ranges;
99struct iwl_trans_ops; 99struct iwl_trans_ops;
100 100
101#define DRV_NAME "iwlwifi" 101#define DRV_NAME "iwlwifi"
@@ -118,252 +118,56 @@ extern struct iwl_mod_params iwlagn_mod_params;
118 * @disable_11n: disable 11n capabilities, default = 0, 118 * @disable_11n: disable 11n capabilities, default = 0,
119 * use IWL_DISABLE_HT_* constants 119 * use IWL_DISABLE_HT_* constants
120 * @amsdu_size_8K: enable 8K amsdu size, default = 1 120 * @amsdu_size_8K: enable 8K amsdu size, default = 1
121 * @antenna: both antennas (use diversity), default = 0
122 * @restart_fw: restart firmware, default = 1 121 * @restart_fw: restart firmware, default = 1
123 * @plcp_check: enable plcp health check, default = true 122 * @plcp_check: enable plcp health check, default = true
124 * @ack_check: disable ack health check, default = false
125 * @wd_disable: enable stuck queue check, default = 0 123 * @wd_disable: enable stuck queue check, default = 0
126 * @bt_coex_active: enable bt coex, default = true 124 * @bt_coex_active: enable bt coex, default = true
127 * @led_mode: system default, default = 0 125 * @led_mode: system default, default = 0
128 * @no_sleep_autoadjust: disable autoadjust, default = true
129 * @power_save: disable power save, default = false 126 * @power_save: disable power save, default = false
130 * @power_level: power level, default = 1 127 * @power_level: power level, default = 1
131 * @debug_level: levels are IWL_DL_* 128 * @debug_level: levels are IWL_DL_*
132 * @ant_coupling: antenna coupling in dB, default = 0 129 * @ant_coupling: antenna coupling in dB, default = 0
133 * @bt_ch_announce: BT channel inhibition, default = enable 130 * @bt_ch_announce: BT channel inhibition, default = enable
134 * @wanted_ucode_alternative: ucode alternative to use, default = 1
135 * @auto_agg: enable agg. without check, default = true 131 * @auto_agg: enable agg. without check, default = true
136 */ 132 */
137struct iwl_mod_params { 133struct iwl_mod_params {
138 int sw_crypto; 134 int sw_crypto;
139 unsigned int disable_11n; 135 unsigned int disable_11n;
140 int amsdu_size_8K; 136 int amsdu_size_8K;
141 int antenna;
142 int restart_fw; 137 int restart_fw;
143 bool plcp_check; 138 bool plcp_check;
144 bool ack_check;
145 int wd_disable; 139 int wd_disable;
146 bool bt_coex_active; 140 bool bt_coex_active;
147 int led_mode; 141 int led_mode;
148 bool no_sleep_autoadjust;
149 bool power_save; 142 bool power_save;
150 int power_level; 143 int power_level;
151 u32 debug_level; 144 u32 debug_level;
152 int ant_coupling; 145 int ant_coupling;
153 bool bt_ch_announce; 146 bool bt_ch_announce;
154 int wanted_ucode_alternative;
155 bool auto_agg; 147 bool auto_agg;
156}; 148};
157 149
158/** 150/**
159 * struct iwl_hw_params
160 *
161 * Holds the module parameters
162 *
163 * @tx_chains_num: Number of TX chains
164 * @rx_chains_num: Number of RX chains
165 * @valid_tx_ant: usable antennas for TX
166 * @valid_rx_ant: usable antennas for RX
167 * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX)
168 * @sku: sku read from EEPROM
169 * @rx_page_order: Rx buffer page order
170 * @ct_kill_threshold: temperature threshold - in hw dependent unit
171 * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit
172 * relevant for 1000, 6000 and up
173 * @wd_timeout: TX queues watchdog timeout
174 * @struct iwl_sensitivity_ranges: range of sensitivity values
175 * @use_rts_for_aggregation: use rts/cts protection for HT traffic
176 */
177struct iwl_hw_params {
178 u8 tx_chains_num;
179 u8 rx_chains_num;
180 u8 valid_tx_ant;
181 u8 valid_rx_ant;
182 u8 ht40_channel;
183 bool use_rts_for_aggregation;
184 u16 sku;
185 u32 rx_page_order;
186 u32 ct_kill_threshold;
187 u32 ct_kill_exit_threshold;
188 unsigned int wd_timeout;
189
190 const struct iwl_sensitivity_ranges *sens;
191};
192
193/*
194 * LED mode
195 * IWL_LED_DEFAULT: use device default
196 * IWL_LED_RF_STATE: turn LED on/off based on RF state
197 * LED ON = RF ON
198 * LED OFF = RF OFF
199 * IWL_LED_BLINK: adjust led blink rate based on blink table
200 * IWL_LED_DISABLE: led disabled
201 */
202enum iwl_led_mode {
203 IWL_LED_DEFAULT,
204 IWL_LED_RF_STATE,
205 IWL_LED_BLINK,
206 IWL_LED_DISABLE,
207};
208
209/*
210 * @max_ll_items: max number of OTP blocks
211 * @shadow_ram_support: shadow support for OTP memory
212 * @led_compensation: compensate on the led on/off time per HW according
213 * to the deviation to achieve the desired led frequency.
214 * The detail algorithm is described in iwl-led.c
215 * @chain_noise_num_beacons: number of beacons used to compute chain noise
216 * @adv_thermal_throttle: support advance thermal throttle
217 * @support_ct_kill_exit: support ct kill exit condition
218 * @plcp_delta_threshold: plcp error rate threshold used to trigger
219 * radio tuning when there is a high receiving plcp error rate
220 * @chain_noise_scale: default chain noise scale used for gain computation
221 * @wd_timeout: TX queues watchdog timeout
222 * @max_event_log_size: size of event log buffer size for ucode event logging
223 * @shadow_reg_enable: HW shadhow register bit
224 * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
225 * @no_idle_support: do not support idle mode
226 * wd_disable: disable watchdog timer
227 */
228struct iwl_base_params {
229 int eeprom_size;
230 int num_of_queues; /* def: HW dependent */
231 /* for iwl_apm_init() */
232 u32 pll_cfg_val;
233
234 const u16 max_ll_items;
235 const bool shadow_ram_support;
236 u16 led_compensation;
237 bool adv_thermal_throttle;
238 bool support_ct_kill_exit;
239 u8 plcp_delta_threshold;
240 s32 chain_noise_scale;
241 unsigned int wd_timeout;
242 u32 max_event_log_size;
243 const bool shadow_reg_enable;
244 const bool hd_v2;
245 const bool no_idle_support;
246 const bool wd_disable;
247};
248
249/*
250 * @advanced_bt_coexist: support advanced bt coexist
251 * @bt_init_traffic_load: specify initial bt traffic load
252 * @bt_prio_boost: default bt priority boost value
253 * @agg_time_limit: maximum number of uSec in aggregation
254 * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
255 */
256struct iwl_bt_params {
257 bool advanced_bt_coexist;
258 u8 bt_init_traffic_load;
259 u8 bt_prio_boost;
260 u16 agg_time_limit;
261 bool bt_sco_disable;
262 bool bt_session_2;
263};
264/*
265 * @use_rts_for_aggregation: use rts/cts protection for HT traffic
266 */
267struct iwl_ht_params {
268 const bool ht_greenfield_support; /* if used set to true */
269 bool use_rts_for_aggregation;
270 enum ieee80211_smps_mode smps_mode;
271};
272
273/**
274 * struct iwl_cfg
275 * @name: Offical name of the device
276 * @fw_name_pre: Firmware filename prefix. The api version and extension
277 * (.ucode) will be added to filename before loading from disk. The
278 * filename is constructed as fw_name_pre<api>.ucode.
279 * @ucode_api_max: Highest version of uCode API supported by driver.
280 * @ucode_api_ok: oldest version of the uCode API that is OK to load
281 * without a warning, for use in transitions
282 * @ucode_api_min: Lowest version of uCode API supported by driver.
283 * @max_inst_size: The maximal length of the fw inst section
284 * @max_data_size: The maximal length of the fw data section
285 * @valid_tx_ant: valid transmit antenna
286 * @valid_rx_ant: valid receive antenna
287 * @eeprom_ver: EEPROM version
288 * @eeprom_calib_ver: EEPROM calibration version
289 * @lib: pointer to the lib ops
290 * @additional_nic_config: additional nic configuration
291 * @base_params: pointer to basic parameters
292 * @ht_params: point to ht patameters
293 * @bt_params: pointer to bt parameters
294 * @need_temp_offset_calib: need to perform temperature offset calibration
295 * @no_xtal_calib: some devices do not need crystal calibration data,
296 * don't send it to those
297 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
298 * @adv_pm: advance power management
299 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
300 * @internal_wimax_coex: internal wifi/wimax combo device
301 * @temp_offset_v2: support v2 of temperature offset calibration
302 *
303 * We enable the driver to be backward compatible wrt. hardware features.
304 * API differences in uCode shouldn't be handled here but through TLVs
305 * and/or the uCode API version instead.
306 */
307struct iwl_cfg {
308 /* params specific to an individual device within a device family */
309 const char *name;
310 const char *fw_name_pre;
311 const unsigned int ucode_api_max;
312 const unsigned int ucode_api_ok;
313 const unsigned int ucode_api_min;
314 const u32 max_data_size;
315 const u32 max_inst_size;
316 u8 valid_tx_ant;
317 u8 valid_rx_ant;
318 u16 eeprom_ver;
319 u16 eeprom_calib_ver;
320 const struct iwl_lib_ops *lib;
321 void (*additional_nic_config)(struct iwl_priv *priv);
322 /* params not likely to change within a device family */
323 const struct iwl_base_params *base_params;
324 /* params likely to change within a device family */
325 const struct iwl_ht_params *ht_params;
326 const struct iwl_bt_params *bt_params;
327 const bool need_temp_offset_calib; /* if used set to true */
328 const bool no_xtal_calib;
329 enum iwl_led_mode led_mode;
330 const bool adv_pm;
331 const bool rx_with_siso_diversity;
332 const bool internal_wimax_coex;
333 const bool temp_offset_v2;
334};
335
336/**
337 * struct iwl_shared - shared fields for all the layers of the driver 151 * struct iwl_shared - shared fields for all the layers of the driver
338 * 152 *
339 * @status: STATUS_*
340 * @wowlan: are we running wowlan uCode 153 * @wowlan: are we running wowlan uCode
341 * @bus: pointer to the bus layer data 154 * @bus: pointer to the bus layer data
342 * @cfg: see struct iwl_cfg 155 * @cfg: see struct iwl_cfg
343 * @priv: pointer to the upper layer data 156 * @priv: pointer to the upper layer data
344 * @trans: pointer to the transport layer data 157 * @trans: pointer to the transport layer data
345 * @nic: pointer to the nic data 158 * @nic: pointer to the nic data
346 * @hw_params: see struct iwl_hw_params
347 * @lock: protect general shared data 159 * @lock: protect general shared data
348 * @eeprom: pointer to the eeprom/OTP image 160 * @eeprom: pointer to the eeprom/OTP image
349 */ 161 */
350struct iwl_shared { 162struct iwl_shared {
351 unsigned long status;
352
353 const struct iwl_cfg *cfg; 163 const struct iwl_cfg *cfg;
354 struct iwl_trans *trans; 164 struct iwl_trans *trans;
355 void *drv; 165 void *drv;
356 struct iwl_hw_params hw_params;
357
358 /* eeprom -- this is in the card's little endian byte order */
359 u8 *eeprom;
360
361}; 166};
362 167
363/*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ 168/*Whatever _m is (iwl_trans, iwl_priv, these macros will work */
364#define cfg(_m) ((_m)->shrd->cfg) 169#define cfg(_m) ((_m)->shrd->cfg)
365#define trans(_m) ((_m)->shrd->trans) 170#define trans(_m) ((_m)->shrd->trans)
366#define hw_params(_m) ((_m)->shrd->hw_params)
367 171
368static inline bool iwl_have_debug_level(u32 level) 172static inline bool iwl_have_debug_level(u32 level)
369{ 173{
@@ -377,33 +181,4 @@ enum iwl_rxon_context_id {
377 NUM_IWL_RXON_CTX 181 NUM_IWL_RXON_CTX
378}; 182};
379 183
380int iwlagn_hw_valid_rtc_data_addr(u32 addr);
381const char *get_cmd_string(u8 cmd);
382
383#define IWL_CMD(x) case x: return #x
384
385/*****************************************************
386* DRIVER STATUS FUNCTIONS
387******************************************************/
388#define STATUS_HCMD_ACTIVE 0 /* host command in progress */
389/* 1 is unused (used to be STATUS_HCMD_SYNC_ACTIVE) */
390#define STATUS_INT_ENABLED 2
391#define STATUS_RF_KILL_HW 3
392#define STATUS_CT_KILL 4
393#define STATUS_INIT 5
394#define STATUS_ALIVE 6
395#define STATUS_READY 7
396#define STATUS_TEMPERATURE 8
397#define STATUS_GEO_CONFIGURED 9
398#define STATUS_EXIT_PENDING 10
399#define STATUS_STATISTICS 12
400#define STATUS_SCANNING 13
401#define STATUS_SCAN_ABORTING 14
402#define STATUS_SCAN_HW 15
403#define STATUS_POWER_PMI 16
404#define STATUS_FW_ERROR 17
405#define STATUS_DEVICE_ENABLED 18
406#define STATUS_CHANNEL_SWITCH_PENDING 19
407#define STATUS_SCAN_COMPLETE 20
408
409#endif /* #__iwl_shared_h__ */ 184#endif /* #__iwl_shared_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c
index f31a0629c6c6..bb275098bb10 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c
@@ -536,7 +536,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
536 break; 536 break;
537 537
538 case IWL_TM_CMD_APP2DEV_GET_EEPROM: 538 case IWL_TM_CMD_APP2DEV_GET_EEPROM:
539 if (priv->shrd->eeprom) { 539 if (priv->eeprom) {
540 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 540 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
541 cfg(priv)->base_params->eeprom_size + 20); 541 cfg(priv)->base_params->eeprom_size + 20);
542 if (!skb) { 542 if (!skb) {
@@ -547,7 +547,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
547 IWL_TM_CMD_DEV2APP_EEPROM_RSP) || 547 IWL_TM_CMD_DEV2APP_EEPROM_RSP) ||
548 nla_put(skb, IWL_TM_ATTR_EEPROM, 548 nla_put(skb, IWL_TM_ATTR_EEPROM,
549 cfg(priv)->base_params->eeprom_size, 549 cfg(priv)->base_params->eeprom_size,
550 priv->shrd->eeprom)) 550 priv->eeprom))
551 goto nla_put_failure; 551 goto nla_put_failure;
552 status = cfg80211_testmode_reply(skb); 552 status = cfg80211_testmode_reply(skb);
553 if (status < 0) 553 if (status < 0)
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
index 32adee3b54e3..70bdd0e2df38 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
@@ -34,6 +34,7 @@
34#include <linux/skbuff.h> 34#include <linux/skbuff.h>
35#include <linux/wait.h> 35#include <linux/wait.h>
36#include <linux/pci.h> 36#include <linux/pci.h>
37#include <linux/timer.h>
37 38
38#include "iwl-fh.h" 39#include "iwl-fh.h"
39#include "iwl-csr.h" 40#include "iwl-csr.h"
@@ -43,8 +44,6 @@
43#include "iwl-io.h" 44#include "iwl-io.h"
44#include "iwl-op-mode.h" 45#include "iwl-op-mode.h"
45 46
46struct iwl_tx_queue;
47struct iwl_queue;
48struct iwl_host_cmd; 47struct iwl_host_cmd;
49 48
50/*This file includes the declaration that are internal to the 49/*This file includes the declaration that are internal to the
@@ -140,10 +139,10 @@ struct iwl_cmd_meta {
140 /* only for SYNC commands, iff the reply skb is wanted */ 139 /* only for SYNC commands, iff the reply skb is wanted */
141 struct iwl_host_cmd *source; 140 struct iwl_host_cmd *source;
142 141
143 u32 flags;
144
145 DEFINE_DMA_UNMAP_ADDR(mapping); 142 DEFINE_DMA_UNMAP_ADDR(mapping);
146 DEFINE_DMA_UNMAP_LEN(len); 143 DEFINE_DMA_UNMAP_LEN(len);
144
145 u32 flags;
147}; 146};
148 147
149/* 148/*
@@ -206,7 +205,8 @@ struct iwl_tx_queue {
206 struct iwl_cmd_meta *meta; 205 struct iwl_cmd_meta *meta;
207 struct sk_buff **skbs; 206 struct sk_buff **skbs;
208 spinlock_t lock; 207 spinlock_t lock;
209 unsigned long time_stamp; 208 struct timer_list stuck_timer;
209 struct iwl_trans_pcie *trans_pcie;
210 u8 need_update; 210 u8 need_update;
211 u8 active; 211 u8 active;
212}; 212};
@@ -227,6 +227,9 @@ struct iwl_tx_queue {
227 * @ucode_write_waitq: wait queue for uCode load 227 * @ucode_write_waitq: wait queue for uCode load
228 * @status - transport specific status flags 228 * @status - transport specific status flags
229 * @cmd_queue - command queue number 229 * @cmd_queue - command queue number
230 * @rx_buf_size_8k: 8 kB RX buffer size
231 * @rx_page_order: page order for receive buffer size
232 * @wd_timeout: queue watchdog timeout (jiffies)
230 */ 233 */
231struct iwl_trans_pcie { 234struct iwl_trans_pcie {
232 struct iwl_rx_queue rxq; 235 struct iwl_rx_queue rxq;
@@ -266,11 +269,34 @@ struct iwl_trans_pcie {
266 u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; 269 u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS];
267 u8 setup_q_to_fifo[IWL_MAX_HW_QUEUES]; 270 u8 setup_q_to_fifo[IWL_MAX_HW_QUEUES];
268 u8 n_q_to_fifo; 271 u8 n_q_to_fifo;
272
273 bool rx_buf_size_8k;
274 u32 rx_page_order;
275
276 const char **command_names;
277
278 /* queue watchdog */
279 unsigned long wd_timeout;
269}; 280};
270 281
282/*****************************************************
283* DRIVER STATUS FUNCTIONS
284******************************************************/
285#define STATUS_HCMD_ACTIVE 0
286#define STATUS_DEVICE_ENABLED 1
287#define STATUS_TPOWER_PMI 2
288#define STATUS_INT_ENABLED 3
289
271#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ 290#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
272 ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific)) 291 ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific))
273 292
293static inline struct iwl_trans *
294iwl_trans_pcie_get_trans(struct iwl_trans_pcie *trans_pcie)
295{
296 return container_of((void *)trans_pcie, struct iwl_trans,
297 trans_specific);
298}
299
274/***************************************************** 300/*****************************************************
275* RX 301* RX
276******************************************************/ 302******************************************************/
@@ -392,4 +418,12 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index)
392 return index & (q->n_window - 1); 418 return index & (q->n_window - 1);
393} 419}
394 420
421static inline const char *
422trans_pcie_get_cmd_string(struct iwl_trans_pcie *trans_pcie, u8 cmd)
423{
424 if (!trans_pcie->command_names || !trans_pcie->command_names[cmd])
425 return "UNKNOWN";
426 return trans_pcie->command_names[cmd];
427}
428
395#endif /* __iwl_trans_int_pcie_h__ */ 429#endif /* __iwl_trans_int_pcie_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
index ab0f3fc22b87..de78fb8dca9f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
@@ -150,7 +150,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans,
150 IWL_TRANS_GET_PCIE_TRANS(trans); 150 IWL_TRANS_GET_PCIE_TRANS(trans);
151 151
152 /* If power-saving is in use, make sure device is awake */ 152 /* If power-saving is in use, make sure device is awake */
153 if (test_bit(STATUS_POWER_PMI, &trans_pcie->status)) { 153 if (test_bit(STATUS_TPOWER_PMI, &trans_pcie->status)) {
154 reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); 154 reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
155 155
156 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { 156 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
@@ -274,17 +274,17 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
274 if (rxq->free_count > RX_LOW_WATERMARK) 274 if (rxq->free_count > RX_LOW_WATERMARK)
275 gfp_mask |= __GFP_NOWARN; 275 gfp_mask |= __GFP_NOWARN;
276 276
277 if (hw_params(trans).rx_page_order > 0) 277 if (trans_pcie->rx_page_order > 0)
278 gfp_mask |= __GFP_COMP; 278 gfp_mask |= __GFP_COMP;
279 279
280 /* Alloc a new receive buffer */ 280 /* Alloc a new receive buffer */
281 page = alloc_pages(gfp_mask, 281 page = alloc_pages(gfp_mask,
282 hw_params(trans).rx_page_order); 282 trans_pcie->rx_page_order);
283 if (!page) { 283 if (!page) {
284 if (net_ratelimit()) 284 if (net_ratelimit())
285 IWL_DEBUG_INFO(trans, "alloc_pages failed, " 285 IWL_DEBUG_INFO(trans, "alloc_pages failed, "
286 "order: %d\n", 286 "order: %d\n",
287 hw_params(trans).rx_page_order); 287 trans_pcie->rx_page_order);
288 288
289 if ((rxq->free_count <= RX_LOW_WATERMARK) && 289 if ((rxq->free_count <= RX_LOW_WATERMARK) &&
290 net_ratelimit()) 290 net_ratelimit())
@@ -303,7 +303,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
303 303
304 if (list_empty(&rxq->rx_used)) { 304 if (list_empty(&rxq->rx_used)) {
305 spin_unlock_irqrestore(&rxq->lock, flags); 305 spin_unlock_irqrestore(&rxq->lock, flags);
306 __free_pages(page, hw_params(trans).rx_page_order); 306 __free_pages(page, trans_pcie->rx_page_order);
307 return; 307 return;
308 } 308 }
309 element = rxq->rx_used.next; 309 element = rxq->rx_used.next;
@@ -316,7 +316,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
316 rxb->page = page; 316 rxb->page = page;
317 /* Get physical address of the RB */ 317 /* Get physical address of the RB */
318 rxb->page_dma = dma_map_page(trans->dev, page, 0, 318 rxb->page_dma = dma_map_page(trans->dev, page, 0,
319 PAGE_SIZE << hw_params(trans).rx_page_order, 319 PAGE_SIZE << trans_pcie->rx_page_order,
320 DMA_FROM_DEVICE); 320 DMA_FROM_DEVICE);
321 /* dma address must be no more than 36 bits */ 321 /* dma address must be no more than 36 bits */
322 BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); 322 BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
@@ -367,7 +367,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
367 struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; 367 struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
368 unsigned long flags; 368 unsigned long flags;
369 bool page_stolen = false; 369 bool page_stolen = false;
370 int max_len = PAGE_SIZE << hw_params(trans).rx_page_order; 370 int max_len = PAGE_SIZE << trans_pcie->rx_page_order;
371 u32 offset = 0; 371 u32 offset = 0;
372 372
373 if (WARN_ON(!rxb)) 373 if (WARN_ON(!rxb))
@@ -393,8 +393,9 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
393 break; 393 break;
394 394
395 IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n", 395 IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n",
396 rxcb._offset, get_cmd_string(pkt->hdr.cmd), 396 rxcb._offset,
397 pkt->hdr.cmd); 397 trans_pcie_get_cmd_string(trans_pcie, pkt->hdr.cmd),
398 pkt->hdr.cmd);
398 399
399 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 400 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
400 len += sizeof(u32); /* account for status word */ 401 len += sizeof(u32); /* account for status word */
@@ -452,7 +453,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
452 453
453 /* page was stolen from us -- free our reference */ 454 /* page was stolen from us -- free our reference */
454 if (page_stolen) { 455 if (page_stolen) {
455 __free_pages(rxb->page, hw_params(trans).rx_page_order); 456 __free_pages(rxb->page, trans_pcie->rx_page_order);
456 rxb->page = NULL; 457 rxb->page = NULL;
457 } 458 }
458 459
@@ -463,7 +464,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
463 if (rxb->page != NULL) { 464 if (rxb->page != NULL) {
464 rxb->page_dma = 465 rxb->page_dma =
465 dma_map_page(trans->dev, rxb->page, 0, 466 dma_map_page(trans->dev, rxb->page, 0,
466 PAGE_SIZE << hw_params(trans).rx_page_order, 467 PAGE_SIZE << trans_pcie->rx_page_order,
467 DMA_FROM_DEVICE); 468 DMA_FROM_DEVICE);
468 list_add_tail(&rxb->list, &rxq->rx_free); 469 list_add_tail(&rxb->list, &rxq->rx_free);
469 rxq->free_count++; 470 rxq->free_count++;
@@ -547,14 +548,12 @@ static void iwl_irq_handle_error(struct iwl_trans *trans)
547 APMS_CLK_VAL_MRB_FUNC_MODE) || 548 APMS_CLK_VAL_MRB_FUNC_MODE) ||
548 (iwl_read_prph(trans, APMG_PS_CTRL_REG) & 549 (iwl_read_prph(trans, APMG_PS_CTRL_REG) &
549 APMG_PS_CTRL_VAL_RESET_REQ))) { 550 APMG_PS_CTRL_VAL_RESET_REQ))) {
550 /* 551 struct iwl_trans_pcie *trans_pcie;
551 * Keep the restart process from trying to send host 552
552 * commands by clearing the ready bit. 553 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
553 */ 554 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
554 clear_bit(STATUS_READY, &trans->shrd->status); 555 iwl_op_mode_wimax_active(trans->op_mode);
555 clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
556 wake_up(&trans->wait_command_queue); 556 wake_up(&trans->wait_command_queue);
557 IWL_ERR(trans, "RF is used by WiMAX\n");
558 return; 557 return;
559 } 558 }
560 559
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
index 4684e2310cd8..918874067bd3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -107,7 +107,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq)
107 struct iwl_trans_pcie *trans_pcie = 107 struct iwl_trans_pcie *trans_pcie =
108 IWL_TRANS_GET_PCIE_TRANS(trans); 108 IWL_TRANS_GET_PCIE_TRANS(trans);
109 /* if we're trying to save power */ 109 /* if we're trying to save power */
110 if (test_bit(STATUS_POWER_PMI, &trans_pcie->status)) { 110 if (test_bit(STATUS_TPOWER_PMI, &trans_pcie->status)) {
111 /* wake up nic if it's powered down ... 111 /* wake up nic if it's powered down ...
112 * uCode will wake up, and interrupt us again, so next 112 * uCode will wake up, and interrupt us again, so next
113 * time we'll skip this part. */ 113 * time we'll skip this part. */
@@ -605,12 +605,11 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
605 cmd_dest += cmd->len[i]; 605 cmd_dest += cmd->len[i];
606 } 606 }
607 607
608 IWL_DEBUG_HC(trans, "Sending command %s (#%x), seq: 0x%04X, " 608 IWL_DEBUG_HC(trans,
609 "%d bytes at %d[%d]:%d\n", 609 "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n",
610 get_cmd_string(out_cmd->hdr.cmd), 610 trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd),
611 out_cmd->hdr.cmd, 611 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size,
612 le16_to_cpu(out_cmd->hdr.sequence), cmd_size, 612 q->write_ptr, idx, trans_pcie->cmd_queue);
613 q->write_ptr, idx, trans_pcie->cmd_queue);
614 613
615 phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, 614 phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
616 DMA_BIDIRECTIONAL); 615 DMA_BIDIRECTIONAL);
@@ -668,6 +667,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
668 trace_bufs[2], trace_lens[2]); 667 trace_bufs[2], trace_lens[2]);
669#endif 668#endif
670 669
670 /* start timer if queue currently empty */
671 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
672 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
673
671 /* Increment and update queue's write index */ 674 /* Increment and update queue's write index */
672 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 675 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
673 iwl_txq_update_write_ptr(trans, txq); 676 iwl_txq_update_write_ptr(trans, txq);
@@ -677,6 +680,22 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
677 return idx; 680 return idx;
678} 681}
679 682
683static inline void iwl_queue_progress(struct iwl_trans_pcie *trans_pcie,
684 struct iwl_tx_queue *txq)
685{
686 if (!trans_pcie->wd_timeout)
687 return;
688
689 /*
690 * if empty delete timer, otherwise move timer forward
691 * since we're making progress on this queue
692 */
693 if (txq->q.read_ptr == txq->q.write_ptr)
694 del_timer(&txq->stuck_timer);
695 else
696 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
697}
698
680/** 699/**
681 * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd 700 * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd
682 * 701 *
@@ -711,6 +730,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
711 } 730 }
712 731
713 } 732 }
733
734 iwl_queue_progress(trans_pcie, txq);
714} 735}
715 736
716/** 737/**
@@ -754,8 +775,6 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
754 cmd = txq->cmd[cmd_index]; 775 cmd = txq->cmd[cmd_index];
755 meta = &txq->meta[cmd_index]; 776 meta = &txq->meta[cmd_index];
756 777
757 txq->time_stamp = jiffies;
758
759 iwlagn_unmap_tfd(trans, meta, &txq->tfds[index], 778 iwlagn_unmap_tfd(trans, meta, &txq->tfds[index],
760 DMA_BIDIRECTIONAL); 779 DMA_BIDIRECTIONAL);
761 780
@@ -765,21 +784,23 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
765 784
766 meta->source->resp_pkt = pkt; 785 meta->source->resp_pkt = pkt;
767 meta->source->_rx_page_addr = (unsigned long)page_address(p); 786 meta->source->_rx_page_addr = (unsigned long)page_address(p);
768 meta->source->_rx_page_order = hw_params(trans).rx_page_order; 787 meta->source->_rx_page_order = trans_pcie->rx_page_order;
769 meta->source->handler_status = handler_status; 788 meta->source->handler_status = handler_status;
770 } 789 }
771 790
772 iwl_hcmd_queue_reclaim(trans, txq_id, index); 791 iwl_hcmd_queue_reclaim(trans, txq_id, index);
773 792
774 if (!(meta->flags & CMD_ASYNC)) { 793 if (!(meta->flags & CMD_ASYNC)) {
775 if (!test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { 794 if (!test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) {
776 IWL_WARN(trans, 795 IWL_WARN(trans,
777 "HCMD_ACTIVE already clear for command %s\n", 796 "HCMD_ACTIVE already clear for command %s\n",
778 get_cmd_string(cmd->hdr.cmd)); 797 trans_pcie_get_cmd_string(trans_pcie,
798 cmd->hdr.cmd));
779 } 799 }
780 clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); 800 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
781 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", 801 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
782 get_cmd_string(cmd->hdr.cmd)); 802 trans_pcie_get_cmd_string(trans_pcie,
803 cmd->hdr.cmd));
783 wake_up(&trans->wait_command_queue); 804 wake_up(&trans->wait_command_queue);
784 } 805 }
785 806
@@ -792,6 +813,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
792 813
793static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) 814static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
794{ 815{
816 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
795 int ret; 817 int ret;
796 818
797 /* An asynchronous command can not expect an SKB to be set. */ 819 /* An asynchronous command can not expect an SKB to be set. */
@@ -803,7 +825,7 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
803 if (ret < 0) { 825 if (ret < 0) {
804 IWL_ERR(trans, 826 IWL_ERR(trans,
805 "Error sending %s: enqueue_hcmd failed: %d\n", 827 "Error sending %s: enqueue_hcmd failed: %d\n",
806 get_cmd_string(cmd->id), ret); 828 trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret);
807 return ret; 829 return ret;
808 } 830 }
809 return 0; 831 return 0;
@@ -816,49 +838,51 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
816 int ret; 838 int ret;
817 839
818 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", 840 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
819 get_cmd_string(cmd->id)); 841 trans_pcie_get_cmd_string(trans_pcie, cmd->id));
820 842
821 if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, 843 if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE,
822 &trans->shrd->status))) { 844 &trans_pcie->status))) {
823 IWL_ERR(trans, "Command %s: a command is already active!\n", 845 IWL_ERR(trans, "Command %s: a command is already active!\n",
824 get_cmd_string(cmd->id)); 846 trans_pcie_get_cmd_string(trans_pcie, cmd->id));
825 return -EIO; 847 return -EIO;
826 } 848 }
827 849
828 IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", 850 IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n",
829 get_cmd_string(cmd->id)); 851 trans_pcie_get_cmd_string(trans_pcie, cmd->id));
830 852
831 cmd_idx = iwl_enqueue_hcmd(trans, cmd); 853 cmd_idx = iwl_enqueue_hcmd(trans, cmd);
832 if (cmd_idx < 0) { 854 if (cmd_idx < 0) {
833 ret = cmd_idx; 855 ret = cmd_idx;
834 clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); 856 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
835 IWL_ERR(trans, 857 IWL_ERR(trans,
836 "Error sending %s: enqueue_hcmd failed: %d\n", 858 "Error sending %s: enqueue_hcmd failed: %d\n",
837 get_cmd_string(cmd->id), ret); 859 trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret);
838 return ret; 860 return ret;
839 } 861 }
840 862
841 ret = wait_event_timeout(trans->wait_command_queue, 863 ret = wait_event_timeout(trans->wait_command_queue,
842 !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), 864 !test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status),
843 HOST_COMPLETE_TIMEOUT); 865 HOST_COMPLETE_TIMEOUT);
844 if (!ret) { 866 if (!ret) {
845 if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { 867 if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) {
846 struct iwl_tx_queue *txq = 868 struct iwl_tx_queue *txq =
847 &trans_pcie->txq[trans_pcie->cmd_queue]; 869 &trans_pcie->txq[trans_pcie->cmd_queue];
848 struct iwl_queue *q = &txq->q; 870 struct iwl_queue *q = &txq->q;
849 871
850 IWL_ERR(trans, 872 IWL_ERR(trans,
851 "Error sending %s: time out after %dms.\n", 873 "Error sending %s: time out after %dms.\n",
852 get_cmd_string(cmd->id), 874 trans_pcie_get_cmd_string(trans_pcie, cmd->id),
853 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 875 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
854 876
855 IWL_ERR(trans, 877 IWL_ERR(trans,
856 "Current CMD queue read_ptr %d write_ptr %d\n", 878 "Current CMD queue read_ptr %d write_ptr %d\n",
857 q->read_ptr, q->write_ptr); 879 q->read_ptr, q->write_ptr);
858 880
859 clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); 881 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
860 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command" 882 IWL_DEBUG_INFO(trans,
861 "%s\n", get_cmd_string(cmd->id)); 883 "Clearing HCMD_ACTIVE for command %s\n",
884 trans_pcie_get_cmd_string(trans_pcie,
885 cmd->id));
862 ret = -ETIMEDOUT; 886 ret = -ETIMEDOUT;
863 goto cancel; 887 goto cancel;
864 } 888 }
@@ -866,7 +890,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
866 890
867 if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { 891 if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) {
868 IWL_ERR(trans, "Error: Response NULL in '%s'\n", 892 IWL_ERR(trans, "Error: Response NULL in '%s'\n",
869 get_cmd_string(cmd->id)); 893 trans_pcie_get_cmd_string(trans_pcie, cmd->id));
870 ret = -EIO; 894 ret = -EIO;
871 goto cancel; 895 goto cancel;
872 } 896 }
@@ -949,5 +973,8 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
949 iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE); 973 iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE);
950 freed++; 974 freed++;
951 } 975 }
976
977 iwl_queue_progress(trans_pcie, txq);
978
952 return freed; 979 return freed;
953} 980}
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 9f62283504e3..14a32c420fd4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -132,10 +132,10 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans)
132 * to an SKB, so we need to unmap and free potential storage */ 132 * to an SKB, so we need to unmap and free potential storage */
133 if (rxq->pool[i].page != NULL) { 133 if (rxq->pool[i].page != NULL) {
134 dma_unmap_page(trans->dev, rxq->pool[i].page_dma, 134 dma_unmap_page(trans->dev, rxq->pool[i].page_dma,
135 PAGE_SIZE << hw_params(trans).rx_page_order, 135 PAGE_SIZE << trans_pcie->rx_page_order,
136 DMA_FROM_DEVICE); 136 DMA_FROM_DEVICE);
137 __free_pages(rxq->pool[i].page, 137 __free_pages(rxq->pool[i].page,
138 hw_params(trans).rx_page_order); 138 trans_pcie->rx_page_order);
139 rxq->pool[i].page = NULL; 139 rxq->pool[i].page = NULL;
140 } 140 }
141 list_add_tail(&rxq->pool[i].list, &rxq->rx_used); 141 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
@@ -145,11 +145,12 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans)
145static void iwl_trans_rx_hw_init(struct iwl_trans *trans, 145static void iwl_trans_rx_hw_init(struct iwl_trans *trans,
146 struct iwl_rx_queue *rxq) 146 struct iwl_rx_queue *rxq)
147{ 147{
148 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
148 u32 rb_size; 149 u32 rb_size;
149 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ 150 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
150 u32 rb_timeout = RX_RB_TIMEOUT; /* FIXME: RX_RB_TIMEOUT for all devices? */ 151 u32 rb_timeout = RX_RB_TIMEOUT; /* FIXME: RX_RB_TIMEOUT for all devices? */
151 152
152 if (iwlagn_mod_params.amsdu_size_8K) 153 if (trans_pcie->rx_buf_size_8k)
153 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; 154 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
154 else 155 else
155 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; 156 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
@@ -298,6 +299,33 @@ static inline void iwlagn_free_dma_ptr(struct iwl_trans *trans,
298 memset(ptr, 0, sizeof(*ptr)); 299 memset(ptr, 0, sizeof(*ptr));
299} 300}
300 301
302static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
303{
304 struct iwl_tx_queue *txq = (void *)data;
305 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
306 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
307
308 spin_lock(&txq->lock);
309 /* check if triggered erroneously */
310 if (txq->q.read_ptr == txq->q.write_ptr) {
311 spin_unlock(&txq->lock);
312 return;
313 }
314 spin_unlock(&txq->lock);
315
316
317 IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id,
318 jiffies_to_msecs(trans_pcie->wd_timeout));
319 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
320 txq->q.read_ptr, txq->q.write_ptr);
321 IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n",
322 iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq->q.id))
323 & (TFD_QUEUE_SIZE_MAX - 1),
324 iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq->q.id)));
325
326 iwl_op_mode_nic_error(trans->op_mode);
327}
328
301static int iwl_trans_txq_alloc(struct iwl_trans *trans, 329static int iwl_trans_txq_alloc(struct iwl_trans *trans,
302 struct iwl_tx_queue *txq, int slots_num, 330 struct iwl_tx_queue *txq, int slots_num,
303 u32 txq_id) 331 u32 txq_id)
@@ -309,6 +337,10 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
309 if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) 337 if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds))
310 return -EINVAL; 338 return -EINVAL;
311 339
340 setup_timer(&txq->stuck_timer, iwl_trans_pcie_queue_stuck_timer,
341 (unsigned long)txq);
342 txq->trans_pcie = trans_pcie;
343
312 txq->q.n_window = slots_num; 344 txq->q.n_window = slots_num;
313 345
314 txq->meta = kcalloc(slots_num, sizeof(txq->meta[0]), GFP_KERNEL); 346 txq->meta = kcalloc(slots_num, sizeof(txq->meta[0]), GFP_KERNEL);
@@ -471,6 +503,8 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id)
471 txq->cmd = NULL; 503 txq->cmd = NULL;
472 txq->meta = NULL; 504 txq->meta = NULL;
473 505
506 del_timer_sync(&txq->stuck_timer);
507
474 /* 0-fill queue descriptor structure */ 508 /* 0-fill queue descriptor structure */
475 memset(txq, 0, sizeof(*txq)); 509 memset(txq, 0, sizeof(*txq));
476} 510}
@@ -1214,6 +1248,12 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
1214 1248
1215 /* stop and reset the on-board processor */ 1249 /* stop and reset the on-board processor */
1216 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); 1250 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
1251
1252 /* clear all status bits */
1253 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
1254 clear_bit(STATUS_INT_ENABLED, &trans_pcie->status);
1255 clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status);
1256 clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status);
1217} 1257}
1218 1258
1219static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) 1259static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans)
@@ -1346,6 +1386,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1346 &dev_cmd->hdr, firstlen, 1386 &dev_cmd->hdr, firstlen,
1347 skb->data + hdr_len, secondlen); 1387 skb->data + hdr_len, secondlen);
1348 1388
1389 /* start timer if queue currently empty */
1390 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
1391 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
1392
1349 /* Tell device the write index *just past* this latest filled TFD */ 1393 /* Tell device the write index *just past* this latest filled TFD */
1350 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 1394 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
1351 iwl_txq_update_write_ptr(trans, txq); 1395 iwl_txq_update_write_ptr(trans, txq);
@@ -1441,8 +1485,6 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
1441 1485
1442 spin_lock(&txq->lock); 1486 spin_lock(&txq->lock);
1443 1487
1444 txq->time_stamp = jiffies;
1445
1446 if (txq->q.read_ptr != tfd_num) { 1488 if (txq->q.read_ptr != tfd_num) {
1447 IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", 1489 IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n",
1448 txq_id, txq->q.read_ptr, tfd_num, ssn); 1490 txq_id, txq->q.read_ptr, tfd_num, ssn);
@@ -1493,6 +1535,17 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
1493 1535
1494 memcpy(trans_pcie->setup_q_to_fifo, trans_cfg->queue_to_fifo, 1536 memcpy(trans_pcie->setup_q_to_fifo, trans_cfg->queue_to_fifo,
1495 trans_pcie->n_q_to_fifo * sizeof(u8)); 1537 trans_pcie->n_q_to_fifo * sizeof(u8));
1538
1539 trans_pcie->rx_buf_size_8k = trans_cfg->rx_buf_size_8k;
1540 if (trans_pcie->rx_buf_size_8k)
1541 trans_pcie->rx_page_order = get_order(8 * 1024);
1542 else
1543 trans_pcie->rx_page_order = get_order(4 * 1024);
1544
1545 trans_pcie->wd_timeout =
1546 msecs_to_jiffies(trans_cfg->queue_watchdog_timeout);
1547
1548 trans_pcie->command_names = trans_cfg->command_names;
1496} 1549}
1497 1550
1498static void iwl_trans_pcie_free(struct iwl_trans *trans) 1551static void iwl_trans_pcie_free(struct iwl_trans *trans)
@@ -1523,9 +1576,9 @@ static void iwl_trans_pcie_set_pmi(struct iwl_trans *trans, bool state)
1523 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1576 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1524 1577
1525 if (state) 1578 if (state)
1526 set_bit(STATUS_POWER_PMI, &trans_pcie->status); 1579 set_bit(STATUS_TPOWER_PMI, &trans_pcie->status);
1527 else 1580 else
1528 clear_bit(STATUS_POWER_PMI, &trans_pcie->status); 1581 clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status);
1529} 1582}
1530 1583
1531#ifdef CONFIG_PM_SLEEP 1584#ifdef CONFIG_PM_SLEEP
@@ -1582,42 +1635,9 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans)
1582 return ret; 1635 return ret;
1583} 1636}
1584 1637
1585/*
1586 * On every watchdog tick we check (latest) time stamp. If it does not
1587 * change during timeout period and queue is not empty we reset firmware.
1588 */
1589static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt)
1590{
1591 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1592 struct iwl_tx_queue *txq = &trans_pcie->txq[cnt];
1593 struct iwl_queue *q = &txq->q;
1594 unsigned long timeout;
1595
1596 if (q->read_ptr == q->write_ptr) {
1597 txq->time_stamp = jiffies;
1598 return 0;
1599 }
1600
1601 timeout = txq->time_stamp +
1602 msecs_to_jiffies(hw_params(trans).wd_timeout);
1603
1604 if (time_after(jiffies, timeout)) {
1605 IWL_ERR(trans, "Queue %d stuck for %u ms.\n", q->id,
1606 hw_params(trans).wd_timeout);
1607 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
1608 q->read_ptr, q->write_ptr);
1609 IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n",
1610 iwl_read_prph(trans, SCD_QUEUE_RDPTR(cnt))
1611 & (TFD_QUEUE_SIZE_MAX - 1),
1612 iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt)));
1613 return 1;
1614 }
1615
1616 return 0;
1617}
1618
1619static const char *get_fh_string(int cmd) 1638static const char *get_fh_string(int cmd)
1620{ 1639{
1640#define IWL_CMD(x) case x: return #x
1621 switch (cmd) { 1641 switch (cmd) {
1622 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); 1642 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
1623 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); 1643 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
@@ -1631,6 +1651,7 @@ static const char *get_fh_string(int cmd)
1631 default: 1651 default:
1632 return "UNKNOWN"; 1652 return "UNKNOWN";
1633 } 1653 }
1654#undef IWL_CMD
1634} 1655}
1635 1656
1636int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) 1657int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display)
@@ -1679,6 +1700,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display)
1679 1700
1680static const char *get_csr_string(int cmd) 1701static const char *get_csr_string(int cmd)
1681{ 1702{
1703#define IWL_CMD(x) case x: return #x
1682 switch (cmd) { 1704 switch (cmd) {
1683 IWL_CMD(CSR_HW_IF_CONFIG_REG); 1705 IWL_CMD(CSR_HW_IF_CONFIG_REG);
1684 IWL_CMD(CSR_INT_COALESCING); 1706 IWL_CMD(CSR_INT_COALESCING);
@@ -1706,6 +1728,7 @@ static const char *get_csr_string(int cmd)
1706 default: 1728 default:
1707 return "UNKNOWN"; 1729 return "UNKNOWN";
1708 } 1730 }
1731#undef IWL_CMD
1709} 1732}
1710 1733
1711void iwl_dump_csr(struct iwl_trans *trans) 1734void iwl_dump_csr(struct iwl_trans *trans)
@@ -1983,11 +2006,26 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
1983 return ret; 2006 return ret;
1984} 2007}
1985 2008
2009static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
2010 const char __user *user_buf,
2011 size_t count, loff_t *ppos)
2012{
2013 struct iwl_trans *trans = file->private_data;
2014
2015 if (!trans->op_mode)
2016 return -EAGAIN;
2017
2018 iwl_op_mode_nic_error(trans->op_mode);
2019
2020 return count;
2021}
2022
1986DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 2023DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
1987DEBUGFS_READ_FILE_OPS(fh_reg); 2024DEBUGFS_READ_FILE_OPS(fh_reg);
1988DEBUGFS_READ_FILE_OPS(rx_queue); 2025DEBUGFS_READ_FILE_OPS(rx_queue);
1989DEBUGFS_READ_FILE_OPS(tx_queue); 2026DEBUGFS_READ_FILE_OPS(tx_queue);
1990DEBUGFS_WRITE_FILE_OPS(csr); 2027DEBUGFS_WRITE_FILE_OPS(csr);
2028DEBUGFS_WRITE_FILE_OPS(fw_restart);
1991 2029
1992/* 2030/*
1993 * Create the debugfs files and directories 2031 * Create the debugfs files and directories
@@ -2001,6 +2039,7 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
2001 DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); 2039 DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);
2002 DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); 2040 DEBUGFS_ADD_FILE(csr, dir, S_IWUSR);
2003 DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); 2041 DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR);
2042 DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR);
2004 return 0; 2043 return 0;
2005} 2044}
2006#else 2045#else
@@ -2032,7 +2071,6 @@ const struct iwl_trans_ops trans_ops_pcie = {
2032 .dbgfs_register = iwl_trans_pcie_dbgfs_register, 2071 .dbgfs_register = iwl_trans_pcie_dbgfs_register,
2033 2072
2034 .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty, 2073 .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty,
2035 .check_stuck_queue = iwl_trans_pcie_check_stuck_queue,
2036 2074
2037#ifdef CONFIG_PM_SLEEP 2075#ifdef CONFIG_PM_SLEEP
2038 .suspend = iwl_trans_pcie_suspend, 2076 .suspend = iwl_trans_pcie_suspend,
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 66c54c1b404e..f3496a0490f0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -305,6 +305,12 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
305 * list of such notifications to filter. Max length is 305 * list of such notifications to filter. Max length is
306 * %MAX_NO_RECLAIM_CMDS. 306 * %MAX_NO_RECLAIM_CMDS.
307 * @n_no_reclaim_cmds: # of commands in list 307 * @n_no_reclaim_cmds: # of commands in list
308 * @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs,
309 * if unset 4k will be the RX buffer size
310 * @queue_watchdog_timeout: time (in ms) after which queues
311 * are considered stuck and will trigger device restart
312 * @command_names: array of command names, must be 256 entries
313 * (one for each command); for debugging only
308 */ 314 */
309struct iwl_trans_config { 315struct iwl_trans_config {
310 struct iwl_op_mode *op_mode; 316 struct iwl_op_mode *op_mode;
@@ -314,6 +320,10 @@ struct iwl_trans_config {
314 u8 cmd_queue; 320 u8 cmd_queue;
315 const u8 *no_reclaim_cmds; 321 const u8 *no_reclaim_cmds;
316 int n_no_reclaim_cmds; 322 int n_no_reclaim_cmds;
323
324 bool rx_buf_size_8k;
325 unsigned int queue_watchdog_timeout;
326 const char **command_names;
317}; 327};
318 328
319/** 329/**
@@ -351,7 +361,6 @@ struct iwl_trans_config {
351 * irq, tasklet etc... From this point on, the device may not issue 361 * irq, tasklet etc... From this point on, the device may not issue
352 * any interrupt (incl. RFKILL). 362 * any interrupt (incl. RFKILL).
353 * May sleep 363 * May sleep
354 * @check_stuck_queue: check if a specific queue is stuck
355 * @wait_tx_queue_empty: wait until all tx queues are empty 364 * @wait_tx_queue_empty: wait until all tx queues are empty
356 * May sleep 365 * May sleep
357 * @dbgfs_register: add the dbgfs files under this directory. Files will be 366 * @dbgfs_register: add the dbgfs files under this directory. Files will be
@@ -390,7 +399,6 @@ struct iwl_trans_ops {
390 void (*free)(struct iwl_trans *trans); 399 void (*free)(struct iwl_trans *trans);
391 400
392 int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); 401 int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
393 int (*check_stuck_queue)(struct iwl_trans *trans, int q);
394 int (*wait_tx_queue_empty)(struct iwl_trans *trans); 402 int (*wait_tx_queue_empty)(struct iwl_trans *trans);
395#ifdef CONFIG_PM_SLEEP 403#ifdef CONFIG_PM_SLEEP
396 int (*suspend)(struct iwl_trans *trans); 404 int (*suspend)(struct iwl_trans *trans);
@@ -426,7 +434,6 @@ enum iwl_trans_state {
426 * @hw_id: a u32 with the ID of the device / subdevice. 434 * @hw_id: a u32 with the ID of the device / subdevice.
427 * Set during transport allocation. 435 * Set during transport allocation.
428 * @hw_id_str: a string with info about HW ID. Set during transport allocation. 436 * @hw_id_str: a string with info about HW ID. Set during transport allocation.
429 * @nvm_device_type: indicates OTP or eeprom
430 * @pm_support: set to true in start_hw if link pm is supported 437 * @pm_support: set to true in start_hw if link pm is supported
431 * @wait_command_queue: the wait_queue for SYNC host commands 438 * @wait_command_queue: the wait_queue for SYNC host commands
432 */ 439 */
@@ -442,7 +449,6 @@ struct iwl_trans {
442 u32 hw_id; 449 u32 hw_id;
443 char hw_id_str[52]; 450 char hw_id_str[52];
444 451
445 int nvm_device_type;
446 bool pm_support; 452 bool pm_support;
447 453
448 wait_queue_head_t wait_command_queue; 454 wait_queue_head_t wait_command_queue;
@@ -573,13 +579,6 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
573 return trans->ops->wait_tx_queue_empty(trans); 579 return trans->ops->wait_tx_queue_empty(trans);
574} 580}
575 581
576static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q)
577{
578 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
579 "%s bad state = %d", __func__, trans->state);
580
581 return trans->ops->check_stuck_queue(trans, q);
582}
583static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, 582static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
584 struct dentry *dir) 583 struct dentry *dir)
585{ 584{
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c
index ba7c9f883cb6..539171945610 100644
--- a/drivers/net/wireless/iwlwifi/iwl-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c
@@ -62,7 +62,7 @@ static int iwl_set_Xtal_calib(struct iwl_priv *priv)
62{ 62{
63 struct iwl_calib_xtal_freq_cmd cmd; 63 struct iwl_calib_xtal_freq_cmd cmd;
64 __le16 *xtal_calib = 64 __le16 *xtal_calib =
65 (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL); 65 (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL);
66 66
67 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); 67 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD);
68 cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); 68 cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
@@ -74,8 +74,7 @@ static int iwl_set_temperature_offset_calib(struct iwl_priv *priv)
74{ 74{
75 struct iwl_calib_temperature_offset_cmd cmd; 75 struct iwl_calib_temperature_offset_cmd cmd;
76 __le16 *offset_calib = 76 __le16 *offset_calib =
77 (__le16 *)iwl_eeprom_query_addr(priv->shrd, 77 (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE);
78 EEPROM_RAW_TEMPERATURE);
79 78
80 memset(&cmd, 0, sizeof(cmd)); 79 memset(&cmd, 0, sizeof(cmd));
81 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); 80 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD);
@@ -91,16 +90,15 @@ static int iwl_set_temperature_offset_calib(struct iwl_priv *priv)
91static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) 90static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv)
92{ 91{
93 struct iwl_calib_temperature_offset_v2_cmd cmd; 92 struct iwl_calib_temperature_offset_v2_cmd cmd;
94 __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd, 93 __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv,
95 EEPROM_KELVIN_TEMPERATURE); 94 EEPROM_KELVIN_TEMPERATURE);
96 __le16 *offset_calib_low = 95 __le16 *offset_calib_low =
97 (__le16 *)iwl_eeprom_query_addr(priv->shrd, 96 (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE);
98 EEPROM_RAW_TEMPERATURE);
99 struct iwl_eeprom_calib_hdr *hdr; 97 struct iwl_eeprom_calib_hdr *hdr;
100 98
101 memset(&cmd, 0, sizeof(cmd)); 99 memset(&cmd, 0, sizeof(cmd));
102 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); 100 iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD);
103 hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd, 101 hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
104 EEPROM_CALIB_ALL); 102 EEPROM_CALIB_ALL);
105 memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, 103 memcpy(&cmd.radio_sensor_offset_high, offset_calib_high,
106 sizeof(*offset_calib_high)); 104 sizeof(*offset_calib_high));
@@ -180,7 +178,7 @@ int iwl_init_alive_start(struct iwl_priv *priv)
180 return 0; 178 return 0;
181} 179}
182 180
183static int iwl_send_wimax_coex(struct iwl_priv *priv) 181int iwl_send_wimax_coex(struct iwl_priv *priv)
184{ 182{
185 struct iwl_wimax_coex_cmd coex_cmd; 183 struct iwl_wimax_coex_cmd coex_cmd;
186 184
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index f7d01bfa2e4a..eac72f7bd341 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -6,6 +6,7 @@ libertas-y += ethtool.o
6libertas-y += main.o 6libertas-y += main.o
7libertas-y += rx.o 7libertas-y += rx.o
8libertas-y += tx.o 8libertas-y += tx.o
9libertas-y += firmware.o
9libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o 10libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o
10 11
11usb8xxx-objs += if_usb.o 12usb8xxx-objs += if_usb.o
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index bc951ab4b681..84a3aa7ac570 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -19,6 +19,10 @@ struct lbs_fw_table {
19}; 19};
20 20
21struct lbs_private; 21struct lbs_private;
22typedef void (*lbs_fw_cb)(struct lbs_private *priv, int ret,
23 const struct firmware *helper, const struct firmware *mainfw);
24
25struct lbs_private;
22struct sk_buff; 26struct sk_buff;
23struct net_device; 27struct net_device;
24struct cmd_ds_command; 28struct cmd_ds_command;
@@ -66,10 +70,13 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
66u32 lbs_fw_index_to_data_rate(u8 index); 70u32 lbs_fw_index_to_data_rate(u8 index);
67u8 lbs_data_rate_to_fw_index(u32 rate); 71u8 lbs_data_rate_to_fw_index(u32 rate);
68 72
69int lbs_get_firmware(struct device *dev, const char *user_helper, 73int lbs_get_firmware(struct device *dev, u32 card_model,
70 const char *user_mainfw, u32 card_model,
71 const struct lbs_fw_table *fw_table, 74 const struct lbs_fw_table *fw_table,
72 const struct firmware **helper, 75 const struct firmware **helper,
73 const struct firmware **mainfw); 76 const struct firmware **mainfw);
77int lbs_get_firmware_async(struct lbs_private *priv, struct device *device,
78 u32 card_model, const struct lbs_fw_table *fw_table,
79 lbs_fw_cb callback);
80void lbs_wait_for_firmware_load(struct lbs_private *priv);
74 81
75#endif 82#endif
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index f3fd447131c2..672005430aca 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -7,6 +7,7 @@
7#define _LBS_DEV_H_ 7#define _LBS_DEV_H_
8 8
9#include "defs.h" 9#include "defs.h"
10#include "decl.h"
10#include "host.h" 11#include "host.h"
11 12
12#include <linux/kfifo.h> 13#include <linux/kfifo.h>
@@ -180,6 +181,15 @@ struct lbs_private {
180 wait_queue_head_t scan_q; 181 wait_queue_head_t scan_q;
181 /* Whether the scan was initiated internally and not by cfg80211 */ 182 /* Whether the scan was initiated internally and not by cfg80211 */
182 bool internal_scan; 183 bool internal_scan;
184
185 /* Firmware load */
186 u32 fw_model;
187 wait_queue_head_t fw_waitq;
188 struct device *fw_device;
189 const struct firmware *helper_fw;
190 const struct lbs_fw_table *fw_table;
191 const struct lbs_fw_table *fw_iter;
192 lbs_fw_cb fw_callback;
183}; 193};
184 194
185extern struct cmd_confirm_sleep confirm_sleep; 195extern struct cmd_confirm_sleep confirm_sleep;
diff --git a/drivers/net/wireless/libertas/firmware.c b/drivers/net/wireless/libertas/firmware.c
new file mode 100644
index 000000000000..cd23f1a8c98a
--- /dev/null
+++ b/drivers/net/wireless/libertas/firmware.c
@@ -0,0 +1,222 @@
1/*
2 * Firmware loading and handling functions.
3 */
4
5#include <linux/firmware.h>
6#include <linux/firmware.h>
7#include <linux/module.h>
8
9#include "dev.h"
10#include "decl.h"
11
12static void load_next_firmware_from_table(struct lbs_private *private);
13
14static void lbs_fw_loaded(struct lbs_private *priv, int ret,
15 const struct firmware *helper, const struct firmware *mainfw)
16{
17 unsigned long flags;
18
19 lbs_deb_fw("firmware load complete, code %d\n", ret);
20
21 /* User must free helper/mainfw */
22 priv->fw_callback(priv, ret, helper, mainfw);
23
24 spin_lock_irqsave(&priv->driver_lock, flags);
25 priv->fw_callback = NULL;
26 wake_up(&priv->fw_waitq);
27 spin_unlock_irqrestore(&priv->driver_lock, flags);
28}
29
30static void do_load_firmware(struct lbs_private *priv, const char *name,
31 void (*cb)(const struct firmware *fw, void *context))
32{
33 int ret;
34
35 lbs_deb_fw("Requesting %s\n", name);
36 ret = request_firmware_nowait(THIS_MODULE, true, name,
37 priv->fw_device, GFP_KERNEL, priv, cb);
38 if (ret) {
39 lbs_deb_fw("request_firmware_nowait error %d\n", ret);
40 lbs_fw_loaded(priv, ret, NULL, NULL);
41 }
42}
43
44static void main_firmware_cb(const struct firmware *firmware, void *context)
45{
46 struct lbs_private *priv = context;
47
48 if (!firmware) {
49 /* Failed to find firmware: try next table entry */
50 load_next_firmware_from_table(priv);
51 return;
52 }
53
54 /* Firmware found! */
55 lbs_fw_loaded(priv, 0, priv->helper_fw, firmware);
56}
57
58static void helper_firmware_cb(const struct firmware *firmware, void *context)
59{
60 struct lbs_private *priv = context;
61
62 if (!firmware) {
63 /* Failed to find firmware: try next table entry */
64 load_next_firmware_from_table(priv);
65 return;
66 }
67
68 /* Firmware found! */
69 if (priv->fw_iter->fwname) {
70 priv->helper_fw = firmware;
71 do_load_firmware(priv, priv->fw_iter->fwname, main_firmware_cb);
72 } else {
73 /* No main firmware needed for this helper --> success! */
74 lbs_fw_loaded(priv, 0, firmware, NULL);
75 }
76}
77
78static void load_next_firmware_from_table(struct lbs_private *priv)
79{
80 const struct lbs_fw_table *iter;
81
82 if (!priv->fw_iter)
83 iter = priv->fw_table;
84 else
85 iter = ++priv->fw_iter;
86
87 if (priv->helper_fw) {
88 release_firmware(priv->helper_fw);
89 priv->helper_fw = NULL;
90 }
91
92next:
93 if (!iter->helper) {
94 /* End of table hit. */
95 lbs_fw_loaded(priv, -ENOENT, NULL, NULL);
96 return;
97 }
98
99 if (iter->model != priv->fw_model) {
100 iter++;
101 goto next;
102 }
103
104 priv->fw_iter = iter;
105 do_load_firmware(priv, iter->helper, helper_firmware_cb);
106}
107
108void lbs_wait_for_firmware_load(struct lbs_private *priv)
109{
110 wait_event(priv->fw_waitq, priv->fw_callback == NULL);
111}
112
113/**
114 * lbs_get_firmware_async - Retrieves firmware asynchronously. Can load
115 * either a helper firmware and a main firmware (2-stage), or just the helper.
116 *
117 * @priv: Pointer to lbs_private instance
118 * @dev: A pointer to &device structure
119 * @card_model: Bus-specific card model ID used to filter firmware table
120 * elements
121 * @fw_table: Table of firmware file names and device model numbers
122 * terminated by an entry with a NULL helper name
123 * @callback: User callback to invoke when firmware load succeeds or fails.
124 */
125int lbs_get_firmware_async(struct lbs_private *priv, struct device *device,
126 u32 card_model, const struct lbs_fw_table *fw_table,
127 lbs_fw_cb callback)
128{
129 unsigned long flags;
130
131 spin_lock_irqsave(&priv->driver_lock, flags);
132 if (priv->fw_callback) {
133 lbs_deb_fw("firmware load already in progress\n");
134 spin_unlock_irqrestore(&priv->driver_lock, flags);
135 return -EBUSY;
136 }
137
138 priv->fw_device = device;
139 priv->fw_callback = callback;
140 priv->fw_table = fw_table;
141 priv->fw_iter = NULL;
142 priv->fw_model = card_model;
143 spin_unlock_irqrestore(&priv->driver_lock, flags);
144
145 lbs_deb_fw("Starting async firmware load\n");
146 load_next_firmware_from_table(priv);
147 return 0;
148}
149EXPORT_SYMBOL_GPL(lbs_get_firmware_async);
150
151/**
152 * lbs_get_firmware - Retrieves two-stage firmware
153 *
154 * @dev: A pointer to &device structure
155 * @card_model: Bus-specific card model ID used to filter firmware table
156 * elements
157 * @fw_table: Table of firmware file names and device model numbers
158 * terminated by an entry with a NULL helper name
159 * @helper: On success, the helper firmware; caller must free
160 * @mainfw: On success, the main firmware; caller must free
161 *
162 * Deprecated: use lbs_get_firmware_async() instead.
163 *
164 * returns: 0 on success, non-zero on failure
165 */
166int lbs_get_firmware(struct device *dev, u32 card_model,
167 const struct lbs_fw_table *fw_table,
168 const struct firmware **helper,
169 const struct firmware **mainfw)
170{
171 const struct lbs_fw_table *iter;
172 int ret;
173
174 BUG_ON(helper == NULL);
175 BUG_ON(mainfw == NULL);
176
177 /* Search for firmware to use from the table. */
178 iter = fw_table;
179 while (iter && iter->helper) {
180 if (iter->model != card_model)
181 goto next;
182
183 if (*helper == NULL) {
184 ret = request_firmware(helper, iter->helper, dev);
185 if (ret)
186 goto next;
187
188 /* If the device has one-stage firmware (ie cf8305) and
189 * we've got it then we don't need to bother with the
190 * main firmware.
191 */
192 if (iter->fwname == NULL)
193 return 0;
194 }
195
196 if (*mainfw == NULL) {
197 ret = request_firmware(mainfw, iter->fwname, dev);
198 if (ret) {
199 /* Clear the helper to ensure we don't have
200 * mismatched firmware pairs.
201 */
202 release_firmware(*helper);
203 *helper = NULL;
204 }
205 }
206
207 if (*helper && *mainfw)
208 return 0;
209
210 next:
211 iter++;
212 }
213
214 /* Failed */
215 release_firmware(*helper);
216 *helper = NULL;
217 release_firmware(*mainfw);
218 *mainfw = NULL;
219
220 return -ENOENT;
221}
222EXPORT_SYMBOL_GPL(lbs_get_firmware);
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 234ee88dec95..cee50528522b 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -890,8 +890,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
890 goto out2; 890 goto out2;
891 } 891 }
892 892
893 ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model, 893 ret = lbs_get_firmware(&p_dev->dev, card->model, &fw_table[0],
894 &fw_table[0], &helper, &mainfw); 894 &helper, &mainfw);
895 if (ret) { 895 if (ret) {
896 pr_err("failed to find firmware (%d)\n", ret); 896 pr_err("failed to find firmware (%d)\n", ret);
897 goto out2; 897 goto out2;
@@ -951,10 +951,8 @@ out2:
951out1: 951out1:
952 pcmcia_disable_device(p_dev); 952 pcmcia_disable_device(p_dev);
953out: 953out:
954 if (helper) 954 release_firmware(helper);
955 release_firmware(helper); 955 release_firmware(mainfw);
956 if (mainfw)
957 release_firmware(mainfw);
958 956
959 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); 957 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
960 return ret; 958 return ret;
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 9804ebc892d4..76caebaa4397 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -65,12 +65,6 @@ static void if_sdio_interrupt(struct sdio_func *func);
65 */ 65 */
66static u8 user_rmmod; 66static u8 user_rmmod;
67 67
68static char *lbs_helper_name = NULL;
69module_param_named(helper_name, lbs_helper_name, charp, 0644);
70
71static char *lbs_fw_name = NULL;
72module_param_named(fw_name, lbs_fw_name, charp, 0644);
73
74static const struct sdio_device_id if_sdio_ids[] = { 68static const struct sdio_device_id if_sdio_ids[] = {
75 { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 69 { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
76 SDIO_DEVICE_ID_MARVELL_LIBERTAS) }, 70 SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
@@ -123,11 +117,8 @@ struct if_sdio_card {
123 int model; 117 int model;
124 unsigned long ioport; 118 unsigned long ioport;
125 unsigned int scratch_reg; 119 unsigned int scratch_reg;
126 120 bool started;
127 const char *helper; 121 wait_queue_head_t pwron_waitq;
128 const char *firmware;
129 bool helper_allocated;
130 bool firmware_allocated;
131 122
132 u8 buffer[65536] __attribute__((aligned(4))); 123 u8 buffer[65536] __attribute__((aligned(4)));
133 124
@@ -140,6 +131,9 @@ struct if_sdio_card {
140 u8 rx_unit; 131 u8 rx_unit;
141}; 132};
142 133
134static void if_sdio_finish_power_on(struct if_sdio_card *card);
135static int if_sdio_power_off(struct if_sdio_card *card);
136
143/********************************************************************/ 137/********************************************************************/
144/* I/O */ 138/* I/O */
145/********************************************************************/ 139/********************************************************************/
@@ -680,12 +674,39 @@ out:
680 return ret; 674 return ret;
681} 675}
682 676
677static void if_sdio_do_prog_firmware(struct lbs_private *priv, int ret,
678 const struct firmware *helper,
679 const struct firmware *mainfw)
680{
681 struct if_sdio_card *card = priv->card;
682
683 if (ret) {
684 pr_err("failed to find firmware (%d)\n", ret);
685 return;
686 }
687
688 ret = if_sdio_prog_helper(card, helper);
689 if (ret)
690 goto out;
691
692 lbs_deb_sdio("Helper firmware loaded\n");
693
694 ret = if_sdio_prog_real(card, mainfw);
695 if (ret)
696 goto out;
697
698 lbs_deb_sdio("Firmware loaded\n");
699 if_sdio_finish_power_on(card);
700
701out:
702 release_firmware(helper);
703 release_firmware(mainfw);
704}
705
683static int if_sdio_prog_firmware(struct if_sdio_card *card) 706static int if_sdio_prog_firmware(struct if_sdio_card *card)
684{ 707{
685 int ret; 708 int ret;
686 u16 scratch; 709 u16 scratch;
687 const struct firmware *helper = NULL;
688 const struct firmware *mainfw = NULL;
689 710
690 lbs_deb_enter(LBS_DEB_SDIO); 711 lbs_deb_enter(LBS_DEB_SDIO);
691 712
@@ -719,43 +740,18 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
719 */ 740 */
720 if (scratch == IF_SDIO_FIRMWARE_OK) { 741 if (scratch == IF_SDIO_FIRMWARE_OK) {
721 lbs_deb_sdio("firmware already loaded\n"); 742 lbs_deb_sdio("firmware already loaded\n");
722 goto success; 743 if_sdio_finish_power_on(card);
744 return 0;
723 } else if ((card->model == MODEL_8686) && (scratch & 0x7fff)) { 745 } else if ((card->model == MODEL_8686) && (scratch & 0x7fff)) {
724 lbs_deb_sdio("firmware may be running\n"); 746 lbs_deb_sdio("firmware may be running\n");
725 goto success; 747 if_sdio_finish_power_on(card);
726 } 748 return 0;
727
728 ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name,
729 card->model, &fw_table[0], &helper, &mainfw);
730 if (ret) {
731 pr_err("failed to find firmware (%d)\n", ret);
732 goto out;
733 } 749 }
734 750
735 ret = if_sdio_prog_helper(card, helper); 751 ret = lbs_get_firmware_async(card->priv, &card->func->dev, card->model,
736 if (ret) 752 fw_table, if_sdio_do_prog_firmware);
737 goto out;
738
739 lbs_deb_sdio("Helper firmware loaded\n");
740
741 ret = if_sdio_prog_real(card, mainfw);
742 if (ret)
743 goto out;
744
745 lbs_deb_sdio("Firmware loaded\n");
746
747success:
748 sdio_claim_host(card->func);
749 sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
750 sdio_release_host(card->func);
751 ret = 0;
752 753
753out: 754out:
754 if (helper)
755 release_firmware(helper);
756 if (mainfw)
757 release_firmware(mainfw);
758
759 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 755 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
760 return ret; 756 return ret;
761} 757}
@@ -764,55 +760,15 @@ out:
764/* Power management */ 760/* Power management */
765/********************************************************************/ 761/********************************************************************/
766 762
767static int if_sdio_power_on(struct if_sdio_card *card) 763/* Finish power on sequence (after firmware is loaded) */
764static void if_sdio_finish_power_on(struct if_sdio_card *card)
768{ 765{
769 struct sdio_func *func = card->func; 766 struct sdio_func *func = card->func;
770 struct lbs_private *priv = card->priv; 767 struct lbs_private *priv = card->priv;
771 struct mmc_host *host = func->card->host;
772 int ret; 768 int ret;
773 769
774 sdio_claim_host(func); 770 sdio_claim_host(func);
775 771 sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
776 ret = sdio_enable_func(func);
777 if (ret)
778 goto release;
779
780 /* For 1-bit transfers to the 8686 model, we need to enable the
781 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
782 * bit to allow access to non-vendor registers. */
783 if ((card->model == MODEL_8686) &&
784 (host->caps & MMC_CAP_SDIO_IRQ) &&
785 (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
786 u8 reg;
787
788 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
789 reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret);
790 if (ret)
791 goto disable;
792
793 reg |= SDIO_BUS_ECSI;
794 sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret);
795 if (ret)
796 goto disable;
797 }
798
799 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
800 if (ret)
801 goto disable;
802
803 card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8;
804 if (ret)
805 goto disable;
806
807 card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16;
808 if (ret)
809 goto disable;
810
811 sdio_release_host(func);
812 ret = if_sdio_prog_firmware(card);
813 sdio_claim_host(func);
814 if (ret)
815 goto disable;
816 772
817 /* 773 /*
818 * Get rx_unit if the chip is SD8688 or newer. 774 * Get rx_unit if the chip is SD8688 or newer.
@@ -837,7 +793,7 @@ static int if_sdio_power_on(struct if_sdio_card *card)
837 */ 793 */
838 ret = sdio_claim_irq(func, if_sdio_interrupt); 794 ret = sdio_claim_irq(func, if_sdio_interrupt);
839 if (ret) 795 if (ret)
840 goto disable; 796 goto release;
841 797
842 /* 798 /*
843 * Enable interrupts now that everything is set up 799 * Enable interrupts now that everything is set up
@@ -863,11 +819,79 @@ static int if_sdio_power_on(struct if_sdio_card *card)
863 } 819 }
864 820
865 priv->fw_ready = 1; 821 priv->fw_ready = 1;
822 wake_up(&card->pwron_waitq);
866 823
867 return 0; 824 if (!card->started) {
825 ret = lbs_start_card(priv);
826 if_sdio_power_off(card);
827 if (ret == 0) {
828 card->started = true;
829 /* Tell PM core that we don't need the card to be
830 * powered now */
831 pm_runtime_put_noidle(&func->dev);
832 }
833 }
834
835 return;
868 836
869release_irq: 837release_irq:
870 sdio_release_irq(func); 838 sdio_release_irq(func);
839release:
840 sdio_release_host(func);
841}
842
843static int if_sdio_power_on(struct if_sdio_card *card)
844{
845 struct sdio_func *func = card->func;
846 struct mmc_host *host = func->card->host;
847 int ret;
848
849 sdio_claim_host(func);
850
851 ret = sdio_enable_func(func);
852 if (ret)
853 goto release;
854
855 /* For 1-bit transfers to the 8686 model, we need to enable the
856 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
857 * bit to allow access to non-vendor registers. */
858 if ((card->model == MODEL_8686) &&
859 (host->caps & MMC_CAP_SDIO_IRQ) &&
860 (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
861 u8 reg;
862
863 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
864 reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret);
865 if (ret)
866 goto disable;
867
868 reg |= SDIO_BUS_ECSI;
869 sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret);
870 if (ret)
871 goto disable;
872 }
873
874 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
875 if (ret)
876 goto disable;
877
878 card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8;
879 if (ret)
880 goto disable;
881
882 card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16;
883 if (ret)
884 goto disable;
885
886 sdio_release_host(func);
887 ret = if_sdio_prog_firmware(card);
888 if (ret) {
889 sdio_disable_func(func);
890 return ret;
891 }
892
893 return 0;
894
871disable: 895disable:
872 sdio_disable_func(func); 896 sdio_disable_func(func);
873release: 897release:
@@ -1074,11 +1098,17 @@ static int if_sdio_power_save(struct lbs_private *priv)
1074static int if_sdio_power_restore(struct lbs_private *priv) 1098static int if_sdio_power_restore(struct lbs_private *priv)
1075{ 1099{
1076 struct if_sdio_card *card = priv->card; 1100 struct if_sdio_card *card = priv->card;
1101 int r;
1077 1102
1078 /* Make sure the card will not be powered off by runtime PM */ 1103 /* Make sure the card will not be powered off by runtime PM */
1079 pm_runtime_get_sync(&card->func->dev); 1104 pm_runtime_get_sync(&card->func->dev);
1080 1105
1081 return if_sdio_power_on(card); 1106 r = if_sdio_power_on(card);
1107 if (r)
1108 return r;
1109
1110 wait_event(card->pwron_waitq, priv->fw_ready);
1111 return 0;
1082} 1112}
1083 1113
1084 1114
@@ -1179,6 +1209,7 @@ static int if_sdio_probe(struct sdio_func *func,
1179 spin_lock_init(&card->lock); 1209 spin_lock_init(&card->lock);
1180 card->workqueue = create_workqueue("libertas_sdio"); 1210 card->workqueue = create_workqueue("libertas_sdio");
1181 INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); 1211 INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
1212 init_waitqueue_head(&card->pwron_waitq);
1182 1213
1183 /* Check if we support this card */ 1214 /* Check if we support this card */
1184 for (i = 0; i < ARRAY_SIZE(fw_table); i++) { 1215 for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
@@ -1220,14 +1251,6 @@ static int if_sdio_probe(struct sdio_func *func,
1220 if (ret) 1251 if (ret)
1221 goto err_activate_card; 1252 goto err_activate_card;
1222 1253
1223 ret = lbs_start_card(priv);
1224 if_sdio_power_off(card);
1225 if (ret)
1226 goto err_activate_card;
1227
1228 /* Tell PM core that we don't need the card to be powered now */
1229 pm_runtime_put_noidle(&func->dev);
1230
1231out: 1254out:
1232 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 1255 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
1233 1256
@@ -1244,10 +1267,6 @@ free:
1244 kfree(packet); 1267 kfree(packet);
1245 } 1268 }
1246 1269
1247 if (card->helper_allocated)
1248 kfree(card->helper);
1249 if (card->firmware_allocated)
1250 kfree(card->firmware);
1251 kfree(card); 1270 kfree(card);
1252 1271
1253 goto out; 1272 goto out;
@@ -1295,12 +1314,6 @@ static void if_sdio_remove(struct sdio_func *func)
1295 kfree(packet); 1314 kfree(packet);
1296 } 1315 }
1297 1316
1298 if (card->helper_allocated)
1299 kfree(card->helper);
1300 if (card->firmware_allocated)
1301 kfree(card->firmware);
1302 kfree(card);
1303
1304 lbs_deb_leave(LBS_DEB_SDIO); 1317 lbs_deb_leave(LBS_DEB_SDIO);
1305} 1318}
1306 1319
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 50b1ee7721e9..9604a1c4a74d 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -1064,9 +1064,8 @@ static int if_spi_init_card(struct if_spi_card *card)
1064 goto out; 1064 goto out;
1065 } 1065 }
1066 1066
1067 err = lbs_get_firmware(&card->spi->dev, NULL, NULL, 1067 err = lbs_get_firmware(&card->spi->dev, card->card_id,
1068 card->card_id, &fw_table[0], &helper, 1068 &fw_table[0], &helper, &mainfw);
1069 &mainfw);
1070 if (err) { 1069 if (err) {
1071 netdev_err(priv->dev, "failed to find firmware (%d)\n", 1070 netdev_err(priv->dev, "failed to find firmware (%d)\n",
1072 err); 1071 err);
@@ -1095,10 +1094,8 @@ static int if_spi_init_card(struct if_spi_card *card)
1095 goto out; 1094 goto out;
1096 1095
1097out: 1096out:
1098 if (helper) 1097 release_firmware(helper);
1099 release_firmware(helper); 1098 release_firmware(mainfw);
1100 if (mainfw)
1101 release_firmware(mainfw);
1102 1099
1103 lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); 1100 lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
1104 1101
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 74da5f1ea243..75403e6e3990 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -29,9 +29,6 @@
29 29
30#define MESSAGE_HEADER_LEN 4 30#define MESSAGE_HEADER_LEN 4
31 31
32static char *lbs_fw_name = NULL;
33module_param_named(fw_name, lbs_fw_name, charp, 0644);
34
35MODULE_FIRMWARE("libertas/usb8388_v9.bin"); 32MODULE_FIRMWARE("libertas/usb8388_v9.bin");
36MODULE_FIRMWARE("libertas/usb8388_v5.bin"); 33MODULE_FIRMWARE("libertas/usb8388_v5.bin");
37MODULE_FIRMWARE("libertas/usb8388.bin"); 34MODULE_FIRMWARE("libertas/usb8388.bin");
@@ -44,6 +41,16 @@ enum {
44 MODEL_8682 = 0x2 41 MODEL_8682 = 0x2
45}; 42};
46 43
44/* table of firmware file names */
45static const struct lbs_fw_table fw_table[] = {
46 { MODEL_8388, "libertas/usb8388_olpc.bin", NULL },
47 { MODEL_8388, "libertas/usb8388_v9.bin", NULL },
48 { MODEL_8388, "libertas/usb8388_v5.bin", NULL },
49 { MODEL_8388, "libertas/usb8388.bin", NULL },
50 { MODEL_8388, "usb8388.bin", NULL },
51 { MODEL_8682, "libertas/usb8682.bin", NULL }
52};
53
47static struct usb_device_id if_usb_table[] = { 54static struct usb_device_id if_usb_table[] = {
48 /* Enter the device signature inside */ 55 /* Enter the device signature inside */
49 { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 }, 56 { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 },
@@ -55,10 +62,9 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
55 62
56static void if_usb_receive(struct urb *urb); 63static void if_usb_receive(struct urb *urb);
57static void if_usb_receive_fwload(struct urb *urb); 64static void if_usb_receive_fwload(struct urb *urb);
58static int __if_usb_prog_firmware(struct if_usb_card *cardp, 65static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
59 const char *fwname, int cmd); 66 const struct firmware *fw,
60static int if_usb_prog_firmware(struct if_usb_card *cardp, 67 const struct firmware *unused);
61 const char *fwname, int cmd);
62static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, 68static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
63 uint8_t *payload, uint16_t nb); 69 uint8_t *payload, uint16_t nb);
64static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, 70static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
@@ -67,69 +73,6 @@ static void if_usb_free(struct if_usb_card *cardp);
67static int if_usb_submit_rx_urb(struct if_usb_card *cardp); 73static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
68static int if_usb_reset_device(struct if_usb_card *cardp); 74static int if_usb_reset_device(struct if_usb_card *cardp);
69 75
70/* sysfs hooks */
71
72/*
73 * Set function to write firmware to device's persistent memory
74 */
75static ssize_t if_usb_firmware_set(struct device *dev,
76 struct device_attribute *attr, const char *buf, size_t count)
77{
78 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
79 struct if_usb_card *cardp = priv->card;
80 int ret;
81
82 BUG_ON(buf == NULL);
83
84 ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW);
85 if (ret == 0)
86 return count;
87
88 return ret;
89}
90
91/*
92 * lbs_flash_fw attribute to be exported per ethX interface through sysfs
93 * (/sys/class/net/ethX/lbs_flash_fw). Use this like so to write firmware to
94 * the device's persistent memory:
95 * echo usb8388-5.126.0.p5.bin > /sys/class/net/ethX/lbs_flash_fw
96 */
97static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set);
98
99/**
100 * if_usb_boot2_set - write firmware to device's persistent memory
101 *
102 * @dev: target device
103 * @attr: device attributes
104 * @buf: firmware buffer to write
105 * @count: number of bytes to write
106 *
107 * returns: number of bytes written or negative error code
108 */
109static ssize_t if_usb_boot2_set(struct device *dev,
110 struct device_attribute *attr, const char *buf, size_t count)
111{
112 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
113 struct if_usb_card *cardp = priv->card;
114 int ret;
115
116 BUG_ON(buf == NULL);
117
118 ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2);
119 if (ret == 0)
120 return count;
121
122 return ret;
123}
124
125/*
126 * lbs_flash_boot2 attribute to be exported per ethX interface through sysfs
127 * (/sys/class/net/ethX/lbs_flash_boot2). Use this like so to write firmware
128 * to the device's persistent memory:
129 * echo usb8388-5.126.0.p5.bin > /sys/class/net/ethX/lbs_flash_boot2
130 */
131static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set);
132
133/** 76/**
134 * if_usb_write_bulk_callback - callback function to handle the status 77 * if_usb_write_bulk_callback - callback function to handle the status
135 * of the URB 78 * of the URB
@@ -256,6 +199,7 @@ static int if_usb_probe(struct usb_interface *intf,
256 struct usb_endpoint_descriptor *endpoint; 199 struct usb_endpoint_descriptor *endpoint;
257 struct lbs_private *priv; 200 struct lbs_private *priv;
258 struct if_usb_card *cardp; 201 struct if_usb_card *cardp;
202 int r = -ENOMEM;
259 int i; 203 int i;
260 204
261 udev = interface_to_usbdev(intf); 205 udev = interface_to_usbdev(intf);
@@ -313,20 +257,10 @@ static int if_usb_probe(struct usb_interface *intf,
313 goto dealloc; 257 goto dealloc;
314 } 258 }
315 259
316 /* Upload firmware */
317 kparam_block_sysfs_write(fw_name);
318 if (__if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) {
319 kparam_unblock_sysfs_write(fw_name);
320 lbs_deb_usbd(&udev->dev, "FW upload failed\n");
321 goto err_prog_firmware;
322 }
323 kparam_unblock_sysfs_write(fw_name);
324
325 if (!(priv = lbs_add_card(cardp, &intf->dev))) 260 if (!(priv = lbs_add_card(cardp, &intf->dev)))
326 goto err_prog_firmware; 261 goto err_add_card;
327 262
328 cardp->priv = priv; 263 cardp->priv = priv;
329 cardp->priv->fw_ready = 1;
330 264
331 priv->hw_host_to_card = if_usb_host_to_card; 265 priv->hw_host_to_card = if_usb_host_to_card;
332 priv->enter_deep_sleep = NULL; 266 priv->enter_deep_sleep = NULL;
@@ -339,42 +273,25 @@ static int if_usb_probe(struct usb_interface *intf,
339 273
340 cardp->boot2_version = udev->descriptor.bcdDevice; 274 cardp->boot2_version = udev->descriptor.bcdDevice;
341 275
342 if_usb_submit_rx_urb(cardp);
343
344 if (lbs_start_card(priv))
345 goto err_start_card;
346
347 if_usb_setup_firmware(priv);
348
349 usb_get_dev(udev); 276 usb_get_dev(udev);
350 usb_set_intfdata(intf, cardp); 277 usb_set_intfdata(intf, cardp);
351 278
352 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_fw)) 279 r = lbs_get_firmware_async(priv, &udev->dev, cardp->model,
353 netdev_err(priv->dev, 280 fw_table, if_usb_prog_firmware);
354 "cannot register lbs_flash_fw attribute\n"); 281 if (r)
355 282 goto err_get_fw;
356 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2))
357 netdev_err(priv->dev,
358 "cannot register lbs_flash_boot2 attribute\n");
359
360 /*
361 * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
362 */
363 priv->wol_criteria = EHS_REMOVE_WAKEUP;
364 if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
365 priv->ehs_remove_supported = false;
366 283
367 return 0; 284 return 0;
368 285
369err_start_card: 286err_get_fw:
370 lbs_remove_card(priv); 287 lbs_remove_card(priv);
371err_prog_firmware: 288err_add_card:
372 if_usb_reset_device(cardp); 289 if_usb_reset_device(cardp);
373dealloc: 290dealloc:
374 if_usb_free(cardp); 291 if_usb_free(cardp);
375 292
376error: 293error:
377 return -ENOMEM; 294 return r;
378} 295}
379 296
380/** 297/**
@@ -389,9 +306,6 @@ static void if_usb_disconnect(struct usb_interface *intf)
389 306
390 lbs_deb_enter(LBS_DEB_MAIN); 307 lbs_deb_enter(LBS_DEB_MAIN);
391 308
392 device_remove_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2);
393 device_remove_file(&priv->dev->dev, &dev_attr_lbs_flash_fw);
394
395 cardp->surprise_removed = 1; 309 cardp->surprise_removed = 1;
396 310
397 if (priv) { 311 if (priv) {
@@ -912,121 +826,22 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
912 return ret; 826 return ret;
913} 827}
914 828
915 829static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
916/** 830 const struct firmware *fw,
917* if_usb_prog_firmware - programs the firmware subject to cmd 831 const struct firmware *unused)
918*
919* @cardp: the if_usb_card descriptor
920* @fwname: firmware or boot2 image file name
921* @cmd: either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
922* or BOOT_CMD_UPDATE_BOOT2.
923* returns: 0 or error code
924*/
925static int if_usb_prog_firmware(struct if_usb_card *cardp,
926 const char *fwname, int cmd)
927{
928 struct lbs_private *priv = cardp->priv;
929 unsigned long flags, caps;
930 int ret;
931
932 caps = priv->fwcapinfo;
933 if (((cmd == BOOT_CMD_UPDATE_FW) && !(caps & FW_CAPINFO_FIRMWARE_UPGRADE)) ||
934 ((cmd == BOOT_CMD_UPDATE_BOOT2) && !(caps & FW_CAPINFO_BOOT2_UPGRADE)))
935 return -EOPNOTSUPP;
936
937 /* Ensure main thread is idle. */
938 spin_lock_irqsave(&priv->driver_lock, flags);
939 while (priv->cur_cmd != NULL || priv->dnld_sent != DNLD_RES_RECEIVED) {
940 spin_unlock_irqrestore(&priv->driver_lock, flags);
941 if (wait_event_interruptible(priv->waitq,
942 (priv->cur_cmd == NULL &&
943 priv->dnld_sent == DNLD_RES_RECEIVED))) {
944 return -ERESTARTSYS;
945 }
946 spin_lock_irqsave(&priv->driver_lock, flags);
947 }
948 priv->dnld_sent = DNLD_BOOTCMD_SENT;
949 spin_unlock_irqrestore(&priv->driver_lock, flags);
950
951 ret = __if_usb_prog_firmware(cardp, fwname, cmd);
952
953 spin_lock_irqsave(&priv->driver_lock, flags);
954 priv->dnld_sent = DNLD_RES_RECEIVED;
955 spin_unlock_irqrestore(&priv->driver_lock, flags);
956
957 wake_up(&priv->waitq);
958
959 return ret;
960}
961
962/* table of firmware file names */
963static const struct {
964 u32 model;
965 const char *fwname;
966} fw_table[] = {
967 { MODEL_8388, "libertas/usb8388_v9.bin" },
968 { MODEL_8388, "libertas/usb8388_v5.bin" },
969 { MODEL_8388, "libertas/usb8388.bin" },
970 { MODEL_8388, "usb8388.bin" },
971 { MODEL_8682, "libertas/usb8682.bin" }
972};
973
974#ifdef CONFIG_OLPC
975
976static int try_olpc_fw(struct if_usb_card *cardp)
977{
978 int retval = -ENOENT;
979
980 /* try the OLPC firmware first; fall back to fw_table list */
981 if (machine_is_olpc() && cardp->model == MODEL_8388)
982 retval = request_firmware(&cardp->fw,
983 "libertas/usb8388_olpc.bin", &cardp->udev->dev);
984 return retval;
985}
986
987#else
988static int try_olpc_fw(struct if_usb_card *cardp) { return -ENOENT; }
989#endif /* !CONFIG_OLPC */
990
991static int get_fw(struct if_usb_card *cardp, const char *fwname)
992{
993 int i;
994
995 /* Try user-specified firmware first */
996 if (fwname)
997 return request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
998
999 /* Handle OLPC firmware */
1000 if (try_olpc_fw(cardp) == 0)
1001 return 0;
1002
1003 /* Otherwise search for firmware to use */
1004 for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
1005 if (fw_table[i].model != cardp->model)
1006 continue;
1007 if (request_firmware(&cardp->fw, fw_table[i].fwname,
1008 &cardp->udev->dev) == 0)
1009 return 0;
1010 }
1011
1012 return -ENOENT;
1013}
1014
1015static int __if_usb_prog_firmware(struct if_usb_card *cardp,
1016 const char *fwname, int cmd)
1017{ 832{
833 struct if_usb_card *cardp = priv->card;
1018 int i = 0; 834 int i = 0;
1019 static int reset_count = 10; 835 static int reset_count = 10;
1020 int ret = 0;
1021 836
1022 lbs_deb_enter(LBS_DEB_USB); 837 lbs_deb_enter(LBS_DEB_USB);
1023 838
1024 ret = get_fw(cardp, fwname);
1025 if (ret) { 839 if (ret) {
1026 pr_err("failed to find firmware (%d)\n", ret); 840 pr_err("failed to find firmware (%d)\n", ret);
1027 goto done; 841 goto done;
1028 } 842 }
1029 843
844 cardp->fw = fw;
1030 if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) { 845 if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
1031 ret = -EINVAL; 846 ret = -EINVAL;
1032 goto release_fw; 847 goto release_fw;
@@ -1053,7 +868,7 @@ restart:
1053 do { 868 do {
1054 int j = 0; 869 int j = 0;
1055 i++; 870 i++;
1056 if_usb_issue_boot_command(cardp, cmd); 871 if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
1057 /* wait for command response */ 872 /* wait for command response */
1058 do { 873 do {
1059 j++; 874 j++;
@@ -1109,13 +924,27 @@ restart:
1109 goto release_fw; 924 goto release_fw;
1110 } 925 }
1111 926
927 cardp->priv->fw_ready = 1;
928 if_usb_submit_rx_urb(cardp);
929
930 if (lbs_start_card(priv))
931 goto release_fw;
932
933 if_usb_setup_firmware(priv);
934
935 /*
936 * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
937 */
938 priv->wol_criteria = EHS_REMOVE_WAKEUP;
939 if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
940 priv->ehs_remove_supported = false;
941
1112 release_fw: 942 release_fw:
1113 release_firmware(cardp->fw); 943 release_firmware(cardp->fw);
1114 cardp->fw = NULL; 944 cardp->fw = NULL;
1115 945
1116 done: 946 done:
1117 lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret); 947 lbs_deb_leave(LBS_DEB_USB);
1118 return ret;
1119} 948}
1120 949
1121 950
@@ -1128,8 +957,10 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
1128 957
1129 lbs_deb_enter(LBS_DEB_USB); 958 lbs_deb_enter(LBS_DEB_USB);
1130 959
1131 if (priv->psstate != PS_STATE_FULL_POWER) 960 if (priv->psstate != PS_STATE_FULL_POWER) {
1132 return -1; 961 ret = -1;
962 goto out;
963 }
1133 964
1134#ifdef CONFIG_OLPC 965#ifdef CONFIG_OLPC
1135 if (machine_is_olpc()) { 966 if (machine_is_olpc()) {
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 957681dede17..e96ee0aa8439 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -878,6 +878,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
878 priv->is_host_sleep_configured = 0; 878 priv->is_host_sleep_configured = 0;
879 priv->is_host_sleep_activated = 0; 879 priv->is_host_sleep_activated = 0;
880 init_waitqueue_head(&priv->host_sleep_q); 880 init_waitqueue_head(&priv->host_sleep_q);
881 init_waitqueue_head(&priv->fw_waitq);
881 mutex_init(&priv->lock); 882 mutex_init(&priv->lock);
882 883
883 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler, 884 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
@@ -1033,7 +1034,11 @@ void lbs_remove_card(struct lbs_private *priv)
1033 lbs_deb_enter(LBS_DEB_MAIN); 1034 lbs_deb_enter(LBS_DEB_MAIN);
1034 1035
1035 lbs_remove_mesh(priv); 1036 lbs_remove_mesh(priv);
1036 lbs_scan_deinit(priv); 1037
1038 if (priv->wiphy_registered)
1039 lbs_scan_deinit(priv);
1040
1041 lbs_wait_for_firmware_load(priv);
1037 1042
1038 /* worker thread destruction blocks on the in-flight command which 1043 /* worker thread destruction blocks on the in-flight command which
1039 * should have been cleared already in lbs_stop_card(). 1044 * should have been cleared already in lbs_stop_card().
@@ -1128,6 +1133,11 @@ void lbs_stop_card(struct lbs_private *priv)
1128 goto out; 1133 goto out;
1129 dev = priv->dev; 1134 dev = priv->dev;
1130 1135
1136 /* If the netdev isn't registered, it means that lbs_start_card() was
1137 * never called so we have nothing to do here. */
1138 if (dev->reg_state != NETREG_REGISTERED)
1139 goto out;
1140
1131 netif_stop_queue(dev); 1141 netif_stop_queue(dev);
1132 netif_carrier_off(dev); 1142 netif_carrier_off(dev);
1133 1143
@@ -1177,111 +1187,6 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
1177} 1187}
1178EXPORT_SYMBOL_GPL(lbs_notify_command_response); 1188EXPORT_SYMBOL_GPL(lbs_notify_command_response);
1179 1189
1180/**
1181 * lbs_get_firmware - Retrieves two-stage firmware
1182 *
1183 * @dev: A pointer to &device structure
1184 * @user_helper: User-defined helper firmware file
1185 * @user_mainfw: User-defined main firmware file
1186 * @card_model: Bus-specific card model ID used to filter firmware table
1187 * elements
1188 * @fw_table: Table of firmware file names and device model numbers
1189 * terminated by an entry with a NULL helper name
1190 * @helper: On success, the helper firmware; caller must free
1191 * @mainfw: On success, the main firmware; caller must free
1192 *
1193 * returns: 0 on success, non-zero on failure
1194 */
1195int lbs_get_firmware(struct device *dev, const char *user_helper,
1196 const char *user_mainfw, u32 card_model,
1197 const struct lbs_fw_table *fw_table,
1198 const struct firmware **helper,
1199 const struct firmware **mainfw)
1200{
1201 const struct lbs_fw_table *iter;
1202 int ret;
1203
1204 BUG_ON(helper == NULL);
1205 BUG_ON(mainfw == NULL);
1206
1207 /* Try user-specified firmware first */
1208 if (user_helper) {
1209 ret = request_firmware(helper, user_helper, dev);
1210 if (ret) {
1211 dev_err(dev, "couldn't find helper firmware %s\n",
1212 user_helper);
1213 goto fail;
1214 }
1215 }
1216 if (user_mainfw) {
1217 ret = request_firmware(mainfw, user_mainfw, dev);
1218 if (ret) {
1219 dev_err(dev, "couldn't find main firmware %s\n",
1220 user_mainfw);
1221 goto fail;
1222 }
1223 }
1224
1225 if (*helper && *mainfw)
1226 return 0;
1227
1228 /* Otherwise search for firmware to use. If neither the helper or
1229 * the main firmware were specified by the user, then we need to
1230 * make sure that found helper & main are from the same entry in
1231 * fw_table.
1232 */
1233 iter = fw_table;
1234 while (iter && iter->helper) {
1235 if (iter->model != card_model)
1236 goto next;
1237
1238 if (*helper == NULL) {
1239 ret = request_firmware(helper, iter->helper, dev);
1240 if (ret)
1241 goto next;
1242
1243 /* If the device has one-stage firmware (ie cf8305) and
1244 * we've got it then we don't need to bother with the
1245 * main firmware.
1246 */
1247 if (iter->fwname == NULL)
1248 return 0;
1249 }
1250
1251 if (*mainfw == NULL) {
1252 ret = request_firmware(mainfw, iter->fwname, dev);
1253 if (ret && !user_helper) {
1254 /* Clear the helper if it wasn't user-specified
1255 * and the main firmware load failed, to ensure
1256 * we don't have mismatched firmware pairs.
1257 */
1258 release_firmware(*helper);
1259 *helper = NULL;
1260 }
1261 }
1262
1263 if (*helper && *mainfw)
1264 return 0;
1265
1266 next:
1267 iter++;
1268 }
1269
1270 fail:
1271 /* Failed */
1272 if (*helper) {
1273 release_firmware(*helper);
1274 *helper = NULL;
1275 }
1276 if (*mainfw) {
1277 release_firmware(*mainfw);
1278 *mainfw = NULL;
1279 }
1280
1281 return -ENOENT;
1282}
1283EXPORT_SYMBOL_GPL(lbs_get_firmware);
1284
1285static int __init lbs_init_module(void) 1190static int __init lbs_init_module(void)
1286{ 1191{
1287 lbs_deb_enter(LBS_DEB_MAIN); 1192 lbs_deb_enter(LBS_DEB_MAIN);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 2d913644d92b..03c0c6b1372c 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -699,6 +699,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
699 ieee80211_is_probe_resp(mgmt->frame_control)) 699 ieee80211_is_probe_resp(mgmt->frame_control))
700 mgmt->u.beacon.timestamp = cpu_to_le64( 700 mgmt->u.beacon.timestamp = cpu_to_le64(
701 rx_status.mactime + 701 rx_status.mactime +
702 (data->tsf_offset - data2->tsf_offset) +
702 24 * 8 * 10 / txrate->bitrate); 703 24 * 8 * 10 / txrate->bitrate);
703 704
704 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); 705 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index c7e89188c350..c78ea873a63a 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1162,6 +1162,17 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
1162 priv->user_scan_cfg->num_ssids = request->n_ssids; 1162 priv->user_scan_cfg->num_ssids = request->n_ssids;
1163 priv->user_scan_cfg->ssid_list = request->ssids; 1163 priv->user_scan_cfg->ssid_list = request->ssids;
1164 1164
1165 if (request->ie && request->ie_len) {
1166 for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
1167 if (priv->vs_ie[i].mask != MWIFIEX_VSIE_MASK_CLEAR)
1168 continue;
1169 priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_SCAN;
1170 memcpy(&priv->vs_ie[i].ie, request->ie,
1171 request->ie_len);
1172 break;
1173 }
1174 }
1175
1165 for (i = 0; i < request->n_channels; i++) { 1176 for (i = 0; i < request->n_channels; i++) {
1166 chan = request->channels[i]; 1177 chan = request->channels[i];
1167 priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; 1178 priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
@@ -1179,6 +1190,15 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
1179 if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg)) 1190 if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg))
1180 return -EFAULT; 1191 return -EFAULT;
1181 1192
1193 if (request->ie && request->ie_len) {
1194 for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
1195 if (priv->vs_ie[i].mask == MWIFIEX_VSIE_MASK_SCAN) {
1196 priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_CLEAR;
1197 memset(&priv->vs_ie[i].ie, 0,
1198 MWIFIEX_MAX_VSIE_LEN);
1199 }
1200 }
1201 }
1182 return 0; 1202 return 0;
1183} 1203}
1184 1204
@@ -1422,6 +1442,7 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
1422 void *wdev_priv; 1442 void *wdev_priv;
1423 struct wireless_dev *wdev; 1443 struct wireless_dev *wdev;
1424 struct ieee80211_sta_ht_cap *ht_info; 1444 struct ieee80211_sta_ht_cap *ht_info;
1445 u8 *country_code;
1425 1446
1426 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 1447 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1427 if (!wdev) { 1448 if (!wdev) {
@@ -1438,6 +1459,7 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
1438 } 1459 }
1439 wdev->iftype = NL80211_IFTYPE_STATION; 1460 wdev->iftype = NL80211_IFTYPE_STATION;
1440 wdev->wiphy->max_scan_ssids = 10; 1461 wdev->wiphy->max_scan_ssids = 10;
1462 wdev->wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
1441 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1463 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1442 BIT(NL80211_IFTYPE_ADHOC); 1464 BIT(NL80211_IFTYPE_ADHOC);
1443 1465
@@ -1460,8 +1482,8 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
1460 memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN); 1482 memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
1461 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 1483 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1462 1484
1463 /* Reserve space for bss band information */ 1485 /* Reserve space for mwifiex specific private data for BSS */
1464 wdev->wiphy->bss_priv_size = sizeof(u8); 1486 wdev->wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
1465 1487
1466 wdev->wiphy->reg_notifier = mwifiex_reg_notifier; 1488 wdev->wiphy->reg_notifier = mwifiex_reg_notifier;
1467 1489
@@ -1484,6 +1506,11 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
1484 "info: successfully registered wiphy device\n"); 1506 "info: successfully registered wiphy device\n");
1485 } 1507 }
1486 1508
1509 country_code = mwifiex_11d_code_2_region(priv->adapter->region_code);
1510 if (country_code && regulatory_hint(wdev->wiphy, country_code))
1511 dev_err(priv->adapter->dev,
1512 "%s: regulatory_hint failed\n", __func__);
1513
1487 priv->wdev = wdev; 1514 priv->wdev = wdev;
1488 1515
1489 return ret; 1516 return ret;
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 2fe1c33765b8..560871b0e236 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -71,6 +71,37 @@ u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x10, 0x20, 0x30,
71 71
72static u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 }; 72static u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
73 73
74struct region_code_mapping {
75 u8 code;
76 u8 region[IEEE80211_COUNTRY_STRING_LEN];
77};
78
79static struct region_code_mapping region_code_mapping_t[] = {
80 { 0x10, "US " }, /* US FCC */
81 { 0x20, "CA " }, /* IC Canada */
82 { 0x30, "EU " }, /* ETSI */
83 { 0x31, "ES " }, /* Spain */
84 { 0x32, "FR " }, /* France */
85 { 0x40, "JP " }, /* Japan */
86 { 0x41, "JP " }, /* Japan */
87 { 0x50, "CN " }, /* China */
88};
89
90/* This function converts integer code to region string */
91u8 *mwifiex_11d_code_2_region(u8 code)
92{
93 u8 i;
94 u8 size = sizeof(region_code_mapping_t)/
95 sizeof(struct region_code_mapping);
96
97 /* Look for code in mapping table */
98 for (i = 0; i < size; i++)
99 if (region_code_mapping_t[i].code == code)
100 return region_code_mapping_t[i].region;
101
102 return NULL;
103}
104
74/* 105/*
75 * This function maps an index in supported rates table into 106 * This function maps an index in supported rates table into
76 * the corresponding data rate. 107 * the corresponding data rate.
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 1a845074c52a..a870b5885c09 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -212,7 +212,7 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
212 p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid); 212 p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
213 p += sprintf(p, "bssid=\"%pM\"\n", info.bssid); 213 p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
214 p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan); 214 p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
215 p += sprintf(p, "region_code = \"%02x\"\n", info.region_code); 215 p += sprintf(p, "country_code = \"%s\"\n", info.country_code);
216 216
217 netdev_for_each_mc_addr(ha, netdev) 217 netdev_for_each_mc_addr(ha, netdev)
218 p += sprintf(p, "multicast_address[%d]=\"%pM\"\n", 218 p += sprintf(p, "multicast_address[%d]=\"%pM\"\n",
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index bb26114bdb96..6b15449a4cb7 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -104,6 +104,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
104#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83) 104#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83)
105#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84) 105#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84)
106#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94) 106#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94)
107#define TLV_TYPE_MGMT_IE (PROPRIETARY_TLV_BASE_ID + 105)
107#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113) 108#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113)
108#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114) 109#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114)
109 110
@@ -818,7 +819,7 @@ struct host_cmd_ds_txpwr_cfg {
818struct mwifiex_bcn_param { 819struct mwifiex_bcn_param {
819 u8 bssid[ETH_ALEN]; 820 u8 bssid[ETH_ALEN];
820 u8 rssi; 821 u8 rssi;
821 __le32 timestamp[2]; 822 __le64 timestamp;
822 __le16 beacon_period; 823 __le16 beacon_period;
823 __le16 cap_info_bitmap; 824 __le16 cap_info_bitmap;
824} __packed; 825} __packed;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 54bb4839b57c..0d55c5b542d7 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -131,6 +131,8 @@ static int mwifiex_init_priv(struct mwifiex_private *priv)
131 priv->wmm_qosinfo = 0; 131 priv->wmm_qosinfo = 0;
132 priv->curr_bcn_buf = NULL; 132 priv->curr_bcn_buf = NULL;
133 priv->curr_bcn_size = 0; 133 priv->curr_bcn_size = 0;
134 priv->wps_ie = NULL;
135 priv->wps_ie_len = 0;
134 136
135 priv->scan_block = false; 137 priv->scan_block = false;
136 138
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 99c06649f94c..f0f95524e96b 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -96,7 +96,7 @@ struct mwifiex_bss_info {
96 u32 bss_mode; 96 u32 bss_mode;
97 struct cfg80211_ssid ssid; 97 struct cfg80211_ssid ssid;
98 u32 bss_chan; 98 u32 bss_chan;
99 u32 region_code; 99 u8 country_code[3];
100 u32 media_connected; 100 u32 media_connected;
101 u32 max_power_level; 101 u32 max_power_level;
102 u32 min_power_level; 102 u32 min_power_level;
@@ -303,6 +303,7 @@ struct mwifiex_ds_misc_subsc_evt {
303 303
304#define MWIFIEX_MAX_VSIE_LEN (256) 304#define MWIFIEX_MAX_VSIE_LEN (256)
305#define MWIFIEX_MAX_VSIE_NUM (8) 305#define MWIFIEX_MAX_VSIE_NUM (8)
306#define MWIFIEX_VSIE_MASK_CLEAR 0x00
306#define MWIFIEX_VSIE_MASK_SCAN 0x01 307#define MWIFIEX_VSIE_MASK_SCAN 0x01
307#define MWIFIEX_VSIE_MASK_ASSOC 0x02 308#define MWIFIEX_VSIE_MASK_ASSOC 0x02
308#define MWIFIEX_VSIE_MASK_ADHOC 0x04 309#define MWIFIEX_VSIE_MASK_ADHOC 0x04
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index bca8b6d52273..8a390982463e 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -118,15 +118,15 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer,
118 *buffer += sizeof(tsf_tlv.header); 118 *buffer += sizeof(tsf_tlv.header);
119 119
120 /* TSF at the time when beacon/probe_response was received */ 120 /* TSF at the time when beacon/probe_response was received */
121 tsf_val = cpu_to_le64(bss_desc->network_tsf); 121 tsf_val = cpu_to_le64(bss_desc->fw_tsf);
122 memcpy(*buffer, &tsf_val, sizeof(tsf_val)); 122 memcpy(*buffer, &tsf_val, sizeof(tsf_val));
123 *buffer += sizeof(tsf_val); 123 *buffer += sizeof(tsf_val);
124 124
125 memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val)); 125 tsf_val = cpu_to_le64(bss_desc->timestamp);
126 126
127 dev_dbg(priv->adapter->dev, 127 dev_dbg(priv->adapter->dev,
128 "info: %s: TSF offset calc: %016llx - %016llx\n", 128 "info: %s: TSF offset calc: %016llx - %016llx\n",
129 __func__, tsf_val, bss_desc->network_tsf); 129 __func__, bss_desc->timestamp, bss_desc->fw_tsf);
130 130
131 memcpy(*buffer, &tsf_val, sizeof(tsf_val)); 131 memcpy(*buffer, &tsf_val, sizeof(tsf_val));
132 *buffer += sizeof(tsf_val); 132 *buffer += sizeof(tsf_val);
@@ -225,6 +225,48 @@ mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
225} 225}
226 226
227/* 227/*
228 * This function appends a WPS IE. It is called from the network join command
229 * preparation routine.
230 *
231 * If the IE buffer has been setup by the application, this routine appends
232 * the buffer as a WPS TLV type to the request.
233 */
234static int
235mwifiex_cmd_append_wps_ie(struct mwifiex_private *priv, u8 **buffer)
236{
237 int retLen = 0;
238 struct mwifiex_ie_types_header ie_header;
239
240 if (!buffer || !*buffer)
241 return 0;
242
243 /*
244 * If there is a wps ie buffer setup, append it to the return
245 * parameter buffer pointer.
246 */
247 if (priv->wps_ie_len) {
248 dev_dbg(priv->adapter->dev, "cmd: append wps ie %d to %p\n",
249 priv->wps_ie_len, *buffer);
250
251 /* Wrap the generic IE buffer with a pass through TLV type */
252 ie_header.type = cpu_to_le16(TLV_TYPE_MGMT_IE);
253 ie_header.len = cpu_to_le16(priv->wps_ie_len);
254 memcpy(*buffer, &ie_header, sizeof(ie_header));
255 *buffer += sizeof(ie_header);
256 retLen += sizeof(ie_header);
257
258 memcpy(*buffer, priv->wps_ie, priv->wps_ie_len);
259 *buffer += priv->wps_ie_len;
260 retLen += priv->wps_ie_len;
261
262 }
263
264 kfree(priv->wps_ie);
265 priv->wps_ie_len = 0;
266 return retLen;
267}
268
269/*
228 * This function appends a WAPI IE. 270 * This function appends a WAPI IE.
229 * 271 *
230 * This function is called from the network join command preparation routine. 272 * This function is called from the network join command preparation routine.
@@ -480,6 +522,8 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
480 if (priv->sec_info.wapi_enabled && priv->wapi_ie_len) 522 if (priv->sec_info.wapi_enabled && priv->wapi_ie_len)
481 mwifiex_cmd_append_wapi_ie(priv, &pos); 523 mwifiex_cmd_append_wapi_ie(priv, &pos);
482 524
525 if (priv->wps.session_enable && priv->wps_ie_len)
526 mwifiex_cmd_append_wps_ie(priv, &pos);
483 527
484 mwifiex_cmd_append_generic_ie(priv, &pos); 528 mwifiex_cmd_append_generic_ie(priv, &pos);
485 529
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 9d1b3ca6334b..245b7329e0c9 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -292,29 +292,28 @@ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
292} 292}
293 293
294/* 294/*
295 * This function initializes the hardware and firmware. 295 * This function gets firmware and initializes it.
296 * 296 *
297 * The main initialization steps followed are - 297 * The main initialization steps followed are -
298 * - Download the correct firmware to card 298 * - Download the correct firmware to card
299 * - Allocate and initialize the adapter structure
300 * - Initialize the private structures
301 * - Issue the init commands to firmware 299 * - Issue the init commands to firmware
302 */ 300 */
303static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter) 301static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
304{ 302{
305 int ret, err; 303 int ret;
304 char fmt[64];
305 struct mwifiex_private *priv;
306 struct mwifiex_adapter *adapter = context;
306 struct mwifiex_fw_image fw; 307 struct mwifiex_fw_image fw;
307 308
308 memset(&fw, 0, sizeof(struct mwifiex_fw_image)); 309 if (!firmware) {
309 310 dev_err(adapter->dev,
310 err = request_firmware(&adapter->firmware, adapter->fw_name, 311 "Failed to get firmware %s\n", adapter->fw_name);
311 adapter->dev);
312 if (err < 0) {
313 dev_err(adapter->dev, "request_firmware() returned"
314 " error code %#x\n", err);
315 ret = -1;
316 goto done; 312 goto done;
317 } 313 }
314
315 memset(&fw, 0, sizeof(struct mwifiex_fw_image));
316 adapter->firmware = firmware;
318 fw.fw_buf = (u8 *) adapter->firmware->data; 317 fw.fw_buf = (u8 *) adapter->firmware->data;
319 fw.fw_len = adapter->firmware->size; 318 fw.fw_len = adapter->firmware->size;
320 319
@@ -335,17 +334,54 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
335 /* Wait for mwifiex_init to complete */ 334 /* Wait for mwifiex_init to complete */
336 wait_event_interruptible(adapter->init_wait_q, 335 wait_event_interruptible(adapter->init_wait_q,
337 adapter->init_wait_q_woken); 336 adapter->init_wait_q_woken);
338 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) { 337 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
339 ret = -1;
340 goto done; 338 goto done;
339
340 priv = adapter->priv[0];
341 if (mwifiex_register_cfg80211(priv) != 0) {
342 dev_err(adapter->dev, "cannot register with cfg80211\n");
343 goto err_init_fw;
344 }
345
346 rtnl_lock();
347 /* Create station interface by default */
348 if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d",
349 NL80211_IFTYPE_STATION, NULL, NULL)) {
350 dev_err(adapter->dev, "cannot create default STA interface\n");
351 goto err_add_intf;
341 } 352 }
342 ret = 0; 353 rtnl_unlock();
354
355 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
356 dev_notice(adapter->dev, "driver_version = %s\n", fmt);
357 goto done;
343 358
359err_add_intf:
360 mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
361 rtnl_unlock();
362err_init_fw:
363 pr_debug("info: %s: unregister device\n", __func__);
364 adapter->if_ops.unregister_dev(adapter);
344done: 365done:
345 if (adapter->firmware) 366 release_firmware(adapter->firmware);
346 release_firmware(adapter->firmware); 367 complete(&adapter->fw_load);
347 if (ret) 368 return;
348 ret = -1; 369}
370
371/*
372 * This function initializes the hardware and gets firmware.
373 */
374static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
375{
376 int ret;
377
378 init_completion(&adapter->fw_load);
379 ret = request_firmware_nowait(THIS_MODULE, 1, adapter->fw_name,
380 adapter->dev, GFP_KERNEL, adapter,
381 mwifiex_fw_dpc);
382 if (ret < 0)
383 dev_err(adapter->dev,
384 "request_firmware_nowait() returned error %d\n", ret);
349 return ret; 385 return ret;
350} 386}
351 387
@@ -650,8 +686,6 @@ mwifiex_add_card(void *card, struct semaphore *sem,
650 struct mwifiex_if_ops *if_ops, u8 iface_type) 686 struct mwifiex_if_ops *if_ops, u8 iface_type)
651{ 687{
652 struct mwifiex_adapter *adapter; 688 struct mwifiex_adapter *adapter;
653 char fmt[64];
654 struct mwifiex_private *priv;
655 689
656 if (down_interruptible(sem)) 690 if (down_interruptible(sem))
657 goto exit_sem_err; 691 goto exit_sem_err;
@@ -692,37 +726,9 @@ mwifiex_add_card(void *card, struct semaphore *sem,
692 goto err_init_fw; 726 goto err_init_fw;
693 } 727 }
694 728
695 priv = adapter->priv[0];
696
697 if (mwifiex_register_cfg80211(priv) != 0) {
698 dev_err(adapter->dev, "cannot register netdevice"
699 " with cfg80211\n");
700 goto err_init_fw;
701 }
702
703 rtnl_lock();
704 /* Create station interface by default */
705 if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d",
706 NL80211_IFTYPE_STATION, NULL, NULL)) {
707 rtnl_unlock();
708 dev_err(adapter->dev, "cannot create default station"
709 " interface\n");
710 goto err_add_intf;
711 }
712
713 rtnl_unlock();
714
715 up(sem); 729 up(sem);
716
717 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
718 dev_notice(adapter->dev, "driver_version = %s\n", fmt);
719
720 return 0; 730 return 0;
721 731
722err_add_intf:
723 rtnl_lock();
724 mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
725 rtnl_unlock();
726err_init_fw: 732err_init_fw:
727 pr_debug("info: %s: unregister device\n", __func__); 733 pr_debug("info: %s: unregister device\n", __func__);
728 adapter->if_ops.unregister_dev(adapter); 734 adapter->if_ops.unregister_dev(adapter);
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index fcccf6b1373f..a4000f9608d5 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -260,8 +260,8 @@ struct mwifiex_bssdescriptor {
260 * BAND_A(0X04): 'a' band 260 * BAND_A(0X04): 'a' band
261 */ 261 */
262 u16 bss_band; 262 u16 bss_band;
263 u64 network_tsf; 263 u64 fw_tsf;
264 u8 time_stamp[8]; 264 u64 timestamp;
265 union ieee_types_phy_param_set phy_param_set; 265 union ieee_types_phy_param_set phy_param_set;
266 union ieee_types_ss_param_set ss_param_set; 266 union ieee_types_ss_param_set ss_param_set;
267 u16 cap_info_bitmap; 267 u16 cap_info_bitmap;
@@ -407,6 +407,8 @@ struct mwifiex_private {
407 struct host_cmd_ds_802_11_key_material aes_key; 407 struct host_cmd_ds_802_11_key_material aes_key;
408 u8 wapi_ie[256]; 408 u8 wapi_ie[256];
409 u8 wapi_ie_len; 409 u8 wapi_ie_len;
410 u8 *wps_ie;
411 u8 wps_ie_len;
410 u8 wmm_required; 412 u8 wmm_required;
411 u8 wmm_enabled; 413 u8 wmm_enabled;
412 u8 wmm_qosinfo; 414 u8 wmm_qosinfo;
@@ -520,6 +522,11 @@ struct cmd_ctrl_node {
520 u8 cmd_wait_q_woken; 522 u8 cmd_wait_q_woken;
521}; 523};
522 524
525struct mwifiex_bss_priv {
526 u8 band;
527 u64 fw_tsf;
528};
529
523struct mwifiex_if_ops { 530struct mwifiex_if_ops {
524 int (*init_if) (struct mwifiex_adapter *); 531 int (*init_if) (struct mwifiex_adapter *);
525 void (*cleanup_if) (struct mwifiex_adapter *); 532 void (*cleanup_if) (struct mwifiex_adapter *);
@@ -653,6 +660,7 @@ struct mwifiex_adapter {
653 u8 scan_wait_q_woken; 660 u8 scan_wait_q_woken;
654 struct cmd_ctrl_node *cmd_queued; 661 struct cmd_ctrl_node *cmd_queued;
655 spinlock_t queue_lock; /* lock for tx queues */ 662 spinlock_t queue_lock; /* lock for tx queues */
663 struct completion fw_load;
656}; 664};
657 665
658int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 666int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -950,13 +958,10 @@ int mwifiex_bss_set_channel(struct mwifiex_private *,
950int mwifiex_get_bss_info(struct mwifiex_private *, 958int mwifiex_get_bss_info(struct mwifiex_private *,
951 struct mwifiex_bss_info *); 959 struct mwifiex_bss_info *);
952int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, 960int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
953 u8 *bssid, s32 rssi, u8 *ie_buf, 961 struct cfg80211_bss *bss,
954 size_t ie_len, u16 beacon_period,
955 u16 cap_info_bitmap, u8 band,
956 struct mwifiex_bssdescriptor *bss_desc); 962 struct mwifiex_bssdescriptor *bss_desc);
957int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, 963int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
958 struct mwifiex_bssdescriptor *bss_entry, 964 struct mwifiex_bssdescriptor *bss_entry);
959 u8 *ie_buf, u32 ie_len);
960int mwifiex_check_network_compatibility(struct mwifiex_private *priv, 965int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
961 struct mwifiex_bssdescriptor *bss_desc); 966 struct mwifiex_bssdescriptor *bss_desc);
962 967
@@ -965,6 +970,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
965 u32 *flags, struct vif_params *params); 970 u32 *flags, struct vif_params *params);
966int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev); 971int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev);
967 972
973u8 *mwifiex_11d_code_2_region(u8 code);
968 974
969#ifdef CONFIG_DEBUG_FS 975#ifdef CONFIG_DEBUG_FS
970void mwifiex_debugfs_init(void); 976void mwifiex_debugfs_init(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 5867facd415d..13fbc4eb1595 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -119,6 +119,9 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
119 if (!adapter || !adapter->priv_num) 119 if (!adapter || !adapter->priv_num)
120 return; 120 return;
121 121
122 /* In case driver is removed when asynchronous FW load is in progress */
123 wait_for_completion(&adapter->fw_load);
124
122 if (user_rmmod) { 125 if (user_rmmod) {
123#ifdef CONFIG_PM 126#ifdef CONFIG_PM
124 if (adapter->is_suspended) 127 if (adapter->is_suspended)
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index ef84a1a6742f..74f045715723 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1048,10 +1048,8 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
1048 * This function parses provided beacon buffer and updates 1048 * This function parses provided beacon buffer and updates
1049 * respective fields in bss descriptor structure. 1049 * respective fields in bss descriptor structure.
1050 */ 1050 */
1051int 1051int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1052mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, 1052 struct mwifiex_bssdescriptor *bss_entry)
1053 struct mwifiex_bssdescriptor *bss_entry,
1054 u8 *ie_buf, u32 ie_len)
1055{ 1053{
1056 int ret = 0; 1054 int ret = 0;
1057 u8 element_id; 1055 u8 element_id;
@@ -1073,10 +1071,8 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1073 1071
1074 found_data_rate_ie = false; 1072 found_data_rate_ie = false;
1075 rate_size = 0; 1073 rate_size = 0;
1076 current_ptr = ie_buf; 1074 current_ptr = bss_entry->beacon_buf;
1077 bytes_left = ie_len; 1075 bytes_left = bss_entry->beacon_buf_size;
1078 bss_entry->beacon_buf = ie_buf;
1079 bss_entry->beacon_buf_size = ie_len;
1080 1076
1081 /* Process variable IE */ 1077 /* Process variable IE */
1082 while (bytes_left >= 2) { 1078 while (bytes_left >= 2) {
@@ -1447,15 +1443,12 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1447 return ret; 1443 return ret;
1448} 1444}
1449 1445
1450static int 1446static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
1451mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid, 1447 struct cfg80211_bss *bss)
1452 s32 rssi, const u8 *ie_buf, size_t ie_len,
1453 u16 beacon_period, u16 cap_info_bitmap, u8 band)
1454{ 1448{
1455 struct mwifiex_bssdescriptor *bss_desc; 1449 struct mwifiex_bssdescriptor *bss_desc;
1456 int ret; 1450 int ret;
1457 unsigned long flags; 1451 unsigned long flags;
1458 u8 *beacon_ie;
1459 1452
1460 /* Allocate and fill new bss descriptor */ 1453 /* Allocate and fill new bss descriptor */
1461 bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), 1454 bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
@@ -1465,16 +1458,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
1465 return -ENOMEM; 1458 return -ENOMEM;
1466 } 1459 }
1467 1460
1468 beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL); 1461 ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
1469 if (!beacon_ie) {
1470 kfree(bss_desc);
1471 dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
1472 return -ENOMEM;
1473 }
1474
1475 ret = mwifiex_fill_new_bss_desc(priv, bssid, rssi, beacon_ie,
1476 ie_len, beacon_period,
1477 cap_info_bitmap, band, bss_desc);
1478 if (ret) 1462 if (ret)
1479 goto done; 1463 goto done;
1480 1464
@@ -1514,7 +1498,6 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
1514 1498
1515done: 1499done:
1516 kfree(bss_desc); 1500 kfree(bss_desc);
1517 kfree(beacon_ie);
1518 return 0; 1501 return 0;
1519} 1502}
1520 1503
@@ -1620,14 +1603,16 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1620 const u8 *ie_buf; 1603 const u8 *ie_buf;
1621 size_t ie_len; 1604 size_t ie_len;
1622 u16 channel = 0; 1605 u16 channel = 0;
1623 u64 network_tsf = 0; 1606 u64 fw_tsf = 0;
1624 u16 beacon_size = 0; 1607 u16 beacon_size = 0;
1625 u32 curr_bcn_bytes; 1608 u32 curr_bcn_bytes;
1626 u32 freq; 1609 u32 freq;
1627 u16 beacon_period; 1610 u16 beacon_period;
1628 u16 cap_info_bitmap; 1611 u16 cap_info_bitmap;
1629 u8 *current_ptr; 1612 u8 *current_ptr;
1613 u64 timestamp;
1630 struct mwifiex_bcn_param *bcn_param; 1614 struct mwifiex_bcn_param *bcn_param;
1615 struct mwifiex_bss_priv *bss_priv;
1631 1616
1632 if (bytes_left >= sizeof(beacon_size)) { 1617 if (bytes_left >= sizeof(beacon_size)) {
1633 /* Extract & convert beacon size from command buffer */ 1618 /* Extract & convert beacon size from command buffer */
@@ -1671,6 +1656,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1671 rssi = (-rssi) * 100; /* Convert dBm to mBm */ 1656 rssi = (-rssi) * 100; /* Convert dBm to mBm */
1672 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%d\n", rssi); 1657 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%d\n", rssi);
1673 1658
1659 timestamp = le64_to_cpu(bcn_param->timestamp);
1674 beacon_period = le16_to_cpu(bcn_param->beacon_period); 1660 beacon_period = le16_to_cpu(bcn_param->beacon_period);
1675 1661
1676 cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap); 1662 cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
@@ -1710,14 +1696,13 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1710 1696
1711 /* 1697 /*
1712 * If the TSF TLV was appended to the scan results, save this 1698 * If the TSF TLV was appended to the scan results, save this
1713 * entry's TSF value in the networkTSF field.The networkTSF is 1699 * entry's TSF value in the fw_tsf field. It is the firmware's
1714 * the firmware's TSF value at the time the beacon or probe 1700 * TSF value at the time the beacon or probe response was
1715 * response was received. 1701 * received.
1716 */ 1702 */
1717 if (tsf_tlv) 1703 if (tsf_tlv)
1718 memcpy(&network_tsf, 1704 memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
1719 &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], 1705 sizeof(fw_tsf));
1720 sizeof(network_tsf));
1721 1706
1722 if (channel) { 1707 if (channel) {
1723 struct ieee80211_channel *chan; 1708 struct ieee80211_channel *chan;
@@ -1740,21 +1725,19 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1740 1725
1741 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { 1726 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
1742 bss = cfg80211_inform_bss(priv->wdev->wiphy, 1727 bss = cfg80211_inform_bss(priv->wdev->wiphy,
1743 chan, bssid, network_tsf, 1728 chan, bssid, timestamp,
1744 cap_info_bitmap, beacon_period, 1729 cap_info_bitmap, beacon_period,
1745 ie_buf, ie_len, rssi, GFP_KERNEL); 1730 ie_buf, ie_len, rssi, GFP_KERNEL);
1746 *(u8 *)bss->priv = band; 1731 bss_priv = (struct mwifiex_bss_priv *)bss->priv;
1747 cfg80211_put_bss(bss); 1732 bss_priv->band = band;
1748 1733 bss_priv->fw_tsf = fw_tsf;
1749 if (priv->media_connected && 1734 if (priv->media_connected &&
1750 !memcmp(bssid, 1735 !memcmp(bssid,
1751 priv->curr_bss_params.bss_descriptor 1736 priv->curr_bss_params.bss_descriptor
1752 .mac_address, ETH_ALEN)) 1737 .mac_address, ETH_ALEN))
1753 mwifiex_update_curr_bss_params 1738 mwifiex_update_curr_bss_params(priv,
1754 (priv, bssid, rssi, 1739 bss);
1755 ie_buf, ie_len, 1740 cfg80211_put_bss(bss);
1756 beacon_period,
1757 cap_info_bitmap, band);
1758 } 1741 }
1759 } else { 1742 } else {
1760 dev_dbg(adapter->dev, "missing BSS channel IE\n"); 1743 dev_dbg(adapter->dev, "missing BSS channel IE\n");
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index f8012e2b7f7c..1aa45c4295bb 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -123,6 +123,9 @@ mwifiex_sdio_remove(struct sdio_func *func)
123 if (!adapter || !adapter->priv_num) 123 if (!adapter || !adapter->priv_num)
124 return; 124 return;
125 125
126 /* In case driver is removed when asynchronous FW load is in progress */
127 wait_for_completion(&adapter->fw_load);
128
126 if (user_rmmod) { 129 if (user_rmmod) {
127 if (adapter->is_suspended) 130 if (adapter->is_suspended)
128 mwifiex_sdio_resume(adapter->dev); 131 mwifiex_sdio_resume(adapter->dev);
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index e90c34d9c63d..1f7110577b9d 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -988,7 +988,7 @@ mwifiex_cmd_802_11_subsc_evt(struct mwifiex_private *priv,
988 rssi_tlv->abs_value = subsc_evt_cfg->bcn_h_rssi_cfg.abs_value; 988 rssi_tlv->abs_value = subsc_evt_cfg->bcn_h_rssi_cfg.abs_value;
989 rssi_tlv->evt_freq = subsc_evt_cfg->bcn_h_rssi_cfg.evt_freq; 989 rssi_tlv->evt_freq = subsc_evt_cfg->bcn_h_rssi_cfg.evt_freq;
990 990
991 dev_dbg(priv->adapter->dev, "Cfg Beacon Low Rssi event, " 991 dev_dbg(priv->adapter->dev, "Cfg Beacon High Rssi event, "
992 "RSSI:-%d dBm, Freq:%d\n", 992 "RSSI:-%d dBm, Freq:%d\n",
993 subsc_evt_cfg->bcn_h_rssi_cfg.abs_value, 993 subsc_evt_cfg->bcn_h_rssi_cfg.abs_value,
994 subsc_evt_cfg->bcn_h_rssi_cfg.evt_freq); 994 subsc_evt_cfg->bcn_h_rssi_cfg.evt_freq);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 8ba58d935328..58970e0f7d13 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -155,20 +155,29 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
155 * information. 155 * information.
156 */ 156 */
157int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, 157int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
158 u8 *bssid, s32 rssi, u8 *ie_buf, 158 struct cfg80211_bss *bss,
159 size_t ie_len, u16 beacon_period,
160 u16 cap_info_bitmap, u8 band,
161 struct mwifiex_bssdescriptor *bss_desc) 159 struct mwifiex_bssdescriptor *bss_desc)
162{ 160{
163 int ret; 161 int ret;
162 u8 *beacon_ie;
163 struct mwifiex_bss_priv *bss_priv = (void *)bss->priv;
164 164
165 memcpy(bss_desc->mac_address, bssid, ETH_ALEN); 165 beacon_ie = kmemdup(bss->information_elements, bss->len_beacon_ies,
166 bss_desc->rssi = rssi; 166 GFP_KERNEL);
167 bss_desc->beacon_buf = ie_buf; 167 if (!beacon_ie) {
168 bss_desc->beacon_buf_size = ie_len; 168 dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
169 bss_desc->beacon_period = beacon_period; 169 return -ENOMEM;
170 bss_desc->cap_info_bitmap = cap_info_bitmap; 170 }
171 bss_desc->bss_band = band; 171
172 memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN);
173 bss_desc->rssi = bss->signal;
174 bss_desc->beacon_buf = beacon_ie;
175 bss_desc->beacon_buf_size = bss->len_beacon_ies;
176 bss_desc->beacon_period = bss->beacon_interval;
177 bss_desc->cap_info_bitmap = bss->capability;
178 bss_desc->bss_band = bss_priv->band;
179 bss_desc->fw_tsf = bss_priv->fw_tsf;
180 bss_desc->timestamp = bss->tsf;
172 if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) { 181 if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
173 dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n"); 182 dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n");
174 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP; 183 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
@@ -180,9 +189,9 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
180 else 189 else
181 bss_desc->bss_mode = NL80211_IFTYPE_STATION; 190 bss_desc->bss_mode = NL80211_IFTYPE_STATION;
182 191
183 ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc, 192 ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc);
184 ie_buf, ie_len);
185 193
194 kfree(beacon_ie);
186 return ret; 195 return ret;
187} 196}
188 197
@@ -197,7 +206,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
197 int ret; 206 int ret;
198 struct mwifiex_adapter *adapter = priv->adapter; 207 struct mwifiex_adapter *adapter = priv->adapter;
199 struct mwifiex_bssdescriptor *bss_desc = NULL; 208 struct mwifiex_bssdescriptor *bss_desc = NULL;
200 u8 *beacon_ie = NULL;
201 209
202 priv->scan_block = false; 210 priv->scan_block = false;
203 211
@@ -210,19 +218,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
210 return -ENOMEM; 218 return -ENOMEM;
211 } 219 }
212 220
213 beacon_ie = kmemdup(bss->information_elements, 221 ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
214 bss->len_beacon_ies, GFP_KERNEL);
215 if (!beacon_ie) {
216 kfree(bss_desc);
217 dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
218 return -ENOMEM;
219 }
220
221 ret = mwifiex_fill_new_bss_desc(priv, bss->bssid, bss->signal,
222 beacon_ie, bss->len_beacon_ies,
223 bss->beacon_interval,
224 bss->capability,
225 *(u8 *)bss->priv, bss_desc);
226 if (ret) 222 if (ret)
227 goto done; 223 goto done;
228 } 224 }
@@ -269,7 +265,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
269 (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. 265 (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor.
270 ssid, &bss_desc->ssid))) { 266 ssid, &bss_desc->ssid))) {
271 kfree(bss_desc); 267 kfree(bss_desc);
272 kfree(beacon_ie);
273 return 0; 268 return 0;
274 } 269 }
275 270
@@ -304,7 +299,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
304 299
305done: 300done:
306 kfree(bss_desc); 301 kfree(bss_desc);
307 kfree(beacon_ie);
308 return ret; 302 return ret;
309} 303}
310 304
@@ -468,7 +462,8 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
468 462
469 info->bss_chan = bss_desc->channel; 463 info->bss_chan = bss_desc->channel;
470 464
471 info->region_code = adapter->region_code; 465 memcpy(info->country_code, priv->country_code,
466 IEEE80211_COUNTRY_STRING_LEN);
472 467
473 info->media_connected = priv->media_connected; 468 info->media_connected = priv->media_connected;
474 469
@@ -996,6 +991,39 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv,
996} 991}
997 992
998/* 993/*
994 * IOCTL request handler to set/reset WPS IE.
995 *
996 * The supplied WPS IE is treated as a opaque buffer. Only the first field
997 * is checked to internally enable WPS. If buffer length is zero, the existing
998 * WPS IE is reset.
999 */
1000static int mwifiex_set_wps_ie(struct mwifiex_private *priv,
1001 u8 *ie_data_ptr, u16 ie_len)
1002{
1003 if (ie_len) {
1004 priv->wps_ie = kzalloc(MWIFIEX_MAX_VSIE_LEN, GFP_KERNEL);
1005 if (!priv->wps_ie)
1006 return -ENOMEM;
1007 if (ie_len > sizeof(priv->wps_ie)) {
1008 dev_dbg(priv->adapter->dev,
1009 "info: failed to copy WPS IE, too big\n");
1010 kfree(priv->wps_ie);
1011 return -1;
1012 }
1013 memcpy(priv->wps_ie, ie_data_ptr, ie_len);
1014 priv->wps_ie_len = ie_len;
1015 dev_dbg(priv->adapter->dev, "cmd: Set wps_ie_len=%d IE=%#x\n",
1016 priv->wps_ie_len, priv->wps_ie[0]);
1017 } else {
1018 kfree(priv->wps_ie);
1019 priv->wps_ie_len = ie_len;
1020 dev_dbg(priv->adapter->dev,
1021 "info: Reset wps_ie_len=%d\n", priv->wps_ie_len);
1022 }
1023 return 0;
1024}
1025
1026/*
999 * IOCTL request handler to set WAPI key. 1027 * IOCTL request handler to set WAPI key.
1000 * 1028 *
1001 * This function prepares the correct firmware command and 1029 * This function prepares the correct firmware command and
@@ -1408,6 +1436,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
1408 priv->wps.session_enable = true; 1436 priv->wps.session_enable = true;
1409 dev_dbg(priv->adapter->dev, 1437 dev_dbg(priv->adapter->dev,
1410 "info: WPS Session Enabled.\n"); 1438 "info: WPS Session Enabled.\n");
1439 ret = mwifiex_set_wps_ie(priv, ie_data_ptr, ie_len);
1411 } 1440 }
1412 1441
1413 /* Append the passed data to the end of the 1442 /* Append the passed data to the end of the
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index b48674b577e6..e30cc32f8279 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -5893,18 +5893,7 @@ static struct pci_driver mwl8k_driver = {
5893 .shutdown = __devexit_p(mwl8k_shutdown), 5893 .shutdown = __devexit_p(mwl8k_shutdown),
5894}; 5894};
5895 5895
5896static int __init mwl8k_init(void) 5896module_pci_driver(mwl8k_driver);
5897{
5898 return pci_register_driver(&mwl8k_driver);
5899}
5900
5901static void __exit mwl8k_exit(void)
5902{
5903 pci_unregister_driver(&mwl8k_driver);
5904}
5905
5906module_init(mwl8k_init);
5907module_exit(mwl8k_exit);
5908 5897
5909MODULE_DESCRIPTION(MWL8K_DESC); 5898MODULE_DESCRIPTION(MWL8K_DESC);
5910MODULE_VERSION(MWL8K_VERSION); 5899MODULE_VERSION(MWL8K_VERSION);
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c
index 4df8cf64b56c..400a35217644 100644
--- a/drivers/net/wireless/orinoco/fw.c
+++ b/drivers/net/wireless/orinoco/fw.c
@@ -379,11 +379,8 @@ void orinoco_cache_fw(struct orinoco_private *priv, int ap)
379 379
380void orinoco_uncache_fw(struct orinoco_private *priv) 380void orinoco_uncache_fw(struct orinoco_private *priv)
381{ 381{
382 if (priv->cached_pri_fw) 382 release_firmware(priv->cached_pri_fw);
383 release_firmware(priv->cached_pri_fw); 383 release_firmware(priv->cached_fw);
384 if (priv->cached_fw)
385 release_firmware(priv->cached_fw);
386
387 priv->cached_pri_fw = NULL; 384 priv->cached_pri_fw = NULL;
388 priv->cached_fw = NULL; 385 priv->cached_fw = NULL;
389} 386}
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 45df728183fd..89318adc8c7f 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -667,15 +667,4 @@ static struct pci_driver p54p_driver = {
667 .driver.pm = P54P_PM_OPS, 667 .driver.pm = P54P_PM_OPS,
668}; 668};
669 669
670static int __init p54p_init(void) 670module_pci_driver(p54p_driver);
671{
672 return pci_register_driver(&p54p_driver);
673}
674
675static void __exit p54p_exit(void)
676{
677 pci_unregister_driver(&p54p_driver);
678}
679
680module_init(p54p_init);
681module_exit(p54p_exit);
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index 9b796cae4afe..a01606b36e03 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -693,8 +693,6 @@ mgt_update_addr(islpci_private *priv)
693 return ret; 693 return ret;
694} 694}
695 695
696#define VEC_SIZE(a) ARRAY_SIZE(a)
697
698int 696int
699mgt_commit(islpci_private *priv) 697mgt_commit(islpci_private *priv)
700{ 698{
@@ -704,10 +702,10 @@ mgt_commit(islpci_private *priv)
704 if (islpci_get_state(priv) < PRV_STATE_INIT) 702 if (islpci_get_state(priv) < PRV_STATE_INIT)
705 return 0; 703 return 0;
706 704
707 rvalue = mgt_commit_list(priv, commit_part1, VEC_SIZE(commit_part1)); 705 rvalue = mgt_commit_list(priv, commit_part1, ARRAY_SIZE(commit_part1));
708 706
709 if (priv->iw_mode != IW_MODE_MONITOR) 707 if (priv->iw_mode != IW_MODE_MONITOR)
710 rvalue |= mgt_commit_list(priv, commit_part2, VEC_SIZE(commit_part2)); 708 rvalue |= mgt_commit_list(priv, commit_part2, ARRAY_SIZE(commit_part2));
711 709
712 u = OID_INL_MODE; 710 u = OID_INL_MODE;
713 rvalue |= mgt_commit_list(priv, &u, 1); 711 rvalue |= mgt_commit_list(priv, &u, 1);
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 3a6b40239bc1..5e6b50143165 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1828,15 +1828,4 @@ static struct pci_driver rt2400pci_driver = {
1828 .resume = rt2x00pci_resume, 1828 .resume = rt2x00pci_resume,
1829}; 1829};
1830 1830
1831static int __init rt2400pci_init(void) 1831module_pci_driver(rt2400pci_driver);
1832{
1833 return pci_register_driver(&rt2400pci_driver);
1834}
1835
1836static void __exit rt2400pci_exit(void)
1837{
1838 pci_unregister_driver(&rt2400pci_driver);
1839}
1840
1841module_init(rt2400pci_init);
1842module_exit(rt2400pci_exit);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index dcc0e1fcca77..136b849f11b5 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -2119,15 +2119,4 @@ static struct pci_driver rt2500pci_driver = {
2119 .resume = rt2x00pci_resume, 2119 .resume = rt2x00pci_resume,
2120}; 2120};
2121 2121
2122static int __init rt2500pci_init(void) 2122module_pci_driver(rt2500pci_driver);
2123{
2124 return pci_register_driver(&rt2500pci_driver);
2125}
2126
2127static void __exit rt2500pci_exit(void)
2128{
2129 pci_unregister_driver(&rt2500pci_driver);
2130}
2131
2132module_init(rt2500pci_init);
2133module_exit(rt2500pci_exit);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 1de9c752c88b..c88fd3e61090 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1912,7 +1912,7 @@ static struct usb_device_id rt2500usb_device_table[] = {
1912 { USB_DEVICE(0x0b05, 0x1706) }, 1912 { USB_DEVICE(0x0b05, 0x1706) },
1913 { USB_DEVICE(0x0b05, 0x1707) }, 1913 { USB_DEVICE(0x0b05, 0x1707) },
1914 /* Belkin */ 1914 /* Belkin */
1915 { USB_DEVICE(0x050d, 0x7050) }, 1915 { USB_DEVICE(0x050d, 0x7050) }, /* FCC ID: K7SF5D7050A ver. 2.x */
1916 { USB_DEVICE(0x050d, 0x7051) }, 1916 { USB_DEVICE(0x050d, 0x7051) },
1917 /* Cisco Systems */ 1917 /* Cisco Systems */
1918 { USB_DEVICE(0x13b1, 0x000d) }, 1918 { USB_DEVICE(0x13b1, 0x000d) },
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 6c0a12ea6a15..bd1980202f19 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -290,11 +290,25 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
290 msleep(10); 290 msleep(10);
291 } 291 }
292 292
293 ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n"); 293 ERROR(rt2x00dev, "WPDMA TX/RX busy [0x%08x].\n", reg);
294 return -EACCES; 294 return -EACCES;
295} 295}
296EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); 296EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready);
297 297
298void rt2800_disable_wpdma(struct rt2x00_dev *rt2x00dev)
299{
300 u32 reg;
301
302 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
303 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
304 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
305 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
306 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
307 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
308 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
309}
310EXPORT_SYMBOL_GPL(rt2800_disable_wpdma);
311
298static bool rt2800_check_firmware_crc(const u8 *data, const size_t len) 312static bool rt2800_check_firmware_crc(const u8 *data, const size_t len)
299{ 313{
300 u16 fw_crc; 314 u16 fw_crc;
@@ -412,6 +426,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
412 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); 426 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002);
413 } 427 }
414 428
429 rt2800_disable_wpdma(rt2x00dev);
430
415 /* 431 /*
416 * Write firmware to the device. 432 * Write firmware to the device.
417 */ 433 */
@@ -436,10 +452,7 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
436 * Disable DMA, will be reenabled later when enabling 452 * Disable DMA, will be reenabled later when enabling
437 * the radio. 453 * the radio.
438 */ 454 */
439 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg); 455 rt2800_disable_wpdma(rt2x00dev);
440 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
441 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
442 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
443 456
444 /* 457 /*
445 * Initialize firmware. 458 * Initialize firmware.
@@ -2717,13 +2730,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
2717 unsigned int i; 2730 unsigned int i;
2718 int ret; 2731 int ret;
2719 2732
2720 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg); 2733 rt2800_disable_wpdma(rt2x00dev);
2721 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
2722 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
2723 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
2724 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
2725 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
2726 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
2727 2734
2728 ret = rt2800_drv_init_registers(rt2x00dev); 2735 ret = rt2800_drv_init_registers(rt2x00dev);
2729 if (ret) 2736 if (ret)
@@ -3997,10 +4004,7 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev)
3997{ 4004{
3998 u32 reg; 4005 u32 reg;
3999 4006
4000 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg); 4007 rt2800_disable_wpdma(rt2x00dev);
4001 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
4002 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
4003 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
4004 4008
4005 /* Wait for DMA, ignore error */ 4009 /* Wait for DMA, ignore error */
4006 rt2800_wait_wpdma_ready(rt2x00dev); 4010 rt2800_wait_wpdma_ready(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 419e36cb06be..18a0b67b4c68 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -208,5 +208,6 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
208 u8 buf_size); 208 u8 buf_size);
209int rt2800_get_survey(struct ieee80211_hw *hw, int idx, 209int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
210 struct survey_info *survey); 210 struct survey_info *survey);
211void rt2800_disable_wpdma(struct rt2x00_dev *rt2x00dev);
211 212
212#endif /* RT2800LIB_H */ 213#endif /* RT2800LIB_H */
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 0397bbf0ce01..931331d95217 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -361,7 +361,6 @@ static void rt2800pci_clear_entry(struct queue_entry *entry)
361static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) 361static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
362{ 362{
363 struct queue_entry_priv_pci *entry_priv; 363 struct queue_entry_priv_pci *entry_priv;
364 u32 reg;
365 364
366 /* 365 /*
367 * Initialize registers. 366 * Initialize registers.
@@ -394,6 +393,16 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
394 rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX3, 0); 393 rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX3, 0);
395 rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX3, 0); 394 rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX3, 0);
396 395
396 rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR4, 0);
397 rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT4, 0);
398 rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX4, 0);
399 rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX4, 0);
400
401 rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR5, 0);
402 rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT5, 0);
403 rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX5, 0);
404 rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX5, 0);
405
397 entry_priv = rt2x00dev->rx->entries[0].priv_data; 406 entry_priv = rt2x00dev->rx->entries[0].priv_data;
398 rt2x00pci_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma); 407 rt2x00pci_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma);
399 rt2x00pci_register_write(rt2x00dev, RX_MAX_CNT, 408 rt2x00pci_register_write(rt2x00dev, RX_MAX_CNT,
@@ -402,14 +411,7 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
402 rt2x00dev->rx[0].limit - 1); 411 rt2x00dev->rx[0].limit - 1);
403 rt2x00pci_register_write(rt2x00dev, RX_DRX_IDX, 0); 412 rt2x00pci_register_write(rt2x00dev, RX_DRX_IDX, 0);
404 413
405 /* 414 rt2800_disable_wpdma(rt2x00dev);
406 * Enable global DMA configuration
407 */
408 rt2x00pci_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
409 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
410 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
411 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
412 rt2x00pci_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
413 415
414 rt2x00pci_register_write(rt2x00dev, DELAY_INT_CFG, 0); 416 rt2x00pci_register_write(rt2x00dev, DELAY_INT_CFG, 0);
415 417
@@ -504,8 +506,10 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
504{ 506{
505 int retval; 507 int retval;
506 508
507 if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || 509 /* Wait for DMA, ignore error until we initialize queues. */
508 rt2800pci_init_queues(rt2x00dev))) 510 rt2800_wait_wpdma_ready(rt2x00dev);
511
512 if (unlikely(rt2800pci_init_queues(rt2x00dev)))
509 return -EIO; 513 return -EIO;
510 514
511 retval = rt2800_enable_radio(rt2x00dev); 515 retval = rt2800_enable_radio(rt2x00dev);
@@ -1184,7 +1188,9 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
1184 { PCI_DEVICE(0x1814, 0x3593) }, 1188 { PCI_DEVICE(0x1814, 0x3593) },
1185#endif 1189#endif
1186#ifdef CONFIG_RT2800PCI_RT53XX 1190#ifdef CONFIG_RT2800PCI_RT53XX
1191 { PCI_DEVICE(0x1814, 0x5362) },
1187 { PCI_DEVICE(0x1814, 0x5390) }, 1192 { PCI_DEVICE(0x1814, 0x5390) },
1193 { PCI_DEVICE(0x1814, 0x5392) },
1188 { PCI_DEVICE(0x1814, 0x539a) }, 1194 { PCI_DEVICE(0x1814, 0x539a) },
1189 { PCI_DEVICE(0x1814, 0x539f) }, 1195 { PCI_DEVICE(0x1814, 0x539f) },
1190#endif 1196#endif
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 90cc5e772650..dd87d41ac936 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -391,9 +391,10 @@ void rt2x00lib_txdone(struct queue_entry *entry,
391 tx_info->flags |= IEEE80211_TX_STAT_AMPDU; 391 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
392 tx_info->status.ampdu_len = 1; 392 tx_info->status.ampdu_len = 1;
393 tx_info->status.ampdu_ack_len = success ? 1 : 0; 393 tx_info->status.ampdu_ack_len = success ? 1 : 0;
394 394 /*
395 if (!success) 395 * TODO: Need to tear down BA session here
396 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 396 * if not successful.
397 */
397 } 398 }
398 399
399 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { 400 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index e0c6d117429d..ee22bd74579d 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -3092,15 +3092,4 @@ static struct pci_driver rt61pci_driver = {
3092 .resume = rt2x00pci_resume, 3092 .resume = rt2x00pci_resume,
3093}; 3093};
3094 3094
3095static int __init rt61pci_init(void) 3095module_pci_driver(rt61pci_driver);
3096{
3097 return pci_register_driver(&rt61pci_driver);
3098}
3099
3100static void __exit rt61pci_exit(void)
3101{
3102 pci_unregister_driver(&rt61pci_driver);
3103}
3104
3105module_init(rt61pci_init);
3106module_exit(rt61pci_exit);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index e477a964081d..155136691a38 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2412,6 +2412,7 @@ static struct usb_device_id rt73usb_device_table[] = {
2412 { USB_DEVICE(0x0b05, 0x1723) }, 2412 { USB_DEVICE(0x0b05, 0x1723) },
2413 { USB_DEVICE(0x0b05, 0x1724) }, 2413 { USB_DEVICE(0x0b05, 0x1724) },
2414 /* Belkin */ 2414 /* Belkin */
2415 { USB_DEVICE(0x050d, 0x7050) }, /* FCC ID: K7SF5D7050B ver. 3.x */
2415 { USB_DEVICE(0x050d, 0x705a) }, 2416 { USB_DEVICE(0x050d, 0x705a) },
2416 { USB_DEVICE(0x050d, 0x905b) }, 2417 { USB_DEVICE(0x050d, 0x905b) },
2417 { USB_DEVICE(0x050d, 0x905c) }, 2418 { USB_DEVICE(0x050d, 0x905c) },
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 2f14a5fb0cbb..2bebcb71a1e9 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -1173,15 +1173,4 @@ static struct pci_driver rtl8180_driver = {
1173#endif /* CONFIG_PM */ 1173#endif /* CONFIG_PM */
1174}; 1174};
1175 1175
1176static int __init rtl8180_init(void) 1176module_pci_driver(rtl8180_driver);
1177{
1178 return pci_register_driver(&rtl8180_driver);
1179}
1180
1181static void __exit rtl8180_exit(void)
1182{
1183 pci_unregister_driver(&rtl8180_driver);
1184}
1185
1186module_init(rtl8180_init);
1187module_exit(rtl8180_exit);
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index cf53ac9d6f23..d8114962b0c9 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -294,6 +294,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
294 hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); 294 hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8);
295 hdr->tx_duration = 295 hdr->tx_duration =
296 ieee80211_generic_frame_duration(dev, priv->vif, 296 ieee80211_generic_frame_duration(dev, priv->vif,
297 info->band,
297 skb->len, txrate); 298 skb->len, txrate);
298 buf = hdr; 299 buf = hdr;
299 300
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 288b035a3579..81d0c9b34328 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -34,6 +34,7 @@
34#include "ps.h" 34#include "ps.h"
35#include "efuse.h" 35#include "efuse.h"
36#include <linux/export.h> 36#include <linux/export.h>
37#include <linux/kmemleak.h>
37 38
38static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { 39static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
39 PCI_VENDOR_ID_INTEL, 40 PCI_VENDOR_ID_INTEL,
@@ -1099,6 +1100,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
1099 u32 bufferaddress; 1100 u32 bufferaddress;
1100 if (!skb) 1101 if (!skb)
1101 return 0; 1102 return 0;
1103 kmemleak_not_leak(skb);
1102 entry = &rtlpci->rx_ring[rx_queue_idx].desc[i]; 1104 entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
1103 1105
1104 /*skb->dev = dev; */ 1106 /*skb->dev = dev; */
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index c20b3c30f62e..692c8ef5ee89 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -34,6 +34,7 @@
34#include "../rtl8192ce/def.h" 34#include "../rtl8192ce/def.h"
35#include "fw_common.h" 35#include "fw_common.h"
36#include <linux/export.h> 36#include <linux/export.h>
37#include <linux/kmemleak.h>
37 38
38static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) 39static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
39{ 40{
@@ -776,6 +777,8 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
776 skb = dev_alloc_skb(totalpacketlen); 777 skb = dev_alloc_skb(totalpacketlen);
777 if (!skb) 778 if (!skb)
778 return; 779 return;
780 kmemleak_not_leak(skb);
781
779 memcpy((u8 *) skb_put(skb, totalpacketlen), 782 memcpy((u8 *) skb_put(skb, totalpacketlen),
780 &reserved_page_packet, totalpacketlen); 783 &reserved_page_packet, totalpacketlen);
781 784
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index 2c3b73366cd2..3aa927f8b9b9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -389,21 +389,4 @@ static struct pci_driver rtl92ce_driver = {
389 .driver.pm = &rtlwifi_pm_ops, 389 .driver.pm = &rtlwifi_pm_ops,
390}; 390};
391 391
392static int __init rtl92ce_module_init(void) 392module_pci_driver(rtl92ce_driver);
393{
394 int ret;
395
396 ret = pci_register_driver(&rtl92ce_driver);
397 if (ret)
398 RT_ASSERT(false, "No device found\n");
399
400 return ret;
401}
402
403static void __exit rtl92ce_module_exit(void)
404{
405 pci_unregister_driver(&rtl92ce_driver);
406}
407
408module_init(rtl92ce_module_init);
409module_exit(rtl92ce_module_exit);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 82c85286ab2e..7737fb0c6661 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -338,6 +338,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
338 {RTL_USB_DEVICE(0x2019, 0x1201, rtl92cu_hal_cfg)}, /*Planex-Vencer*/ 338 {RTL_USB_DEVICE(0x2019, 0x1201, rtl92cu_hal_cfg)}, /*Planex-Vencer*/
339 339
340 /****** 8192CU ********/ 340 /****** 8192CU ********/
341 {RTL_USB_DEVICE(0x050d, 0x1004, rtl92cu_hal_cfg)}, /*Belcom-SurfN300*/
341 {RTL_USB_DEVICE(0x050d, 0x2102, rtl92cu_hal_cfg)}, /*Belcom-Sercomm*/ 342 {RTL_USB_DEVICE(0x050d, 0x2102, rtl92cu_hal_cfg)}, /*Belcom-Sercomm*/
342 {RTL_USB_DEVICE(0x050d, 0x2103, rtl92cu_hal_cfg)}, /*Belcom-Edimax*/ 343 {RTL_USB_DEVICE(0x050d, 0x2103, rtl92cu_hal_cfg)}, /*Belcom-Edimax*/
343 {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ 344 {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
index eafdf76ed64d..939c905f547f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
@@ -151,9 +151,6 @@ enum version_8192d {
151 151
152/* for 92D */ 152/* for 92D */
153#define CHIP_92D_SINGLEPHY BIT(9) 153#define CHIP_92D_SINGLEPHY BIT(9)
154#define C_CUT_VERSION BIT(13)
155#define D_CUT_VERSION ((BIT(12)|BIT(13)))
156#define E_CUT_VERSION BIT(14)
157 154
158/* Chip specific */ 155/* Chip specific */
159#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) 156#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)
@@ -173,7 +170,10 @@ enum version_8192d {
173#define RF_TYPE_1T2R BIT(4) 170#define RF_TYPE_1T2R BIT(4)
174#define RF_TYPE_2T2R BIT(5) 171#define RF_TYPE_2T2R BIT(5)
175#define CHIP_VENDOR_UMC BIT(7) 172#define CHIP_VENDOR_UMC BIT(7)
176#define B_CUT_VERSION BIT(12) 173#define CHIP_92D_B_CUT BIT(12)
174#define CHIP_92D_C_CUT BIT(13)
175#define CHIP_92D_D_CUT (BIT(13)|BIT(12))
176#define CHIP_92D_E_CUT BIT(14)
177 177
178/* MASK */ 178/* MASK */
179#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) 179#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2))
@@ -205,15 +205,13 @@ enum version_8192d {
205 CHIP_92D) ? true : false) 205 CHIP_92D) ? true : false)
206#define IS_92D_C_CUT(version) ((IS_92D(version)) ? \ 206#define IS_92D_C_CUT(version) ((IS_92D(version)) ? \
207 ((GET_CVID_CUT_VERSION(version) == \ 207 ((GET_CVID_CUT_VERSION(version) == \
208 0x2000) ? true : false) : false) 208 CHIP_92D_C_CUT) ? true : false) : false)
209#define IS_92D_D_CUT(version) ((IS_92D(version)) ? \ 209#define IS_92D_D_CUT(version) ((IS_92D(version)) ? \
210 ((GET_CVID_CUT_VERSION(version) == \ 210 ((GET_CVID_CUT_VERSION(version) == \
211 0x3000) ? true : false) : false) 211 CHIP_92D_D_CUT) ? true : false) : false)
212#define IS_92D_E_CUT(version) ((IS_92D(version)) ? \ 212#define IS_92D_E_CUT(version) ((IS_92D(version)) ? \
213 ((GET_CVID_CUT_VERSION(version) == \ 213 ((GET_CVID_CUT_VERSION(version) == \
214 0x4000) ? true : false) : false) 214 CHIP_92D_E_CUT) ? true : false) : false)
215#define CHIP_92D_C_CUT BIT(10)
216#define CHIP_92D_D_CUT BIT(11)
217 215
218enum rf_optype { 216enum rf_optype {
219 RF_OP_BY_SW_3WIRE = 0, 217 RF_OP_BY_SW_3WIRE = 0,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index 7ac9b8cb2ced..b338d526c422 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -1743,6 +1743,10 @@ static void _rtl92de_efuse_update_chip_version(struct ieee80211_hw *hw)
1743 chipver |= CHIP_92D_D_CUT; 1743 chipver |= CHIP_92D_D_CUT;
1744 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n"); 1744 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n");
1745 break; 1745 break;
1746 case 0xCC33:
1747 chipver |= CHIP_92D_E_CUT;
1748 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "E-CUT!!!\n");
1749 break;
1746 default: 1750 default:
1747 chipver |= CHIP_92D_D_CUT; 1751 chipver |= CHIP_92D_D_CUT;
1748 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unknown CUT!\n"); 1752 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unknown CUT!\n");
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
index f1b36005c6a2..730bcc919529 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -450,21 +450,4 @@ static struct pci_driver rtl92se_driver = {
450 .driver.pm = &rtlwifi_pm_ops, 450 .driver.pm = &rtlwifi_pm_ops,
451}; 451};
452 452
453static int __init rtl92se_module_init(void) 453module_pci_driver(rtl92se_driver);
454{
455 int ret = 0;
456
457 ret = pci_register_driver(&rtl92se_driver);
458 if (ret)
459 RT_ASSERT(false, "No device found\n");
460
461 return ret;
462}
463
464static void __exit rtl92se_module_exit(void)
465{
466 pci_unregister_driver(&rtl92se_driver);
467}
468
469module_init(rtl92se_module_init);
470module_exit(rtl92se_module_exit);
diff --git a/drivers/net/wireless/ti/Kconfig b/drivers/net/wireless/ti/Kconfig
new file mode 100644
index 000000000000..1a72932e2213
--- /dev/null
+++ b/drivers/net/wireless/ti/Kconfig
@@ -0,0 +1,14 @@
1menuconfig WL_TI
2 bool "TI Wireless LAN support"
3 ---help---
4 This section contains support for all the wireless drivers
5 for Texas Instruments WLAN chips, such as wl1251 and the wl12xx
6 family.
7
8if WL_TI
9source "drivers/net/wireless/ti/wl1251/Kconfig"
10source "drivers/net/wireless/ti/wl12xx/Kconfig"
11
12# keep last for automatic dependencies
13source "drivers/net/wireless/ti/wlcore/Kconfig"
14endif # WL_TI
diff --git a/drivers/net/wireless/ti/Makefile b/drivers/net/wireless/ti/Makefile
new file mode 100644
index 000000000000..0a565622d4a4
--- /dev/null
+++ b/drivers/net/wireless/ti/Makefile
@@ -0,0 +1,4 @@
1obj-$(CONFIG_WLCORE) += wlcore/
2obj-$(CONFIG_WL12XX) += wl12xx/
3obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wlcore/
4obj-$(CONFIG_WL1251) += wl1251/
diff --git a/drivers/net/wireless/wl1251/Kconfig b/drivers/net/wireless/ti/wl1251/Kconfig
index 1fb65849414f..1fb65849414f 100644
--- a/drivers/net/wireless/wl1251/Kconfig
+++ b/drivers/net/wireless/ti/wl1251/Kconfig
diff --git a/drivers/net/wireless/wl1251/Makefile b/drivers/net/wireless/ti/wl1251/Makefile
index a5c6328b5f72..a5c6328b5f72 100644
--- a/drivers/net/wireless/wl1251/Makefile
+++ b/drivers/net/wireless/ti/wl1251/Makefile
diff --git a/drivers/net/wireless/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c
index ad87a1ac6462..ad87a1ac6462 100644
--- a/drivers/net/wireless/wl1251/acx.c
+++ b/drivers/net/wireless/ti/wl1251/acx.c
diff --git a/drivers/net/wireless/wl1251/acx.h b/drivers/net/wireless/ti/wl1251/acx.h
index c2ba100f9b1a..c2ba100f9b1a 100644
--- a/drivers/net/wireless/wl1251/acx.h
+++ b/drivers/net/wireless/ti/wl1251/acx.h
diff --git a/drivers/net/wireless/wl1251/boot.c b/drivers/net/wireless/ti/wl1251/boot.c
index a2e5241382da..a2e5241382da 100644
--- a/drivers/net/wireless/wl1251/boot.c
+++ b/drivers/net/wireless/ti/wl1251/boot.c
diff --git a/drivers/net/wireless/wl1251/boot.h b/drivers/net/wireless/ti/wl1251/boot.h
index 7661bc5e4662..7661bc5e4662 100644
--- a/drivers/net/wireless/wl1251/boot.h
+++ b/drivers/net/wireless/ti/wl1251/boot.h
diff --git a/drivers/net/wireless/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c
index d14d69d733a0..d14d69d733a0 100644
--- a/drivers/net/wireless/wl1251/cmd.c
+++ b/drivers/net/wireless/ti/wl1251/cmd.c
diff --git a/drivers/net/wireless/wl1251/cmd.h b/drivers/net/wireless/ti/wl1251/cmd.h
index ee4f2b391822..ee4f2b391822 100644
--- a/drivers/net/wireless/wl1251/cmd.h
+++ b/drivers/net/wireless/ti/wl1251/cmd.h
diff --git a/drivers/net/wireless/wl1251/debugfs.c b/drivers/net/wireless/ti/wl1251/debugfs.c
index 448da1f8c22f..448da1f8c22f 100644
--- a/drivers/net/wireless/wl1251/debugfs.c
+++ b/drivers/net/wireless/ti/wl1251/debugfs.c
diff --git a/drivers/net/wireless/wl1251/debugfs.h b/drivers/net/wireless/ti/wl1251/debugfs.h
index b3417c02a218..b3417c02a218 100644
--- a/drivers/net/wireless/wl1251/debugfs.h
+++ b/drivers/net/wireless/ti/wl1251/debugfs.h
diff --git a/drivers/net/wireless/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c
index 9f15ccaf8f05..9f15ccaf8f05 100644
--- a/drivers/net/wireless/wl1251/event.c
+++ b/drivers/net/wireless/ti/wl1251/event.c
diff --git a/drivers/net/wireless/wl1251/event.h b/drivers/net/wireless/ti/wl1251/event.h
index 30eb5d150bf7..30eb5d150bf7 100644
--- a/drivers/net/wireless/wl1251/event.h
+++ b/drivers/net/wireless/ti/wl1251/event.h
diff --git a/drivers/net/wireless/wl1251/init.c b/drivers/net/wireless/ti/wl1251/init.c
index 89b43d35473c..89b43d35473c 100644
--- a/drivers/net/wireless/wl1251/init.c
+++ b/drivers/net/wireless/ti/wl1251/init.c
diff --git a/drivers/net/wireless/wl1251/init.h b/drivers/net/wireless/ti/wl1251/init.h
index 543f17582ead..543f17582ead 100644
--- a/drivers/net/wireless/wl1251/init.h
+++ b/drivers/net/wireless/ti/wl1251/init.h
diff --git a/drivers/net/wireless/wl1251/io.c b/drivers/net/wireless/ti/wl1251/io.c
index cdcadbf6ac2c..cdcadbf6ac2c 100644
--- a/drivers/net/wireless/wl1251/io.c
+++ b/drivers/net/wireless/ti/wl1251/io.c
diff --git a/drivers/net/wireless/wl1251/io.h b/drivers/net/wireless/ti/wl1251/io.h
index d382877c34cc..d382877c34cc 100644
--- a/drivers/net/wireless/wl1251/io.h
+++ b/drivers/net/wireless/ti/wl1251/io.h
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 41302c7b1ad0..41302c7b1ad0 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/ti/wl1251/ps.c
index db719f7d2692..db719f7d2692 100644
--- a/drivers/net/wireless/wl1251/ps.c
+++ b/drivers/net/wireless/ti/wl1251/ps.c
diff --git a/drivers/net/wireless/wl1251/ps.h b/drivers/net/wireless/ti/wl1251/ps.h
index 75efad246d67..75efad246d67 100644
--- a/drivers/net/wireless/wl1251/ps.h
+++ b/drivers/net/wireless/ti/wl1251/ps.h
diff --git a/drivers/net/wireless/wl1251/reg.h b/drivers/net/wireless/ti/wl1251/reg.h
index a5809019c5c1..a5809019c5c1 100644
--- a/drivers/net/wireless/wl1251/reg.h
+++ b/drivers/net/wireless/ti/wl1251/reg.h
diff --git a/drivers/net/wireless/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c
index 6af35265c900..6af35265c900 100644
--- a/drivers/net/wireless/wl1251/rx.c
+++ b/drivers/net/wireless/ti/wl1251/rx.c
diff --git a/drivers/net/wireless/wl1251/rx.h b/drivers/net/wireless/ti/wl1251/rx.h
index 4448f635a4d8..4448f635a4d8 100644
--- a/drivers/net/wireless/wl1251/rx.h
+++ b/drivers/net/wireless/ti/wl1251/rx.h
diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index f78694295c39..f78694295c39 100644
--- a/drivers/net/wireless/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 6248c354fc5c..6248c354fc5c 100644
--- a/drivers/net/wireless/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
diff --git a/drivers/net/wireless/wl1251/spi.h b/drivers/net/wireless/ti/wl1251/spi.h
index 16d506955cc0..16d506955cc0 100644
--- a/drivers/net/wireless/wl1251/spi.h
+++ b/drivers/net/wireless/ti/wl1251/spi.h
diff --git a/drivers/net/wireless/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c
index 28121c590a2b..28121c590a2b 100644
--- a/drivers/net/wireless/wl1251/tx.c
+++ b/drivers/net/wireless/ti/wl1251/tx.c
diff --git a/drivers/net/wireless/wl1251/tx.h b/drivers/net/wireless/ti/wl1251/tx.h
index 81338d39b43e..81338d39b43e 100644
--- a/drivers/net/wireless/wl1251/tx.h
+++ b/drivers/net/wireless/ti/wl1251/tx.h
diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 9d8f5816c6f9..9d8f5816c6f9 100644
--- a/drivers/net/wireless/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/ti/wl1251/wl12xx_80211.h
index 04ed51495772..04ed51495772 100644
--- a/drivers/net/wireless/wl1251/wl12xx_80211.h
+++ b/drivers/net/wireless/ti/wl1251/wl12xx_80211.h
diff --git a/drivers/net/wireless/ti/wl12xx/Kconfig b/drivers/net/wireless/ti/wl12xx/Kconfig
new file mode 100644
index 000000000000..5b92329122c4
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/Kconfig
@@ -0,0 +1,8 @@
1config WL12XX
2 tristate "TI wl12xx support"
3 select WLCORE
4 ---help---
5 This module adds support for wireless adapters based on TI wl1271,
6 wl1273, wl1281 and wl1283 chipsets. This module does *not* include
7 support for wl1251. For wl1251 support, use the separate homonymous
8 driver instead.
diff --git a/drivers/net/wireless/ti/wl12xx/Makefile b/drivers/net/wireless/ti/wl12xx/Makefile
new file mode 100644
index 000000000000..87f64b14db35
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/Makefile
@@ -0,0 +1,3 @@
1wl12xx-objs = main.o cmd.o acx.o
2
3obj-$(CONFIG_WL12XX) += wl12xx.o
diff --git a/drivers/net/wireless/ti/wl12xx/acx.c b/drivers/net/wireless/ti/wl12xx/acx.c
new file mode 100644
index 000000000000..bea06b2d7bf4
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/acx.c
@@ -0,0 +1,53 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 * Copyright (C) 2011 Texas Instruments Inc.
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, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include "../wlcore/cmd.h"
24#include "../wlcore/debug.h"
25#include "../wlcore/acx.h"
26
27#include "acx.h"
28
29int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap)
30{
31 struct wl1271_acx_host_config_bitmap *bitmap_conf;
32 int ret;
33
34 bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
35 if (!bitmap_conf) {
36 ret = -ENOMEM;
37 goto out;
38 }
39
40 bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
41
42 ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
43 bitmap_conf, sizeof(*bitmap_conf));
44 if (ret < 0) {
45 wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
46 goto out;
47 }
48
49out:
50 kfree(bitmap_conf);
51
52 return ret;
53}
diff --git a/drivers/net/wireless/ti/wl12xx/acx.h b/drivers/net/wireless/ti/wl12xx/acx.h
new file mode 100644
index 000000000000..d1f5aba0afce
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/acx.h
@@ -0,0 +1,36 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 1998-2009, 2011 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2010 Nokia Corporation
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, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef __WL12XX_ACX_H__
24#define __WL12XX_ACX_H__
25
26#include "../wlcore/wlcore.h"
27
28struct wl1271_acx_host_config_bitmap {
29 struct acx_header header;
30
31 __le32 host_cfg_bitmap;
32} __packed;
33
34int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap);
35
36#endif /* __WL12XX_ACX_H__ */
diff --git a/drivers/net/wireless/ti/wl12xx/cmd.c b/drivers/net/wireless/ti/wl12xx/cmd.c
new file mode 100644
index 000000000000..8ffaeb5f2147
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/cmd.c
@@ -0,0 +1,254 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2009-2010 Nokia Corporation
5 * Copyright (C) 2011 Texas Instruments Inc.
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, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include "../wlcore/cmd.h"
24#include "../wlcore/debug.h"
25
26#include "wl12xx.h"
27#include "cmd.h"
28
29int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
30{
31 struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
32 struct wl12xx_priv *priv = wl->priv;
33 struct wl12xx_conf_rf *rf = &priv->conf.rf;
34 int ret;
35
36 if (!wl->nvs)
37 return -ENODEV;
38
39 ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
40 if (!ext_radio_parms)
41 return -ENOMEM;
42
43 ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
44
45 memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
46 rf->tx_per_channel_power_compensation_2,
47 CONF_TX_PWR_COMPENSATION_LEN_2);
48 memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
49 rf->tx_per_channel_power_compensation_5,
50 CONF_TX_PWR_COMPENSATION_LEN_5);
51
52 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
53 ext_radio_parms, sizeof(*ext_radio_parms));
54
55 ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
56 if (ret < 0)
57 wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
58
59 kfree(ext_radio_parms);
60 return ret;
61}
62
63int wl1271_cmd_general_parms(struct wl1271 *wl)
64{
65 struct wl1271_general_parms_cmd *gen_parms;
66 struct wl1271_ini_general_params *gp =
67 &((struct wl1271_nvs_file *)wl->nvs)->general_params;
68 bool answer = false;
69 int ret;
70
71 if (!wl->nvs)
72 return -ENODEV;
73
74 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
75 wl1271_warning("FEM index from INI out of bounds");
76 return -EINVAL;
77 }
78
79 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
80 if (!gen_parms)
81 return -ENOMEM;
82
83 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
84
85 memcpy(&gen_parms->general_params, gp, sizeof(*gp));
86
87 if (gp->tx_bip_fem_auto_detect)
88 answer = true;
89
90 /* Override the REF CLK from the NVS with the one from platform data */
91 gen_parms->general_params.ref_clock = wl->ref_clock;
92
93 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
94 if (ret < 0) {
95 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
96 goto out;
97 }
98
99 gp->tx_bip_fem_manufacturer =
100 gen_parms->general_params.tx_bip_fem_manufacturer;
101
102 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
103 wl1271_warning("FEM index from FW out of bounds");
104 ret = -EINVAL;
105 goto out;
106 }
107
108 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
109 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
110
111out:
112 kfree(gen_parms);
113 return ret;
114}
115
116int wl128x_cmd_general_parms(struct wl1271 *wl)
117{
118 struct wl128x_general_parms_cmd *gen_parms;
119 struct wl128x_ini_general_params *gp =
120 &((struct wl128x_nvs_file *)wl->nvs)->general_params;
121 bool answer = false;
122 int ret;
123
124 if (!wl->nvs)
125 return -ENODEV;
126
127 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
128 wl1271_warning("FEM index from ini out of bounds");
129 return -EINVAL;
130 }
131
132 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
133 if (!gen_parms)
134 return -ENOMEM;
135
136 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
137
138 memcpy(&gen_parms->general_params, gp, sizeof(*gp));
139
140 if (gp->tx_bip_fem_auto_detect)
141 answer = true;
142
143 /* Replace REF and TCXO CLKs with the ones from platform data */
144 gen_parms->general_params.ref_clock = wl->ref_clock;
145 gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
146
147 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
148 if (ret < 0) {
149 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
150 goto out;
151 }
152
153 gp->tx_bip_fem_manufacturer =
154 gen_parms->general_params.tx_bip_fem_manufacturer;
155
156 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
157 wl1271_warning("FEM index from FW out of bounds");
158 ret = -EINVAL;
159 goto out;
160 }
161
162 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
163 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
164
165out:
166 kfree(gen_parms);
167 return ret;
168}
169
170int wl1271_cmd_radio_parms(struct wl1271 *wl)
171{
172 struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
173 struct wl1271_radio_parms_cmd *radio_parms;
174 struct wl1271_ini_general_params *gp = &nvs->general_params;
175 int ret;
176
177 if (!wl->nvs)
178 return -ENODEV;
179
180 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
181 if (!radio_parms)
182 return -ENOMEM;
183
184 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
185
186 /* 2.4GHz parameters */
187 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
188 sizeof(struct wl1271_ini_band_params_2));
189 memcpy(&radio_parms->dyn_params_2,
190 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
191 sizeof(struct wl1271_ini_fem_params_2));
192
193 /* 5GHz parameters */
194 memcpy(&radio_parms->static_params_5,
195 &nvs->stat_radio_params_5,
196 sizeof(struct wl1271_ini_band_params_5));
197 memcpy(&radio_parms->dyn_params_5,
198 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
199 sizeof(struct wl1271_ini_fem_params_5));
200
201 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
202 radio_parms, sizeof(*radio_parms));
203
204 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
205 if (ret < 0)
206 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
207
208 kfree(radio_parms);
209 return ret;
210}
211
212int wl128x_cmd_radio_parms(struct wl1271 *wl)
213{
214 struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
215 struct wl128x_radio_parms_cmd *radio_parms;
216 struct wl128x_ini_general_params *gp = &nvs->general_params;
217 int ret;
218
219 if (!wl->nvs)
220 return -ENODEV;
221
222 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
223 if (!radio_parms)
224 return -ENOMEM;
225
226 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
227
228 /* 2.4GHz parameters */
229 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
230 sizeof(struct wl128x_ini_band_params_2));
231 memcpy(&radio_parms->dyn_params_2,
232 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
233 sizeof(struct wl128x_ini_fem_params_2));
234
235 /* 5GHz parameters */
236 memcpy(&radio_parms->static_params_5,
237 &nvs->stat_radio_params_5,
238 sizeof(struct wl128x_ini_band_params_5));
239 memcpy(&radio_parms->dyn_params_5,
240 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
241 sizeof(struct wl128x_ini_fem_params_5));
242
243 radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
244
245 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
246 radio_parms, sizeof(*radio_parms));
247
248 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
249 if (ret < 0)
250 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
251
252 kfree(radio_parms);
253 return ret;
254}
diff --git a/drivers/net/wireless/ti/wl12xx/cmd.h b/drivers/net/wireless/ti/wl12xx/cmd.h
new file mode 100644
index 000000000000..140a0e8829d5
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/cmd.h
@@ -0,0 +1,112 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 1998-2009, 2011 Texas Instruments. All rights reserved.
5 * Copyright (C) 2009 Nokia Corporation
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, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef __WL12XX_CMD_H__
24#define __WL12XX_CMD_H__
25
26#include "conf.h"
27
28#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
29#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
30
31struct wl1271_general_parms_cmd {
32 struct wl1271_cmd_header header;
33
34 struct wl1271_cmd_test_header test;
35
36 struct wl1271_ini_general_params general_params;
37
38 u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
39 u8 sr_sen_n_p;
40 u8 sr_sen_n_p_gain;
41 u8 sr_sen_nrn;
42 u8 sr_sen_prn;
43 u8 padding[3];
44} __packed;
45
46struct wl128x_general_parms_cmd {
47 struct wl1271_cmd_header header;
48
49 struct wl1271_cmd_test_header test;
50
51 struct wl128x_ini_general_params general_params;
52
53 u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
54 u8 sr_sen_n_p;
55 u8 sr_sen_n_p_gain;
56 u8 sr_sen_nrn;
57 u8 sr_sen_prn;
58 u8 padding[3];
59} __packed;
60
61struct wl1271_radio_parms_cmd {
62 struct wl1271_cmd_header header;
63
64 struct wl1271_cmd_test_header test;
65
66 /* Static radio parameters */
67 struct wl1271_ini_band_params_2 static_params_2;
68 struct wl1271_ini_band_params_5 static_params_5;
69
70 /* Dynamic radio parameters */
71 struct wl1271_ini_fem_params_2 dyn_params_2;
72 u8 padding2;
73 struct wl1271_ini_fem_params_5 dyn_params_5;
74 u8 padding3[2];
75} __packed;
76
77struct wl128x_radio_parms_cmd {
78 struct wl1271_cmd_header header;
79
80 struct wl1271_cmd_test_header test;
81
82 /* Static radio parameters */
83 struct wl128x_ini_band_params_2 static_params_2;
84 struct wl128x_ini_band_params_5 static_params_5;
85
86 u8 fem_vendor_and_options;
87
88 /* Dynamic radio parameters */
89 struct wl128x_ini_fem_params_2 dyn_params_2;
90 u8 padding2;
91 struct wl128x_ini_fem_params_5 dyn_params_5;
92} __packed;
93
94#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
95
96struct wl1271_ext_radio_parms_cmd {
97 struct wl1271_cmd_header header;
98
99 struct wl1271_cmd_test_header test;
100
101 u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
102 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
103 u8 padding[3];
104} __packed;
105
106int wl1271_cmd_general_parms(struct wl1271 *wl);
107int wl128x_cmd_general_parms(struct wl1271 *wl);
108int wl1271_cmd_radio_parms(struct wl1271 *wl);
109int wl128x_cmd_radio_parms(struct wl1271 *wl);
110int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
111
112#endif /* __WL12XX_CMD_H__ */
diff --git a/drivers/net/wireless/ti/wl12xx/conf.h b/drivers/net/wireless/ti/wl12xx/conf.h
new file mode 100644
index 000000000000..75e29897a0f5
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/conf.h
@@ -0,0 +1,50 @@
1/*
2 * This file is part of wl12xx
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#ifndef __WL12XX_CONF_H__
23#define __WL12XX_CONF_H__
24
25/* these are number of channels on the band divided by two, rounded up */
26#define CONF_TX_PWR_COMPENSATION_LEN_2 7
27#define CONF_TX_PWR_COMPENSATION_LEN_5 18
28
29struct wl12xx_conf_rf {
30 /*
31 * Per channel power compensation for 2.4GHz
32 *
33 * Range: s8
34 */
35 u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
36
37 /*
38 * Per channel power compensation for 5GHz
39 *
40 * Range: s8
41 */
42 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
43};
44
45struct wl12xx_priv_conf {
46 struct wl12xx_conf_rf rf;
47 struct conf_memory_settings mem_wl127x;
48};
49
50#endif /* __WL12XX_CONF_H__ */
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
new file mode 100644
index 000000000000..d7dd3def07b5
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -0,0 +1,1388 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
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/module.h>
23#include <linux/platform_device.h>
24
25#include <linux/err.h>
26
27#include <linux/wl12xx.h>
28
29#include "../wlcore/wlcore.h"
30#include "../wlcore/debug.h"
31#include "../wlcore/io.h"
32#include "../wlcore/acx.h"
33#include "../wlcore/tx.h"
34#include "../wlcore/rx.h"
35#include "../wlcore/io.h"
36#include "../wlcore/boot.h"
37
38#include "wl12xx.h"
39#include "reg.h"
40#include "cmd.h"
41#include "acx.h"
42
43static struct wlcore_conf wl12xx_conf = {
44 .sg = {
45 .params = {
46 [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
47 [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
48 [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
49 [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
50 [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
51 [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
52 [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
53 [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
54 [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
55 [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
56 [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
57 [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
58 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
59 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
60 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
61 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
62 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
63 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
64 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
65 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
66 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
67 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
68 [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
69 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
70 [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
71 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
72 /* active scan params */
73 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
74 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
75 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
76 /* passive scan params */
77 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
78 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
79 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
80 /* passive scan in dual antenna params */
81 [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
82 [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
83 [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
84 /* general params */
85 [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
86 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
87 [CONF_SG_BEACON_MISS_PERCENT] = 60,
88 [CONF_SG_DHCP_TIME] = 5000,
89 [CONF_SG_RXT] = 1200,
90 [CONF_SG_TXT] = 1000,
91 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
92 [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
93 [CONF_SG_HV3_MAX_SERVED] = 6,
94 [CONF_SG_PS_POLL_TIMEOUT] = 10,
95 [CONF_SG_UPSD_TIMEOUT] = 10,
96 [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
97 [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
98 [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
99 /* AP params */
100 [CONF_AP_BEACON_MISS_TX] = 3,
101 [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
102 [CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
103 [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
104 [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
105 [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
106 /* CTS Diluting params */
107 [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
108 [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
109 },
110 .state = CONF_SG_PROTECTIVE,
111 },
112 .rx = {
113 .rx_msdu_life_time = 512000,
114 .packet_detection_threshold = 0,
115 .ps_poll_timeout = 15,
116 .upsd_timeout = 15,
117 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
118 .rx_cca_threshold = 0,
119 .irq_blk_threshold = 0xFFFF,
120 .irq_pkt_threshold = 0,
121 .irq_timeout = 600,
122 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
123 },
124 .tx = {
125 .tx_energy_detection = 0,
126 .sta_rc_conf = {
127 .enabled_rates = 0,
128 .short_retry_limit = 10,
129 .long_retry_limit = 10,
130 .aflags = 0,
131 },
132 .ac_conf_count = 4,
133 .ac_conf = {
134 [CONF_TX_AC_BE] = {
135 .ac = CONF_TX_AC_BE,
136 .cw_min = 15,
137 .cw_max = 63,
138 .aifsn = 3,
139 .tx_op_limit = 0,
140 },
141 [CONF_TX_AC_BK] = {
142 .ac = CONF_TX_AC_BK,
143 .cw_min = 15,
144 .cw_max = 63,
145 .aifsn = 7,
146 .tx_op_limit = 0,
147 },
148 [CONF_TX_AC_VI] = {
149 .ac = CONF_TX_AC_VI,
150 .cw_min = 15,
151 .cw_max = 63,
152 .aifsn = CONF_TX_AIFS_PIFS,
153 .tx_op_limit = 3008,
154 },
155 [CONF_TX_AC_VO] = {
156 .ac = CONF_TX_AC_VO,
157 .cw_min = 15,
158 .cw_max = 63,
159 .aifsn = CONF_TX_AIFS_PIFS,
160 .tx_op_limit = 1504,
161 },
162 },
163 .max_tx_retries = 100,
164 .ap_aging_period = 300,
165 .tid_conf_count = 4,
166 .tid_conf = {
167 [CONF_TX_AC_BE] = {
168 .queue_id = CONF_TX_AC_BE,
169 .channel_type = CONF_CHANNEL_TYPE_EDCF,
170 .tsid = CONF_TX_AC_BE,
171 .ps_scheme = CONF_PS_SCHEME_LEGACY,
172 .ack_policy = CONF_ACK_POLICY_LEGACY,
173 .apsd_conf = {0, 0},
174 },
175 [CONF_TX_AC_BK] = {
176 .queue_id = CONF_TX_AC_BK,
177 .channel_type = CONF_CHANNEL_TYPE_EDCF,
178 .tsid = CONF_TX_AC_BK,
179 .ps_scheme = CONF_PS_SCHEME_LEGACY,
180 .ack_policy = CONF_ACK_POLICY_LEGACY,
181 .apsd_conf = {0, 0},
182 },
183 [CONF_TX_AC_VI] = {
184 .queue_id = CONF_TX_AC_VI,
185 .channel_type = CONF_CHANNEL_TYPE_EDCF,
186 .tsid = CONF_TX_AC_VI,
187 .ps_scheme = CONF_PS_SCHEME_LEGACY,
188 .ack_policy = CONF_ACK_POLICY_LEGACY,
189 .apsd_conf = {0, 0},
190 },
191 [CONF_TX_AC_VO] = {
192 .queue_id = CONF_TX_AC_VO,
193 .channel_type = CONF_CHANNEL_TYPE_EDCF,
194 .tsid = CONF_TX_AC_VO,
195 .ps_scheme = CONF_PS_SCHEME_LEGACY,
196 .ack_policy = CONF_ACK_POLICY_LEGACY,
197 .apsd_conf = {0, 0},
198 },
199 },
200 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
201 .tx_compl_timeout = 700,
202 .tx_compl_threshold = 4,
203 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
204 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
205 .tmpl_short_retry_limit = 10,
206 .tmpl_long_retry_limit = 10,
207 .tx_watchdog_timeout = 5000,
208 },
209 .conn = {
210 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
211 .listen_interval = 1,
212 .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
213 .suspend_listen_interval = 3,
214 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
215 .bcn_filt_ie_count = 2,
216 .bcn_filt_ie = {
217 [0] = {
218 .ie = WLAN_EID_CHANNEL_SWITCH,
219 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
220 },
221 [1] = {
222 .ie = WLAN_EID_HT_OPERATION,
223 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
224 },
225 },
226 .synch_fail_thold = 10,
227 .bss_lose_timeout = 100,
228 .beacon_rx_timeout = 10000,
229 .broadcast_timeout = 20000,
230 .rx_broadcast_in_ps = 1,
231 .ps_poll_threshold = 10,
232 .bet_enable = CONF_BET_MODE_ENABLE,
233 .bet_max_consecutive = 50,
234 .psm_entry_retries = 8,
235 .psm_exit_retries = 16,
236 .psm_entry_nullfunc_retries = 3,
237 .dynamic_ps_timeout = 40,
238 .forced_ps = false,
239 .keep_alive_interval = 55000,
240 .max_listen_interval = 20,
241 },
242 .itrim = {
243 .enable = false,
244 .timeout = 50000,
245 },
246 .pm_config = {
247 .host_clk_settling_time = 5000,
248 .host_fast_wakeup_support = false
249 },
250 .roam_trigger = {
251 .trigger_pacing = 1,
252 .avg_weight_rssi_beacon = 20,
253 .avg_weight_rssi_data = 10,
254 .avg_weight_snr_beacon = 20,
255 .avg_weight_snr_data = 10,
256 },
257 .scan = {
258 .min_dwell_time_active = 7500,
259 .max_dwell_time_active = 30000,
260 .min_dwell_time_passive = 100000,
261 .max_dwell_time_passive = 100000,
262 .num_probe_reqs = 2,
263 .split_scan_timeout = 50000,
264 },
265 .sched_scan = {
266 /*
267 * Values are in TU/1000 but since sched scan FW command
268 * params are in TUs rounding up may occur.
269 */
270 .base_dwell_time = 7500,
271 .max_dwell_time_delta = 22500,
272 /* based on 250bits per probe @1Mbps */
273 .dwell_time_delta_per_probe = 2000,
274 /* based on 250bits per probe @6Mbps (plus a bit more) */
275 .dwell_time_delta_per_probe_5 = 350,
276 .dwell_time_passive = 100000,
277 .dwell_time_dfs = 150000,
278 .num_probe_reqs = 2,
279 .rssi_threshold = -90,
280 .snr_threshold = 0,
281 },
282 .ht = {
283 .rx_ba_win_size = 8,
284 .tx_ba_win_size = 64,
285 .inactivity_timeout = 10000,
286 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
287 },
288 /*
289 * Memory config for wl127x chips is given in the
290 * wl12xx_default_priv_conf struct. The below configuration is
291 * for wl128x chips.
292 */
293 .mem = {
294 .num_stations = 1,
295 .ssid_profiles = 1,
296 .rx_block_num = 40,
297 .tx_min_block_num = 40,
298 .dynamic_memory = 1,
299 .min_req_tx_blocks = 45,
300 .min_req_rx_blocks = 22,
301 .tx_min = 27,
302 },
303 .fm_coex = {
304 .enable = true,
305 .swallow_period = 5,
306 .n_divider_fref_set_1 = 0xff, /* default */
307 .n_divider_fref_set_2 = 12,
308 .m_divider_fref_set_1 = 148,
309 .m_divider_fref_set_2 = 0xffff, /* default */
310 .coex_pll_stabilization_time = 0xffffffff, /* default */
311 .ldo_stabilization_time = 0xffff, /* default */
312 .fm_disturbed_band_margin = 0xff, /* default */
313 .swallow_clk_diff = 0xff, /* default */
314 },
315 .rx_streaming = {
316 .duration = 150,
317 .queues = 0x1,
318 .interval = 20,
319 .always = 0,
320 },
321 .fwlog = {
322 .mode = WL12XX_FWLOG_ON_DEMAND,
323 .mem_blocks = 2,
324 .severity = 0,
325 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
326 .output = WL12XX_FWLOG_OUTPUT_HOST,
327 .threshold = 0,
328 },
329 .rate = {
330 .rate_retry_score = 32000,
331 .per_add = 8192,
332 .per_th1 = 2048,
333 .per_th2 = 4096,
334 .max_per = 8100,
335 .inverse_curiosity_factor = 5,
336 .tx_fail_low_th = 4,
337 .tx_fail_high_th = 10,
338 .per_alpha_shift = 4,
339 .per_add_shift = 13,
340 .per_beta1_shift = 10,
341 .per_beta2_shift = 8,
342 .rate_check_up = 2,
343 .rate_check_down = 12,
344 .rate_retry_policy = {
345 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00,
348 },
349 },
350 .hangover = {
351 .recover_time = 0,
352 .hangover_period = 20,
353 .dynamic_mode = 1,
354 .early_termination_mode = 1,
355 .max_period = 20,
356 .min_period = 1,
357 .increase_delta = 1,
358 .decrease_delta = 2,
359 .quiet_time = 4,
360 .increase_time = 1,
361 .window_size = 16,
362 },
363};
364
365static struct wl12xx_priv_conf wl12xx_default_priv_conf = {
366 .rf = {
367 .tx_per_channel_power_compensation_2 = {
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 },
370 .tx_per_channel_power_compensation_5 = {
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 },
375 },
376 .mem_wl127x = {
377 .num_stations = 1,
378 .ssid_profiles = 1,
379 .rx_block_num = 70,
380 .tx_min_block_num = 40,
381 .dynamic_memory = 1,
382 .min_req_tx_blocks = 100,
383 .min_req_rx_blocks = 22,
384 .tx_min = 27,
385 },
386
387};
388
389#define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT 1
390#define WL12XX_TX_HW_BLOCK_GEM_SPARE 2
391#define WL12XX_TX_HW_BLOCK_SIZE 252
392
393static const u8 wl12xx_rate_to_idx_2ghz[] = {
394 /* MCS rates are used only with 11n */
395 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI */
396 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7 */
397 6, /* WL12XX_CONF_HW_RXTX_RATE_MCS6 */
398 5, /* WL12XX_CONF_HW_RXTX_RATE_MCS5 */
399 4, /* WL12XX_CONF_HW_RXTX_RATE_MCS4 */
400 3, /* WL12XX_CONF_HW_RXTX_RATE_MCS3 */
401 2, /* WL12XX_CONF_HW_RXTX_RATE_MCS2 */
402 1, /* WL12XX_CONF_HW_RXTX_RATE_MCS1 */
403 0, /* WL12XX_CONF_HW_RXTX_RATE_MCS0 */
404
405 11, /* WL12XX_CONF_HW_RXTX_RATE_54 */
406 10, /* WL12XX_CONF_HW_RXTX_RATE_48 */
407 9, /* WL12XX_CONF_HW_RXTX_RATE_36 */
408 8, /* WL12XX_CONF_HW_RXTX_RATE_24 */
409
410 /* TI-specific rate */
411 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_22 */
412
413 7, /* WL12XX_CONF_HW_RXTX_RATE_18 */
414 6, /* WL12XX_CONF_HW_RXTX_RATE_12 */
415 3, /* WL12XX_CONF_HW_RXTX_RATE_11 */
416 5, /* WL12XX_CONF_HW_RXTX_RATE_9 */
417 4, /* WL12XX_CONF_HW_RXTX_RATE_6 */
418 2, /* WL12XX_CONF_HW_RXTX_RATE_5_5 */
419 1, /* WL12XX_CONF_HW_RXTX_RATE_2 */
420 0 /* WL12XX_CONF_HW_RXTX_RATE_1 */
421};
422
423static const u8 wl12xx_rate_to_idx_5ghz[] = {
424 /* MCS rates are used only with 11n */
425 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI */
426 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7 */
427 6, /* WL12XX_CONF_HW_RXTX_RATE_MCS6 */
428 5, /* WL12XX_CONF_HW_RXTX_RATE_MCS5 */
429 4, /* WL12XX_CONF_HW_RXTX_RATE_MCS4 */
430 3, /* WL12XX_CONF_HW_RXTX_RATE_MCS3 */
431 2, /* WL12XX_CONF_HW_RXTX_RATE_MCS2 */
432 1, /* WL12XX_CONF_HW_RXTX_RATE_MCS1 */
433 0, /* WL12XX_CONF_HW_RXTX_RATE_MCS0 */
434
435 7, /* WL12XX_CONF_HW_RXTX_RATE_54 */
436 6, /* WL12XX_CONF_HW_RXTX_RATE_48 */
437 5, /* WL12XX_CONF_HW_RXTX_RATE_36 */
438 4, /* WL12XX_CONF_HW_RXTX_RATE_24 */
439
440 /* TI-specific rate */
441 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_22 */
442
443 3, /* WL12XX_CONF_HW_RXTX_RATE_18 */
444 2, /* WL12XX_CONF_HW_RXTX_RATE_12 */
445 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_11 */
446 1, /* WL12XX_CONF_HW_RXTX_RATE_9 */
447 0, /* WL12XX_CONF_HW_RXTX_RATE_6 */
448 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_5_5 */
449 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_2 */
450 CONF_HW_RXTX_RATE_UNSUPPORTED /* WL12XX_CONF_HW_RXTX_RATE_1 */
451};
452
453static const u8 *wl12xx_band_rate_to_idx[] = {
454 [IEEE80211_BAND_2GHZ] = wl12xx_rate_to_idx_2ghz,
455 [IEEE80211_BAND_5GHZ] = wl12xx_rate_to_idx_5ghz
456};
457
458enum wl12xx_hw_rates {
459 WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI = 0,
460 WL12XX_CONF_HW_RXTX_RATE_MCS7,
461 WL12XX_CONF_HW_RXTX_RATE_MCS6,
462 WL12XX_CONF_HW_RXTX_RATE_MCS5,
463 WL12XX_CONF_HW_RXTX_RATE_MCS4,
464 WL12XX_CONF_HW_RXTX_RATE_MCS3,
465 WL12XX_CONF_HW_RXTX_RATE_MCS2,
466 WL12XX_CONF_HW_RXTX_RATE_MCS1,
467 WL12XX_CONF_HW_RXTX_RATE_MCS0,
468 WL12XX_CONF_HW_RXTX_RATE_54,
469 WL12XX_CONF_HW_RXTX_RATE_48,
470 WL12XX_CONF_HW_RXTX_RATE_36,
471 WL12XX_CONF_HW_RXTX_RATE_24,
472 WL12XX_CONF_HW_RXTX_RATE_22,
473 WL12XX_CONF_HW_RXTX_RATE_18,
474 WL12XX_CONF_HW_RXTX_RATE_12,
475 WL12XX_CONF_HW_RXTX_RATE_11,
476 WL12XX_CONF_HW_RXTX_RATE_9,
477 WL12XX_CONF_HW_RXTX_RATE_6,
478 WL12XX_CONF_HW_RXTX_RATE_5_5,
479 WL12XX_CONF_HW_RXTX_RATE_2,
480 WL12XX_CONF_HW_RXTX_RATE_1,
481 WL12XX_CONF_HW_RXTX_RATE_MAX,
482};
483
484static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
485 [PART_DOWN] = {
486 .mem = {
487 .start = 0x00000000,
488 .size = 0x000177c0
489 },
490 .reg = {
491 .start = REGISTERS_BASE,
492 .size = 0x00008800
493 },
494 .mem2 = {
495 .start = 0x00000000,
496 .size = 0x00000000
497 },
498 .mem3 = {
499 .start = 0x00000000,
500 .size = 0x00000000
501 },
502 },
503
504 [PART_BOOT] = { /* in wl12xx we can use a mix of work and down
505 * partition here */
506 .mem = {
507 .start = 0x00040000,
508 .size = 0x00014fc0
509 },
510 .reg = {
511 .start = REGISTERS_BASE,
512 .size = 0x00008800
513 },
514 .mem2 = {
515 .start = 0x00000000,
516 .size = 0x00000000
517 },
518 .mem3 = {
519 .start = 0x00000000,
520 .size = 0x00000000
521 },
522 },
523
524 [PART_WORK] = {
525 .mem = {
526 .start = 0x00040000,
527 .size = 0x00014fc0
528 },
529 .reg = {
530 .start = REGISTERS_BASE,
531 .size = 0x0000a000
532 },
533 .mem2 = {
534 .start = 0x003004f8,
535 .size = 0x00000004
536 },
537 .mem3 = {
538 .start = 0x00040404,
539 .size = 0x00000000
540 },
541 },
542
543 [PART_DRPW] = {
544 .mem = {
545 .start = 0x00040000,
546 .size = 0x00014fc0
547 },
548 .reg = {
549 .start = DRPW_BASE,
550 .size = 0x00006000
551 },
552 .mem2 = {
553 .start = 0x00000000,
554 .size = 0x00000000
555 },
556 .mem3 = {
557 .start = 0x00000000,
558 .size = 0x00000000
559 }
560 }
561};
562
563static const int wl12xx_rtable[REG_TABLE_LEN] = {
564 [REG_ECPU_CONTROL] = WL12XX_REG_ECPU_CONTROL,
565 [REG_INTERRUPT_NO_CLEAR] = WL12XX_REG_INTERRUPT_NO_CLEAR,
566 [REG_INTERRUPT_ACK] = WL12XX_REG_INTERRUPT_ACK,
567 [REG_COMMAND_MAILBOX_PTR] = WL12XX_REG_COMMAND_MAILBOX_PTR,
568 [REG_EVENT_MAILBOX_PTR] = WL12XX_REG_EVENT_MAILBOX_PTR,
569 [REG_INTERRUPT_TRIG] = WL12XX_REG_INTERRUPT_TRIG,
570 [REG_INTERRUPT_MASK] = WL12XX_REG_INTERRUPT_MASK,
571 [REG_PC_ON_RECOVERY] = WL12XX_SCR_PAD4,
572 [REG_CHIP_ID_B] = WL12XX_CHIP_ID_B,
573 [REG_CMD_MBOX_ADDRESS] = WL12XX_CMD_MBOX_ADDRESS,
574
575 /* data access memory addresses, used with partition translation */
576 [REG_SLV_MEM_DATA] = WL1271_SLV_MEM_DATA,
577 [REG_SLV_REG_DATA] = WL1271_SLV_REG_DATA,
578
579 /* raw data access memory addresses */
580 [REG_RAW_FW_STATUS_ADDR] = FW_STATUS_ADDR,
581};
582
583/* TODO: maybe move to a new header file? */
584#define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-4-mr.bin"
585#define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-4-sr.bin"
586#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
587
588#define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-4-mr.bin"
589#define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
590#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
591
592static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
593{
594 if (wl->chip.id != CHIP_ID_1283_PG20) {
595 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
596 struct wl1271_rx_mem_pool_addr rx_mem_addr;
597
598 /*
599 * Choose the block we want to read
600 * For aggregated packets, only the first memory block
601 * should be retrieved. The FW takes care of the rest.
602 */
603 u32 mem_block = rx_desc & RX_MEM_BLOCK_MASK;
604
605 rx_mem_addr.addr = (mem_block << 8) +
606 le32_to_cpu(wl_mem_map->packet_memory_pool_start);
607
608 rx_mem_addr.addr_extra = rx_mem_addr.addr + 4;
609
610 wl1271_write(wl, WL1271_SLV_REG_DATA,
611 &rx_mem_addr, sizeof(rx_mem_addr), false);
612 }
613}
614
615static int wl12xx_identify_chip(struct wl1271 *wl)
616{
617 int ret = 0;
618
619 switch (wl->chip.id) {
620 case CHIP_ID_1271_PG10:
621 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
622 wl->chip.id);
623
624 /* clear the alignment quirk, since we don't support it */
625 wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN;
626
627 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS;
628 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
629 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
630 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
631 sizeof(wl->conf.mem));
632
633 /* read data preparation is only needed by wl127x */
634 wl->ops->prepare_read = wl127x_prepare_read;
635
636 break;
637
638 case CHIP_ID_1271_PG20:
639 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
640 wl->chip.id);
641
642 /* clear the alignment quirk, since we don't support it */
643 wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN;
644
645 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS;
646 wl->plt_fw_name = WL127X_PLT_FW_NAME;
647 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
648 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
649 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
650 sizeof(wl->conf.mem));
651
652 /* read data preparation is only needed by wl127x */
653 wl->ops->prepare_read = wl127x_prepare_read;
654
655 break;
656
657 case CHIP_ID_1283_PG20:
658 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
659 wl->chip.id);
660 wl->plt_fw_name = WL128X_PLT_FW_NAME;
661 wl->sr_fw_name = WL128X_FW_NAME_SINGLE;
662 wl->mr_fw_name = WL128X_FW_NAME_MULTI;
663 break;
664 case CHIP_ID_1283_PG10:
665 default:
666 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
667 ret = -ENODEV;
668 goto out;
669 }
670
671out:
672 return ret;
673}
674
675static void wl12xx_top_reg_write(struct wl1271 *wl, int addr, u16 val)
676{
677 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
678 addr = (addr >> 1) + 0x30000;
679 wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr);
680
681 /* write value to OCP_POR_WDATA */
682 wl1271_write32(wl, WL12XX_OCP_DATA_WRITE, val);
683
684 /* write 1 to OCP_CMD */
685 wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE);
686}
687
688static u16 wl12xx_top_reg_read(struct wl1271 *wl, int addr)
689{
690 u32 val;
691 int timeout = OCP_CMD_LOOP;
692
693 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
694 addr = (addr >> 1) + 0x30000;
695 wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr);
696
697 /* write 2 to OCP_CMD */
698 wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ);
699
700 /* poll for data ready */
701 do {
702 val = wl1271_read32(wl, WL12XX_OCP_DATA_READ);
703 } while (!(val & OCP_READY_MASK) && --timeout);
704
705 if (!timeout) {
706 wl1271_warning("Top register access timed out.");
707 return 0xffff;
708 }
709
710 /* check data status and return if OK */
711 if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
712 return val & 0xffff;
713 else {
714 wl1271_warning("Top register access returned error.");
715 return 0xffff;
716 }
717}
718
719static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
720{
721 u16 spare_reg;
722
723 /* Mask bits [2] & [8:4] in the sys_clk_cfg register */
724 spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG);
725 if (spare_reg == 0xFFFF)
726 return -EFAULT;
727 spare_reg |= (BIT(3) | BIT(5) | BIT(6));
728 wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
729
730 /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
731 wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG,
732 WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
733
734 /* Delay execution for 15msec, to let the HW settle */
735 mdelay(15);
736
737 return 0;
738}
739
740static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
741{
742 u16 tcxo_detection;
743
744 tcxo_detection = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG);
745 if (tcxo_detection & TCXO_DET_FAILED)
746 return false;
747
748 return true;
749}
750
751static bool wl128x_is_fref_valid(struct wl1271 *wl)
752{
753 u16 fref_detection;
754
755 fref_detection = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG);
756 if (fref_detection & FREF_CLK_DETECT_FAIL)
757 return false;
758
759 return true;
760}
761
762static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
763{
764 wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
765 wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
766 wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL);
767
768 return 0;
769}
770
771static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
772{
773 u16 spare_reg;
774 u16 pll_config;
775 u8 input_freq;
776
777 /* Mask bits [3:1] in the sys_clk_cfg register */
778 spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG);
779 if (spare_reg == 0xFFFF)
780 return -EFAULT;
781 spare_reg |= BIT(2);
782 wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
783
784 /* Handle special cases of the TCXO clock */
785 if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
786 wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
787 return wl128x_manually_configure_mcs_pll(wl);
788
789 /* Set the input frequency according to the selected clock source */
790 input_freq = (clk & 1) + 1;
791
792 pll_config = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG);
793 if (pll_config == 0xFFFF)
794 return -EFAULT;
795 pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
796 pll_config |= MCS_PLL_ENABLE_HP;
797 wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
798
799 return 0;
800}
801
802/*
803 * WL128x has two clocks input - TCXO and FREF.
804 * TCXO is the main clock of the device, while FREF is used to sync
805 * between the GPS and the cellular modem.
806 * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
807 * as the WLAN/BT main clock.
808 */
809static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
810{
811 u16 sys_clk_cfg;
812
813 /* For XTAL-only modes, FREF will be used after switching from TCXO */
814 if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
815 wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
816 if (!wl128x_switch_tcxo_to_fref(wl))
817 return -EINVAL;
818 goto fref_clk;
819 }
820
821 /* Query the HW, to determine which clock source we should use */
822 sys_clk_cfg = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG);
823 if (sys_clk_cfg == 0xFFFF)
824 return -EINVAL;
825 if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
826 goto fref_clk;
827
828 /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
829 if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
830 wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
831 if (!wl128x_switch_tcxo_to_fref(wl))
832 return -EINVAL;
833 goto fref_clk;
834 }
835
836 /* TCXO clock is selected */
837 if (!wl128x_is_tcxo_valid(wl))
838 return -EINVAL;
839 *selected_clock = wl->tcxo_clock;
840 goto config_mcs_pll;
841
842fref_clk:
843 /* FREF clock is selected */
844 if (!wl128x_is_fref_valid(wl))
845 return -EINVAL;
846 *selected_clock = wl->ref_clock;
847
848config_mcs_pll:
849 return wl128x_configure_mcs_pll(wl, *selected_clock);
850}
851
852static int wl127x_boot_clk(struct wl1271 *wl)
853{
854 u32 pause;
855 u32 clk;
856
857 if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
858 wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
859
860 if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
861 wl->ref_clock == CONF_REF_CLK_38_4_E ||
862 wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
863 /* ref clk: 19.2/38.4/38.4-XTAL */
864 clk = 0x3;
865 else if (wl->ref_clock == CONF_REF_CLK_26_E ||
866 wl->ref_clock == CONF_REF_CLK_52_E)
867 /* ref clk: 26/52 */
868 clk = 0x5;
869 else
870 return -EINVAL;
871
872 if (wl->ref_clock != CONF_REF_CLK_19_2_E) {
873 u16 val;
874 /* Set clock type (open drain) */
875 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE);
876 val &= FREF_CLK_TYPE_BITS;
877 wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
878
879 /* Set clock pull mode (no pull) */
880 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL);
881 val |= NO_PULL;
882 wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val);
883 } else {
884 u16 val;
885 /* Set clock polarity */
886 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY);
887 val &= FREF_CLK_POLARITY_BITS;
888 val |= CLK_REQ_OUTN_SEL;
889 wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
890 }
891
892 wl1271_write32(wl, WL12XX_PLL_PARAMETERS, clk);
893
894 pause = wl1271_read32(wl, WL12XX_PLL_PARAMETERS);
895
896 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
897
898 pause &= ~(WU_COUNTER_PAUSE_VAL);
899 pause |= WU_COUNTER_PAUSE_VAL;
900 wl1271_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause);
901
902 return 0;
903}
904
905static int wl1271_boot_soft_reset(struct wl1271 *wl)
906{
907 unsigned long timeout;
908 u32 boot_data;
909
910 /* perform soft reset */
911 wl1271_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
912
913 /* SOFT_RESET is self clearing */
914 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
915 while (1) {
916 boot_data = wl1271_read32(wl, WL12XX_SLV_SOFT_RESET);
917 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
918 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
919 break;
920
921 if (time_after(jiffies, timeout)) {
922 /* 1.2 check pWhalBus->uSelfClearTime if the
923 * timeout was reached */
924 wl1271_error("soft reset timeout");
925 return -1;
926 }
927
928 udelay(SOFT_RESET_STALL_TIME);
929 }
930
931 /* disable Rx/Tx */
932 wl1271_write32(wl, WL12XX_ENABLE, 0x0);
933
934 /* disable auto calibration on start*/
935 wl1271_write32(wl, WL12XX_SPARE_A2, 0xffff);
936
937 return 0;
938}
939
940static int wl12xx_pre_boot(struct wl1271 *wl)
941{
942 int ret = 0;
943 u32 clk;
944 int selected_clock = -1;
945
946 if (wl->chip.id == CHIP_ID_1283_PG20) {
947 ret = wl128x_boot_clk(wl, &selected_clock);
948 if (ret < 0)
949 goto out;
950 } else {
951 ret = wl127x_boot_clk(wl);
952 if (ret < 0)
953 goto out;
954 }
955
956 /* Continue the ELP wake up sequence */
957 wl1271_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
958 udelay(500);
959
960 wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
961
962 /* Read-modify-write DRPW_SCRATCH_START register (see next state)
963 to be used by DRPw FW. The RTRIM value will be added by the FW
964 before taking DRPw out of reset */
965
966 clk = wl1271_read32(wl, WL12XX_DRPW_SCRATCH_START);
967
968 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
969
970 if (wl->chip.id == CHIP_ID_1283_PG20)
971 clk |= ((selected_clock & 0x3) << 1) << 4;
972 else
973 clk |= (wl->ref_clock << 1) << 4;
974
975 wl1271_write32(wl, WL12XX_DRPW_SCRATCH_START, clk);
976
977 wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
978
979 /* Disable interrupts */
980 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
981
982 ret = wl1271_boot_soft_reset(wl);
983 if (ret < 0)
984 goto out;
985
986out:
987 return ret;
988}
989
990static void wl12xx_pre_upload(struct wl1271 *wl)
991{
992 u32 tmp;
993
994 /* write firmware's last address (ie. it's length) to
995 * ACX_EEPROMLESS_IND_REG */
996 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
997
998 wl1271_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND);
999
1000 tmp = wlcore_read_reg(wl, REG_CHIP_ID_B);
1001
1002 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
1003
1004 /* 6. read the EEPROM parameters */
1005 tmp = wl1271_read32(wl, WL12XX_SCR_PAD2);
1006
1007 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
1008 * to upload_fw) */
1009
1010 if (wl->chip.id == CHIP_ID_1283_PG20)
1011 wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
1012}
1013
1014static void wl12xx_enable_interrupts(struct wl1271 *wl)
1015{
1016 u32 polarity;
1017
1018 polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY);
1019
1020 /* We use HIGH polarity, so unset the LOW bit */
1021 polarity &= ~POLARITY_LOW;
1022 wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);
1023
1024 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR);
1025
1026 wlcore_enable_interrupts(wl);
1027 wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1028 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
1029
1030 wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
1031}
1032
1033static int wl12xx_boot(struct wl1271 *wl)
1034{
1035 int ret;
1036
1037 ret = wl12xx_pre_boot(wl);
1038 if (ret < 0)
1039 goto out;
1040
1041 ret = wlcore_boot_upload_nvs(wl);
1042 if (ret < 0)
1043 goto out;
1044
1045 wl12xx_pre_upload(wl);
1046
1047 ret = wlcore_boot_upload_firmware(wl);
1048 if (ret < 0)
1049 goto out;
1050
1051 ret = wlcore_boot_run_firmware(wl);
1052 if (ret < 0)
1053 goto out;
1054
1055 wl12xx_enable_interrupts(wl);
1056
1057out:
1058 return ret;
1059}
1060
1061static void wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
1062 void *buf, size_t len)
1063{
1064 wl1271_write(wl, cmd_box_addr, buf, len, false);
1065 wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD);
1066}
1067
1068static void wl12xx_ack_event(struct wl1271 *wl)
1069{
1070 wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_EVENT_ACK);
1071}
1072
1073static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
1074{
1075 u32 blk_size = WL12XX_TX_HW_BLOCK_SIZE;
1076 u32 align_len = wlcore_calc_packet_alignment(wl, len);
1077
1078 return (align_len + blk_size - 1) / blk_size + spare_blks;
1079}
1080
1081static void
1082wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1083 u32 blks, u32 spare_blks)
1084{
1085 if (wl->chip.id == CHIP_ID_1283_PG20) {
1086 desc->wl128x_mem.total_mem_blocks = blks;
1087 } else {
1088 desc->wl127x_mem.extra_blocks = spare_blks;
1089 desc->wl127x_mem.total_mem_blocks = blks;
1090 }
1091}
1092
1093static void
1094wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1095 struct sk_buff *skb)
1096{
1097 u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len);
1098
1099 if (wl->chip.id == CHIP_ID_1283_PG20) {
1100 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
1101 desc->length = cpu_to_le16(aligned_len >> 2);
1102
1103 wl1271_debug(DEBUG_TX,
1104 "tx_fill_hdr: hlid: %d len: %d life: %d mem: %d extra: %d",
1105 desc->hlid,
1106 le16_to_cpu(desc->length),
1107 le16_to_cpu(desc->life_time),
1108 desc->wl128x_mem.total_mem_blocks,
1109 desc->wl128x_mem.extra_bytes);
1110 } else {
1111 /* calculate number of padding bytes */
1112 int pad = aligned_len - skb->len;
1113 desc->tx_attr |=
1114 cpu_to_le16(pad << TX_HW_ATTR_OFST_LAST_WORD_PAD);
1115
1116 /* Store the aligned length in terms of words */
1117 desc->length = cpu_to_le16(aligned_len >> 2);
1118
1119 wl1271_debug(DEBUG_TX,
1120 "tx_fill_hdr: pad: %d hlid: %d len: %d life: %d mem: %d",
1121 pad, desc->hlid,
1122 le16_to_cpu(desc->length),
1123 le16_to_cpu(desc->life_time),
1124 desc->wl127x_mem.total_mem_blocks);
1125 }
1126}
1127
1128static enum wl_rx_buf_align
1129wl12xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
1130{
1131 if (rx_desc & RX_BUF_UNALIGNED_PAYLOAD)
1132 return WLCORE_RX_BUF_UNALIGNED;
1133
1134 return WLCORE_RX_BUF_ALIGNED;
1135}
1136
1137static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1138 u32 data_len)
1139{
1140 struct wl1271_rx_descriptor *desc = rx_data;
1141
1142 /* invalid packet */
1143 if (data_len < sizeof(*desc) ||
1144 data_len < sizeof(*desc) + desc->pad_len)
1145 return 0;
1146
1147 return data_len - sizeof(*desc) - desc->pad_len;
1148}
1149
1150static void wl12xx_tx_delayed_compl(struct wl1271 *wl)
1151{
1152 if (wl->fw_status->tx_results_counter == (wl->tx_results_count & 0xff))
1153 return;
1154
1155 wl1271_tx_complete(wl);
1156}
1157
1158static int wl12xx_hw_init(struct wl1271 *wl)
1159{
1160 int ret;
1161
1162 if (wl->chip.id == CHIP_ID_1283_PG20) {
1163 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
1164
1165 ret = wl128x_cmd_general_parms(wl);
1166 if (ret < 0)
1167 goto out;
1168 ret = wl128x_cmd_radio_parms(wl);
1169 if (ret < 0)
1170 goto out;
1171
1172 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
1173 /* Enable SDIO padding */
1174 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1175
1176 /* Must be before wl1271_acx_init_mem_config() */
1177 ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
1178 if (ret < 0)
1179 goto out;
1180 } else {
1181 ret = wl1271_cmd_general_parms(wl);
1182 if (ret < 0)
1183 goto out;
1184 ret = wl1271_cmd_radio_parms(wl);
1185 if (ret < 0)
1186 goto out;
1187 ret = wl1271_cmd_ext_radio_parms(wl);
1188 if (ret < 0)
1189 goto out;
1190 }
1191out:
1192 return ret;
1193}
1194
1195static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1196 struct wl12xx_vif *wlvif)
1197{
1198 return wlvif->rate_set;
1199}
1200
1201static int wl12xx_identify_fw(struct wl1271 *wl)
1202{
1203 unsigned int *fw_ver = wl->chip.fw_ver;
1204
1205 /* Only new station firmwares support routing fw logs to the host */
1206 if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
1207 (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN))
1208 wl->quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
1209
1210 /* This feature is not yet supported for AP mode */
1211 if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP)
1212 wl->quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
1213
1214 return 0;
1215}
1216
1217static void wl12xx_conf_init(struct wl1271 *wl)
1218{
1219 struct wl12xx_priv *priv = wl->priv;
1220
1221 /* apply driver default configuration */
1222 memcpy(&wl->conf, &wl12xx_conf, sizeof(wl12xx_conf));
1223
1224 /* apply default private configuration */
1225 memcpy(&priv->conf, &wl12xx_default_priv_conf, sizeof(priv->conf));
1226}
1227
1228static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
1229{
1230 bool supported = false;
1231 u8 major, minor;
1232
1233 if (wl->chip.id == CHIP_ID_1283_PG20) {
1234 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
1235 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
1236
1237 /* in wl128x we have the MAC address if the PG is >= (2, 1) */
1238 if (major > 2 || (major == 2 && minor >= 1))
1239 supported = true;
1240 } else {
1241 major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
1242 minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
1243
1244 /* in wl127x we have the MAC address if the PG is >= (3, 1) */
1245 if (major == 3 && minor >= 1)
1246 supported = true;
1247 }
1248
1249 wl1271_debug(DEBUG_PROBE,
1250 "PG Ver major = %d minor = %d, MAC %s present",
1251 major, minor, supported ? "is" : "is not");
1252
1253 return supported;
1254}
1255
1256static void wl12xx_get_fuse_mac(struct wl1271 *wl)
1257{
1258 u32 mac1, mac2;
1259
1260 wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1261
1262 mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1);
1263 mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2);
1264
1265 /* these are the two parts of the BD_ADDR */
1266 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1267 ((mac1 & 0xff000000) >> 24);
1268 wl->fuse_nic_addr = mac1 & 0xffffff;
1269
1270 wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1271}
1272
1273static s8 wl12xx_get_pg_ver(struct wl1271 *wl)
1274{
1275 u32 die_info;
1276
1277 if (wl->chip.id == CHIP_ID_1283_PG20)
1278 die_info = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1);
1279 else
1280 die_info = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);
1281
1282 return (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET;
1283}
1284
1285static void wl12xx_get_mac(struct wl1271 *wl)
1286{
1287 if (wl12xx_mac_in_fuse(wl))
1288 wl12xx_get_fuse_mac(wl);
1289}
1290
1291static struct wlcore_ops wl12xx_ops = {
1292 .identify_chip = wl12xx_identify_chip,
1293 .identify_fw = wl12xx_identify_fw,
1294 .boot = wl12xx_boot,
1295 .trigger_cmd = wl12xx_trigger_cmd,
1296 .ack_event = wl12xx_ack_event,
1297 .calc_tx_blocks = wl12xx_calc_tx_blocks,
1298 .set_tx_desc_blocks = wl12xx_set_tx_desc_blocks,
1299 .set_tx_desc_data_len = wl12xx_set_tx_desc_data_len,
1300 .get_rx_buf_align = wl12xx_get_rx_buf_align,
1301 .get_rx_packet_len = wl12xx_get_rx_packet_len,
1302 .tx_immediate_compl = NULL,
1303 .tx_delayed_compl = wl12xx_tx_delayed_compl,
1304 .hw_init = wl12xx_hw_init,
1305 .init_vif = NULL,
1306 .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask,
1307 .get_pg_ver = wl12xx_get_pg_ver,
1308 .get_mac = wl12xx_get_mac,
1309};
1310
1311static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
1312 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
1313 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT),
1314 .ht_supported = true,
1315 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
1316 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8,
1317 .mcs = {
1318 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1319 .rx_highest = cpu_to_le16(72),
1320 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1321 },
1322};
1323
1324static int __devinit wl12xx_probe(struct platform_device *pdev)
1325{
1326 struct wl1271 *wl;
1327 struct ieee80211_hw *hw;
1328 struct wl12xx_priv *priv;
1329
1330 hw = wlcore_alloc_hw(sizeof(*priv));
1331 if (IS_ERR(hw)) {
1332 wl1271_error("can't allocate hw");
1333 return PTR_ERR(hw);
1334 }
1335
1336 wl = hw->priv;
1337 wl->ops = &wl12xx_ops;
1338 wl->ptable = wl12xx_ptable;
1339 wl->rtable = wl12xx_rtable;
1340 wl->num_tx_desc = 16;
1341 wl->normal_tx_spare = WL12XX_TX_HW_BLOCK_SPARE_DEFAULT;
1342 wl->gem_tx_spare = WL12XX_TX_HW_BLOCK_GEM_SPARE;
1343 wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1344 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
1345 wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
1346 wl->fw_status_priv_len = 0;
1347 memcpy(&wl->ht_cap, &wl12xx_ht_cap, sizeof(wl12xx_ht_cap));
1348 wl12xx_conf_init(wl);
1349
1350 return wlcore_probe(wl, pdev);
1351}
1352
1353static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
1354 { "wl12xx", 0 },
1355 { } /* Terminating Entry */
1356};
1357MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
1358
1359static struct platform_driver wl12xx_driver = {
1360 .probe = wl12xx_probe,
1361 .remove = __devexit_p(wlcore_remove),
1362 .id_table = wl12xx_id_table,
1363 .driver = {
1364 .name = "wl12xx_driver",
1365 .owner = THIS_MODULE,
1366 }
1367};
1368
1369static int __init wl12xx_init(void)
1370{
1371 return platform_driver_register(&wl12xx_driver);
1372}
1373module_init(wl12xx_init);
1374
1375static void __exit wl12xx_exit(void)
1376{
1377 platform_driver_unregister(&wl12xx_driver);
1378}
1379module_exit(wl12xx_exit);
1380
1381MODULE_LICENSE("GPL v2");
1382MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
1383MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
1384MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
1385MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
1386MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
1387MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
1388MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/ti/wl12xx/reg.h
index 340db324bc26..79ede02e2587 100644
--- a/drivers/net/wireless/wl12xx/reg.h
+++ b/drivers/net/wireless/ti/wl12xx/reg.h
@@ -33,16 +33,8 @@
33#define REGISTERS_DOWN_SIZE 0x00008800 33#define REGISTERS_DOWN_SIZE 0x00008800
34#define REGISTERS_WORK_SIZE 0x0000b000 34#define REGISTERS_WORK_SIZE 0x0000b000
35 35
36#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC
37#define FW_STATUS_ADDR (0x14FC0 + 0xA000) 36#define FW_STATUS_ADDR (0x14FC0 + 0xA000)
38 37
39/* ELP register commands */
40#define ELPCTRL_WAKE_UP 0x1
41#define ELPCTRL_WAKE_UP_WLAN_READY 0x5
42#define ELPCTRL_SLEEP 0x0
43/* ELP WLAN_READY bit */
44#define ELPCTRL_WLAN_READY 0x2
45
46/*=============================================== 38/*===============================================
47 Host Software Reset - 32bit RW 39 Host Software Reset - 32bit RW
48 ------------------------------------------ 40 ------------------------------------------
@@ -57,14 +49,14 @@
57 (not self-clearing), the Wlan hardware 49 (not self-clearing), the Wlan hardware
58 exits the software reset state. 50 exits the software reset state.
59===============================================*/ 51===============================================*/
60#define ACX_REG_SLV_SOFT_RESET (REGISTERS_BASE + 0x0000) 52#define WL12XX_SLV_SOFT_RESET (REGISTERS_BASE + 0x0000)
61 53
62#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008) 54#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008)
63#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c) 55#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c)
64#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018) 56#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018)
65 57
66#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474) 58#define WL12XX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474)
67#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478) 59#define WL12XX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478)
68 60
69/*============================================= 61/*=============================================
70 Host Interrupt Mask Register - 32bit (RW) 62 Host Interrupt Mask Register - 32bit (RW)
@@ -94,7 +86,7 @@
94 21- - 86 21- -
95 Default: 0x0001 87 Default: 0x0001
96*==============================================*/ 88*==============================================*/
97#define ACX_REG_INTERRUPT_MASK (REGISTERS_BASE + 0x04DC) 89#define WL12XX_REG_INTERRUPT_MASK (REGISTERS_BASE + 0x04DC)
98 90
99/*============================================= 91/*=============================================
100 Host Interrupt Mask Set 16bit, (Write only) 92 Host Interrupt Mask Set 16bit, (Write only)
@@ -125,7 +117,7 @@
125 Reading this register doesn't 117 Reading this register doesn't
126 effect its content. 118 effect its content.
127=============================================*/ 119=============================================*/
128#define ACX_REG_INTERRUPT_NO_CLEAR (REGISTERS_BASE + 0x04E8) 120#define WL12XX_REG_INTERRUPT_NO_CLEAR (REGISTERS_BASE + 0x04E8)
129 121
130/*============================================= 122/*=============================================
131 Host Interrupt Status Clear on Read Register 123 Host Interrupt Status Clear on Read Register
@@ -148,9 +140,9 @@
148 HINT_STS_ND registers, thus making the 140 HINT_STS_ND registers, thus making the
149 assotiated interrupt inactive. (0-no effect) 141 assotiated interrupt inactive. (0-no effect)
150==============================================*/ 142==============================================*/
151#define ACX_REG_INTERRUPT_ACK (REGISTERS_BASE + 0x04F0) 143#define WL12XX_REG_INTERRUPT_ACK (REGISTERS_BASE + 0x04F0)
152 144
153#define RX_DRIVER_COUNTER_ADDRESS (REGISTERS_BASE + 0x0538) 145#define WL12XX_REG_RX_DRIVER_COUNTER (REGISTERS_BASE + 0x0538)
154 146
155/* Device Configuration registers*/ 147/* Device Configuration registers*/
156#define SOR_CFG (REGISTERS_BASE + 0x0800) 148#define SOR_CFG (REGISTERS_BASE + 0x0800)
@@ -175,9 +167,9 @@
175 1 halt eCPU 167 1 halt eCPU
176 0 enable eCPU 168 0 enable eCPU
177 ===============================================*/ 169 ===============================================*/
178#define ACX_REG_ECPU_CONTROL (REGISTERS_BASE + 0x0804) 170#define WL12XX_REG_ECPU_CONTROL (REGISTERS_BASE + 0x0804)
179 171
180#define HI_CFG (REGISTERS_BASE + 0x0808) 172#define WL12XX_HI_CFG (REGISTERS_BASE + 0x0808)
181 173
182/*=============================================== 174/*===============================================
183 EEPROM Burst Read Start - 32bit RW 175 EEPROM Burst Read Start - 32bit RW
@@ -196,72 +188,67 @@
196*================================================*/ 188*================================================*/
197#define ACX_REG_EE_START (REGISTERS_BASE + 0x080C) 189#define ACX_REG_EE_START (REGISTERS_BASE + 0x080C)
198 190
199#define OCP_POR_CTR (REGISTERS_BASE + 0x09B4) 191#define WL12XX_OCP_POR_CTR (REGISTERS_BASE + 0x09B4)
200#define OCP_DATA_WRITE (REGISTERS_BASE + 0x09B8) 192#define WL12XX_OCP_DATA_WRITE (REGISTERS_BASE + 0x09B8)
201#define OCP_DATA_READ (REGISTERS_BASE + 0x09BC) 193#define WL12XX_OCP_DATA_READ (REGISTERS_BASE + 0x09BC)
202#define OCP_CMD (REGISTERS_BASE + 0x09C0) 194#define WL12XX_OCP_CMD (REGISTERS_BASE + 0x09C0)
203
204#define WL1271_HOST_WR_ACCESS (REGISTERS_BASE + 0x09F8)
205 195
206#define CHIP_ID_B (REGISTERS_BASE + 0x5674) 196#define WL12XX_HOST_WR_ACCESS (REGISTERS_BASE + 0x09F8)
207 197
208#define CHIP_ID_1271_PG10 (0x4030101) 198#define WL12XX_CHIP_ID_B (REGISTERS_BASE + 0x5674)
209#define CHIP_ID_1271_PG20 (0x4030111)
210#define CHIP_ID_1283_PG10 (0x05030101)
211#define CHIP_ID_1283_PG20 (0x05030111)
212 199
213#define ENABLE (REGISTERS_BASE + 0x5450) 200#define WL12XX_ENABLE (REGISTERS_BASE + 0x5450)
214 201
215/* Power Management registers */ 202/* Power Management registers */
216#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804) 203#define WL12XX_ELP_CFG_MODE (REGISTERS_BASE + 0x5804)
217#define ELP_CMD (REGISTERS_BASE + 0x5808) 204#define WL12XX_ELP_CMD (REGISTERS_BASE + 0x5808)
218#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810) 205#define WL12XX_PLL_CAL_TIME (REGISTERS_BASE + 0x5810)
219#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814) 206#define WL12XX_CLK_REQ_TIME (REGISTERS_BASE + 0x5814)
220#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818) 207#define WL12XX_CLK_BUF_TIME (REGISTERS_BASE + 0x5818)
221 208
222#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820) 209#define WL12XX_CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820)
223 210
224/* Scratch Pad registers*/ 211/* Scratch Pad registers*/
225#define SCR_PAD0 (REGISTERS_BASE + 0x5608) 212#define WL12XX_SCR_PAD0 (REGISTERS_BASE + 0x5608)
226#define SCR_PAD1 (REGISTERS_BASE + 0x560C) 213#define WL12XX_SCR_PAD1 (REGISTERS_BASE + 0x560C)
227#define SCR_PAD2 (REGISTERS_BASE + 0x5610) 214#define WL12XX_SCR_PAD2 (REGISTERS_BASE + 0x5610)
228#define SCR_PAD3 (REGISTERS_BASE + 0x5614) 215#define WL12XX_SCR_PAD3 (REGISTERS_BASE + 0x5614)
229#define SCR_PAD4 (REGISTERS_BASE + 0x5618) 216#define WL12XX_SCR_PAD4 (REGISTERS_BASE + 0x5618)
230#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C) 217#define WL12XX_SCR_PAD4_SET (REGISTERS_BASE + 0x561C)
231#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620) 218#define WL12XX_SCR_PAD4_CLR (REGISTERS_BASE + 0x5620)
232#define SCR_PAD5 (REGISTERS_BASE + 0x5624) 219#define WL12XX_SCR_PAD5 (REGISTERS_BASE + 0x5624)
233#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628) 220#define WL12XX_SCR_PAD5_SET (REGISTERS_BASE + 0x5628)
234#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C) 221#define WL12XX_SCR_PAD5_CLR (REGISTERS_BASE + 0x562C)
235#define SCR_PAD6 (REGISTERS_BASE + 0x5630) 222#define WL12XX_SCR_PAD6 (REGISTERS_BASE + 0x5630)
236#define SCR_PAD7 (REGISTERS_BASE + 0x5634) 223#define WL12XX_SCR_PAD7 (REGISTERS_BASE + 0x5634)
237#define SCR_PAD8 (REGISTERS_BASE + 0x5638) 224#define WL12XX_SCR_PAD8 (REGISTERS_BASE + 0x5638)
238#define SCR_PAD9 (REGISTERS_BASE + 0x563C) 225#define WL12XX_SCR_PAD9 (REGISTERS_BASE + 0x563C)
239 226
240/* Spare registers*/ 227/* Spare registers*/
241#define SPARE_A1 (REGISTERS_BASE + 0x0994) 228#define WL12XX_SPARE_A1 (REGISTERS_BASE + 0x0994)
242#define SPARE_A2 (REGISTERS_BASE + 0x0998) 229#define WL12XX_SPARE_A2 (REGISTERS_BASE + 0x0998)
243#define SPARE_A3 (REGISTERS_BASE + 0x099C) 230#define WL12XX_SPARE_A3 (REGISTERS_BASE + 0x099C)
244#define SPARE_A4 (REGISTERS_BASE + 0x09A0) 231#define WL12XX_SPARE_A4 (REGISTERS_BASE + 0x09A0)
245#define SPARE_A5 (REGISTERS_BASE + 0x09A4) 232#define WL12XX_SPARE_A5 (REGISTERS_BASE + 0x09A4)
246#define SPARE_A6 (REGISTERS_BASE + 0x09A8) 233#define WL12XX_SPARE_A6 (REGISTERS_BASE + 0x09A8)
247#define SPARE_A7 (REGISTERS_BASE + 0x09AC) 234#define WL12XX_SPARE_A7 (REGISTERS_BASE + 0x09AC)
248#define SPARE_A8 (REGISTERS_BASE + 0x09B0) 235#define WL12XX_SPARE_A8 (REGISTERS_BASE + 0x09B0)
249#define SPARE_B1 (REGISTERS_BASE + 0x5420) 236#define WL12XX_SPARE_B1 (REGISTERS_BASE + 0x5420)
250#define SPARE_B2 (REGISTERS_BASE + 0x5424) 237#define WL12XX_SPARE_B2 (REGISTERS_BASE + 0x5424)
251#define SPARE_B3 (REGISTERS_BASE + 0x5428) 238#define WL12XX_SPARE_B3 (REGISTERS_BASE + 0x5428)
252#define SPARE_B4 (REGISTERS_BASE + 0x542C) 239#define WL12XX_SPARE_B4 (REGISTERS_BASE + 0x542C)
253#define SPARE_B5 (REGISTERS_BASE + 0x5430) 240#define WL12XX_SPARE_B5 (REGISTERS_BASE + 0x5430)
254#define SPARE_B6 (REGISTERS_BASE + 0x5434) 241#define WL12XX_SPARE_B6 (REGISTERS_BASE + 0x5434)
255#define SPARE_B7 (REGISTERS_BASE + 0x5438) 242#define WL12XX_SPARE_B7 (REGISTERS_BASE + 0x5438)
256#define SPARE_B8 (REGISTERS_BASE + 0x543C) 243#define WL12XX_SPARE_B8 (REGISTERS_BASE + 0x543C)
257 244
258#define PLL_PARAMETERS (REGISTERS_BASE + 0x6040) 245#define WL12XX_PLL_PARAMETERS (REGISTERS_BASE + 0x6040)
259#define WU_COUNTER_PAUSE (REGISTERS_BASE + 0x6008) 246#define WL12XX_WU_COUNTER_PAUSE (REGISTERS_BASE + 0x6008)
260#define WELP_ARM_COMMAND (REGISTERS_BASE + 0x6100) 247#define WL12XX_WELP_ARM_COMMAND (REGISTERS_BASE + 0x6100)
261#define DRPW_SCRATCH_START (DRPW_BASE + 0x002C) 248#define WL12XX_DRPW_SCRATCH_START (DRPW_BASE + 0x002C)
262 249
263 250#define WL12XX_CMD_MBOX_ADDRESS 0x407B4
264#define ACX_SLV_SOFT_RESET_BIT BIT(1) 251
265#define ACX_REG_EEPROM_START_BIT BIT(1) 252#define ACX_REG_EEPROM_START_BIT BIT(1)
266 253
267/* Command/Information Mailbox Pointers */ 254/* Command/Information Mailbox Pointers */
@@ -279,7 +266,7 @@
279 the host receives the Init Complete interrupt from 266 the host receives the Init Complete interrupt from
280 the Wlan hardware. 267 the Wlan hardware.
281 ===============================================*/ 268 ===============================================*/
282#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0) 269#define WL12XX_REG_COMMAND_MAILBOX_PTR (WL12XX_SCR_PAD0)
283 270
284/*=============================================== 271/*===============================================
285 Information Mailbox Pointer - 32bit RW 272 Information Mailbox Pointer - 32bit RW
@@ -294,7 +281,7 @@
294 until after the host receives the Init Complete interrupt from 281 until after the host receives the Init Complete interrupt from
295 the Wlan hardware. 282 the Wlan hardware.
296 ===============================================*/ 283 ===============================================*/
297#define REG_EVENT_MAILBOX_PTR (SCR_PAD1) 284#define WL12XX_REG_EVENT_MAILBOX_PTR (WL12XX_SCR_PAD1)
298 285
299/*=============================================== 286/*===============================================
300 EEPROM Read/Write Request 32bit RW 287 EEPROM Read/Write Request 32bit RW
@@ -365,26 +352,6 @@
365#define ACX_CONT_WIND_MIN_MASK 0x0000007f 352#define ACX_CONT_WIND_MIN_MASK 0x0000007f
366#define ACX_CONT_WIND_MAX 0x03ff0000 353#define ACX_CONT_WIND_MAX 0x03ff0000
367 354
368/*===============================================
369 HI_CFG Interface Configuration Register Values
370 ------------------------------------------
371 ===============================================*/
372#define HI_CFG_UART_ENABLE 0x00000004
373#define HI_CFG_RST232_ENABLE 0x00000008
374#define HI_CFG_CLOCK_REQ_SELECT 0x00000010
375#define HI_CFG_HOST_INT_ENABLE 0x00000020
376#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040
377#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080
378#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100
379#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
380#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
381
382#define HI_CFG_DEF_VAL \
383 (HI_CFG_UART_ENABLE | \
384 HI_CFG_RST232_ENABLE | \
385 HI_CFG_CLOCK_REQ_SELECT | \
386 HI_CFG_HOST_INT_ENABLE)
387
388#define REF_FREQ_19_2 0 355#define REF_FREQ_19_2 0
389#define REF_FREQ_26_0 1 356#define REF_FREQ_26_0 1
390#define REF_FREQ_38_4 2 357#define REF_FREQ_38_4 2
@@ -400,38 +367,19 @@
400#define LUT_PARAM_BB_PLL_LOOP_FILTER 5 367#define LUT_PARAM_BB_PLL_LOOP_FILTER 5
401#define LUT_PARAM_NUM 6 368#define LUT_PARAM_NUM 6
402 369
403#define ACX_EEPROMLESS_IND_REG (SCR_PAD4) 370#define WL12XX_EEPROMLESS_IND (WL12XX_SCR_PAD4)
404#define USE_EEPROM 0 371#define USE_EEPROM 0
405#define SOFT_RESET_MAX_TIME 1000000
406#define SOFT_RESET_STALL_TIME 1000
407#define NVS_DATA_BUNDARY_ALIGNMENT 4 372#define NVS_DATA_BUNDARY_ALIGNMENT 4
408 373
409
410/* Firmware image load chunk size */
411#define CHUNK_SIZE 16384
412
413/* Firmware image header size */ 374/* Firmware image header size */
414#define FW_HDR_SIZE 8 375#define FW_HDR_SIZE 8
415 376
416#define ECPU_CONTROL_HALT 0x00000101
417
418
419/****************************************************************************** 377/******************************************************************************
420 378
421 CHANNELS, BAND & REG DOMAINS definitions 379 CHANNELS, BAND & REG DOMAINS definitions
422 380
423******************************************************************************/ 381******************************************************************************/
424 382
425
426enum {
427 RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */
428 RADIO_BAND_5GHZ = 1, /* 5 Ghz band */
429 RADIO_BAND_JAPAN_4_9_GHZ = 2,
430 DEFAULT_BAND = RADIO_BAND_2_4GHZ,
431 INVALID_BAND = 0xFE,
432 MAX_RADIO_BANDS = 0xFF
433};
434
435#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */ 383#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */
436#define OFDM_RATE_BIT BIT(6) 384#define OFDM_RATE_BIT BIT(6)
437#define PBCC_RATE_BIT BIT(7) 385#define PBCC_RATE_BIT BIT(7)
@@ -465,14 +413,82 @@ b12-b0 - Supported Rate indicator bits as defined below.
465 413
466******************************************************************************/ 414******************************************************************************/
467 415
416#define OCP_CMD_LOOP 32
417#define OCP_CMD_WRITE 0x1
418#define OCP_CMD_READ 0x2
419#define OCP_READY_MASK BIT(18)
420#define OCP_STATUS_MASK (BIT(16) | BIT(17))
421#define OCP_STATUS_NO_RESP 0x00000
422#define OCP_STATUS_OK 0x10000
423#define OCP_STATUS_REQ_FAILED 0x20000
424#define OCP_STATUS_RESP_ERROR 0x30000
425
426#define OCP_REG_POLARITY 0x0064
427#define OCP_REG_CLK_TYPE 0x0448
428#define OCP_REG_CLK_POLARITY 0x0cb2
429#define OCP_REG_CLK_PULL 0x0cb4
430
431#define POLARITY_LOW BIT(1)
432#define NO_PULL (BIT(14) | BIT(15))
433
434#define FREF_CLK_TYPE_BITS 0xfffffe7f
435#define CLK_REQ_PRCM 0x100
436#define FREF_CLK_POLARITY_BITS 0xfffff8ff
437#define CLK_REQ_OUTN_SEL 0x700
438
439#define WU_COUNTER_PAUSE_VAL 0x3FF
440
441/* PLL configuration algorithm for wl128x */
442#define SYS_CLK_CFG_REG 0x2200
443/* Bit[0] - 0-TCXO, 1-FREF */
444#define MCS_PLL_CLK_SEL_FREF BIT(0)
445/* Bit[3:2] - 01-TCXO, 10-FREF */
446#define WL_CLK_REQ_TYPE_FREF BIT(3)
447#define WL_CLK_REQ_TYPE_PG2 (BIT(3) | BIT(2))
448/* Bit[4] - 0-TCXO, 1-FREF */
449#define PRCM_CM_EN_MUX_WLAN_FREF BIT(4)
450
451#define TCXO_ILOAD_INT_REG 0x2264
452#define TCXO_CLK_DETECT_REG 0x2266
453
454#define TCXO_DET_FAILED BIT(4)
455
456#define FREF_ILOAD_INT_REG 0x2084
457#define FREF_CLK_DETECT_REG 0x2086
458#define FREF_CLK_DETECT_FAIL BIT(4)
459
460/* Use this reg for masking during driver access */
461#define WL_SPARE_REG 0x2320
462#define WL_SPARE_VAL BIT(2)
463/* Bit[6:5:3] - mask wl write SYS_CLK_CFG[8:5:2:4] */
464#define WL_SPARE_MASK_8526 (BIT(6) | BIT(5) | BIT(3))
465
466#define PLL_LOCK_COUNTERS_REG 0xD8C
467#define PLL_LOCK_COUNTERS_COEX 0x0F
468#define PLL_LOCK_COUNTERS_MCS 0xF0
469#define MCS_PLL_OVERRIDE_REG 0xD90
470#define MCS_PLL_CONFIG_REG 0xD92
471#define MCS_SEL_IN_FREQ_MASK 0x0070
472#define MCS_SEL_IN_FREQ_SHIFT 4
473#define MCS_PLL_CONFIG_REG_VAL 0x73
474#define MCS_PLL_ENABLE_HP (BIT(0) | BIT(1))
475
476#define MCS_PLL_M_REG 0xD94
477#define MCS_PLL_N_REG 0xD96
478#define MCS_PLL_M_REG_VAL 0xC8
479#define MCS_PLL_N_REG_VAL 0x07
480
481#define SDIO_IO_DS 0xd14
482
483/* SDIO/wSPI DS configuration values */
484enum {
485 HCI_IO_DS_8MA = 0,
486 HCI_IO_DS_4MA = 1, /* default */
487 HCI_IO_DS_6MA = 2,
488 HCI_IO_DS_2MA = 3,
489};
468 490
469/************************************************************************* 491/* end PLL configuration algorithm for wl128x */
470
471 Interrupt Trigger Register (Host -> WiLink)
472
473**************************************************************************/
474
475/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
476 492
477/* 493/*
478 * Host Command Interrupt. Setting this bit masks 494 * Host Command Interrupt. Setting this bit masks
@@ -480,7 +496,7 @@ b12-b0 - Supported Rate indicator bits as defined below.
480 * the FW that it has sent a command 496 * the FW that it has sent a command
481 * to the Wlan hardware Command Mailbox. 497 * to the Wlan hardware Command Mailbox.
482 */ 498 */
483#define INTR_TRIG_CMD BIT(0) 499#define WL12XX_INTR_TRIG_CMD BIT(0)
484 500
485/* 501/*
486 * Host Event Acknowlegde Interrupt. The host 502 * Host Event Acknowlegde Interrupt. The host
@@ -488,42 +504,27 @@ b12-b0 - Supported Rate indicator bits as defined below.
488 * the unsolicited information from the event 504 * the unsolicited information from the event
489 * mailbox. 505 * mailbox.
490 */ 506 */
491#define INTR_TRIG_EVENT_ACK BIT(1) 507#define WL12XX_INTR_TRIG_EVENT_ACK BIT(1)
492
493/*
494 * The host sets this bit to inform the Wlan
495 * FW that a TX packet is in the XFER
496 * Buffer #0.
497 */
498#define INTR_TRIG_TX_PROC0 BIT(2)
499
500/*
501 * The host sets this bit to inform the FW
502 * that it read a packet from RX XFER
503 * Buffer #0.
504 */
505#define INTR_TRIG_RX_PROC0 BIT(3)
506
507#define INTR_TRIG_DEBUG_ACK BIT(4)
508 508
509#define INTR_TRIG_STATE_CHANGED BIT(5) 509/*===============================================
510 510 HI_CFG Interface Configuration Register Values
511 511 ------------------------------------------
512/* Hardware to Embedded CPU Interrupts - second 32-bit register set */ 512 ===============================================*/
513 513#define HI_CFG_UART_ENABLE 0x00000004
514/* 514#define HI_CFG_RST232_ENABLE 0x00000008
515 * The host sets this bit to inform the FW 515#define HI_CFG_CLOCK_REQ_SELECT 0x00000010
516 * that it read a packet from RX XFER 516#define HI_CFG_HOST_INT_ENABLE 0x00000020
517 * Buffer #1. 517#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040
518 */ 518#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080
519#define INTR_TRIG_RX_PROC1 BIT(17) 519#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100
520#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
521#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
520 522
521/* 523#define HI_CFG_DEF_VAL \
522 * The host sets this bit to inform the Wlan 524 (HI_CFG_UART_ENABLE | \
523 * hardware that a TX packet is in the XFER 525 HI_CFG_RST232_ENABLE | \
524 * Buffer #1. 526 HI_CFG_CLOCK_REQ_SELECT | \
525 */ 527 HI_CFG_HOST_INT_ENABLE)
526#define INTR_TRIG_TX_PROC1 BIT(18)
527 528
528#define WL127X_REG_FUSE_DATA_2_1 0x050a 529#define WL127X_REG_FUSE_DATA_2_1 0x050a
529#define WL128X_REG_FUSE_DATA_2_1 0x2152 530#define WL128X_REG_FUSE_DATA_2_1 0x2152
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
new file mode 100644
index 000000000000..74cd332e23ef
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -0,0 +1,31 @@
1/*
2 * This file is part of wl12xx
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#ifndef __WL12XX_PRIV_H__
23#define __WL12XX_PRIV_H__
24
25#include "conf.h"
26
27struct wl12xx_priv {
28 struct wl12xx_priv_conf conf;
29};
30
31#endif /* __WL12XX_PRIV_H__ */
diff --git a/drivers/net/wireless/ti/wlcore/Kconfig b/drivers/net/wireless/ti/wlcore/Kconfig
new file mode 100644
index 000000000000..9d04c38938bc
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/Kconfig
@@ -0,0 +1,41 @@
1config WLCORE
2 tristate "TI wlcore support"
3 depends on WL_TI && GENERIC_HARDIRQS
4 depends on INET
5 select FW_LOADER
6 ---help---
7 This module contains the main code for TI WLAN chips. It abstracts
8 hardware-specific differences among different chipset families.
9 Each chipset family needs to implement its own lower-level module
10 that will depend on this module for the common code.
11
12 If you choose to build a module, it will be called wlcore. Say N if
13 unsure.
14
15config WLCORE_SPI
16 tristate "TI wlcore SPI support"
17 depends on WLCORE && SPI_MASTER
18 select CRC7
19 ---help---
20 This module adds support for the SPI interface of adapters using
21 TI WLAN chipsets. Select this if your platform is using
22 the SPI bus.
23
24 If you choose to build a module, it'll be called wlcore_spi.
25 Say N if unsure.
26
27config WLCORE_SDIO
28 tristate "TI wlcore SDIO support"
29 depends on WLCORE && MMC
30 ---help---
31 This module adds support for the SDIO interface of adapters using
32 TI WLAN chipsets. Select this if your platform is using
33 the SDIO bus.
34
35 If you choose to build a module, it'll be called wlcore_sdio.
36 Say N if unsure.
37
38config WL12XX_PLATFORM_DATA
39 bool
40 depends on WLCORE_SDIO != n || WL1251_SDIO != n
41 default y
diff --git a/drivers/net/wireless/ti/wlcore/Makefile b/drivers/net/wireless/ti/wlcore/Makefile
new file mode 100644
index 000000000000..d9fba9e32130
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/Makefile
@@ -0,0 +1,15 @@
1wlcore-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
2 boot.o init.o debugfs.o scan.o
3
4wlcore_spi-objs = spi.o
5wlcore_sdio-objs = sdio.o
6
7wlcore-$(CONFIG_NL80211_TESTMODE) += testmode.o
8obj-$(CONFIG_WLCORE) += wlcore.o
9obj-$(CONFIG_WLCORE_SPI) += wlcore_spi.o
10obj-$(CONFIG_WLCORE_SDIO) += wlcore_sdio.o
11
12# small builtin driver bit
13obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
14
15ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index bc96db0683a5..5912541a925e 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -28,11 +28,11 @@
28#include <linux/spi/spi.h> 28#include <linux/spi/spi.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30 30
31#include "wl12xx.h" 31#include "wlcore.h"
32#include "debug.h" 32#include "debug.h"
33#include "wl12xx_80211.h" 33#include "wl12xx_80211.h"
34#include "reg.h"
35#include "ps.h" 34#include "ps.h"
35#include "hw_ops.h"
36 36
37int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif, 37int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif,
38 u8 wake_up_event, u8 listen_interval) 38 u8 wake_up_event, u8 listen_interval)
@@ -757,7 +757,10 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
757 757
758 /* configure one AP supported rate class */ 758 /* configure one AP supported rate class */
759 acx->rate_policy_idx = cpu_to_le32(wlvif->sta.ap_rate_idx); 759 acx->rate_policy_idx = cpu_to_le32(wlvif->sta.ap_rate_idx);
760 acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->rate_set); 760
761 /* the AP policy is HW specific */
762 acx->rate_policy.enabled_rates =
763 cpu_to_le32(wlcore_hw_sta_get_ap_rate_mask(wl, wlvif));
761 acx->rate_policy.short_retry_limit = c->short_retry_limit; 764 acx->rate_policy.short_retry_limit = c->short_retry_limit;
762 acx->rate_policy.long_retry_limit = c->long_retry_limit; 765 acx->rate_policy.long_retry_limit = c->long_retry_limit;
763 acx->rate_policy.aflags = c->aflags; 766 acx->rate_policy.aflags = c->aflags;
@@ -969,17 +972,14 @@ int wl12xx_acx_mem_cfg(struct wl1271 *wl)
969 goto out; 972 goto out;
970 } 973 }
971 974
972 if (wl->chip.id == CHIP_ID_1283_PG20) 975 mem = &wl->conf.mem;
973 mem = &wl->conf.mem_wl128x;
974 else
975 mem = &wl->conf.mem_wl127x;
976 976
977 /* memory config */ 977 /* memory config */
978 mem_conf->num_stations = mem->num_stations; 978 mem_conf->num_stations = mem->num_stations;
979 mem_conf->rx_mem_block_num = mem->rx_block_num; 979 mem_conf->rx_mem_block_num = mem->rx_block_num;
980 mem_conf->tx_min_mem_block_num = mem->tx_min_block_num; 980 mem_conf->tx_min_mem_block_num = mem->tx_min_block_num;
981 mem_conf->num_ssid_profiles = mem->ssid_profiles; 981 mem_conf->num_ssid_profiles = mem->ssid_profiles;
982 mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); 982 mem_conf->total_tx_descriptors = cpu_to_le32(wl->num_tx_desc);
983 mem_conf->dyn_mem_enable = mem->dynamic_memory; 983 mem_conf->dyn_mem_enable = mem->dynamic_memory;
984 mem_conf->tx_free_req = mem->min_req_tx_blocks; 984 mem_conf->tx_free_req = mem->min_req_tx_blocks;
985 mem_conf->rx_free_req = mem->min_req_rx_blocks; 985 mem_conf->rx_free_req = mem->min_req_rx_blocks;
@@ -998,32 +998,6 @@ out:
998 return ret; 998 return ret;
999} 999}
1000 1000
1001int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap)
1002{
1003 struct wl1271_acx_host_config_bitmap *bitmap_conf;
1004 int ret;
1005
1006 bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
1007 if (!bitmap_conf) {
1008 ret = -ENOMEM;
1009 goto out;
1010 }
1011
1012 bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
1013
1014 ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
1015 bitmap_conf, sizeof(*bitmap_conf));
1016 if (ret < 0) {
1017 wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
1018 goto out;
1019 }
1020
1021out:
1022 kfree(bitmap_conf);
1023
1024 return ret;
1025}
1026
1027int wl1271_acx_init_mem_config(struct wl1271 *wl) 1001int wl1271_acx_init_mem_config(struct wl1271 *wl)
1028{ 1002{
1029 int ret; 1003 int ret;
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index a28fc044034c..b2f88831b7a9 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -25,7 +25,7 @@
25#ifndef __ACX_H__ 25#ifndef __ACX_H__
26#define __ACX_H__ 26#define __ACX_H__
27 27
28#include "wl12xx.h" 28#include "wlcore.h"
29#include "cmd.h" 29#include "cmd.h"
30 30
31/************************************************************************* 31/*************************************************************************
@@ -824,16 +824,11 @@ struct wl1271_acx_keep_alive_config {
824 __le32 period; 824 __le32 period;
825} __packed; 825} __packed;
826 826
827/* TODO: maybe this needs to be moved somewhere else? */
827#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0) 828#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0)
828#define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1) 829#define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1)
829#define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3) 830#define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3)
830 831
831struct wl1271_acx_host_config_bitmap {
832 struct acx_header header;
833
834 __le32 host_cfg_bitmap;
835} __packed;
836
837enum { 832enum {
838 WL1271_ACX_TRIG_TYPE_LEVEL = 0, 833 WL1271_ACX_TRIG_TYPE_LEVEL = 0,
839 WL1271_ACX_TRIG_TYPE_EDGE, 834 WL1271_ACX_TRIG_TYPE_EDGE,
@@ -1274,7 +1269,6 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold);
1274int wl1271_acx_tx_config_options(struct wl1271 *wl); 1269int wl1271_acx_tx_config_options(struct wl1271 *wl);
1275int wl12xx_acx_mem_cfg(struct wl1271 *wl); 1270int wl12xx_acx_mem_cfg(struct wl1271 *wl);
1276int wl1271_acx_init_mem_config(struct wl1271 *wl); 1271int wl1271_acx_init_mem_config(struct wl1271 *wl);
1277int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap);
1278int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); 1272int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
1279int wl1271_acx_smart_reflex(struct wl1271 *wl); 1273int wl1271_acx_smart_reflex(struct wl1271 *wl);
1280int wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1274int wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif,
diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c
new file mode 100644
index 000000000000..3a2207db5405
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/boot.c
@@ -0,0 +1,443 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/slab.h>
25#include <linux/wl12xx.h>
26#include <linux/export.h>
27
28#include "debug.h"
29#include "acx.h"
30#include "boot.h"
31#include "io.h"
32#include "event.h"
33#include "rx.h"
34#include "hw_ops.h"
35
36static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
37{
38 u32 cpu_ctrl;
39
40 /* 10.5.0 run the firmware (I) */
41 cpu_ctrl = wlcore_read_reg(wl, REG_ECPU_CONTROL);
42
43 /* 10.5.1 run the firmware (II) */
44 cpu_ctrl |= flag;
45 wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl);
46}
47
48static int wlcore_parse_fw_ver(struct wl1271 *wl)
49{
50 int ret;
51
52 ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u",
53 &wl->chip.fw_ver[0], &wl->chip.fw_ver[1],
54 &wl->chip.fw_ver[2], &wl->chip.fw_ver[3],
55 &wl->chip.fw_ver[4]);
56
57 if (ret != 5) {
58 wl1271_warning("fw version incorrect value");
59 memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
60 return -EINVAL;
61 }
62
63 ret = wlcore_identify_fw(wl);
64 if (ret < 0)
65 return ret;
66
67 return 0;
68}
69
70static int wlcore_boot_fw_version(struct wl1271 *wl)
71{
72 struct wl1271_static_data *static_data;
73 int ret;
74
75 static_data = kmalloc(sizeof(*static_data), GFP_DMA);
76 if (!static_data) {
77 wl1271_error("Couldn't allocate memory for static data!");
78 return -ENOMEM;
79 }
80
81 wl1271_read(wl, wl->cmd_box_addr, static_data, sizeof(*static_data),
82 false);
83
84 strncpy(wl->chip.fw_ver_str, static_data->fw_version,
85 sizeof(wl->chip.fw_ver_str));
86
87 kfree(static_data);
88
89 /* make sure the string is NULL-terminated */
90 wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
91
92 ret = wlcore_parse_fw_ver(wl);
93 if (ret < 0)
94 return ret;
95
96 return 0;
97}
98
99static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
100 size_t fw_data_len, u32 dest)
101{
102 struct wlcore_partition_set partition;
103 int addr, chunk_num, partition_limit;
104 u8 *p, *chunk;
105
106 /* whal_FwCtrl_LoadFwImageSm() */
107
108 wl1271_debug(DEBUG_BOOT, "starting firmware upload");
109
110 wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d",
111 fw_data_len, CHUNK_SIZE);
112
113 if ((fw_data_len % 4) != 0) {
114 wl1271_error("firmware length not multiple of four");
115 return -EIO;
116 }
117
118 chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL);
119 if (!chunk) {
120 wl1271_error("allocation for firmware upload chunk failed");
121 return -ENOMEM;
122 }
123
124 memcpy(&partition, &wl->ptable[PART_DOWN], sizeof(partition));
125 partition.mem.start = dest;
126 wlcore_set_partition(wl, &partition);
127
128 /* 10.1 set partition limit and chunk num */
129 chunk_num = 0;
130 partition_limit = wl->ptable[PART_DOWN].mem.size;
131
132 while (chunk_num < fw_data_len / CHUNK_SIZE) {
133 /* 10.2 update partition, if needed */
134 addr = dest + (chunk_num + 2) * CHUNK_SIZE;
135 if (addr > partition_limit) {
136 addr = dest + chunk_num * CHUNK_SIZE;
137 partition_limit = chunk_num * CHUNK_SIZE +
138 wl->ptable[PART_DOWN].mem.size;
139 partition.mem.start = addr;
140 wlcore_set_partition(wl, &partition);
141 }
142
143 /* 10.3 upload the chunk */
144 addr = dest + chunk_num * CHUNK_SIZE;
145 p = buf + chunk_num * CHUNK_SIZE;
146 memcpy(chunk, p, CHUNK_SIZE);
147 wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
148 p, addr);
149 wl1271_write(wl, addr, chunk, CHUNK_SIZE, false);
150
151 chunk_num++;
152 }
153
154 /* 10.4 upload the last chunk */
155 addr = dest + chunk_num * CHUNK_SIZE;
156 p = buf + chunk_num * CHUNK_SIZE;
157 memcpy(chunk, p, fw_data_len % CHUNK_SIZE);
158 wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
159 fw_data_len % CHUNK_SIZE, p, addr);
160 wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
161
162 kfree(chunk);
163 return 0;
164}
165
166int wlcore_boot_upload_firmware(struct wl1271 *wl)
167{
168 u32 chunks, addr, len;
169 int ret = 0;
170 u8 *fw;
171
172 fw = wl->fw;
173 chunks = be32_to_cpup((__be32 *) fw);
174 fw += sizeof(u32);
175
176 wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks);
177
178 while (chunks--) {
179 addr = be32_to_cpup((__be32 *) fw);
180 fw += sizeof(u32);
181 len = be32_to_cpup((__be32 *) fw);
182 fw += sizeof(u32);
183
184 if (len > 300000) {
185 wl1271_info("firmware chunk too long: %u", len);
186 return -EINVAL;
187 }
188 wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u",
189 chunks, addr, len);
190 ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
191 if (ret != 0)
192 break;
193 fw += len;
194 }
195
196 return ret;
197}
198EXPORT_SYMBOL_GPL(wlcore_boot_upload_firmware);
199
200int wlcore_boot_upload_nvs(struct wl1271 *wl)
201{
202 size_t nvs_len, burst_len;
203 int i;
204 u32 dest_addr, val;
205 u8 *nvs_ptr, *nvs_aligned;
206
207 if (wl->nvs == NULL)
208 return -ENODEV;
209
210 if (wl->quirks & WLCORE_QUIRK_LEGACY_NVS) {
211 struct wl1271_nvs_file *nvs =
212 (struct wl1271_nvs_file *)wl->nvs;
213 /*
214 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz
215 * band configurations) can be removed when those NVS files stop
216 * floating around.
217 */
218 if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
219 wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
220 if (nvs->general_params.dual_mode_select)
221 wl->enable_11a = true;
222 }
223
224 if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
225 (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
226 wl->enable_11a)) {
227 wl1271_error("nvs size is not as expected: %zu != %zu",
228 wl->nvs_len, sizeof(struct wl1271_nvs_file));
229 kfree(wl->nvs);
230 wl->nvs = NULL;
231 wl->nvs_len = 0;
232 return -EILSEQ;
233 }
234
235 /* only the first part of the NVS needs to be uploaded */
236 nvs_len = sizeof(nvs->nvs);
237 nvs_ptr = (u8 *) nvs->nvs;
238 } else {
239 struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
240
241 if (wl->nvs_len == sizeof(struct wl128x_nvs_file)) {
242 if (nvs->general_params.dual_mode_select)
243 wl->enable_11a = true;
244 } else {
245 wl1271_error("nvs size is not as expected: %zu != %zu",
246 wl->nvs_len,
247 sizeof(struct wl128x_nvs_file));
248 kfree(wl->nvs);
249 wl->nvs = NULL;
250 wl->nvs_len = 0;
251 return -EILSEQ;
252 }
253
254 /* only the first part of the NVS needs to be uploaded */
255 nvs_len = sizeof(nvs->nvs);
256 nvs_ptr = (u8 *)nvs->nvs;
257 }
258
259 /* update current MAC address to NVS */
260 nvs_ptr[11] = wl->addresses[0].addr[0];
261 nvs_ptr[10] = wl->addresses[0].addr[1];
262 nvs_ptr[6] = wl->addresses[0].addr[2];
263 nvs_ptr[5] = wl->addresses[0].addr[3];
264 nvs_ptr[4] = wl->addresses[0].addr[4];
265 nvs_ptr[3] = wl->addresses[0].addr[5];
266
267 /*
268 * Layout before the actual NVS tables:
269 * 1 byte : burst length.
270 * 2 bytes: destination address.
271 * n bytes: data to burst copy.
272 *
273 * This is ended by a 0 length, then the NVS tables.
274 */
275
276 /* FIXME: Do we need to check here whether the LSB is 1? */
277 while (nvs_ptr[0]) {
278 burst_len = nvs_ptr[0];
279 dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
280
281 /*
282 * Due to our new wl1271_translate_reg_addr function,
283 * we need to add the register partition start address
284 * to the destination
285 */
286 dest_addr += wl->curr_part.reg.start;
287
288 /* We move our pointer to the data */
289 nvs_ptr += 3;
290
291 for (i = 0; i < burst_len; i++) {
292 if (nvs_ptr + 3 >= (u8 *) wl->nvs + nvs_len)
293 goto out_badnvs;
294
295 val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
296 | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
297
298 wl1271_debug(DEBUG_BOOT,
299 "nvs burst write 0x%x: 0x%x",
300 dest_addr, val);
301 wl1271_write32(wl, dest_addr, val);
302
303 nvs_ptr += 4;
304 dest_addr += 4;
305 }
306
307 if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
308 goto out_badnvs;
309 }
310
311 /*
312 * We've reached the first zero length, the first NVS table
313 * is located at an aligned offset which is at least 7 bytes further.
314 * NOTE: The wl->nvs->nvs element must be first, in order to
315 * simplify the casting, we assume it is at the beginning of
316 * the wl->nvs structure.
317 */
318 nvs_ptr = (u8 *)wl->nvs +
319 ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
320
321 if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
322 goto out_badnvs;
323
324 nvs_len -= nvs_ptr - (u8 *)wl->nvs;
325
326 /* Now we must set the partition correctly */
327 wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
328
329 /* Copy the NVS tables to a new block to ensure alignment */
330 nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
331 if (!nvs_aligned)
332 return -ENOMEM;
333
334 /* And finally we upload the NVS tables */
335 wlcore_write_data(wl, REG_CMD_MBOX_ADDRESS,
336 nvs_aligned, nvs_len, false);
337
338 kfree(nvs_aligned);
339 return 0;
340
341out_badnvs:
342 wl1271_error("nvs data is malformed");
343 return -EILSEQ;
344}
345EXPORT_SYMBOL_GPL(wlcore_boot_upload_nvs);
346
347int wlcore_boot_run_firmware(struct wl1271 *wl)
348{
349 int loop, ret;
350 u32 chip_id, intr;
351
352 /* Make sure we have the boot partition */
353 wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
354
355 wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
356
357 chip_id = wlcore_read_reg(wl, REG_CHIP_ID_B);
358
359 wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
360
361 if (chip_id != wl->chip.id) {
362 wl1271_error("chip id doesn't match after firmware boot");
363 return -EIO;
364 }
365
366 /* wait for init to complete */
367 loop = 0;
368 while (loop++ < INIT_LOOP) {
369 udelay(INIT_LOOP_DELAY);
370 intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR);
371
372 if (intr == 0xffffffff) {
373 wl1271_error("error reading hardware complete "
374 "init indication");
375 return -EIO;
376 }
377 /* check that ACX_INTR_INIT_COMPLETE is enabled */
378 else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) {
379 wlcore_write_reg(wl, REG_INTERRUPT_ACK,
380 WL1271_ACX_INTR_INIT_COMPLETE);
381 break;
382 }
383 }
384
385 if (loop > INIT_LOOP) {
386 wl1271_error("timeout waiting for the hardware to "
387 "complete initialization");
388 return -EIO;
389 }
390
391 /* get hardware config command mail box */
392 wl->cmd_box_addr = wlcore_read_reg(wl, REG_COMMAND_MAILBOX_PTR);
393
394 wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x", wl->cmd_box_addr);
395
396 /* get hardware config event mail box */
397 wl->mbox_ptr[0] = wlcore_read_reg(wl, REG_EVENT_MAILBOX_PTR);
398 wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
399
400 wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x",
401 wl->mbox_ptr[0], wl->mbox_ptr[1]);
402
403 ret = wlcore_boot_fw_version(wl);
404 if (ret < 0) {
405 wl1271_error("couldn't boot firmware");
406 return ret;
407 }
408
409 /*
410 * in case of full asynchronous mode the firmware event must be
411 * ready to receive event from the command mailbox
412 */
413
414 /* unmask required mbox events */
415 wl->event_mask = BSS_LOSE_EVENT_ID |
416 SCAN_COMPLETE_EVENT_ID |
417 ROLE_STOP_COMPLETE_EVENT_ID |
418 RSSI_SNR_TRIGGER_0_EVENT_ID |
419 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
420 SOFT_GEMINI_SENSE_EVENT_ID |
421 PERIODIC_SCAN_REPORT_EVENT_ID |
422 PERIODIC_SCAN_COMPLETE_EVENT_ID |
423 DUMMY_PACKET_EVENT_ID |
424 PEER_REMOVE_COMPLETE_EVENT_ID |
425 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
426 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
427 INACTIVE_STA_EVENT_ID |
428 MAX_TX_RETRY_EVENT_ID |
429 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
430
431 ret = wl1271_event_unmask(wl);
432 if (ret < 0) {
433 wl1271_error("EVENT mask setting failed");
434 return ret;
435 }
436
437 /* set the working partition to its "running" mode offset */
438 wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
439
440 /* firmware startup completed */
441 return 0;
442}
443EXPORT_SYMBOL_GPL(wlcore_boot_run_firmware);
diff --git a/drivers/net/wireless/ti/wlcore/boot.h b/drivers/net/wireless/ti/wlcore/boot.h
new file mode 100644
index 000000000000..094981dd2227
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/boot.h
@@ -0,0 +1,54 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __BOOT_H__
25#define __BOOT_H__
26
27#include "wlcore.h"
28
29int wlcore_boot_upload_firmware(struct wl1271 *wl);
30int wlcore_boot_upload_nvs(struct wl1271 *wl);
31int wlcore_boot_run_firmware(struct wl1271 *wl);
32
33#define WL1271_NO_SUBBANDS 8
34#define WL1271_NO_POWER_LEVELS 4
35#define WL1271_FW_VERSION_MAX_LEN 20
36
37struct wl1271_static_data {
38 u8 mac_address[ETH_ALEN];
39 u8 padding[2];
40 u8 fw_version[WL1271_FW_VERSION_MAX_LEN];
41 u32 hw_version;
42 u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS];
43};
44
45/* number of times we try to read the INIT interrupt */
46#define INIT_LOOP 20000
47
48/* delay between retries */
49#define INIT_LOOP_DELAY 50
50
51#define WU_COUNTER_PAUSE_VAL 0x3FF
52#define WELP_ARM_COMMAND_VAL 0x4
53
54#endif
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 3414fc11e9ba..5c4716c6f040 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -28,9 +28,8 @@
28#include <linux/ieee80211.h> 28#include <linux/ieee80211.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30 30
31#include "wl12xx.h" 31#include "wlcore.h"
32#include "debug.h" 32#include "debug.h"
33#include "reg.h"
34#include "io.h" 33#include "io.h"
35#include "acx.h" 34#include "acx.h"
36#include "wl12xx_80211.h" 35#include "wl12xx_80211.h"
@@ -67,11 +66,15 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
67 66
68 wl1271_write(wl, wl->cmd_box_addr, buf, len, false); 67 wl1271_write(wl, wl->cmd_box_addr, buf, len, false);
69 68
70 wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); 69 /*
70 * TODO: we just need this because one bit is in a different
71 * place. Is there any better way?
72 */
73 wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len);
71 74
72 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); 75 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
73 76
74 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 77 intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR);
75 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { 78 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
76 if (time_after(jiffies, timeout)) { 79 if (time_after(jiffies, timeout)) {
77 wl1271_error("command complete timeout"); 80 wl1271_error("command complete timeout");
@@ -85,7 +88,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
85 else 88 else
86 msleep(1); 89 msleep(1);
87 90
88 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 91 intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR);
89 } 92 }
90 93
91 /* read back the status code of the command */ 94 /* read back the status code of the command */
@@ -100,8 +103,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
100 goto fail; 103 goto fail;
101 } 104 }
102 105
103 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, 106 wlcore_write_reg(wl, REG_INTERRUPT_ACK, WL1271_ACX_INTR_CMD_COMPLETE);
104 WL1271_ACX_INTR_CMD_COMPLETE);
105 return 0; 107 return 0;
106 108
107fail: 109fail:
@@ -110,240 +112,18 @@ fail:
110 return ret; 112 return ret;
111} 113}
112 114
113int wl1271_cmd_general_parms(struct wl1271 *wl)
114{
115 struct wl1271_general_parms_cmd *gen_parms;
116 struct wl1271_ini_general_params *gp =
117 &((struct wl1271_nvs_file *)wl->nvs)->general_params;
118 bool answer = false;
119 int ret;
120
121 if (!wl->nvs)
122 return -ENODEV;
123
124 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
125 wl1271_warning("FEM index from INI out of bounds");
126 return -EINVAL;
127 }
128
129 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
130 if (!gen_parms)
131 return -ENOMEM;
132
133 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
134
135 memcpy(&gen_parms->general_params, gp, sizeof(*gp));
136
137 if (gp->tx_bip_fem_auto_detect)
138 answer = true;
139
140 /* Override the REF CLK from the NVS with the one from platform data */
141 gen_parms->general_params.ref_clock = wl->ref_clock;
142
143 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
144 if (ret < 0) {
145 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
146 goto out;
147 }
148
149 gp->tx_bip_fem_manufacturer =
150 gen_parms->general_params.tx_bip_fem_manufacturer;
151
152 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
153 wl1271_warning("FEM index from FW out of bounds");
154 ret = -EINVAL;
155 goto out;
156 }
157
158 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
159 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
160
161out:
162 kfree(gen_parms);
163 return ret;
164}
165
166int wl128x_cmd_general_parms(struct wl1271 *wl)
167{
168 struct wl128x_general_parms_cmd *gen_parms;
169 struct wl128x_ini_general_params *gp =
170 &((struct wl128x_nvs_file *)wl->nvs)->general_params;
171 bool answer = false;
172 int ret;
173
174 if (!wl->nvs)
175 return -ENODEV;
176
177 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
178 wl1271_warning("FEM index from ini out of bounds");
179 return -EINVAL;
180 }
181
182 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
183 if (!gen_parms)
184 return -ENOMEM;
185
186 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
187
188 memcpy(&gen_parms->general_params, gp, sizeof(*gp));
189
190 if (gp->tx_bip_fem_auto_detect)
191 answer = true;
192
193 /* Replace REF and TCXO CLKs with the ones from platform data */
194 gen_parms->general_params.ref_clock = wl->ref_clock;
195 gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
196
197 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
198 if (ret < 0) {
199 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
200 goto out;
201 }
202
203 gp->tx_bip_fem_manufacturer =
204 gen_parms->general_params.tx_bip_fem_manufacturer;
205
206 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
207 wl1271_warning("FEM index from FW out of bounds");
208 ret = -EINVAL;
209 goto out;
210 }
211
212 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
213 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
214
215out:
216 kfree(gen_parms);
217 return ret;
218}
219
220int wl1271_cmd_radio_parms(struct wl1271 *wl)
221{
222 struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
223 struct wl1271_radio_parms_cmd *radio_parms;
224 struct wl1271_ini_general_params *gp = &nvs->general_params;
225 int ret;
226
227 if (!wl->nvs)
228 return -ENODEV;
229
230 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
231 if (!radio_parms)
232 return -ENOMEM;
233
234 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
235
236 /* 2.4GHz parameters */
237 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
238 sizeof(struct wl1271_ini_band_params_2));
239 memcpy(&radio_parms->dyn_params_2,
240 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
241 sizeof(struct wl1271_ini_fem_params_2));
242
243 /* 5GHz parameters */
244 memcpy(&radio_parms->static_params_5,
245 &nvs->stat_radio_params_5,
246 sizeof(struct wl1271_ini_band_params_5));
247 memcpy(&radio_parms->dyn_params_5,
248 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
249 sizeof(struct wl1271_ini_fem_params_5));
250
251 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
252 radio_parms, sizeof(*radio_parms));
253
254 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
255 if (ret < 0)
256 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
257
258 kfree(radio_parms);
259 return ret;
260}
261
262int wl128x_cmd_radio_parms(struct wl1271 *wl)
263{
264 struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
265 struct wl128x_radio_parms_cmd *radio_parms;
266 struct wl128x_ini_general_params *gp = &nvs->general_params;
267 int ret;
268
269 if (!wl->nvs)
270 return -ENODEV;
271
272 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
273 if (!radio_parms)
274 return -ENOMEM;
275
276 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
277
278 /* 2.4GHz parameters */
279 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
280 sizeof(struct wl128x_ini_band_params_2));
281 memcpy(&radio_parms->dyn_params_2,
282 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
283 sizeof(struct wl128x_ini_fem_params_2));
284
285 /* 5GHz parameters */
286 memcpy(&radio_parms->static_params_5,
287 &nvs->stat_radio_params_5,
288 sizeof(struct wl128x_ini_band_params_5));
289 memcpy(&radio_parms->dyn_params_5,
290 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
291 sizeof(struct wl128x_ini_fem_params_5));
292
293 radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
294
295 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
296 radio_parms, sizeof(*radio_parms));
297
298 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
299 if (ret < 0)
300 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
301
302 kfree(radio_parms);
303 return ret;
304}
305
306int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
307{
308 struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
309 struct conf_rf_settings *rf = &wl->conf.rf;
310 int ret;
311
312 if (!wl->nvs)
313 return -ENODEV;
314
315 ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
316 if (!ext_radio_parms)
317 return -ENOMEM;
318
319 ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
320
321 memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
322 rf->tx_per_channel_power_compensation_2,
323 CONF_TX_PWR_COMPENSATION_LEN_2);
324 memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
325 rf->tx_per_channel_power_compensation_5,
326 CONF_TX_PWR_COMPENSATION_LEN_5);
327
328 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
329 ext_radio_parms, sizeof(*ext_radio_parms));
330
331 ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
332 if (ret < 0)
333 wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
334
335 kfree(ext_radio_parms);
336 return ret;
337}
338
339/* 115/*
340 * Poll the mailbox event field until any of the bits in the mask is set or a 116 * Poll the mailbox event field until any of the bits in the mask is set or a
341 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) 117 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
342 */ 118 */
343static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask) 119static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask)
344{ 120{
345 u32 events_vector, event; 121 u32 *events_vector;
122 u32 event;
346 unsigned long timeout; 123 unsigned long timeout;
124 int ret = 0;
125
126 events_vector = kmalloc(sizeof(*events_vector), GFP_DMA);
347 127
348 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); 128 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
349 129
@@ -351,21 +131,24 @@ static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask)
351 if (time_after(jiffies, timeout)) { 131 if (time_after(jiffies, timeout)) {
352 wl1271_debug(DEBUG_CMD, "timeout waiting for event %d", 132 wl1271_debug(DEBUG_CMD, "timeout waiting for event %d",
353 (int)mask); 133 (int)mask);
354 return -ETIMEDOUT; 134 ret = -ETIMEDOUT;
135 goto out;
355 } 136 }
356 137
357 msleep(1); 138 msleep(1);
358 139
359 /* read from both event fields */ 140 /* read from both event fields */
360 wl1271_read(wl, wl->mbox_ptr[0], &events_vector, 141 wl1271_read(wl, wl->mbox_ptr[0], events_vector,
361 sizeof(events_vector), false); 142 sizeof(*events_vector), false);
362 event = events_vector & mask; 143 event = *events_vector & mask;
363 wl1271_read(wl, wl->mbox_ptr[1], &events_vector, 144 wl1271_read(wl, wl->mbox_ptr[1], events_vector,
364 sizeof(events_vector), false); 145 sizeof(*events_vector), false);
365 event |= events_vector & mask; 146 event |= *events_vector & mask;
366 } while (!event); 147 } while (!event);
367 148
368 return 0; 149out:
150 kfree(events_vector);
151 return ret;
369} 152}
370 153
371static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) 154static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
@@ -522,7 +305,7 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
522 305
523 cmd->role_id = wlvif->dev_role_id; 306 cmd->role_id = wlvif->dev_role_id;
524 if (wlvif->band == IEEE80211_BAND_5GHZ) 307 if (wlvif->band == IEEE80211_BAND_5GHZ)
525 cmd->band = WL12XX_BAND_5GHZ; 308 cmd->band = WLCORE_BAND_5GHZ;
526 cmd->channel = wlvif->channel; 309 cmd->channel = wlvif->channel;
527 310
528 if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) { 311 if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) {
@@ -613,7 +396,7 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
613 396
614 cmd->role_id = wlvif->role_id; 397 cmd->role_id = wlvif->role_id;
615 if (wlvif->band == IEEE80211_BAND_5GHZ) 398 if (wlvif->band == IEEE80211_BAND_5GHZ)
616 cmd->band = WL12XX_BAND_5GHZ; 399 cmd->band = WLCORE_BAND_5GHZ;
617 cmd->channel = wlvif->channel; 400 cmd->channel = wlvif->channel;
618 cmd->sta.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set); 401 cmd->sta.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
619 cmd->sta.beacon_interval = cpu_to_le16(wlvif->beacon_int); 402 cmd->sta.beacon_interval = cpu_to_le16(wlvif->beacon_int);
@@ -750,14 +533,14 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
750 533
751 switch (wlvif->band) { 534 switch (wlvif->band) {
752 case IEEE80211_BAND_2GHZ: 535 case IEEE80211_BAND_2GHZ:
753 cmd->band = RADIO_BAND_2_4GHZ; 536 cmd->band = WLCORE_BAND_2_4GHZ;
754 break; 537 break;
755 case IEEE80211_BAND_5GHZ: 538 case IEEE80211_BAND_5GHZ:
756 cmd->band = RADIO_BAND_5GHZ; 539 cmd->band = WLCORE_BAND_5GHZ;
757 break; 540 break;
758 default: 541 default:
759 wl1271_warning("ap start - unknown band: %d", (int)wlvif->band); 542 wl1271_warning("ap start - unknown band: %d", (int)wlvif->band);
760 cmd->band = RADIO_BAND_2_4GHZ; 543 cmd->band = WLCORE_BAND_2_4GHZ;
761 break; 544 break;
762 } 545 }
763 546
@@ -830,7 +613,7 @@ int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif)
830 613
831 cmd->role_id = wlvif->role_id; 614 cmd->role_id = wlvif->role_id;
832 if (wlvif->band == IEEE80211_BAND_5GHZ) 615 if (wlvif->band == IEEE80211_BAND_5GHZ)
833 cmd->band = WL12XX_BAND_5GHZ; 616 cmd->band = WLCORE_BAND_5GHZ;
834 cmd->channel = wlvif->channel; 617 cmd->channel = wlvif->channel;
835 cmd->ibss.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set); 618 cmd->ibss.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
836 cmd->ibss.beacon_interval = cpu_to_le16(wlvif->beacon_int); 619 cmd->ibss.beacon_interval = cpu_to_le16(wlvif->beacon_int);
@@ -904,6 +687,7 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
904 687
905 return ret; 688 return ret;
906} 689}
690EXPORT_SYMBOL_GPL(wl1271_cmd_test);
907 691
908/** 692/**
909 * read acx from firmware 693 * read acx from firmware
@@ -960,6 +744,7 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
960 744
961 return 0; 745 return 0;
962} 746}
747EXPORT_SYMBOL_GPL(wl1271_cmd_configure);
963 748
964int wl1271_cmd_data_path(struct wl1271 *wl, bool enable) 749int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
965{ 750{
@@ -1730,10 +1515,10 @@ static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1730 cmd->channel = wlvif->channel; 1515 cmd->channel = wlvif->channel;
1731 switch (wlvif->band) { 1516 switch (wlvif->band) {
1732 case IEEE80211_BAND_2GHZ: 1517 case IEEE80211_BAND_2GHZ:
1733 cmd->band = RADIO_BAND_2_4GHZ; 1518 cmd->band = WLCORE_BAND_2_4GHZ;
1734 break; 1519 break;
1735 case IEEE80211_BAND_5GHZ: 1520 case IEEE80211_BAND_5GHZ:
1736 cmd->band = RADIO_BAND_5GHZ; 1521 cmd->band = WLCORE_BAND_5GHZ;
1737 break; 1522 break;
1738 default: 1523 default:
1739 wl1271_error("roc - unknown band: %d", (int)wlvif->band); 1524 wl1271_error("roc - unknown band: %d", (int)wlvif->band);
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h
index de217d92516b..a46ae07cb77e 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/ti/wlcore/cmd.h
@@ -25,17 +25,12 @@
25#ifndef __CMD_H__ 25#ifndef __CMD_H__
26#define __CMD_H__ 26#define __CMD_H__
27 27
28#include "wl12xx.h" 28#include "wlcore.h"
29 29
30struct acx_header; 30struct 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 wl1271_cmd_general_parms(struct wl1271 *wl);
35int wl128x_cmd_general_parms(struct wl1271 *wl);
36int wl1271_cmd_radio_parms(struct wl1271 *wl);
37int wl128x_cmd_radio_parms(struct wl1271 *wl);
38int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
39int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, 34int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type,
40 u8 *role_id); 35 u8 *role_id);
41int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id); 36int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id);
@@ -262,13 +257,13 @@ struct wl12xx_cmd_role_disable {
262 u8 padding[3]; 257 u8 padding[3];
263} __packed; 258} __packed;
264 259
265enum wl12xx_band { 260enum wlcore_band {
266 WL12XX_BAND_2_4GHZ = 0, 261 WLCORE_BAND_2_4GHZ = 0,
267 WL12XX_BAND_5GHZ = 1, 262 WLCORE_BAND_5GHZ = 1,
268 WL12XX_BAND_JAPAN_4_9_GHZ = 2, 263 WLCORE_BAND_JAPAN_4_9_GHZ = 2,
269 WL12XX_BAND_DEFAULT = WL12XX_BAND_2_4GHZ, 264 WLCORE_BAND_DEFAULT = WLCORE_BAND_2_4GHZ,
270 WL12XX_BAND_INVALID = 0x7E, 265 WLCORE_BAND_INVALID = 0x7E,
271 WL12XX_BAND_MAX_RADIO = 0x7F, 266 WLCORE_BAND_MAX_RADIO = 0x7F,
272}; 267};
273 268
274struct wl12xx_cmd_role_start { 269struct wl12xx_cmd_role_start {
@@ -494,83 +489,6 @@ enum wl1271_channel_tune_bands {
494 489
495#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0 490#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
496 491
497#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
498#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
499#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
500
501struct wl1271_general_parms_cmd {
502 struct wl1271_cmd_header header;
503
504 struct wl1271_cmd_test_header test;
505
506 struct wl1271_ini_general_params general_params;
507
508 u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
509 u8 sr_sen_n_p;
510 u8 sr_sen_n_p_gain;
511 u8 sr_sen_nrn;
512 u8 sr_sen_prn;
513 u8 padding[3];
514} __packed;
515
516struct wl128x_general_parms_cmd {
517 struct wl1271_cmd_header header;
518
519 struct wl1271_cmd_test_header test;
520
521 struct wl128x_ini_general_params general_params;
522
523 u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
524 u8 sr_sen_n_p;
525 u8 sr_sen_n_p_gain;
526 u8 sr_sen_nrn;
527 u8 sr_sen_prn;
528 u8 padding[3];
529} __packed;
530
531struct wl1271_radio_parms_cmd {
532 struct wl1271_cmd_header header;
533
534 struct wl1271_cmd_test_header test;
535
536 /* Static radio parameters */
537 struct wl1271_ini_band_params_2 static_params_2;
538 struct wl1271_ini_band_params_5 static_params_5;
539
540 /* Dynamic radio parameters */
541 struct wl1271_ini_fem_params_2 dyn_params_2;
542 u8 padding2;
543 struct wl1271_ini_fem_params_5 dyn_params_5;
544 u8 padding3[2];
545} __packed;
546
547struct wl128x_radio_parms_cmd {
548 struct wl1271_cmd_header header;
549
550 struct wl1271_cmd_test_header test;
551
552 /* Static radio parameters */
553 struct wl128x_ini_band_params_2 static_params_2;
554 struct wl128x_ini_band_params_5 static_params_5;
555
556 u8 fem_vendor_and_options;
557
558 /* Dynamic radio parameters */
559 struct wl128x_ini_fem_params_2 dyn_params_2;
560 u8 padding2;
561 struct wl128x_ini_fem_params_5 dyn_params_5;
562} __packed;
563
564struct wl1271_ext_radio_parms_cmd {
565 struct wl1271_cmd_header header;
566
567 struct wl1271_cmd_test_header test;
568
569 u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
570 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
571 u8 padding[3];
572} __packed;
573
574/* 492/*
575 * There are three types of disconnections: 493 * There are three types of disconnections:
576 * 494 *
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/ti/wlcore/conf.h
index 3e581e19424c..fef0db4213bc 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/ti/wlcore/conf.h
@@ -65,36 +65,7 @@ enum {
65 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, 65 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS,
66}; 66};
67 67
68enum { 68#define CONF_HW_RXTX_RATE_UNSUPPORTED 0xff
69 CONF_HW_RXTX_RATE_MCS7_SGI = 0,
70 CONF_HW_RXTX_RATE_MCS7,
71 CONF_HW_RXTX_RATE_MCS6,
72 CONF_HW_RXTX_RATE_MCS5,
73 CONF_HW_RXTX_RATE_MCS4,
74 CONF_HW_RXTX_RATE_MCS3,
75 CONF_HW_RXTX_RATE_MCS2,
76 CONF_HW_RXTX_RATE_MCS1,
77 CONF_HW_RXTX_RATE_MCS0,
78 CONF_HW_RXTX_RATE_54,
79 CONF_HW_RXTX_RATE_48,
80 CONF_HW_RXTX_RATE_36,
81 CONF_HW_RXTX_RATE_24,
82 CONF_HW_RXTX_RATE_22,
83 CONF_HW_RXTX_RATE_18,
84 CONF_HW_RXTX_RATE_12,
85 CONF_HW_RXTX_RATE_11,
86 CONF_HW_RXTX_RATE_9,
87 CONF_HW_RXTX_RATE_6,
88 CONF_HW_RXTX_RATE_5_5,
89 CONF_HW_RXTX_RATE_2,
90 CONF_HW_RXTX_RATE_1,
91 CONF_HW_RXTX_RATE_MAX,
92 CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff
93};
94
95/* Rates between and including these are MCS rates */
96#define CONF_HW_RXTX_RATE_MCS_MIN CONF_HW_RXTX_RATE_MCS7_SGI
97#define CONF_HW_RXTX_RATE_MCS_MAX CONF_HW_RXTX_RATE_MCS0
98 69
99enum { 70enum {
100 CONF_SG_DISABLE = 0, 71 CONF_SG_DISABLE = 0,
@@ -1096,16 +1067,31 @@ struct conf_scan_settings {
1096}; 1067};
1097 1068
1098struct conf_sched_scan_settings { 1069struct conf_sched_scan_settings {
1099 /* minimum time to wait on the channel for active scans (in TUs) */ 1070 /*
1100 u16 min_dwell_time_active; 1071 * The base time to wait on the channel for active scans (in TU/1000).
1072 * The minimum dwell time is calculated according to this:
1073 * min_dwell_time = base + num_of_probes_to_be_sent * delta_per_probe
1074 * The maximum dwell time is calculated according to this:
1075 * max_dwell_time = min_dwell_time + max_dwell_time_delta
1076 */
1077 u32 base_dwell_time;
1101 1078
1102 /* maximum time to wait on the channel for active scans (in TUs) */ 1079 /* The delta between the min dwell time and max dwell time for
1103 u16 max_dwell_time_active; 1080 * active scans (in TU/1000s). The max dwell time is used by the FW once
1081 * traffic is detected on the channel.
1082 */
1083 u32 max_dwell_time_delta;
1084
1085 /* Delta added to min dwell time per each probe in 2.4 GHz (TU/1000) */
1086 u32 dwell_time_delta_per_probe;
1104 1087
1105 /* time to wait on the channel for passive scans (in TUs) */ 1088 /* Delta added to min dwell time per each probe in 5 GHz (TU/1000) */
1089 u32 dwell_time_delta_per_probe_5;
1090
1091 /* time to wait on the channel for passive scans (in TU/1000) */
1106 u32 dwell_time_passive; 1092 u32 dwell_time_passive;
1107 1093
1108 /* time to wait on the channel for DFS scans (in TUs) */ 1094 /* time to wait on the channel for DFS scans (in TU/1000) */
1109 u32 dwell_time_dfs; 1095 u32 dwell_time_dfs;
1110 1096
1111 /* number of probe requests to send on each channel in active scans */ 1097 /* number of probe requests to send on each channel in active scans */
@@ -1118,26 +1104,6 @@ struct conf_sched_scan_settings {
1118 s8 snr_threshold; 1104 s8 snr_threshold;
1119}; 1105};
1120 1106
1121/* these are number of channels on the band divided by two, rounded up */
1122#define CONF_TX_PWR_COMPENSATION_LEN_2 7
1123#define CONF_TX_PWR_COMPENSATION_LEN_5 18
1124
1125struct conf_rf_settings {
1126 /*
1127 * Per channel power compensation for 2.4GHz
1128 *
1129 * Range: s8
1130 */
1131 u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
1132
1133 /*
1134 * Per channel power compensation for 5GHz
1135 *
1136 * Range: s8
1137 */
1138 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
1139};
1140
1141struct conf_ht_setting { 1107struct conf_ht_setting {
1142 u8 rx_ba_win_size; 1108 u8 rx_ba_win_size;
1143 u8 tx_ba_win_size; 1109 u8 tx_ba_win_size;
@@ -1286,7 +1252,7 @@ struct conf_hangover_settings {
1286 u8 window_size; 1252 u8 window_size;
1287}; 1253};
1288 1254
1289struct conf_drv_settings { 1255struct wlcore_conf {
1290 struct conf_sg_settings sg; 1256 struct conf_sg_settings sg;
1291 struct conf_rx_settings rx; 1257 struct conf_rx_settings rx;
1292 struct conf_tx_settings tx; 1258 struct conf_tx_settings tx;
@@ -1296,16 +1262,13 @@ struct conf_drv_settings {
1296 struct conf_roam_trigger_settings roam_trigger; 1262 struct conf_roam_trigger_settings roam_trigger;
1297 struct conf_scan_settings scan; 1263 struct conf_scan_settings scan;
1298 struct conf_sched_scan_settings sched_scan; 1264 struct conf_sched_scan_settings sched_scan;
1299 struct conf_rf_settings rf;
1300 struct conf_ht_setting ht; 1265 struct conf_ht_setting ht;
1301 struct conf_memory_settings mem_wl127x; 1266 struct conf_memory_settings mem;
1302 struct conf_memory_settings mem_wl128x;
1303 struct conf_fm_coex fm_coex; 1267 struct conf_fm_coex fm_coex;
1304 struct conf_rx_streaming_settings rx_streaming; 1268 struct conf_rx_streaming_settings rx_streaming;
1305 struct conf_fwlog fwlog; 1269 struct conf_fwlog fwlog;
1306 struct conf_rate_policy_settings rate; 1270 struct conf_rate_policy_settings rate;
1307 struct conf_hangover_settings hangover; 1271 struct conf_hangover_settings hangover;
1308 u8 hci_io_ds;
1309}; 1272};
1310 1273
1311#endif 1274#endif
diff --git a/drivers/net/wireless/wl12xx/debug.h b/drivers/net/wireless/ti/wlcore/debug.h
index ec0fdc25b280..6b800b3cbea5 100644
--- a/drivers/net/wireless/wl12xx/debug.h
+++ b/drivers/net/wireless/ti/wlcore/debug.h
@@ -52,6 +52,7 @@ enum {
52 DEBUG_ADHOC = BIT(16), 52 DEBUG_ADHOC = BIT(16),
53 DEBUG_AP = BIT(17), 53 DEBUG_AP = BIT(17),
54 DEBUG_PROBE = BIT(18), 54 DEBUG_PROBE = BIT(18),
55 DEBUG_IO = BIT(19),
55 DEBUG_MASTER = (DEBUG_ADHOC | DEBUG_AP), 56 DEBUG_MASTER = (DEBUG_ADHOC | DEBUG_AP),
56 DEBUG_ALL = ~0, 57 DEBUG_ALL = ~0,
57}; 58};
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index 564d49575c94..d5aea1ff5ad1 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -26,7 +26,7 @@
26#include <linux/skbuff.h> 26#include <linux/skbuff.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28 28
29#include "wl12xx.h" 29#include "wlcore.h"
30#include "debug.h" 30#include "debug.h"
31#include "acx.h" 31#include "acx.h"
32#include "ps.h" 32#include "ps.h"
@@ -647,6 +647,7 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
647 VIF_STATE_PRINT_INT(last_rssi_event); 647 VIF_STATE_PRINT_INT(last_rssi_event);
648 VIF_STATE_PRINT_INT(ba_support); 648 VIF_STATE_PRINT_INT(ba_support);
649 VIF_STATE_PRINT_INT(ba_allowed); 649 VIF_STATE_PRINT_INT(ba_allowed);
650 VIF_STATE_PRINT_INT(is_gem);
650 VIF_STATE_PRINT_LLHEX(tx_security_seq); 651 VIF_STATE_PRINT_LLHEX(tx_security_seq);
651 VIF_STATE_PRINT_INT(tx_security_last_seq_lsb); 652 VIF_STATE_PRINT_INT(tx_security_last_seq_lsb);
652 } 653 }
diff --git a/drivers/net/wireless/wl12xx/debugfs.h b/drivers/net/wireless/ti/wlcore/debugfs.h
index 254c5b292cf6..a8d3aef011ff 100644
--- a/drivers/net/wireless/wl12xx/debugfs.h
+++ b/drivers/net/wireless/ti/wlcore/debugfs.h
@@ -24,7 +24,7 @@
24#ifndef __DEBUGFS_H__ 24#ifndef __DEBUGFS_H__
25#define __DEBUGFS_H__ 25#define __DEBUGFS_H__
26 26
27#include "wl12xx.h" 27#include "wlcore.h"
28 28
29int wl1271_debugfs_init(struct wl1271 *wl); 29int wl1271_debugfs_init(struct wl1271 *wl);
30void wl1271_debugfs_exit(struct wl1271 *wl); 30void wl1271_debugfs_exit(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/ti/wlcore/event.c
index c953717f38eb..292632ddf890 100644
--- a/drivers/net/wireless/wl12xx/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -21,9 +21,8 @@
21 * 21 *
22 */ 22 */
23 23
24#include "wl12xx.h" 24#include "wlcore.h"
25#include "debug.h" 25#include "debug.h"
26#include "reg.h"
27#include "io.h" 26#include "io.h"
28#include "event.h" 27#include "event.h"
29#include "ps.h" 28#include "ps.h"
@@ -98,8 +97,9 @@ static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
98 wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask); 97 wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
99} 98}
100 99
101static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) 100static int wl1271_event_process(struct wl1271 *wl)
102{ 101{
102 struct event_mailbox *mbox = wl->mbox;
103 struct ieee80211_vif *vif; 103 struct ieee80211_vif *vif;
104 struct wl12xx_vif *wlvif; 104 struct wl12xx_vif *wlvif;
105 u32 vector; 105 u32 vector;
@@ -196,7 +196,7 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
196 bool success; 196 bool success;
197 197
198 if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, 198 if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS,
199 &wl->flags)) 199 &wlvif->flags))
200 continue; 200 continue;
201 201
202 success = mbox->channel_switch_status ? false : true; 202 success = mbox->channel_switch_status ? false : true;
@@ -278,18 +278,8 @@ int wl1271_event_unmask(struct wl1271 *wl)
278 return 0; 278 return 0;
279} 279}
280 280
281void wl1271_event_mbox_config(struct wl1271 *wl)
282{
283 wl->mbox_ptr[0] = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
284 wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
285
286 wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
287 wl->mbox_ptr[0], wl->mbox_ptr[1]);
288}
289
290int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) 281int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
291{ 282{
292 struct event_mailbox mbox;
293 int ret; 283 int ret;
294 284
295 wl1271_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num); 285 wl1271_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
@@ -298,16 +288,19 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
298 return -EINVAL; 288 return -EINVAL;
299 289
300 /* first we read the mbox descriptor */ 290 /* first we read the mbox descriptor */
301 wl1271_read(wl, wl->mbox_ptr[mbox_num], &mbox, 291 wl1271_read(wl, wl->mbox_ptr[mbox_num], wl->mbox,
302 sizeof(struct event_mailbox), false); 292 sizeof(*wl->mbox), false);
303 293
304 /* process the descriptor */ 294 /* process the descriptor */
305 ret = wl1271_event_process(wl, &mbox); 295 ret = wl1271_event_process(wl);
306 if (ret < 0) 296 if (ret < 0)
307 return ret; 297 return ret;
308 298
309 /* then we let the firmware know it can go on...*/ 299 /*
310 wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK); 300 * TODO: we just need this because one bit is in a different
301 * place. Is there any better way?
302 */
303 wl->ops->ack_event(wl);
311 304
312 return 0; 305 return 0;
313} 306}
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/ti/wlcore/event.h
index 057d193d3525..8adf18d6c58f 100644
--- a/drivers/net/wireless/wl12xx/event.h
+++ b/drivers/net/wireless/ti/wlcore/event.h
@@ -132,8 +132,9 @@ struct event_mailbox {
132 u8 reserved_8[9]; 132 u8 reserved_8[9];
133} __packed; 133} __packed;
134 134
135struct wl1271;
136
135int wl1271_event_unmask(struct wl1271 *wl); 137int wl1271_event_unmask(struct wl1271 *wl);
136void wl1271_event_mbox_config(struct wl1271 *wl);
137int wl1271_event_handle(struct wl1271 *wl, u8 mbox); 138int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
138 139
139#endif 140#endif
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
new file mode 100644
index 000000000000..9384b4d56c24
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -0,0 +1,122 @@
1/*
2 * This file is part of wlcore
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#ifndef __WLCORE_HW_OPS_H__
23#define __WLCORE_HW_OPS_H__
24
25#include "wlcore.h"
26#include "rx.h"
27
28static inline u32
29wlcore_hw_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
30{
31 if (!wl->ops->calc_tx_blocks)
32 BUG_ON(1);
33
34 return wl->ops->calc_tx_blocks(wl, len, spare_blks);
35}
36
37static inline void
38wlcore_hw_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
39 u32 blks, u32 spare_blks)
40{
41 if (!wl->ops->set_tx_desc_blocks)
42 BUG_ON(1);
43
44 return wl->ops->set_tx_desc_blocks(wl, desc, blks, spare_blks);
45}
46
47static inline void
48wlcore_hw_set_tx_desc_data_len(struct wl1271 *wl,
49 struct wl1271_tx_hw_descr *desc,
50 struct sk_buff *skb)
51{
52 if (!wl->ops->set_tx_desc_data_len)
53 BUG_ON(1);
54
55 wl->ops->set_tx_desc_data_len(wl, desc, skb);
56}
57
58static inline enum wl_rx_buf_align
59wlcore_hw_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
60{
61
62 if (!wl->ops->get_rx_buf_align)
63 BUG_ON(1);
64
65 return wl->ops->get_rx_buf_align(wl, rx_desc);
66}
67
68static inline void
69wlcore_hw_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
70{
71 if (wl->ops->prepare_read)
72 wl->ops->prepare_read(wl, rx_desc, len);
73}
74
75static inline u32
76wlcore_hw_get_rx_packet_len(struct wl1271 *wl, void *rx_data, u32 data_len)
77{
78 if (!wl->ops->get_rx_packet_len)
79 BUG_ON(1);
80
81 return wl->ops->get_rx_packet_len(wl, rx_data, data_len);
82}
83
84static inline void wlcore_hw_tx_delayed_compl(struct wl1271 *wl)
85{
86 if (wl->ops->tx_delayed_compl)
87 wl->ops->tx_delayed_compl(wl);
88}
89
90static inline void wlcore_hw_tx_immediate_compl(struct wl1271 *wl)
91{
92 if (wl->ops->tx_immediate_compl)
93 wl->ops->tx_immediate_compl(wl);
94}
95
96static inline int
97wlcore_hw_init_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
98{
99 if (wl->ops->init_vif)
100 return wl->ops->init_vif(wl, wlvif);
101
102 return 0;
103}
104
105static inline u32
106wlcore_hw_sta_get_ap_rate_mask(struct wl1271 *wl, struct wl12xx_vif *wlvif)
107{
108 if (!wl->ops->sta_get_ap_rate_mask)
109 BUG_ON(1);
110
111 return wl->ops->sta_get_ap_rate_mask(wl, wlvif);
112}
113
114static inline int wlcore_identify_fw(struct wl1271 *wl)
115{
116 if (wl->ops->identify_fw)
117 return wl->ops->identify_fw(wl);
118
119 return 0;
120}
121
122#endif
diff --git a/drivers/net/wireless/wl12xx/ini.h b/drivers/net/wireless/ti/wlcore/ini.h
index 4cf9ecc56212..4cf9ecc56212 100644
--- a/drivers/net/wireless/wl12xx/ini.h
+++ b/drivers/net/wireless/ti/wlcore/ini.h
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/ti/wlcore/init.c
index 203fbebf09eb..9f89255eb6e6 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/ti/wlcore/init.c
@@ -30,9 +30,9 @@
30#include "wl12xx_80211.h" 30#include "wl12xx_80211.h"
31#include "acx.h" 31#include "acx.h"
32#include "cmd.h" 32#include "cmd.h"
33#include "reg.h"
34#include "tx.h" 33#include "tx.h"
35#include "io.h" 34#include "io.h"
35#include "hw_ops.h"
36 36
37int wl1271_init_templates_config(struct wl1271 *wl) 37int wl1271_init_templates_config(struct wl1271 *wl)
38{ 38{
@@ -319,7 +319,7 @@ static int wl12xx_init_fwlog(struct wl1271 *wl)
319{ 319{
320 int ret; 320 int ret;
321 321
322 if (wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) 322 if (wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED)
323 return 0; 323 return 0;
324 324
325 ret = wl12xx_cmd_config_fwlog(wl); 325 ret = wl12xx_cmd_config_fwlog(wl);
@@ -494,26 +494,6 @@ static int wl1271_set_ba_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
494 return wl12xx_acx_set_ba_initiator_policy(wl, wlvif); 494 return wl12xx_acx_set_ba_initiator_policy(wl, wlvif);
495} 495}
496 496
497int wl1271_chip_specific_init(struct wl1271 *wl)
498{
499 int ret = 0;
500
501 if (wl->chip.id == CHIP_ID_1283_PG20) {
502 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
503
504 if (!(wl->quirks & WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT))
505 /* Enable SDIO padding */
506 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
507
508 /* Must be before wl1271_acx_init_mem_config() */
509 ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
510 if (ret < 0)
511 goto out;
512 }
513out:
514 return ret;
515}
516
517/* vif-specifc initialization */ 497/* vif-specifc initialization */
518static int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) 498static int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
519{ 499{
@@ -582,10 +562,17 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif)
582 if (ret < 0) 562 if (ret < 0)
583 return ret; 563 return ret;
584 } else if (!wl->sta_count) { 564 } else if (!wl->sta_count) {
585 /* Configure for ELP power saving */ 565 if (wl->quirks & WLCORE_QUIRK_NO_ELP) {
586 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); 566 /* Configure for power always on */
587 if (ret < 0) 567 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
588 return ret; 568 if (ret < 0)
569 return ret;
570 } else {
571 /* Configure for ELP power saving */
572 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
573 if (ret < 0)
574 return ret;
575 }
589 } 576 }
590 } 577 }
591 578
@@ -652,6 +639,10 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif)
652 if (ret < 0) 639 if (ret < 0)
653 return ret; 640 return ret;
654 641
642 ret = wlcore_hw_init_vif(wl, wlvif);
643 if (ret < 0)
644 return ret;
645
655 return 0; 646 return 0;
656} 647}
657 648
@@ -659,27 +650,8 @@ int wl1271_hw_init(struct wl1271 *wl)
659{ 650{
660 int ret; 651 int ret;
661 652
662 if (wl->chip.id == CHIP_ID_1283_PG20) { 653 /* Chip-specific hw init */
663 ret = wl128x_cmd_general_parms(wl); 654 ret = wl->ops->hw_init(wl);
664 if (ret < 0)
665 return ret;
666 ret = wl128x_cmd_radio_parms(wl);
667 if (ret < 0)
668 return ret;
669 } else {
670 ret = wl1271_cmd_general_parms(wl);
671 if (ret < 0)
672 return ret;
673 ret = wl1271_cmd_radio_parms(wl);
674 if (ret < 0)
675 return ret;
676 ret = wl1271_cmd_ext_radio_parms(wl);
677 if (ret < 0)
678 return ret;
679 }
680
681 /* Chip-specific init */
682 ret = wl1271_chip_specific_init(wl);
683 if (ret < 0) 655 if (ret < 0)
684 return ret; 656 return ret;
685 657
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/ti/wlcore/init.h
index 2da0f404ef6e..a45fbfddec19 100644
--- a/drivers/net/wireless/wl12xx/init.h
+++ b/drivers/net/wireless/ti/wlcore/init.h
@@ -24,7 +24,7 @@
24#ifndef __INIT_H__ 24#ifndef __INIT_H__
25#define __INIT_H__ 25#define __INIT_H__
26 26
27#include "wl12xx.h" 27#include "wlcore.h"
28 28
29int wl1271_hw_init_power_auth(struct wl1271 *wl); 29int wl1271_hw_init_power_auth(struct wl1271 *wl);
30int wl1271_init_templates_config(struct wl1271 *wl); 30int wl1271_init_templates_config(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/ti/wlcore/io.c
index c574a3b31e31..7cd0081aede5 100644
--- a/drivers/net/wireless/wl12xx/io.c
+++ b/drivers/net/wireless/ti/wlcore/io.c
@@ -26,84 +26,12 @@
26#include <linux/spi/spi.h> 26#include <linux/spi/spi.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28 28
29#include "wl12xx.h" 29#include "wlcore.h"
30#include "debug.h" 30#include "debug.h"
31#include "wl12xx_80211.h" 31#include "wl12xx_80211.h"
32#include "io.h" 32#include "io.h"
33#include "tx.h" 33#include "tx.h"
34 34
35#define OCP_CMD_LOOP 32
36
37#define OCP_CMD_WRITE 0x1
38#define OCP_CMD_READ 0x2
39
40#define OCP_READY_MASK BIT(18)
41#define OCP_STATUS_MASK (BIT(16) | BIT(17))
42
43#define OCP_STATUS_NO_RESP 0x00000
44#define OCP_STATUS_OK 0x10000
45#define OCP_STATUS_REQ_FAILED 0x20000
46#define OCP_STATUS_RESP_ERROR 0x30000
47
48struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN] = {
49 [PART_DOWN] = {
50 .mem = {
51 .start = 0x00000000,
52 .size = 0x000177c0
53 },
54 .reg = {
55 .start = REGISTERS_BASE,
56 .size = 0x00008800
57 },
58 .mem2 = {
59 .start = 0x00000000,
60 .size = 0x00000000
61 },
62 .mem3 = {
63 .start = 0x00000000,
64 .size = 0x00000000
65 },
66 },
67
68 [PART_WORK] = {
69 .mem = {
70 .start = 0x00040000,
71 .size = 0x00014fc0
72 },
73 .reg = {
74 .start = REGISTERS_BASE,
75 .size = 0x0000a000
76 },
77 .mem2 = {
78 .start = 0x003004f8,
79 .size = 0x00000004
80 },
81 .mem3 = {
82 .start = 0x00040404,
83 .size = 0x00000000
84 },
85 },
86
87 [PART_DRPW] = {
88 .mem = {
89 .start = 0x00040000,
90 .size = 0x00014fc0
91 },
92 .reg = {
93 .start = DRPW_BASE,
94 .size = 0x00006000
95 },
96 .mem2 = {
97 .start = 0x00000000,
98 .size = 0x00000000
99 },
100 .mem3 = {
101 .start = 0x00000000,
102 .size = 0x00000000
103 }
104 }
105};
106
107bool wl1271_set_block_size(struct wl1271 *wl) 35bool wl1271_set_block_size(struct wl1271 *wl)
108{ 36{
109 if (wl->if_ops->set_block_size) { 37 if (wl->if_ops->set_block_size) {
@@ -114,17 +42,53 @@ bool wl1271_set_block_size(struct wl1271 *wl)
114 return false; 42 return false;
115} 43}
116 44
117void wl1271_disable_interrupts(struct wl1271 *wl) 45void wlcore_disable_interrupts(struct wl1271 *wl)
118{ 46{
119 disable_irq(wl->irq); 47 disable_irq(wl->irq);
120} 48}
49EXPORT_SYMBOL_GPL(wlcore_disable_interrupts);
121 50
122void wl1271_enable_interrupts(struct wl1271 *wl) 51void wlcore_enable_interrupts(struct wl1271 *wl)
123{ 52{
124 enable_irq(wl->irq); 53 enable_irq(wl->irq);
125} 54}
55EXPORT_SYMBOL_GPL(wlcore_enable_interrupts);
126 56
127/* Set the SPI partitions to access the chip addresses 57int wlcore_translate_addr(struct wl1271 *wl, int addr)
58{
59 struct wlcore_partition_set *part = &wl->curr_part;
60
61 /*
62 * To translate, first check to which window of addresses the
63 * particular address belongs. Then subtract the starting address
64 * of that window from the address. Then, add offset of the
65 * translated region.
66 *
67 * The translated regions occur next to each other in physical device
68 * memory, so just add the sizes of the preceding address regions to
69 * get the offset to the new region.
70 */
71 if ((addr >= part->mem.start) &&
72 (addr < part->mem.start + part->mem.size))
73 return addr - part->mem.start;
74 else if ((addr >= part->reg.start) &&
75 (addr < part->reg.start + part->reg.size))
76 return addr - part->reg.start + part->mem.size;
77 else if ((addr >= part->mem2.start) &&
78 (addr < part->mem2.start + part->mem2.size))
79 return addr - part->mem2.start + part->mem.size +
80 part->reg.size;
81 else if ((addr >= part->mem3.start) &&
82 (addr < part->mem3.start + part->mem3.size))
83 return addr - part->mem3.start + part->mem.size +
84 part->reg.size + part->mem2.size;
85
86 WARN(1, "HW address 0x%x out of range", addr);
87 return 0;
88}
89EXPORT_SYMBOL_GPL(wlcore_translate_addr);
90
91/* Set the partitions to access the chip addresses
128 * 92 *
129 * To simplify driver code, a fixed (virtual) memory map is defined for 93 * To simplify driver code, a fixed (virtual) memory map is defined for
130 * register and memory addresses. Because in the chipset, in different stages 94 * register and memory addresses. Because in the chipset, in different stages
@@ -158,33 +122,43 @@ void wl1271_enable_interrupts(struct wl1271 *wl)
158 * | | 122 * | |
159 * 123 *
160 */ 124 */
161int wl1271_set_partition(struct wl1271 *wl, 125void wlcore_set_partition(struct wl1271 *wl,
162 struct wl1271_partition_set *p) 126 const struct wlcore_partition_set *p)
163{ 127{
164 /* copy partition info */ 128 /* copy partition info */
165 memcpy(&wl->part, p, sizeof(*p)); 129 memcpy(&wl->curr_part, p, sizeof(*p));
166 130
167 wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", 131 wl1271_debug(DEBUG_IO, "mem_start %08X mem_size %08X",
168 p->mem.start, p->mem.size); 132 p->mem.start, p->mem.size);
169 wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", 133 wl1271_debug(DEBUG_IO, "reg_start %08X reg_size %08X",
170 p->reg.start, p->reg.size); 134 p->reg.start, p->reg.size);
171 wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X", 135 wl1271_debug(DEBUG_IO, "mem2_start %08X mem2_size %08X",
172 p->mem2.start, p->mem2.size); 136 p->mem2.start, p->mem2.size);
173 wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X", 137 wl1271_debug(DEBUG_IO, "mem3_start %08X mem3_size %08X",
174 p->mem3.start, p->mem3.size); 138 p->mem3.start, p->mem3.size);
175 139
176 /* write partition info to the chipset */
177 wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); 140 wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);
178 wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); 141 wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
179 wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); 142 wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);
180 wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); 143 wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
181 wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); 144 wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
182 wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); 145 wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
146 /*
147 * We don't need the size of the last partition, as it is
148 * automatically calculated based on the total memory size and
149 * the sizes of the previous partitions.
150 */
183 wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); 151 wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
152}
153EXPORT_SYMBOL_GPL(wlcore_set_partition);
184 154
185 return 0; 155void wlcore_select_partition(struct wl1271 *wl, u8 part)
156{
157 wl1271_debug(DEBUG_IO, "setting partition %d", part);
158
159 wlcore_set_partition(wl, &wl->ptable[part]);
186} 160}
187EXPORT_SYMBOL_GPL(wl1271_set_partition); 161EXPORT_SYMBOL_GPL(wlcore_select_partition);
188 162
189void wl1271_io_reset(struct wl1271 *wl) 163void wl1271_io_reset(struct wl1271 *wl)
190{ 164{
@@ -197,48 +171,3 @@ void wl1271_io_init(struct wl1271 *wl)
197 if (wl->if_ops->init) 171 if (wl->if_ops->init)
198 wl->if_ops->init(wl->dev); 172 wl->if_ops->init(wl->dev);
199} 173}
200
201void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
202{
203 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
204 addr = (addr >> 1) + 0x30000;
205 wl1271_write32(wl, OCP_POR_CTR, addr);
206
207 /* write value to OCP_POR_WDATA */
208 wl1271_write32(wl, OCP_DATA_WRITE, val);
209
210 /* write 1 to OCP_CMD */
211 wl1271_write32(wl, OCP_CMD, OCP_CMD_WRITE);
212}
213
214u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
215{
216 u32 val;
217 int timeout = OCP_CMD_LOOP;
218
219 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
220 addr = (addr >> 1) + 0x30000;
221 wl1271_write32(wl, OCP_POR_CTR, addr);
222
223 /* write 2 to OCP_CMD */
224 wl1271_write32(wl, OCP_CMD, OCP_CMD_READ);
225
226 /* poll for data ready */
227 do {
228 val = wl1271_read32(wl, OCP_DATA_READ);
229 } while (!(val & OCP_READY_MASK) && --timeout);
230
231 if (!timeout) {
232 wl1271_warning("Top register access timed out.");
233 return 0xffff;
234 }
235
236 /* check data status and return if OK */
237 if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
238 return val & 0xffff;
239 else {
240 wl1271_warning("Top register access returned error.");
241 return 0xffff;
242 }
243}
244
diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/ti/wlcore/io.h
index 4fb3dab8c3b2..8942954b56a0 100644
--- a/drivers/net/wireless/wl12xx/io.h
+++ b/drivers/net/wireless/ti/wlcore/io.h
@@ -26,7 +26,6 @@
26#define __IO_H__ 26#define __IO_H__
27 27
28#include <linux/irqreturn.h> 28#include <linux/irqreturn.h>
29#include "reg.h"
30 29
31#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 30#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
32 31
@@ -43,15 +42,14 @@
43 42
44#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 43#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
45 44
46extern struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN];
47
48struct wl1271; 45struct wl1271;
49 46
50void wl1271_disable_interrupts(struct wl1271 *wl); 47void wlcore_disable_interrupts(struct wl1271 *wl);
51void wl1271_enable_interrupts(struct wl1271 *wl); 48void wlcore_enable_interrupts(struct wl1271 *wl);
52 49
53void wl1271_io_reset(struct wl1271 *wl); 50void wl1271_io_reset(struct wl1271 *wl);
54void wl1271_io_init(struct wl1271 *wl); 51void wl1271_io_init(struct wl1271 *wl);
52int wlcore_translate_addr(struct wl1271 *wl, int addr);
55 53
56/* Raw target IO, address is not translated */ 54/* Raw target IO, address is not translated */
57static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, 55static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
@@ -66,6 +64,18 @@ static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
66 wl->if_ops->read(wl->dev, addr, buf, len, fixed); 64 wl->if_ops->read(wl->dev, addr, buf, len, fixed);
67} 65}
68 66
67static inline void wlcore_raw_read_data(struct wl1271 *wl, int reg, void *buf,
68 size_t len, bool fixed)
69{
70 wl1271_raw_read(wl, wl->rtable[reg], buf, len, fixed);
71}
72
73static inline void wlcore_raw_write_data(struct wl1271 *wl, int reg, void *buf,
74 size_t len, bool fixed)
75{
76 wl1271_raw_write(wl, wl->rtable[reg], buf, len, fixed);
77}
78
69static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) 79static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
70{ 80{
71 wl1271_raw_read(wl, addr, &wl->buffer_32, 81 wl1271_raw_read(wl, addr, &wl->buffer_32,
@@ -81,36 +91,12 @@ static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
81 sizeof(wl->buffer_32), false); 91 sizeof(wl->buffer_32), false);
82} 92}
83 93
84/* Translated target IO */
85static inline int wl1271_translate_addr(struct wl1271 *wl, int addr)
86{
87 /*
88 * To translate, first check to which window of addresses the
89 * particular address belongs. Then subtract the starting address
90 * of that window from the address. Then, add offset of the
91 * translated region.
92 *
93 * The translated regions occur next to each other in physical device
94 * memory, so just add the sizes of the preceding address regions to
95 * get the offset to the new region.
96 *
97 * Currently, only the two first regions are addressed, and the
98 * assumption is that all addresses will fall into either of those
99 * two.
100 */
101 if ((addr >= wl->part.reg.start) &&
102 (addr < wl->part.reg.start + wl->part.reg.size))
103 return addr - wl->part.reg.start + wl->part.mem.size;
104 else
105 return addr - wl->part.mem.start;
106}
107
108static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf, 94static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf,
109 size_t len, bool fixed) 95 size_t len, bool fixed)
110{ 96{
111 int physical; 97 int physical;
112 98
113 physical = wl1271_translate_addr(wl, addr); 99 physical = wlcore_translate_addr(wl, addr);
114 100
115 wl1271_raw_read(wl, physical, buf, len, fixed); 101 wl1271_raw_read(wl, physical, buf, len, fixed);
116} 102}
@@ -120,11 +106,23 @@ static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf,
120{ 106{
121 int physical; 107 int physical;
122 108
123 physical = wl1271_translate_addr(wl, addr); 109 physical = wlcore_translate_addr(wl, addr);
124 110
125 wl1271_raw_write(wl, physical, buf, len, fixed); 111 wl1271_raw_write(wl, physical, buf, len, fixed);
126} 112}
127 113
114static inline void wlcore_write_data(struct wl1271 *wl, int reg, void *buf,
115 size_t len, bool fixed)
116{
117 wl1271_write(wl, wl->rtable[reg], buf, len, fixed);
118}
119
120static inline void wlcore_read_data(struct wl1271 *wl, int reg, void *buf,
121 size_t len, bool fixed)
122{
123 wl1271_read(wl, wl->rtable[reg], buf, len, fixed);
124}
125
128static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr, 126static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr,
129 void *buf, size_t len, bool fixed) 127 void *buf, size_t len, bool fixed)
130{ 128{
@@ -134,19 +132,30 @@ static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr,
134 /* Addresses are stored internally as addresses to 32 bytes blocks */ 132 /* Addresses are stored internally as addresses to 32 bytes blocks */
135 addr = hwaddr << 5; 133 addr = hwaddr << 5;
136 134
137 physical = wl1271_translate_addr(wl, addr); 135 physical = wlcore_translate_addr(wl, addr);
138 136
139 wl1271_raw_read(wl, physical, buf, len, fixed); 137 wl1271_raw_read(wl, physical, buf, len, fixed);
140} 138}
141 139
142static inline u32 wl1271_read32(struct wl1271 *wl, int addr) 140static inline u32 wl1271_read32(struct wl1271 *wl, int addr)
143{ 141{
144 return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr)); 142 return wl1271_raw_read32(wl, wlcore_translate_addr(wl, addr));
145} 143}
146 144
147static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) 145static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
148{ 146{
149 wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); 147 wl1271_raw_write32(wl, wlcore_translate_addr(wl, addr), val);
148}
149
150static inline u32 wlcore_read_reg(struct wl1271 *wl, int reg)
151{
152 return wl1271_raw_read32(wl,
153 wlcore_translate_addr(wl, wl->rtable[reg]));
154}
155
156static inline void wlcore_write_reg(struct wl1271 *wl, int reg, u32 val)
157{
158 wl1271_raw_write32(wl, wlcore_translate_addr(wl, wl->rtable[reg]), val);
150} 159}
151 160
152static inline void wl1271_power_off(struct wl1271 *wl) 161static inline void wl1271_power_off(struct wl1271 *wl)
@@ -164,13 +173,8 @@ static inline int wl1271_power_on(struct wl1271 *wl)
164 return ret; 173 return ret;
165} 174}
166 175
167 176void wlcore_set_partition(struct wl1271 *wl,
168/* Top Register IO */ 177 const struct wlcore_partition_set *p);
169void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
170u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
171
172int wl1271_set_partition(struct wl1271 *wl,
173 struct wl1271_partition_set *p);
174 178
175bool wl1271_set_block_size(struct wl1271 *wl); 179bool wl1271_set_block_size(struct wl1271 *wl);
176 180
@@ -178,4 +182,6 @@ bool wl1271_set_block_size(struct wl1271 *wl);
178 182
179int wl1271_tx_dummy_packet(struct wl1271 *wl); 183int wl1271_tx_dummy_packet(struct wl1271 *wl);
180 184
185void wlcore_select_partition(struct wl1271 *wl, u8 part);
186
181#endif 187#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 362ff1a7067e..2b0f987660c6 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -35,10 +35,9 @@
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37 37
38#include "wl12xx.h" 38#include "wlcore.h"
39#include "debug.h" 39#include "debug.h"
40#include "wl12xx_80211.h" 40#include "wl12xx_80211.h"
41#include "reg.h"
42#include "io.h" 41#include "io.h"
43#include "event.h" 42#include "event.h"
44#include "tx.h" 43#include "tx.h"
@@ -50,342 +49,15 @@
50#include "boot.h" 49#include "boot.h"
51#include "testmode.h" 50#include "testmode.h"
52#include "scan.h" 51#include "scan.h"
52#include "hw_ops.h"
53 53
54#define WL1271_BOOT_RETRIES 3 54#define WL1271_BOOT_RETRIES 3
55 55
56static struct conf_drv_settings default_conf = { 56#define WL1271_BOOT_RETRIES 3
57 .sg = {
58 .params = {
59 [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
60 [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
61 [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
62 [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
63 [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
64 [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
65 [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
66 [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
67 [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
68 [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
69 [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
70 [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
71 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
72 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
73 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
74 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
75 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
76 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
77 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
78 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
79 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
80 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
81 [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
82 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
83 [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
84 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
85 /* active scan params */
86 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
87 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
88 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
89 /* passive scan params */
90 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
91 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
92 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
93 /* passive scan in dual antenna params */
94 [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
95 [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
96 [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
97 /* general params */
98 [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
99 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
100 [CONF_SG_BEACON_MISS_PERCENT] = 60,
101 [CONF_SG_DHCP_TIME] = 5000,
102 [CONF_SG_RXT] = 1200,
103 [CONF_SG_TXT] = 1000,
104 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
105 [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
106 [CONF_SG_HV3_MAX_SERVED] = 6,
107 [CONF_SG_PS_POLL_TIMEOUT] = 10,
108 [CONF_SG_UPSD_TIMEOUT] = 10,
109 [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
110 [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
111 [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
112 /* AP params */
113 [CONF_AP_BEACON_MISS_TX] = 3,
114 [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
115 [CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
116 [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
117 [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
118 [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
119 /* CTS Diluting params */
120 [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
121 [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
122 },
123 .state = CONF_SG_PROTECTIVE,
124 },
125 .rx = {
126 .rx_msdu_life_time = 512000,
127 .packet_detection_threshold = 0,
128 .ps_poll_timeout = 15,
129 .upsd_timeout = 15,
130 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
131 .rx_cca_threshold = 0,
132 .irq_blk_threshold = 0xFFFF,
133 .irq_pkt_threshold = 0,
134 .irq_timeout = 600,
135 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
136 },
137 .tx = {
138 .tx_energy_detection = 0,
139 .sta_rc_conf = {
140 .enabled_rates = 0,
141 .short_retry_limit = 10,
142 .long_retry_limit = 10,
143 .aflags = 0,
144 },
145 .ac_conf_count = 4,
146 .ac_conf = {
147 [CONF_TX_AC_BE] = {
148 .ac = CONF_TX_AC_BE,
149 .cw_min = 15,
150 .cw_max = 63,
151 .aifsn = 3,
152 .tx_op_limit = 0,
153 },
154 [CONF_TX_AC_BK] = {
155 .ac = CONF_TX_AC_BK,
156 .cw_min = 15,
157 .cw_max = 63,
158 .aifsn = 7,
159 .tx_op_limit = 0,
160 },
161 [CONF_TX_AC_VI] = {
162 .ac = CONF_TX_AC_VI,
163 .cw_min = 15,
164 .cw_max = 63,
165 .aifsn = CONF_TX_AIFS_PIFS,
166 .tx_op_limit = 3008,
167 },
168 [CONF_TX_AC_VO] = {
169 .ac = CONF_TX_AC_VO,
170 .cw_min = 15,
171 .cw_max = 63,
172 .aifsn = CONF_TX_AIFS_PIFS,
173 .tx_op_limit = 1504,
174 },
175 },
176 .max_tx_retries = 100,
177 .ap_aging_period = 300,
178 .tid_conf_count = 4,
179 .tid_conf = {
180 [CONF_TX_AC_BE] = {
181 .queue_id = CONF_TX_AC_BE,
182 .channel_type = CONF_CHANNEL_TYPE_EDCF,
183 .tsid = CONF_TX_AC_BE,
184 .ps_scheme = CONF_PS_SCHEME_LEGACY,
185 .ack_policy = CONF_ACK_POLICY_LEGACY,
186 .apsd_conf = {0, 0},
187 },
188 [CONF_TX_AC_BK] = {
189 .queue_id = CONF_TX_AC_BK,
190 .channel_type = CONF_CHANNEL_TYPE_EDCF,
191 .tsid = CONF_TX_AC_BK,
192 .ps_scheme = CONF_PS_SCHEME_LEGACY,
193 .ack_policy = CONF_ACK_POLICY_LEGACY,
194 .apsd_conf = {0, 0},
195 },
196 [CONF_TX_AC_VI] = {
197 .queue_id = CONF_TX_AC_VI,
198 .channel_type = CONF_CHANNEL_TYPE_EDCF,
199 .tsid = CONF_TX_AC_VI,
200 .ps_scheme = CONF_PS_SCHEME_LEGACY,
201 .ack_policy = CONF_ACK_POLICY_LEGACY,
202 .apsd_conf = {0, 0},
203 },
204 [CONF_TX_AC_VO] = {
205 .queue_id = CONF_TX_AC_VO,
206 .channel_type = CONF_CHANNEL_TYPE_EDCF,
207 .tsid = CONF_TX_AC_VO,
208 .ps_scheme = CONF_PS_SCHEME_LEGACY,
209 .ack_policy = CONF_ACK_POLICY_LEGACY,
210 .apsd_conf = {0, 0},
211 },
212 },
213 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
214 .tx_compl_timeout = 700,
215 .tx_compl_threshold = 4,
216 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
217 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
218 .tmpl_short_retry_limit = 10,
219 .tmpl_long_retry_limit = 10,
220 .tx_watchdog_timeout = 5000,
221 },
222 .conn = {
223 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
224 .listen_interval = 1,
225 .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
226 .suspend_listen_interval = 3,
227 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
228 .bcn_filt_ie_count = 2,
229 .bcn_filt_ie = {
230 [0] = {
231 .ie = WLAN_EID_CHANNEL_SWITCH,
232 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
233 },
234 [1] = {
235 .ie = WLAN_EID_HT_OPERATION,
236 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
237 },
238 },
239 .synch_fail_thold = 10,
240 .bss_lose_timeout = 100,
241 .beacon_rx_timeout = 10000,
242 .broadcast_timeout = 20000,
243 .rx_broadcast_in_ps = 1,
244 .ps_poll_threshold = 10,
245 .bet_enable = CONF_BET_MODE_ENABLE,
246 .bet_max_consecutive = 50,
247 .psm_entry_retries = 8,
248 .psm_exit_retries = 16,
249 .psm_entry_nullfunc_retries = 3,
250 .dynamic_ps_timeout = 200,
251 .forced_ps = false,
252 .keep_alive_interval = 55000,
253 .max_listen_interval = 20,
254 },
255 .itrim = {
256 .enable = false,
257 .timeout = 50000,
258 },
259 .pm_config = {
260 .host_clk_settling_time = 5000,
261 .host_fast_wakeup_support = false
262 },
263 .roam_trigger = {
264 .trigger_pacing = 1,
265 .avg_weight_rssi_beacon = 20,
266 .avg_weight_rssi_data = 10,
267 .avg_weight_snr_beacon = 20,
268 .avg_weight_snr_data = 10,
269 },
270 .scan = {
271 .min_dwell_time_active = 7500,
272 .max_dwell_time_active = 30000,
273 .min_dwell_time_passive = 100000,
274 .max_dwell_time_passive = 100000,
275 .num_probe_reqs = 2,
276 .split_scan_timeout = 50000,
277 },
278 .sched_scan = {
279 /* sched_scan requires dwell times in TU instead of TU/1000 */
280 .min_dwell_time_active = 30,
281 .max_dwell_time_active = 60,
282 .dwell_time_passive = 100,
283 .dwell_time_dfs = 150,
284 .num_probe_reqs = 2,
285 .rssi_threshold = -90,
286 .snr_threshold = 0,
287 },
288 .rf = {
289 .tx_per_channel_power_compensation_2 = {
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 },
292 .tx_per_channel_power_compensation_5 = {
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 },
297 },
298 .ht = {
299 .rx_ba_win_size = 8,
300 .tx_ba_win_size = 64,
301 .inactivity_timeout = 10000,
302 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
303 },
304 .mem_wl127x = {
305 .num_stations = 1,
306 .ssid_profiles = 1,
307 .rx_block_num = 70,
308 .tx_min_block_num = 40,
309 .dynamic_memory = 1,
310 .min_req_tx_blocks = 100,
311 .min_req_rx_blocks = 22,
312 .tx_min = 27,
313 },
314 .mem_wl128x = {
315 .num_stations = 1,
316 .ssid_profiles = 1,
317 .rx_block_num = 40,
318 .tx_min_block_num = 40,
319 .dynamic_memory = 1,
320 .min_req_tx_blocks = 45,
321 .min_req_rx_blocks = 22,
322 .tx_min = 27,
323 },
324 .fm_coex = {
325 .enable = true,
326 .swallow_period = 5,
327 .n_divider_fref_set_1 = 0xff, /* default */
328 .n_divider_fref_set_2 = 12,
329 .m_divider_fref_set_1 = 148,
330 .m_divider_fref_set_2 = 0xffff, /* default */
331 .coex_pll_stabilization_time = 0xffffffff, /* default */
332 .ldo_stabilization_time = 0xffff, /* default */
333 .fm_disturbed_band_margin = 0xff, /* default */
334 .swallow_clk_diff = 0xff, /* default */
335 },
336 .rx_streaming = {
337 .duration = 150,
338 .queues = 0x1,
339 .interval = 20,
340 .always = 0,
341 },
342 .fwlog = {
343 .mode = WL12XX_FWLOG_ON_DEMAND,
344 .mem_blocks = 2,
345 .severity = 0,
346 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
347 .output = WL12XX_FWLOG_OUTPUT_HOST,
348 .threshold = 0,
349 },
350 .hci_io_ds = HCI_IO_DS_6MA,
351 .rate = {
352 .rate_retry_score = 32000,
353 .per_add = 8192,
354 .per_th1 = 2048,
355 .per_th2 = 4096,
356 .max_per = 8100,
357 .inverse_curiosity_factor = 5,
358 .tx_fail_low_th = 4,
359 .tx_fail_high_th = 10,
360 .per_alpha_shift = 4,
361 .per_add_shift = 13,
362 .per_beta1_shift = 10,
363 .per_beta2_shift = 8,
364 .rate_check_up = 2,
365 .rate_check_down = 12,
366 .rate_retry_policy = {
367 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00,
370 },
371 },
372 .hangover = {
373 .recover_time = 0,
374 .hangover_period = 20,
375 .dynamic_mode = 1,
376 .early_termination_mode = 1,
377 .max_period = 20,
378 .min_period = 1,
379 .increase_delta = 1,
380 .decrease_delta = 2,
381 .quiet_time = 4,
382 .increase_time = 1,
383 .window_size = 16,
384 },
385};
386 57
387static char *fwlog_param; 58static char *fwlog_param;
388static bool bug_on_recovery; 59static bool bug_on_recovery;
60static bool no_recovery;
389 61
390static void __wl1271_op_remove_interface(struct wl1271 *wl, 62static void __wl1271_op_remove_interface(struct wl1271 *wl,
391 struct ieee80211_vif *vif, 63 struct ieee80211_vif *vif,
@@ -628,22 +300,8 @@ out:
628 mutex_unlock(&wl->mutex); 300 mutex_unlock(&wl->mutex);
629} 301}
630 302
631static void wl1271_conf_init(struct wl1271 *wl) 303static void wlcore_adjust_conf(struct wl1271 *wl)
632{ 304{
633
634 /*
635 * This function applies the default configuration to the driver. This
636 * function is invoked upon driver load (spi probe.)
637 *
638 * The configuration is stored in a run-time structure in order to
639 * facilitate for run-time adjustment of any of the parameters. Making
640 * changes to the configuration structure will apply the new values on
641 * the next interface up (wl1271_op_start.)
642 */
643
644 /* apply driver default configuration */
645 memcpy(&wl->conf, &default_conf, sizeof(default_conf));
646
647 /* Adjust settings according to optional module parameters */ 305 /* Adjust settings according to optional module parameters */
648 if (fwlog_param) { 306 if (fwlog_param) {
649 if (!strcmp(fwlog_param, "continuous")) { 307 if (!strcmp(fwlog_param, "continuous")) {
@@ -666,28 +324,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
666{ 324{
667 int ret; 325 int ret;
668 326
669 if (wl->chip.id == CHIP_ID_1283_PG20) 327 ret = wl->ops->hw_init(wl);
670 ret = wl128x_cmd_general_parms(wl);
671 else
672 ret = wl1271_cmd_general_parms(wl);
673 if (ret < 0)
674 return ret;
675
676 if (wl->chip.id == CHIP_ID_1283_PG20)
677 ret = wl128x_cmd_radio_parms(wl);
678 else
679 ret = wl1271_cmd_radio_parms(wl);
680 if (ret < 0)
681 return ret;
682
683 if (wl->chip.id != CHIP_ID_1283_PG20) {
684 ret = wl1271_cmd_ext_radio_parms(wl);
685 if (ret < 0)
686 return ret;
687 }
688
689 /* Chip-specific initializations */
690 ret = wl1271_chip_specific_init(wl);
691 if (ret < 0) 328 if (ret < 0)
692 return ret; 329 return ret;
693 330
@@ -750,7 +387,7 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
750 387
751static void wl12xx_irq_update_links_status(struct wl1271 *wl, 388static void wl12xx_irq_update_links_status(struct wl1271 *wl,
752 struct wl12xx_vif *wlvif, 389 struct wl12xx_vif *wlvif,
753 struct wl12xx_fw_status *status) 390 struct wl_fw_status *status)
754{ 391{
755 struct wl1271_link *lnk; 392 struct wl1271_link *lnk;
756 u32 cur_fw_ps_map; 393 u32 cur_fw_ps_map;
@@ -770,9 +407,10 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
770 407
771 for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) { 408 for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) {
772 lnk = &wl->links[hlid]; 409 lnk = &wl->links[hlid];
773 cnt = status->tx_lnk_free_pkts[hlid] - lnk->prev_freed_pkts; 410 cnt = status->counters.tx_lnk_free_pkts[hlid] -
411 lnk->prev_freed_pkts;
774 412
775 lnk->prev_freed_pkts = status->tx_lnk_free_pkts[hlid]; 413 lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[hlid];
776 lnk->allocated_pkts -= cnt; 414 lnk->allocated_pkts -= cnt;
777 415
778 wl12xx_irq_ps_regulate_link(wl, wlvif, hlid, 416 wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
@@ -781,15 +419,19 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
781} 419}
782 420
783static void wl12xx_fw_status(struct wl1271 *wl, 421static void wl12xx_fw_status(struct wl1271 *wl,
784 struct wl12xx_fw_status *status) 422 struct wl_fw_status *status)
785{ 423{
786 struct wl12xx_vif *wlvif; 424 struct wl12xx_vif *wlvif;
787 struct timespec ts; 425 struct timespec ts;
788 u32 old_tx_blk_count = wl->tx_blocks_available; 426 u32 old_tx_blk_count = wl->tx_blocks_available;
789 int avail, freed_blocks; 427 int avail, freed_blocks;
790 int i; 428 int i;
429 size_t status_len;
430
431 status_len = sizeof(*status) + wl->fw_status_priv_len;
791 432
792 wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); 433 wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status,
434 status_len, false);
793 435
794 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " 436 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
795 "drv_rx_counter = %d, tx_results_counter = %d)", 437 "drv_rx_counter = %d, tx_results_counter = %d)",
@@ -801,10 +443,10 @@ static void wl12xx_fw_status(struct wl1271 *wl,
801 for (i = 0; i < NUM_TX_QUEUES; i++) { 443 for (i = 0; i < NUM_TX_QUEUES; i++) {
802 /* prevent wrap-around in freed-packets counter */ 444 /* prevent wrap-around in freed-packets counter */
803 wl->tx_allocated_pkts[i] -= 445 wl->tx_allocated_pkts[i] -=
804 (status->tx_released_pkts[i] - 446 (status->counters.tx_released_pkts[i] -
805 wl->tx_pkts_freed[i]) & 0xff; 447 wl->tx_pkts_freed[i]) & 0xff;
806 448
807 wl->tx_pkts_freed[i] = status->tx_released_pkts[i]; 449 wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i];
808 } 450 }
809 451
810 /* prevent wrap-around in total blocks counter */ 452 /* prevent wrap-around in total blocks counter */
@@ -927,6 +569,9 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
927 smp_mb__after_clear_bit(); 569 smp_mb__after_clear_bit();
928 570
929 wl12xx_fw_status(wl, wl->fw_status); 571 wl12xx_fw_status(wl, wl->fw_status);
572
573 wlcore_hw_tx_immediate_compl(wl);
574
930 intr = le32_to_cpu(wl->fw_status->intr); 575 intr = le32_to_cpu(wl->fw_status->intr);
931 intr &= WL1271_INTR_MASK; 576 intr &= WL1271_INTR_MASK;
932 if (!intr) { 577 if (!intr) {
@@ -963,9 +608,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
963 } 608 }
964 609
965 /* check for tx results */ 610 /* check for tx results */
966 if (wl->fw_status->tx_results_counter != 611 wlcore_hw_tx_delayed_compl(wl);
967 (wl->tx_results_count & 0xff))
968 wl1271_tx_complete(wl);
969 612
970 /* Make sure the deferred queues don't get too long */ 613 /* Make sure the deferred queues don't get too long */
971 defer_count = skb_queue_len(&wl->deferred_tx_queue) + 614 defer_count = skb_queue_len(&wl->deferred_tx_queue) +
@@ -1046,10 +689,7 @@ static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
1046 689
1047 if (plt) { 690 if (plt) {
1048 fw_type = WL12XX_FW_TYPE_PLT; 691 fw_type = WL12XX_FW_TYPE_PLT;
1049 if (wl->chip.id == CHIP_ID_1283_PG20) 692 fw_name = wl->plt_fw_name;
1050 fw_name = WL128X_PLT_FW_NAME;
1051 else
1052 fw_name = WL127X_PLT_FW_NAME;
1053 } else { 693 } else {
1054 /* 694 /*
1055 * we can't call wl12xx_get_vif_count() here because 695 * we can't call wl12xx_get_vif_count() here because
@@ -1057,16 +697,10 @@ static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
1057 */ 697 */
1058 if (wl->last_vif_count > 1) { 698 if (wl->last_vif_count > 1) {
1059 fw_type = WL12XX_FW_TYPE_MULTI; 699 fw_type = WL12XX_FW_TYPE_MULTI;
1060 if (wl->chip.id == CHIP_ID_1283_PG20) 700 fw_name = wl->mr_fw_name;
1061 fw_name = WL128X_FW_NAME_MULTI;
1062 else
1063 fw_name = WL127X_FW_NAME_MULTI;
1064 } else { 701 } else {
1065 fw_type = WL12XX_FW_TYPE_NORMAL; 702 fw_type = WL12XX_FW_TYPE_NORMAL;
1066 if (wl->chip.id == CHIP_ID_1283_PG20) 703 fw_name = wl->sr_fw_name;
1067 fw_name = WL128X_FW_NAME_SINGLE;
1068 else
1069 fw_name = WL127X_FW_NAME_SINGLE;
1070 } 704 }
1071 } 705 }
1072 706
@@ -1173,7 +807,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
1173 u32 first_addr; 807 u32 first_addr;
1174 u8 *block; 808 u8 *block;
1175 809
1176 if ((wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) || 810 if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
1177 (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) || 811 (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) ||
1178 (wl->conf.fwlog.mem_blocks == 0)) 812 (wl->conf.fwlog.mem_blocks == 0))
1179 return; 813 return;
@@ -1239,11 +873,20 @@ static void wl1271_recovery_work(struct work_struct *work)
1239 wl12xx_read_fwlog_panic(wl); 873 wl12xx_read_fwlog_panic(wl);
1240 874
1241 wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", 875 wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
1242 wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); 876 wl->chip.fw_ver_str,
877 wlcore_read_reg(wl, REG_PC_ON_RECOVERY));
1243 878
1244 BUG_ON(bug_on_recovery && 879 BUG_ON(bug_on_recovery &&
1245 !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); 880 !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
1246 881
882 if (no_recovery) {
883 wl1271_info("No recovery (chosen on module load). Fw will remain stuck.");
884 clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
885 goto out_unlock;
886 }
887
888 BUG_ON(bug_on_recovery);
889
1247 /* 890 /*
1248 * Advance security sequence number to overcome potential progress 891 * Advance security sequence number to overcome potential progress
1249 * in the firmware during recovery. This doens't hurt if the network is 892 * in the firmware during recovery. This doens't hurt if the network is
@@ -1290,10 +933,7 @@ out_unlock:
1290 933
1291static void wl1271_fw_wakeup(struct wl1271 *wl) 934static void wl1271_fw_wakeup(struct wl1271 *wl)
1292{ 935{
1293 u32 elp_reg; 936 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
1294
1295 elp_reg = ELPCTRL_WAKE_UP;
1296 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
1297} 937}
1298 938
1299static int wl1271_setup(struct wl1271 *wl) 939static int wl1271_setup(struct wl1271 *wl)
@@ -1323,7 +963,7 @@ static int wl12xx_set_power_on(struct wl1271 *wl)
1323 wl1271_io_reset(wl); 963 wl1271_io_reset(wl);
1324 wl1271_io_init(wl); 964 wl1271_io_init(wl);
1325 965
1326 wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]); 966 wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
1327 967
1328 /* ELP module wake up */ 968 /* ELP module wake up */
1329 wl1271_fw_wakeup(wl); 969 wl1271_fw_wakeup(wl);
@@ -1348,44 +988,18 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
1348 * negligible, we use the same block size for all different 988 * negligible, we use the same block size for all different
1349 * chip types. 989 * chip types.
1350 */ 990 */
1351 if (!wl1271_set_block_size(wl)) 991 if (wl1271_set_block_size(wl))
1352 wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT; 992 wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN;
1353
1354 switch (wl->chip.id) {
1355 case CHIP_ID_1271_PG10:
1356 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
1357 wl->chip.id);
1358 993
1359 ret = wl1271_setup(wl); 994 ret = wl->ops->identify_chip(wl);
1360 if (ret < 0) 995 if (ret < 0)
1361 goto out; 996 goto out;
1362 wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
1363 break;
1364
1365 case CHIP_ID_1271_PG20:
1366 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
1367 wl->chip.id);
1368
1369 ret = wl1271_setup(wl);
1370 if (ret < 0)
1371 goto out;
1372 wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
1373 break;
1374 997
1375 case CHIP_ID_1283_PG20: 998 /* TODO: make sure the lower driver has set things up correctly */
1376 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
1377 wl->chip.id);
1378 999
1379 ret = wl1271_setup(wl); 1000 ret = wl1271_setup(wl);
1380 if (ret < 0) 1001 if (ret < 0)
1381 goto out;
1382 break;
1383 case CHIP_ID_1283_PG10:
1384 default:
1385 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
1386 ret = -ENODEV;
1387 goto out; 1002 goto out;
1388 }
1389 1003
1390 ret = wl12xx_fetch_firmware(wl, plt); 1004 ret = wl12xx_fetch_firmware(wl, plt);
1391 if (ret < 0) 1005 if (ret < 0)
@@ -1425,7 +1039,7 @@ int wl1271_plt_start(struct wl1271 *wl)
1425 if (ret < 0) 1039 if (ret < 0)
1426 goto power_off; 1040 goto power_off;
1427 1041
1428 ret = wl1271_boot(wl); 1042 ret = wl->ops->boot(wl);
1429 if (ret < 0) 1043 if (ret < 0)
1430 goto power_off; 1044 goto power_off;
1431 1045
@@ -1454,7 +1068,7 @@ irq_disable:
1454 work function will not do anything.) Also, any other 1068 work function will not do anything.) Also, any other
1455 possible concurrent operations will fail due to the 1069 possible concurrent operations will fail due to the
1456 current state, hence the wl1271 struct should be safe. */ 1070 current state, hence the wl1271 struct should be safe. */
1457 wl1271_disable_interrupts(wl); 1071 wlcore_disable_interrupts(wl);
1458 wl1271_flush_deferred_work(wl); 1072 wl1271_flush_deferred_work(wl);
1459 cancel_work_sync(&wl->netstack_work); 1073 cancel_work_sync(&wl->netstack_work);
1460 mutex_lock(&wl->mutex); 1074 mutex_lock(&wl->mutex);
@@ -1481,7 +1095,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
1481 * Otherwise, the interrupt handler might be called and exit without 1095 * Otherwise, the interrupt handler might be called and exit without
1482 * reading the interrupt status. 1096 * reading the interrupt status.
1483 */ 1097 */
1484 wl1271_disable_interrupts(wl); 1098 wlcore_disable_interrupts(wl);
1485 mutex_lock(&wl->mutex); 1099 mutex_lock(&wl->mutex);
1486 if (!wl->plt) { 1100 if (!wl->plt) {
1487 mutex_unlock(&wl->mutex); 1101 mutex_unlock(&wl->mutex);
@@ -1491,7 +1105,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
1491 * may have been disabled when op_stop was called. It will, 1105 * may have been disabled when op_stop was called. It will,
1492 * however, balance the above call to disable_interrupts(). 1106 * however, balance the above call to disable_interrupts().
1493 */ 1107 */
1494 wl1271_enable_interrupts(wl); 1108 wlcore_enable_interrupts(wl);
1495 1109
1496 wl1271_error("cannot power down because not in PLT " 1110 wl1271_error("cannot power down because not in PLT "
1497 "state: %d", wl->state); 1111 "state: %d", wl->state);
@@ -1652,14 +1266,12 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1652{ 1266{
1653 int ret = 0; 1267 int ret = 0;
1654 1268
1655 mutex_lock(&wl->mutex);
1656
1657 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 1269 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1658 goto out_unlock; 1270 goto out;
1659 1271
1660 ret = wl1271_ps_elp_wakeup(wl); 1272 ret = wl1271_ps_elp_wakeup(wl);
1661 if (ret < 0) 1273 if (ret < 0)
1662 goto out_unlock; 1274 goto out;
1663 1275
1664 ret = wl1271_acx_wake_up_conditions(wl, wlvif, 1276 ret = wl1271_acx_wake_up_conditions(wl, wlvif,
1665 wl->conf.conn.suspend_wake_up_event, 1277 wl->conf.conn.suspend_wake_up_event,
@@ -1668,11 +1280,9 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1668 if (ret < 0) 1280 if (ret < 0)
1669 wl1271_error("suspend: set wake up conditions failed: %d", ret); 1281 wl1271_error("suspend: set wake up conditions failed: %d", ret);
1670 1282
1671
1672 wl1271_ps_elp_sleep(wl); 1283 wl1271_ps_elp_sleep(wl);
1673 1284
1674out_unlock: 1285out:
1675 mutex_unlock(&wl->mutex);
1676 return ret; 1286 return ret;
1677 1287
1678} 1288}
@@ -1682,20 +1292,17 @@ static int wl1271_configure_suspend_ap(struct wl1271 *wl,
1682{ 1292{
1683 int ret = 0; 1293 int ret = 0;
1684 1294
1685 mutex_lock(&wl->mutex);
1686
1687 if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) 1295 if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
1688 goto out_unlock; 1296 goto out;
1689 1297
1690 ret = wl1271_ps_elp_wakeup(wl); 1298 ret = wl1271_ps_elp_wakeup(wl);
1691 if (ret < 0) 1299 if (ret < 0)
1692 goto out_unlock; 1300 goto out;
1693 1301
1694 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true); 1302 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
1695 1303
1696 wl1271_ps_elp_sleep(wl); 1304 wl1271_ps_elp_sleep(wl);
1697out_unlock: 1305out:
1698 mutex_unlock(&wl->mutex);
1699 return ret; 1306 return ret;
1700 1307
1701} 1308}
@@ -1720,10 +1327,9 @@ static void wl1271_configure_resume(struct wl1271 *wl,
1720 if ((!is_ap) && (!is_sta)) 1327 if ((!is_ap) && (!is_sta))
1721 return; 1328 return;
1722 1329
1723 mutex_lock(&wl->mutex);
1724 ret = wl1271_ps_elp_wakeup(wl); 1330 ret = wl1271_ps_elp_wakeup(wl);
1725 if (ret < 0) 1331 if (ret < 0)
1726 goto out; 1332 return;
1727 1333
1728 if (is_sta) { 1334 if (is_sta) {
1729 ret = wl1271_acx_wake_up_conditions(wl, wlvif, 1335 ret = wl1271_acx_wake_up_conditions(wl, wlvif,
@@ -1739,8 +1345,6 @@ static void wl1271_configure_resume(struct wl1271 *wl,
1739 } 1345 }
1740 1346
1741 wl1271_ps_elp_sleep(wl); 1347 wl1271_ps_elp_sleep(wl);
1742out:
1743 mutex_unlock(&wl->mutex);
1744} 1348}
1745 1349
1746static int wl1271_op_suspend(struct ieee80211_hw *hw, 1350static int wl1271_op_suspend(struct ieee80211_hw *hw,
@@ -1755,6 +1359,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1755 1359
1756 wl1271_tx_flush(wl); 1360 wl1271_tx_flush(wl);
1757 1361
1362 mutex_lock(&wl->mutex);
1758 wl->wow_enabled = true; 1363 wl->wow_enabled = true;
1759 wl12xx_for_each_wlvif(wl, wlvif) { 1364 wl12xx_for_each_wlvif(wl, wlvif) {
1760 ret = wl1271_configure_suspend(wl, wlvif); 1365 ret = wl1271_configure_suspend(wl, wlvif);
@@ -1763,6 +1368,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1763 return ret; 1368 return ret;
1764 } 1369 }
1765 } 1370 }
1371 mutex_unlock(&wl->mutex);
1766 /* flush any remaining work */ 1372 /* flush any remaining work */
1767 wl1271_debug(DEBUG_MAC80211, "flushing remaining works"); 1373 wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
1768 1374
@@ -1770,7 +1376,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1770 * disable and re-enable interrupts in order to flush 1376 * disable and re-enable interrupts in order to flush
1771 * the threaded_irq 1377 * the threaded_irq
1772 */ 1378 */
1773 wl1271_disable_interrupts(wl); 1379 wlcore_disable_interrupts(wl);
1774 1380
1775 /* 1381 /*
1776 * set suspended flag to avoid triggering a new threaded_irq 1382 * set suspended flag to avoid triggering a new threaded_irq
@@ -1778,7 +1384,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1778 */ 1384 */
1779 set_bit(WL1271_FLAG_SUSPENDED, &wl->flags); 1385 set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
1780 1386
1781 wl1271_enable_interrupts(wl); 1387 wlcore_enable_interrupts(wl);
1782 flush_work(&wl->tx_work); 1388 flush_work(&wl->tx_work);
1783 flush_delayed_work(&wl->elp_work); 1389 flush_delayed_work(&wl->elp_work);
1784 1390
@@ -1810,12 +1416,15 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
1810 wl1271_debug(DEBUG_MAC80211, 1416 wl1271_debug(DEBUG_MAC80211,
1811 "run postponed irq_work directly"); 1417 "run postponed irq_work directly");
1812 wl1271_irq(0, wl); 1418 wl1271_irq(0, wl);
1813 wl1271_enable_interrupts(wl); 1419 wlcore_enable_interrupts(wl);
1814 } 1420 }
1421
1422 mutex_lock(&wl->mutex);
1815 wl12xx_for_each_wlvif(wl, wlvif) { 1423 wl12xx_for_each_wlvif(wl, wlvif) {
1816 wl1271_configure_resume(wl, wlvif); 1424 wl1271_configure_resume(wl, wlvif);
1817 } 1425 }
1818 wl->wow_enabled = false; 1426 wl->wow_enabled = false;
1427 mutex_unlock(&wl->mutex);
1819 1428
1820 return 0; 1429 return 0;
1821} 1430}
@@ -1851,7 +1460,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1851 * Otherwise, the interrupt handler might be called and exit without 1460 * Otherwise, the interrupt handler might be called and exit without
1852 * reading the interrupt status. 1461 * reading the interrupt status.
1853 */ 1462 */
1854 wl1271_disable_interrupts(wl); 1463 wlcore_disable_interrupts(wl);
1855 mutex_lock(&wl->mutex); 1464 mutex_lock(&wl->mutex);
1856 if (wl->state == WL1271_STATE_OFF) { 1465 if (wl->state == WL1271_STATE_OFF) {
1857 mutex_unlock(&wl->mutex); 1466 mutex_unlock(&wl->mutex);
@@ -1861,7 +1470,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1861 * may have been disabled when op_stop was called. It will, 1470 * may have been disabled when op_stop was called. It will,
1862 * however, balance the above call to disable_interrupts(). 1471 * however, balance the above call to disable_interrupts().
1863 */ 1472 */
1864 wl1271_enable_interrupts(wl); 1473 wlcore_enable_interrupts(wl);
1865 return; 1474 return;
1866 } 1475 }
1867 1476
@@ -1894,7 +1503,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1894 wl->tx_results_count = 0; 1503 wl->tx_results_count = 0;
1895 wl->tx_packets_count = 0; 1504 wl->tx_packets_count = 0;
1896 wl->time_offset = 0; 1505 wl->time_offset = 0;
1897 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
1898 wl->ap_fw_ps_map = 0; 1506 wl->ap_fw_ps_map = 0;
1899 wl->ap_ps_map = 0; 1507 wl->ap_ps_map = 0;
1900 wl->sched_scanning = false; 1508 wl->sched_scanning = false;
@@ -2067,7 +1675,7 @@ static bool wl12xx_init_fw(struct wl1271 *wl)
2067 if (ret < 0) 1675 if (ret < 0)
2068 goto power_off; 1676 goto power_off;
2069 1677
2070 ret = wl1271_boot(wl); 1678 ret = wl->ops->boot(wl);
2071 if (ret < 0) 1679 if (ret < 0)
2072 goto power_off; 1680 goto power_off;
2073 1681
@@ -2087,7 +1695,7 @@ irq_disable:
2087 work function will not do anything.) Also, any other 1695 work function will not do anything.) Also, any other
2088 possible concurrent operations will fail due to the 1696 possible concurrent operations will fail due to the
2089 current state, hence the wl1271 struct should be safe. */ 1697 current state, hence the wl1271 struct should be safe. */
2090 wl1271_disable_interrupts(wl); 1698 wlcore_disable_interrupts(wl);
2091 wl1271_flush_deferred_work(wl); 1699 wl1271_flush_deferred_work(wl);
2092 cancel_work_sync(&wl->netstack_work); 1700 cancel_work_sync(&wl->netstack_work);
2093 mutex_lock(&wl->mutex); 1701 mutex_lock(&wl->mutex);
@@ -2360,10 +1968,12 @@ deinit:
2360 for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++) 1968 for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
2361 wl12xx_free_rate_policy(wl, 1969 wl12xx_free_rate_policy(wl,
2362 &wlvif->ap.ucast_rate_idx[i]); 1970 &wlvif->ap.ucast_rate_idx[i]);
1971 wl1271_free_ap_keys(wl, wlvif);
2363 } 1972 }
2364 1973
1974 dev_kfree_skb(wlvif->probereq);
1975 wlvif->probereq = NULL;
2365 wl12xx_tx_reset_wlvif(wl, wlvif); 1976 wl12xx_tx_reset_wlvif(wl, wlvif);
2366 wl1271_free_ap_keys(wl, wlvif);
2367 if (wl->last_wlvif == wlvif) 1977 if (wl->last_wlvif == wlvif)
2368 wl->last_wlvif = NULL; 1978 wl->last_wlvif = NULL;
2369 list_del(&wlvif->list); 1979 list_del(&wlvif->list);
@@ -2946,6 +2556,17 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2946 int ret; 2556 int ret;
2947 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 2557 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
2948 2558
2559 /*
2560 * A role set to GEM cipher requires different Tx settings (namely
2561 * spare blocks). Note when we are in this mode so the HW can adjust.
2562 */
2563 if (key_type == KEY_GEM) {
2564 if (action == KEY_ADD_OR_REPLACE)
2565 wlvif->is_gem = true;
2566 else if (action == KEY_REMOVE)
2567 wlvif->is_gem = false;
2568 }
2569
2949 if (is_ap) { 2570 if (is_ap) {
2950 struct wl1271_station *wl_sta; 2571 struct wl1271_station *wl_sta;
2951 u8 hlid; 2572 u8 hlid;
@@ -2984,17 +2605,6 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2984 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 2605 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2985 }; 2606 };
2986 2607
2987 /*
2988 * A STA set to GEM cipher requires 2 tx spare blocks.
2989 * Return to default value when GEM cipher key is removed
2990 */
2991 if (key_type == KEY_GEM) {
2992 if (action == KEY_ADD_OR_REPLACE)
2993 wl->tx_spare_blocks = 2;
2994 else if (action == KEY_REMOVE)
2995 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
2996 }
2997
2998 addr = sta ? sta->addr : bcast_addr; 2608 addr = sta ? sta->addr : bcast_addr;
2999 2609
3000 if (is_zero_ether_addr(addr)) { 2610 if (is_zero_ether_addr(addr)) {
@@ -3791,8 +3401,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3791 wlvif->rssi_thold = bss_conf->cqm_rssi_thold; 3401 wlvif->rssi_thold = bss_conf->cqm_rssi_thold;
3792 } 3402 }
3793 3403
3794 if (changed & BSS_CHANGED_BSSID && 3404 if (changed & BSS_CHANGED_BSSID)
3795 (is_ibss || bss_conf->assoc))
3796 if (!is_zero_ether_addr(bss_conf->bssid)) { 3405 if (!is_zero_ether_addr(bss_conf->bssid)) {
3797 ret = wl12xx_cmd_build_null_data(wl, wlvif); 3406 ret = wl12xx_cmd_build_null_data(wl, wlvif);
3798 if (ret < 0) 3407 if (ret < 0)
@@ -3801,9 +3410,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3801 ret = wl1271_build_qos_null_data(wl, vif); 3410 ret = wl1271_build_qos_null_data(wl, vif);
3802 if (ret < 0) 3411 if (ret < 0)
3803 goto out; 3412 goto out;
3804
3805 /* Need to update the BSSID (for filtering etc) */
3806 do_join = true;
3807 } 3413 }
3808 3414
3809 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) { 3415 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) {
@@ -3830,6 +3436,7 @@ sta_not_found:
3830 int ieoffset; 3436 int ieoffset;
3831 wlvif->aid = bss_conf->aid; 3437 wlvif->aid = bss_conf->aid;
3832 wlvif->beacon_int = bss_conf->beacon_int; 3438 wlvif->beacon_int = bss_conf->beacon_int;
3439 do_join = true;
3833 set_assoc = true; 3440 set_assoc = true;
3834 3441
3835 /* 3442 /*
@@ -4662,60 +4269,12 @@ static struct ieee80211_channel wl1271_channels[] = {
4662 { .hw_value = 14, .center_freq = 2484, .max_power = 25 }, 4269 { .hw_value = 14, .center_freq = 2484, .max_power = 25 },
4663}; 4270};
4664 4271
4665/* mapping to indexes for wl1271_rates */
4666static const u8 wl1271_rate_to_idx_2ghz[] = {
4667 /* MCS rates are used only with 11n */
4668 7, /* CONF_HW_RXTX_RATE_MCS7_SGI */
4669 7, /* CONF_HW_RXTX_RATE_MCS7 */
4670 6, /* CONF_HW_RXTX_RATE_MCS6 */
4671 5, /* CONF_HW_RXTX_RATE_MCS5 */
4672 4, /* CONF_HW_RXTX_RATE_MCS4 */
4673 3, /* CONF_HW_RXTX_RATE_MCS3 */
4674 2, /* CONF_HW_RXTX_RATE_MCS2 */
4675 1, /* CONF_HW_RXTX_RATE_MCS1 */
4676 0, /* CONF_HW_RXTX_RATE_MCS0 */
4677
4678 11, /* CONF_HW_RXTX_RATE_54 */
4679 10, /* CONF_HW_RXTX_RATE_48 */
4680 9, /* CONF_HW_RXTX_RATE_36 */
4681 8, /* CONF_HW_RXTX_RATE_24 */
4682
4683 /* TI-specific rate */
4684 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
4685
4686 7, /* CONF_HW_RXTX_RATE_18 */
4687 6, /* CONF_HW_RXTX_RATE_12 */
4688 3, /* CONF_HW_RXTX_RATE_11 */
4689 5, /* CONF_HW_RXTX_RATE_9 */
4690 4, /* CONF_HW_RXTX_RATE_6 */
4691 2, /* CONF_HW_RXTX_RATE_5_5 */
4692 1, /* CONF_HW_RXTX_RATE_2 */
4693 0 /* CONF_HW_RXTX_RATE_1 */
4694};
4695
4696/* 11n STA capabilities */
4697#define HW_RX_HIGHEST_RATE 72
4698
4699#define WL12XX_HT_CAP { \
4700 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | \
4701 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), \
4702 .ht_supported = true, \
4703 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \
4704 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
4705 .mcs = { \
4706 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
4707 .rx_highest = cpu_to_le16(HW_RX_HIGHEST_RATE), \
4708 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
4709 }, \
4710}
4711
4712/* can't be const, mac80211 writes to this */ 4272/* can't be const, mac80211 writes to this */
4713static struct ieee80211_supported_band wl1271_band_2ghz = { 4273static struct ieee80211_supported_band wl1271_band_2ghz = {
4714 .channels = wl1271_channels, 4274 .channels = wl1271_channels,
4715 .n_channels = ARRAY_SIZE(wl1271_channels), 4275 .n_channels = ARRAY_SIZE(wl1271_channels),
4716 .bitrates = wl1271_rates, 4276 .bitrates = wl1271_rates,
4717 .n_bitrates = ARRAY_SIZE(wl1271_rates), 4277 .n_bitrates = ARRAY_SIZE(wl1271_rates),
4718 .ht_cap = WL12XX_HT_CAP,
4719}; 4278};
4720 4279
4721/* 5 GHz data rates for WL1273 */ 4280/* 5 GHz data rates for WL1273 */
@@ -4784,48 +4343,11 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = {
4784 { .hw_value = 165, .center_freq = 5825, .max_power = 25 }, 4343 { .hw_value = 165, .center_freq = 5825, .max_power = 25 },
4785}; 4344};
4786 4345
4787/* mapping to indexes for wl1271_rates_5ghz */
4788static const u8 wl1271_rate_to_idx_5ghz[] = {
4789 /* MCS rates are used only with 11n */
4790 7, /* CONF_HW_RXTX_RATE_MCS7_SGI */
4791 7, /* CONF_HW_RXTX_RATE_MCS7 */
4792 6, /* CONF_HW_RXTX_RATE_MCS6 */
4793 5, /* CONF_HW_RXTX_RATE_MCS5 */
4794 4, /* CONF_HW_RXTX_RATE_MCS4 */
4795 3, /* CONF_HW_RXTX_RATE_MCS3 */
4796 2, /* CONF_HW_RXTX_RATE_MCS2 */
4797 1, /* CONF_HW_RXTX_RATE_MCS1 */
4798 0, /* CONF_HW_RXTX_RATE_MCS0 */
4799
4800 7, /* CONF_HW_RXTX_RATE_54 */
4801 6, /* CONF_HW_RXTX_RATE_48 */
4802 5, /* CONF_HW_RXTX_RATE_36 */
4803 4, /* CONF_HW_RXTX_RATE_24 */
4804
4805 /* TI-specific rate */
4806 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
4807
4808 3, /* CONF_HW_RXTX_RATE_18 */
4809 2, /* CONF_HW_RXTX_RATE_12 */
4810 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_11 */
4811 1, /* CONF_HW_RXTX_RATE_9 */
4812 0, /* CONF_HW_RXTX_RATE_6 */
4813 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_5_5 */
4814 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_2 */
4815 CONF_HW_RXTX_RATE_UNSUPPORTED /* CONF_HW_RXTX_RATE_1 */
4816};
4817
4818static struct ieee80211_supported_band wl1271_band_5ghz = { 4346static struct ieee80211_supported_band wl1271_band_5ghz = {
4819 .channels = wl1271_channels_5ghz, 4347 .channels = wl1271_channels_5ghz,
4820 .n_channels = ARRAY_SIZE(wl1271_channels_5ghz), 4348 .n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
4821 .bitrates = wl1271_rates_5ghz, 4349 .bitrates = wl1271_rates_5ghz,
4822 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), 4350 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
4823 .ht_cap = WL12XX_HT_CAP,
4824};
4825
4826static const u8 *wl1271_band_rate_to_idx[] = {
4827 [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz,
4828 [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz
4829}; 4351};
4830 4352
4831static const struct ieee80211_ops wl1271_ops = { 4353static const struct ieee80211_ops wl1271_ops = {
@@ -4862,18 +4384,18 @@ static const struct ieee80211_ops wl1271_ops = {
4862}; 4384};
4863 4385
4864 4386
4865u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band) 4387u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum ieee80211_band band)
4866{ 4388{
4867 u8 idx; 4389 u8 idx;
4868 4390
4869 BUG_ON(band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *)); 4391 BUG_ON(band >= 2);
4870 4392
4871 if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) { 4393 if (unlikely(rate >= wl->hw_tx_rate_tbl_size)) {
4872 wl1271_error("Illegal RX rate from HW: %d", rate); 4394 wl1271_error("Illegal RX rate from HW: %d", rate);
4873 return 0; 4395 return 0;
4874 } 4396 }
4875 4397
4876 idx = wl1271_band_rate_to_idx[band][rate]; 4398 idx = wl->band_rate_to_idx[band][rate];
4877 if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) { 4399 if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
4878 wl1271_error("Unsupported RX rate from HW: %d", rate); 4400 wl1271_error("Unsupported RX rate from HW: %d", rate);
4879 return 0; 4401 return 0;
@@ -5027,34 +4549,6 @@ static struct bin_attribute fwlog_attr = {
5027 .read = wl1271_sysfs_read_fwlog, 4549 .read = wl1271_sysfs_read_fwlog,
5028}; 4550};
5029 4551
5030static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
5031{
5032 bool supported = false;
5033 u8 major, minor;
5034
5035 if (wl->chip.id == CHIP_ID_1283_PG20) {
5036 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
5037 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
5038
5039 /* in wl128x we have the MAC address if the PG is >= (2, 1) */
5040 if (major > 2 || (major == 2 && minor >= 1))
5041 supported = true;
5042 } else {
5043 major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
5044 minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
5045
5046 /* in wl127x we have the MAC address if the PG is >= (3, 1) */
5047 if (major == 3 && minor >= 1)
5048 supported = true;
5049 }
5050
5051 wl1271_debug(DEBUG_PROBE,
5052 "PG Ver major = %d minor = %d, MAC %s present",
5053 major, minor, supported ? "is" : "is not");
5054
5055 return supported;
5056}
5057
5058static void wl12xx_derive_mac_addresses(struct wl1271 *wl, 4552static void wl12xx_derive_mac_addresses(struct wl1271 *wl,
5059 u32 oui, u32 nic, int n) 4553 u32 oui, u32 nic, int n)
5060{ 4554{
@@ -5080,47 +4574,23 @@ static void wl12xx_derive_mac_addresses(struct wl1271 *wl,
5080 wl->hw->wiphy->addresses = wl->addresses; 4574 wl->hw->wiphy->addresses = wl->addresses;
5081} 4575}
5082 4576
5083static void wl12xx_get_fuse_mac(struct wl1271 *wl)
5084{
5085 u32 mac1, mac2;
5086
5087 wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]);
5088
5089 mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1);
5090 mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2);
5091
5092 /* these are the two parts of the BD_ADDR */
5093 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
5094 ((mac1 & 0xff000000) >> 24);
5095 wl->fuse_nic_addr = mac1 & 0xffffff;
5096
5097 wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]);
5098}
5099
5100static int wl12xx_get_hw_info(struct wl1271 *wl) 4577static int wl12xx_get_hw_info(struct wl1271 *wl)
5101{ 4578{
5102 int ret; 4579 int ret;
5103 u32 die_info;
5104 4580
5105 ret = wl12xx_set_power_on(wl); 4581 ret = wl12xx_set_power_on(wl);
5106 if (ret < 0) 4582 if (ret < 0)
5107 goto out; 4583 goto out;
5108 4584
5109 wl->chip.id = wl1271_read32(wl, CHIP_ID_B); 4585 wl->chip.id = wlcore_read_reg(wl, REG_CHIP_ID_B);
5110 4586
5111 if (wl->chip.id == CHIP_ID_1283_PG20) 4587 wl->fuse_oui_addr = 0;
5112 die_info = wl1271_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1); 4588 wl->fuse_nic_addr = 0;
5113 else
5114 die_info = wl1271_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);
5115 4589
5116 wl->hw_pg_ver = (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET; 4590 wl->hw_pg_ver = wl->ops->get_pg_ver(wl);
5117 4591
5118 if (!wl12xx_mac_in_fuse(wl)) { 4592 if (wl->ops->get_mac)
5119 wl->fuse_oui_addr = 0; 4593 wl->ops->get_mac(wl);
5120 wl->fuse_nic_addr = 0;
5121 } else {
5122 wl12xx_get_fuse_mac(wl);
5123 }
5124 4594
5125 wl1271_power_off(wl); 4595 wl1271_power_off(wl);
5126out: 4596out:
@@ -5255,8 +4725,12 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5255 */ 4725 */
5256 memcpy(&wl->bands[IEEE80211_BAND_2GHZ], &wl1271_band_2ghz, 4726 memcpy(&wl->bands[IEEE80211_BAND_2GHZ], &wl1271_band_2ghz,
5257 sizeof(wl1271_band_2ghz)); 4727 sizeof(wl1271_band_2ghz));
4728 memcpy(&wl->bands[IEEE80211_BAND_2GHZ].ht_cap, &wl->ht_cap,
4729 sizeof(wl->ht_cap));
5258 memcpy(&wl->bands[IEEE80211_BAND_5GHZ], &wl1271_band_5ghz, 4730 memcpy(&wl->bands[IEEE80211_BAND_5GHZ], &wl1271_band_5ghz,
5259 sizeof(wl1271_band_5ghz)); 4731 sizeof(wl1271_band_5ghz));
4732 memcpy(&wl->bands[IEEE80211_BAND_5GHZ].ht_cap, &wl->ht_cap,
4733 sizeof(wl->ht_cap));
5260 4734
5261 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 4735 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
5262 &wl->bands[IEEE80211_BAND_2GHZ]; 4736 &wl->bands[IEEE80211_BAND_2GHZ];
@@ -5280,14 +4754,14 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5280 wl->hw->sta_data_size = sizeof(struct wl1271_station); 4754 wl->hw->sta_data_size = sizeof(struct wl1271_station);
5281 wl->hw->vif_data_size = sizeof(struct wl12xx_vif); 4755 wl->hw->vif_data_size = sizeof(struct wl12xx_vif);
5282 4756
5283 wl->hw->max_rx_aggregation_subframes = 8; 4757 wl->hw->max_rx_aggregation_subframes = wl->conf.ht.rx_ba_win_size;
5284 4758
5285 return 0; 4759 return 0;
5286} 4760}
5287 4761
5288#define WL1271_DEFAULT_CHANNEL 0 4762#define WL1271_DEFAULT_CHANNEL 0
5289 4763
5290static struct ieee80211_hw *wl1271_alloc_hw(void) 4764struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size)
5291{ 4765{
5292 struct ieee80211_hw *hw; 4766 struct ieee80211_hw *hw;
5293 struct wl1271 *wl; 4767 struct wl1271 *wl;
@@ -5306,6 +4780,13 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5306 wl = hw->priv; 4780 wl = hw->priv;
5307 memset(wl, 0, sizeof(*wl)); 4781 memset(wl, 0, sizeof(*wl));
5308 4782
4783 wl->priv = kzalloc(priv_size, GFP_KERNEL);
4784 if (!wl->priv) {
4785 wl1271_error("could not alloc wl priv");
4786 ret = -ENOMEM;
4787 goto err_priv_alloc;
4788 }
4789
5309 INIT_LIST_HEAD(&wl->wlvif_list); 4790 INIT_LIST_HEAD(&wl->wlvif_list);
5310 4791
5311 wl->hw = hw; 4792 wl->hw = hw;
@@ -5342,7 +4823,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5342 wl->quirks = 0; 4823 wl->quirks = 0;
5343 wl->platform_quirks = 0; 4824 wl->platform_quirks = 0;
5344 wl->sched_scanning = false; 4825 wl->sched_scanning = false;
5345 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
5346 wl->system_hlid = WL12XX_SYSTEM_HLID; 4826 wl->system_hlid = WL12XX_SYSTEM_HLID;
5347 wl->active_sta_count = 0; 4827 wl->active_sta_count = 0;
5348 wl->fwlog_size = 0; 4828 wl->fwlog_size = 0;
@@ -5352,7 +4832,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5352 __set_bit(WL12XX_SYSTEM_HLID, wl->links_map); 4832 __set_bit(WL12XX_SYSTEM_HLID, wl->links_map);
5353 4833
5354 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); 4834 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
5355 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 4835 for (i = 0; i < wl->num_tx_desc; i++)
5356 wl->tx_frames[i] = NULL; 4836 wl->tx_frames[i] = NULL;
5357 4837
5358 spin_lock_init(&wl->wl_lock); 4838 spin_lock_init(&wl->wl_lock);
@@ -5361,9 +4841,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5361 wl->fw_type = WL12XX_FW_TYPE_NONE; 4841 wl->fw_type = WL12XX_FW_TYPE_NONE;
5362 mutex_init(&wl->mutex); 4842 mutex_init(&wl->mutex);
5363 4843
5364 /* Apply default driver configuration. */
5365 wl1271_conf_init(wl);
5366
5367 order = get_order(WL1271_AGGR_BUFFER_SIZE); 4844 order = get_order(WL1271_AGGR_BUFFER_SIZE);
5368 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); 4845 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
5369 if (!wl->aggr_buf) { 4846 if (!wl->aggr_buf) {
@@ -5384,8 +4861,17 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5384 goto err_dummy_packet; 4861 goto err_dummy_packet;
5385 } 4862 }
5386 4863
4864 wl->mbox = kmalloc(sizeof(*wl->mbox), GFP_DMA);
4865 if (!wl->mbox) {
4866 ret = -ENOMEM;
4867 goto err_fwlog;
4868 }
4869
5387 return hw; 4870 return hw;
5388 4871
4872err_fwlog:
4873 free_page((unsigned long)wl->fwlog);
4874
5389err_dummy_packet: 4875err_dummy_packet:
5390 dev_kfree_skb(wl->dummy_packet); 4876 dev_kfree_skb(wl->dummy_packet);
5391 4877
@@ -5397,14 +4883,18 @@ err_wq:
5397 4883
5398err_hw: 4884err_hw:
5399 wl1271_debugfs_exit(wl); 4885 wl1271_debugfs_exit(wl);
4886 kfree(wl->priv);
4887
4888err_priv_alloc:
5400 ieee80211_free_hw(hw); 4889 ieee80211_free_hw(hw);
5401 4890
5402err_hw_alloc: 4891err_hw_alloc:
5403 4892
5404 return ERR_PTR(ret); 4893 return ERR_PTR(ret);
5405} 4894}
4895EXPORT_SYMBOL_GPL(wlcore_alloc_hw);
5406 4896
5407static int wl1271_free_hw(struct wl1271 *wl) 4897int wlcore_free_hw(struct wl1271 *wl)
5408{ 4898{
5409 /* Unblock any fwlog readers */ 4899 /* Unblock any fwlog readers */
5410 mutex_lock(&wl->mutex); 4900 mutex_lock(&wl->mutex);
@@ -5434,10 +4924,12 @@ static int wl1271_free_hw(struct wl1271 *wl)
5434 kfree(wl->tx_res_if); 4924 kfree(wl->tx_res_if);
5435 destroy_workqueue(wl->freezable_wq); 4925 destroy_workqueue(wl->freezable_wq);
5436 4926
4927 kfree(wl->priv);
5437 ieee80211_free_hw(wl->hw); 4928 ieee80211_free_hw(wl->hw);
5438 4929
5439 return 0; 4930 return 0;
5440} 4931}
4932EXPORT_SYMBOL_GPL(wlcore_free_hw);
5441 4933
5442static irqreturn_t wl12xx_hardirq(int irq, void *cookie) 4934static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
5443{ 4935{
@@ -5468,22 +4960,22 @@ static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
5468 return IRQ_WAKE_THREAD; 4960 return IRQ_WAKE_THREAD;
5469} 4961}
5470 4962
5471static int __devinit wl12xx_probe(struct platform_device *pdev) 4963int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
5472{ 4964{
5473 struct wl12xx_platform_data *pdata = pdev->dev.platform_data; 4965 struct wl12xx_platform_data *pdata = pdev->dev.platform_data;
5474 struct ieee80211_hw *hw;
5475 struct wl1271 *wl;
5476 unsigned long irqflags; 4966 unsigned long irqflags;
5477 int ret = -ENODEV; 4967 int ret;
5478 4968
5479 hw = wl1271_alloc_hw(); 4969 if (!wl->ops || !wl->ptable) {
5480 if (IS_ERR(hw)) { 4970 ret = -EINVAL;
5481 wl1271_error("can't allocate hw"); 4971 goto out_free_hw;
5482 ret = PTR_ERR(hw);
5483 goto out;
5484 } 4972 }
5485 4973
5486 wl = hw->priv; 4974 BUG_ON(wl->num_tx_desc > WLCORE_MAX_TX_DESCRIPTORS);
4975
4976 /* adjust some runtime configuration parameters */
4977 wlcore_adjust_conf(wl);
4978
5487 wl->irq = platform_get_irq(pdev, 0); 4979 wl->irq = platform_get_irq(pdev, 0);
5488 wl->ref_clock = pdata->board_ref_clock; 4980 wl->ref_clock = pdata->board_ref_clock;
5489 wl->tcxo_clock = pdata->board_tcxo_clock; 4981 wl->tcxo_clock = pdata->board_tcxo_clock;
@@ -5512,7 +5004,7 @@ static int __devinit wl12xx_probe(struct platform_device *pdev)
5512 wl->irq_wake_enabled = true; 5004 wl->irq_wake_enabled = true;
5513 device_init_wakeup(wl->dev, 1); 5005 device_init_wakeup(wl->dev, 1);
5514 if (pdata->pwr_in_suspend) 5006 if (pdata->pwr_in_suspend)
5515 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY; 5007 wl->hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
5516 5008
5517 } 5009 }
5518 disable_irq(wl->irq); 5010 disable_irq(wl->irq);
@@ -5546,7 +5038,7 @@ static int __devinit wl12xx_probe(struct platform_device *pdev)
5546 goto out_hw_pg_ver; 5038 goto out_hw_pg_ver;
5547 } 5039 }
5548 5040
5549 return 0; 5041 goto out;
5550 5042
5551out_hw_pg_ver: 5043out_hw_pg_ver:
5552 device_remove_file(wl->dev, &dev_attr_hw_pg_ver); 5044 device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
@@ -5558,13 +5050,14 @@ out_irq:
5558 free_irq(wl->irq, wl); 5050 free_irq(wl->irq, wl);
5559 5051
5560out_free_hw: 5052out_free_hw:
5561 wl1271_free_hw(wl); 5053 wlcore_free_hw(wl);
5562 5054
5563out: 5055out:
5564 return ret; 5056 return ret;
5565} 5057}
5058EXPORT_SYMBOL_GPL(wlcore_probe);
5566 5059
5567static int __devexit wl12xx_remove(struct platform_device *pdev) 5060int __devexit wlcore_remove(struct platform_device *pdev)
5568{ 5061{
5569 struct wl1271 *wl = platform_get_drvdata(pdev); 5062 struct wl1271 *wl = platform_get_drvdata(pdev);
5570 5063
@@ -5574,38 +5067,11 @@ static int __devexit wl12xx_remove(struct platform_device *pdev)
5574 } 5067 }
5575 wl1271_unregister_hw(wl); 5068 wl1271_unregister_hw(wl);
5576 free_irq(wl->irq, wl); 5069 free_irq(wl->irq, wl);
5577 wl1271_free_hw(wl); 5070 wlcore_free_hw(wl);
5578 5071
5579 return 0; 5072 return 0;
5580} 5073}
5581 5074EXPORT_SYMBOL_GPL(wlcore_remove);
5582static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
5583 { "wl12xx", 0 },
5584 { } /* Terminating Entry */
5585};
5586MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
5587
5588static struct platform_driver wl12xx_driver = {
5589 .probe = wl12xx_probe,
5590 .remove = __devexit_p(wl12xx_remove),
5591 .id_table = wl12xx_id_table,
5592 .driver = {
5593 .name = "wl12xx_driver",
5594 .owner = THIS_MODULE,
5595 }
5596};
5597
5598static int __init wl12xx_init(void)
5599{
5600 return platform_driver_register(&wl12xx_driver);
5601}
5602module_init(wl12xx_init);
5603
5604static void __exit wl12xx_exit(void)
5605{
5606 platform_driver_unregister(&wl12xx_driver);
5607}
5608module_exit(wl12xx_exit);
5609 5075
5610u32 wl12xx_debug_level = DEBUG_NONE; 5076u32 wl12xx_debug_level = DEBUG_NONE;
5611EXPORT_SYMBOL_GPL(wl12xx_debug_level); 5077EXPORT_SYMBOL_GPL(wl12xx_debug_level);
@@ -5619,6 +5085,9 @@ MODULE_PARM_DESC(fwlog,
5619module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR); 5085module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR);
5620MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); 5086MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery");
5621 5087
5088module_param(no_recovery, bool, S_IRUSR | S_IWUSR);
5089MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck.");
5090
5622MODULE_LICENSE("GPL"); 5091MODULE_LICENSE("GPL");
5623MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); 5092MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
5624MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 5093MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 78f598b4f97b..756eee2257b4 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include "reg.h"
25#include "ps.h" 24#include "ps.h"
26#include "io.h" 25#include "io.h"
27#include "tx.h" 26#include "tx.h"
@@ -62,7 +61,7 @@ void wl1271_elp_work(struct work_struct *work)
62 } 61 }
63 62
64 wl1271_debug(DEBUG_PSM, "chip to elp"); 63 wl1271_debug(DEBUG_PSM, "chip to elp");
65 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); 64 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP);
66 set_bit(WL1271_FLAG_IN_ELP, &wl->flags); 65 set_bit(WL1271_FLAG_IN_ELP, &wl->flags);
67 66
68out: 67out:
@@ -74,6 +73,9 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
74{ 73{
75 struct wl12xx_vif *wlvif; 74 struct wl12xx_vif *wlvif;
76 75
76 if (wl->quirks & WLCORE_QUIRK_NO_ELP)
77 return;
78
77 /* we shouldn't get consecutive sleep requests */ 79 /* we shouldn't get consecutive sleep requests */
78 if (WARN_ON(test_and_set_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags))) 80 if (WARN_ON(test_and_set_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
79 return; 81 return;
@@ -125,7 +127,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
125 wl->elp_compl = &compl; 127 wl->elp_compl = &compl;
126 spin_unlock_irqrestore(&wl->wl_lock, flags); 128 spin_unlock_irqrestore(&wl->wl_lock, flags);
127 129
128 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); 130 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
129 131
130 if (!pending) { 132 if (!pending) {
131 ret = wait_for_completion_timeout( 133 ret = wait_for_completion_timeout(
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/ti/wlcore/ps.h
index 5f19d4fbbf27..de4f9da8ed26 100644
--- a/drivers/net/wireless/wl12xx/ps.h
+++ b/drivers/net/wireless/ti/wlcore/ps.h
@@ -24,7 +24,7 @@
24#ifndef __PS_H__ 24#ifndef __PS_H__
25#define __PS_H__ 25#define __PS_H__
26 26
27#include "wl12xx.h" 27#include "wlcore.h"
28#include "acx.h" 28#include "acx.h"
29 29
30int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, 30int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/ti/wlcore/rx.c
index cfa6071704c5..89bd9385e90b 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/ti/wlcore/rx.c
@@ -24,34 +24,36 @@
24#include <linux/gfp.h> 24#include <linux/gfp.h>
25#include <linux/sched.h> 25#include <linux/sched.h>
26 26
27#include "wl12xx.h" 27#include "wlcore.h"
28#include "debug.h" 28#include "debug.h"
29#include "acx.h" 29#include "acx.h"
30#include "reg.h"
31#include "rx.h" 30#include "rx.h"
32#include "tx.h" 31#include "tx.h"
33#include "io.h" 32#include "io.h"
33#include "hw_ops.h"
34 34
35static u8 wl12xx_rx_get_mem_block(struct wl12xx_fw_status *status, 35/*
36 u32 drv_rx_counter) 36 * TODO: this is here just for now, it must be removed when the data
37{ 37 * operations are in place.
38 return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & 38 */
39 RX_MEM_BLOCK_MASK; 39#include "../wl12xx/reg.h"
40}
41 40
42static u32 wl12xx_rx_get_buf_size(struct wl12xx_fw_status *status, 41static u32 wlcore_rx_get_buf_size(struct wl1271 *wl,
43 u32 drv_rx_counter) 42 u32 rx_pkt_desc)
44{ 43{
45 return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & 44 if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN)
46 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV; 45 return (rx_pkt_desc & ALIGNED_RX_BUF_SIZE_MASK) >>
46 ALIGNED_RX_BUF_SIZE_SHIFT;
47
48 return (rx_pkt_desc & RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
47} 49}
48 50
49static bool wl12xx_rx_get_unaligned(struct wl12xx_fw_status *status, 51static u32 wlcore_rx_get_align_buf_size(struct wl1271 *wl, u32 pkt_len)
50 u32 drv_rx_counter)
51{ 52{
52 /* Convert the value to bool */ 53 if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN)
53 return !!(le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & 54 return ALIGN(pkt_len, WL12XX_BUS_BLOCK_SIZE);
54 RX_BUF_UNALIGNED_PAYLOAD); 55
56 return pkt_len;
55} 57}
56 58
57static void wl1271_rx_status(struct wl1271 *wl, 59static void wl1271_rx_status(struct wl1271 *wl,
@@ -66,10 +68,10 @@ static void wl1271_rx_status(struct wl1271 *wl,
66 else 68 else
67 status->band = IEEE80211_BAND_5GHZ; 69 status->band = IEEE80211_BAND_5GHZ;
68 70
69 status->rate_idx = wl1271_rate_to_idx(desc->rate, status->band); 71 status->rate_idx = wlcore_rate_to_idx(wl, desc->rate, status->band);
70 72
71 /* 11n support */ 73 /* 11n support */
72 if (desc->rate <= CONF_HW_RXTX_RATE_MCS0) 74 if (desc->rate <= wl->hw_min_ht_rate)
73 status->flag |= RX_FLAG_HT; 75 status->flag |= RX_FLAG_HT;
74 76
75 status->signal = desc->rssi; 77 status->signal = desc->rssi;
@@ -98,7 +100,7 @@ static void wl1271_rx_status(struct wl1271 *wl,
98} 100}
99 101
100static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, 102static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
101 bool unaligned, u8 *hlid) 103 enum wl_rx_buf_align rx_align, u8 *hlid)
102{ 104{
103 struct wl1271_rx_descriptor *desc; 105 struct wl1271_rx_descriptor *desc;
104 struct sk_buff *skb; 106 struct sk_buff *skb;
@@ -106,8 +108,9 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
106 u8 *buf; 108 u8 *buf;
107 u8 beacon = 0; 109 u8 beacon = 0;
108 u8 is_data = 0; 110 u8 is_data = 0;
109 u8 reserved = unaligned ? NET_IP_ALIGN : 0; 111 u8 reserved = 0;
110 u16 seq_num; 112 u16 seq_num;
113 u32 pkt_data_len;
111 114
112 /* 115 /*
113 * In PLT mode we seem to get frames and mac80211 warns about them, 116 * In PLT mode we seem to get frames and mac80211 warns about them,
@@ -116,6 +119,16 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
116 if (unlikely(wl->plt)) 119 if (unlikely(wl->plt))
117 return -EINVAL; 120 return -EINVAL;
118 121
122 pkt_data_len = wlcore_hw_get_rx_packet_len(wl, data, length);
123 if (!pkt_data_len) {
124 wl1271_error("Invalid packet arrived from HW. length %d",
125 length);
126 return -EINVAL;
127 }
128
129 if (rx_align == WLCORE_RX_BUF_UNALIGNED)
130 reserved = NET_IP_ALIGN;
131
119 /* the data read starts with the descriptor */ 132 /* the data read starts with the descriptor */
120 desc = (struct wl1271_rx_descriptor *) data; 133 desc = (struct wl1271_rx_descriptor *) data;
121 134
@@ -142,8 +155,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
142 return -EINVAL; 155 return -EINVAL;
143 } 156 }
144 157
145 /* skb length not included rx descriptor */ 158 /* skb length not including rx descriptor */
146 skb = __dev_alloc_skb(length + reserved - sizeof(*desc), GFP_KERNEL); 159 skb = __dev_alloc_skb(pkt_data_len + reserved, GFP_KERNEL);
147 if (!skb) { 160 if (!skb) {
148 wl1271_error("Couldn't allocate RX frame"); 161 wl1271_error("Couldn't allocate RX frame");
149 return -ENOMEM; 162 return -ENOMEM;
@@ -152,7 +165,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
152 /* reserve the unaligned payload(if any) */ 165 /* reserve the unaligned payload(if any) */
153 skb_reserve(skb, reserved); 166 skb_reserve(skb, reserved);
154 167
155 buf = skb_put(skb, length - sizeof(*desc)); 168 buf = skb_put(skb, pkt_data_len);
156 169
157 /* 170 /*
158 * Copy packets from aggregation buffer to the skbs without rx 171 * Copy packets from aggregation buffer to the skbs without rx
@@ -160,7 +173,10 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
160 * packets copy the packets in offset of 2 bytes guarantee IP header 173 * packets copy the packets in offset of 2 bytes guarantee IP header
161 * payload aligned to 4 bytes. 174 * payload aligned to 4 bytes.
162 */ 175 */
163 memcpy(buf, data + sizeof(*desc), length - sizeof(*desc)); 176 memcpy(buf, data + sizeof(*desc), pkt_data_len);
177 if (rx_align == WLCORE_RX_BUF_PADDED)
178 skb_pull(skb, NET_IP_ALIGN);
179
164 *hlid = desc->hlid; 180 *hlid = desc->hlid;
165 181
166 hdr = (struct ieee80211_hdr *)skb->data; 182 hdr = (struct ieee80211_hdr *)skb->data;
@@ -177,36 +193,35 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
177 beacon ? "beacon" : "", 193 beacon ? "beacon" : "",
178 seq_num, *hlid); 194 seq_num, *hlid);
179 195
180 skb_trim(skb, skb->len - desc->pad_len);
181
182 skb_queue_tail(&wl->deferred_rx_queue, skb); 196 skb_queue_tail(&wl->deferred_rx_queue, skb);
183 queue_work(wl->freezable_wq, &wl->netstack_work); 197 queue_work(wl->freezable_wq, &wl->netstack_work);
184 198
185 return is_data; 199 return is_data;
186} 200}
187 201
188void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status) 202void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status)
189{ 203{
190 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
191 unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; 204 unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
192 u32 buf_size; 205 u32 buf_size;
193 u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 206 u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
194 u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 207 u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
195 u32 rx_counter; 208 u32 rx_counter;
196 u32 mem_block; 209 u32 pkt_len, align_pkt_len;
197 u32 pkt_length; 210 u32 pkt_offset, des;
198 u32 pkt_offset;
199 u8 hlid; 211 u8 hlid;
200 bool unaligned = false; 212 enum wl_rx_buf_align rx_align;
201 213
202 while (drv_rx_counter != fw_rx_counter) { 214 while (drv_rx_counter != fw_rx_counter) {
203 buf_size = 0; 215 buf_size = 0;
204 rx_counter = drv_rx_counter; 216 rx_counter = drv_rx_counter;
205 while (rx_counter != fw_rx_counter) { 217 while (rx_counter != fw_rx_counter) {
206 pkt_length = wl12xx_rx_get_buf_size(status, rx_counter); 218 des = le32_to_cpu(status->rx_pkt_descs[rx_counter]);
207 if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE) 219 pkt_len = wlcore_rx_get_buf_size(wl, des);
220 align_pkt_len = wlcore_rx_get_align_buf_size(wl,
221 pkt_len);
222 if (buf_size + align_pkt_len > WL1271_AGGR_BUFFER_SIZE)
208 break; 223 break;
209 buf_size += pkt_length; 224 buf_size += align_pkt_len;
210 rx_counter++; 225 rx_counter++;
211 rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; 226 rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
212 } 227 }
@@ -216,38 +231,18 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
216 break; 231 break;
217 } 232 }
218 233
219 if (wl->chip.id != CHIP_ID_1283_PG20) {
220 /*
221 * Choose the block we want to read
222 * For aggregated packets, only the first memory block
223 * should be retrieved. The FW takes care of the rest.
224 */
225 mem_block = wl12xx_rx_get_mem_block(status,
226 drv_rx_counter);
227
228 wl->rx_mem_pool_addr.addr = (mem_block << 8) +
229 le32_to_cpu(wl_mem_map->packet_memory_pool_start);
230
231 wl->rx_mem_pool_addr.addr_extra =
232 wl->rx_mem_pool_addr.addr + 4;
233
234 wl1271_write(wl, WL1271_SLV_REG_DATA,
235 &wl->rx_mem_pool_addr,
236 sizeof(wl->rx_mem_pool_addr), false);
237 }
238
239 /* Read all available packets at once */ 234 /* Read all available packets at once */
240 wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, 235 des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]);
241 buf_size, true); 236 wlcore_hw_prepare_read(wl, des, buf_size);
237 wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
238 buf_size, true);
242 239
243 /* Split data into separate packets */ 240 /* Split data into separate packets */
244 pkt_offset = 0; 241 pkt_offset = 0;
245 while (pkt_offset < buf_size) { 242 while (pkt_offset < buf_size) {
246 pkt_length = wl12xx_rx_get_buf_size(status, 243 des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]);
247 drv_rx_counter); 244 pkt_len = wlcore_rx_get_buf_size(wl, des);
248 245 rx_align = wlcore_hw_get_rx_buf_align(wl, des);
249 unaligned = wl12xx_rx_get_unaligned(status,
250 drv_rx_counter);
251 246
252 /* 247 /*
253 * the handle data call can only fail in memory-outage 248 * the handle data call can only fail in memory-outage
@@ -256,7 +251,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
256 */ 251 */
257 if (wl1271_rx_handle_data(wl, 252 if (wl1271_rx_handle_data(wl,
258 wl->aggr_buf + pkt_offset, 253 wl->aggr_buf + pkt_offset,
259 pkt_length, unaligned, 254 pkt_len, rx_align,
260 &hlid) == 1) { 255 &hlid) == 1) {
261 if (hlid < WL12XX_MAX_LINKS) 256 if (hlid < WL12XX_MAX_LINKS)
262 __set_bit(hlid, active_hlids); 257 __set_bit(hlid, active_hlids);
@@ -269,7 +264,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
269 wl->rx_counter++; 264 wl->rx_counter++;
270 drv_rx_counter++; 265 drv_rx_counter++;
271 drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; 266 drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
272 pkt_offset += pkt_length; 267 pkt_offset += wlcore_rx_get_align_buf_size(wl, pkt_len);
273 } 268 }
274 } 269 }
275 270
@@ -277,8 +272,9 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
277 * Write the driver's packet counter to the FW. This is only required 272 * Write the driver's packet counter to the FW. This is only required
278 * for older hardware revisions 273 * for older hardware revisions
279 */ 274 */
280 if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) 275 if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION)
281 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); 276 wl1271_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER,
277 wl->rx_counter);
282 278
283 wl12xx_rearm_rx_streaming(wl, active_hlids); 279 wl12xx_rearm_rx_streaming(wl, active_hlids);
284} 280}
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/ti/wlcore/rx.h
index 86ba6b1d0cdc..6e129e2a8546 100644
--- a/drivers/net/wireless/wl12xx/rx.h
+++ b/drivers/net/wireless/ti/wlcore/rx.h
@@ -96,9 +96,19 @@
96#define RX_MEM_BLOCK_MASK 0xFF 96#define RX_MEM_BLOCK_MASK 0xFF
97#define RX_BUF_SIZE_MASK 0xFFF00 97#define RX_BUF_SIZE_MASK 0xFFF00
98#define RX_BUF_SIZE_SHIFT_DIV 6 98#define RX_BUF_SIZE_SHIFT_DIV 6
99#define ALIGNED_RX_BUF_SIZE_MASK 0xFFFF00
100#define ALIGNED_RX_BUF_SIZE_SHIFT 8
101
99/* If set, the start of IP payload is not 4 bytes aligned */ 102/* If set, the start of IP payload is not 4 bytes aligned */
100#define RX_BUF_UNALIGNED_PAYLOAD BIT(20) 103#define RX_BUF_UNALIGNED_PAYLOAD BIT(20)
101 104
105/* Describes the alignment state of a Rx buffer */
106enum wl_rx_buf_align {
107 WLCORE_RX_BUF_ALIGNED,
108 WLCORE_RX_BUF_UNALIGNED,
109 WLCORE_RX_BUF_PADDED,
110};
111
102enum { 112enum {
103 WL12XX_RX_CLASS_UNKNOWN, 113 WL12XX_RX_CLASS_UNKNOWN,
104 WL12XX_RX_CLASS_MANAGEMENT, 114 WL12XX_RX_CLASS_MANAGEMENT,
@@ -126,7 +136,7 @@ struct wl1271_rx_descriptor {
126 u8 reserved; 136 u8 reserved;
127} __packed; 137} __packed;
128 138
129void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status); 139void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status);
130u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); 140u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
131 141
132#endif 142#endif
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
index fcba055ef196..ade21a011c45 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/ti/wlcore/scan.c
@@ -23,7 +23,7 @@
23 23
24#include <linux/ieee80211.h> 24#include <linux/ieee80211.h>
25 25
26#include "wl12xx.h" 26#include "wlcore.h"
27#include "debug.h" 27#include "debug.h"
28#include "cmd.h" 28#include "cmd.h"
29#include "scan.h" 29#include "scan.h"
@@ -417,6 +417,23 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
417 int i, j; 417 int i, j;
418 u32 flags; 418 u32 flags;
419 bool force_passive = !req->n_ssids; 419 bool force_passive = !req->n_ssids;
420 u32 min_dwell_time_active, max_dwell_time_active, delta_per_probe;
421 u32 dwell_time_passive, dwell_time_dfs;
422
423 if (band == IEEE80211_BAND_5GHZ)
424 delta_per_probe = c->dwell_time_delta_per_probe_5;
425 else
426 delta_per_probe = c->dwell_time_delta_per_probe;
427
428 min_dwell_time_active = c->base_dwell_time +
429 req->n_ssids * c->num_probe_reqs * delta_per_probe;
430
431 max_dwell_time_active = min_dwell_time_active + c->max_dwell_time_delta;
432
433 min_dwell_time_active = DIV_ROUND_UP(min_dwell_time_active, 1000);
434 max_dwell_time_active = DIV_ROUND_UP(max_dwell_time_active, 1000);
435 dwell_time_passive = DIV_ROUND_UP(c->dwell_time_passive, 1000);
436 dwell_time_dfs = DIV_ROUND_UP(c->dwell_time_dfs, 1000);
420 437
421 for (i = 0, j = start; 438 for (i = 0, j = start;
422 i < req->n_channels && j < max_channels; 439 i < req->n_channels && j < max_channels;
@@ -440,21 +457,24 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
440 req->channels[i]->flags); 457 req->channels[i]->flags);
441 wl1271_debug(DEBUG_SCAN, "max_power %d", 458 wl1271_debug(DEBUG_SCAN, "max_power %d",
442 req->channels[i]->max_power); 459 req->channels[i]->max_power);
460 wl1271_debug(DEBUG_SCAN, "min_dwell_time %d max dwell time %d",
461 min_dwell_time_active,
462 max_dwell_time_active);
443 463
444 if (flags & IEEE80211_CHAN_RADAR) { 464 if (flags & IEEE80211_CHAN_RADAR) {
445 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; 465 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
446 466
447 channels[j].passive_duration = 467 channels[j].passive_duration =
448 cpu_to_le16(c->dwell_time_dfs); 468 cpu_to_le16(dwell_time_dfs);
449 } else { 469 } else {
450 channels[j].passive_duration = 470 channels[j].passive_duration =
451 cpu_to_le16(c->dwell_time_passive); 471 cpu_to_le16(dwell_time_passive);
452 } 472 }
453 473
454 channels[j].min_duration = 474 channels[j].min_duration =
455 cpu_to_le16(c->min_dwell_time_active); 475 cpu_to_le16(min_dwell_time_active);
456 channels[j].max_duration = 476 channels[j].max_duration =
457 cpu_to_le16(c->max_dwell_time_active); 477 cpu_to_le16(max_dwell_time_active);
458 478
459 channels[j].tx_power_att = req->channels[i]->max_power; 479 channels[j].tx_power_att = req->channels[i]->max_power;
460 channels[j].channel = req->channels[i]->hw_value; 480 channels[j].channel = req->channels[i]->hw_value;
diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/ti/wlcore/scan.h
index 96ff457a3a0b..81ee36ac2078 100644
--- a/drivers/net/wireless/wl12xx/scan.h
+++ b/drivers/net/wireless/ti/wlcore/scan.h
@@ -24,7 +24,7 @@
24#ifndef __SCAN_H__ 24#ifndef __SCAN_H__
25#define __SCAN_H__ 25#define __SCAN_H__
26 26
27#include "wl12xx.h" 27#include "wlcore.h"
28 28
29int wl1271_scan(struct wl1271 *wl, struct ieee80211_vif *vif, 29int wl1271_scan(struct wl1271 *wl, struct ieee80211_vif *vif,
30 const u8 *ssid, size_t ssid_len, 30 const u8 *ssid, size_t ssid_len,
@@ -55,7 +55,7 @@ void wl1271_scan_sched_scan_results(struct wl1271 *wl);
55#define WL1271_SCAN_BAND_2_4_GHZ 0 55#define WL1271_SCAN_BAND_2_4_GHZ 0
56#define WL1271_SCAN_BAND_5_GHZ 1 56#define WL1271_SCAN_BAND_5_GHZ 1
57 57
58#define WL1271_SCAN_TIMEOUT 10000 /* msec */ 58#define WL1271_SCAN_TIMEOUT 30000 /* msec */
59 59
60enum { 60enum {
61 WL1271_SCAN_STATE_IDLE, 61 WL1271_SCAN_STATE_IDLE,
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 4b3c32774bae..0a72347cfc4c 100644
--- a/drivers/net/wireless/wl12xx/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -33,7 +33,7 @@
33#include <linux/wl12xx.h> 33#include <linux/wl12xx.h>
34#include <linux/pm_runtime.h> 34#include <linux/pm_runtime.h>
35 35
36#include "wl12xx.h" 36#include "wlcore.h"
37#include "wl12xx_80211.h" 37#include "wl12xx_80211.h"
38#include "io.h" 38#include "io.h"
39 39
@@ -76,7 +76,7 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf,
76 76
77 sdio_claim_host(func); 77 sdio_claim_host(func);
78 78
79 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 79 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) {
80 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); 80 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
81 dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n", 81 dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n",
82 addr, ((u8 *)buf)[0]); 82 addr, ((u8 *)buf)[0]);
@@ -105,7 +105,7 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf,
105 105
106 sdio_claim_host(func); 106 sdio_claim_host(func);
107 107
108 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 108 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) {
109 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); 109 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
110 dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n", 110 dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n",
111 addr, ((u8 *)buf)[0]); 111 addr, ((u8 *)buf)[0]);
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index 2fc18a8dcce8..553cd3cbb98c 100644
--- a/drivers/net/wireless/wl12xx/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,12 +30,10 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32 32
33#include "wl12xx.h" 33#include "wlcore.h"
34#include "wl12xx_80211.h" 34#include "wl12xx_80211.h"
35#include "io.h" 35#include "io.h"
36 36
37#include "reg.h"
38
39#define WSPI_CMD_READ 0x40000000 37#define WSPI_CMD_READ 0x40000000
40#define WSPI_CMD_WRITE 0x00000000 38#define WSPI_CMD_WRITE 0x00000000
41#define WSPI_CMD_FIXED 0x20000000 39#define WSPI_CMD_FIXED 0x20000000
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c
index b41428f5b3b2..0e59ea2cdd39 100644
--- a/drivers/net/wireless/wl12xx/testmode.c
+++ b/drivers/net/wireless/ti/wlcore/testmode.c
@@ -25,10 +25,9 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <net/genetlink.h> 26#include <net/genetlink.h>
27 27
28#include "wl12xx.h" 28#include "wlcore.h"
29#include "debug.h" 29#include "debug.h"
30#include "acx.h" 30#include "acx.h"
31#include "reg.h"
32#include "ps.h" 31#include "ps.h"
33#include "io.h" 32#include "io.h"
34 33
diff --git a/drivers/net/wireless/wl12xx/testmode.h b/drivers/net/wireless/ti/wlcore/testmode.h
index 8071654259ea..8071654259ea 100644
--- a/drivers/net/wireless/wl12xx/testmode.h
+++ b/drivers/net/wireless/ti/wlcore/testmode.h
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 43ae49143d68..6893bc207994 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -25,13 +25,19 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/etherdevice.h> 26#include <linux/etherdevice.h>
27 27
28#include "wl12xx.h" 28#include "wlcore.h"
29#include "debug.h" 29#include "debug.h"
30#include "io.h" 30#include "io.h"
31#include "reg.h"
32#include "ps.h" 31#include "ps.h"
33#include "tx.h" 32#include "tx.h"
34#include "event.h" 33#include "event.h"
34#include "hw_ops.h"
35
36/*
37 * TODO: this is here just for now, it must be removed when the data
38 * operations are in place.
39 */
40#include "../wl12xx/reg.h"
35 41
36static int wl1271_set_default_wep_key(struct wl1271 *wl, 42static int wl1271_set_default_wep_key(struct wl1271 *wl,
37 struct wl12xx_vif *wlvif, u8 id) 43 struct wl12xx_vif *wlvif, u8 id)
@@ -56,8 +62,8 @@ static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
56{ 62{
57 int id; 63 int id;
58 64
59 id = find_first_zero_bit(wl->tx_frames_map, ACX_TX_DESCRIPTORS); 65 id = find_first_zero_bit(wl->tx_frames_map, wl->num_tx_desc);
60 if (id >= ACX_TX_DESCRIPTORS) 66 if (id >= wl->num_tx_desc)
61 return -EBUSY; 67 return -EBUSY;
62 68
63 __set_bit(id, wl->tx_frames_map); 69 __set_bit(id, wl->tx_frames_map);
@@ -69,7 +75,7 @@ static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
69static void wl1271_free_tx_id(struct wl1271 *wl, int id) 75static void wl1271_free_tx_id(struct wl1271 *wl, int id)
70{ 76{
71 if (__test_and_clear_bit(id, wl->tx_frames_map)) { 77 if (__test_and_clear_bit(id, wl->tx_frames_map)) {
72 if (unlikely(wl->tx_frames_cnt == ACX_TX_DESCRIPTORS)) 78 if (unlikely(wl->tx_frames_cnt == wl->num_tx_desc))
73 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); 79 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
74 80
75 wl->tx_frames[id] = NULL; 81 wl->tx_frames[id] = NULL;
@@ -167,14 +173,15 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
167 return wlvif->dev_hlid; 173 return wlvif->dev_hlid;
168} 174}
169 175
170static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl, 176unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl,
171 unsigned int packet_length) 177 unsigned int packet_length)
172{ 178{
173 if (wl->quirks & WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT) 179 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
174 return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
175 else
176 return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE); 180 return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
181 else
182 return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
177} 183}
184EXPORT_SYMBOL(wlcore_calc_packet_alignment);
178 185
179static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, 186static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
180 struct sk_buff *skb, u32 extra, u32 buf_offset, 187 struct sk_buff *skb, u32 extra, u32 buf_offset,
@@ -182,10 +189,9 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
182{ 189{
183 struct wl1271_tx_hw_descr *desc; 190 struct wl1271_tx_hw_descr *desc;
184 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; 191 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
185 u32 len;
186 u32 total_blocks; 192 u32 total_blocks;
187 int id, ret = -EBUSY, ac; 193 int id, ret = -EBUSY, ac;
188 u32 spare_blocks = wl->tx_spare_blocks; 194 u32 spare_blocks = wl->normal_tx_spare;
189 bool is_dummy = false; 195 bool is_dummy = false;
190 196
191 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) 197 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
@@ -196,30 +202,19 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
196 if (id < 0) 202 if (id < 0)
197 return id; 203 return id;
198 204
199 /* approximate the number of blocks required for this packet 205 if (unlikely(wl12xx_is_dummy_packet(wl, skb)))
200 in the firmware */
201 len = wl12xx_calc_packet_alignment(wl, total_len);
202
203 /* in case of a dummy packet, use default amount of spare mem blocks */
204 if (unlikely(wl12xx_is_dummy_packet(wl, skb))) {
205 is_dummy = true; 206 is_dummy = true;
206 spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; 207 else if (wlvif->is_gem)
207 } 208 spare_blocks = wl->gem_tx_spare;
208 209
209 total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE + 210 total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks);
210 spare_blocks;
211 211
212 if (total_blocks <= wl->tx_blocks_available) { 212 if (total_blocks <= wl->tx_blocks_available) {
213 desc = (struct wl1271_tx_hw_descr *)skb_push( 213 desc = (struct wl1271_tx_hw_descr *)skb_push(
214 skb, total_len - skb->len); 214 skb, total_len - skb->len);
215 215
216 /* HW descriptor fields change between wl127x and wl128x */ 216 wlcore_hw_set_tx_desc_blocks(wl, desc, total_blocks,
217 if (wl->chip.id == CHIP_ID_1283_PG20) { 217 spare_blocks);
218 desc->wl128x_mem.total_mem_blocks = total_blocks;
219 } else {
220 desc->wl127x_mem.extra_blocks = spare_blocks;
221 desc->wl127x_mem.total_mem_blocks = total_blocks;
222 }
223 218
224 desc->id = id; 219 desc->id = id;
225 220
@@ -256,7 +251,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
256{ 251{
257 struct timespec ts; 252 struct timespec ts;
258 struct wl1271_tx_hw_descr *desc; 253 struct wl1271_tx_hw_descr *desc;
259 int aligned_len, ac, rate_idx; 254 int ac, rate_idx;
260 s64 hosttime; 255 s64 hosttime;
261 u16 tx_attr = 0; 256 u16 tx_attr = 0;
262 __le16 frame_control; 257 __le16 frame_control;
@@ -329,44 +324,16 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
329 } 324 }
330 325
331 tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; 326 tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
332 desc->reserved = 0;
333
334 aligned_len = wl12xx_calc_packet_alignment(wl, skb->len);
335
336 if (wl->chip.id == CHIP_ID_1283_PG20) {
337 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
338 desc->length = cpu_to_le16(aligned_len >> 2);
339
340 wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
341 "tx_attr: 0x%x len: %d life: %d mem: %d",
342 desc->hlid, tx_attr,
343 le16_to_cpu(desc->length),
344 le16_to_cpu(desc->life_time),
345 desc->wl128x_mem.total_mem_blocks);
346 } else {
347 int pad;
348
349 /* Store the aligned length in terms of words */
350 desc->length = cpu_to_le16(aligned_len >> 2);
351
352 /* calculate number of padding bytes */
353 pad = aligned_len - skb->len;
354 tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
355
356 wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d "
357 "tx_attr: 0x%x len: %d life: %d mem: %d", pad,
358 desc->hlid, tx_attr,
359 le16_to_cpu(desc->length),
360 le16_to_cpu(desc->life_time),
361 desc->wl127x_mem.total_mem_blocks);
362 }
363 327
364 /* for WEP shared auth - no fw encryption is needed */ 328 /* for WEP shared auth - no fw encryption is needed */
365 if (ieee80211_is_auth(frame_control) && 329 if (ieee80211_is_auth(frame_control) &&
366 ieee80211_has_protected(frame_control)) 330 ieee80211_has_protected(frame_control))
367 tx_attr |= TX_HW_ATTR_HOST_ENCRYPT; 331 tx_attr |= TX_HW_ATTR_HOST_ENCRYPT;
368 332
333 desc->reserved = 0;
369 desc->tx_attr = cpu_to_le16(tx_attr); 334 desc->tx_attr = cpu_to_le16(tx_attr);
335
336 wlcore_hw_set_tx_desc_data_len(wl, desc, skb);
370} 337}
371 338
372/* caller must hold wl->mutex */ 339/* caller must hold wl->mutex */
@@ -432,7 +399,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
432 * In special cases, we want to align to a specific block size 399 * In special cases, we want to align to a specific block size
433 * (eg. for wl128x with SDIO we align to 256). 400 * (eg. for wl128x with SDIO we align to 256).
434 */ 401 */
435 total_len = wl12xx_calc_packet_alignment(wl, skb->len); 402 total_len = wlcore_calc_packet_alignment(wl, skb->len);
436 403
437 memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); 404 memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
438 memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); 405 memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
@@ -718,8 +685,8 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
718 * Flush buffer and try again. 685 * Flush buffer and try again.
719 */ 686 */
720 wl1271_skb_queue_head(wl, wlvif, skb); 687 wl1271_skb_queue_head(wl, wlvif, skb);
721 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, 688 wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
722 buf_offset, true); 689 buf_offset, true);
723 sent_packets = true; 690 sent_packets = true;
724 buf_offset = 0; 691 buf_offset = 0;
725 continue; 692 continue;
@@ -753,8 +720,8 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
753 720
754out_ack: 721out_ack:
755 if (buf_offset) { 722 if (buf_offset) {
756 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, 723 wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
757 buf_offset, true); 724 buf_offset, true);
758 sent_packets = true; 725 sent_packets = true;
759 } 726 }
760 if (sent_packets) { 727 if (sent_packets) {
@@ -762,8 +729,8 @@ out_ack:
762 * Interrupt the firmware with the new packets. This is only 729 * Interrupt the firmware with the new packets. This is only
763 * required for older hardware revisions 730 * required for older hardware revisions
764 */ 731 */
765 if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) 732 if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION)
766 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, 733 wl1271_write32(wl, WL12XX_HOST_WR_ACCESS,
767 wl->tx_packets_count); 734 wl->tx_packets_count);
768 735
769 wl1271_handle_tx_low_watermark(wl); 736 wl1271_handle_tx_low_watermark(wl);
@@ -792,11 +759,20 @@ static u8 wl1271_tx_get_rate_flags(u8 rate_class_index)
792{ 759{
793 u8 flags = 0; 760 u8 flags = 0;
794 761
795 if (rate_class_index >= CONF_HW_RXTX_RATE_MCS_MIN && 762 /*
796 rate_class_index <= CONF_HW_RXTX_RATE_MCS_MAX) 763 * TODO: use wl12xx constants when this code is moved to wl12xx, as
764 * only it uses Tx-completion.
765 */
766 if (rate_class_index <= 8)
797 flags |= IEEE80211_TX_RC_MCS; 767 flags |= IEEE80211_TX_RC_MCS;
798 if (rate_class_index == CONF_HW_RXTX_RATE_MCS7_SGI) 768
769 /*
770 * TODO: use wl12xx constants when this code is moved to wl12xx, as
771 * only it uses Tx-completion.
772 */
773 if (rate_class_index == 0)
799 flags |= IEEE80211_TX_RC_SHORT_GI; 774 flags |= IEEE80211_TX_RC_SHORT_GI;
775
800 return flags; 776 return flags;
801} 777}
802 778
@@ -813,7 +789,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
813 u8 retries = 0; 789 u8 retries = 0;
814 790
815 /* check for id legality */ 791 /* check for id legality */
816 if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) { 792 if (unlikely(id >= wl->num_tx_desc || wl->tx_frames[id] == NULL)) {
817 wl1271_warning("TX result illegal id: %d", id); 793 wl1271_warning("TX result illegal id: %d", id);
818 return; 794 return;
819 } 795 }
@@ -834,7 +810,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
834 if (result->status == TX_SUCCESS) { 810 if (result->status == TX_SUCCESS) {
835 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 811 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
836 info->flags |= IEEE80211_TX_STAT_ACK; 812 info->flags |= IEEE80211_TX_STAT_ACK;
837 rate = wl1271_rate_to_idx(result->rate_class_index, 813 rate = wlcore_rate_to_idx(wl, result->rate_class_index,
838 wlvif->band); 814 wlvif->band);
839 rate_flags = wl1271_tx_get_rate_flags(result->rate_class_index); 815 rate_flags = wl1271_tx_get_rate_flags(result->rate_class_index);
840 retries = result->ack_failures; 816 retries = result->ack_failures;
@@ -929,6 +905,7 @@ void wl1271_tx_complete(struct wl1271 *wl)
929 wl->tx_results_count++; 905 wl->tx_results_count++;
930 } 906 }
931} 907}
908EXPORT_SYMBOL(wl1271_tx_complete);
932 909
933void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid) 910void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
934{ 911{
@@ -1006,7 +983,7 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
1006 if (reset_tx_queues) 983 if (reset_tx_queues)
1007 wl1271_handle_tx_low_watermark(wl); 984 wl1271_handle_tx_low_watermark(wl);
1008 985
1009 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) { 986 for (i = 0; i < wl->num_tx_desc; i++) {
1010 if (wl->tx_frames[i] == NULL) 987 if (wl->tx_frames[i] == NULL)
1011 continue; 988 continue;
1012 989
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/ti/wlcore/tx.h
index 5cf8c32d40d1..2fd6e5dc6f75 100644
--- a/drivers/net/wireless/wl12xx/tx.h
+++ b/drivers/net/wireless/ti/wlcore/tx.h
@@ -25,9 +25,6 @@
25#ifndef __TX_H__ 25#ifndef __TX_H__
26#define __TX_H__ 26#define __TX_H__
27 27
28#define TX_HW_BLOCK_SPARE_DEFAULT 1
29#define TX_HW_BLOCK_SIZE 252
30
31#define TX_HW_MGMT_PKT_LIFETIME_TU 2000 28#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
32#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000 29#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000
33 30
@@ -212,7 +209,7 @@ void wl1271_tx_complete(struct wl1271 *wl);
212void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif); 209void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif);
213void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues); 210void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
214void wl1271_tx_flush(struct wl1271 *wl); 211void wl1271_tx_flush(struct wl1271 *wl);
215u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); 212u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum ieee80211_band band);
216u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, 213u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
217 enum ieee80211_band rate_band); 214 enum ieee80211_band rate_band);
218u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set); 215u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set);
@@ -224,6 +221,8 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
224void wl1271_handle_tx_low_watermark(struct wl1271 *wl); 221void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
225bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); 222bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb);
226void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); 223void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids);
224unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl,
225 unsigned int packet_length);
227 226
228/* from main.c */ 227/* from main.c */
229void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); 228void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wlcore/wl12xx.h
index 749a15a75d38..a9b220c43e54 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wlcore/wl12xx.h
@@ -89,8 +89,6 @@
89#define WL1271_AP_BSS_INDEX 0 89#define WL1271_AP_BSS_INDEX 0
90#define WL1271_AP_DEF_BEACON_EXP 20 90#define WL1271_AP_DEF_BEACON_EXP 20
91 91
92#define ACX_TX_DESCRIPTORS 16
93
94#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) 92#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
95 93
96enum wl1271_state { 94enum wl1271_state {
@@ -105,26 +103,6 @@ enum wl12xx_fw_type {
105 WL12XX_FW_TYPE_PLT, 103 WL12XX_FW_TYPE_PLT,
106}; 104};
107 105
108enum wl1271_partition_type {
109 PART_DOWN,
110 PART_WORK,
111 PART_DRPW,
112
113 PART_TABLE_LEN
114};
115
116struct wl1271_partition {
117 u32 size;
118 u32 start;
119};
120
121struct wl1271_partition_set {
122 struct wl1271_partition mem;
123 struct wl1271_partition reg;
124 struct wl1271_partition mem2;
125 struct wl1271_partition mem3;
126};
127
128struct wl1271; 106struct wl1271;
129 107
130enum { 108enum {
@@ -167,8 +145,21 @@ struct wl1271_stats {
167 145
168#define AP_MAX_STATIONS 8 146#define AP_MAX_STATIONS 8
169 147
148struct wl_fw_packet_counters {
149 /* Cumulative counter of released packets per AC */
150 u8 tx_released_pkts[NUM_TX_QUEUES];
151
152 /* Cumulative counter of freed packets per HLID */
153 u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
154
155 /* Cumulative counter of released Voice memory blocks */
156 u8 tx_voice_released_blks;
157
158 u8 padding[3];
159} __packed;
160
170/* FW status registers */ 161/* FW status registers */
171struct wl12xx_fw_status { 162struct wl_fw_status {
172 __le32 intr; 163 __le32 intr;
173 u8 fw_rx_counter; 164 u8 fw_rx_counter;
174 u8 drv_rx_counter; 165 u8 drv_rx_counter;
@@ -195,16 +186,12 @@ struct wl12xx_fw_status {
195 /* Size (in Memory Blocks) of TX pool */ 186 /* Size (in Memory Blocks) of TX pool */
196 __le32 tx_total; 187 __le32 tx_total;
197 188
198 /* Cumulative counter of released packets per AC */ 189 struct wl_fw_packet_counters counters;
199 u8 tx_released_pkts[NUM_TX_QUEUES];
200 190
201 /* Cumulative counter of freed packets per HLID */
202 u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
203
204 /* Cumulative counter of released Voice memory blocks */
205 u8 tx_voice_released_blks;
206 u8 padding_1[3];
207 __le32 log_start_addr; 191 __le32 log_start_addr;
192
193 /* Private status to be used by the lower drivers */
194 u8 priv[0];
208} __packed; 195} __packed;
209 196
210struct wl1271_rx_mem_pool_addr { 197struct wl1271_rx_mem_pool_addr {
@@ -292,214 +279,6 @@ struct wl1271_link {
292 u8 ba_bitmap; 279 u8 ba_bitmap;
293}; 280};
294 281
295struct wl1271 {
296 struct ieee80211_hw *hw;
297 bool mac80211_registered;
298
299 struct device *dev;
300
301 void *if_priv;
302
303 struct wl1271_if_operations *if_ops;
304
305 void (*set_power)(bool enable);
306 int irq;
307 int ref_clock;
308
309 spinlock_t wl_lock;
310
311 enum wl1271_state state;
312 enum wl12xx_fw_type fw_type;
313 bool plt;
314 u8 last_vif_count;
315 struct mutex mutex;
316
317 unsigned long flags;
318
319 struct wl1271_partition_set part;
320
321 struct wl1271_chip chip;
322
323 int cmd_box_addr;
324 int event_box_addr;
325
326 u8 *fw;
327 size_t fw_len;
328 void *nvs;
329 size_t nvs_len;
330
331 s8 hw_pg_ver;
332
333 /* address read from the fuse ROM */
334 u32 fuse_oui_addr;
335 u32 fuse_nic_addr;
336
337 /* we have up to 2 MAC addresses */
338 struct mac_address addresses[2];
339 int channel;
340 u8 system_hlid;
341
342 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
343 unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
344 unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
345 unsigned long rate_policies_map[
346 BITS_TO_LONGS(WL12XX_MAX_RATE_POLICIES)];
347
348 struct list_head wlvif_list;
349
350 u8 sta_count;
351 u8 ap_count;
352
353 struct wl1271_acx_mem_map *target_mem_map;
354
355 /* Accounting for allocated / available TX blocks on HW */
356 u32 tx_blocks_freed;
357 u32 tx_blocks_available;
358 u32 tx_allocated_blocks;
359 u32 tx_results_count;
360
361 /* amount of spare TX blocks to use */
362 u32 tx_spare_blocks;
363
364 /* Accounting for allocated / available Tx packets in HW */
365 u32 tx_pkts_freed[NUM_TX_QUEUES];
366 u32 tx_allocated_pkts[NUM_TX_QUEUES];
367
368 /* Transmitted TX packets counter for chipset interface */
369 u32 tx_packets_count;
370
371 /* Time-offset between host and chipset clocks */
372 s64 time_offset;
373
374 /* Frames scheduled for transmission, not handled yet */
375 int tx_queue_count[NUM_TX_QUEUES];
376 long stopped_queues_map;
377
378 /* Frames received, not handled yet by mac80211 */
379 struct sk_buff_head deferred_rx_queue;
380
381 /* Frames sent, not returned yet to mac80211 */
382 struct sk_buff_head deferred_tx_queue;
383
384 struct work_struct tx_work;
385 struct workqueue_struct *freezable_wq;
386
387 /* Pending TX frames */
388 unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)];
389 struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
390 int tx_frames_cnt;
391
392 /* FW Rx counter */
393 u32 rx_counter;
394
395 /* Rx memory pool address */
396 struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
397
398 /* Intermediate buffer, used for packet aggregation */
399 u8 *aggr_buf;
400
401 /* Reusable dummy packet template */
402 struct sk_buff *dummy_packet;
403
404 /* Network stack work */
405 struct work_struct netstack_work;
406
407 /* FW log buffer */
408 u8 *fwlog;
409
410 /* Number of valid bytes in the FW log buffer */
411 ssize_t fwlog_size;
412
413 /* Sysfs FW log entry readers wait queue */
414 wait_queue_head_t fwlog_waitq;
415
416 /* Hardware recovery work */
417 struct work_struct recovery_work;
418
419 /* The mbox event mask */
420 u32 event_mask;
421
422 /* Mailbox pointers */
423 u32 mbox_ptr[2];
424
425 /* Are we currently scanning */
426 struct ieee80211_vif *scan_vif;
427 struct wl1271_scan scan;
428 struct delayed_work scan_complete_work;
429
430 bool sched_scanning;
431
432 /* The current band */
433 enum ieee80211_band band;
434
435 struct completion *elp_compl;
436 struct delayed_work elp_work;
437
438 /* in dBm */
439 int power_level;
440
441 struct wl1271_stats stats;
442
443 __le32 buffer_32;
444 u32 buffer_cmd;
445 u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
446
447 struct wl12xx_fw_status *fw_status;
448 struct wl1271_tx_hw_res_if *tx_res_if;
449
450 /* Current chipset configuration */
451 struct conf_drv_settings conf;
452
453 bool sg_enabled;
454
455 bool enable_11a;
456
457 /* Most recently reported noise in dBm */
458 s8 noise;
459
460 /* bands supported by this instance of wl12xx */
461 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
462
463 int tcxo_clock;
464
465 /*
466 * wowlan trigger was configured during suspend.
467 * (currently, only "ANY" trigger is supported)
468 */
469 bool wow_enabled;
470 bool irq_wake_enabled;
471
472 /*
473 * AP-mode - links indexed by HLID. The global and broadcast links
474 * are always active.
475 */
476 struct wl1271_link links[WL12XX_MAX_LINKS];
477
478 /* AP-mode - a bitmap of links currently in PS mode according to FW */
479 u32 ap_fw_ps_map;
480
481 /* AP-mode - a bitmap of links currently in PS mode in mac80211 */
482 unsigned long ap_ps_map;
483
484 /* Quirks of specific hardware revisions */
485 unsigned int quirks;
486
487 /* Platform limitations */
488 unsigned int platform_quirks;
489
490 /* number of currently active RX BA sessions */
491 int ba_rx_session_count;
492
493 /* AP-mode - number of currently connected stations */
494 int active_sta_count;
495
496 /* last wlvif we transmitted from */
497 struct wl12xx_vif *last_wlvif;
498
499 /* work to fire when Tx is stuck */
500 struct delayed_work tx_watchdog_work;
501};
502
503struct wl1271_station { 282struct wl1271_station {
504 u8 hlid; 283 u8 hlid;
505}; 284};
@@ -605,6 +384,9 @@ struct wl12xx_vif {
605 struct work_struct rx_streaming_disable_work; 384 struct work_struct rx_streaming_disable_work;
606 struct timer_list rx_streaming_timer; 385 struct timer_list rx_streaming_timer;
607 386
387 /* does the current role use GEM for encryption (AP or STA) */
388 bool is_gem;
389
608 /* 390 /*
609 * This struct must be last! 391 * This struct must be last!
610 * data that has to be saved acrossed reconfigs (e.g. recovery) 392 * data that has to be saved acrossed reconfigs (e.g. recovery)
@@ -679,17 +461,6 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
679#define HW_BG_RATES_MASK 0xffff 461#define HW_BG_RATES_MASK 0xffff
680#define HW_HT_RATES_OFFSET 16 462#define HW_HT_RATES_OFFSET 16
681 463
682/* Quirks */
683
684/* Each RX/TX transaction requires an end-of-transaction transfer */
685#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
686
687/* wl127x and SPI don't support SDIO block size alignment */
688#define WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT BIT(2)
689
690/* Older firmwares did not implement the FW logger over bus feature */
691#define WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)
692
693#define WL12XX_HW_BLOCK_SIZE 256 464#define WL12XX_HW_BLOCK_SIZE 256
694 465
695#endif 466#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/ti/wlcore/wl12xx_80211.h
index 22b0bc98d7b5..22b0bc98d7b5 100644
--- a/drivers/net/wireless/wl12xx/wl12xx_80211.h
+++ b/drivers/net/wireless/ti/wlcore/wl12xx_80211.h
diff --git a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c b/drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c
index 998e95895f9d..998e95895f9d 100644
--- a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c
+++ b/drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
new file mode 100644
index 000000000000..39f9fadfebd9
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -0,0 +1,448 @@
1/*
2 * This file is part of wlcore
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#ifndef __WLCORE_H__
23#define __WLCORE_H__
24
25#include <linux/platform_device.h>
26
27#include "wl12xx.h"
28#include "event.h"
29
30/* The maximum number of Tx descriptors in all chip families */
31#define WLCORE_MAX_TX_DESCRIPTORS 32
32
33/* forward declaration */
34struct wl1271_tx_hw_descr;
35enum wl_rx_buf_align;
36
37struct wlcore_ops {
38 int (*identify_chip)(struct wl1271 *wl);
39 int (*identify_fw)(struct wl1271 *wl);
40 int (*boot)(struct wl1271 *wl);
41 void (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr,
42 void *buf, size_t len);
43 void (*ack_event)(struct wl1271 *wl);
44 u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks);
45 void (*set_tx_desc_blocks)(struct wl1271 *wl,
46 struct wl1271_tx_hw_descr *desc,
47 u32 blks, u32 spare_blks);
48 void (*set_tx_desc_data_len)(struct wl1271 *wl,
49 struct wl1271_tx_hw_descr *desc,
50 struct sk_buff *skb);
51 enum wl_rx_buf_align (*get_rx_buf_align)(struct wl1271 *wl,
52 u32 rx_desc);
53 void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len);
54 u32 (*get_rx_packet_len)(struct wl1271 *wl, void *rx_data,
55 u32 data_len);
56 void (*tx_delayed_compl)(struct wl1271 *wl);
57 void (*tx_immediate_compl)(struct wl1271 *wl);
58 int (*hw_init)(struct wl1271 *wl);
59 int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
60 u32 (*sta_get_ap_rate_mask)(struct wl1271 *wl,
61 struct wl12xx_vif *wlvif);
62 s8 (*get_pg_ver)(struct wl1271 *wl);
63 void (*get_mac)(struct wl1271 *wl);
64};
65
66enum wlcore_partitions {
67 PART_DOWN,
68 PART_WORK,
69 PART_BOOT,
70 PART_DRPW,
71 PART_TOP_PRCM_ELP_SOC,
72 PART_PHY_INIT,
73
74 PART_TABLE_LEN,
75};
76
77struct wlcore_partition {
78 u32 size;
79 u32 start;
80};
81
82struct wlcore_partition_set {
83 struct wlcore_partition mem;
84 struct wlcore_partition reg;
85 struct wlcore_partition mem2;
86 struct wlcore_partition mem3;
87};
88
89enum wlcore_registers {
90 /* register addresses, used with partition translation */
91 REG_ECPU_CONTROL,
92 REG_INTERRUPT_NO_CLEAR,
93 REG_INTERRUPT_ACK,
94 REG_COMMAND_MAILBOX_PTR,
95 REG_EVENT_MAILBOX_PTR,
96 REG_INTERRUPT_TRIG,
97 REG_INTERRUPT_MASK,
98 REG_PC_ON_RECOVERY,
99 REG_CHIP_ID_B,
100 REG_CMD_MBOX_ADDRESS,
101
102 /* data access memory addresses, used with partition translation */
103 REG_SLV_MEM_DATA,
104 REG_SLV_REG_DATA,
105
106 /* raw data access memory addresses */
107 REG_RAW_FW_STATUS_ADDR,
108
109 REG_TABLE_LEN,
110};
111
112struct wl1271 {
113 struct ieee80211_hw *hw;
114 bool mac80211_registered;
115
116 struct device *dev;
117
118 void *if_priv;
119
120 struct wl1271_if_operations *if_ops;
121
122 void (*set_power)(bool enable);
123 int irq;
124 int ref_clock;
125
126 spinlock_t wl_lock;
127
128 enum wl1271_state state;
129 enum wl12xx_fw_type fw_type;
130 bool plt;
131 u8 last_vif_count;
132 struct mutex mutex;
133
134 unsigned long flags;
135
136 struct wlcore_partition_set curr_part;
137
138 struct wl1271_chip chip;
139
140 int cmd_box_addr;
141
142 u8 *fw;
143 size_t fw_len;
144 void *nvs;
145 size_t nvs_len;
146
147 s8 hw_pg_ver;
148
149 /* address read from the fuse ROM */
150 u32 fuse_oui_addr;
151 u32 fuse_nic_addr;
152
153 /* we have up to 2 MAC addresses */
154 struct mac_address addresses[2];
155 int channel;
156 u8 system_hlid;
157
158 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
159 unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
160 unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
161 unsigned long rate_policies_map[
162 BITS_TO_LONGS(WL12XX_MAX_RATE_POLICIES)];
163
164 struct list_head wlvif_list;
165
166 u8 sta_count;
167 u8 ap_count;
168
169 struct wl1271_acx_mem_map *target_mem_map;
170
171 /* Accounting for allocated / available TX blocks on HW */
172 u32 tx_blocks_freed;
173 u32 tx_blocks_available;
174 u32 tx_allocated_blocks;
175 u32 tx_results_count;
176
177 /* Accounting for allocated / available Tx packets in HW */
178 u32 tx_pkts_freed[NUM_TX_QUEUES];
179 u32 tx_allocated_pkts[NUM_TX_QUEUES];
180
181 /* Transmitted TX packets counter for chipset interface */
182 u32 tx_packets_count;
183
184 /* Time-offset between host and chipset clocks */
185 s64 time_offset;
186
187 /* Frames scheduled for transmission, not handled yet */
188 int tx_queue_count[NUM_TX_QUEUES];
189 long stopped_queues_map;
190
191 /* Frames received, not handled yet by mac80211 */
192 struct sk_buff_head deferred_rx_queue;
193
194 /* Frames sent, not returned yet to mac80211 */
195 struct sk_buff_head deferred_tx_queue;
196
197 struct work_struct tx_work;
198 struct workqueue_struct *freezable_wq;
199
200 /* Pending TX frames */
201 unsigned long tx_frames_map[BITS_TO_LONGS(WLCORE_MAX_TX_DESCRIPTORS)];
202 struct sk_buff *tx_frames[WLCORE_MAX_TX_DESCRIPTORS];
203 int tx_frames_cnt;
204
205 /* FW Rx counter */
206 u32 rx_counter;
207
208 /* Rx memory pool address */
209 struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
210
211 /* Intermediate buffer, used for packet aggregation */
212 u8 *aggr_buf;
213
214 /* Reusable dummy packet template */
215 struct sk_buff *dummy_packet;
216
217 /* Network stack work */
218 struct work_struct netstack_work;
219
220 /* FW log buffer */
221 u8 *fwlog;
222
223 /* Number of valid bytes in the FW log buffer */
224 ssize_t fwlog_size;
225
226 /* Sysfs FW log entry readers wait queue */
227 wait_queue_head_t fwlog_waitq;
228
229 /* Hardware recovery work */
230 struct work_struct recovery_work;
231
232 /* Pointer that holds DMA-friendly block for the mailbox */
233 struct event_mailbox *mbox;
234
235 /* The mbox event mask */
236 u32 event_mask;
237
238 /* Mailbox pointers */
239 u32 mbox_ptr[2];
240
241 /* Are we currently scanning */
242 struct ieee80211_vif *scan_vif;
243 struct wl1271_scan scan;
244 struct delayed_work scan_complete_work;
245
246 bool sched_scanning;
247
248 /* The current band */
249 enum ieee80211_band band;
250
251 struct completion *elp_compl;
252 struct delayed_work elp_work;
253
254 /* in dBm */
255 int power_level;
256
257 struct wl1271_stats stats;
258
259 __le32 buffer_32;
260 u32 buffer_cmd;
261 u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
262
263 struct wl_fw_status *fw_status;
264 struct wl1271_tx_hw_res_if *tx_res_if;
265
266 /* Current chipset configuration */
267 struct wlcore_conf conf;
268
269 bool sg_enabled;
270
271 bool enable_11a;
272
273 /* Most recently reported noise in dBm */
274 s8 noise;
275
276 /* bands supported by this instance of wl12xx */
277 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
278
279 int tcxo_clock;
280
281 /*
282 * wowlan trigger was configured during suspend.
283 * (currently, only "ANY" trigger is supported)
284 */
285 bool wow_enabled;
286 bool irq_wake_enabled;
287
288 /*
289 * AP-mode - links indexed by HLID. The global and broadcast links
290 * are always active.
291 */
292 struct wl1271_link links[WL12XX_MAX_LINKS];
293
294 /* AP-mode - a bitmap of links currently in PS mode according to FW */
295 u32 ap_fw_ps_map;
296
297 /* AP-mode - a bitmap of links currently in PS mode in mac80211 */
298 unsigned long ap_ps_map;
299
300 /* Quirks of specific hardware revisions */
301 unsigned int quirks;
302
303 /* Platform limitations */
304 unsigned int platform_quirks;
305
306 /* number of currently active RX BA sessions */
307 int ba_rx_session_count;
308
309 /* AP-mode - number of currently connected stations */
310 int active_sta_count;
311
312 /* last wlvif we transmitted from */
313 struct wl12xx_vif *last_wlvif;
314
315 /* work to fire when Tx is stuck */
316 struct delayed_work tx_watchdog_work;
317
318 struct wlcore_ops *ops;
319 /* pointer to the lower driver partition table */
320 const struct wlcore_partition_set *ptable;
321 /* pointer to the lower driver register table */
322 const int *rtable;
323 /* name of the firmwares to load - for PLT, single role, multi-role */
324 const char *plt_fw_name;
325 const char *sr_fw_name;
326 const char *mr_fw_name;
327
328 /* per-chip-family private structure */
329 void *priv;
330
331 /* number of TX descriptors the HW supports. */
332 u32 num_tx_desc;
333
334 /* spare Tx blocks for normal/GEM operating modes */
335 u32 normal_tx_spare;
336 u32 gem_tx_spare;
337
338 /* translate HW Tx rates to standard rate-indices */
339 const u8 **band_rate_to_idx;
340
341 /* size of table for HW rates that can be received from chip */
342 u8 hw_tx_rate_tbl_size;
343
344 /* this HW rate and below are considered HT rates for this chip */
345 u8 hw_min_ht_rate;
346
347 /* HW HT (11n) capabilities */
348 struct ieee80211_sta_ht_cap ht_cap;
349
350 /* size of the private FW status data */
351 size_t fw_status_priv_len;
352};
353
354int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
355int __devexit wlcore_remove(struct platform_device *pdev);
356struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size);
357int wlcore_free_hw(struct wl1271 *wl);
358
359/* Firmware image load chunk size */
360#define CHUNK_SIZE 16384
361
362/* Quirks */
363
364/* Each RX/TX transaction requires an end-of-transaction transfer */
365#define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0)
366
367/* wl127x and SPI don't support SDIO block size alignment */
368#define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2)
369
370/* means aggregated Rx packets are aligned to a SDIO block */
371#define WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN BIT(3)
372
373/* Older firmwares did not implement the FW logger over bus feature */
374#define WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)
375
376/* Older firmwares use an old NVS format */
377#define WLCORE_QUIRK_LEGACY_NVS BIT(5)
378
379/* Some firmwares may not support ELP */
380#define WLCORE_QUIRK_NO_ELP BIT(6)
381
382/* TODO: move to the lower drivers when all usages are abstracted */
383#define CHIP_ID_1271_PG10 (0x4030101)
384#define CHIP_ID_1271_PG20 (0x4030111)
385#define CHIP_ID_1283_PG10 (0x05030101)
386#define CHIP_ID_1283_PG20 (0x05030111)
387
388/* TODO: move all these common registers and values elsewhere */
389#define HW_ACCESS_ELP_CTRL_REG 0x1FFFC
390
391/* ELP register commands */
392#define ELPCTRL_WAKE_UP 0x1
393#define ELPCTRL_WAKE_UP_WLAN_READY 0x5
394#define ELPCTRL_SLEEP 0x0
395/* ELP WLAN_READY bit */
396#define ELPCTRL_WLAN_READY 0x2
397
398/*************************************************************************
399
400 Interrupt Trigger Register (Host -> WiLink)
401
402**************************************************************************/
403
404/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
405
406/*
407 * The host sets this bit to inform the Wlan
408 * FW that a TX packet is in the XFER
409 * Buffer #0.
410 */
411#define INTR_TRIG_TX_PROC0 BIT(2)
412
413/*
414 * The host sets this bit to inform the FW
415 * that it read a packet from RX XFER
416 * Buffer #0.
417 */
418#define INTR_TRIG_RX_PROC0 BIT(3)
419
420#define INTR_TRIG_DEBUG_ACK BIT(4)
421
422#define INTR_TRIG_STATE_CHANGED BIT(5)
423
424/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
425
426/*
427 * The host sets this bit to inform the FW
428 * that it read a packet from RX XFER
429 * Buffer #1.
430 */
431#define INTR_TRIG_RX_PROC1 BIT(17)
432
433/*
434 * The host sets this bit to inform the Wlan
435 * hardware that a TX packet is in the XFER
436 * Buffer #1.
437 */
438#define INTR_TRIG_TX_PROC1 BIT(18)
439
440#define ACX_SLV_SOFT_RESET_BIT BIT(1)
441#define SOFT_RESET_MAX_TIME 1000000
442#define SOFT_RESET_STALL_TIME 1000
443
444#define ECPU_CONTROL_HALT 0x00000101
445
446#define WELP_ARM_COMMAND_VAL 0x4
447
448#endif /* __WLCORE_H__ */
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
deleted file mode 100644
index af08c8609c63..000000000000
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ /dev/null
@@ -1,48 +0,0 @@
1menuconfig WL12XX_MENU
2 tristate "TI wl12xx driver support"
3 depends on MAC80211 && EXPERIMENTAL
4 ---help---
5 This will enable TI wl12xx driver support for the following chips:
6 wl1271, wl1273, wl1281 and wl1283.
7 The drivers make use of the mac80211 stack.
8
9config WL12XX
10 tristate "TI wl12xx support"
11 depends on WL12XX_MENU && GENERIC_HARDIRQS
12 depends on INET
13 select FW_LOADER
14 ---help---
15 This module adds support for wireless adapters based on TI wl1271 and
16 TI wl1273 chipsets. This module does *not* include support for wl1251.
17 For wl1251 support, use the separate homonymous driver instead.
18
19 If you choose to build a module, it will be called wl12xx. Say N if
20 unsure.
21
22config WL12XX_SPI
23 tristate "TI wl12xx SPI support"
24 depends on WL12XX && SPI_MASTER
25 select CRC7
26 ---help---
27 This module adds support for the SPI interface of adapters using
28 TI wl12xx chipsets. Select this if your platform is using
29 the SPI bus.
30
31 If you choose to build a module, it'll be called wl12xx_spi.
32 Say N if unsure.
33
34config WL12XX_SDIO
35 tristate "TI wl12xx SDIO support"
36 depends on WL12XX && MMC
37 ---help---
38 This module adds support for the SDIO interface of adapters using
39 TI wl12xx chipsets. Select this if your platform is using
40 the SDIO bus.
41
42 If you choose to build a module, it'll be called wl12xx_sdio.
43 Say N if unsure.
44
45config WL12XX_PLATFORM_DATA
46 bool
47 depends on WL12XX_SDIO != n || WL1251_SDIO != n
48 default y
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
deleted file mode 100644
index 98f289c907a9..000000000000
--- a/drivers/net/wireless/wl12xx/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
1wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
2 boot.o init.o debugfs.o scan.o
3
4wl12xx_spi-objs = spi.o
5wl12xx_sdio-objs = sdio.o
6
7wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
8obj-$(CONFIG_WL12XX) += wl12xx.o
9obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o
10obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o
11
12# small builtin driver bit
13obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
14
15ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
deleted file mode 100644
index 954101d03f06..000000000000
--- a/drivers/net/wireless/wl12xx/boot.c
+++ /dev/null
@@ -1,786 +0,0 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/slab.h>
25#include <linux/wl12xx.h>
26#include <linux/export.h>
27
28#include "debug.h"
29#include "acx.h"
30#include "reg.h"
31#include "boot.h"
32#include "io.h"
33#include "event.h"
34#include "rx.h"
35
36static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
37{
38 u32 cpu_ctrl;
39
40 /* 10.5.0 run the firmware (I) */
41 cpu_ctrl = wl1271_read32(wl, ACX_REG_ECPU_CONTROL);
42
43 /* 10.5.1 run the firmware (II) */
44 cpu_ctrl |= flag;
45 wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
46}
47
48static unsigned int wl12xx_get_fw_ver_quirks(struct wl1271 *wl)
49{
50 unsigned int quirks = 0;
51 unsigned int *fw_ver = wl->chip.fw_ver;
52
53 /* Only new station firmwares support routing fw logs to the host */
54 if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
55 (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN))
56 quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED;
57
58 /* This feature is not yet supported for AP mode */
59 if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP)
60 quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED;
61
62 return quirks;
63}
64
65static void wl1271_parse_fw_ver(struct wl1271 *wl)
66{
67 int ret;
68
69 ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u",
70 &wl->chip.fw_ver[0], &wl->chip.fw_ver[1],
71 &wl->chip.fw_ver[2], &wl->chip.fw_ver[3],
72 &wl->chip.fw_ver[4]);
73
74 if (ret != 5) {
75 wl1271_warning("fw version incorrect value");
76 memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
77 return;
78 }
79
80 /* Check if any quirks are needed with older fw versions */
81 wl->quirks |= wl12xx_get_fw_ver_quirks(wl);
82}
83
84static void wl1271_boot_fw_version(struct wl1271 *wl)
85{
86 struct wl1271_static_data static_data;
87
88 wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data),
89 false);
90
91 strncpy(wl->chip.fw_ver_str, static_data.fw_version,
92 sizeof(wl->chip.fw_ver_str));
93
94 /* make sure the string is NULL-terminated */
95 wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
96
97 wl1271_parse_fw_ver(wl);
98}
99
100static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
101 size_t fw_data_len, u32 dest)
102{
103 struct wl1271_partition_set partition;
104 int addr, chunk_num, partition_limit;
105 u8 *p, *chunk;
106
107 /* whal_FwCtrl_LoadFwImageSm() */
108
109 wl1271_debug(DEBUG_BOOT, "starting firmware upload");
110
111 wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d",
112 fw_data_len, CHUNK_SIZE);
113
114 if ((fw_data_len % 4) != 0) {
115 wl1271_error("firmware length not multiple of four");
116 return -EIO;
117 }
118
119 chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL);
120 if (!chunk) {
121 wl1271_error("allocation for firmware upload chunk failed");
122 return -ENOMEM;
123 }
124
125 memcpy(&partition, &wl12xx_part_table[PART_DOWN], sizeof(partition));
126 partition.mem.start = dest;
127 wl1271_set_partition(wl, &partition);
128
129 /* 10.1 set partition limit and chunk num */
130 chunk_num = 0;
131 partition_limit = wl12xx_part_table[PART_DOWN].mem.size;
132
133 while (chunk_num < fw_data_len / CHUNK_SIZE) {
134 /* 10.2 update partition, if needed */
135 addr = dest + (chunk_num + 2) * CHUNK_SIZE;
136 if (addr > partition_limit) {
137 addr = dest + chunk_num * CHUNK_SIZE;
138 partition_limit = chunk_num * CHUNK_SIZE +
139 wl12xx_part_table[PART_DOWN].mem.size;
140 partition.mem.start = addr;
141 wl1271_set_partition(wl, &partition);
142 }
143
144 /* 10.3 upload the chunk */
145 addr = dest + chunk_num * CHUNK_SIZE;
146 p = buf + chunk_num * CHUNK_SIZE;
147 memcpy(chunk, p, CHUNK_SIZE);
148 wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
149 p, addr);
150 wl1271_write(wl, addr, chunk, CHUNK_SIZE, false);
151
152 chunk_num++;
153 }
154
155 /* 10.4 upload the last chunk */
156 addr = dest + chunk_num * CHUNK_SIZE;
157 p = buf + chunk_num * CHUNK_SIZE;
158 memcpy(chunk, p, fw_data_len % CHUNK_SIZE);
159 wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
160 fw_data_len % CHUNK_SIZE, p, addr);
161 wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
162
163 kfree(chunk);
164 return 0;
165}
166
167static int wl1271_boot_upload_firmware(struct wl1271 *wl)
168{
169 u32 chunks, addr, len;
170 int ret = 0;
171 u8 *fw;
172
173 fw = wl->fw;
174 chunks = be32_to_cpup((__be32 *) fw);
175 fw += sizeof(u32);
176
177 wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks);
178
179 while (chunks--) {
180 addr = be32_to_cpup((__be32 *) fw);
181 fw += sizeof(u32);
182 len = be32_to_cpup((__be32 *) fw);
183 fw += sizeof(u32);
184
185 if (len > 300000) {
186 wl1271_info("firmware chunk too long: %u", len);
187 return -EINVAL;
188 }
189 wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u",
190 chunks, addr, len);
191 ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
192 if (ret != 0)
193 break;
194 fw += len;
195 }
196
197 return ret;
198}
199
200static int wl1271_boot_upload_nvs(struct wl1271 *wl)
201{
202 size_t nvs_len, burst_len;
203 int i;
204 u32 dest_addr, val;
205 u8 *nvs_ptr, *nvs_aligned;
206
207 if (wl->nvs == NULL)
208 return -ENODEV;
209
210 if (wl->chip.id == CHIP_ID_1283_PG20) {
211 struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
212
213 if (wl->nvs_len == sizeof(struct wl128x_nvs_file)) {
214 if (nvs->general_params.dual_mode_select)
215 wl->enable_11a = true;
216 } else {
217 wl1271_error("nvs size is not as expected: %zu != %zu",
218 wl->nvs_len,
219 sizeof(struct wl128x_nvs_file));
220 kfree(wl->nvs);
221 wl->nvs = NULL;
222 wl->nvs_len = 0;
223 return -EILSEQ;
224 }
225
226 /* only the first part of the NVS needs to be uploaded */
227 nvs_len = sizeof(nvs->nvs);
228 nvs_ptr = (u8 *)nvs->nvs;
229
230 } else {
231 struct wl1271_nvs_file *nvs =
232 (struct wl1271_nvs_file *)wl->nvs;
233 /*
234 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz
235 * band configurations) can be removed when those NVS files stop
236 * floating around.
237 */
238 if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
239 wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
240 if (nvs->general_params.dual_mode_select)
241 wl->enable_11a = true;
242 }
243
244 if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
245 (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
246 wl->enable_11a)) {
247 wl1271_error("nvs size is not as expected: %zu != %zu",
248 wl->nvs_len, sizeof(struct wl1271_nvs_file));
249 kfree(wl->nvs);
250 wl->nvs = NULL;
251 wl->nvs_len = 0;
252 return -EILSEQ;
253 }
254
255 /* only the first part of the NVS needs to be uploaded */
256 nvs_len = sizeof(nvs->nvs);
257 nvs_ptr = (u8 *) nvs->nvs;
258 }
259
260 /* update current MAC address to NVS */
261 nvs_ptr[11] = wl->addresses[0].addr[0];
262 nvs_ptr[10] = wl->addresses[0].addr[1];
263 nvs_ptr[6] = wl->addresses[0].addr[2];
264 nvs_ptr[5] = wl->addresses[0].addr[3];
265 nvs_ptr[4] = wl->addresses[0].addr[4];
266 nvs_ptr[3] = wl->addresses[0].addr[5];
267
268 /*
269 * Layout before the actual NVS tables:
270 * 1 byte : burst length.
271 * 2 bytes: destination address.
272 * n bytes: data to burst copy.
273 *
274 * This is ended by a 0 length, then the NVS tables.
275 */
276
277 /* FIXME: Do we need to check here whether the LSB is 1? */
278 while (nvs_ptr[0]) {
279 burst_len = nvs_ptr[0];
280 dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
281
282 /*
283 * Due to our new wl1271_translate_reg_addr function,
284 * we need to add the REGISTER_BASE to the destination
285 */
286 dest_addr += REGISTERS_BASE;
287
288 /* We move our pointer to the data */
289 nvs_ptr += 3;
290
291 for (i = 0; i < burst_len; i++) {
292 if (nvs_ptr + 3 >= (u8 *) wl->nvs + nvs_len)
293 goto out_badnvs;
294
295 val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
296 | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
297
298 wl1271_debug(DEBUG_BOOT,
299 "nvs burst write 0x%x: 0x%x",
300 dest_addr, val);
301 wl1271_write32(wl, dest_addr, val);
302
303 nvs_ptr += 4;
304 dest_addr += 4;
305 }
306
307 if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
308 goto out_badnvs;
309 }
310
311 /*
312 * We've reached the first zero length, the first NVS table
313 * is located at an aligned offset which is at least 7 bytes further.
314 * NOTE: The wl->nvs->nvs element must be first, in order to
315 * simplify the casting, we assume it is at the beginning of
316 * the wl->nvs structure.
317 */
318 nvs_ptr = (u8 *)wl->nvs +
319 ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
320
321 if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
322 goto out_badnvs;
323
324 nvs_len -= nvs_ptr - (u8 *)wl->nvs;
325
326 /* Now we must set the partition correctly */
327 wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
328
329 /* Copy the NVS tables to a new block to ensure alignment */
330 nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
331 if (!nvs_aligned)
332 return -ENOMEM;
333
334 /* And finally we upload the NVS tables */
335 wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
336
337 kfree(nvs_aligned);
338 return 0;
339
340out_badnvs:
341 wl1271_error("nvs data is malformed");
342 return -EILSEQ;
343}
344
345static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
346{
347 wl1271_enable_interrupts(wl);
348 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
349 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
350 wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
351}
352
353static int wl1271_boot_soft_reset(struct wl1271 *wl)
354{
355 unsigned long timeout;
356 u32 boot_data;
357
358 /* perform soft reset */
359 wl1271_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
360
361 /* SOFT_RESET is self clearing */
362 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
363 while (1) {
364 boot_data = wl1271_read32(wl, ACX_REG_SLV_SOFT_RESET);
365 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
366 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
367 break;
368
369 if (time_after(jiffies, timeout)) {
370 /* 1.2 check pWhalBus->uSelfClearTime if the
371 * timeout was reached */
372 wl1271_error("soft reset timeout");
373 return -1;
374 }
375
376 udelay(SOFT_RESET_STALL_TIME);
377 }
378
379 /* disable Rx/Tx */
380 wl1271_write32(wl, ENABLE, 0x0);
381
382 /* disable auto calibration on start*/
383 wl1271_write32(wl, SPARE_A2, 0xffff);
384
385 return 0;
386}
387
388static int wl1271_boot_run_firmware(struct wl1271 *wl)
389{
390 int loop, ret;
391 u32 chip_id, intr;
392
393 wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
394
395 chip_id = wl1271_read32(wl, CHIP_ID_B);
396
397 wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
398
399 if (chip_id != wl->chip.id) {
400 wl1271_error("chip id doesn't match after firmware boot");
401 return -EIO;
402 }
403
404 /* wait for init to complete */
405 loop = 0;
406 while (loop++ < INIT_LOOP) {
407 udelay(INIT_LOOP_DELAY);
408 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
409
410 if (intr == 0xffffffff) {
411 wl1271_error("error reading hardware complete "
412 "init indication");
413 return -EIO;
414 }
415 /* check that ACX_INTR_INIT_COMPLETE is enabled */
416 else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) {
417 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
418 WL1271_ACX_INTR_INIT_COMPLETE);
419 break;
420 }
421 }
422
423 if (loop > INIT_LOOP) {
424 wl1271_error("timeout waiting for the hardware to "
425 "complete initialization");
426 return -EIO;
427 }
428
429 /* get hardware config command mail box */
430 wl->cmd_box_addr = wl1271_read32(wl, REG_COMMAND_MAILBOX_PTR);
431
432 /* get hardware config event mail box */
433 wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
434
435 /* set the working partition to its "running" mode offset */
436 wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
437
438 wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
439 wl->cmd_box_addr, wl->event_box_addr);
440
441 wl1271_boot_fw_version(wl);
442
443 /*
444 * in case of full asynchronous mode the firmware event must be
445 * ready to receive event from the command mailbox
446 */
447
448 /* unmask required mbox events */
449 wl->event_mask = BSS_LOSE_EVENT_ID |
450 SCAN_COMPLETE_EVENT_ID |
451 ROLE_STOP_COMPLETE_EVENT_ID |
452 RSSI_SNR_TRIGGER_0_EVENT_ID |
453 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
454 SOFT_GEMINI_SENSE_EVENT_ID |
455 PERIODIC_SCAN_REPORT_EVENT_ID |
456 PERIODIC_SCAN_COMPLETE_EVENT_ID |
457 DUMMY_PACKET_EVENT_ID |
458 PEER_REMOVE_COMPLETE_EVENT_ID |
459 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
460 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
461 INACTIVE_STA_EVENT_ID |
462 MAX_TX_RETRY_EVENT_ID |
463 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
464
465 ret = wl1271_event_unmask(wl);
466 if (ret < 0) {
467 wl1271_error("EVENT mask setting failed");
468 return ret;
469 }
470
471 wl1271_event_mbox_config(wl);
472
473 /* firmware startup completed */
474 return 0;
475}
476
477static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
478{
479 u32 polarity;
480
481 polarity = wl1271_top_reg_read(wl, OCP_REG_POLARITY);
482
483 /* We use HIGH polarity, so unset the LOW bit */
484 polarity &= ~POLARITY_LOW;
485 wl1271_top_reg_write(wl, OCP_REG_POLARITY, polarity);
486
487 return 0;
488}
489
490static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
491{
492 u16 spare_reg;
493
494 /* Mask bits [2] & [8:4] in the sys_clk_cfg register */
495 spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG);
496 if (spare_reg == 0xFFFF)
497 return -EFAULT;
498 spare_reg |= (BIT(3) | BIT(5) | BIT(6));
499 wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg);
500
501 /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
502 wl1271_top_reg_write(wl, SYS_CLK_CFG_REG,
503 WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
504
505 /* Delay execution for 15msec, to let the HW settle */
506 mdelay(15);
507
508 return 0;
509}
510
511static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
512{
513 u16 tcxo_detection;
514
515 tcxo_detection = wl1271_top_reg_read(wl, TCXO_CLK_DETECT_REG);
516 if (tcxo_detection & TCXO_DET_FAILED)
517 return false;
518
519 return true;
520}
521
522static bool wl128x_is_fref_valid(struct wl1271 *wl)
523{
524 u16 fref_detection;
525
526 fref_detection = wl1271_top_reg_read(wl, FREF_CLK_DETECT_REG);
527 if (fref_detection & FREF_CLK_DETECT_FAIL)
528 return false;
529
530 return true;
531}
532
533static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
534{
535 wl1271_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
536 wl1271_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
537 wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL);
538
539 return 0;
540}
541
542static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
543{
544 u16 spare_reg;
545 u16 pll_config;
546 u8 input_freq;
547
548 /* Mask bits [3:1] in the sys_clk_cfg register */
549 spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG);
550 if (spare_reg == 0xFFFF)
551 return -EFAULT;
552 spare_reg |= BIT(2);
553 wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg);
554
555 /* Handle special cases of the TCXO clock */
556 if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
557 wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
558 return wl128x_manually_configure_mcs_pll(wl);
559
560 /* Set the input frequency according to the selected clock source */
561 input_freq = (clk & 1) + 1;
562
563 pll_config = wl1271_top_reg_read(wl, MCS_PLL_CONFIG_REG);
564 if (pll_config == 0xFFFF)
565 return -EFAULT;
566 pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
567 pll_config |= MCS_PLL_ENABLE_HP;
568 wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
569
570 return 0;
571}
572
573/*
574 * WL128x has two clocks input - TCXO and FREF.
575 * TCXO is the main clock of the device, while FREF is used to sync
576 * between the GPS and the cellular modem.
577 * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
578 * as the WLAN/BT main clock.
579 */
580static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
581{
582 u16 sys_clk_cfg;
583
584 /* For XTAL-only modes, FREF will be used after switching from TCXO */
585 if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
586 wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
587 if (!wl128x_switch_tcxo_to_fref(wl))
588 return -EINVAL;
589 goto fref_clk;
590 }
591
592 /* Query the HW, to determine which clock source we should use */
593 sys_clk_cfg = wl1271_top_reg_read(wl, SYS_CLK_CFG_REG);
594 if (sys_clk_cfg == 0xFFFF)
595 return -EINVAL;
596 if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
597 goto fref_clk;
598
599 /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
600 if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
601 wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
602 if (!wl128x_switch_tcxo_to_fref(wl))
603 return -EINVAL;
604 goto fref_clk;
605 }
606
607 /* TCXO clock is selected */
608 if (!wl128x_is_tcxo_valid(wl))
609 return -EINVAL;
610 *selected_clock = wl->tcxo_clock;
611 goto config_mcs_pll;
612
613fref_clk:
614 /* FREF clock is selected */
615 if (!wl128x_is_fref_valid(wl))
616 return -EINVAL;
617 *selected_clock = wl->ref_clock;
618
619config_mcs_pll:
620 return wl128x_configure_mcs_pll(wl, *selected_clock);
621}
622
623static int wl127x_boot_clk(struct wl1271 *wl)
624{
625 u32 pause;
626 u32 clk;
627
628 if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
629 wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
630
631 if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
632 wl->ref_clock == CONF_REF_CLK_38_4_E ||
633 wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
634 /* ref clk: 19.2/38.4/38.4-XTAL */
635 clk = 0x3;
636 else if (wl->ref_clock == CONF_REF_CLK_26_E ||
637 wl->ref_clock == CONF_REF_CLK_52_E)
638 /* ref clk: 26/52 */
639 clk = 0x5;
640 else
641 return -EINVAL;
642
643 if (wl->ref_clock != CONF_REF_CLK_19_2_E) {
644 u16 val;
645 /* Set clock type (open drain) */
646 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
647 val &= FREF_CLK_TYPE_BITS;
648 wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
649
650 /* Set clock pull mode (no pull) */
651 val = wl1271_top_reg_read(wl, OCP_REG_CLK_PULL);
652 val |= NO_PULL;
653 wl1271_top_reg_write(wl, OCP_REG_CLK_PULL, val);
654 } else {
655 u16 val;
656 /* Set clock polarity */
657 val = wl1271_top_reg_read(wl, OCP_REG_CLK_POLARITY);
658 val &= FREF_CLK_POLARITY_BITS;
659 val |= CLK_REQ_OUTN_SEL;
660 wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
661 }
662
663 wl1271_write32(wl, PLL_PARAMETERS, clk);
664
665 pause = wl1271_read32(wl, PLL_PARAMETERS);
666
667 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
668
669 pause &= ~(WU_COUNTER_PAUSE_VAL);
670 pause |= WU_COUNTER_PAUSE_VAL;
671 wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
672
673 return 0;
674}
675
676/* uploads NVS and firmware */
677int wl1271_load_firmware(struct wl1271 *wl)
678{
679 int ret = 0;
680 u32 tmp, clk;
681 int selected_clock = -1;
682
683 if (wl->chip.id == CHIP_ID_1283_PG20) {
684 ret = wl128x_boot_clk(wl, &selected_clock);
685 if (ret < 0)
686 goto out;
687 } else {
688 ret = wl127x_boot_clk(wl);
689 if (ret < 0)
690 goto out;
691 }
692
693 /* Continue the ELP wake up sequence */
694 wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
695 udelay(500);
696
697 wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]);
698
699 /* Read-modify-write DRPW_SCRATCH_START register (see next state)
700 to be used by DRPw FW. The RTRIM value will be added by the FW
701 before taking DRPw out of reset */
702
703 wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START);
704 clk = wl1271_read32(wl, DRPW_SCRATCH_START);
705
706 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
707
708 if (wl->chip.id == CHIP_ID_1283_PG20) {
709 clk |= ((selected_clock & 0x3) << 1) << 4;
710 } else {
711 clk |= (wl->ref_clock << 1) << 4;
712 }
713
714 wl1271_write32(wl, DRPW_SCRATCH_START, clk);
715
716 wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
717
718 /* Disable interrupts */
719 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
720
721 ret = wl1271_boot_soft_reset(wl);
722 if (ret < 0)
723 goto out;
724
725 /* 2. start processing NVS file */
726 ret = wl1271_boot_upload_nvs(wl);
727 if (ret < 0)
728 goto out;
729
730 /* write firmware's last address (ie. it's length) to
731 * ACX_EEPROMLESS_IND_REG */
732 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
733
734 wl1271_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG);
735
736 tmp = wl1271_read32(wl, CHIP_ID_B);
737
738 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
739
740 /* 6. read the EEPROM parameters */
741 tmp = wl1271_read32(wl, SCR_PAD2);
742
743 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
744 * to upload_fw) */
745
746 if (wl->chip.id == CHIP_ID_1283_PG20)
747 wl1271_top_reg_write(wl, SDIO_IO_DS, wl->conf.hci_io_ds);
748
749 ret = wl1271_boot_upload_firmware(wl);
750 if (ret < 0)
751 goto out;
752
753out:
754 return ret;
755}
756EXPORT_SYMBOL_GPL(wl1271_load_firmware);
757
758int wl1271_boot(struct wl1271 *wl)
759{
760 int ret;
761
762 /* upload NVS and firmware */
763 ret = wl1271_load_firmware(wl);
764 if (ret)
765 return ret;
766
767 /* 10.5 start firmware */
768 ret = wl1271_boot_run_firmware(wl);
769 if (ret < 0)
770 goto out;
771
772 ret = wl1271_boot_write_irq_polarity(wl);
773 if (ret < 0)
774 goto out;
775
776 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
777 WL1271_ACX_ALL_EVENTS_VECTOR);
778
779 /* Enable firmware interrupts now */
780 wl1271_boot_enable_interrupts(wl);
781
782 wl1271_event_mbox_config(wl);
783
784out:
785 return ret;
786}
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h
deleted file mode 100644
index c3adc09f403d..000000000000
--- a/drivers/net/wireless/wl12xx/boot.h
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __BOOT_H__
25#define __BOOT_H__
26
27#include "wl12xx.h"
28
29int wl1271_boot(struct wl1271 *wl);
30int wl1271_load_firmware(struct wl1271 *wl);
31
32#define WL1271_NO_SUBBANDS 8
33#define WL1271_NO_POWER_LEVELS 4
34#define WL1271_FW_VERSION_MAX_LEN 20
35
36struct wl1271_static_data {
37 u8 mac_address[ETH_ALEN];
38 u8 padding[2];
39 u8 fw_version[WL1271_FW_VERSION_MAX_LEN];
40 u32 hw_version;
41 u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS];
42};
43
44/* number of times we try to read the INIT interrupt */
45#define INIT_LOOP 20000
46
47/* delay between retries */
48#define INIT_LOOP_DELAY 50
49
50#define WU_COUNTER_PAUSE_VAL 0x3FF
51#define WELP_ARM_COMMAND_VAL 0x4
52
53#define OCP_REG_POLARITY 0x0064
54#define OCP_REG_CLK_TYPE 0x0448
55#define OCP_REG_CLK_POLARITY 0x0cb2
56#define OCP_REG_CLK_PULL 0x0cb4
57
58#define CMD_MBOX_ADDRESS 0x407B4
59
60#define POLARITY_LOW BIT(1)
61#define NO_PULL (BIT(14) | BIT(15))
62
63#define FREF_CLK_TYPE_BITS 0xfffffe7f
64#define CLK_REQ_PRCM 0x100
65#define FREF_CLK_POLARITY_BITS 0xfffff8ff
66#define CLK_REQ_OUTN_SEL 0x700
67
68/* PLL configuration algorithm for wl128x */
69#define SYS_CLK_CFG_REG 0x2200
70/* Bit[0] - 0-TCXO, 1-FREF */
71#define MCS_PLL_CLK_SEL_FREF BIT(0)
72/* Bit[3:2] - 01-TCXO, 10-FREF */
73#define WL_CLK_REQ_TYPE_FREF BIT(3)
74#define WL_CLK_REQ_TYPE_PG2 (BIT(3) | BIT(2))
75/* Bit[4] - 0-TCXO, 1-FREF */
76#define PRCM_CM_EN_MUX_WLAN_FREF BIT(4)
77
78#define TCXO_ILOAD_INT_REG 0x2264
79#define TCXO_CLK_DETECT_REG 0x2266
80
81#define TCXO_DET_FAILED BIT(4)
82
83#define FREF_ILOAD_INT_REG 0x2084
84#define FREF_CLK_DETECT_REG 0x2086
85#define FREF_CLK_DETECT_FAIL BIT(4)
86
87/* Use this reg for masking during driver access */
88#define WL_SPARE_REG 0x2320
89#define WL_SPARE_VAL BIT(2)
90/* Bit[6:5:3] - mask wl write SYS_CLK_CFG[8:5:2:4] */
91#define WL_SPARE_MASK_8526 (BIT(6) | BIT(5) | BIT(3))
92
93#define PLL_LOCK_COUNTERS_REG 0xD8C
94#define PLL_LOCK_COUNTERS_COEX 0x0F
95#define PLL_LOCK_COUNTERS_MCS 0xF0
96#define MCS_PLL_OVERRIDE_REG 0xD90
97#define MCS_PLL_CONFIG_REG 0xD92
98#define MCS_SEL_IN_FREQ_MASK 0x0070
99#define MCS_SEL_IN_FREQ_SHIFT 4
100#define MCS_PLL_CONFIG_REG_VAL 0x73
101#define MCS_PLL_ENABLE_HP (BIT(0) | BIT(1))
102
103#define MCS_PLL_M_REG 0xD94
104#define MCS_PLL_N_REG 0xD96
105#define MCS_PLL_M_REG_VAL 0xC8
106#define MCS_PLL_N_REG_VAL 0x07
107
108#define SDIO_IO_DS 0xd14
109
110/* SDIO/wSPI DS configuration values */
111enum {
112 HCI_IO_DS_8MA = 0,
113 HCI_IO_DS_4MA = 1, /* default */
114 HCI_IO_DS_6MA = 2,
115 HCI_IO_DS_2MA = 3,
116};
117
118/* end PLL configuration algorithm for wl128x */
119
120#endif