Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorWey-Yi Guy <wey-yi.w.guy@intel.com>
Thu, 8 Mar 2012 19:13:29 +0000 (11:13 -0800)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Thu, 8 Mar 2012 19:13:29 +0000 (11:13 -0800)
481 files changed:
Documentation/DocBook/80211.tmpl
MAINTAINERS
arch/mips/bcm47xx/Makefile
arch/mips/bcm47xx/nvram.c
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/sprom.c [new file with mode: 0644]
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
arch/mips/include/asm/mach-bcm47xx/nvram.h
arch/mips/pci/pci-bcm47xx.c
drivers/bcma/bcma_private.h
drivers/bcma/driver_chipcommon_pmu.c
drivers/bcma/driver_pci.c
drivers/bcma/driver_pci_host.c
drivers/bcma/host_pci.c
drivers/bcma/main.c
drivers/bcma/scan.c
drivers/bcma/sprom.c
drivers/bluetooth/btusb.c
drivers/net/wireless/airo.c
drivers/net/wireless/ath/ath5k/ahb.c
drivers/net/wireless/ath/ath5k/ath5k.h
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/ath/ath5k/reset.c
drivers/net/wireless/ath/ath6kl/Kconfig
drivers/net/wireless/ath/ath6kl/Makefile
drivers/net/wireless/ath/ath6kl/bmi.c
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/cfg80211.h
drivers/net/wireless/ath/ath6kl/common.h
drivers/net/wireless/ath/ath6kl/core.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/core.h
drivers/net/wireless/ath/ath6kl/debug.c
drivers/net/wireless/ath/ath6kl/debug.h
drivers/net/wireless/ath/ath6kl/hif.c
drivers/net/wireless/ath/ath6kl/htc.c
drivers/net/wireless/ath/ath6kl/init.c
drivers/net/wireless/ath/ath6kl/main.c
drivers/net/wireless/ath/ath6kl/sdio.c
drivers/net/wireless/ath/ath6kl/testmode.c
drivers/net/wireless/ath/ath6kl/testmode.h
drivers/net/wireless/ath/ath6kl/txrx.c
drivers/net/wireless/ath/ath6kl/usb.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.h
drivers/net/wireless/ath/ath9k/Kconfig
drivers/net/wireless/ath/ath9k/Makefile
drivers/net/wireless/ath/ath9k/ar5008_phy.c
drivers/net/wireless/ath/ath9k/ar9001_initvals.h
drivers/net/wireless/ath/ath9k/ar9002_hw.c
drivers/net/wireless/ath/ath9k/ar9002_initvals.h
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/ar9003_mac.c
drivers/net/wireless/ath/ath9k/ar9003_mac.h
drivers/net/wireless/ath/ath9k/ar9003_mci.c
drivers/net/wireless/ath/ath9k/ar9003_mci.h
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ar9003_phy.h
drivers/net/wireless/ath/ath9k/ar9462_1p0_initvals.h [deleted file]
drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/btcoex.c
drivers/net/wireless/ath/ath9k/btcoex.h
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/gpio.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/hif_usb.h
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/mci.c
drivers/net/wireless/ath/ath9k/mci.h
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/rc.h
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/carl9170/carl9170.h
drivers/net/wireless/ath/carl9170/fw.c
drivers/net/wireless/ath/carl9170/mac.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/carl9170/phy.c
drivers/net/wireless/ath/carl9170/tx.c
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/b43/phy_n.h
drivers/net/wireless/b43/tables_nphy.c
drivers/net/wireless/b43/tables_nphy.h
drivers/net/wireless/b43legacy/phy.c
drivers/net/wireless/brcm80211/Kconfig
drivers/net/wireless/brcm80211/Makefile
drivers/net/wireless/brcm80211/brcmfmac/Makefile
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
drivers/net/wireless/brcm80211/brcmfmac/dhd.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
drivers/net/wireless/brcm80211/brcmfmac/usb.c [new file with mode: 0644]
drivers/net/wireless/brcm80211/brcmfmac/usb.h [new file with mode: 0644]
drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h [new file with mode: 0644]
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
drivers/net/wireless/brcm80211/brcmsmac/dma.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
drivers/net/wireless/brcm80211/brcmsmac/main.c
drivers/net/wireless/brcm80211/brcmsmac/main.h
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
drivers/net/wireless/brcm80211/brcmsmac/srom.c
drivers/net/wireless/brcm80211/brcmutil/utils.c
drivers/net/wireless/brcm80211/include/brcmu_utils.h
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/ipw2x00/ipw2200.h
drivers/net/wireless/ipw2x00/libipw_rx.c
drivers/net/wireless/iwlegacy/3945-debug.c
drivers/net/wireless/iwlegacy/3945-mac.c
drivers/net/wireless/iwlegacy/3945-rs.c
drivers/net/wireless/iwlegacy/3945.c
drivers/net/wireless/iwlegacy/3945.h
drivers/net/wireless/iwlegacy/4965-calib.c
drivers/net/wireless/iwlegacy/4965-debug.c
drivers/net/wireless/iwlegacy/4965-mac.c
drivers/net/wireless/iwlegacy/4965-rs.c
drivers/net/wireless/iwlegacy/4965.c
drivers/net/wireless/iwlegacy/4965.h
drivers/net/wireless/iwlegacy/Kconfig
drivers/net/wireless/iwlegacy/common.c
drivers/net/wireless/iwlegacy/common.h
drivers/net/wireless/iwlegacy/debug.c
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/Makefile
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-calib.c
drivers/net/wireless/iwlwifi/iwl-agn-calib.h
drivers/net/wireless/iwlwifi/iwl-agn-hw.h
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.h
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-sta.c
drivers/net/wireless/iwlwifi/iwl-agn-tt.c
drivers/net/wireless/iwlwifi/iwl-agn-tt.h
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-bus.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-cfg.h
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/iwl-debug.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-debug.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-devtrace.c
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/iwl-drv.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-drv.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/iwlwifi/iwl-fh.h
drivers/net/wireless/iwlwifi/iwl-fw-file.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-fw.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-io.c
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-led.c
drivers/net/wireless/iwlwifi/iwl-led.h
drivers/net/wireless/iwlwifi/iwl-mac80211.c
drivers/net/wireless/iwlwifi/iwl-notif-wait.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-notif-wait.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-op-mode.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-pci.c
drivers/net/wireless/iwlwifi/iwl-power.c
drivers/net/wireless/iwlwifi/iwl-power.h
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-shared.h
drivers/net/wireless/iwlwifi/iwl-testmode.c
drivers/net/wireless/iwlwifi/iwl-testmode.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
drivers/net/wireless/iwlwifi/iwl-trans.c [deleted file]
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/iwl-ucode.c
drivers/net/wireless/iwlwifi/iwl-wifi.h [deleted file]
drivers/net/wireless/iwmc3200wifi/trace.h
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwifiex/11n_aggr.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/decl.h
drivers/net/wireless/mwifiex/fw.h
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/ioctl.h
drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sta_cmd.c
drivers/net/wireless/mwifiex/sta_cmdresp.c
drivers/net/wireless/mwifiex/sta_event.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/mwifiex/sta_rx.c
drivers/net/wireless/mwifiex/sta_tx.c
drivers/net/wireless/mwifiex/txrx.c
drivers/net/wireless/mwifiex/util.c
drivers/net/wireless/mwifiex/wmm.c
drivers/net/wireless/mwifiex/wmm.h
drivers/net/wireless/mwl8k.c
drivers/net/wireless/orinoco/orinoco_usb.c
drivers/net/wireless/p54/main.c
drivers/net/wireless/p54/p54pci.c
drivers/net/wireless/p54/p54spi.c
drivers/net/wireless/p54/txrx.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rt2x00/rt2800.h
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2800lib.h
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00lib.h
drivers/net/wireless/rt2x00/rt2x00link.c
drivers/net/wireless/rtl818x/rtl8187/dev.c
drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
drivers/net/wireless/rtlwifi/Kconfig
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/base.h
drivers/net/wireless/rtlwifi/cam.c
drivers/net/wireless/rtlwifi/cam.h
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/core.h
drivers/net/wireless/rtlwifi/debug.c
drivers/net/wireless/rtlwifi/debug.h
drivers/net/wireless/rtlwifi/efuse.c
drivers/net/wireless/rtlwifi/efuse.h
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/pci.h
drivers/net/wireless/rtlwifi/ps.c
drivers/net/wireless/rtlwifi/ps.h
drivers/net/wireless/rtlwifi/rc.c
drivers/net/wireless/rtlwifi/rc.h
drivers/net/wireless/rtlwifi/regd.c
drivers/net/wireless/rtlwifi/regd.h
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
drivers/net/wireless/rtlwifi/rtl8192c/main.c
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
drivers/net/wireless/rtlwifi/rtl8192ce/def.h
drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
drivers/net/wireless/rtlwifi/rtl8192ce/led.c
drivers/net/wireless/rtlwifi/rtl8192ce/led.h
drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
drivers/net/wireless/rtlwifi/rtl8192ce/table.c
drivers/net/wireless/rtlwifi/rtl8192ce/table.h
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
drivers/net/wireless/rtlwifi/rtl8192cu/def.h
drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
drivers/net/wireless/rtlwifi/rtl8192cu/led.c
drivers/net/wireless/rtlwifi/rtl8192cu/led.h
drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
drivers/net/wireless/rtlwifi/rtl8192cu/reg.h
drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
drivers/net/wireless/rtlwifi/rtl8192cu/table.c
drivers/net/wireless/rtlwifi/rtl8192cu/table.h
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
drivers/net/wireless/rtlwifi/rtl8192de/def.h
drivers/net/wireless/rtlwifi/rtl8192de/dm.c
drivers/net/wireless/rtlwifi/rtl8192de/dm.h
drivers/net/wireless/rtlwifi/rtl8192de/fw.c
drivers/net/wireless/rtlwifi/rtl8192de/fw.h
drivers/net/wireless/rtlwifi/rtl8192de/hw.c
drivers/net/wireless/rtlwifi/rtl8192de/hw.h
drivers/net/wireless/rtlwifi/rtl8192de/led.c
drivers/net/wireless/rtlwifi/rtl8192de/led.h
drivers/net/wireless/rtlwifi/rtl8192de/phy.c
drivers/net/wireless/rtlwifi/rtl8192de/phy.h
drivers/net/wireless/rtlwifi/rtl8192de/reg.h
drivers/net/wireless/rtlwifi/rtl8192de/rf.c
drivers/net/wireless/rtlwifi/rtl8192de/rf.h
drivers/net/wireless/rtlwifi/rtl8192de/sw.c
drivers/net/wireless/rtlwifi/rtl8192de/sw.h
drivers/net/wireless/rtlwifi/rtl8192de/table.c
drivers/net/wireless/rtlwifi/rtl8192de/table.h
drivers/net/wireless/rtlwifi/rtl8192de/trx.c
drivers/net/wireless/rtlwifi/rtl8192de/trx.h
drivers/net/wireless/rtlwifi/rtl8192se/def.h
drivers/net/wireless/rtlwifi/rtl8192se/dm.c
drivers/net/wireless/rtlwifi/rtl8192se/dm.h
drivers/net/wireless/rtlwifi/rtl8192se/fw.c
drivers/net/wireless/rtlwifi/rtl8192se/fw.h
drivers/net/wireless/rtlwifi/rtl8192se/hw.c
drivers/net/wireless/rtlwifi/rtl8192se/hw.h
drivers/net/wireless/rtlwifi/rtl8192se/led.c
drivers/net/wireless/rtlwifi/rtl8192se/led.h
drivers/net/wireless/rtlwifi/rtl8192se/phy.c
drivers/net/wireless/rtlwifi/rtl8192se/phy.h
drivers/net/wireless/rtlwifi/rtl8192se/reg.h
drivers/net/wireless/rtlwifi/rtl8192se/rf.c
drivers/net/wireless/rtlwifi/rtl8192se/rf.h
drivers/net/wireless/rtlwifi/rtl8192se/sw.c
drivers/net/wireless/rtlwifi/rtl8192se/sw.h
drivers/net/wireless/rtlwifi/rtl8192se/table.c
drivers/net/wireless/rtlwifi/rtl8192se/table.h
drivers/net/wireless/rtlwifi/rtl8192se/trx.c
drivers/net/wireless/rtlwifi/rtl8192se/trx.h
drivers/net/wireless/rtlwifi/usb.c
drivers/net/wireless/rtlwifi/usb.h
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/wireless/wl1251/Makefile
drivers/net/wireless/wl1251/boot.c
drivers/net/wireless/wl1251/io.h
drivers/net/wireless/wl1251/main.c
drivers/net/wireless/wl1251/wl1251.h
drivers/net/wireless/wl12xx/Makefile
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/boot.h
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/debug.h
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/io.c
drivers/net/wireless/wl12xx/io.h
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/ps.h
drivers/net/wireless/wl12xx/reg.h
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/scan.h
drivers/net/wireless/wl12xx/sdio.c
drivers/net/wireless/wl12xx/spi.c
drivers/net/wireless/wl12xx/testmode.c
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx_80211.h
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/nfc/nfcwilink.c
drivers/nfc/pn533.c
drivers/ssb/driver_chipcommon_pmu.c
drivers/ssb/driver_mipscore.c
drivers/ssb/main.c
drivers/ssb/pci.c
drivers/ssb/pcmcia.c
drivers/ssb/scan.c
drivers/ssb/sdio.c
drivers/ssb/ssb_private.h
include/linux/bcma/bcma.h
include/linux/bcma/bcma_driver_chipcommon.h
include/linux/bcma/bcma_driver_pci.h
include/linux/bcma/bcma_regs.h
include/linux/nfc.h
include/linux/nl80211.h
include/linux/ssb/ssb.h
include/linux/ssb/ssb_regs.h
include/net/bluetooth/bluetooth.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/l2cap.h
include/net/cfg80211.h
include/net/mac80211.h
include/net/nfc/nci.h
include/net/nfc/nci_core.h
include/net/nfc/nfc.h
net/bluetooth/af_bluetooth.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/sock.c
net/mac80211/Makefile
net/mac80211/cfg.c
net/mac80211/chan.c
net/mac80211/debugfs.c
net/mac80211/debugfs_netdev.c
net/mac80211/debugfs_sta.c
net/mac80211/driver-ops.h
net/mac80211/driver-trace.h
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/key.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mesh_hwmp.c
net/mac80211/mesh_pathtbl.c
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/pm.c
net/mac80211/rate.c
net/mac80211/rate.h
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/status.c
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/work.c
net/nfc/af_nfc.c
net/nfc/core.c
net/nfc/llcp/commands.c
net/nfc/llcp/llcp.c
net/nfc/llcp/llcp.h
net/nfc/llcp/sock.c
net/nfc/nci/core.c
net/nfc/nci/data.c
net/nfc/nci/ntf.c
net/nfc/nci/rsp.c
net/nfc/netlink.c
net/nfc/nfc.h
net/nfc/rawsock.c
net/wireless/core.h
net/wireless/mesh.c
net/wireless/mlme.c
net/wireless/nl80211.c
net/wireless/nl80211.h
net/wireless/reg.c
net/wireless/scan.c
net/wireless/sme.c
net/wireless/util.c

index 2014155c899d00c7da58f3fbab2409dc2880d139..c5ac6929c41c7cbdd068a095e37c2fef3acc70c5 100644 (file)
 !Finclude/net/cfg80211.h cfg80211_pmksa
 !Finclude/net/cfg80211.h cfg80211_send_rx_auth
 !Finclude/net/cfg80211.h cfg80211_send_auth_timeout
-!Finclude/net/cfg80211.h __cfg80211_auth_canceled
 !Finclude/net/cfg80211.h cfg80211_send_rx_assoc
 !Finclude/net/cfg80211.h cfg80211_send_assoc_timeout
 !Finclude/net/cfg80211.h cfg80211_send_deauth
index 75a9a5fc230acde24280a584bc7f8af994b677c7..3612de541cb39c557f574b537cdd5ae0b9046ea8 100644 (file)
@@ -1405,7 +1405,7 @@ F:        net/ax25/
 B43 WIRELESS DRIVER
 M:     Stefano Brivio <stefano.brivio@polimi.it>
 L:     linux-wireless@vger.kernel.org
-L:     b43-dev@lists.infradead.org (moderated for non-subscribers)
+L:     b43-dev@lists.infradead.org
 W:     http://linuxwireless.org/en/users/Drivers/b43
 S:     Maintained
 F:     drivers/net/wireless/b43/
@@ -1414,6 +1414,7 @@ B43LEGACY WIRELESS DRIVER
 M:     Larry Finger <Larry.Finger@lwfinger.net>
 M:     Stefano Brivio <stefano.brivio@polimi.it>
 L:     linux-wireless@vger.kernel.org
+L:     b43-dev@lists.infradead.org
 W:     http://linuxwireless.org/en/users/Drivers/b43
 S:     Maintained
 F:     drivers/net/wireless/b43legacy/
@@ -1567,7 +1568,6 @@ F:        drivers/net/ethernet/broadcom/tg3.*
 
 BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
 M:     Brett Rudley <brudley@broadcom.com>
-M:     Henry Ptasinski <henryp@broadcom.com>
 M:     Roland Vossen <rvossen@broadcom.com>
 M:     Arend van Spriel <arend@broadcom.com>
 M:     Franky (Zhenhui) Lin <frankyl@broadcom.com>
@@ -4910,8 +4910,6 @@ F:        fs/ocfs2/
 
 ORINOCO DRIVER
 L:     linux-wireless@vger.kernel.org
-L:     orinoco-users@lists.sourceforge.net
-L:     orinoco-devel@lists.sourceforge.net
 W:     http://linuxwireless.org/en/users/Drivers/orinoco
 W:     http://www.nongnu.org/orinoco/
 S:     Orphan
index 4add17349ff9549a264da1814249ae533144e042..4389de182eb476a5cf3ff50565e7f13b86585611 100644 (file)
@@ -3,5 +3,5 @@
 # under Linux.
 #
 
-obj-y                          += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
+obj-y                          += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
 obj-$(CONFIG_BCM47XX_SSB)      += wgt634u.o
index a84e3bb7387f685bc7025e689e01e57cfa97bd21..d43ceff5be4782b7024ae0f04ad73f278d4d7486 100644 (file)
@@ -107,8 +107,7 @@ int nvram_getenv(char *name, char *val, size_t val_len)
                value = eq + 1;
                if ((eq - var) == strlen(name) &&
                        strncmp(var, name, (eq - var)) == 0) {
-                       snprintf(val, val_len, "%s", value);
-                       return 0;
+                       return snprintf(val, val_len, "%s", value);
                }
        }
        return NVRAM_ERR_ENVNOTFOUND;
index aab6b0c40a7569b54767c5e473e75da5ba5b8563..19780aa917081e0ce547c63e1ffc8fff9d8723be 100644 (file)
@@ -3,7 +3,7 @@
  *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
  *  Copyright (C) 2006 Michael Buesch <m@bues.ch>
  *  Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
- *  Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de>
+ *  Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
  *
  *  This program is free software; you can redistribute  it and/or modify it
  *  under  the terms of  the GNU General  Public License as published by the
@@ -85,156 +85,7 @@ static void bcm47xx_machine_halt(void)
 }
 
 #ifdef CONFIG_BCM47XX_SSB
-#define READ_FROM_NVRAM(_outvar, name, buf) \
-       if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\
-               sprom->_outvar = simple_strtoul(buf, NULL, 0);
-
-#define READ_FROM_NVRAM2(_outvar, name1, name2, buf) \
-       if (nvram_getprefix(prefix, name1, buf, sizeof(buf)) >= 0 || \
-           nvram_getprefix(prefix, name2, buf, sizeof(buf)) >= 0)\
-               sprom->_outvar = simple_strtoul(buf, NULL, 0);
-
-static inline int nvram_getprefix(const char *prefix, char *name,
-                                 char *buf, int len)
-{
-       if (prefix) {
-               char key[100];
-
-               snprintf(key, sizeof(key), "%s%s", prefix, name);
-               return nvram_getenv(key, buf, len);
-       }
-
-       return nvram_getenv(name, buf, len);
-}
-
-static u32 nvram_getu32(const char *name, char *buf, int len)
-{
-       int rv;
-       char key[100];
-       u16 var0, var1;
-
-       snprintf(key, sizeof(key), "%s0", name);
-       rv = nvram_getenv(key, buf, len);
-       /* return 0 here so this looks like unset */
-       if (rv < 0)
-               return 0;
-       var0 = simple_strtoul(buf, NULL, 0);
-
-       snprintf(key, sizeof(key), "%s1", name);
-       rv = nvram_getenv(key, buf, len);
-       if (rv < 0)
-               return 0;
-       var1 = simple_strtoul(buf, NULL, 0);
-       return var1 << 16 | var0;
-}
-
-static void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
-{
-       char buf[100];
-       u32 boardflags;
-
-       memset(sprom, 0, sizeof(struct ssb_sprom));
-
-       sprom->revision = 1; /* Fallback: Old hardware does not define this. */
-       READ_FROM_NVRAM(revision, "sromrev", buf);
-       if (nvram_getprefix(prefix, "il0macaddr", buf, sizeof(buf)) >= 0 ||
-           nvram_getprefix(prefix, "macaddr", buf, sizeof(buf)) >= 0)
-               nvram_parse_macaddr(buf, sprom->il0mac);
-       if (nvram_getprefix(prefix, "et0macaddr", buf, sizeof(buf)) >= 0)
-               nvram_parse_macaddr(buf, sprom->et0mac);
-       if (nvram_getprefix(prefix, "et1macaddr", buf, sizeof(buf)) >= 0)
-               nvram_parse_macaddr(buf, sprom->et1mac);
-       READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
-       READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
-       READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf);
-       READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf);
-       READ_FROM_NVRAM(board_rev, "boardrev", buf);
-       READ_FROM_NVRAM(country_code, "ccode", buf);
-       READ_FROM_NVRAM(ant_available_a, "aa5g", buf);
-       READ_FROM_NVRAM(ant_available_bg, "aa2g", buf);
-       READ_FROM_NVRAM(pa0b0, "pa0b0", buf);
-       READ_FROM_NVRAM(pa0b1, "pa0b1", buf);
-       READ_FROM_NVRAM(pa0b2, "pa0b2", buf);
-       READ_FROM_NVRAM(pa1b0, "pa1b0", buf);
-       READ_FROM_NVRAM(pa1b1, "pa1b1", buf);
-       READ_FROM_NVRAM(pa1b2, "pa1b2", buf);
-       READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf);
-       READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf);
-       READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf);
-       READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
-       READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
-       READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
-       READ_FROM_NVRAM2(gpio0, "ledbh0", "wl0gpio0", buf);
-       READ_FROM_NVRAM2(gpio1, "ledbh1", "wl0gpio1", buf);
-       READ_FROM_NVRAM2(gpio2, "ledbh2", "wl0gpio2", buf);
-       READ_FROM_NVRAM2(gpio3, "ledbh3", "wl0gpio3", buf);
-       READ_FROM_NVRAM2(maxpwr_bg, "maxp2ga0", "pa0maxpwr", buf);
-       READ_FROM_NVRAM2(maxpwr_al, "maxp5gla0", "pa1lomaxpwr", buf);
-       READ_FROM_NVRAM2(maxpwr_a, "maxp5ga0", "pa1maxpwr", buf);
-       READ_FROM_NVRAM2(maxpwr_ah, "maxp5gha0", "pa1himaxpwr", buf);
-       READ_FROM_NVRAM2(itssi_bg, "itt5ga0", "pa0itssit", buf);
-       READ_FROM_NVRAM2(itssi_a, "itt2ga0", "pa1itssit", buf);
-       READ_FROM_NVRAM(tri2g, "tri2g", buf);
-       READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
-       READ_FROM_NVRAM(tri5g, "tri5g", buf);
-       READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
-       READ_FROM_NVRAM(txpid2g[0], "txpid2ga0", buf);
-       READ_FROM_NVRAM(txpid2g[1], "txpid2ga1", buf);
-       READ_FROM_NVRAM(txpid2g[2], "txpid2ga2", buf);
-       READ_FROM_NVRAM(txpid2g[3], "txpid2ga3", buf);
-       READ_FROM_NVRAM(txpid5g[0], "txpid5ga0", buf);
-       READ_FROM_NVRAM(txpid5g[1], "txpid5ga1", buf);
-       READ_FROM_NVRAM(txpid5g[2], "txpid5ga2", buf);
-       READ_FROM_NVRAM(txpid5g[3], "txpid5ga3", buf);
-       READ_FROM_NVRAM(txpid5gl[0], "txpid5gla0", buf);
-       READ_FROM_NVRAM(txpid5gl[1], "txpid5gla1", buf);
-       READ_FROM_NVRAM(txpid5gl[2], "txpid5gla2", buf);
-       READ_FROM_NVRAM(txpid5gl[3], "txpid5gla3", buf);
-       READ_FROM_NVRAM(txpid5gh[0], "txpid5gha0", buf);
-       READ_FROM_NVRAM(txpid5gh[1], "txpid5gha1", buf);
-       READ_FROM_NVRAM(txpid5gh[2], "txpid5gha2", buf);
-       READ_FROM_NVRAM(txpid5gh[3], "txpid5gha3", buf);
-       READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
-       READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
-       READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
-       READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf);
-       READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf);
-       READ_FROM_NVRAM(bxa2g, "bxa2g", buf);
-       READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf);
-       READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf);
-       READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
-       READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
-       READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
-
-       sprom->ofdm2gpo = nvram_getu32("ofdm2gpo", buf, sizeof(buf));
-       sprom->ofdm5glpo = nvram_getu32("ofdm5glpo", buf, sizeof(buf));
-       sprom->ofdm5gpo = nvram_getu32("ofdm5gpo", buf, sizeof(buf));
-       sprom->ofdm5ghpo = nvram_getu32("ofdm5ghpo", buf, sizeof(buf));
-
-       READ_FROM_NVRAM(antenna_gain.ghz24.a0, "ag0", buf);
-       READ_FROM_NVRAM(antenna_gain.ghz24.a1, "ag1", buf);
-       READ_FROM_NVRAM(antenna_gain.ghz24.a2, "ag2", buf);
-       READ_FROM_NVRAM(antenna_gain.ghz24.a3, "ag3", buf);
-       memcpy(&sprom->antenna_gain.ghz5, &sprom->antenna_gain.ghz24,
-              sizeof(sprom->antenna_gain.ghz5));
-
-       if (nvram_getprefix(prefix, "boardflags", buf, sizeof(buf)) >= 0) {
-               boardflags = simple_strtoul(buf, NULL, 0);
-               if (boardflags) {
-                       sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
-                       sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
-               }
-       }
-       if (nvram_getprefix(prefix, "boardflags2", buf, sizeof(buf)) >= 0) {
-               boardflags = simple_strtoul(buf, NULL, 0);
-               if (boardflags) {
-                       sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
-                       sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16;
-               }
-       }
-}
-
-int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
+static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
 {
        char prefix[10];
 
@@ -251,7 +102,7 @@ int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
 }
 
 static int bcm47xx_get_invariants(struct ssb_bus *bus,
-                                  struct ssb_init_invariants *iv)
+                                 struct ssb_init_invariants *iv)
 {
        char buf[20];
 
@@ -281,7 +132,7 @@ static void __init bcm47xx_register_ssb(void)
        char buf[100];
        struct ssb_mipscore *mcore;
 
-       err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom);
+       err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb);
        if (err)
                printk(KERN_WARNING "bcm47xx: someone else already registered"
                        " a ssb SPROM callback handler (err %d)\n", err);
@@ -308,10 +159,41 @@ static void __init bcm47xx_register_ssb(void)
 #endif
 
 #ifdef CONFIG_BCM47XX_BCMA
+static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
+{
+       char prefix[10];
+       struct bcma_device *core;
+
+       switch (bus->hosttype) {
+       case BCMA_HOSTTYPE_PCI:
+               snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
+                        bus->host_pci->bus->number + 1,
+                        PCI_SLOT(bus->host_pci->devfn));
+               bcm47xx_fill_sprom(out, prefix);
+               return 0;
+       case BCMA_HOSTTYPE_SOC:
+               bcm47xx_fill_sprom_ethernet(out, NULL);
+               core = bcma_find_core(bus, BCMA_CORE_80211);
+               if (core) {
+                       snprintf(prefix, sizeof(prefix), "sb/%u/",
+                                core->core_index);
+                       bcm47xx_fill_sprom(out, prefix);
+               }
+               return 0;
+       default:
+               pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
+               return -EINVAL;
+       }
+}
+
 static void __init bcm47xx_register_bcma(void)
 {
        int err;
 
+       err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma);
+       if (err)
+               pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err);
+
        err = bcma_host_soc_register(&bcm47xx_bus.bcma);
        if (err)
                panic("Failed to initialize BCMA bus (err %d)", err);
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c
new file mode 100644 (file)
index 0000000..5c8dcd2
--- /dev/null
@@ -0,0 +1,620 @@
+/*
+ *  Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
+ *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ *  Copyright (C) 2006 Michael Buesch <m@bues.ch>
+ *  Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
+ *  Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <bcm47xx.h>
+#include <nvram.h>
+
+static void create_key(const char *prefix, const char *postfix,
+                      const char *name, char *buf, int len)
+{
+       if (prefix && postfix)
+               snprintf(buf, len, "%s%s%s", prefix, name, postfix);
+       else if (prefix)
+               snprintf(buf, len, "%s%s", prefix, name);
+       else if (postfix)
+               snprintf(buf, len, "%s%s", name, postfix);
+       else
+               snprintf(buf, len, "%s", name);
+}
+
+#define NVRAM_READ_VAL(type)                                           \
+static void nvram_read_ ## type (const char *prefix,                   \
+                                const char *postfix, const char *name, \
+                                type *val, type allset)                \
+{                                                                      \
+       char buf[100];                                                  \
+       char key[40];                                                   \
+       int err;                                                        \
+       type var;                                                       \
+                                                                       \
+       create_key(prefix, postfix, name, key, sizeof(key));            \
+                                                                       \
+       err = nvram_getenv(key, buf, sizeof(buf));                      \
+       if (err < 0)                                                    \
+               return;                                                 \
+       err = kstrto ## type (buf, 0, &var);                            \
+       if (err) {                                                      \
+               pr_warn("can not parse nvram name %s with value %s"     \
+                       " got %i", key, buf, err);                      \
+               return;                                                 \
+       }                                                               \
+       if (allset && var == allset)                                    \
+               return;                                                 \
+       *val = var;                                                     \
+}
+
+NVRAM_READ_VAL(u8)
+NVRAM_READ_VAL(s8)
+NVRAM_READ_VAL(u16)
+NVRAM_READ_VAL(u32)
+
+#undef NVRAM_READ_VAL
+
+static void nvram_read_u32_2(const char *prefix, const char *name,
+                            u16 *val_lo, u16 *val_hi)
+{
+       char buf[100];
+       char key[40];
+       int err;
+       u32 val;
+
+       create_key(prefix, NULL, name, key, sizeof(key));
+
+       err = nvram_getenv(key, buf, sizeof(buf));
+       if (err < 0)
+               return;
+       err = kstrtou32(buf, 0, &val);
+       if (err) {
+               pr_warn("can not parse nvram name %s with value %s got %i",
+                       key, buf, err);
+               return;
+       }
+       *val_lo = (val & 0x0000FFFFU);
+       *val_hi = (val & 0xFFFF0000U) >> 16;
+}
+
+static void nvram_read_leddc(const char *prefix, const char *name,
+                            u8 *leddc_on_time, u8 *leddc_off_time)
+{
+       char buf[100];
+       char key[40];
+       int err;
+       u32 val;
+
+       create_key(prefix, NULL, name, key, sizeof(key));
+
+       err = nvram_getenv(key, buf, sizeof(buf));
+       if (err < 0)
+               return;
+       err = kstrtou32(buf, 0, &val);
+       if (err) {
+               pr_warn("can not parse nvram name %s with value %s got %i",
+                       key, buf, err);
+               return;
+       }
+
+       if (val == 0xffff || val == 0xffffffff)
+               return;
+
+       *leddc_on_time = val & 0xff;
+       *leddc_off_time = (val >> 16) & 0xff;
+}
+
+static void nvram_read_macaddr(const char *prefix, const char *name,
+                              u8 (*val)[6])
+{
+       char buf[100];
+       char key[40];
+       int err;
+
+       create_key(prefix, NULL, name, key, sizeof(key));
+
+       err = nvram_getenv(key, buf, sizeof(buf));
+       if (err < 0)
+               return;
+       nvram_parse_macaddr(buf, *val);
+}
+
+static void nvram_read_alpha2(const char *prefix, const char *name,
+                            char (*val)[2])
+{
+       char buf[10];
+       char key[40];
+       int err;
+
+       create_key(prefix, NULL, name, key, sizeof(key));
+
+       err = nvram_getenv(key, buf, sizeof(buf));
+       if (err < 0)
+               return;
+       if (buf[0] == '0')
+               return;
+       if (strlen(buf) > 2) {
+               pr_warn("alpha2 is too long %s", buf);
+               return;
+       }
+       memcpy(val, buf, sizeof(val));
+}
+
+static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
+                                       const char *prefix)
+{
+       nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0);
+       nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0);
+       nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff);
+       nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff);
+       nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff);
+       nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff);
+       nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0);
+       nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0);
+       nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0);
+       nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0);
+       nvram_read_alpha2(prefix, "ccode", &sprom->alpha2);
+}
+
+static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom,
+                                     const char *prefix)
+{
+       nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0);
+       nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0);
+       nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0);
+       nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0);
+       nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0);
+       nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0);
+       nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0);
+       nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0);
+       nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0);
+       nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0);
+}
+
+static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0);
+       nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0);
+}
+
+static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom,
+                                    const char *prefix)
+{
+       nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0);
+       nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0);
+       nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0);
+       nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0);
+       nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0);
+       nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0);
+       nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0);
+       nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0);
+       nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0);
+}
+
+static void bcm47xx_fill_sprom_r2(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
+                        &sprom->boardflags_hi);
+       nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0);
+}
+
+static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0);
+       nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0);
+       nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0);
+       nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0);
+       nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0);
+       nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0);
+       nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0);
+       nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0);
+       nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0);
+       nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0);
+       nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0);
+       nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0);
+       nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0);
+       nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0);
+}
+
+static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
+                        &sprom->boardflags_hi);
+       nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0);
+       nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0);
+       nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
+                        &sprom->leddc_off_time);
+}
+
+static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom,
+                                    const char *prefix)
+{
+       nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
+                        &sprom->boardflags_hi);
+       nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo,
+                        &sprom->boardflags2_hi);
+       nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0);
+       nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0);
+       nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0);
+       nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0);
+       nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf);
+       nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf);
+       nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff);
+       nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
+                        &sprom->leddc_off_time);
+}
+
+static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0);
+       nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0);
+       nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0);
+       nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0);
+       nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0);
+       nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0);
+       nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0);
+       nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0);
+       nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0);
+}
+
+static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0);
+       nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0);
+       nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0);
+       nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0);
+       nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0);
+       nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0);
+       nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0);
+       nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0);
+}
+
+static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0);
+       nvram_read_u8(prefix, NULL, "extpagain2g",
+                     &sprom->fem.ghz2.extpa_gain, 0);
+       nvram_read_u8(prefix, NULL, "pdetrange2g",
+                     &sprom->fem.ghz2.pdet_range, 0);
+       nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0);
+       nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0);
+       nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0);
+       nvram_read_u8(prefix, NULL, "extpagain5g",
+                     &sprom->fem.ghz5.extpa_gain, 0);
+       nvram_read_u8(prefix, NULL, "pdetrange5g",
+                     &sprom->fem.ghz5.pdet_range, 0);
+       nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0);
+       nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0);
+       nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0);
+       nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0);
+       nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0);
+       nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0);
+       nvram_read_u8(prefix, NULL, "tempsense_slope",
+                     &sprom->tempsense_slope, 0);
+       nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0);
+       nvram_read_u8(prefix, NULL, "tempsense_option",
+                     &sprom->tempsense_option, 0);
+       nvram_read_u8(prefix, NULL, "freqoffset_corr",
+                     &sprom->freqoffset_corr, 0);
+       nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0);
+       nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0);
+       nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0);
+       nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0);
+       nvram_read_u8(prefix, NULL, "phycal_tempdelta",
+                     &sprom->phycal_tempdelta, 0);
+       nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0);
+       nvram_read_u8(prefix, NULL, "temps_hysteresis",
+                     &sprom->temps_hysteresis, 0);
+       nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0);
+       nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr2ga0",
+                     &sprom->rxgainerr2ga[0], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr2ga1",
+                     &sprom->rxgainerr2ga[1], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr2ga2",
+                     &sprom->rxgainerr2ga[2], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gla0",
+                     &sprom->rxgainerr5gla[0], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gla1",
+                     &sprom->rxgainerr5gla[1], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gla2",
+                     &sprom->rxgainerr5gla[2], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gma0",
+                     &sprom->rxgainerr5gma[0], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gma1",
+                     &sprom->rxgainerr5gma[1], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gma2",
+                     &sprom->rxgainerr5gma[2], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gha0",
+                     &sprom->rxgainerr5gha[0], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gha1",
+                     &sprom->rxgainerr5gha[1], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gha2",
+                     &sprom->rxgainerr5gha[2], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gua0",
+                     &sprom->rxgainerr5gua[0], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gua1",
+                     &sprom->rxgainerr5gua[1], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gua2",
+                     &sprom->rxgainerr5gua[2], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gla0",
+                     &sprom->noiselvl5gla[0], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gla1",
+                     &sprom->noiselvl5gla[1], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gla2",
+                     &sprom->noiselvl5gla[2], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gma0",
+                     &sprom->noiselvl5gma[0], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gma1",
+                     &sprom->noiselvl5gma[1], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gma2",
+                     &sprom->noiselvl5gma[2], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gha0",
+                     &sprom->noiselvl5gha[0], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gha1",
+                     &sprom->noiselvl5gha[1], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gha2",
+                     &sprom->noiselvl5gha[2], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gua0",
+                     &sprom->noiselvl5gua[0], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gua1",
+                     &sprom->noiselvl5gua[1], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gua2",
+                     &sprom->noiselvl5gua[2], 0);
+       nvram_read_u8(prefix, NULL, "pcieingress_war",
+                     &sprom->pcieingress_war, 0);
+}
+
+static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0);
+       nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw202gpo",
+                      &sprom->legofdmbw202gpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo",
+                      &sprom->legofdmbw20ul2gpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw205glpo",
+                      &sprom->legofdmbw205glpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo",
+                      &sprom->legofdmbw20ul5glpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw205gmpo",
+                      &sprom->legofdmbw205gmpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo",
+                      &sprom->legofdmbw20ul5gmpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw205ghpo",
+                      &sprom->legofdmbw205ghpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo",
+                      &sprom->legofdmbw20ul5ghpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo",
+                      &sprom->mcsbw20ul5glpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo",
+                      &sprom->mcsbw20ul5gmpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo",
+                      &sprom->mcsbw20ul5ghpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0);
+       nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0);
+       nvram_read_u16(prefix, NULL, "legofdm40duppo",
+                      &sprom->legofdm40duppo, 0);
+       nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0);
+       nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0);
+}
+
+static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom,
+                                         const char *prefix)
+{
+       char postfix[2];
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
+               struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
+               snprintf(postfix, sizeof(postfix), "%i", i);
+               nvram_read_u8(prefix, postfix, "maxp2ga",
+                             &pwr_info->maxpwr_2g, 0);
+               nvram_read_u8(prefix, postfix, "itt2ga",
+                             &pwr_info->itssi_2g, 0);
+               nvram_read_u8(prefix, postfix, "itt5ga",
+                             &pwr_info->itssi_5g, 0);
+               nvram_read_u16(prefix, postfix, "pa2gw0a",
+                              &pwr_info->pa_2g[0], 0);
+               nvram_read_u16(prefix, postfix, "pa2gw1a",
+                              &pwr_info->pa_2g[1], 0);
+               nvram_read_u16(prefix, postfix, "pa2gw2a",
+                              &pwr_info->pa_2g[2], 0);
+               nvram_read_u8(prefix, postfix, "maxp5ga",
+                             &pwr_info->maxpwr_5g, 0);
+               nvram_read_u8(prefix, postfix, "maxp5gha",
+                             &pwr_info->maxpwr_5gh, 0);
+               nvram_read_u8(prefix, postfix, "maxp5gla",
+                             &pwr_info->maxpwr_5gl, 0);
+               nvram_read_u16(prefix, postfix, "pa5gw0a",
+                              &pwr_info->pa_5g[0], 0);
+               nvram_read_u16(prefix, postfix, "pa5gw1a",
+                              &pwr_info->pa_5g[1], 0);
+               nvram_read_u16(prefix, postfix, "pa5gw2a",
+                              &pwr_info->pa_5g[2], 0);
+               nvram_read_u16(prefix, postfix, "pa5glw0a",
+                              &pwr_info->pa_5gl[0], 0);
+               nvram_read_u16(prefix, postfix, "pa5glw1a",
+                              &pwr_info->pa_5gl[1], 0);
+               nvram_read_u16(prefix, postfix, "pa5glw2a",
+                              &pwr_info->pa_5gl[2], 0);
+               nvram_read_u16(prefix, postfix, "pa5ghw0a",
+                              &pwr_info->pa_5gh[0], 0);
+               nvram_read_u16(prefix, postfix, "pa5ghw1a",
+                              &pwr_info->pa_5gh[1], 0);
+               nvram_read_u16(prefix, postfix, "pa5ghw2a",
+                              &pwr_info->pa_5gh[2], 0);
+       }
+}
+
+static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
+                                       const char *prefix)
+{
+       char postfix[2];
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
+               struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
+               snprintf(postfix, sizeof(postfix), "%i", i);
+               nvram_read_u16(prefix, postfix, "pa2gw3a",
+                              &pwr_info->pa_2g[3], 0);
+               nvram_read_u16(prefix, postfix, "pa5gw3a",
+                              &pwr_info->pa_5g[3], 0);
+               nvram_read_u16(prefix, postfix, "pa5glw3a",
+                              &pwr_info->pa_5gl[3], 0);
+               nvram_read_u16(prefix, postfix, "pa5ghw3a",
+                              &pwr_info->pa_5gh[3], 0);
+       }
+}
+
+void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac);
+       nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0);
+       nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0);
+
+       nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac);
+       nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0);
+       nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0);
+
+       nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac);
+       nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac);
+}
+
+void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
+{
+       memset(sprom, 0, sizeof(struct ssb_sprom));
+
+       bcm47xx_fill_sprom_ethernet(sprom, prefix);
+
+       nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0);
+
+       switch (sprom->revision) {
+       case 1:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r1(sprom, prefix);
+               break;
+       case 2:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r2389(sprom, prefix);
+               bcm47xx_fill_sprom_r2(sprom, prefix);
+               break;
+       case 3:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r2389(sprom, prefix);
+               bcm47xx_fill_sprom_r389(sprom, prefix);
+               bcm47xx_fill_sprom_r3(sprom, prefix);
+               break;
+       case 4:
+       case 5:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r4589(sprom, prefix);
+               bcm47xx_fill_sprom_r458(sprom, prefix);
+               bcm47xx_fill_sprom_r45(sprom, prefix);
+               bcm47xx_fill_sprom_path_r4589(sprom, prefix);
+               bcm47xx_fill_sprom_path_r45(sprom, prefix);
+               break;
+       case 8:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r2389(sprom, prefix);
+               bcm47xx_fill_sprom_r389(sprom, prefix);
+               bcm47xx_fill_sprom_r4589(sprom, prefix);
+               bcm47xx_fill_sprom_r458(sprom, prefix);
+               bcm47xx_fill_sprom_r89(sprom, prefix);
+               bcm47xx_fill_sprom_path_r4589(sprom, prefix);
+               break;
+       case 9:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r2389(sprom, prefix);
+               bcm47xx_fill_sprom_r389(sprom, prefix);
+               bcm47xx_fill_sprom_r4589(sprom, prefix);
+               bcm47xx_fill_sprom_r89(sprom, prefix);
+               bcm47xx_fill_sprom_r9(sprom, prefix);
+               bcm47xx_fill_sprom_path_r4589(sprom, prefix);
+               break;
+       default:
+               pr_warn("Unsupported SPROM revision %d detected. Will extract"
+                       " v1\n", sprom->revision);
+               sprom->revision = 1;
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r1(sprom, prefix);
+       }
+}
index de95e0723e2bb058d3164a54c6cc9a1153b9b6e0..5ecaf47b34d2c965dac18d212497dcaf1c71a562 100644 (file)
@@ -44,4 +44,7 @@ union bcm47xx_bus {
 extern union bcm47xx_bus bcm47xx_bus;
 extern enum bcm47xx_bus_type bcm47xx_bus_type;
 
+void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix);
+void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix);
+
 #endif /* __ASM_BCM47XX_H */
index 184d5ecb5f51bbec1f7b0584adfe0e273a383a42..69ef3efe06e7ab40f5a168a5ec766031177df2d6 100644 (file)
@@ -37,7 +37,7 @@ struct nvram_header {
 
 extern int nvram_getenv(char *name, char *val, size_t val_len);
 
-static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
+static inline void nvram_parse_macaddr(char *buf, u8 macaddr[6])
 {
        if (strchr(buf, ':'))
                sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
index 400535a955d02daea0b4c96a836b5f2ac6cc8854..c682468010c518788a6f1c42fb2535476152ca9d 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/ssb/ssb.h>
+#include <linux/bcma/bcma.h>
 #include <bcm47xx.h>
 
 int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
@@ -32,15 +33,12 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
        return 0;
 }
 
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
 #ifdef CONFIG_BCM47XX_SSB
+static int bcm47xx_pcibios_plat_dev_init_ssb(struct pci_dev *dev)
+{
        int res;
        u8 slot, pin;
 
-       if (bcm47xx_bus_type !=  BCM47XX_BUS_TYPE_SSB)
-               return 0;
-
        res = ssb_pcibios_plat_dev_init(dev);
        if (res < 0) {
                printk(KERN_ALERT "PCI: Failed to init device %s\n",
@@ -60,6 +58,47 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
        }
 
        dev->irq = res;
+       return 0;
+}
 #endif
+
+#ifdef CONFIG_BCM47XX_BCMA
+static int bcm47xx_pcibios_plat_dev_init_bcma(struct pci_dev *dev)
+{
+       int res;
+
+       res = bcma_core_pci_plat_dev_init(dev);
+       if (res < 0) {
+               printk(KERN_ALERT "PCI: Failed to init device %s\n",
+                      pci_name(dev));
+               return res;
+       }
+
+       res = bcma_core_pci_pcibios_map_irq(dev);
+
+       /* IRQ-0 and IRQ-1 are software interrupts. */
+       if (res < 2) {
+               printk(KERN_ALERT "PCI: Failed to map IRQ of device %s\n",
+                      pci_name(dev));
+               return res;
+       }
+
+       dev->irq = res;
        return 0;
 }
+#endif
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+#ifdef CONFIG_BCM47XX_SSB
+       if (bcm47xx_bus_type ==  BCM47XX_BUS_TYPE_SSB)
+               return bcm47xx_pcibios_plat_dev_init_ssb(dev);
+       else
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       if  (bcm47xx_bus_type ==  BCM47XX_BUS_TYPE_BCMA)
+               return bcm47xx_pcibios_plat_dev_init_bcma(dev);
+       else
+#endif
+               return 0;
+}
index 0def898a1d159c12d2543df6ffd6264932a7affc..b81755bb47984e9c49ec2096829a47458149f359 100644 (file)
@@ -13,7 +13,7 @@
 struct bcma_bus;
 
 /* main.c */
-int bcma_bus_register(struct bcma_bus *bus);
+int __devinit bcma_bus_register(struct bcma_bus *bus);
 void bcma_bus_unregister(struct bcma_bus *bus);
 int __init bcma_bus_early_register(struct bcma_bus *bus,
                                   struct bcma_device *core_cc,
@@ -48,8 +48,12 @@ extern int __init bcma_host_pci_init(void);
 extern void __exit bcma_host_pci_exit(void);
 #endif /* CONFIG_BCMA_HOST_PCI */
 
+/* driver_pci.c */
+u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
+
 #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
-void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
+bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
+void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
 #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
 
 #endif
index 800163c8c2e7a046a4aa1219e6d7c876be0be19b..a058842f14fdf54b92b495f01c34a02ed2b74bcc 100644 (file)
@@ -80,6 +80,7 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
                min_msk = 0x200D;
                max_msk = 0xFFFF;
                break;
+       case 0x4331:
        case 43224:
        case 43225:
                break;
index 4fde6254f04e236a71ea6f755df4e106aef0f495..4d38ae179b48506164d3b5cda84f8844b8d66d21 100644 (file)
@@ -2,8 +2,9 @@
  * Broadcom specific AMBA
  * PCI Core
  *
- * Copyright 2005, Broadcom Corporation
+ * Copyright 2005, 2011, Broadcom Corporation
  * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
  *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
  * R/W ops.
  **************************************************/
 
-static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
+u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
 {
-       pcicore_write32(pc, 0x130, address);
-       pcicore_read32(pc, 0x130);
-       return pcicore_read32(pc, 0x134);
+       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
+       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
+       return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
 }
 
 #if 0
 static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
 {
-       pcicore_write32(pc, 0x130, address);
-       pcicore_read32(pc, 0x130);
-       pcicore_write32(pc, 0x134, data);
+       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
+       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
+       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
 }
 #endif
 
 static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
 {
-       const u16 mdio_control = 0x128;
-       const u16 mdio_data = 0x12C;
        u32 v;
        int i;
 
-       v = (1 << 30); /* Start of Transaction */
-       v |= (1 << 28); /* Write Transaction */
-       v |= (1 << 17); /* Turnaround */
-       v |= (0x1F << 18);
+       v = BCMA_CORE_PCI_MDIODATA_START;
+       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
+       v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
+             BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
+       v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
+             BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
+       v |= BCMA_CORE_PCI_MDIODATA_TA;
        v |= (phy << 4);
-       pcicore_write32(pc, mdio_data, v);
+       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
 
        udelay(10);
        for (i = 0; i < 200; i++) {
-               v = pcicore_read32(pc, mdio_control);
-               if (v & 0x100 /* Trans complete */)
+               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
+               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
                        break;
                msleep(1);
        }
@@ -57,79 +59,84 @@ static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
 
 static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
 {
-       const u16 mdio_control = 0x128;
-       const u16 mdio_data = 0x12C;
        int max_retries = 10;
        u16 ret = 0;
        u32 v;
        int i;
 
-       v = 0x80; /* Enable Preamble Sequence */
-       v |= 0x2; /* MDIO Clock Divisor */
-       pcicore_write32(pc, mdio_control, v);
+       /* enable mdio access to SERDES */
+       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
+       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
+       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
 
        if (pc->core->id.rev >= 10) {
                max_retries = 200;
                bcma_pcie_mdio_set_phy(pc, device);
+               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
+                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
+               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
+       } else {
+               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
+               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
        }
 
-       v = (1 << 30); /* Start of Transaction */
-       v |= (1 << 29); /* Read Transaction */
-       v |= (1 << 17); /* Turnaround */
-       if (pc->core->id.rev < 10)
-               v |= (u32)device << 22;
-       v |= (u32)address << 18;
-       pcicore_write32(pc, mdio_data, v);
+       v = BCMA_CORE_PCI_MDIODATA_START;
+       v |= BCMA_CORE_PCI_MDIODATA_READ;
+       v |= BCMA_CORE_PCI_MDIODATA_TA;
+
+       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
        /* Wait for the device to complete the transaction */
        udelay(10);
        for (i = 0; i < max_retries; i++) {
-               v = pcicore_read32(pc, mdio_control);
-               if (v & 0x100 /* Trans complete */) {
+               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
+               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
                        udelay(10);
-                       ret = pcicore_read32(pc, mdio_data);
+                       ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
                        break;
                }
                msleep(1);
        }
-       pcicore_write32(pc, mdio_control, 0);
+       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
        return ret;
 }
 
 static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
                                u8 address, u16 data)
 {
-       const u16 mdio_control = 0x128;
-       const u16 mdio_data = 0x12C;
        int max_retries = 10;
        u32 v;
        int i;
 
-       v = 0x80; /* Enable Preamble Sequence */
-       v |= 0x2; /* MDIO Clock Divisor */
-       pcicore_write32(pc, mdio_control, v);
+       /* enable mdio access to SERDES */
+       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
+       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
+       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
 
        if (pc->core->id.rev >= 10) {
                max_retries = 200;
                bcma_pcie_mdio_set_phy(pc, device);
+               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
+                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
+               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
+       } else {
+               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
+               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
        }
 
-       v = (1 << 30); /* Start of Transaction */
-       v |= (1 << 28); /* Write Transaction */
-       v |= (1 << 17); /* Turnaround */
-       if (pc->core->id.rev < 10)
-               v |= (u32)device << 22;
-       v |= (u32)address << 18;
+       v = BCMA_CORE_PCI_MDIODATA_START;
+       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
+       v |= BCMA_CORE_PCI_MDIODATA_TA;
        v |= data;
-       pcicore_write32(pc, mdio_data, v);
+       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
        /* Wait for the device to complete the transaction */
        udelay(10);
        for (i = 0; i < max_retries; i++) {
-               v = pcicore_read32(pc, mdio_control);
-               if (v & 0x100 /* Trans complete */)
+               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
+               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
                        break;
                msleep(1);
        }
-       pcicore_write32(pc, mdio_control, 0);
+       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
 }
 
 /**************************************************
@@ -138,72 +145,53 @@ static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
 
 static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
 {
-       return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
+       u32 tmp;
+
+       tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
+       if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
+               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
+                      BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
+       else
+               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
 }
 
 static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
 {
-       const u8 serdes_pll_device = 0x1D;
-       const u8 serdes_rx_device = 0x1F;
        u16 tmp;
 
-       bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
-                             bcma_pcicore_polarity_workaround(pc));
-       tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
-       if (tmp & 0x4000)
-               bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
+       bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
+                            BCMA_CORE_PCI_SERDES_RX_CTRL,
+                            bcma_pcicore_polarity_workaround(pc));
+       tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
+                                 BCMA_CORE_PCI_SERDES_PLL_CTRL);
+       if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
+               bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
+                                    BCMA_CORE_PCI_SERDES_PLL_CTRL,
+                                    tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
 }
 
 /**************************************************
  * Init.
  **************************************************/
 
-static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
+static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
 {
        bcma_pcicore_serdes_workaround(pc);
 }
 
-static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
-{
-       struct bcma_bus *bus = pc->core->bus;
-       u16 chipid_top;
-
-       chipid_top = (bus->chipinfo.id & 0xFF00);
-       if (chipid_top != 0x4700 &&
-           chipid_top != 0x5300)
-               return false;
-
-#ifdef CONFIG_SSB_DRIVER_PCICORE
-       if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
-               return false;
-#endif /* CONFIG_SSB_DRIVER_PCICORE */
-
-#if 0
-       /* TODO: on BCMA we use address from EROM instead of magic formula */
-       u32 tmp;
-       return !mips_busprobe32(tmp, (bus->mmio +
-               (pc->core->core_index * BCMA_CORE_SIZE)));
-#endif
-
-       return true;
-}
-
-void bcma_core_pci_init(struct bcma_drv_pci *pc)
+void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
 {
        if (pc->setup_done)
                return;
 
-       if (bcma_core_pci_is_in_hostmode(pc)) {
 #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
+       pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
+       if (pc->hostmode)
                bcma_core_pci_hostmode_init(pc);
-#else
-               pr_err("Driver compiled without support for hostmode PCI\n");
 #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
-       } else {
-               bcma_core_pci_clientmode_init(pc);
-       }
 
-       pc->setup_done = true;
+       if (!pc->hostmode)
+               bcma_core_pci_clientmode_init(pc);
 }
 
 int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
index eb332b75ce83d96306983725e44a5f397bf31426..4e20bcfa7ec5d3e62bdf34004601c2edca813ddc 100644 (file)
  * Broadcom specific AMBA
  * PCI Core in hostmode
  *
+ * Copyright 2005 - 2011, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
+ *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
 
 #include "bcma_private.h"
+#include <linux/export.h>
 #include <linux/bcma/bcma.h>
+#include <asm/paccess.h>
+
+/* Probe a 32bit value on the bus and catch bus exceptions.
+ * Returns nonzero on a bus exception.
+ * This is MIPS specific */
+#define mips_busprobe32(val, addr)     get_dbe((val), ((u32 *)(addr)))
+
+/* Assume one-hot slot wiring */
+#define BCMA_PCI_SLOT_MAX      16
+#define        PCI_CONFIG_SPACE_SIZE   256
+
+bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
+{
+       struct bcma_bus *bus = pc->core->bus;
+       u16 chipid_top;
+       u32 tmp;
+
+       chipid_top = (bus->chipinfo.id & 0xFF00);
+       if (chipid_top != 0x4700 &&
+           chipid_top != 0x5300)
+               return false;
+
+       if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
+               pr_info("This PCI core is disabled and not working\n");
+               return false;
+       }
+
+       bcma_core_enable(pc->core, 0);
+
+       return !mips_busprobe32(tmp, pc->core->io_addr);
+}
+
+static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address)
+{
+       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
+       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
+       return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA);
+}
+
+static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address,
+                                  u32 data)
+{
+       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
+       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
+       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data);
+}
+
+static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
+                            unsigned int func, unsigned int off)
+{
+       u32 addr = 0;
+
+       /* Issue config commands only when the data link is up (atleast
+        * one external pcie device is present).
+        */
+       if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
+                         & BCMA_CORE_PCI_DLLP_LSREG_LINKUP))
+               goto out;
+
+       /* Type 0 transaction */
+       /* Slide the PCI window to the appropriate slot */
+       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
+       /* Calculate the address */
+       addr = pc->host_controller->host_cfg_addr;
+       addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT);
+       addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT);
+       addr |= (off & ~3);
+
+out:
+       return addr;
+}
 
-void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
+static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
+                                 unsigned int func, unsigned int off,
+                                 void *buf, int len)
 {
-       pr_err("No support for PCI core in hostmode yet\n");
+       int err = -EINVAL;
+       u32 addr, val;
+       void __iomem *mmio = 0;
+
+       WARN_ON(!pc->hostmode);
+       if (unlikely(len != 1 && len != 2 && len != 4))
+               goto out;
+       if (dev == 0) {
+               /* we support only two functions on device 0 */
+               if (func > 1)
+                       return -EINVAL;
+
+               /* accesses to config registers with offsets >= 256
+                * requires indirect access.
+                */
+               if (off >= PCI_CONFIG_SPACE_SIZE) {
+                       addr = (func << 12);
+                       addr |= (off & 0x0FFF);
+                       val = bcma_pcie_read_config(pc, addr);
+               } else {
+                       addr = BCMA_CORE_PCI_PCICFG0;
+                       addr |= (func << 8);
+                       addr |= (off & 0xfc);
+                       val = pcicore_read32(pc, addr);
+               }
+       } else {
+               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
+               if (unlikely(!addr))
+                       goto out;
+               err = -ENOMEM;
+               mmio = ioremap_nocache(addr, len);
+               if (!mmio)
+                       goto out;
+
+               if (mips_busprobe32(val, mmio)) {
+                       val = 0xffffffff;
+                       goto unmap;
+               }
+
+               val = readl(mmio);
+       }
+       val >>= (8 * (off & 3));
+
+       switch (len) {
+       case 1:
+               *((u8 *)buf) = (u8)val;
+               break;
+       case 2:
+               *((u16 *)buf) = (u16)val;
+               break;
+       case 4:
+               *((u32 *)buf) = (u32)val;
+               break;
+       }
+       err = 0;
+unmap:
+       if (mmio)
+               iounmap(mmio);
+out:
+       return err;
+}
+
+static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
+                                  unsigned int func, unsigned int off,
+                                  const void *buf, int len)
+{
+       int err = -EINVAL;
+       u32 addr = 0, val = 0;
+       void __iomem *mmio = 0;
+       u16 chipid = pc->core->bus->chipinfo.id;
+
+       WARN_ON(!pc->hostmode);
+       if (unlikely(len != 1 && len != 2 && len != 4))
+               goto out;
+       if (dev == 0) {
+               /* accesses to config registers with offsets >= 256
+                * requires indirect access.
+                */
+               if (off < PCI_CONFIG_SPACE_SIZE) {
+                       addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
+                       addr |= (func << 8);
+                       addr |= (off & 0xfc);
+                       mmio = ioremap_nocache(addr, len);
+                       if (!mmio)
+                               goto out;
+               }
+       } else {
+               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
+               if (unlikely(!addr))
+                       goto out;
+               err = -ENOMEM;
+               mmio = ioremap_nocache(addr, len);
+               if (!mmio)
+                       goto out;
+
+               if (mips_busprobe32(val, mmio)) {
+                       val = 0xffffffff;
+                       goto unmap;
+               }
+       }
+
+       switch (len) {
+       case 1:
+               val = readl(mmio);
+               val &= ~(0xFF << (8 * (off & 3)));
+               val |= *((const u8 *)buf) << (8 * (off & 3));
+               break;
+       case 2:
+               val = readl(mmio);
+               val &= ~(0xFFFF << (8 * (off & 3)));
+               val |= *((const u16 *)buf) << (8 * (off & 3));
+               break;
+       case 4:
+               val = *((const u32 *)buf);
+               break;
+       }
+       if (dev == 0 && !addr) {
+               /* accesses to config registers with offsets >= 256
+                * requires indirect access.
+                */
+               addr = (func << 12);
+               addr |= (off & 0x0FFF);
+               bcma_pcie_write_config(pc, addr, val);
+       } else {
+               writel(val, mmio);
+
+               if (chipid == 0x4716 || chipid == 0x4748)
+                       readl(mmio);
+       }
+
+       err = 0;
+unmap:
+       if (mmio)
+               iounmap(mmio);
+out:
+       return err;
+}
+
+static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus,
+                                             unsigned int devfn,
+                                             int reg, int size, u32 *val)
+{
+       unsigned long flags;
+       int err;
+       struct bcma_drv_pci *pc;
+       struct bcma_drv_pci_host *pc_host;
+
+       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
+       pc = pc_host->pdev;
+
+       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
+       err = bcma_extpci_read_config(pc, PCI_SLOT(devfn),
+                                    PCI_FUNC(devfn), reg, val, size);
+       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
+
+       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+}
+
+static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus,
+                                              unsigned int devfn,
+                                              int reg, int size, u32 val)
+{
+       unsigned long flags;
+       int err;
+       struct bcma_drv_pci *pc;
+       struct bcma_drv_pci_host *pc_host;
+
+       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
+       pc = pc_host->pdev;
+
+       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
+       err = bcma_extpci_write_config(pc, PCI_SLOT(devfn),
+                                     PCI_FUNC(devfn), reg, &val, size);
+       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
+
+       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+}
+
+/* return cap_offset if requested capability exists in the PCI config space */
+static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
+                                            unsigned int dev,
+                                            unsigned int func, u8 req_cap_id,
+                                            unsigned char *buf, u32 *buflen)
+{
+       u8 cap_id;
+       u8 cap_ptr = 0;
+       u32 bufsize;
+       u8 byte_val;
+
+       /* check for Header type 0 */
+       bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
+                               sizeof(u8));
+       if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
+               return cap_ptr;
+
+       /* check if the capability pointer field exists */
+       bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val,
+                               sizeof(u8));
+       if (!(byte_val & PCI_STATUS_CAP_LIST))
+               return cap_ptr;
+
+       /* check if the capability pointer is 0x00 */
+       bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr,
+                               sizeof(u8));
+       if (cap_ptr == 0x00)
+               return cap_ptr;
+
+       /* loop thr'u the capability list and see if the requested capabilty
+        * exists */
+       bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
+       while (cap_id != req_cap_id) {
+               bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
+                                       sizeof(u8));
+               if (cap_ptr == 0x00)
+                       return cap_ptr;
+               bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
+                                       sizeof(u8));
+       }
+
+       /* found the caller requested capability */
+       if ((buf != NULL) && (buflen != NULL)) {
+               u8 cap_data;
+
+               bufsize = *buflen;
+               if (!bufsize)
+                       return cap_ptr;
+
+               *buflen = 0;
+
+               /* copy the cpability data excluding cap ID and next ptr */
+               cap_data = cap_ptr + 2;
+               if ((bufsize + cap_data)  > PCI_CONFIG_SPACE_SIZE)
+                       bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
+               *buflen = bufsize;
+               while (bufsize--) {
+                       bcma_extpci_read_config(pc, dev, func, cap_data, buf,
+                                               sizeof(u8));
+                       cap_data++;
+                       buf++;
+               }
+       }
+
+       return cap_ptr;
+}
+
+/* If the root port is capable of returning Config Request
+ * Retry Status (CRS) Completion Status to software then
+ * enable the feature.
+ */
+static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc)
+{
+       u8 cap_ptr, root_ctrl, root_cap, dev;
+       u16 val16;
+       int i;
+
+       cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL,
+                                          NULL);
+       root_cap = cap_ptr + PCI_EXP_RTCAP;
+       bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16));
+       if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) {
+               /* Enable CRS software visibility */
+               root_ctrl = cap_ptr + PCI_EXP_RTCTL;
+               val16 = PCI_EXP_RTCTL_CRSSVE;
+               bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
+                                       sizeof(u16));
+
+               /* Initiate a configuration request to read the vendor id
+                * field of the device function's config space header after
+                * 100 ms wait time from the end of Reset. If the device is
+                * not done with its internal initialization, it must at
+                * least return a completion TLP, with a completion status
+                * of "Configuration Request Retry Status (CRS)". The root
+                * complex must complete the request to the host by returning
+                * a read-data value of 0001h for the Vendor ID field and
+                * all 1s for any additional bytes included in the request.
+                * Poll using the config reads for max wait time of 1 sec or
+                * until we receive the successful completion status. Repeat
+                * the procedure for all the devices.
+                */
+               for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) {
+                       for (i = 0; i < 100000; i++) {
+                               bcma_extpci_read_config(pc, dev, 0,
+                                                       PCI_VENDOR_ID, &val16,
+                                                       sizeof(val16));
+                               if (val16 != 0x1)
+                                       break;
+                               udelay(10);
+                       }
+                       if (val16 == 0x1)
+                               pr_err("PCI: Broken device in slot %d\n", dev);
+               }
+       }
+}
+
+void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
+{
+       struct bcma_bus *bus = pc->core->bus;
+       struct bcma_drv_pci_host *pc_host;
+       u32 tmp;
+       u32 pci_membase_1G;
+       unsigned long io_map_base;
+
+       pr_info("PCIEcore in host mode found\n");
+
+       pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
+       if (!pc_host)  {
+               pr_err("can not allocate memory");
+               return;
+       }
+
+       pc->host_controller = pc_host;
+       pc_host->pci_controller.io_resource = &pc_host->io_resource;
+       pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
+       pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
+       pc_host->pdev = pc;
+
+       pci_membase_1G = BCMA_SOC_PCI_DMA;
+       pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG;
+
+       pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
+       pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
+
+       pc_host->mem_resource.name = "BCMA PCIcore external memory",
+       pc_host->mem_resource.start = BCMA_SOC_PCI_DMA;
+       pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1;
+       pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
+
+       pc_host->io_resource.name = "BCMA PCIcore external I/O",
+       pc_host->io_resource.start = 0x100;
+       pc_host->io_resource.end = 0x7FF;
+       pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
+
+       /* Reset RC */
+       udelay(3000);
+       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
+       udelay(1000);
+       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
+                       BCMA_CORE_PCI_CTL_RST_OE);
+
+       /* 64 MB I/O access window. On 4716, use
+        * sbtopcie0 to access the device registers. We
+        * can't use address match 2 (1 GB window) region
+        * as mips can't generate 64-bit address on the
+        * backplane.
+        */
+       if (bus->chipinfo.id == 0x4716 || bus->chipinfo.id == 0x4748) {
+               pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
+               pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
+                                           BCMA_SOC_PCI_MEM_SZ - 1;
+               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
+                               BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM);
+       } else if (bus->chipinfo.id == 0x5300) {
+               tmp = BCMA_CORE_PCI_SBTOPCI_MEM;
+               tmp |= BCMA_CORE_PCI_SBTOPCI_PREF;
+               tmp |= BCMA_CORE_PCI_SBTOPCI_BURST;
+               if (pc->core->core_unit == 0) {
+                       pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
+                       pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
+                                                   BCMA_SOC_PCI_MEM_SZ - 1;
+                       pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
+                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
+                                       tmp | BCMA_SOC_PCI_MEM);
+               } else if (pc->core->core_unit == 1) {
+                       pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
+                       pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
+                                                   BCMA_SOC_PCI_MEM_SZ - 1;
+                       pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
+                       pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
+                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
+                                       tmp | BCMA_SOC_PCI1_MEM);
+               }
+       } else
+               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
+                               BCMA_CORE_PCI_SBTOPCI_IO);
+
+       /* 64 MB configuration access window */
+       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
+
+       /* 1 GB memory access window */
+       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2,
+                       BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G);
+
+
+       /* As per PCI Express Base Spec 1.1 we need to wait for
+        * at least 100 ms from the end of a reset (cold/warm/hot)
+        * before issuing configuration requests to PCI Express
+        * devices.
+        */
+       udelay(100000);
+
+       bcma_core_pci_enable_crs(pc);
+
+       /* Enable PCI bridge BAR0 memory & master access */
+       tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+       bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
+
+       /* Enable PCI interrupts */
+       pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA);
+
+       /* Ok, ready to run, register it to the system.
+        * The following needs change, if we want to port hostmode
+        * to non-MIPS platform. */
+       io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM,
+                                                    0x04000000);
+       pc_host->pci_controller.io_map_base = io_map_base;
+       set_io_port_base(pc_host->pci_controller.io_map_base);
+       /* Give some time to the PCI controller to configure itself with the new
+        * values. Not waiting at this point causes crashes of the machine. */
+       mdelay(10);
+       register_pci_controller(&pc_host->pci_controller);
+       return;
+}
+
+/* Early PCI fixup for a device on the PCI-core bridge. */
+static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev)
+{
+       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
+               /* This is not a device on the PCI-core bridge. */
+               return;
+       }
+       if (PCI_SLOT(dev->devfn) != 0)
+               return;
+
+       pr_info("PCI: Fixing up bridge %s\n", pci_name(dev));
+
+       /* Enable PCI bridge bus mastering and memory space */
+       pci_set_master(dev);
+       if (pcibios_enable_device(dev, ~0) < 0) {
+               pr_err("PCI: BCMA bridge enable failed\n");
+               return;
+       }
+
+       /* Enable PCI bridge BAR1 prefetch and burst */
+       pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
+
+/* Early PCI fixup for all PCI-cores to set the correct memory address. */
+static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
+{
+       struct resource *res;
+       int pos;
+
+       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
+               /* This is not a device on the PCI-core bridge. */
+               return;
+       }
+       if (PCI_SLOT(dev->devfn) == 0)
+               return;
+
+       pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));
+
+       for (pos = 0; pos < 6; pos++) {
+               res = &dev->resource[pos];
+               if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM))
+                       pci_assign_resource(dev, pos);
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
+
+/* This function is called when doing a pci_enable_device().
+ * We must first check if the device is a device on the PCI-core bridge. */
+int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
+{
+       struct bcma_drv_pci_host *pc_host;
+
+       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
+               /* This is not a device on the PCI-core bridge. */
+               return -ENODEV;
+       }
+       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
+                              pci_ops);
+
+       pr_info("PCI: Fixing up device %s\n", pci_name(dev));
+
+       /* Fix up interrupt lines */
+       dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
+       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
+       return 0;
+}
+EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
+
+/* PCI device IRQ mapping. */
+int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
+{
+       struct bcma_drv_pci_host *pc_host;
+
+       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
+               /* This is not a device on the PCI-core bridge. */
+               return -ENODEV;
+       }
+
+       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
+                              pci_ops);
+       return bcma_core_mips_irq(pc_host->pdev->core) + 2;
 }
+EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
index f59244e3397137ca9b6a6d311612dd53db721646..e3928d68802b2ba0c283a1eca2fe0bc86bea40be 100644 (file)
@@ -154,8 +154,8 @@ const struct bcma_host_ops bcma_host_pci_ops = {
        .awrite32       = bcma_host_pci_awrite32,
 };
 
-static int bcma_host_pci_probe(struct pci_dev *dev,
-                            const struct pci_device_id *id)
+static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
+                                        const struct pci_device_id *id)
 {
        struct bcma_bus *bus;
        int err = -ENOMEM;
index ec31f7dd55491aeaea79b071c8aebc7065a8452a..7e138ec21357bb460e69f5aaed01d09307605709 100644 (file)
 MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
 MODULE_LICENSE("GPL");
 
+/* contains the number the next bus should get. */
+static unsigned int bcma_bus_next_num = 0;
+
+/* bcma_buses_mutex locks the bcma_bus_next_num */
+static DEFINE_MUTEX(bcma_buses_mutex);
+
 static int bcma_bus_match(struct device *dev, struct device_driver *drv);
 static int bcma_device_probe(struct device *dev);
 static int bcma_device_remove(struct device *dev);
@@ -55,7 +61,7 @@ static struct bus_type bcma_bus_type = {
        .dev_attrs      = bcma_device_attrs,
 };
 
-static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
+struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
 {
        struct bcma_device *core;
 
@@ -65,6 +71,7 @@ static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
        }
        return NULL;
 }
+EXPORT_SYMBOL_GPL(bcma_find_core);
 
 static void bcma_release_core_dev(struct device *dev)
 {
@@ -93,7 +100,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
 
                core->dev.release = bcma_release_core_dev;
                core->dev.bus = &bcma_bus_type;
-               dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
+               dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
 
                switch (bus->hosttype) {
                case BCMA_HOSTTYPE_PCI:
@@ -132,11 +139,15 @@ static void bcma_unregister_cores(struct bcma_bus *bus)
        }
 }
 
-int bcma_bus_register(struct bcma_bus *bus)
+int __devinit bcma_bus_register(struct bcma_bus *bus)
 {
        int err;
        struct bcma_device *core;
 
+       mutex_lock(&bcma_buses_mutex);
+       bus->num = bcma_bus_next_num++;
+       mutex_unlock(&bcma_buses_mutex);
+
        /* Scan for devices (cores) */
        err = bcma_bus_scan(bus);
        if (err) {
index 3a2f672db9ad217c264cf7a2203e4d96aa0910d7..f94cccccfa56fc94a2e0b2cf454b30afd3864855 100644 (file)
@@ -212,6 +212,17 @@ static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
        return NULL;
 }
 
+static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
+{
+       struct bcma_device *core;
+
+       list_for_each_entry_reverse(core, &bus->cores, list) {
+               if (core->id.id == coreid)
+                       return core;
+       }
+       return NULL;
+}
+
 static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
                              struct bcma_device_id *match, int core_num,
                              struct bcma_device *core)
@@ -353,6 +364,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 void bcma_init_bus(struct bcma_bus *bus)
 {
        s32 tmp;
+       struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
 
        if (bus->init_done)
                return;
@@ -363,9 +375,12 @@ void bcma_init_bus(struct bcma_bus *bus)
        bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
 
        tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
-       bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
-       bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
-       bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
+       chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
+       chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
+       chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
+       pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
+               chipinfo->id, chipinfo->rev, chipinfo->pkg);
+
        bus->init_done = true;
 }
 
@@ -392,6 +407,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
        bcma_scan_switch_core(bus, erombase);
 
        while (eromptr < eromend) {
+               struct bcma_device *other_core;
                struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
                if (!core)
                        return -ENOMEM;
@@ -414,6 +430,8 @@ int bcma_bus_scan(struct bcma_bus *bus)
 
                core->core_index = core_num++;
                bus->nr_cores++;
+               other_core = bcma_find_core_reverse(bus, core->id.id);
+               core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
 
                pr_info("Core %d found: %s "
                        "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
index 6f230fb087c5ebd064a52aafa8924368b2039c0e..cdcf75c0954febe06c4ac04f030568470284c160 100644 (file)
@@ -2,6 +2,8 @@
  * Broadcom specific AMBA
  * SPROM reading
  *
+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
+ *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
 
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 
-#define SPOFF(offset)  ((offset) / sizeof(u16))
+static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
+
+/**
+ * bcma_arch_register_fallback_sprom - Registers a method providing a
+ * fallback SPROM if no SPROM is found.
+ *
+ * @sprom_callback: The callback function.
+ *
+ * With this function the architecture implementation may register a
+ * callback handler which fills the SPROM data structure. The fallback is
+ * used for PCI based BCMA devices, where no valid SPROM can be found
+ * in the shadow registers and to provide the SPROM for SoCs where BCMA is
+ * to controll the system bus.
+ *
+ * This function is useful for weird architectures that have a half-assed
+ * BCMA device hardwired to their PCI bus.
+ *
+ * This function is available for architecture code, only. So it is not
+ * exported.
+ */
+int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
+                                    struct ssb_sprom *out))
+{
+       if (get_fallback_sprom)
+               return -EEXIST;
+       get_fallback_sprom = sprom_callback;
+
+       return 0;
+}
+
+static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
+                                        struct ssb_sprom *out)
+{
+       int err;
+
+       if (!get_fallback_sprom) {
+               err = -ENOENT;
+               goto fail;
+       }
+
+       err = get_fallback_sprom(bus, out);
+       if (err)
+               goto fail;
+
+       pr_debug("Using SPROM revision %d provided by"
+                " platform.\n", bus->sprom.revision);
+       return 0;
+fail:
+       pr_warn("Using fallback SPROM failed (err %d)\n", err);
+       return err;
+}
 
 /**************************************************
  * R/W ops.
@@ -124,10 +176,21 @@ static int bcma_sprom_valid(const u16 *sprom)
  * SPROM extraction.
  **************************************************/
 
+#define SPOFF(offset)  ((offset) / sizeof(u16))
+
+#define SPEX(_field, _offset, _mask, _shift)   \
+       bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
+
 static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 {
-       u16 v;
+       u16 v, o;
        int i;
+       u16 pwr_info_offset[] = {
+               SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
+               SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
+       };
+       BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
+                       ARRAY_SIZE(bus->sprom.core_pwr_info));
 
        bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
                SSB_SPROM_REVISION_REV;
@@ -137,85 +200,229 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
                *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
        }
 
-       bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
-
-       bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
-            SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
-       bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
-            SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
-       bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
-            SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
-       bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
-            SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
-
-       bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
-            SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
-       bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
-            SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
-       bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
-            SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
-       bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
-            SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
-
-       bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
-            SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
-       bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
-            SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
-       bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
-            SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
-       bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
-            SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
-
-       bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
-            SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
-       bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
-            SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
-       bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
-            SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
-       bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
-            SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
-
-       bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
-       bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
-       bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
-       bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
-
-       bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
-
-       bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
-               SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
-       bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
-               SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
-       bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
-               SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
-       bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
-               SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
-       bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
-               SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
-
-       bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
-               SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
-       bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
-               SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
-       bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
-               SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
-       bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
-               SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
-       bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
-               SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
+       SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
+
+       SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
+            SSB_SPROM4_TXPID2G0_SHIFT);
+       SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
+            SSB_SPROM4_TXPID2G1_SHIFT);
+       SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
+            SSB_SPROM4_TXPID2G2_SHIFT);
+       SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
+            SSB_SPROM4_TXPID2G3_SHIFT);
+
+       SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
+            SSB_SPROM4_TXPID5GL0_SHIFT);
+       SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
+            SSB_SPROM4_TXPID5GL1_SHIFT);
+       SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
+            SSB_SPROM4_TXPID5GL2_SHIFT);
+       SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
+            SSB_SPROM4_TXPID5GL3_SHIFT);
+
+       SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
+            SSB_SPROM4_TXPID5G0_SHIFT);
+       SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
+            SSB_SPROM4_TXPID5G1_SHIFT);
+       SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
+            SSB_SPROM4_TXPID5G2_SHIFT);
+       SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
+            SSB_SPROM4_TXPID5G3_SHIFT);
+
+       SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
+            SSB_SPROM4_TXPID5GH0_SHIFT);
+       SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
+            SSB_SPROM4_TXPID5GH1_SHIFT);
+       SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
+            SSB_SPROM4_TXPID5GH2_SHIFT);
+       SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
+            SSB_SPROM4_TXPID5GH3_SHIFT);
+
+       SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
+       SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
+       SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
+       SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
+
+       SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0);
+
+       /* Extract cores power info info */
+       for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
+               o = pwr_info_offset[i];
+               SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
+                       SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
+               SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
+                       SSB_SPROM8_2G_MAXP, 0);
+
+               SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
+               SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
+               SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
+
+               SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
+                       SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
+               SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
+                       SSB_SPROM8_5G_MAXP, 0);
+               SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
+                       SSB_SPROM8_5GH_MAXP, 0);
+               SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
+                       SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
+
+               SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
+       }
+
+       SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
+            SSB_SROM8_FEM_TSSIPOS_SHIFT);
+       SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
+            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
+       SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
+            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
+       SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
+            SSB_SROM8_FEM_TR_ISO_SHIFT);
+       SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
+            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
+
+       SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
+            SSB_SROM8_FEM_TSSIPOS_SHIFT);
+       SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
+            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
+       SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
+            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
+       SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
+            SSB_SROM8_FEM_TR_ISO_SHIFT);
+       SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
+            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
+}
+
+/*
+ * Indicates the presence of external SPROM.
+ */
+static bool bcma_sprom_ext_available(struct bcma_bus *bus)
+{
+       u32 chip_status;
+       u32 srom_control;
+       u32 present_mask;
+
+       if (bus->drv_cc.core->id.rev >= 31) {
+               if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
+                       return false;
+
+               srom_control = bcma_read32(bus->drv_cc.core,
+                                          BCMA_CC_SROM_CONTROL);
+               return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
+       }
+
+       /* older chipcommon revisions use chip status register */
+       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
+       switch (bus->chipinfo.id) {
+       case 0x4313:
+               present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
+               break;
+
+       case 0x4331:
+               present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
+               break;
+
+       default:
+               return true;
+       }
+
+       return chip_status & present_mask;
+}
+
+/*
+ * Indicates that on-chip OTP memory is present and enabled.
+ */
+static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
+{
+       u32 chip_status;
+       u32 otpsize = 0;
+       bool present;
+
+       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
+       switch (bus->chipinfo.id) {
+       case 0x4313:
+               present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
+               break;
+
+       case 0x4331:
+               present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
+               break;
+
+       case 43224:
+       case 43225:
+               /* for these chips OTP is always available */
+               present = true;
+               break;
+
+       default:
+               present = false;
+               break;
+       }
+
+       if (present) {
+               otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
+               otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
+       }
+
+       return otpsize != 0;
+}
+
+/*
+ * Verify OTP is filled and determine the byte
+ * offset where SPROM data is located.
+ *
+ * On error, returns 0; byte offset otherwise.
+ */
+static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
+{
+       struct bcma_device *cc = bus->drv_cc.core;
+       u32 offset;
+
+       /* verify OTP status */
+       if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
+               return 0;
+
+       /* obtain bit offset from otplayout register */
+       offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
+       return BCMA_CC_SPROM + (offset >> 3);
 }
 
 int bcma_sprom_get(struct bcma_bus *bus)
 {
-       u16 offset;
+       u16 offset = BCMA_CC_SPROM;
        u16 *sprom;
        int err = 0;
 
        if (!bus->drv_cc.core)
                return -EOPNOTSUPP;
 
-       if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
-               return -ENOENT;
+       if (!bcma_sprom_ext_available(bus)) {
+               /*
+                * External SPROM takes precedence so check
+                * on-chip OTP only when no external SPROM
+                * is present.
+                */
+               if (bcma_sprom_onchip_available(bus)) {
+                       /* determine offset */
+                       offset = bcma_sprom_onchip_offset(bus);
+               }
+               if (!offset) {
+                       /*
+                        * Maybe there is no SPROM on the device?
+                        * Now we ask the arch code if there is some sprom
+                        * available for this device in some other storage.
+                        */
+                       err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
+                       return err;
+               }
+       }
 
        sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
                        GFP_KERNEL);
@@ -225,11 +432,7 @@ int bcma_sprom_get(struct bcma_bus *bus)
        if (bus->chipinfo.id == 0x4331)
                bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
 
-       /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
-        * According to brcm80211 this applies to cards with PCIe rev >= 6
-        * TODO: understand this condition and use it */
-       offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
-               BCMA_CC_SPROM_PCIE6;
+       pr_debug("SPROM offset 0x%x\n", offset);
        bcma_sprom_read(bus, offset, sprom);
 
        if (bus->chipinfo.id == 0x4331)
index f00f596c102997c8b32c48d4e41007eeae9a99a4..789c9b579aea5bac7e0b2abfe3d14b377917a9c4 100644 (file)
@@ -102,6 +102,7 @@ static struct usb_device_id btusb_table[] = {
 
        /* Broadcom BCM20702A0 */
        { USB_DEVICE(0x0a5c, 0x21e3) },
+       { USB_DEVICE(0x0a5c, 0x21f3) },
        { USB_DEVICE(0x413c, 0x8197) },
 
        { }     /* Terminating entry */
@@ -726,9 +727,6 @@ static int btusb_send_frame(struct sk_buff *skb)
                usb_fill_bulk_urb(urb, data->udev, pipe,
                                skb->data, skb->len, btusb_tx_complete, skb);
 
-               if (skb->priority >= HCI_PRIO_MAX - 1)
-                       urb->transfer_flags  = URB_ISO_ASAP;
-
                hdev->stat.acl_tx++;
                break;
 
index 1c008c61b95ce8113d8ad230ee4e48aad27992b7..ddc061dd150ce47438020f28424a7449e9ab66a5 100644 (file)
@@ -1869,7 +1869,7 @@ static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
 
 static void try_auto_wep(struct airo_info *ai)
 {
-       if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) {
+       if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) {
                ai->expires = RUN_AT(3*HZ);
                wake_up_interruptible(&ai->thr_wait);
        }
index ee7ea572b065753c3271c184bb84c65bcf2908e2..8faa129da5a00b60c74dd255ae1692effb3d329d 100644 (file)
@@ -140,23 +140,23 @@ static int ath_ahb_probe(struct platform_device *pdev)
 
        if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
                /* Enable WMAC AHB arbitration */
-               reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+               reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
                reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
-               __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+               iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
 
                /* Enable global WMAC swapping */
-               reg = __raw_readl((void __iomem *) AR5K_AR2315_BYTESWAP);
+               reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP);
                reg |= AR5K_AR2315_BYTESWAP_WMAC;
-               __raw_writel(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
+               iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
        } else {
                /* Enable WMAC DMA access (assuming 5312 or 231x*/
                /* TODO: check other platforms */
-               reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
+               reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
                if (to_platform_device(ah->dev)->id == 0)
                        reg |= AR5K_AR5312_ENABLE_WLAN0;
                else
                        reg |= AR5K_AR5312_ENABLE_WLAN1;
-               __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
+               iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
 
                /*
                 * On a dual-band AR5312, the multiband radio is only
@@ -203,17 +203,17 @@ static int ath_ahb_remove(struct platform_device *pdev)
 
        if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
                /* Disable WMAC AHB arbitration */
-               reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+               reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
                reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
-               __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+               iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
        } else {
                /*Stop DMA access */
-               reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
+               reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
                if (to_platform_device(ah->dev)->id == 0)
                        reg &= ~AR5K_AR5312_ENABLE_WLAN0;
                else
                        reg &= ~AR5K_AR5312_ENABLE_WLAN1;
-               __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
+               iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
        }
 
        ath5k_deinit_ah(ah);
index c2b2518c2ecd30732c900ab3490d01765b0c35b9..8d434b8f58557ff8b105371fe012661b829367e4 100644 (file)
@@ -1320,6 +1320,7 @@ struct ath5k_hw {
        struct ieee80211_vif    *bslot[ATH_BCBUF];
        u16                     num_ap_vifs;
        u16                     num_adhoc_vifs;
+       u16                     num_mesh_vifs;
        unsigned int            bhalq,          /* SW q for outgoing beacons */
                                bmisscount,     /* missed beacon transmits */
                                bintval,        /* beacon interval in TU */
@@ -1656,12 +1657,12 @@ static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
 
 static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
 {
-       return __raw_readl(ath5k_ahb_reg(ah, reg));
+       return ioread32(ath5k_ahb_reg(ah, reg));
 }
 
 static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
 {
-       __raw_writel(val, ath5k_ahb_reg(ah, reg));
+       iowrite32(val, ath5k_ahb_reg(ah, reg));
 }
 
 #else
index d366dadcf86e6a47c6a48261bd2a480a803d5cac..0e643b016b3286a12d80e040a7d399914468f8fb 100644 (file)
@@ -80,7 +80,7 @@ static bool modparam_fastchanswitch;
 module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO);
 MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
 
-static int ath5k_modparam_no_hw_rfkill_switch;
+static bool ath5k_modparam_no_hw_rfkill_switch;
 module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch,
                                                                bool, S_IRUGO);
 MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state");
@@ -1867,7 +1867,8 @@ ath5k_beacon_send(struct ath5k_hw *ah)
                ah->bmisscount = 0;
        }
 
-       if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) ||
+       if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
+                       ah->num_mesh_vifs > 1) ||
                        ah->opmode == NL80211_IFTYPE_MESH_POINT) {
                u64 tsf = ath5k_hw_get_tsf64(ah);
                u32 tsftu = TSF_TO_TU(tsf);
@@ -1952,7 +1953,8 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf)
        u64 hw_tsf;
 
        intval = ah->bintval & AR5K_BEACON_PERIOD;
-       if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) {
+       if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
+               + ah->num_mesh_vifs > 1) {
                intval /= ATH_BCBUF;    /* staggered multi-bss beacons */
                if (intval < 15)
                        ATH5K_WARN(ah, "intval %u is too low, min 15\n",
@@ -2330,15 +2332,6 @@ ath5k_calibrate_work(struct work_struct *work)
                                        "got new rfgain, resetting\n");
                        ieee80211_queue_work(ah->hw, &ah->reset_work);
                }
-
-               /* TODO: On full calibration we should stop TX here,
-                * so that it doesn't interfere (mostly due to gain_f
-                * calibration that messes with tx packets -see phy.c).
-                *
-                * NOTE: Stopping the queues from above is not enough
-                * to stop TX but saves us from disconecting (at least
-                * we don't lose packets). */
-               ieee80211_stop_queues(ah->hw);
        } else
                ah->ah_cal_mask |= AR5K_CALIBRATION_SHORT;
 
@@ -2353,10 +2346,9 @@ ath5k_calibrate_work(struct work_struct *work)
                                ah->curchan->center_freq));
 
        /* Clear calibration flags */
-       if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) {
-               ieee80211_wake_queues(ah->hw);
+       if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL)
                ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
-       else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT)
+       else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT)
                ah->ah_cal_mask &= ~AR5K_CALIBRATION_SHORT;
 }
 
@@ -2442,6 +2434,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
                BIT(NL80211_IFTYPE_ADHOC) |
                BIT(NL80211_IFTYPE_MESH_POINT);
 
+       /* SW support for IBSS_RSN is provided by mac80211 */
+       hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
        /* both antennas can be configured as RX or TX */
        hw->wiphy->available_antennas_tx = 0x3;
        hw->wiphy->available_antennas_rx = 0x3;
index 6ed4c0717e3e31bbe85ad871ada0c0b0fb11f62e..5c5329955414966247d5f44dcb8d7760e2d474f1 100644 (file)
@@ -134,6 +134,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                        ah->num_ap_vifs++;
                else if (avf->opmode == NL80211_IFTYPE_ADHOC)
                        ah->num_adhoc_vifs++;
+               else if (avf->opmode == NL80211_IFTYPE_MESH_POINT)
+                       ah->num_mesh_vifs++;
        }
 
        /* Any MAC address is fine, all others are included through the
@@ -175,6 +177,8 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
                ah->num_ap_vifs--;
        else if (avf->opmode == NL80211_IFTYPE_ADHOC)
                ah->num_adhoc_vifs--;
+       else if (avf->opmode == NL80211_IFTYPE_MESH_POINT)
+               ah->num_mesh_vifs--;
 
        ath5k_update_bssid_mask_and_opmode(ah, NULL);
        mutex_unlock(&ah->lock);
@@ -483,6 +487,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        if (ath5k_modparam_nohwcrypt)
                return -EOPNOTSUPP;
 
+       if (vif->type == NL80211_IFTYPE_ADHOC &&
+           (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
+            key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
+           !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+               /* don't program group keys when using IBSS_RSN */
+               return -EOPNOTSUPP;
+       }
+
        switch (key->cipher) {
        case WLAN_CIPHER_SUITE_WEP40:
        case WLAN_CIPHER_SUITE_WEP104:
index e1f8613426a921f05fe294ba1409baaec7e2b954..3a2845489a1b67cb7df9c4750785a690639d9bdd 100644 (file)
@@ -1871,31 +1871,15 @@ ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
                ret = 0;
        }
 
-       /* On full calibration do an AGC calibration and
-        * request a PAPD probe for gainf calibration if
-        * needed */
-       if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) {
-
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
-                                       AR5K_PHY_AGCCTL_CAL);
-
-               ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
-                       AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF,
-                       0, false);
-               if (ret) {
-                       ATH5K_ERR(ah,
-                               "gain calibration timeout (%uMHz)\n",
-                               channel->center_freq);
-               }
-
-               if ((ah->ah_radio == AR5K_RF5111 ||
-                       ah->ah_radio == AR5K_RF5112)
-                       && (channel->hw_value != AR5K_MODE_11B))
-                       ath5k_hw_request_rfgain_probe(ah);
-       }
-
-       /* Update noise floor
-        * XXX: Only do this after AGC calibration */
+       /* On full calibration request a PAPD probe for
+        * gainf calibration if needed */
+       if ((ah->ah_cal_mask & AR5K_CALIBRATION_FULL) &&
+           (ah->ah_radio == AR5K_RF5111 ||
+            ah->ah_radio == AR5K_RF5112) &&
+           channel->hw_value != AR5K_MODE_11B)
+               ath5k_hw_request_rfgain_probe(ah);
+
+       /* Update noise floor */
        if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF))
                ath5k_hw_update_noise_floor(ah);
 
index 250db40b751d1780b0c7937cb53c6de016973bdd..200f165c0c6d9c4a508ece1da7a2fd996b9df094 100644 (file)
@@ -473,14 +473,14 @@ ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
        }
 
        /* Put BB/MAC into reset */
-       regval = __raw_readl(reg);
-       __raw_writel(regval | val, reg);
-       regval = __raw_readl(reg);
+       regval = ioread32(reg);
+       iowrite32(regval | val, reg);
+       regval = ioread32(reg);
        usleep_range(100, 150);
 
        /* Bring BB/MAC out of reset */
-       __raw_writel(regval & ~val, reg);
-       regval = __raw_readl(reg);
+       iowrite32(regval & ~val, reg);
+       regval = ioread32(reg);
 
        /*
         * Reset configuration register (for hw byte-swap). Note that this
index 3d5f8be20eac588435498745f0ae41d2b64ae975..d755a5e7ed2036b9f7e237431413cd093fed07fc 100644 (file)
@@ -1,12 +1,29 @@
 config ATH6KL
-       tristate "Atheros ath6kl support"
+       tristate "Atheros mobile chipsets support"
+
+config ATH6KL_SDIO
+       tristate "Atheros ath6kl SDIO support"
+       depends on ATH6KL
        depends on MMC
        depends on CFG80211
        ---help---
          This module adds support for wireless adapters based on
-         Atheros AR6003 chipset running over SDIO. If you choose to
-         build it as a module, it will be called ath6kl. Pls note
-         that AR6002 and AR6001 are not supported by this driver.
+         Atheros AR6003 and AR6004 chipsets running over SDIO. If you
+         choose to build it as a module, it will be called ath6kl_sdio.
+         Please note that AR6002 and AR6001 are not supported by this
+         driver.
+
+config ATH6KL_USB
+       tristate "Atheros ath6kl USB support"
+       depends on ATH6KL
+       depends on USB
+       depends on CFG80211
+       depends on EXPERIMENTAL
+       ---help---
+         This module adds support for wireless adapters based on
+         Atheros AR6004 chipset running over USB. This is still under
+         implementation and it isn't functional. If you choose to
+         build it as a module, it will be called ath6kl_usb.
 
 config ATH6KL_DEBUG
        bool "Atheros ath6kl debugging"
index 707069303550e9eae103f533875eb72b3376d9fb..9ba42fa049624b07772144a9f04b34999ad11065 100644 (file)
 # Author(s): ="Atheros"
 #------------------------------------------------------------------------------
 
-obj-$(CONFIG_ATH6KL) := ath6kl.o
-ath6kl-y += debug.o
-ath6kl-y += hif.o
-ath6kl-y += htc.o
-ath6kl-y += bmi.o
-ath6kl-y += cfg80211.o
-ath6kl-y += init.o
-ath6kl-y += main.o
-ath6kl-y += txrx.o
-ath6kl-y += wmi.o
-ath6kl-y += sdio.o
-ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o
+obj-$(CONFIG_ATH6KL) += ath6kl_core.o
+ath6kl_core-y += debug.o
+ath6kl_core-y += hif.o
+ath6kl_core-y += htc.o
+ath6kl_core-y += bmi.o
+ath6kl_core-y += cfg80211.o
+ath6kl_core-y += init.o
+ath6kl_core-y += main.o
+ath6kl_core-y += txrx.o
+ath6kl_core-y += wmi.o
+ath6kl_core-y += core.o
+ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
 
-ccflags-y += -D__CHECK_ENDIAN__
+obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o
+ath6kl_sdio-y += sdio.o
+
+obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o
+ath6kl_usb-y += usb.o
index bce3575c310ae230acc99024d14d42e3935e3ad6..aef00d5a1438ce501408e8d1055cac00df449977 100644 (file)
@@ -57,8 +57,14 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
                return ret;
        }
 
-       ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
-                                 sizeof(targ_info->version));
+       if (ar->hif_type == ATH6KL_HIF_TYPE_USB) {
+               ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info,
+                                         sizeof(*targ_info));
+       } else {
+               ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
+                               sizeof(targ_info->version));
+       }
+
        if (ret) {
                ath6kl_err("Unable to recv target info: %d\n", ret);
                return ret;
index 6c59a217b1a133f390d1dd2f444494110660b9f7..5370333883e4632c03e9ca9958c43631d0072119 100644 (file)
@@ -15,6 +15,8 @@
  */
 
 #include <linux/moduleparam.h>
+#include <linux/inetdevice.h>
+#include <linux/export.h>
 
 #include "core.h"
 #include "cfg80211.h"
 #include "hif-ops.h"
 #include "testmode.h"
 
-static unsigned int ath6kl_p2p;
-
-module_param(ath6kl_p2p, uint, 0644);
-
 #define RATETAB_ENT(_rate, _rateid, _flags) {   \
        .bitrate    = (_rate),                  \
        .flags      = (_flags),                 \
@@ -196,7 +194,7 @@ static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
                break;
 
        default:
-               ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
+               ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
                return -ENOTSUPP;
        }
 
@@ -461,13 +459,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                }
        }
 
-       if (sme->ie && (sme->ie_len > 0)) {
-               status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
-               if (status) {
-                       up(&ar->sem);
-                       return status;
-               }
-       } else
+       status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
+       if (status) {
+               up(&ar->sem);
+               return status;
+       }
+
+       if (sme->ie == NULL || sme->ie_len == 0)
                ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
 
        if (test_bit(CONNECTED, &vif->flags) &&
@@ -523,8 +521,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
            (vif->prwise_crypto == WEP_CRYPT)) {
                struct ath6kl_key *key = NULL;
 
-               if (sme->key_idx < WMI_MIN_KEY_INDEX ||
-                   sme->key_idx > WMI_MAX_KEY_INDEX) {
+               if (sme->key_idx > WMI_MAX_KEY_INDEX) {
                        ath6kl_err("key index %d out of bounds\n",
                                   sme->key_idx);
                        up(&ar->sem);
@@ -605,11 +602,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
        return 0;
 }
 
-static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
-                                   enum network_type nw_type,
-                                   const u8 *bssid,
-                                   struct ieee80211_channel *chan,
-                                   const u8 *beacon_ie, size_t beacon_ie_len)
+static struct cfg80211_bss *
+ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
+                        enum network_type nw_type,
+                        const u8 *bssid,
+                        struct ieee80211_channel *chan,
+                        const u8 *beacon_ie,
+                        size_t beacon_ie_len)
 {
        struct ath6kl *ar = vif->ar;
        struct cfg80211_bss *bss;
@@ -638,7 +637,7 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
                 */
                ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
                if (ie == NULL)
-                       return -ENOMEM;
+                       return NULL;
                ie[0] = WLAN_EID_SSID;
                ie[1] = vif->ssid_len;
                memcpy(ie + 2, vif->ssid, vif->ssid_len);
@@ -652,15 +651,9 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
                                   "cfg80211\n", bssid);
                kfree(ie);
        } else
-               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
-                          "entry\n");
-
-       if (bss == NULL)
-               return -ENOMEM;
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
 
-       cfg80211_put_bss(bss);
-
-       return 0;
+       return bss;
 }
 
 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
@@ -672,6 +665,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 {
        struct ieee80211_channel *chan;
        struct ath6kl *ar = vif->ar;
+       struct cfg80211_bss *bss;
 
        /* capinfo + listen interval */
        u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
@@ -712,8 +706,9 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 
        chan = ieee80211_get_channel(ar->wiphy, (int) channel);
 
-       if (ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, assoc_info,
-                                    beacon_ie_len) < 0) {
+       bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
+                                      assoc_info, beacon_ie_len);
+       if (!bss) {
                ath6kl_err("could not add cfg80211 bss entry\n");
                return;
        }
@@ -722,6 +717,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
                           nw_type & ADHOC_CREATOR ? "creator" : "joiner");
                cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
+               cfg80211_put_bss(bss);
                return;
        }
 
@@ -732,11 +728,11 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
                                        assoc_req_ie, assoc_req_len,
                                        assoc_resp_ie, assoc_resp_len,
                                        WLAN_STATUS_SUCCESS, GFP_KERNEL);
+               cfg80211_put_bss(bss);
        } else if (vif->sme_state == SME_CONNECTED) {
                /* inform roam event to cfg80211 */
-               cfg80211_roamed(vif->ndev, chan, bssid,
-                               assoc_req_ie, assoc_req_len,
-                               assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
+               cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
+                                   assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
        }
 }
 
@@ -984,6 +980,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
        struct ath6kl *ar = ath6kl_priv(ndev);
        struct ath6kl_vif *vif = netdev_priv(ndev);
        struct ath6kl_key *key = NULL;
+       int seq_len;
        u8 key_usage;
        u8 key_type;
 
@@ -997,7 +994,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
                                              params->key);
        }
 
-       if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+       if (key_index > WMI_MAX_KEY_INDEX) {
                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
                           "%s: key index %d out of bounds\n", __func__,
                           key_index);
@@ -1012,23 +1009,21 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
        else
                key_usage = GROUP_USAGE;
 
-       if (params) {
-               int seq_len = params->seq_len;
-               if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
-                   seq_len > ATH6KL_KEY_SEQ_LEN) {
-                       /* Only first half of the WPI PN is configured */
-                       seq_len = ATH6KL_KEY_SEQ_LEN;
-               }
-               if (params->key_len > WLAN_MAX_KEY_LEN ||
-                   seq_len > sizeof(key->seq))
-                       return -EINVAL;
-
-               key->key_len = params->key_len;
-               memcpy(key->key, params->key, key->key_len);
-               key->seq_len = seq_len;
-               memcpy(key->seq, params->seq, key->seq_len);
-               key->cipher = params->cipher;
+       seq_len = params->seq_len;
+       if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
+           seq_len > ATH6KL_KEY_SEQ_LEN) {
+               /* Only first half of the WPI PN is configured */
+               seq_len = ATH6KL_KEY_SEQ_LEN;
        }
+       if (params->key_len > WLAN_MAX_KEY_LEN ||
+           seq_len > sizeof(key->seq))
+               return -EINVAL;
+
+       key->key_len = params->key_len;
+       memcpy(key->key, params->key, key->key_len);
+       key->seq_len = seq_len;
+       memcpy(key->seq, params->seq, key->seq_len);
+       key->cipher = params->cipher;
 
        switch (key->cipher) {
        case WLAN_CIPHER_SUITE_WEP40:
@@ -1115,7 +1110,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
        if (!ath6kl_cfg80211_ready(vif))
                return -EIO;
 
-       if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+       if (key_index > WMI_MAX_KEY_INDEX) {
                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
                           "%s: key index %d out of bounds\n", __func__,
                           key_index);
@@ -1148,7 +1143,7 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
        if (!ath6kl_cfg80211_ready(vif))
                return -EIO;
 
-       if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+       if (key_index > WMI_MAX_KEY_INDEX) {
                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
                           "%s: key index %d out of bounds\n", __func__,
                           key_index);
@@ -1184,7 +1179,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
        if (!ath6kl_cfg80211_ready(vif))
                return -EIO;
 
-       if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+       if (key_index > WMI_MAX_KEY_INDEX) {
                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
                           "%s: key index %d out of bounds\n",
                           __func__, key_index);
@@ -1403,7 +1398,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
 
        ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
 
-       ath6kl_deinit_if_data(vif);
+       ath6kl_cfg80211_vif_cleanup(vif);
 
        return 0;
 }
@@ -1728,29 +1723,14 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
        return 0;
 }
 
-static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
+                         struct cfg80211_wowlan *wow, u32 *filter)
 {
-       struct ath6kl_vif *vif;
-       int ret, pos, left;
-       u32 filter = 0;
-       u16 i;
+       int ret, pos;
        u8 mask[WOW_MASK_SIZE];
+       u16 i;
 
-       vif = ath6kl_vif_first(ar);
-       if (!vif)
-               return -EIO;
-
-       if (!ath6kl_cfg80211_ready(vif))
-               return -EIO;
-
-       if (!test_bit(CONNECTED, &vif->flags))
-               return -EINVAL;
-
-       /* Clear existing WOW patterns */
-       for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
-               ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
-                                              WOW_LIST_ID, i);
-       /* Configure new WOW patterns */
+       /* Configure the patterns that we received from the user. */
        for (i = 0; i < wow->n_patterns; i++) {
 
                /*
@@ -1773,29 +1753,221 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
                 * matched from the first byte of received pkt in the firmware.
                 */
                ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
-                                       vif->fw_vif_idx, WOW_LIST_ID,
-                                       wow->patterns[i].pattern_len,
-                                       0 /* pattern offset */,
-                                       wow->patterns[i].pattern, mask);
+                               vif->fw_vif_idx, WOW_LIST_ID,
+                               wow->patterns[i].pattern_len,
+                               0 /* pattern offset */,
+                               wow->patterns[i].pattern, mask);
                if (ret)
                        return ret;
        }
 
        if (wow->disconnect)
-               filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
+               *filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
 
        if (wow->magic_pkt)
-               filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
+               *filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
 
        if (wow->gtk_rekey_failure)
-               filter |= WOW_FILTER_OPTION_GTK_ERROR;
+               *filter |= WOW_FILTER_OPTION_GTK_ERROR;
 
        if (wow->eap_identity_req)
-               filter |= WOW_FILTER_OPTION_EAP_REQ;
+               *filter |= WOW_FILTER_OPTION_EAP_REQ;
 
        if (wow->four_way_handshake)
-               filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
+               *filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
 
+       return 0;
+}
+
+static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
+{
+       static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x08 };
+       static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x7f };
+       u8 unicst_offset = 0;
+       static const u8 arp_pattern[] = { 0x08, 0x06 };
+       static const u8 arp_mask[] = { 0xff, 0xff };
+       u8 arp_offset = 20;
+       static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
+       static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
+       u8 discvr_offset = 38;
+       static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
+               0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
+       static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
+               0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
+       u8 dhcp_offset = 0;
+       int ret;
+
+       /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
+       ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+                       vif->fw_vif_idx, WOW_LIST_ID,
+                       sizeof(unicst_pattern), unicst_offset,
+                       unicst_pattern, unicst_mask);
+       if (ret) {
+               ath6kl_err("failed to add WOW unicast IP pattern\n");
+               return ret;
+       }
+
+       /* Setup all ARP pkt pattern */
+       ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+                       vif->fw_vif_idx, WOW_LIST_ID,
+                       sizeof(arp_pattern), arp_offset,
+                       arp_pattern, arp_mask);
+       if (ret) {
+               ath6kl_err("failed to add WOW ARP pattern\n");
+               return ret;
+       }
+
+       /*
+        * Setup multicast pattern for mDNS 224.0.0.251,
+        * SSDP 239.255.255.250 and LLMNR  224.0.0.252
+        */
+       ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+                       vif->fw_vif_idx, WOW_LIST_ID,
+                       sizeof(discvr_pattern), discvr_offset,
+                       discvr_pattern, discvr_mask);
+       if (ret) {
+               ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
+               return ret;
+       }
+
+       /* Setup all DHCP broadcast pkt pattern */
+       ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+                       vif->fw_vif_idx, WOW_LIST_ID,
+                       sizeof(dhcp_pattern), dhcp_offset,
+                       dhcp_pattern, dhcp_mask);
+       if (ret) {
+               ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
+{
+       struct net_device *ndev = vif->ndev;
+       static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
+       static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
+       u8 discvr_offset = 38;
+       u8 mac_mask[ETH_ALEN];
+       int ret;
+
+       /* Setup unicast pkt pattern */
+       memset(mac_mask, 0xff, ETH_ALEN);
+       ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+                               vif->fw_vif_idx, WOW_LIST_ID,
+                               ETH_ALEN, 0, ndev->dev_addr,
+                               mac_mask);
+       if (ret) {
+               ath6kl_err("failed to add WOW unicast pattern\n");
+               return ret;
+       }
+
+       /*
+        * Setup multicast pattern for mDNS 224.0.0.251,
+        * SSDP 239.255.255.250 and LLMNR 224.0.0.252
+        */
+       if ((ndev->flags & IFF_ALLMULTI) ||
+           (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
+               ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+                               vif->fw_vif_idx, WOW_LIST_ID,
+                               sizeof(discvr_pattern), discvr_offset,
+                               discvr_pattern, discvr_mask);
+               if (ret) {
+                       ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR "
+                                  "pattern\n");
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+{
+       struct in_device *in_dev;
+       struct in_ifaddr *ifa;
+       struct ath6kl_vif *vif;
+       int ret, left;
+       u32 filter = 0;
+       u16 i;
+       u8 index = 0;
+       __be32 ips[MAX_IP_ADDRS];
+
+       vif = ath6kl_vif_first(ar);
+       if (!vif)
+               return -EIO;
+
+       if (!ath6kl_cfg80211_ready(vif))
+               return -EIO;
+
+       if (!test_bit(CONNECTED, &vif->flags))
+               return -ENOTCONN;
+
+       if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
+               return -EINVAL;
+
+       /* Clear existing WOW patterns */
+       for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
+               ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
+                                              WOW_LIST_ID, i);
+
+       /*
+        * Skip the default WOW pattern configuration
+        * if the driver receives any WOW patterns from
+        * the user.
+        */
+       if (wow)
+               ret = ath6kl_wow_usr(ar, vif, wow, &filter);
+       else if (vif->nw_type == AP_NETWORK)
+               ret = ath6kl_wow_ap(ar, vif);
+       else
+               ret = ath6kl_wow_sta(ar, vif);
+
+       if (ret)
+               return ret;
+
+       /* Setup own IP addr for ARP agent. */
+       in_dev = __in_dev_get_rtnl(vif->ndev);
+       if (!in_dev)
+               goto skip_arp;
+
+       ifa = in_dev->ifa_list;
+       memset(&ips, 0, sizeof(ips));
+
+       /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
+       while (index < MAX_IP_ADDRS && ifa) {
+               ips[index] = ifa->ifa_local;
+               ifa = ifa->ifa_next;
+               index++;
+       }
+
+       if (ifa) {
+               ath6kl_err("total IP addr count is exceeding fw limit\n");
+               return -EINVAL;
+       }
+
+       ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
+       if (ret) {
+               ath6kl_err("fail to setup ip for arp agent\n");
+               return ret;
+       }
+
+skip_arp:
        ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
                                          ATH6KL_WOW_MODE_ENABLE,
                                          filter,
@@ -1803,11 +1975,26 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
        if (ret)
                return ret;
 
+       clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
+
        ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
                                                 ATH6KL_HOST_MODE_ASLEEP);
        if (ret)
                return ret;
 
+       left = wait_event_interruptible_timeout(ar->event_wq,
+                       test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags),
+                       WMI_TIMEOUT);
+       if (left == 0) {
+               ath6kl_warn("timeout, didn't get host sleep cmd "
+                           "processed event\n");
+               ret = -ETIMEDOUT;
+       } else if (left < 0) {
+               ath6kl_warn("error while waiting for host sleep cmd "
+                           "processed event %d\n", left);
+               ret = left;
+       }
+
        if (ar->tx_pending[ar->ctrl_ep]) {
                left = wait_event_interruptible_timeout(ar->event_wq,
                                ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
@@ -1911,6 +2098,7 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
 
        return 0;
 }
+EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
 
 int ath6kl_cfg80211_resume(struct ath6kl *ar)
 {
@@ -1962,6 +2150,7 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
 
        return 0;
 }
+EXPORT_SYMBOL(ath6kl_cfg80211_resume);
 
 #ifdef CONFIG_PM
 
@@ -2014,7 +2203,18 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
                              struct ieee80211_channel *chan,
                              enum nl80211_channel_type channel_type)
 {
-       struct ath6kl_vif *vif = netdev_priv(dev);
+       struct ath6kl_vif *vif;
+
+       /*
+        * 'dev' could be NULL if a channel change is required for the hardware
+        * device itself, instead of a particular VIF.
+        *
+        * FIXME: To be handled properly when monitor mode is supported.
+        */
+       if (!dev)
+               return -EBUSY;
+
+       vif = netdev_priv(dev);
 
        if (!ath6kl_cfg80211_ready(vif))
                return -EIO;
@@ -2069,25 +2269,11 @@ static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
        return ret;
 }
 
-static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
-                           struct beacon_parameters *info, bool add)
+static int ath6kl_set_ies(struct ath6kl_vif *vif,
+                         struct cfg80211_beacon_data *info)
 {
-       struct ath6kl *ar = ath6kl_priv(dev);
-       struct ath6kl_vif *vif = netdev_priv(dev);
-       struct ieee80211_mgmt *mgmt;
-       u8 *ies;
-       int ies_len;
-       struct wmi_connect_cmd p;
+       struct ath6kl *ar = vif->ar;
        int res;
-       int i, ret;
-
-       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
-
-       if (!ath6kl_cfg80211_ready(vif))
-               return -EIO;
-
-       if (vif->next_mode != AP_NETWORK)
-               return -EOPNOTSUPP;
 
        if (info->beacon_ies) {
                res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
@@ -2097,12 +2283,14 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
                if (res)
                        return res;
        }
+
        if (info->proberesp_ies) {
                res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
                                                   info->proberesp_ies_len);
                if (res)
                        return res;
        }
+
        if (info->assocresp_ies) {
                res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
                                               WMI_FRAME_ASSOC_RESP,
@@ -2112,8 +2300,30 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
                        return res;
        }
 
-       if (!add)
-               return 0;
+       return 0;
+}
+
+static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
+                          struct cfg80211_ap_settings *info)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       struct ath6kl_vif *vif = netdev_priv(dev);
+       struct ieee80211_mgmt *mgmt;
+       u8 *ies;
+       int ies_len;
+       struct wmi_connect_cmd p;
+       int res;
+       int i, ret;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
+
+       if (!ath6kl_cfg80211_ready(vif))
+               return -EIO;
+
+       if (vif->next_mode != AP_NETWORK)
+               return -EOPNOTSUPP;
+
+       res = ath6kl_set_ies(vif, &info->beacon);
 
        ar->ap_mode_bkey.valid = false;
 
@@ -2122,13 +2332,13 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
         * info->dtim_period
         */
 
-       if (info->head == NULL)
+       if (info->beacon.head == NULL)
                return -EINVAL;
-       mgmt = (struct ieee80211_mgmt *) info->head;
+       mgmt = (struct ieee80211_mgmt *) info->beacon.head;
        ies = mgmt->u.beacon.variable;
-       if (ies > info->head + info->head_len)
+       if (ies > info->beacon.head + info->beacon.head_len)
                return -EINVAL;
-       ies_len = info->head + info->head_len - ies;
+       ies_len = info->beacon.head + info->beacon.head_len - ies;
 
        if (info->ssid == NULL)
                return -EINVAL;
@@ -2214,6 +2424,11 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
        p.dot11_auth_mode = vif->dot11_auth_mode;
        p.ch = cpu_to_le16(vif->next_chan);
 
+       /* Enable uAPSD support by default */
+       res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
+       if (res < 0)
+               return res;
+
        if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
                p.nw_subtype = SUBTYPE_P2PGO;
        } else {
@@ -2231,19 +2446,21 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
        return 0;
 }
 
-static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
-                            struct beacon_parameters *info)
+static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
+                               struct cfg80211_beacon_data *beacon)
 {
-       return ath6kl_ap_beacon(wiphy, dev, info, true);
-}
+       struct ath6kl_vif *vif = netdev_priv(dev);
 
-static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
-                            struct beacon_parameters *info)
-{
-       return ath6kl_ap_beacon(wiphy, dev, info, false);
+       if (!ath6kl_cfg80211_ready(vif))
+               return -EIO;
+
+       if (vif->next_mode != AP_NETWORK)
+               return -EOPNOTSUPP;
+
+       return ath6kl_set_ies(vif, beacon);
 }
 
-static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
+static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
 {
        struct ath6kl *ar = ath6kl_priv(dev);
        struct ath6kl_vif *vif = netdev_priv(dev);
@@ -2259,6 +2476,19 @@ static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
        return 0;
 }
 
+static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
+                             u8 *mac)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       struct ath6kl_vif *vif = netdev_priv(dev);
+       const u8 *addr = mac ? mac : bcast_addr;
+
+       return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
+                                     addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
+}
+
 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
                                 u8 *mac, struct station_parameters *params)
 {
@@ -2518,6 +2748,12 @@ ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
        },
+       [NL80211_IFTYPE_AP] = {
+               .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+               BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
+               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+               BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+       },
        [NL80211_IFTYPE_P2P_CLIENT] = {
                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
@@ -2559,9 +2795,10 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
        .resume = __ath6kl_cfg80211_resume,
 #endif
        .set_channel = ath6kl_set_channel,
-       .add_beacon = ath6kl_add_beacon,
-       .set_beacon = ath6kl_set_beacon,
-       .del_beacon = ath6kl_del_beacon,
+       .start_ap = ath6kl_start_ap,
+       .change_beacon = ath6kl_change_beacon,
+       .stop_ap = ath6kl_stop_ap,
+       .del_station = ath6kl_del_station,
        .change_station = ath6kl_change_station,
        .remain_on_channel = ath6kl_remain_on_channel,
        .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
@@ -2629,122 +2866,9 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
                ath6kl_cfg80211_stop(vif);
 }
 
-struct ath6kl *ath6kl_core_alloc(struct device *dev)
-{
-       struct ath6kl *ar;
-       struct wiphy *wiphy;
-       u8 ctr;
-
-       /* create a new wiphy for use with cfg80211 */
-       wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
-
-       if (!wiphy) {
-               ath6kl_err("couldn't allocate wiphy device\n");
-               return NULL;
-       }
-
-       ar = wiphy_priv(wiphy);
-       ar->p2p = !!ath6kl_p2p;
-       ar->wiphy = wiphy;
-       ar->dev = dev;
-
-       ar->vif_max = 1;
-
-       ar->max_norm_iface = 1;
-
-       spin_lock_init(&ar->lock);
-       spin_lock_init(&ar->mcastpsq_lock);
-       spin_lock_init(&ar->list_lock);
-
-       init_waitqueue_head(&ar->event_wq);
-       sema_init(&ar->sem, 1);
-
-       INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
-       INIT_LIST_HEAD(&ar->vif_list);
-
-       clear_bit(WMI_ENABLED, &ar->flag);
-       clear_bit(SKIP_SCAN, &ar->flag);
-       clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
-
-       ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
-       ar->listen_intvl_b = 0;
-       ar->tx_pwr = 0;
-
-       ar->intra_bss = 1;
-       ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
-
-       ar->state = ATH6KL_STATE_OFF;
-
-       memset((u8 *)ar->sta_list, 0,
-              AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
-
-       /* Init the PS queues */
-       for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
-               spin_lock_init(&ar->sta_list[ctr].psq_lock);
-               skb_queue_head_init(&ar->sta_list[ctr].psq);
-       }
-
-       skb_queue_head_init(&ar->mcastpsq);
-
-       memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
-
-       return ar;
-}
-
-int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
-{
-       struct wiphy *wiphy = ar->wiphy;
-       int ret;
-
-       wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
-
-       wiphy->max_remain_on_channel_duration = 5000;
-
-       /* set device pointer for wiphy */
-       set_wiphy_dev(wiphy, ar->dev);
-
-       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-                                BIT(NL80211_IFTYPE_ADHOC) |
-                                BIT(NL80211_IFTYPE_AP);
-       if (ar->p2p) {
-               wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
-                                         BIT(NL80211_IFTYPE_P2P_CLIENT);
-       }
-
-       /* max num of ssids that can be probed during scanning */
-       wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
-       wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
-       wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
-       wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
-       wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-
-       wiphy->cipher_suites = cipher_suites;
-       wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-
-       wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-                             WIPHY_WOWLAN_DISCONNECT |
-                             WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
-                             WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
-                             WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
-                             WIPHY_WOWLAN_4WAY_HANDSHAKE;
-       wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
-       wiphy->wowlan.pattern_min_len = 1;
-       wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
-
-       wiphy->max_sched_scan_ssids = 10;
-
-       ret = wiphy_register(wiphy);
-       if (ret < 0) {
-               ath6kl_err("couldn't register wiphy device\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-static int ath6kl_init_if_data(struct ath6kl_vif *vif)
+static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
 {
-       vif->aggr_cntxt = aggr_init(vif->ndev);
+       vif->aggr_cntxt = aggr_init(vif);
        if (!vif->aggr_cntxt) {
                ath6kl_err("failed to initialize aggr\n");
                return -ENOMEM;
@@ -2758,12 +2882,15 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif)
        set_bit(WMM_ENABLED, &vif->flags);
        spin_lock_init(&vif->if_lock);
 
+       INIT_LIST_HEAD(&vif->mc_filter);
+
        return 0;
 }
 
-void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
+void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
 {
        struct ath6kl *ar = vif->ar;
+       struct ath6kl_mc_filter *mc_filter, *tmp;
 
        aggr_module_destroy(vif->aggr_cntxt);
 
@@ -2772,6 +2899,11 @@ void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
        if (vif->nw_type == ADHOC_NETWORK)
                ar->ibss_if_active = false;
 
+       list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
+               list_del(&mc_filter->list);
+               kfree(mc_filter);
+       }
+
        unregister_netdevice(vif->ndev);
 
        ar->num_vif--;
@@ -2808,8 +2940,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
 
        ath6kl_init_control_info(vif);
 
-       /* TODO: Pass interface specific pointer instead of ar */
-       if (ath6kl_init_if_data(vif))
+       if (ath6kl_cfg80211_vif_init(vif))
                goto err;
 
        if (register_netdevice(ndev))
@@ -2836,8 +2967,89 @@ err:
        return NULL;
 }
 
-void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar)
+int ath6kl_cfg80211_init(struct ath6kl *ar)
+{
+       struct wiphy *wiphy = ar->wiphy;
+       int ret;
+
+       wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
+
+       wiphy->max_remain_on_channel_duration = 5000;
+
+       /* set device pointer for wiphy */
+       set_wiphy_dev(wiphy, ar->dev);
+
+       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                BIT(NL80211_IFTYPE_ADHOC) |
+                                BIT(NL80211_IFTYPE_AP);
+       if (ar->p2p) {
+               wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
+                                         BIT(NL80211_IFTYPE_P2P_CLIENT);
+       }
+
+       /* max num of ssids that can be probed during scanning */
+       wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
+       wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
+       wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
+       wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
+       wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+       wiphy->cipher_suites = cipher_suites;
+       wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
+       wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
+                             WIPHY_WOWLAN_DISCONNECT |
+                             WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
+                             WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+                             WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
+                             WIPHY_WOWLAN_4WAY_HANDSHAKE;
+       wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
+       wiphy->wowlan.pattern_min_len = 1;
+       wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
+
+       wiphy->max_sched_scan_ssids = 10;
+
+       ret = wiphy_register(wiphy);
+       if (ret < 0) {
+               ath6kl_err("couldn't register wiphy device\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
 {
        wiphy_unregister(ar->wiphy);
+}
+
+struct ath6kl *ath6kl_cfg80211_create(void)
+{
+       struct ath6kl *ar;
+       struct wiphy *wiphy;
+
+       /* create a new wiphy for use with cfg80211 */
+       wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
+
+       if (!wiphy) {
+               ath6kl_err("couldn't allocate wiphy device\n");
+               return NULL;
+       }
+
+       ar = wiphy_priv(wiphy);
+       ar->wiphy = wiphy;
+
+       return ar;
+}
+
+/* Note: ar variable must not be accessed after calling this! */
+void ath6kl_cfg80211_destroy(struct ath6kl *ar)
+{
+       int i;
+
+       for (i = 0; i < AP_MAX_NUM_STA; i++)
+               kfree(ar->sta_list[i].aggr_conn);
+
        wiphy_free(ar->wiphy);
 }
+
index 81f20a572315d8291d30a26711745d768eee663d..3c693b7c0efd317bec2fe2bbdea2611b65faef00 100644 (file)
@@ -27,10 +27,6 @@ enum ath6kl_cfg_suspend_mode {
 struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
                                        enum nl80211_iftype type,
                                        u8 fw_vif_idx, u8 nw_type);
-int ath6kl_register_ieee80211_hw(struct ath6kl *ar);
-struct ath6kl *ath6kl_core_alloc(struct device *dev);
-void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar);
-
 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted);
 
 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
@@ -53,7 +49,15 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
 
 int ath6kl_cfg80211_resume(struct ath6kl *ar);
 
+void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif);
+
 void ath6kl_cfg80211_stop(struct ath6kl_vif *vif);
 void ath6kl_cfg80211_stop_all(struct ath6kl *ar);
 
+int ath6kl_cfg80211_init(struct ath6kl *ar);
+void ath6kl_cfg80211_cleanup(struct ath6kl *ar);
+
+struct ath6kl *ath6kl_cfg80211_create(void);
+void ath6kl_cfg80211_destroy(struct ath6kl *ar);
+
 #endif /* ATH6KL_CFG80211_H */
index bfd6597763daa9dcb953aeb413cc5b62c68fcde4..f89f1e180da376b0181da9ec8a01cd0c176e819e 100644 (file)
@@ -79,8 +79,5 @@ struct ath6kl;
 enum htc_credit_dist_reason;
 struct ath6kl_htc_credit_info;
 
-struct ath6kl *ath6kl_core_alloc(struct device *sdev);
-int ath6kl_core_init(struct ath6kl *ar);
-void ath6kl_core_cleanup(struct ath6kl *ar);
 struct sk_buff *ath6kl_buf_alloc(int size);
 #endif /* COMMON_H */
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
new file mode 100644 (file)
index 0000000..722ca59
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "core.h"
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/export.h>
+
+#include "debug.h"
+#include "hif-ops.h"
+#include "cfg80211.h"
+
+unsigned int debug_mask;
+static unsigned int suspend_mode;
+static unsigned int uart_debug;
+static unsigned int ath6kl_p2p;
+static unsigned int testmode;
+
+module_param(debug_mask, uint, 0644);
+module_param(suspend_mode, uint, 0644);
+module_param(uart_debug, uint, 0644);
+module_param(ath6kl_p2p, uint, 0644);
+module_param(testmode, uint, 0644);
+
+int ath6kl_core_init(struct ath6kl *ar)
+{
+       struct ath6kl_bmi_target_info targ_info;
+       struct net_device *ndev;
+       int ret = 0, i;
+
+       ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
+       if (!ar->ath6kl_wq)
+               return -ENOMEM;
+
+       ret = ath6kl_bmi_init(ar);
+       if (ret)
+               goto err_wq;
+
+       /*
+        * Turn on power to get hardware (target) version and leave power
+        * on delibrately as we will boot the hardware anyway within few
+        * seconds.
+        */
+       ret = ath6kl_hif_power_on(ar);
+       if (ret)
+               goto err_bmi_cleanup;
+
+       ret = ath6kl_bmi_get_target_info(ar, &targ_info);
+       if (ret)
+               goto err_power_off;
+
+       ar->version.target_ver = le32_to_cpu(targ_info.version);
+       ar->target_type = le32_to_cpu(targ_info.type);
+       ar->wiphy->hw_version = le32_to_cpu(targ_info.version);
+
+       ret = ath6kl_init_hw_params(ar);
+       if (ret)
+               goto err_power_off;
+
+       ar->htc_target = ath6kl_htc_create(ar);
+
+       if (!ar->htc_target) {
+               ret = -ENOMEM;
+               goto err_power_off;
+       }
+
+       ar->testmode = testmode;
+
+       ret = ath6kl_init_fetch_firmwares(ar);
+       if (ret)
+               goto err_htc_cleanup;
+
+       /* FIXME: we should free all firmwares in the error cases below */
+
+       /* Indicate that WMI is enabled (although not ready yet) */
+       set_bit(WMI_ENABLED, &ar->flag);
+       ar->wmi = ath6kl_wmi_init(ar);
+       if (!ar->wmi) {
+               ath6kl_err("failed to initialize wmi\n");
+               ret = -EIO;
+               goto err_htc_cleanup;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
+
+       ret = ath6kl_cfg80211_init(ar);
+       if (ret)
+               goto err_node_cleanup;
+
+       ret = ath6kl_debug_init(ar);
+       if (ret) {
+               wiphy_unregister(ar->wiphy);
+               goto err_node_cleanup;
+       }
+
+       for (i = 0; i < ar->vif_max; i++)
+               ar->avail_idx_map |= BIT(i);
+
+       rtnl_lock();
+
+       /* Add an initial station interface */
+       ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0,
+                                   INFRA_NETWORK);
+
+       rtnl_unlock();
+
+       if (!ndev) {
+               ath6kl_err("Failed to instantiate a network device\n");
+               ret = -ENOMEM;
+               wiphy_unregister(ar->wiphy);
+               goto err_debug_init;
+       }
+
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
+                       __func__, ndev->name, ndev, ar);
+
+       /* setup access class priority mappings */
+       ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest  */
+       ar->ac_stream_pri_map[WMM_AC_BE] = 1;
+       ar->ac_stream_pri_map[WMM_AC_VI] = 2;
+       ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
+
+       /* give our connected endpoints some buffers */
+       ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
+       ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
+
+       /* allocate some buffers that handle larger AMSDU frames */
+       ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
+
+       ath6kl_cookie_init(ar);
+
+       ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
+                        ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
+
+       if (suspend_mode &&
+               suspend_mode >= WLAN_POWER_STATE_CUT_PWR &&
+               suspend_mode <= WLAN_POWER_STATE_WOW)
+               ar->suspend_mode = suspend_mode;
+       else
+               ar->suspend_mode = 0;
+
+       if (uart_debug)
+               ar->conf_flags |= ATH6KL_CONF_UART_DEBUG;
+
+       ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
+                           WIPHY_FLAG_HAVE_AP_SME |
+                           WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
+                           WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
+
+       if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
+               ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+
+       ar->wiphy->probe_resp_offload =
+               NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
+               NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
+               NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
+               NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
+
+       set_bit(FIRST_BOOT, &ar->flag);
+
+       ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+
+       ret = ath6kl_init_hw_start(ar);
+       if (ret) {
+               ath6kl_err("Failed to start hardware: %d\n", ret);
+               goto err_rxbuf_cleanup;
+       }
+
+       /*
+        * Set mac address which is received in ready event
+        * FIXME: Move to ath6kl_interface_add()
+        */
+       memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
+
+       return ret;
+
+err_rxbuf_cleanup:
+       ath6kl_htc_flush_rx_buf(ar->htc_target);
+       ath6kl_cleanup_amsdu_rxbufs(ar);
+       rtnl_lock();
+       ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev));
+       rtnl_unlock();
+       wiphy_unregister(ar->wiphy);
+err_debug_init:
+       ath6kl_debug_cleanup(ar);
+err_node_cleanup:
+       ath6kl_wmi_shutdown(ar->wmi);
+       clear_bit(WMI_ENABLED, &ar->flag);
+       ar->wmi = NULL;
+err_htc_cleanup:
+       ath6kl_htc_cleanup(ar->htc_target);
+err_power_off:
+       ath6kl_hif_power_off(ar);
+err_bmi_cleanup:
+       ath6kl_bmi_cleanup(ar);
+err_wq:
+       destroy_workqueue(ar->ath6kl_wq);
+
+       return ret;
+}
+EXPORT_SYMBOL(ath6kl_core_init);
+
+struct ath6kl *ath6kl_core_create(struct device *dev)
+{
+       struct ath6kl *ar;
+       u8 ctr;
+
+       ar = ath6kl_cfg80211_create();
+       if (!ar)
+               return NULL;
+
+       ar->p2p = !!ath6kl_p2p;
+       ar->dev = dev;
+
+       ar->vif_max = 1;
+
+       ar->max_norm_iface = 1;
+
+       spin_lock_init(&ar->lock);
+       spin_lock_init(&ar->mcastpsq_lock);
+       spin_lock_init(&ar->list_lock);
+
+       init_waitqueue_head(&ar->event_wq);
+       sema_init(&ar->sem, 1);
+
+       INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
+       INIT_LIST_HEAD(&ar->vif_list);
+
+       clear_bit(WMI_ENABLED, &ar->flag);
+       clear_bit(SKIP_SCAN, &ar->flag);
+       clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
+
+       ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL;
+       ar->tx_pwr = 0;
+
+       ar->intra_bss = 1;
+       ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
+
+       ar->state = ATH6KL_STATE_OFF;
+
+       memset((u8 *)ar->sta_list, 0,
+              AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
+
+       /* Init the PS queues */
+       for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
+               spin_lock_init(&ar->sta_list[ctr].psq_lock);
+               skb_queue_head_init(&ar->sta_list[ctr].psq);
+               skb_queue_head_init(&ar->sta_list[ctr].apsdq);
+               ar->sta_list[ctr].aggr_conn =
+                       kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL);
+               if (!ar->sta_list[ctr].aggr_conn) {
+                       ath6kl_err("Failed to allocate memory for sta aggregation information\n");
+                       ath6kl_core_destroy(ar);
+                       return NULL;
+               }
+       }
+
+       skb_queue_head_init(&ar->mcastpsq);
+
+       memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
+
+       return ar;
+}
+EXPORT_SYMBOL(ath6kl_core_create);
+
+void ath6kl_core_cleanup(struct ath6kl *ar)
+{
+       ath6kl_hif_power_off(ar);
+
+       destroy_workqueue(ar->ath6kl_wq);
+
+       if (ar->htc_target)
+               ath6kl_htc_cleanup(ar->htc_target);
+
+       ath6kl_cookie_cleanup(ar);
+
+       ath6kl_cleanup_amsdu_rxbufs(ar);
+
+       ath6kl_bmi_cleanup(ar);
+
+       ath6kl_debug_cleanup(ar);
+
+       kfree(ar->fw_board);
+       kfree(ar->fw_otp);
+       kfree(ar->fw);
+       kfree(ar->fw_patch);
+       kfree(ar->fw_testscript);
+
+       ath6kl_cfg80211_cleanup(ar);
+}
+EXPORT_SYMBOL(ath6kl_core_cleanup);
+
+void ath6kl_core_destroy(struct ath6kl *ar)
+{
+       ath6kl_cfg80211_destroy(ar);
+}
+EXPORT_SYMBOL(ath6kl_core_destroy);
+
+MODULE_AUTHOR("Qualcomm Atheros");
+MODULE_DESCRIPTION("Core module for AR600x SDIO and USB devices.");
+MODULE_LICENSE("Dual BSD/GPL");
index c863a28f2e0c6f2a6b7477292cbc8be4fbe483e9..c4d66e066dc9f293afeddcc449770fa0386a8d3e 100644 (file)
 #define ATH6KL_MAX_ENDPOINTS   4
 #define MAX_NODE_NUM           15
 
+#define ATH6KL_APSD_ALL_FRAME          0xFFFF
+#define ATH6KL_APSD_NUM_OF_AC          0x4
+#define ATH6KL_APSD_FRAME_MASK         0xF
+
 /* Extra bytes for htc header alignment */
 #define ATH6KL_HTC_ALIGN_BYTES 3
 
@@ -55,7 +59,7 @@
 #define MAX_DEFAULT_SEND_QUEUE_DEPTH      (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
 
 #define DISCON_TIMER_INTVAL               10000  /* in msec */
-#define A_DEFAULT_LISTEN_INTERVAL         100
+#define A_DEFAULT_LISTEN_INTERVAL         1      /* beacon intervals */
 #define A_MAX_WOW_LISTEN_INTERVAL         1000
 
 /* includes also the null byte */
@@ -97,45 +101,49 @@ struct ath6kl_fw_ie {
        u8 data[0];
 };
 
+#define ATH6KL_FW_API2_FILE "fw-2.bin"
+#define ATH6KL_FW_API3_FILE "fw-3.bin"
+
 /* AR6003 1.0 definitions */
 #define AR6003_HW_1_0_VERSION                 0x300002ba
 
 /* AR6003 2.0 definitions */
 #define AR6003_HW_2_0_VERSION                 0x30000384
 #define AR6003_HW_2_0_PATCH_DOWNLOAD_ADDRESS  0x57e910
-#define AR6003_HW_2_0_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
-#define AR6003_HW_2_0_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
-#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
-#define AR6003_HW_2_0_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
-#define AR6003_HW_2_0_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin"
+#define AR6003_HW_2_0_FW_DIR                   "ath6k/AR6003/hw2.0"
+#define AR6003_HW_2_0_OTP_FILE                 "otp.bin.z77"
+#define AR6003_HW_2_0_FIRMWARE_FILE            "athwlan.bin.z77"
+#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE       "athtcmd_ram.bin"
+#define AR6003_HW_2_0_PATCH_FILE               "data.patch.bin"
 #define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin"
 #define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \
                        "ath6k/AR6003/hw2.0/bdata.SD31.bin"
 
 /* AR6003 3.0 definitions */
 #define AR6003_HW_2_1_1_VERSION                 0x30000582
-#define AR6003_HW_2_1_1_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin"
-#define AR6003_HW_2_1_1_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin"
-#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE \
-                       "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin"
-#define AR6003_HW_2_1_1_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin"
-#define AR6003_HW_2_1_1_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin"
+#define AR6003_HW_2_1_1_FW_DIR                 "ath6k/AR6003/hw2.1.1"
+#define AR6003_HW_2_1_1_OTP_FILE               "otp.bin"
+#define AR6003_HW_2_1_1_FIRMWARE_FILE          "athwlan.bin"
+#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE     "athtcmd_ram.bin"
+#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE      "utf.bin"
+#define AR6003_HW_2_1_1_TESTSCRIPT_FILE        "nullTestFlow.bin"
+#define AR6003_HW_2_1_1_PATCH_FILE             "data.patch.bin"
 #define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin"
 #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE        \
                        "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
 
 /* AR6004 1.0 definitions */
 #define AR6004_HW_1_0_VERSION                 0x30000623
-#define AR6004_HW_1_0_FIRMWARE_2_FILE         "ath6k/AR6004/hw1.0/fw-2.bin"
-#define AR6004_HW_1_0_FIRMWARE_FILE           "ath6k/AR6004/hw1.0/fw.ram.bin"
+#define AR6004_HW_1_0_FW_DIR                   "ath6k/AR6004/hw1.0"
+#define AR6004_HW_1_0_FIRMWARE_FILE            "fw.ram.bin"
 #define AR6004_HW_1_0_BOARD_DATA_FILE         "ath6k/AR6004/hw1.0/bdata.bin"
 #define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \
        "ath6k/AR6004/hw1.0/bdata.DB132.bin"
 
 /* AR6004 1.1 definitions */
 #define AR6004_HW_1_1_VERSION                 0x30000001
-#define AR6004_HW_1_1_FIRMWARE_2_FILE         "ath6k/AR6004/hw1.1/fw-2.bin"
-#define AR6004_HW_1_1_FIRMWARE_FILE           "ath6k/AR6004/hw1.1/fw.ram.bin"
+#define AR6004_HW_1_1_FW_DIR                   "ath6k/AR6004/hw1.1"
+#define AR6004_HW_1_1_FIRMWARE_FILE            "fw.ram.bin"
 #define AR6004_HW_1_1_BOARD_DATA_FILE         "ath6k/AR6004/hw1.1/bdata.bin"
 #define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \
        "ath6k/AR6004/hw1.1/bdata.DB132.bin"
@@ -144,6 +152,8 @@ struct ath6kl_fw_ie {
 #define STA_PS_AWAKE           BIT(0)
 #define        STA_PS_SLEEP            BIT(1)
 #define        STA_PS_POLLED           BIT(2)
+#define STA_PS_APSD_TRIGGER     BIT(3)
+#define STA_PS_APSD_EOSP        BIT(4)
 
 /* HTC TX packet tagging definitions */
 #define ATH6KL_CONTROL_PKT_TAG    HTC_TX_PACKET_TAG_USER_DEFINED
@@ -186,7 +196,7 @@ struct ath6kl_fw_ie {
 #define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN  BIT(1)
 #define ATH6KL_CONF_ENABLE_11N                 BIT(2)
 #define ATH6KL_CONF_ENABLE_TX_BURST            BIT(3)
-#define ATH6KL_CONF_SUSPEND_CUTPOWER           BIT(4)
+#define ATH6KL_CONF_UART_DEBUG                 BIT(4)
 
 enum wlan_low_pwr_state {
        WLAN_POWER_STATE_ON,
@@ -231,14 +241,19 @@ struct rxtid_stats {
        u32 num_bar;
 };
 
-struct aggr_info {
+struct aggr_info_conn {
        u8 aggr_sz;
        u8 timer_scheduled;
        struct timer_list timer;
        struct net_device *dev;
        struct rxtid rx_tid[NUM_OF_TIDS];
-       struct sk_buff_head free_q;
        struct rxtid_stats stat[NUM_OF_TIDS];
+       struct aggr_info *aggr_info;
+};
+
+struct aggr_info {
+       struct aggr_info_conn *aggr_conn;
+       struct sk_buff_head rx_amsdu_freeq;
 };
 
 struct ath6kl_wep_key {
@@ -280,6 +295,9 @@ struct ath6kl_sta {
        u8 wpa_ie[ATH6KL_MAX_IE];
        struct sk_buff_head psq;
        spinlock_t psq_lock;
+       u8 apsd_info;
+       struct sk_buff_head apsdq;
+       struct aggr_info_conn *aggr_conn;
 };
 
 struct ath6kl_version {
@@ -408,6 +426,13 @@ enum ath6kl_hif_type {
        ATH6KL_HIF_TYPE_USB,
 };
 
+/* Max number of filters that hw supports */
+#define ATH6K_MAX_MC_FILTERS_PER_LIST 7
+struct ath6kl_mc_filter {
+       struct list_head list;
+       char hw_addr[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
+};
+
 /*
  * Driver's maximum limit, note that some firmwares support only one vif
  * and the runtime (current) limit must be checked from ar->vif_max.
@@ -426,6 +451,7 @@ enum ath6kl_vif_state {
        DTIM_PERIOD_AVAIL,
        WLAN_ENABLED,
        STATS_UPDATE_PEND,
+       HOST_SLEEP_MODE_CMD_PROCESSED,
 };
 
 struct ath6kl_vif {
@@ -471,6 +497,8 @@ struct ath6kl_vif {
        u8 assoc_bss_dtim_period;
        struct net_device_stats net_stats;
        struct target_stats target_stats;
+
+       struct list_head mc_filter;
 };
 
 #define WOW_LIST_ID            0
@@ -504,6 +532,7 @@ struct ath6kl {
        struct wiphy *wiphy;
 
        enum ath6kl_state state;
+       unsigned int testmode;
 
        struct ath6kl_bmi bmi;
        const struct ath6kl_hif_ops *hif_ops;
@@ -523,7 +552,6 @@ struct ath6kl {
        spinlock_t lock;
        struct semaphore sem;
        u16 listen_intvl_b;
-       u16 listen_intvl_t;
        u8 lrssi_roam_threshold;
        struct ath6kl_version version;
        u32 target_type;
@@ -574,17 +602,24 @@ struct ath6kl {
                u32 board_addr;
                u32 refclk_hz;
                u32 uarttx_pin;
+               u32 testscript_addr;
+
+               struct ath6kl_hw_fw {
+                       const char *dir;
+                       const char *otp;
+                       const char *fw;
+                       const char *tcmd;
+                       const char *patch;
+                       const char *utf;
+                       const char *testscript;
+               } fw;
 
-               const char *fw_otp;
-               const char *fw;
-               const char *fw_tcmd;
-               const char *fw_patch;
-               const char *fw_api2;
                const char *fw_board;
                const char *fw_default_board;
        } hw;
 
        u16 conf_flags;
+       u16 suspend_mode;
        wait_queue_head_t event_wq;
        struct ath6kl_mbox_info mbox_info;
 
@@ -603,6 +638,10 @@ struct ath6kl {
        u8 *fw_patch;
        size_t fw_patch_len;
 
+       u8 *fw_testscript;
+       size_t fw_testscript_len;
+
+       unsigned int fw_api;
        unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN];
 
        struct workqueue_struct *ath6kl_wq;
@@ -676,7 +715,9 @@ struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
 void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie);
 int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev);
 
-struct aggr_info *aggr_init(struct net_device *dev);
+struct aggr_info *aggr_init(struct ath6kl_vif *vif);
+void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
+                   struct aggr_info_conn *aggr_conn);
 void ath6kl_rx_refill(struct htc_target *target,
                      enum htc_endpoint_id endpoint);
 void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count);
@@ -684,7 +725,7 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
                                            enum htc_endpoint_id endpoint,
                                            int len);
 void aggr_module_destroy(struct aggr_info *aggr_info);
-void aggr_reset_state(struct aggr_info *aggr_info);
+void aggr_reset_state(struct aggr_info_conn *aggr_conn);
 
 struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr);
 struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
@@ -700,7 +741,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
 void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel);
 void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
                                u8 keymgmt, u8 ucipher, u8 auth,
-                               u8 assoc_req_len, u8 *assoc_info);
+                               u8 assoc_req_len, u8 *assoc_info, u8 apsd_info);
 void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason,
                             u8 *bssid, u8 assoc_resp_len,
                             u8 *assoc_info, u16 prot_reason_status);
@@ -723,12 +764,18 @@ void ath6kl_wakeup_event(void *dev);
 void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
                         bool wait_fot_compltn, bool cold_reset);
 void ath6kl_init_control_info(struct ath6kl_vif *vif);
-void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
-void ath6kl_core_free(struct ath6kl *ar);
 struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
 void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready);
 int ath6kl_init_hw_start(struct ath6kl *ar);
 int ath6kl_init_hw_stop(struct ath6kl *ar);
+int ath6kl_init_fetch_firmwares(struct ath6kl *ar);
+int ath6kl_init_hw_params(struct ath6kl *ar);
+
 void ath6kl_check_wow_status(struct ath6kl *ar);
 
+struct ath6kl *ath6kl_core_create(struct device *dev);
+int ath6kl_core_init(struct ath6kl *ar);
+void ath6kl_core_cleanup(struct ath6kl *ar);
+void ath6kl_core_destroy(struct ath6kl *ar);
+
 #endif /* CORE_H */
index eb808b46f94cec1010a16e0733f9dacbf5ee4147..d832058816fefc635bd10dc408c9a5d56a22cbc9 100644 (file)
@@ -54,9 +54,42 @@ int ath6kl_printk(const char *level, const char *fmt, ...)
 
        return rtn;
 }
+EXPORT_SYMBOL(ath6kl_printk);
 
 #ifdef CONFIG_ATH6KL_DEBUG
 
+void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...)
+{
+       struct va_format vaf;
+       va_list args;
+
+       if (!(debug_mask & mask))
+               return;
+
+       va_start(args, fmt);
+
+       vaf.fmt = fmt;
+       vaf.va = &args;
+
+       ath6kl_printk(KERN_DEBUG, "%pV", &vaf);
+
+       va_end(args);
+}
+EXPORT_SYMBOL(ath6kl_dbg);
+
+void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
+                    const char *msg, const char *prefix,
+                    const void *buf, size_t len)
+{
+       if (debug_mask & mask) {
+               if (msg)
+                       ath6kl_dbg(mask, "%s\n", msg);
+
+               print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
+       }
+}
+EXPORT_SYMBOL(ath6kl_dbg_dump);
+
 #define REG_OUTPUT_LEN_PER_LINE        25
 #define REGTYPE_STR_LEN                100
 
@@ -82,31 +115,31 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
                           struct ath6kl_irq_enable_reg *irq_enable_reg)
 {
 
-       ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n"));
+       ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n"));
 
        if (irq_proc_reg != NULL) {
-               ath6kl_dbg(ATH6KL_DBG_ANY,
+               ath6kl_dbg(ATH6KL_DBG_IRQ,
                        "Host Int status:           0x%x\n",
                        irq_proc_reg->host_int_status);
-               ath6kl_dbg(ATH6KL_DBG_ANY,
+               ath6kl_dbg(ATH6KL_DBG_IRQ,
                           "CPU Int status:            0x%x\n",
                        irq_proc_reg->cpu_int_status);
-               ath6kl_dbg(ATH6KL_DBG_ANY,
+               ath6kl_dbg(ATH6KL_DBG_IRQ,
                           "Error Int status:          0x%x\n",
                        irq_proc_reg->error_int_status);
-               ath6kl_dbg(ATH6KL_DBG_ANY,
+               ath6kl_dbg(ATH6KL_DBG_IRQ,
                           "Counter Int status:        0x%x\n",
                        irq_proc_reg->counter_int_status);
-               ath6kl_dbg(ATH6KL_DBG_ANY,
+               ath6kl_dbg(ATH6KL_DBG_IRQ,
                           "Mbox Frame:                0x%x\n",
                        irq_proc_reg->mbox_frame);
-               ath6kl_dbg(ATH6KL_DBG_ANY,
+               ath6kl_dbg(ATH6KL_DBG_IRQ,
                           "Rx Lookahead Valid:        0x%x\n",
                        irq_proc_reg->rx_lkahd_valid);
-               ath6kl_dbg(ATH6KL_DBG_ANY,
+               ath6kl_dbg(ATH6KL_DBG_IRQ,
                           "Rx Lookahead 0:            0x%x\n",
                        irq_proc_reg->rx_lkahd[0]);
-               ath6kl_dbg(ATH6KL_DBG_ANY,
+               ath6kl_dbg(ATH6KL_DBG_IRQ,
                           "Rx Lookahead 1:            0x%x\n",
                        irq_proc_reg->rx_lkahd[1]);
 
@@ -115,16 +148,16 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
                         * If the target supports GMBOX hardware, dump some
                         * additional state.
                         */
-                       ath6kl_dbg(ATH6KL_DBG_ANY,
+                       ath6kl_dbg(ATH6KL_DBG_IRQ,
                                "GMBOX Host Int status 2:   0x%x\n",
                                irq_proc_reg->host_int_status2);
-                       ath6kl_dbg(ATH6KL_DBG_ANY,
+                       ath6kl_dbg(ATH6KL_DBG_IRQ,
                                "GMBOX RX Avail:            0x%x\n",
                                irq_proc_reg->gmbox_rx_avail);
-                       ath6kl_dbg(ATH6KL_DBG_ANY,
+                       ath6kl_dbg(ATH6KL_DBG_IRQ,
                                "GMBOX lookahead alias 0:   0x%x\n",
                                irq_proc_reg->rx_gmbox_lkahd_alias[0]);
-                       ath6kl_dbg(ATH6KL_DBG_ANY,
+                       ath6kl_dbg(ATH6KL_DBG_IRQ,
                                "GMBOX lookahead alias 1:   0x%x\n",
                                irq_proc_reg->rx_gmbox_lkahd_alias[1]);
                }
@@ -132,13 +165,13 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
        }
 
        if (irq_enable_reg != NULL) {
-               ath6kl_dbg(ATH6KL_DBG_ANY,
+               ath6kl_dbg(ATH6KL_DBG_IRQ,
                        "Int status Enable:         0x%x\n",
                        irq_enable_reg->int_status_en);
-               ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n",
+               ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n",
                        irq_enable_reg->cntr_int_status_en);
        }
-       ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n");
+       ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n");
 }
 
 static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
@@ -175,9 +208,6 @@ void dump_cred_dist_stats(struct htc_target *target)
 {
        struct htc_endpoint_credit_dist *ep_list;
 
-       if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_CREDIT))
-               return;
-
        list_for_each_entry(ep_list, &target->cred_dist_list, list)
                dump_cred_dist(ep_list);
 
@@ -1411,6 +1441,8 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
                return -EINVAL;
        pstream.medium_time = cpu_to_le32(val32);
 
+       pstream.nominal_phy = le32_to_cpu(pstream.min_phy_rate) / 1000000;
+
        ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream);
 
        return count;
@@ -1505,57 +1537,46 @@ static const struct file_operations fops_bgscan_int = {
 };
 
 static ssize_t ath6kl_listen_int_write(struct file *file,
-                                               const char __user *user_buf,
-                                               size_t count, loff_t *ppos)
+                                      const char __user *user_buf,
+                                      size_t count, loff_t *ppos)
 {
        struct ath6kl *ar = file->private_data;
-       u16 listen_int_t, listen_int_b;
+       struct ath6kl_vif *vif;
+       u16 listen_interval;
        char buf[32];
-       char *sptr, *token;
        ssize_t len;
 
+       vif = ath6kl_vif_first(ar);
+       if (!vif)
+               return -EIO;
+
        len = min(count, sizeof(buf) - 1);
        if (copy_from_user(buf, user_buf, len))
                return -EFAULT;
 
        buf[len] = '\0';
-       sptr = buf;
-
-       token = strsep(&sptr, " ");
-       if (!token)
-               return -EINVAL;
-
-       if (kstrtou16(token, 0, &listen_int_t))
-               return -EINVAL;
-
-       if (kstrtou16(sptr, 0, &listen_int_b))
-               return -EINVAL;
-
-       if ((listen_int_t < 15) || (listen_int_t > 5000))
+       if (kstrtou16(buf, 0, &listen_interval))
                return -EINVAL;
 
-       if ((listen_int_b < 1) || (listen_int_b > 50))
+       if ((listen_interval < 1) || (listen_interval > 50))
                return -EINVAL;
 
-       ar->listen_intvl_t = listen_int_t;
-       ar->listen_intvl_b = listen_int_b;
-
-       ath6kl_wmi_listeninterval_cmd(ar->wmi, 0, ar->listen_intvl_t,
+       ar->listen_intvl_b = listen_interval;
+       ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 0,
                                      ar->listen_intvl_b);
 
        return count;
 }
 
 static ssize_t ath6kl_listen_int_read(struct file *file,
-                                               char __user *user_buf,
-                                               size_t count, loff_t *ppos)
+                                     char __user *user_buf,
+                                     size_t count, loff_t *ppos)
 {
        struct ath6kl *ar = file->private_data;
        char buf[32];
        int len;
 
-       len = scnprintf(buf, sizeof(buf), "%u %u\n", ar->listen_intvl_t,
-                                       ar->listen_intvl_b);
+       len = scnprintf(buf, sizeof(buf), "%u\n", ar->listen_intvl_b);
 
        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
@@ -1710,6 +1731,9 @@ int ath6kl_debug_init(struct ath6kl *ar)
        debugfs_create_file("bgscan_interval", S_IWUSR,
                                ar->debugfs_phy, ar, &fops_bgscan_int);
 
+       debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR,
+                           ar->debugfs_phy, ar, &fops_listen_int);
+
        debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar,
                                                &fops_power_params);
 
index 9853c9c125c1417c9ab87de1afc6aea8b8fe3160..c4be6e50996b390a2e36dd242c9dc7de1e082239 100644 (file)
@@ -41,6 +41,7 @@ enum ATH6K_DEBUG_MASK {
        ATH6KL_DBG_BOOT         = BIT(18),    /* driver init and fw boot */
        ATH6KL_DBG_WMI_DUMP     = BIT(19),
        ATH6KL_DBG_SUSPEND      = BIT(20),
+       ATH6KL_DBG_USB          = BIT(21),
        ATH6KL_DBG_ANY          = 0xffffffff  /* enable all logs */
 };
 
@@ -55,35 +56,16 @@ int ath6kl_printk(const char *level, const char *fmt, ...);
 #define ath6kl_warn(fmt, ...)                                  \
        ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__)
 
-#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
-
 enum ath6kl_war {
        ATH6KL_WAR_INVALID_RATE,
 };
 
 #ifdef CONFIG_ATH6KL_DEBUG
-#define ath6kl_dbg(mask, fmt, ...)                                     \
-       ({                                                              \
-        int rtn;                                                       \
-        if (debug_mask & mask)                                         \
-               rtn = ath6kl_printk(KERN_DEBUG, fmt, ##__VA_ARGS__);    \
-        else                                                           \
-               rtn = 0;                                                \
-                                                                       \
-        rtn;                                                           \
-        })
 
-static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
-                                  const char *msg, const char *prefix,
-                                  const void *buf, size_t len)
-{
-       if (debug_mask & mask) {
-               if (msg)
-                       ath6kl_dbg(mask, "%s\n", msg);
-
-               print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
-       }
-}
+void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...);
+void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
+                    const char *msg, const char *prefix,
+                    const void *buf, size_t len);
 
 void ath6kl_dump_registers(struct ath6kl_device *dev,
                           struct ath6kl_irq_proc_registers *irq_proc_reg,
index e57da35e59fa78d66566841765a803f2f36e1637..e911737ab3457ba47c4a757be2aa6354ea05017a 100644 (file)
@@ -15,6 +15,8 @@
  */
 #include "hif.h"
 
+#include <linux/export.h>
+
 #include "core.h"
 #include "target.h"
 #include "hif-ops.h"
@@ -59,6 +61,8 @@ int ath6kl_hif_rw_comp_handler(void *context, int status)
 
        return 0;
 }
+EXPORT_SYMBOL(ath6kl_hif_rw_comp_handler);
+
 #define REG_DUMP_COUNT_AR6003   60
 #define REGISTER_DUMP_LEN_MAX   60
 
@@ -429,9 +433,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
                if (status)
                        goto out;
 
-               if (AR_DBG_LVL_CHECK(ATH6KL_DBG_IRQ))
-                       ath6kl_dump_registers(dev, &dev->irq_proc_reg,
-                                        &dev->irq_en_reg);
+               ath6kl_dump_registers(dev, &dev->irq_proc_reg,
+                                     &dev->irq_en_reg);
 
                /* Update only those registers that are enabled */
                host_int_status = dev->irq_proc_reg.host_int_status &
@@ -561,6 +564,7 @@ int ath6kl_hif_intr_bh_handler(struct ath6kl *ar)
 
        return status;
 }
+EXPORT_SYMBOL(ath6kl_hif_intr_bh_handler);
 
 static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev)
 {
@@ -689,6 +693,11 @@ int ath6kl_hif_setup(struct ath6kl_device *dev)
        ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n",
                   dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);
 
+       /* usb doesn't support enabling interrupts */
+       /* FIXME: remove check once USB support is implemented */
+       if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB)
+               return 0;
+
        status = ath6kl_hif_disable_intrs(dev);
 
 fail_setup:
index f3b63ca25c7e02b469feb800f8294fe1c3d195b5..2d721903640b51015e2202773cb4ba9a65041a08 100644 (file)
@@ -2062,6 +2062,7 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
        enum htc_endpoint_id id;
        int n_fetched = 0;
 
+       INIT_LIST_HEAD(&comp_pktq);
        *num_pkts = 0;
 
        /*
@@ -2543,6 +2544,12 @@ int ath6kl_htc_wait_target(struct htc_target *target)
        struct htc_service_connect_resp resp;
        int status;
 
+       /* FIXME: remove once USB support is implemented */
+       if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) {
+               ath6kl_err("HTC doesn't support USB yet. Patience!\n");
+               return -EOPNOTSUPP;
+       }
+
        /* we should be getting 1 control message that the target is ready */
        packet = htc_wait_for_ctrl_msg(target);
 
@@ -2772,7 +2779,9 @@ void ath6kl_htc_cleanup(struct htc_target *target)
 {
        struct htc_packet *packet, *tmp_packet;
 
-       ath6kl_hif_cleanup_scatter(target->dev->ar);
+       /* FIXME: remove check once USB support is implemented */
+       if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB)
+               ath6kl_hif_cleanup_scatter(target->dev->ar);
 
        list_for_each_entry_safe(packet, tmp_packet,
                        &target->free_ctrl_txbuf, list) {
index 7f55be3092d1c63698bc2f9d83d88d6ce2769868..0d76c3778106b161f4d3195d62763de10e0a36ee 100644 (file)
 
 #include <linux/moduleparam.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/of.h>
 #include <linux/mmc/sdio_func.h>
+
 #include "core.h"
 #include "cfg80211.h"
 #include "target.h"
 #include "debug.h"
 #include "hif-ops.h"
 
-unsigned int debug_mask;
-static unsigned int testmode;
-static bool suspend_cutpower;
-
-module_param(debug_mask, uint, 0644);
-module_param(testmode, uint, 0644);
-module_param(suspend_cutpower, bool, 0444);
-
 static const struct ath6kl_hw hw_list[] = {
        {
                .id                             = AR6003_HW_2_0_VERSION,
@@ -47,11 +41,14 @@ static const struct ath6kl_hw hw_list[] = {
                /* hw2.0 needs override address hardcoded */
                .app_start_override_addr        = 0x944C00,
 
-               .fw_otp                 = AR6003_HW_2_0_OTP_FILE,
-               .fw                     = AR6003_HW_2_0_FIRMWARE_FILE,
-               .fw_tcmd                = AR6003_HW_2_0_TCMD_FIRMWARE_FILE,
-               .fw_patch               = AR6003_HW_2_0_PATCH_FILE,
-               .fw_api2                = AR6003_HW_2_0_FIRMWARE_2_FILE,
+               .fw = {
+                       .dir            = AR6003_HW_2_0_FW_DIR,
+                       .otp            = AR6003_HW_2_0_OTP_FILE,
+                       .fw             = AR6003_HW_2_0_FIRMWARE_FILE,
+                       .tcmd           = AR6003_HW_2_0_TCMD_FIRMWARE_FILE,
+                       .patch          = AR6003_HW_2_0_PATCH_FILE,
+               },
+
                .fw_board               = AR6003_HW_2_0_BOARD_DATA_FILE,
                .fw_default_board       = AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE,
        },
@@ -64,12 +61,18 @@ static const struct ath6kl_hw hw_list[] = {
                .reserved_ram_size              = 512,
                .refclk_hz                      = 26000000,
                .uarttx_pin                     = 8,
+               .testscript_addr                = 0x57ef74,
+
+               .fw = {
+                       .dir            = AR6003_HW_2_1_1_FW_DIR,
+                       .otp            = AR6003_HW_2_1_1_OTP_FILE,
+                       .fw             = AR6003_HW_2_1_1_FIRMWARE_FILE,
+                       .tcmd           = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE,
+                       .patch          = AR6003_HW_2_1_1_PATCH_FILE,
+                       .utf            = AR6003_HW_2_1_1_UTF_FIRMWARE_FILE,
+                       .testscript     = AR6003_HW_2_1_1_TESTSCRIPT_FILE,
+               },
 
-               .fw_otp                 = AR6003_HW_2_1_1_OTP_FILE,
-               .fw                     = AR6003_HW_2_1_1_FIRMWARE_FILE,
-               .fw_tcmd                = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE,
-               .fw_patch               = AR6003_HW_2_1_1_PATCH_FILE,
-               .fw_api2                = AR6003_HW_2_1_1_FIRMWARE_2_FILE,
                .fw_board               = AR6003_HW_2_1_1_BOARD_DATA_FILE,
                .fw_default_board       = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE,
        },
@@ -84,8 +87,11 @@ static const struct ath6kl_hw hw_list[] = {
                .refclk_hz                      = 26000000,
                .uarttx_pin                     = 11,
 
-               .fw                     = AR6004_HW_1_0_FIRMWARE_FILE,
-               .fw_api2                = AR6004_HW_1_0_FIRMWARE_2_FILE,
+               .fw = {
+                       .dir            = AR6004_HW_1_0_FW_DIR,
+                       .fw             = AR6004_HW_1_0_FIRMWARE_FILE,
+               },
+
                .fw_board               = AR6004_HW_1_0_BOARD_DATA_FILE,
                .fw_default_board       = AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE,
        },
@@ -100,8 +106,11 @@ static const struct ath6kl_hw hw_list[] = {
                .refclk_hz                      = 40000000,
                .uarttx_pin                     = 11,
 
-               .fw                     = AR6004_HW_1_1_FIRMWARE_FILE,
-               .fw_api2                = AR6004_HW_1_1_FIRMWARE_2_FILE,
+               .fw = {
+                       .dir            = AR6004_HW_1_1_FW_DIR,
+                       .fw             = AR6004_HW_1_1_FIRMWARE_FILE,
+               },
+
                .fw_board               = AR6004_HW_1_1_BOARD_DATA_FILE,
                .fw_default_board       = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE,
        },
@@ -452,6 +461,13 @@ int ath6kl_configure_target(struct ath6kl *ar)
        u8 fw_iftype, fw_mode = 0, fw_submode = 0;
        int i, status;
 
+       param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG);
+       if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
+                            HI_ITEM(hi_serial_enable)), (u8 *)&param, 4)) {
+               ath6kl_err("bmi_write_memory for uart debug failed\n");
+               return -EIO;
+       }
+
        /*
         * Note: Even though the firmware interface type is
         * chosen as BSS_STA for all three interfaces, can
@@ -573,36 +589,6 @@ int ath6kl_configure_target(struct ath6kl *ar)
        return 0;
 }
 
-void ath6kl_core_free(struct ath6kl *ar)
-{
-       wiphy_free(ar->wiphy);
-}
-
-void ath6kl_core_cleanup(struct ath6kl *ar)
-{
-       ath6kl_hif_power_off(ar);
-
-       destroy_workqueue(ar->ath6kl_wq);
-
-       if (ar->htc_target)
-               ath6kl_htc_cleanup(ar->htc_target);
-
-       ath6kl_cookie_cleanup(ar);
-
-       ath6kl_cleanup_amsdu_rxbufs(ar);
-
-       ath6kl_bmi_cleanup(ar);
-
-       ath6kl_debug_cleanup(ar);
-
-       kfree(ar->fw_board);
-       kfree(ar->fw_otp);
-       kfree(ar->fw);
-       kfree(ar->fw_patch);
-
-       ath6kl_deinit_ieee80211_hw(ar);
-}
-
 /* firmware upload */
 static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
                         u8 **fw, size_t *fw_len)
@@ -626,21 +612,6 @@ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
 }
 
 #ifdef CONFIG_OF
-static const char *get_target_ver_dir(const struct ath6kl *ar)
-{
-       switch (ar->version.target_ver) {
-       case AR6003_HW_1_0_VERSION:
-               return "ath6k/AR6003/hw1.0";
-       case AR6003_HW_2_0_VERSION:
-               return "ath6k/AR6003/hw2.0";
-       case AR6003_HW_2_1_1_VERSION:
-               return "ath6k/AR6003/hw2.1.1";
-       }
-       ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__,
-                   ar->version.target_ver);
-       return NULL;
-}
-
 /*
  * Check the device tree for a board-id and use it to construct
  * the pathname to the firmware file.  Used (for now) to find a
@@ -663,7 +634,7 @@ static bool check_device_tree(struct ath6kl *ar)
                        continue;
                }
                snprintf(board_filename, sizeof(board_filename),
-                        "%s/bdata.%s.bin", get_target_ver_dir(ar), board_id);
+                        "%s/bdata.%s.bin", ar->hw.fw.dir, board_id);
 
                ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board,
                                    &ar->fw_board_len);
@@ -730,19 +701,20 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
 
 static int ath6kl_fetch_otp_file(struct ath6kl *ar)
 {
-       const char *filename;
+       char filename[100];
        int ret;
 
        if (ar->fw_otp != NULL)
                return 0;
 
-       if (ar->hw.fw_otp == NULL) {
+       if (ar->hw.fw.otp == NULL) {
                ath6kl_dbg(ATH6KL_DBG_BOOT,
                           "no OTP file configured for this hw\n");
                return 0;
        }
 
-       filename = ar->hw.fw_otp;
+       snprintf(filename, sizeof(filename), "%s/%s",
+                ar->hw.fw.dir, ar->hw.fw.otp);
 
        ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
                            &ar->fw_otp_len);
@@ -755,33 +727,61 @@ static int ath6kl_fetch_otp_file(struct ath6kl *ar)
        return 0;
 }
 
-static int ath6kl_fetch_fw_file(struct ath6kl *ar)
+static int ath6kl_fetch_testmode_file(struct ath6kl *ar)
 {
-       const char *filename;
+       char filename[100];
        int ret;
 
-       if (ar->fw != NULL)
+       if (ar->testmode == 0)
                return 0;
 
-       if (testmode) {
-               if (ar->hw.fw_tcmd == NULL) {
-                       ath6kl_warn("testmode not supported\n");
+       ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", ar->testmode);
+
+       if (ar->testmode == 2) {
+               if (ar->hw.fw.utf == NULL) {
+                       ath6kl_warn("testmode 2 not supported\n");
+                       return -EOPNOTSUPP;
+               }
+
+               snprintf(filename, sizeof(filename), "%s/%s",
+                        ar->hw.fw.dir, ar->hw.fw.utf);
+       } else {
+               if (ar->hw.fw.tcmd == NULL) {
+                       ath6kl_warn("testmode 1 not supported\n");
                        return -EOPNOTSUPP;
                }
 
-               filename = ar->hw.fw_tcmd;
+               snprintf(filename, sizeof(filename), "%s/%s",
+                        ar->hw.fw.dir, ar->hw.fw.tcmd);
+       }
 
-               set_bit(TESTMODE, &ar->flag);
+       set_bit(TESTMODE, &ar->flag);
 
-               goto get_fw;
+       ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
+       if (ret) {
+               ath6kl_err("Failed to get testmode %d firmware file %s: %d\n",
+                          ar->testmode, filename, ret);
+               return ret;
        }
 
-       if (WARN_ON(ar->hw.fw == NULL))
+       return 0;
+}
+
+static int ath6kl_fetch_fw_file(struct ath6kl *ar)
+{
+       char filename[100];
+       int ret;
+
+       if (ar->fw != NULL)
+               return 0;
+
+       /* FIXME: remove WARN_ON() as we won't support FW API 1 for long */
+       if (WARN_ON(ar->hw.fw.fw == NULL))
                return -EINVAL;
 
-       filename = ar->hw.fw;
+       snprintf(filename, sizeof(filename), "%s/%s",
+                ar->hw.fw.dir, ar->hw.fw.fw);
 
-get_fw:
        ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
        if (ret) {
                ath6kl_err("Failed to get firmware file %s: %d\n",
@@ -794,16 +794,17 @@ get_fw:
 
 static int ath6kl_fetch_patch_file(struct ath6kl *ar)
 {
-       const char *filename;
+       char filename[100];
        int ret;
 
        if (ar->fw_patch != NULL)
                return 0;
 
-       if (ar->hw.fw_patch == NULL)
+       if (ar->hw.fw.patch == NULL)
                return 0;
 
-       filename = ar->hw.fw_patch;
+       snprintf(filename, sizeof(filename), "%s/%s",
+                ar->hw.fw.dir, ar->hw.fw.patch);
 
        ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
                            &ar->fw_patch_len);
@@ -816,6 +817,34 @@ static int ath6kl_fetch_patch_file(struct ath6kl *ar)
        return 0;
 }
 
+static int ath6kl_fetch_testscript_file(struct ath6kl *ar)
+{
+       char filename[100];
+       int ret;
+
+       if (ar->testmode != 2)
+               return 0;
+
+       if (ar->fw_testscript != NULL)
+               return 0;
+
+       if (ar->hw.fw.testscript == NULL)
+               return 0;
+
+       snprintf(filename, sizeof(filename), "%s/%s",
+               ar->hw.fw.dir, ar->hw.fw.testscript);
+
+       ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript,
+                               &ar->fw_testscript_len);
+       if (ret) {
+               ath6kl_err("Failed to get testscript file %s: %d\n",
+                       filename, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
 static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
 {
        int ret;
@@ -832,23 +861,24 @@ static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
        if (ret)
                return ret;
 
+       ret = ath6kl_fetch_testscript_file(ar);
+       if (ret)
+               return ret;
+
        return 0;
 }
 
-static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
+static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
 {
        size_t magic_len, len, ie_len;
        const struct firmware *fw;
        struct ath6kl_fw_ie *hdr;
-       const char *filename;
+       char filename[100];
        const u8 *data;
        int ret, ie_id, i, index, bit;
        __le32 *val;
 
-       if (ar->hw.fw_api2 == NULL)
-               return -EOPNOTSUPP;
-
-       filename = ar->hw.fw_api2;
+       snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name);
 
        ret = request_firmware(&fw, filename, ar->dev);
        if (ret)
@@ -907,6 +937,10 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
                        ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n",
                                ie_len);
 
+                       /* in testmode we already might have a fw file */
+                       if (ar->fw != NULL)
+                               break;
+
                        ar->fw = kmemdup(data, ie_len, GFP_KERNEL);
 
                        if (ar->fw == NULL) {
@@ -1010,7 +1044,7 @@ out:
        return ret;
 }
 
-static int ath6kl_fetch_firmwares(struct ath6kl *ar)
+int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
 {
        int ret;
 
@@ -1018,17 +1052,30 @@ static int ath6kl_fetch_firmwares(struct ath6kl *ar)
        if (ret)
                return ret;
 
-       ret = ath6kl_fetch_fw_api2(ar);
+       ret = ath6kl_fetch_testmode_file(ar);
+       if (ret)
+               return ret;
+
+       ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE);
        if (ret == 0) {
-               ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 2\n");
-               return 0;
+               ar->fw_api = 3;
+               goto out;
+       }
+
+       ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API2_FILE);
+       if (ret == 0) {
+               ar->fw_api = 2;
+               goto out;
        }
 
        ret = ath6kl_fetch_fw_api1(ar);
        if (ret)
                return ret;
 
-       ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 1\n");
+       ar->fw_api = 1;
+
+out:
+       ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api %d\n", ar->fw_api);
 
        return 0;
 }
@@ -1249,6 +1296,50 @@ static int ath6kl_upload_patch(struct ath6kl *ar)
        return 0;
 }
 
+static int ath6kl_upload_testscript(struct ath6kl *ar)
+{
+       u32 address, param;
+       int ret;
+
+       if (ar->testmode != 2)
+               return 0;
+
+       if (ar->fw_testscript == NULL)
+               return 0;
+
+       address = ar->hw.testscript_addr;
+
+       ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n",
+               address, ar->fw_testscript_len);
+
+       ret = ath6kl_bmi_write(ar, address, ar->fw_testscript,
+               ar->fw_testscript_len);
+       if (ret) {
+               ath6kl_err("Failed to write testscript file: %d\n", ret);
+               return ret;
+       }
+
+       param = address;
+       ath6kl_bmi_write(ar,
+                       ath6kl_get_hi_item_addr(ar,
+                       HI_ITEM(hi_ota_testscript)),
+                       (unsigned char *) &param, 4);
+
+       param = 4096;
+       ath6kl_bmi_write(ar,
+                       ath6kl_get_hi_item_addr(ar,
+                       HI_ITEM(hi_end_ram_reserve_sz)),
+                       (unsigned char *) &param, 4);
+
+       param = 1;
+       ath6kl_bmi_write(ar,
+                       ath6kl_get_hi_item_addr(ar,
+                       HI_ITEM(hi_test_apps_related)),
+                       (unsigned char *) &param, 4);
+
+       return 0;
+}
+
 static int ath6kl_init_upload(struct ath6kl *ar)
 {
        u32 param, options, sleep, address;
@@ -1357,6 +1448,11 @@ static int ath6kl_init_upload(struct ath6kl *ar)
        if (status)
                return status;
 
+       /* Download the test script */
+       status = ath6kl_upload_testscript(ar);
+       if (status)
+               return status;
+
        /* Restore system sleep */
        address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
        status = ath6kl_bmi_reg_write(ar, address, sleep);
@@ -1372,9 +1468,9 @@ static int ath6kl_init_upload(struct ath6kl *ar)
        return status;
 }
 
-static int ath6kl_init_hw_params(struct ath6kl *ar)
+int ath6kl_init_hw_params(struct ath6kl *ar)
 {
-       const struct ath6kl_hw *hw;
+       const struct ath6kl_hw *uninitialized_var(hw);
        int i;
 
        for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
@@ -1481,10 +1577,11 @@ int ath6kl_init_hw_start(struct ath6kl *ar)
 
 
        if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) {
-               ath6kl_info("%s %s fw %s%s\n",
+               ath6kl_info("%s %s fw %s api %d%s\n",
                            ar->hw.name,
                            ath6kl_init_get_hif_name(ar->hif_type),
                            ar->wiphy->fw_version,
+                           ar->fw_api,
                            test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
        }
 
@@ -1549,173 +1646,7 @@ int ath6kl_init_hw_stop(struct ath6kl *ar)
        return 0;
 }
 
-int ath6kl_core_init(struct ath6kl *ar)
-{
-       struct ath6kl_bmi_target_info targ_info;
-       struct net_device *ndev;
-       int ret = 0, i;
-
-       ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
-       if (!ar->ath6kl_wq)
-               return -ENOMEM;
-
-       ret = ath6kl_bmi_init(ar);
-       if (ret)
-               goto err_wq;
-
-       /*
-        * Turn on power to get hardware (target) version and leave power
-        * on delibrately as we will boot the hardware anyway within few
-        * seconds.
-        */
-       ret = ath6kl_hif_power_on(ar);
-       if (ret)
-               goto err_bmi_cleanup;
-
-       ret = ath6kl_bmi_get_target_info(ar, &targ_info);
-       if (ret)
-               goto err_power_off;
-
-       ar->version.target_ver = le32_to_cpu(targ_info.version);
-       ar->target_type = le32_to_cpu(targ_info.type);
-       ar->wiphy->hw_version = le32_to_cpu(targ_info.version);
-
-       ret = ath6kl_init_hw_params(ar);
-       if (ret)
-               goto err_power_off;
-
-       ar->htc_target = ath6kl_htc_create(ar);
-
-       if (!ar->htc_target) {
-               ret = -ENOMEM;
-               goto err_power_off;
-       }
-
-       ret = ath6kl_fetch_firmwares(ar);
-       if (ret)
-               goto err_htc_cleanup;
-
-       /* FIXME: we should free all firmwares in the error cases below */
-
-       /* Indicate that WMI is enabled (although not ready yet) */
-       set_bit(WMI_ENABLED, &ar->flag);
-       ar->wmi = ath6kl_wmi_init(ar);
-       if (!ar->wmi) {
-               ath6kl_err("failed to initialize wmi\n");
-               ret = -EIO;
-               goto err_htc_cleanup;
-       }
-
-       ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
-
-       ret = ath6kl_register_ieee80211_hw(ar);
-       if (ret)
-               goto err_node_cleanup;
-
-       ret = ath6kl_debug_init(ar);
-       if (ret) {
-               wiphy_unregister(ar->wiphy);
-               goto err_node_cleanup;
-       }
-
-       for (i = 0; i < ar->vif_max; i++)
-               ar->avail_idx_map |= BIT(i);
-
-       rtnl_lock();
-
-       /* Add an initial station interface */
-       ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0,
-                                   INFRA_NETWORK);
-
-       rtnl_unlock();
-
-       if (!ndev) {
-               ath6kl_err("Failed to instantiate a network device\n");
-               ret = -ENOMEM;
-               wiphy_unregister(ar->wiphy);
-               goto err_debug_init;
-       }
-
-
-       ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
-                       __func__, ndev->name, ndev, ar);
-
-       /* setup access class priority mappings */
-       ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest  */
-       ar->ac_stream_pri_map[WMM_AC_BE] = 1;
-       ar->ac_stream_pri_map[WMM_AC_VI] = 2;
-       ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
-
-       /* give our connected endpoints some buffers */
-       ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
-       ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
-
-       /* allocate some buffers that handle larger AMSDU frames */
-       ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
-
-       ath6kl_cookie_init(ar);
-
-       ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
-                        ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
-
-       if (suspend_cutpower)
-               ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER;
-
-       ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
-                           WIPHY_FLAG_HAVE_AP_SME |
-                           WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
-                           WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
-
-       if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
-               ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
-
-       ar->wiphy->probe_resp_offload =
-               NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
-               NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
-               NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
-               NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
-
-       set_bit(FIRST_BOOT, &ar->flag);
-
-       ret = ath6kl_init_hw_start(ar);
-       if (ret) {
-               ath6kl_err("Failed to start hardware: %d\n", ret);
-               goto err_rxbuf_cleanup;
-       }
-
-       /*
-        * Set mac address which is received in ready event
-        * FIXME: Move to ath6kl_interface_add()
-        */
-       memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
-
-       return ret;
-
-err_rxbuf_cleanup:
-       ath6kl_htc_flush_rx_buf(ar->htc_target);
-       ath6kl_cleanup_amsdu_rxbufs(ar);
-       rtnl_lock();
-       ath6kl_deinit_if_data(netdev_priv(ndev));
-       rtnl_unlock();
-       wiphy_unregister(ar->wiphy);
-err_debug_init:
-       ath6kl_debug_cleanup(ar);
-err_node_cleanup:
-       ath6kl_wmi_shutdown(ar->wmi);
-       clear_bit(WMI_ENABLED, &ar->flag);
-       ar->wmi = NULL;
-err_htc_cleanup:
-       ath6kl_htc_cleanup(ar->htc_target);
-err_power_off:
-       ath6kl_hif_power_off(ar);
-err_bmi_cleanup:
-       ath6kl_bmi_cleanup(ar);
-err_wq:
-       destroy_workqueue(ar->ath6kl_wq);
-
-       return ret;
-}
-
+/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */
 void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
 {
        static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -1747,6 +1678,7 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
 void ath6kl_stop_txrx(struct ath6kl *ar)
 {
        struct ath6kl_vif *vif, *tmp_vif;
+       int i;
 
        set_bit(DESTROY_IN_PROGRESS, &ar->flag);
 
@@ -1755,13 +1687,16 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
                return;
        }
 
+       for (i = 0; i < AP_MAX_NUM_STA; i++)
+               aggr_reset_state(ar->sta_list[i].aggr_conn);
+
        spin_lock_bh(&ar->list_lock);
        list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
                list_del(&vif->list);
                spin_unlock_bh(&ar->list_lock);
                ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
                rtnl_lock();
-               ath6kl_deinit_if_data(vif);
+               ath6kl_cfg80211_vif_cleanup(vif);
                rtnl_unlock();
                spin_lock_bh(&ar->list_lock);
        }
@@ -1796,3 +1731,4 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
 
        clear_bit(WLAN_ENABLED, &ar->flag);
 }
+EXPORT_SYMBOL(ath6kl_stop_txrx);
index eea3c747653ed327ddb03a14ac12cbdf4c0b34f1..b96d01a7919b9294f212ef2f4301aaf3052d650f 100644 (file)
@@ -52,9 +52,11 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid)
        return conn;
 }
 
-static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
-                       u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
+static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid,
+                              u8 *wpaie, size_t ielen, u8 keymgmt,
+                              u8 ucipher, u8 auth, u8 apsd_info)
 {
+       struct ath6kl *ar = vif->ar;
        struct ath6kl_sta *sta;
        u8 free_slot;
 
@@ -68,9 +70,11 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
        sta->keymgmt = keymgmt;
        sta->ucipher = ucipher;
        sta->auth = auth;
+       sta->apsd_info = apsd_info;
 
        ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
        ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid);
+       aggr_conn_init(vif, vif->aggr_cntxt, sta->aggr_conn);
 }
 
 static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
@@ -80,6 +84,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
        /* empty the queued pkts in the PS queue if any */
        spin_lock_bh(&sta->psq_lock);
        skb_queue_purge(&sta->psq);
+       skb_queue_purge(&sta->apsdq);
        spin_unlock_bh(&sta->psq_lock);
 
        memset(&ar->ap_stats.sta[sta->aid - 1], 0,
@@ -90,7 +95,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
        sta->sta_flags = 0;
 
        ar->sta_list_index = ar->sta_list_index & ~(1 << i);
-
+       aggr_reset_state(sta->aggr_conn);
 }
 
 static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason)
@@ -252,7 +257,7 @@ int ath6kl_read_fwlogs(struct ath6kl *ar)
        struct ath6kl_dbglog_hdr debug_hdr;
        struct ath6kl_dbglog_buf debug_buf;
        u32 address, length, dropped, firstbuf, debug_hdr_addr;
-       int ret = 0, loop;
+       int ret, loop;
        u8 *buf;
 
        buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL);
@@ -347,9 +352,6 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
        case TARGET_TYPE_AR6004:
                address = AR6004_RESET_CONTROL_ADDRESS;
                break;
-       default:
-               address = AR6003_RESET_CONTROL_ADDRESS;
-               break;
        }
 
        status = ath6kl_diag_write32(ar, address, data);
@@ -363,7 +365,7 @@ static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
        u8 index;
        u8 keyusage;
 
-       for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
+       for (index = 0; index <= WMI_MAX_KEY_INDEX; index++) {
                if (vif->wep_key_list[index].key_len) {
                        keyusage = GROUP_USAGE;
                        if (index == vif->def_txkey_index)
@@ -428,9 +430,8 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
 
 void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
                                u8 keymgmt, u8 ucipher, u8 auth,
-                               u8 assoc_req_len, u8 *assoc_info)
+                               u8 assoc_req_len, u8 *assoc_info, u8 apsd_info)
 {
-       struct ath6kl *ar = vif->ar;
        u8 *ies = NULL, *wpa_ie = NULL, *pos;
        size_t ies_len = 0;
        struct station_info sinfo;
@@ -484,9 +485,9 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
                pos += 2 + pos[1];
        }
 
-       ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie,
+       ath6kl_add_new_sta(vif, mac_addr, aid, wpa_ie,
                           wpa_ie ? 2 + wpa_ie[1] : 0,
-                          keymgmt, ucipher, auth);
+                          keymgmt, ucipher, auth, apsd_info);
 
        /* send event to application */
        memset(&sinfo, 0, sizeof(sinfo));
@@ -587,10 +588,11 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
        memcpy(vif->bssid, bssid, sizeof(vif->bssid));
        vif->bss_ch = channel;
 
-       if ((vif->nw_type == INFRA_NETWORK))
+       if ((vif->nw_type == INFRA_NETWORK)) {
+               ar->listen_intvl_b = listen_int;
                ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
-                                             ar->listen_intvl_t,
-                                             ar->listen_intvl_b);
+                                             0, ar->listen_intvl_b);
+       }
 
        netif_wake_queue(vif->ndev);
 
@@ -601,7 +603,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
        netif_carrier_on(vif->ndev);
        spin_unlock_bh(&vif->if_lock);
 
-       aggr_reset_state(vif->aggr_cntxt);
+       aggr_reset_state(vif->aggr_cntxt->aggr_conn);
        vif->reconnect_flag = 0;
 
        if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
@@ -923,7 +925,7 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
                                       assoc_resp_len, assoc_info,
                                       prot_reason_status);
 
-       aggr_reset_state(vif->aggr_cntxt);
+       aggr_reset_state(vif->aggr_cntxt->aggr_conn);
 
        del_timer(&vif->disconnect_timer);
 
@@ -1020,11 +1022,155 @@ static struct net_device_stats *ath6kl_get_stats(struct net_device *dev)
        return &vif->net_stats;
 }
 
-static struct net_device_ops ath6kl_netdev_ops = {
+static int ath6kl_set_features(struct net_device *dev,
+                              netdev_features_t features)
+{
+       struct ath6kl_vif *vif = netdev_priv(dev);
+       struct ath6kl *ar = vif->ar;
+       int err = 0;
+
+       if ((features & NETIF_F_RXCSUM) &&
+           (ar->rx_meta_ver != WMI_META_VERSION_2)) {
+               ar->rx_meta_ver = WMI_META_VERSION_2;
+               err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
+                                                        vif->fw_vif_idx,
+                                                        ar->rx_meta_ver, 0, 0);
+               if (err) {
+                       dev->features = features & ~NETIF_F_RXCSUM;
+                       return err;
+               }
+       } else if (!(features & NETIF_F_RXCSUM) &&
+                  (ar->rx_meta_ver == WMI_META_VERSION_2)) {
+               ar->rx_meta_ver = 0;
+               err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
+                                                        vif->fw_vif_idx,
+                                                        ar->rx_meta_ver, 0, 0);
+               if (err) {
+                       dev->features = features | NETIF_F_RXCSUM;
+                       return err;
+               }
+
+       }
+
+       return err;
+}
+
+static void ath6kl_set_multicast_list(struct net_device *ndev)
+{
+       struct ath6kl_vif *vif = netdev_priv(ndev);
+       bool mc_all_on = false, mc_all_off = false;
+       int mc_count = netdev_mc_count(ndev);
+       struct netdev_hw_addr *ha;
+       bool found;
+       struct ath6kl_mc_filter *mc_filter, *tmp;
+       struct list_head mc_filter_new;
+       int ret;
+
+       if (!test_bit(WMI_READY, &vif->ar->flag) ||
+           !test_bit(WLAN_ENABLED, &vif->flags))
+               return;
+
+       mc_all_on = !!(ndev->flags & IFF_PROMISC) ||
+                   !!(ndev->flags & IFF_ALLMULTI) ||
+                   !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST);
+
+       mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0;
+
+       if (mc_all_on || mc_all_off) {
+               /* Enable/disable all multicast */
+               ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n",
+                         mc_all_on ? "enabling" : "disabling");
+               ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
+                                                 mc_all_on);
+               if (ret)
+                       ath6kl_warn("Failed to %s multicast receive\n",
+                                   mc_all_on ? "enable" : "disable");
+               return;
+       }
+
+       list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
+               found = false;
+               netdev_for_each_mc_addr(ha, ndev) {
+                       if (memcmp(ha->addr, mc_filter->hw_addr,
+                           ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
+                               found = true;
+                               break;
+                       }
+               }
+
+               if (!found) {
+                       /*
+                        * Delete the filter which was previously set
+                        * but not in the new request.
+                        */
+                       ath6kl_dbg(ATH6KL_DBG_TRC,
+                                  "Removing %pM from multicast filter\n",
+                                  mc_filter->hw_addr);
+                       ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,
+                                       vif->fw_vif_idx, mc_filter->hw_addr,
+                                       false);
+                       if (ret) {
+                               ath6kl_warn("Failed to remove multicast filter:%pM\n",
+                                            mc_filter->hw_addr);
+                               return;
+                       }
+
+                       list_del(&mc_filter->list);
+                       kfree(mc_filter);
+               }
+       }
+
+       INIT_LIST_HEAD(&mc_filter_new);
+
+       netdev_for_each_mc_addr(ha, ndev) {
+               found = false;
+               list_for_each_entry(mc_filter, &vif->mc_filter, list) {
+                       if (memcmp(ha->addr, mc_filter->hw_addr,
+                           ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
+                               found = true;
+                               break;
+                       }
+               }
+
+               if (!found) {
+                       mc_filter = kzalloc(sizeof(struct ath6kl_mc_filter),
+                                           GFP_ATOMIC);
+                       if (!mc_filter) {
+                               WARN_ON(1);
+                               goto out;
+                       }
+
+                       memcpy(mc_filter->hw_addr, ha->addr,
+                              ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);
+                       /* Set the multicast filter */
+                       ath6kl_dbg(ATH6KL_DBG_TRC,
+                                  "Adding %pM to multicast filter list\n",
+                                  mc_filter->hw_addr);
+                       ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,
+                                       vif->fw_vif_idx, mc_filter->hw_addr,
+                                       true);
+                       if (ret) {
+                               ath6kl_warn("Failed to add multicast filter :%pM\n",
+                                            mc_filter->hw_addr);
+                               kfree(mc_filter);
+                               goto out;
+                       }
+
+                       list_add_tail(&mc_filter->list, &mc_filter_new);
+               }
+       }
+
+out:
+       list_splice_tail(&mc_filter_new, &vif->mc_filter);
+}
+
+static const struct net_device_ops ath6kl_netdev_ops = {
        .ndo_open               = ath6kl_open,
        .ndo_stop               = ath6kl_close,
        .ndo_start_xmit         = ath6kl_data_tx,
        .ndo_get_stats          = ath6kl_get_stats,
+       .ndo_set_features       = ath6kl_set_features,
+       .ndo_set_rx_mode        = ath6kl_set_multicast_list,
 };
 
 void init_netdev(struct net_device *dev)
index 9475e2d0d0b7943bee6dd60288821c95a8dc9588..4febee723495c672f6a4f86e10117b1c81097381 100644 (file)
@@ -49,11 +49,13 @@ struct ath6kl_sdio {
        /* scatter request list head */
        struct list_head scat_req;
 
+       /* Avoids disabling irq while the interrupts being handled */
+       struct mutex mtx_irq;
+
        spinlock_t scat_lock;
        bool scatter_enabled;
 
        bool is_disabled;
-       atomic_t irq_handling;
        const struct sdio_device_id *id;
        struct work_struct wr_async_work;
        struct list_head wr_asyncq;
@@ -460,8 +462,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
        ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n");
 
        ar_sdio = sdio_get_drvdata(func);
-       atomic_set(&ar_sdio->irq_handling, 1);
-
+       mutex_lock(&ar_sdio->mtx_irq);
        /*
         * Release the host during interrups so we can pick it back up when
         * we process commands.
@@ -470,7 +471,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
 
        status = ath6kl_hif_intr_bh_handler(ar_sdio->ar);
        sdio_claim_host(ar_sdio->func);
-       atomic_set(&ar_sdio->irq_handling, 0);
+       mutex_unlock(&ar_sdio->mtx_irq);
        WARN_ON(status && status != -ECANCELED);
 }
 
@@ -578,17 +579,14 @@ static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
 
        sdio_claim_host(ar_sdio->func);
 
-       /* Mask our function IRQ */
-       while (atomic_read(&ar_sdio->irq_handling)) {
-               sdio_release_host(ar_sdio->func);
-               schedule_timeout(HZ / 10);
-               sdio_claim_host(ar_sdio->func);
-       }
+       mutex_lock(&ar_sdio->mtx_irq);
 
        ret = sdio_release_irq(ar_sdio->func);
        if (ret)
                ath6kl_err("Failed to release sdio irq: %d\n", ret);
 
+       mutex_unlock(&ar_sdio->mtx_irq);
+
        sdio_release_host(ar_sdio->func);
 }
 
@@ -772,7 +770,6 @@ static int ath6kl_sdio_config(struct ath6kl *ar)
        if (ret) {
                ath6kl_err("Set sdio block size %d failed: %d)\n",
                           HIF_MBOX_BLOCK_SIZE, ret);
-               sdio_release_host(func);
                goto out;
        }
 
@@ -782,7 +779,7 @@ out:
        return ret;
 }
 
-static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+static int ath6kl_set_sdio_pm_caps(struct ath6kl *ar)
 {
        struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
        struct sdio_func *func = ar_sdio->func;
@@ -793,60 +790,95 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 
        ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio suspend pm_caps 0x%x\n", flags);
 
-       if (!(flags & MMC_PM_KEEP_POWER) ||
-           (ar->conf_flags & ATH6KL_CONF_SUSPEND_CUTPOWER)) {
-               /* as host doesn't support keep power we need to cut power */
-               return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER,
-                                              NULL);
-       }
+       if (!(flags & MMC_PM_WAKE_SDIO_IRQ) ||
+           !(flags & MMC_PM_KEEP_POWER))
+               return -EINVAL;
 
        ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
        if (ret) {
-               printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n",
-                      ret);
+               ath6kl_err("set sdio keep pwr flag failed: %d\n", ret);
                return ret;
        }
 
-       if (!(flags & MMC_PM_WAKE_SDIO_IRQ))
-               goto deepsleep;
-
        /* sdio irq wakes up host */
+       ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+       if (ret)
+               ath6kl_err("set sdio wake irq flag failed: %d\n", ret);
+
+       return ret;
+}
+
+static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+{
+       struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+       struct sdio_func *func = ar_sdio->func;
+       mmc_pm_flag_t flags;
+       int ret;
 
        if (ar->state == ATH6KL_STATE_SCHED_SCAN) {
+               ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n");
+
+               ret = ath6kl_set_sdio_pm_caps(ar);
+               if (ret)
+                       goto cut_pwr;
+
                ret =  ath6kl_cfg80211_suspend(ar,
                                               ATH6KL_CFG_SUSPEND_SCHED_SCAN,
                                               NULL);
-               if (ret) {
-                       ath6kl_warn("Schedule scan suspend failed: %d", ret);
-                       return ret;
-               }
+               if (ret)
+                       goto cut_pwr;
+
+               return 0;
+       }
+
+       if (ar->suspend_mode == WLAN_POWER_STATE_WOW ||
+           (!ar->suspend_mode && wow)) {
 
-               ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+               ret = ath6kl_set_sdio_pm_caps(ar);
                if (ret)
-                       ath6kl_warn("set sdio wake irq flag failed: %d\n", ret);
+                       goto cut_pwr;
 
-               return ret;
+               ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow);
+               if (ret)
+                       goto cut_pwr;
+
+               return 0;
        }
 
-       if (wow) {
+       if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP ||
+           !ar->suspend_mode) {
+
+               flags = sdio_get_host_pm_caps(func);
+               if (!(flags & MMC_PM_KEEP_POWER))
+                       goto cut_pwr;
+
+               ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+               if (ret)
+                       goto cut_pwr;
+
                /*
-                * The host sdio controller is capable of keep power and
-                * sdio irq wake up at this point. It's fine to continue
-                * wow suspend operation.
+                * Workaround to support Deep Sleep with MSM, set the host pm
+                * flag as MMC_PM_WAKE_SDIO_IRQ to allow SDCC deiver to disable
+                * the sdc2_clock and internally allows MSM to enter
+                * TCXO shutdown properly.
                 */
-               ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow);
-               if (ret)
-                       return ret;
+               if ((flags & MMC_PM_WAKE_SDIO_IRQ)) {
+                       ret = sdio_set_host_pm_flags(func,
+                                               MMC_PM_WAKE_SDIO_IRQ);
+                       if (ret)
+                               goto cut_pwr;
+               }
 
-               ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+               ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP,
+                                             NULL);
                if (ret)
-                       ath6kl_err("set sdio wake irq flag failed: %d\n", ret);
+                       goto cut_pwr;
 
-               return ret;
+               return 0;
        }
 
-deepsleep:
-       return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL);
+cut_pwr:
+       return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL);
 }
 
 static int ath6kl_sdio_resume(struct ath6kl *ar)
@@ -1253,6 +1285,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
        spin_lock_init(&ar_sdio->scat_lock);
        spin_lock_init(&ar_sdio->wr_async_lock);
        mutex_init(&ar_sdio->dma_buffer_mutex);
+       mutex_init(&ar_sdio->mtx_irq);
 
        INIT_LIST_HEAD(&ar_sdio->scat_req);
        INIT_LIST_HEAD(&ar_sdio->bus_req_freeq);
@@ -1263,7 +1296,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
        for (count = 0; count < BUS_REQUEST_MAX_NUM; count++)
                ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]);
 
-       ar = ath6kl_core_alloc(&ar_sdio->func->dev);
+       ar = ath6kl_core_create(&ar_sdio->func->dev);
        if (!ar) {
                ath6kl_err("Failed to alloc ath6kl core\n");
                ret = -ENOMEM;
@@ -1293,7 +1326,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
        return ret;
 
 err_core_alloc:
-       ath6kl_core_free(ar_sdio->ar);
+       ath6kl_core_destroy(ar_sdio->ar);
 err_dma:
        kfree(ar_sdio->dma_buffer);
 err_hif:
@@ -1316,6 +1349,7 @@ static void ath6kl_sdio_remove(struct sdio_func *func)
        cancel_work_sync(&ar_sdio->wr_async_work);
 
        ath6kl_core_cleanup(ar_sdio->ar);
+       ath6kl_core_destroy(ar_sdio->ar);
 
        kfree(ar_sdio->dma_buffer);
        kfree(ar_sdio);
@@ -1332,7 +1366,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = {
 MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices);
 
 static struct sdio_driver ath6kl_sdio_driver = {
-       .name = "ath6kl",
+       .name = "ath6kl_sdio",
        .id_table = ath6kl_sdio_devices,
        .probe = ath6kl_sdio_probe,
        .remove = ath6kl_sdio_remove,
@@ -1362,19 +1396,19 @@ MODULE_AUTHOR("Atheros Communications, Inc.");
 MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices");
 MODULE_LICENSE("Dual BSD/GPL");
 
-MODULE_FIRMWARE(AR6003_HW_2_0_OTP_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_0_FIRMWARE_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_0_PATCH_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_OTP_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_PATCH_FILE);
 MODULE_FIRMWARE(AR6003_HW_2_0_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_OTP_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_FIRMWARE_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_PATCH_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_OTP_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_PATCH_FILE);
 MODULE_FIRMWARE(AR6003_HW_2_1_1_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_0_FW_DIR "/" AR6004_HW_1_0_FIRMWARE_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
index 381eb66a605f0e726434dfb7722d152771578742..f0cd61d6188af39cd24741cd70479acf1d8d0542 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "testmode.h"
+#include "debug.h"
 
 #include <net/netlink.h>
 
@@ -30,7 +31,7 @@ enum ath6kl_tm_attr {
 
 enum ath6kl_tm_cmd {
        ATH6KL_TM_CMD_TCMD              = 0,
-       ATH6KL_TM_CMD_RX_REPORT         = 1,
+       ATH6KL_TM_CMD_RX_REPORT         = 1,    /* not used anymore */
 };
 
 #define ATH6KL_TM_DATA_MAX_LEN         5000
@@ -41,84 +42,33 @@ static const struct nla_policy ath6kl_tm_policy[ATH6KL_TM_ATTR_MAX + 1] = {
                                            .len = ATH6KL_TM_DATA_MAX_LEN },
 };
 
-void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len)
+void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len)
 {
-       if (down_interruptible(&ar->sem))
-               return;
-
-       kfree(ar->tm.rx_report);
-
-       ar->tm.rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
-       ar->tm.rx_report_len = buf_len;
-
-       up(&ar->sem);
-
-       wake_up(&ar->event_wq);
-}
-
-static int ath6kl_tm_rx_report(struct ath6kl *ar, void *buf, size_t buf_len,
-                              struct sk_buff *skb)
-{
-       int ret = 0;
-       long left;
-
-       if (down_interruptible(&ar->sem))
-               return -ERESTARTSYS;
-
-       if (!test_bit(WMI_READY, &ar->flag)) {
-               ret = -EIO;
-               goto out;
-       }
-
-       if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
-               ret = -EBUSY;
-               goto out;
-       }
-
-       if (ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len) < 0) {
-               up(&ar->sem);
-               return -EIO;
-       }
-
-       left = wait_event_interruptible_timeout(ar->event_wq,
-                                               ar->tm.rx_report != NULL,
-                                               WMI_TIMEOUT);
+       struct sk_buff *skb;
 
-       if (left == 0) {
-               ret = -ETIMEDOUT;
-               goto out;
-       } else if (left < 0) {
-               ret = left;
-               goto out;
-       }
+       if (!buf || buf_len == 0)
+               return;
 
-       if (ar->tm.rx_report == NULL || ar->tm.rx_report_len == 0) {
-               ret = -EINVAL;
-               goto out;
+       skb = cfg80211_testmode_alloc_event_skb(ar->wiphy, buf_len, GFP_KERNEL);
+       if (!skb) {
+               ath6kl_warn("failed to allocate testmode rx skb!\n");
+               return;
        }
-
-       NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, ar->tm.rx_report_len,
-               ar->tm.rx_report);
-
-       kfree(ar->tm.rx_report);
-       ar->tm.rx_report = NULL;
-
-out:
-       up(&ar->sem);
-
-       return ret;
+       NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD);
+       NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf);
+       cfg80211_testmode_event(skb, GFP_KERNEL);
+       return;
 
 nla_put_failure:
-       ret = -ENOBUFS;
-       goto out;
+       kfree_skb(skb);
+       ath6kl_warn("nla_put failed on testmode rx skb!\n");
 }
 
 int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
 {
        struct ath6kl *ar = wiphy_priv(wiphy);
        struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1];
-       int err, buf_len, reply_len;
-       struct sk_buff *skb;
+       int err, buf_len;
        void *buf;
 
        err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len,
@@ -143,24 +93,6 @@ int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
 
                break;
        case ATH6KL_TM_CMD_RX_REPORT:
-               if (!tb[ATH6KL_TM_ATTR_DATA])
-                       return -EINVAL;
-
-               buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]);
-               buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]);
-
-               reply_len = nla_total_size(ATH6KL_TM_DATA_MAX_LEN);
-               skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
-               if (!skb)
-                       return -ENOMEM;
-
-               err = ath6kl_tm_rx_report(ar, buf, buf_len, skb);
-               if (err < 0) {
-                       kfree_skb(skb);
-                       return err;
-               }
-
-               return cfg80211_testmode_reply(skb);
        default:
                return -EOPNOTSUPP;
        }
index 43dffcc11fb120b75faffe1307b05279c1881bb9..7fd47a62d078ef0f240a98a9dafd3680ffc8190f 100644 (file)
 
 #ifdef CONFIG_NL80211_TESTMODE
 
-void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len);
+void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len);
 int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len);
 
 #else
 
-static inline void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf,
-                                            size_t buf_len)
+static inline void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf,
+                                     size_t buf_len)
 {
 }
 
index 506a3031a8850d2b8281306df8a6f5346ea57bd4..a3dc6943c7f74a27ef9090d3e00dd55bcdfa1f0a 100644 (file)
 #include "core.h"
 #include "debug.h"
 
+/*
+ * tid - tid_mux0..tid_mux3
+ * aid - tid_mux4..tid_mux7
+ */
+#define ATH6KL_TID_MASK 0xf
+#define ATH6KL_AID_SHIFT 4
+
+static inline u8 ath6kl_get_tid(u8 tid_mux)
+{
+       return tid_mux & ATH6KL_TID_MASK;
+}
+
+static inline u8 ath6kl_get_aid(u8 tid_mux)
+{
+       return tid_mux >> ATH6KL_AID_SHIFT;
+}
+
 static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
                               u32 *map_no)
 {
@@ -77,12 +94,118 @@ static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
        return ar->node_map[ep_map].ep_id;
 }
 
+static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn,
+                               struct ath6kl_vif *vif,
+                               struct sk_buff *skb,
+                               u32 *flags)
+{
+       struct ath6kl *ar = vif->ar;
+       bool is_apsdq_empty = false;
+       struct ethhdr *datap = (struct ethhdr *) skb->data;
+       u8 up = 0, traffic_class, *ip_hdr;
+       u16 ether_type;
+       struct ath6kl_llc_snap_hdr *llc_hdr;
+
+       if (conn->sta_flags & STA_PS_APSD_TRIGGER) {
+               /*
+                * This tx is because of a uAPSD trigger, determine
+                * more and EOSP bit. Set EOSP if queue is empty
+                * or sufficient frames are delivered for this trigger.
+                */
+               spin_lock_bh(&conn->psq_lock);
+               if (!skb_queue_empty(&conn->apsdq))
+                       *flags |= WMI_DATA_HDR_FLAGS_MORE;
+               else if (conn->sta_flags & STA_PS_APSD_EOSP)
+                       *flags |= WMI_DATA_HDR_FLAGS_EOSP;
+               *flags |= WMI_DATA_HDR_FLAGS_UAPSD;
+               spin_unlock_bh(&conn->psq_lock);
+               return false;
+       } else if (!conn->apsd_info)
+               return false;
+
+       if (test_bit(WMM_ENABLED, &vif->flags)) {
+               ether_type = be16_to_cpu(datap->h_proto);
+               if (is_ethertype(ether_type)) {
+                       /* packet is in DIX format  */
+                       ip_hdr = (u8 *)(datap + 1);
+               } else {
+                       /* packet is in 802.3 format */
+                       llc_hdr = (struct ath6kl_llc_snap_hdr *)
+                                                       (datap + 1);
+                       ether_type = be16_to_cpu(llc_hdr->eth_type);
+                       ip_hdr = (u8 *)(llc_hdr + 1);
+               }
+
+               if (ether_type == IP_ETHERTYPE)
+                       up = ath6kl_wmi_determine_user_priority(
+                                                       ip_hdr, 0);
+       }
+
+       traffic_class = ath6kl_wmi_get_traffic_class(up);
+
+       if ((conn->apsd_info & (1 << traffic_class)) == 0)
+               return false;
+
+       /* Queue the frames if the STA is sleeping */
+       spin_lock_bh(&conn->psq_lock);
+       is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+       skb_queue_tail(&conn->apsdq, skb);
+       spin_unlock_bh(&conn->psq_lock);
+
+       /*
+        * If this is the first pkt getting queued
+        * for this STA, update the PVB for this STA
+        */
+       if (is_apsdq_empty) {
+               ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
+                               vif->fw_vif_idx,
+                               conn->aid, 1, 0);
+       }
+       *flags |= WMI_DATA_HDR_FLAGS_UAPSD;
+
+       return true;
+}
+
+static bool ath6kl_process_psq(struct ath6kl_sta *conn,
+                               struct ath6kl_vif *vif,
+                               struct sk_buff *skb,
+                               u32 *flags)
+{
+       bool is_psq_empty = false;
+       struct ath6kl *ar = vif->ar;
+
+       if (conn->sta_flags & STA_PS_POLLED) {
+               spin_lock_bh(&conn->psq_lock);
+               if (!skb_queue_empty(&conn->psq))
+                       *flags |= WMI_DATA_HDR_FLAGS_MORE;
+               spin_unlock_bh(&conn->psq_lock);
+               return false;
+       }
+
+       /* Queue the frames if the STA is sleeping */
+       spin_lock_bh(&conn->psq_lock);
+       is_psq_empty = skb_queue_empty(&conn->psq);
+       skb_queue_tail(&conn->psq, skb);
+       spin_unlock_bh(&conn->psq_lock);
+
+       /*
+        * If this is the first pkt getting queued
+        * for this STA, update the PVB for this
+        * STA.
+        */
+       if (is_psq_empty)
+               ath6kl_wmi_set_pvb_cmd(ar->wmi,
+                                      vif->fw_vif_idx,
+                                      conn->aid, 1);
+       return true;
+}
+
 static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
-                               bool *more_data)
+                               u32 *flags)
 {
        struct ethhdr *datap = (struct ethhdr *) skb->data;
        struct ath6kl_sta *conn = NULL;
-       bool ps_queued = false, is_psq_empty = false;
+       bool ps_queued = false;
        struct ath6kl *ar = vif->ar;
 
        if (is_multicast_ether_addr(datap->h_dest)) {
@@ -128,7 +251,7 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
                                 */
                                spin_lock_bh(&ar->mcastpsq_lock);
                                if (!skb_queue_empty(&ar->mcastpsq))
-                                       *more_data = true;
+                                       *flags |= WMI_DATA_HDR_FLAGS_MORE;
                                spin_unlock_bh(&ar->mcastpsq_lock);
                        }
                }
@@ -142,37 +265,13 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
                }
 
                if (conn->sta_flags & STA_PS_SLEEP) {
-                       if (!(conn->sta_flags & STA_PS_POLLED)) {
-                               /* Queue the frames if the STA is sleeping */
-                               spin_lock_bh(&conn->psq_lock);
-                               is_psq_empty = skb_queue_empty(&conn->psq);
-                               skb_queue_tail(&conn->psq, skb);
-                               spin_unlock_bh(&conn->psq_lock);
-
-                               /*
-                                * If this is the first pkt getting queued
-                                * for this STA, update the PVB for this
-                                * STA.
-                                */
-                               if (is_psq_empty)
-                                       ath6kl_wmi_set_pvb_cmd(ar->wmi,
-                                                              vif->fw_vif_idx,
-                                                              conn->aid, 1);
-
-                               ps_queued = true;
-                       } else {
-                               /*
-                                * This tx is because of a PsPoll.
-                                * Determine if MoreData bit has to be set.
-                                */
-                               spin_lock_bh(&conn->psq_lock);
-                               if (!skb_queue_empty(&conn->psq))
-                                       *more_data = true;
-                               spin_unlock_bh(&conn->psq_lock);
-                       }
+                       ps_queued = ath6kl_process_uapsdq(conn,
+                                               vif, skb, flags);
+                       if (!(*flags & WMI_DATA_HDR_FLAGS_UAPSD))
+                               ps_queued = ath6kl_process_psq(conn,
+                                               vif, skb, flags);
                }
        }
-
        return ps_queued;
 }
 
@@ -242,8 +341,13 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
        u32 map_no = 0;
        u16 htc_tag = ATH6KL_DATA_PKT_TAG;
        u8 ac = 99 ; /* initialize to unmapped ac */
-       bool chk_adhoc_ps_mapping = false, more_data = false;
+       bool chk_adhoc_ps_mapping = false;
        int ret;
+       struct wmi_tx_meta_v2 meta_v2;
+       void *meta;
+       u8 csum_start = 0, csum_dest = 0, csum = skb->ip_summed;
+       u8 meta_ver = 0;
+       u32 flags = 0;
 
        ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
                   "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__,
@@ -260,11 +364,19 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
 
        /* AP mode Power saving processing */
        if (vif->nw_type == AP_NETWORK) {
-               if (ath6kl_powersave_ap(vif, skb, &more_data))
+               if (ath6kl_powersave_ap(vif, skb, &flags))
                        return 0;
        }
 
        if (test_bit(WMI_ENABLED, &ar->flag)) {
+               if ((dev->features & NETIF_F_IP_CSUM) &&
+                               (csum == CHECKSUM_PARTIAL)) {
+                       csum_start = skb->csum_start -
+                                       (skb_network_header(skb) - skb->head) +
+                                       sizeof(struct ath6kl_llc_snap_hdr);
+                       csum_dest = skb->csum_offset + csum_start;
+               }
+
                if (skb_headroom(skb) < dev->needed_headroom) {
                        struct sk_buff *tmp_skb = skb;
 
@@ -281,10 +393,28 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
                        goto fail_tx;
                }
 
-               if (ath6kl_wmi_data_hdr_add(ar->wmi, skb, DATA_MSGTYPE,
-                                           more_data, 0, 0, NULL,
-                                           vif->fw_vif_idx)) {
-                       ath6kl_err("wmi_data_hdr_add failed\n");
+               if ((dev->features & NETIF_F_IP_CSUM) &&
+                               (csum == CHECKSUM_PARTIAL)) {
+                       meta_v2.csum_start = csum_start;
+                       meta_v2.csum_dest = csum_dest;
+
+                       /* instruct target to calculate checksum */
+                       meta_v2.csum_flags = WMI_META_V2_FLAG_CSUM_OFFLOAD;
+                       meta_ver = WMI_META_VERSION_2;
+                       meta = &meta_v2;
+               } else {
+                       meta_ver = 0;
+                       meta = NULL;
+               }
+
+               ret = ath6kl_wmi_data_hdr_add(ar->wmi, skb,
+                               DATA_MSGTYPE, flags, 0,
+                               meta_ver,
+                               meta, vif->fw_vif_idx);
+
+               if (ret) {
+                       ath6kl_warn("failed to add wmi data header:%d\n"
+                               , ret);
                        goto fail_tx;
                }
 
@@ -449,9 +579,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
                 * WMI queue with too many commands the only exception to
                 * this is during testing using endpointping.
                 */
-               spin_lock_bh(&ar->lock);
                set_bit(WMI_CTRL_EP_FULL, &ar->flag);
-               spin_unlock_bh(&ar->lock);
                ath6kl_err("wmi ctrl ep is full\n");
                return action;
        }
@@ -479,9 +607,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
                    action != HTC_SEND_FULL_DROP) {
                        spin_unlock_bh(&ar->list_lock);
 
-                       spin_lock_bh(&vif->if_lock);
                        set_bit(NETQ_STOPPED, &vif->flags);
-                       spin_unlock_bh(&vif->if_lock);
                        netif_stop_queue(vif->ndev);
 
                        return action;
@@ -710,10 +836,12 @@ static struct sk_buff *aggr_get_free_skb(struct aggr_info *p_aggr)
 {
        struct sk_buff *skb = NULL;
 
-       if (skb_queue_len(&p_aggr->free_q) < (AGGR_NUM_OF_FREE_NETBUFS >> 2))
-               ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
+       if (skb_queue_len(&p_aggr->rx_amsdu_freeq) <
+           (AGGR_NUM_OF_FREE_NETBUFS >> 2))
+               ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq,
+                                    AGGR_NUM_OF_FREE_NETBUFS);
 
-       skb = skb_dequeue(&p_aggr->free_q);
+       skb = skb_dequeue(&p_aggr->rx_amsdu_freeq);
 
        return skb;
 }
@@ -881,7 +1009,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr,
        dev_kfree_skb(skb);
 }
 
-static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
+static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
                            u16 seq_no, u8 order)
 {
        struct sk_buff *skb;
@@ -890,11 +1018,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
        u16 idx, idx_end, seq_end;
        struct rxtid_stats *stats;
 
-       if (!p_aggr)
-               return;
-
-       rxtid = &p_aggr->rx_tid[tid];
-       stats = &p_aggr->stat[tid];
+       rxtid = &agg_conn->rx_tid[tid];
+       stats = &agg_conn->stat[tid];
 
        idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
 
@@ -923,7 +1048,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
 
                if (node->skb) {
                        if (node->is_amsdu)
-                               aggr_slice_amsdu(p_aggr, rxtid, node->skb);
+                               aggr_slice_amsdu(agg_conn->aggr_info, rxtid,
+                                                node->skb);
                        else
                                skb_queue_tail(&rxtid->q, node->skb);
                        node->skb = NULL;
@@ -939,10 +1065,10 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
        stats->num_delivered += skb_queue_len(&rxtid->q);
 
        while ((skb = skb_dequeue(&rxtid->q)))
-               ath6kl_deliver_frames_to_nw_stack(p_aggr->dev, skb);
+               ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb);
 }
 
-static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
+static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
                                  u16 seq_no,
                                  bool is_amsdu, struct sk_buff *frame)
 {
@@ -954,18 +1080,18 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
        bool is_queued = false;
        u16 extended_end;
 
-       rxtid = &agg_info->rx_tid[tid];
-       stats = &agg_info->stat[tid];
+       rxtid = &agg_conn->rx_tid[tid];
+       stats = &agg_conn->stat[tid];
 
        stats->num_into_aggr++;
 
        if (!rxtid->aggr) {
                if (is_amsdu) {
-                       aggr_slice_amsdu(agg_info, rxtid, frame);
+                       aggr_slice_amsdu(agg_conn->aggr_info, rxtid, frame);
                        is_queued = true;
                        stats->num_amsdu++;
                        while ((skb = skb_dequeue(&rxtid->q)))
-                               ath6kl_deliver_frames_to_nw_stack(agg_info->dev,
+                               ath6kl_deliver_frames_to_nw_stack(agg_conn->dev,
                                                                  skb);
                }
                return is_queued;
@@ -985,7 +1111,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
                     (cur < end || cur > extended_end)) ||
                    ((end > extended_end) && (cur > extended_end) &&
                     (cur < end))) {
-                       aggr_deque_frms(agg_info, tid, 0, 0);
+                       aggr_deque_frms(agg_conn, tid, 0, 0);
                        if (cur >= rxtid->hold_q_sz - 1)
                                rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
                        else
@@ -1002,7 +1128,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
                                st = ATH6KL_MAX_SEQ_NO -
                                        (rxtid->hold_q_sz - 2 - cur);
 
-                       aggr_deque_frms(agg_info, tid, st, 0);
+                       aggr_deque_frms(agg_conn, tid, st, 0);
                }
 
                stats->num_oow++;
@@ -1041,9 +1167,9 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
 
        spin_unlock_bh(&rxtid->lock);
 
-       aggr_deque_frms(agg_info, tid, 0, 1);
+       aggr_deque_frms(agg_conn, tid, 0, 1);
 
-       if (agg_info->timer_scheduled)
+       if (agg_conn->timer_scheduled)
                rxtid->progress = true;
        else
                for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
@@ -1054,8 +1180,8 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
                                 * the frame doesn't remain stuck
                                 * forever.
                                 */
-                               agg_info->timer_scheduled = true;
-                               mod_timer(&agg_info->timer,
+                               agg_conn->timer_scheduled = true;
+                               mod_timer(&agg_conn->timer,
                                          (jiffies +
                                           HZ * (AGGR_RX_TIMEOUT) / 1000));
                                rxtid->progress = false;
@@ -1067,6 +1193,76 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
        return is_queued;
 }
 
+static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif,
+                                                struct ath6kl_sta *conn)
+{
+       struct ath6kl *ar = vif->ar;
+       bool is_apsdq_empty, is_apsdq_empty_at_start;
+       u32 num_frames_to_deliver, flags;
+       struct sk_buff *skb = NULL;
+
+       /*
+        * If the APSD q for this STA is not empty, dequeue and
+        * send a pkt from the head of the q. Also update the
+        * More data bit in the WMI_DATA_HDR if there are
+        * more pkts for this STA in the APSD q.
+        * If there are no more pkts for this STA,
+        * update the APSD bitmap for this STA.
+        */
+
+       num_frames_to_deliver = (conn->apsd_info >> ATH6KL_APSD_NUM_OF_AC) &
+                                                   ATH6KL_APSD_FRAME_MASK;
+       /*
+        * Number of frames to send in a service period is
+        * indicated by the station
+        * in the QOS_INFO of the association request
+        * If it is zero, send all frames
+        */
+       if (!num_frames_to_deliver)
+               num_frames_to_deliver = ATH6KL_APSD_ALL_FRAME;
+
+       spin_lock_bh(&conn->psq_lock);
+       is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+       spin_unlock_bh(&conn->psq_lock);
+       is_apsdq_empty_at_start = is_apsdq_empty;
+
+       while ((!is_apsdq_empty) && (num_frames_to_deliver)) {
+
+               spin_lock_bh(&conn->psq_lock);
+               skb = skb_dequeue(&conn->apsdq);
+               is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+               spin_unlock_bh(&conn->psq_lock);
+
+               /*
+                * Set the STA flag to Trigger delivery,
+                * so that the frame will go out
+                */
+               conn->sta_flags |= STA_PS_APSD_TRIGGER;
+               num_frames_to_deliver--;
+
+               /* Last frame in the service period, set EOSP or queue empty */
+               if ((is_apsdq_empty) || (!num_frames_to_deliver))
+                       conn->sta_flags |= STA_PS_APSD_EOSP;
+
+               ath6kl_data_tx(skb, vif->ndev);
+               conn->sta_flags &= ~(STA_PS_APSD_TRIGGER);
+               conn->sta_flags &= ~(STA_PS_APSD_EOSP);
+       }
+
+       if (is_apsdq_empty) {
+               if (is_apsdq_empty_at_start)
+                       flags = WMI_AP_APSD_NO_DELIVERY_FRAMES;
+               else
+                       flags = 0;
+
+               ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
+                               vif->fw_vif_idx,
+                               conn->aid, 0, flags);
+       }
+
+       return;
+}
+
 void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 {
        struct ath6kl *ar = target->dev->ar;
@@ -1078,10 +1274,12 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
        int status = packet->status;
        enum htc_endpoint_id ept = packet->endpoint;
        bool is_amsdu, prev_ps, ps_state = false;
+       bool trig_state = false;
        struct ath6kl_sta *conn = NULL;
        struct sk_buff *skb1 = NULL;
        struct ethhdr *datap = NULL;
        struct ath6kl_vif *vif;
+       struct aggr_info_conn *aggr_conn;
        u16 seq_no, offset;
        u8 tid, if_idx;
 
@@ -1171,6 +1369,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
                              WMI_DATA_HDR_PS_MASK);
 
                offset = sizeof(struct wmi_data_hdr);
+               trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG);
 
                switch (meta_type) {
                case 0:
@@ -1209,18 +1408,36 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
                else
                        conn->sta_flags &= ~STA_PS_SLEEP;
 
+               /* Accept trigger only when the station is in sleep */
+               if ((conn->sta_flags & STA_PS_SLEEP) && trig_state)
+                       ath6kl_uapsd_trigger_frame_rx(vif, conn);
+
                if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) {
                        if (!(conn->sta_flags & STA_PS_SLEEP)) {
                                struct sk_buff *skbuff = NULL;
+                               bool is_apsdq_empty;
 
                                spin_lock_bh(&conn->psq_lock);
-                               while ((skbuff = skb_dequeue(&conn->psq))
-                                      != NULL) {
+                               while ((skbuff = skb_dequeue(&conn->psq))) {
+                                       spin_unlock_bh(&conn->psq_lock);
+                                       ath6kl_data_tx(skbuff, vif->ndev);
+                                       spin_lock_bh(&conn->psq_lock);
+                               }
+
+                               is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+                               while ((skbuff = skb_dequeue(&conn->apsdq))) {
                                        spin_unlock_bh(&conn->psq_lock);
                                        ath6kl_data_tx(skbuff, vif->ndev);
                                        spin_lock_bh(&conn->psq_lock);
                                }
                                spin_unlock_bh(&conn->psq_lock);
+
+                               if (!is_apsdq_empty)
+                                       ath6kl_wmi_set_apsd_bfrd_traf(
+                                                       ar->wmi,
+                                                       vif->fw_vif_idx,
+                                                       conn->aid, 0, 0);
+
                                /* Clear the PVB for this STA */
                                ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
                                                       conn->aid, 0);
@@ -1314,11 +1531,21 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 
        datap = (struct ethhdr *) skb->data;
 
-       if (is_unicast_ether_addr(datap->h_dest) &&
-           aggr_process_recv_frm(vif->aggr_cntxt, tid, seq_no,
-                                 is_amsdu, skb))
-               /* aggregation code will handle the skb */
-               return;
+       if (is_unicast_ether_addr(datap->h_dest)) {
+               if (vif->nw_type == AP_NETWORK) {
+                       conn = ath6kl_find_sta(vif, datap->h_source);
+                       if (!conn)
+                               return;
+                       aggr_conn = conn->aggr_conn;
+               } else
+                       aggr_conn = vif->aggr_cntxt->aggr_conn;
+
+               if (aggr_process_recv_frm(aggr_conn, tid, seq_no,
+                   is_amsdu, skb)) {
+                       /* aggregation code will handle the skb */
+                       return;
+               }
+       }
 
        ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb);
 }
@@ -1326,13 +1553,13 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 static void aggr_timeout(unsigned long arg)
 {
        u8 i, j;
-       struct aggr_info *p_aggr = (struct aggr_info *) arg;
+       struct aggr_info_conn *aggr_conn = (struct aggr_info_conn *) arg;
        struct rxtid *rxtid;
        struct rxtid_stats *stats;
 
        for (i = 0; i < NUM_OF_TIDS; i++) {
-               rxtid = &p_aggr->rx_tid[i];
-               stats = &p_aggr->stat[i];
+               rxtid = &aggr_conn->rx_tid[i];
+               stats = &aggr_conn->stat[i];
 
                if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
                        continue;
@@ -1343,18 +1570,18 @@ static void aggr_timeout(unsigned long arg)
                           rxtid->seq_next,
                           ((rxtid->seq_next + rxtid->hold_q_sz-1) &
                            ATH6KL_MAX_SEQ_NO));
-               aggr_deque_frms(p_aggr, i, 0, 0);
+               aggr_deque_frms(aggr_conn, i, 0, 0);
        }
 
-       p_aggr->timer_scheduled = false;
+       aggr_conn->timer_scheduled = false;
 
        for (i = 0; i < NUM_OF_TIDS; i++) {
-               rxtid = &p_aggr->rx_tid[i];
+               rxtid = &aggr_conn->rx_tid[i];
 
                if (rxtid->aggr && rxtid->hold_q) {
                        for (j = 0; j < rxtid->hold_q_sz; j++) {
                                if (rxtid->hold_q[j].skb) {
-                                       p_aggr->timer_scheduled = true;
+                                       aggr_conn->timer_scheduled = true;
                                        rxtid->timer_mon = true;
                                        rxtid->progress = false;
                                        break;
@@ -1366,24 +1593,24 @@ static void aggr_timeout(unsigned long arg)
                }
        }
 
-       if (p_aggr->timer_scheduled)
-               mod_timer(&p_aggr->timer,
+       if (aggr_conn->timer_scheduled)
+               mod_timer(&aggr_conn->timer,
                          jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT));
 }
 
-static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
+static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid)
 {
        struct rxtid *rxtid;
        struct rxtid_stats *stats;
 
-       if (!p_aggr || tid >= NUM_OF_TIDS)
+       if (!aggr_conn || tid >= NUM_OF_TIDS)
                return;
 
-       rxtid = &p_aggr->rx_tid[tid];
-       stats = &p_aggr->stat[tid];
+       rxtid = &aggr_conn->rx_tid[tid];
+       stats = &aggr_conn->stat[tid];
 
        if (rxtid->aggr)
-               aggr_deque_frms(p_aggr, tid, 0, 0);
+               aggr_deque_frms(aggr_conn, tid, 0, 0);
 
        rxtid->aggr = false;
        rxtid->progress = false;
@@ -1398,26 +1625,40 @@ static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
        memset(stats, 0, sizeof(struct rxtid_stats));
 }
 
-void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
+void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no,
                             u8 win_sz)
 {
-       struct aggr_info *p_aggr = vif->aggr_cntxt;
+       struct ath6kl_sta *sta;
+       struct aggr_info_conn *aggr_conn = NULL;
        struct rxtid *rxtid;
        struct rxtid_stats *stats;
        u16 hold_q_size;
+       u8 tid, aid;
 
-       if (!p_aggr)
+       if (vif->nw_type == AP_NETWORK) {
+               aid = ath6kl_get_aid(tid_mux);
+               sta = ath6kl_find_sta_by_aid(vif->ar, aid);
+               if (sta)
+                       aggr_conn = sta->aggr_conn;
+       } else
+               aggr_conn = vif->aggr_cntxt->aggr_conn;
+
+       if (!aggr_conn)
+               return;
+
+       tid = ath6kl_get_tid(tid_mux);
+       if (tid >= NUM_OF_TIDS)
                return;
 
-       rxtid = &p_aggr->rx_tid[tid];
-       stats = &p_aggr->stat[tid];
+       rxtid = &aggr_conn->rx_tid[tid];
+       stats = &aggr_conn->stat[tid];
 
        if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX)
                ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n",
                           __func__, win_sz, tid);
 
        if (rxtid->aggr)
-               aggr_delete_tid_state(p_aggr, tid);
+               aggr_delete_tid_state(aggr_conn, tid);
 
        rxtid->seq_next = seq_no;
        hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q);
@@ -1433,31 +1674,23 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
        rxtid->aggr = true;
 }
 
-struct aggr_info *aggr_init(struct net_device *dev)
+void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
+                   struct aggr_info_conn *aggr_conn)
 {
-       struct aggr_info *p_aggr = NULL;
        struct rxtid *rxtid;
        u8 i;
 
-       p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
-       if (!p_aggr) {
-               ath6kl_err("failed to alloc memory for aggr_node\n");
-               return NULL;
-       }
-
-       p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
-       p_aggr->dev = dev;
-       init_timer(&p_aggr->timer);
-       p_aggr->timer.function = aggr_timeout;
-       p_aggr->timer.data = (unsigned long) p_aggr;
+       aggr_conn->aggr_sz = AGGR_SZ_DEFAULT;
+       aggr_conn->dev = vif->ndev;
+       init_timer(&aggr_conn->timer);
+       aggr_conn->timer.function = aggr_timeout;
+       aggr_conn->timer.data = (unsigned long) aggr_conn;
+       aggr_conn->aggr_info = aggr_info;
 
-       p_aggr->timer_scheduled = false;
-       skb_queue_head_init(&p_aggr->free_q);
-
-       ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
+       aggr_conn->timer_scheduled = false;
 
        for (i = 0; i < NUM_OF_TIDS; i++) {
-               rxtid = &p_aggr->rx_tid[i];
+               rxtid = &aggr_conn->rx_tid[i];
                rxtid->aggr = false;
                rxtid->progress = false;
                rxtid->timer_mon = false;
@@ -1465,29 +1698,75 @@ struct aggr_info *aggr_init(struct net_device *dev)
                spin_lock_init(&rxtid->lock);
        }
 
+}
+
+struct aggr_info *aggr_init(struct ath6kl_vif *vif)
+{
+       struct aggr_info *p_aggr = NULL;
+
+       p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
+       if (!p_aggr) {
+               ath6kl_err("failed to alloc memory for aggr_node\n");
+               return NULL;
+       }
+
+       p_aggr->aggr_conn = kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL);
+       if (!p_aggr->aggr_conn) {
+               ath6kl_err("failed to alloc memory for connection specific aggr info\n");
+               kfree(p_aggr);
+               return NULL;
+       }
+
+       aggr_conn_init(vif, p_aggr, p_aggr->aggr_conn);
+
+       skb_queue_head_init(&p_aggr->rx_amsdu_freeq);
+       ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS);
+
        return p_aggr;
 }
 
-void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid)
+void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux)
 {
-       struct aggr_info *p_aggr = vif->aggr_cntxt;
+       struct ath6kl_sta *sta;
        struct rxtid *rxtid;
+       struct aggr_info_conn *aggr_conn = NULL;
+       u8 tid, aid;
+
+       if (vif->nw_type == AP_NETWORK) {
+               aid = ath6kl_get_aid(tid_mux);
+               sta = ath6kl_find_sta_by_aid(vif->ar, aid);
+               if (sta)
+                       aggr_conn = sta->aggr_conn;
+       } else
+               aggr_conn = vif->aggr_cntxt->aggr_conn;
+
+       if (!aggr_conn)
+               return;
 
-       if (!p_aggr)
+       tid = ath6kl_get_tid(tid_mux);
+       if (tid >= NUM_OF_TIDS)
                return;
 
-       rxtid = &p_aggr->rx_tid[tid];
+       rxtid = &aggr_conn->rx_tid[tid];
 
        if (rxtid->aggr)
-               aggr_delete_tid_state(p_aggr, tid);
+               aggr_delete_tid_state(aggr_conn, tid);
 }
 
-void aggr_reset_state(struct aggr_info *aggr_info)
+void aggr_reset_state(struct aggr_info_conn *aggr_conn)
 {
        u8 tid;
 
+       if (!aggr_conn)
+               return;
+
+       if (aggr_conn->timer_scheduled) {
+               del_timer(&aggr_conn->timer);
+               aggr_conn->timer_scheduled = false;
+       }
+
        for (tid = 0; tid < NUM_OF_TIDS; tid++)
-               aggr_delete_tid_state(aggr_info, tid);
+               aggr_delete_tid_state(aggr_conn, tid);
 }
 
 /* clean up our amsdu buffer list */
@@ -1514,28 +1793,11 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar)
 
 void aggr_module_destroy(struct aggr_info *aggr_info)
 {
-       struct rxtid *rxtid;
-       u8 i, k;
-
        if (!aggr_info)
                return;
 
-       if (aggr_info->timer_scheduled) {
-               del_timer(&aggr_info->timer);
-               aggr_info->timer_scheduled = false;
-       }
-
-       for (i = 0; i < NUM_OF_TIDS; i++) {
-               rxtid = &aggr_info->rx_tid[i];
-               if (rxtid->hold_q) {
-                       for (k = 0; k < rxtid->hold_q_sz; k++)
-                               dev_kfree_skb(rxtid->hold_q[k].skb);
-                       kfree(rxtid->hold_q);
-               }
-
-               skb_queue_purge(&rxtid->q);
-       }
-
-       skb_queue_purge(&aggr_info->free_q);
+       aggr_reset_state(aggr_info->aggr_conn);
+       skb_queue_purge(&aggr_info->rx_amsdu_freeq);
+       kfree(aggr_info->aggr_conn);
        kfree(aggr_info);
 }
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
new file mode 100644 (file)
index 0000000..c72567c
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2007-2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "debug.h"
+#include "core.h"
+
+/* usb device object */
+struct ath6kl_usb {
+       struct usb_device *udev;
+       struct usb_interface *interface;
+       u8 *diag_cmd_buffer;
+       u8 *diag_resp_buffer;
+       struct ath6kl *ar;
+};
+
+/* diagnostic command defnitions */
+#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD        1
+#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP       2
+#define ATH6KL_USB_CONTROL_REQ_DIAG_CMD            3
+#define ATH6KL_USB_CONTROL_REQ_DIAG_RESP           4
+
+#define ATH6KL_USB_CTRL_DIAG_CC_READ               0
+#define ATH6KL_USB_CTRL_DIAG_CC_WRITE              1
+
+struct ath6kl_usb_ctrl_diag_cmd_write {
+       __le32 cmd;
+       __le32 address;
+       __le32 value;
+       __le32 _pad[1];
+} __packed;
+
+struct ath6kl_usb_ctrl_diag_cmd_read {
+       __le32 cmd;
+       __le32 address;
+} __packed;
+
+struct ath6kl_usb_ctrl_diag_resp_read {
+       __le32 value;
+} __packed;
+
+#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write))
+#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read))
+
+static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb)
+{
+       usb_set_intfdata(ar_usb->interface, NULL);
+
+       kfree(ar_usb->diag_cmd_buffer);
+       kfree(ar_usb->diag_resp_buffer);
+
+       kfree(ar_usb);
+}
+
+static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface)
+{
+       struct ath6kl_usb *ar_usb = NULL;
+       struct usb_device *dev = interface_to_usbdev(interface);
+       int status = 0;
+
+       ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL);
+       if (ar_usb == NULL)
+               goto fail_ath6kl_usb_create;
+
+       memset(ar_usb, 0, sizeof(struct ath6kl_usb));
+       usb_set_intfdata(interface, ar_usb);
+       ar_usb->udev = dev;
+       ar_usb->interface = interface;
+
+       ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL);
+       if (ar_usb->diag_cmd_buffer == NULL) {
+               status = -ENOMEM;
+               goto fail_ath6kl_usb_create;
+       }
+
+       ar_usb->diag_resp_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_RESP,
+                                          GFP_KERNEL);
+       if (ar_usb->diag_resp_buffer == NULL) {
+               status = -ENOMEM;
+               goto fail_ath6kl_usb_create;
+       }
+
+fail_ath6kl_usb_create:
+       if (status != 0) {
+               ath6kl_usb_destroy(ar_usb);
+               ar_usb = NULL;
+       }
+       return ar_usb;
+}
+
+static void ath6kl_usb_device_detached(struct usb_interface *interface)
+{
+       struct ath6kl_usb *ar_usb;
+
+       ar_usb = usb_get_intfdata(interface);
+       if (ar_usb == NULL)
+               return;
+
+       ath6kl_stop_txrx(ar_usb->ar);
+
+       ath6kl_core_cleanup(ar_usb->ar);
+
+       ath6kl_usb_destroy(ar_usb);
+}
+
+static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
+                                  u8 req, u16 value, u16 index, void *data,
+                                  u32 size)
+{
+       u8 *buf = NULL;
+       int ret;
+
+       if (size > 0) {
+               buf = kmalloc(size, GFP_KERNEL);
+               if (buf == NULL)
+                       return -ENOMEM;
+
+               memcpy(buf, data, size);
+       }
+
+       /* note: if successful returns number of bytes transfered */
+       ret = usb_control_msg(ar_usb->udev,
+                             usb_sndctrlpipe(ar_usb->udev, 0),
+                             req,
+                             USB_DIR_OUT | USB_TYPE_VENDOR |
+                             USB_RECIP_DEVICE, value, index, buf,
+                             size, 1000);
+
+       if (ret < 0) {
+               ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
+                          __func__, ret);
+       }
+
+       kfree(buf);
+
+       return 0;
+}
+
+static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb,
+                                 u8 req, u16 value, u16 index, void *data,
+                                 u32 size)
+{
+       u8 *buf = NULL;
+       int ret;
+
+       if (size > 0) {
+               buf = kmalloc(size, GFP_KERNEL);
+               if (buf == NULL)
+                       return -ENOMEM;
+       }
+
+       /* note: if successful returns number of bytes transfered */
+       ret = usb_control_msg(ar_usb->udev,
+                                usb_rcvctrlpipe(ar_usb->udev, 0),
+                                req,
+                                USB_DIR_IN | USB_TYPE_VENDOR |
+                                USB_RECIP_DEVICE, value, index, buf,
+                                size, 2 * HZ);
+
+       if (ret < 0) {
+               ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
+                          __func__, ret);
+       }
+
+       memcpy((u8 *) data, buf, size);
+
+       kfree(buf);
+
+       return 0;
+}
+
+static int ath6kl_usb_ctrl_msg_exchange(struct ath6kl_usb *ar_usb,
+                                    u8 req_val, u8 *req_buf, u32 req_len,
+                                    u8 resp_val, u8 *resp_buf, u32 *resp_len)
+{
+       int ret;
+
+       /* send command */
+       ret = ath6kl_usb_submit_ctrl_out(ar_usb, req_val, 0, 0,
+                                        req_buf, req_len);
+
+       if (ret != 0)
+               return ret;
+
+       if (resp_buf == NULL) {
+               /* no expected response */
+               return ret;
+       }
+
+       /* get response */
+       ret = ath6kl_usb_submit_ctrl_in(ar_usb, resp_val, 0, 0,
+                                       resp_buf, *resp_len);
+
+       return ret;
+}
+
+static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
+{
+       struct ath6kl_usb *ar_usb = ar->hif_priv;
+       struct ath6kl_usb_ctrl_diag_resp_read *resp;
+       struct ath6kl_usb_ctrl_diag_cmd_read *cmd;
+       u32 resp_len;
+       int ret;
+
+       cmd = (struct ath6kl_usb_ctrl_diag_cmd_read *) ar_usb->diag_cmd_buffer;
+
+       memset(cmd, 0, sizeof(*cmd));
+       cmd->cmd = ATH6KL_USB_CTRL_DIAG_CC_READ;
+       cmd->address = cpu_to_le32(address);
+       resp_len = sizeof(*resp);
+
+       ret = ath6kl_usb_ctrl_msg_exchange(ar_usb,
+                               ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
+                               (u8 *) cmd,
+                               sizeof(struct ath6kl_usb_ctrl_diag_cmd_write),
+                               ATH6KL_USB_CONTROL_REQ_DIAG_RESP,
+                               ar_usb->diag_resp_buffer, &resp_len);
+
+       if (ret)
+               return ret;
+
+       resp = (struct ath6kl_usb_ctrl_diag_resp_read *)
+               ar_usb->diag_resp_buffer;
+
+       *data = le32_to_cpu(resp->value);
+
+       return ret;
+}
+
+static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
+{
+       struct ath6kl_usb *ar_usb = ar->hif_priv;
+       struct ath6kl_usb_ctrl_diag_cmd_write *cmd;
+
+       cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer;
+
+       memset(cmd, 0, sizeof(struct ath6kl_usb_ctrl_diag_cmd_write));
+       cmd->cmd = cpu_to_le32(ATH6KL_USB_CTRL_DIAG_CC_WRITE);
+       cmd->address = cpu_to_le32(address);
+       cmd->value = data;
+
+       return ath6kl_usb_ctrl_msg_exchange(ar_usb,
+                                           ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
+                                           (u8 *) cmd,
+                                           sizeof(*cmd),
+                                           0, NULL, NULL);
+
+}
+
+static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
+{
+       struct ath6kl_usb *ar_usb = ar->hif_priv;
+       int ret;
+
+       /* get response */
+       ret = ath6kl_usb_submit_ctrl_in(ar_usb,
+                                       ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP,
+                                       0, 0, buf, len);
+       if (ret != 0) {
+               ath6kl_err("Unable to read the bmi data from the device: %d\n",
+                          ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
+{
+       struct ath6kl_usb *ar_usb = ar->hif_priv;
+       int ret;
+
+       /* send command */
+       ret = ath6kl_usb_submit_ctrl_out(ar_usb,
+                                        ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD,
+                                        0, 0, buf, len);
+       if (ret != 0) {
+               ath6kl_err("unable to send the bmi data to the device: %d\n",
+                          ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int ath6kl_usb_power_on(struct ath6kl *ar)
+{
+       return 0;
+}
+
+static int ath6kl_usb_power_off(struct ath6kl *ar)
+{
+       return 0;
+}
+
+static const struct ath6kl_hif_ops ath6kl_usb_ops = {
+       .diag_read32 = ath6kl_usb_diag_read32,
+       .diag_write32 = ath6kl_usb_diag_write32,
+       .bmi_read = ath6kl_usb_bmi_read,
+       .bmi_write = ath6kl_usb_bmi_write,
+       .power_on = ath6kl_usb_power_on,
+       .power_off = ath6kl_usb_power_off,
+};
+
+/* ath6kl usb driver registered functions */
+static int ath6kl_usb_probe(struct usb_interface *interface,
+                           const struct usb_device_id *id)
+{
+       struct usb_device *dev = interface_to_usbdev(interface);
+       struct ath6kl *ar;
+       struct ath6kl_usb *ar_usb = NULL;
+       int vendor_id, product_id;
+       int ret = 0;
+
+       usb_get_dev(dev);
+
+       vendor_id = le16_to_cpu(dev->descriptor.idVendor);
+       product_id = le16_to_cpu(dev->descriptor.idProduct);
+
+       ath6kl_dbg(ATH6KL_DBG_USB, "vendor_id = %04x\n", vendor_id);
+       ath6kl_dbg(ATH6KL_DBG_USB, "product_id = %04x\n", product_id);
+
+       if (interface->cur_altsetting)
+               ath6kl_dbg(ATH6KL_DBG_USB, "USB Interface %d\n",
+                          interface->cur_altsetting->desc.bInterfaceNumber);
+
+
+       if (dev->speed == USB_SPEED_HIGH)
+               ath6kl_dbg(ATH6KL_DBG_USB, "USB 2.0 Host\n");
+       else
+               ath6kl_dbg(ATH6KL_DBG_USB, "USB 1.1 Host\n");
+
+       ar_usb = ath6kl_usb_create(interface);
+
+       if (ar_usb == NULL) {
+               ret = -ENOMEM;
+               goto err_usb_put;
+       }
+
+       ar = ath6kl_core_create(&ar_usb->udev->dev);
+       if (ar == NULL) {
+               ath6kl_err("Failed to alloc ath6kl core\n");
+               ret = -ENOMEM;
+               goto err_usb_destroy;
+       }
+
+       ar->hif_priv = ar_usb;
+       ar->hif_type = ATH6KL_HIF_TYPE_USB;
+       ar->hif_ops = &ath6kl_usb_ops;
+       ar->mbox_info.block_size = 16;
+       ar->bmi.max_data_size = 252;
+
+       ar_usb->ar = ar;
+
+       ret = ath6kl_core_init(ar);
+       if (ret) {
+               ath6kl_err("Failed to init ath6kl core: %d\n", ret);
+               goto err_core_free;
+       }
+
+       return ret;
+
+err_core_free:
+       ath6kl_core_destroy(ar);
+err_usb_destroy:
+       ath6kl_usb_destroy(ar_usb);
+err_usb_put:
+       usb_put_dev(dev);
+
+       return ret;
+}
+
+static void ath6kl_usb_remove(struct usb_interface *interface)
+{
+       usb_put_dev(interface_to_usbdev(interface));
+       ath6kl_usb_device_detached(interface);
+}
+
+/* table of devices that work with this driver */
+static struct usb_device_id ath6kl_usb_ids[] = {
+       {USB_DEVICE(0x0cf3, 0x9374)},
+       { /* Terminating entry */ },
+};
+
+MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids);
+
+static struct usb_driver ath6kl_usb_driver = {
+       .name = "ath6kl_usb",
+       .probe = ath6kl_usb_probe,
+       .disconnect = ath6kl_usb_remove,
+       .id_table = ath6kl_usb_ids,
+};
+
+static int ath6kl_usb_init(void)
+{
+       usb_register(&ath6kl_usb_driver);
+       return 0;
+}
+
+static void ath6kl_usb_exit(void)
+{
+       usb_deregister(&ath6kl_usb_driver);
+}
+
+module_init(ath6kl_usb_init);
+module_exit(ath6kl_usb_exit);
+
+MODULE_AUTHOR("Atheros Communications, Inc.");
+MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
index f6f2aa27fc20ee1abc34e96b4c704894249c48e0..97abf4699b41270883b80357185652253237c59c 100644 (file)
@@ -180,7 +180,7 @@ static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb,
 }
 
 int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
-                           u8 msg_type, bool more_data,
+                           u8 msg_type, u32 flags,
                            enum wmi_data_hdr_data_type data_type,
                            u8 meta_ver, void *tx_meta_info, u8 if_idx)
 {
@@ -204,17 +204,19 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
        data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT;
        data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT;
 
-       if (more_data)
-               data_hdr->info |=
-                   WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT;
+       if (flags & WMI_DATA_HDR_FLAGS_MORE)
+               data_hdr->info |= WMI_DATA_HDR_MORE;
 
-       data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
-       data_hdr->info3 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK);
+       if (flags & WMI_DATA_HDR_FLAGS_EOSP)
+               data_hdr->info3 |= cpu_to_le16(WMI_DATA_HDR_EOSP);
+
+       data_hdr->info2 |= cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
+       data_hdr->info3 |= cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK);
 
        return 0;
 }
 
-static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
+u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
 {
        struct iphdr *ip_hdr = (struct iphdr *) pkt;
        u8 ip_pri;
@@ -236,6 +238,11 @@ static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
                return ip_pri;
 }
 
+u8 ath6kl_wmi_get_traffic_class(u8 user_priority)
+{
+       return  up_to_ac[user_priority & 0x7];
+}
+
 int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
                                       struct sk_buff *skb,
                                       u32 layer2_priority, bool wmm_enabled,
@@ -419,9 +426,6 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
        ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n",
                   evt->num_msg, evt->msg_len, evt->msg_type);
 
-       if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_WMI))
-               return 0;
-
        for (index = 0; index < evt->num_msg; index++) {
                size = sizeof(struct wmi_tx_complete_event) +
                    (index * sizeof(struct tx_complete_msg_v1));
@@ -552,7 +556,8 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len,
                   dlen, freq, vif->probe_req_report);
 
        if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
-               cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC);
+               cfg80211_rx_mgmt(vif->ndev, freq, 0,
+                                ev->data, dlen, GFP_ATOMIC);
 
        return 0;
 }
@@ -591,7 +596,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len,
                return -EINVAL;
        }
        ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
-       cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC);
+       cfg80211_rx_mgmt(vif->ndev, freq, 0,
+                        ev->data, dlen, GFP_ATOMIC);
 
        return 0;
 }
@@ -786,12 +792,14 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
                                   ev->u.ap_sta.keymgmt,
                                   le16_to_cpu(ev->u.ap_sta.cipher),
                                   ev->u.ap_sta.apsd_info);
+
                        ath6kl_connect_ap_mode_sta(
                                vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr,
                                ev->u.ap_sta.keymgmt,
                                le16_to_cpu(ev->u.ap_sta.cipher),
                                ev->u.ap_sta.auth, ev->assoc_req_len,
-                               ev->assoc_info + ev->beacon_ie_len);
+                               ev->assoc_info + ev->beacon_ie_len,
+                               ev->u.ap_sta.apsd_info);
                }
                return 0;
        }
@@ -1145,9 +1153,9 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
        return 0;
 }
 
-static int ath6kl_wmi_tcmd_test_report_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_test_rx(struct wmi *wmi, u8 *datap, int len)
 {
-       ath6kl_tm_rx_report_event(wmi->parent_dev, datap, len);
+       ath6kl_tm_rx_event(wmi->parent_dev, datap, len);
 
        return 0;
 }
@@ -2479,15 +2487,16 @@ int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class,
        return ret;
 }
 
-int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd)
+int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
+                         __be32 ips0, __be32 ips1)
 {
        struct sk_buff *skb;
        struct wmi_set_ip_cmd *cmd;
        int ret;
 
        /* Multicast address are not valid */
-       if ((*((u8 *) &ip_cmd->ips[0]) >= 0xE0) ||
-           (*((u8 *) &ip_cmd->ips[1]) >= 0xE0))
+       if (ipv4_is_multicast(ips0) ||
+           ipv4_is_multicast(ips1))
                return -EINVAL;
 
        skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd));
@@ -2495,9 +2504,10 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd)
                return -ENOMEM;
 
        cmd = (struct wmi_set_ip_cmd *) skb->data;
-       memcpy(cmd, ip_cmd, sizeof(struct wmi_set_ip_cmd));
+       cmd->ips[0] = ips0;
+       cmd->ips[1] = ips1;
 
-       ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_IP_CMDID,
+       ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_IP_CMDID,
                                  NO_SYNC_WMIFLAG);
        return ret;
 }
@@ -2582,6 +2592,18 @@ int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
        return ret;
 }
 
+/* This command has zero length payload */
+static int ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(struct wmi *wmi,
+                                                     struct ath6kl_vif *vif)
+{
+       struct ath6kl *ar = wmi->parent_dev;
+
+       set_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
+       wake_up(&ar->event_wq);
+
+       return 0;
+}
+
 int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
                                enum ath6kl_wow_mode wow_mode,
                                u32 filter, u16 host_req_delay)
@@ -2612,7 +2634,8 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
 
 int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
                                   u8 list_id, u8 filter_size,
-                                  u8 filter_offset, u8 *filter, u8 *mask)
+                                  u8 filter_offset, const u8 *filter,
+                                  const u8 *mask)
 {
        struct sk_buff *skb;
        struct wmi_add_wow_pattern_cmd *cmd;
@@ -2853,6 +2876,51 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len)
        return ret;
 }
 
+int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on)
+{
+       struct sk_buff *skb;
+       struct wmi_mcast_filter_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_mcast_filter_cmd *) skb->data;
+       cmd->mcast_all_enable = mc_all_on;
+
+       ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_MCAST_FILTER_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
+                                       u8 *filter, bool add_filter)
+{
+       struct sk_buff *skb;
+       struct wmi_mcast_filter_add_del_cmd *cmd;
+       int ret;
+
+       if ((filter[0] != 0x33 || filter[1] != 0x33) &&
+           (filter[0] != 0x01 || filter[1] != 0x00 ||
+           filter[2] != 0x5e || filter[3] > 0x7f)) {
+               ath6kl_warn("invalid multicast filter address\n");
+               return -EINVAL;
+       }
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_mcast_filter_add_del_cmd *) skb->data;
+       memcpy(cmd->mcast_mac, filter, ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);
+       ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
+                                 add_filter ? WMI_SET_MCAST_FILTER_CMDID :
+                                 WMI_DEL_MCAST_FILTER_CMDID,
+                                 NO_SYNC_WMIFLAG);
+
+       return ret;
+}
 
 s32 ath6kl_wmi_get_rate(s8 rate_index)
 {
@@ -2946,6 +3014,43 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
                                   NO_SYNC_WMIFLAG);
 }
 
+/* This command will be used to enable/disable AP uAPSD feature */
+int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable)
+{
+       struct wmi_ap_set_apsd_cmd *cmd;
+       struct sk_buff *skb;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_ap_set_apsd_cmd *)skb->data;
+       cmd->enable = enable;
+
+       return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_APSD_CMDID,
+                                  NO_SYNC_WMIFLAG);
+}
+
+int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, u8 if_idx,
+                                            u16 aid, u16 bitmap, u32 flags)
+{
+       struct wmi_ap_apsd_buffered_traffic_cmd *cmd;
+       struct sk_buff *skb;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_ap_apsd_buffered_traffic_cmd *)skb->data;
+       cmd->aid = cpu_to_le16(aid);
+       cmd->bitmap = cpu_to_le16(bitmap);
+       cmd->flags = cpu_to_le32(flags);
+
+       return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
+                                  WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID,
+                                  NO_SYNC_WMIFLAG);
+}
+
 static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len,
                                      struct ath6kl_vif *vif)
 {
@@ -3400,7 +3505,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
                break;
        case WMI_TEST_EVENTID:
                ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n");
-               ret = ath6kl_wmi_tcmd_test_report_rx(wmi, datap, len);
+               ret = ath6kl_wmi_test_rx(wmi, datap, len);
                break;
        case WMI_GET_FIXRATES_CMDID:
                ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n");
@@ -3465,6 +3570,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
                ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
                ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
                break;
+       case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI,
+                          "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID");
+               ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif);
+               break;
        case WMI_REMAIN_ON_CHNL_EVENTID:
                ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
                ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif);
index 42ac311eda4e23f84cc61f29a6ac68d01e147bc0..e7919869725e07b9d6300a259c522f3bd2b59ce3 100644 (file)
@@ -149,8 +149,7 @@ enum wmi_msg_type {
 #define WMI_DATA_HDR_PS_MASK        0x1
 #define WMI_DATA_HDR_PS_SHIFT       5
 
-#define WMI_DATA_HDR_MORE_MASK      0x1
-#define WMI_DATA_HDR_MORE_SHIFT     5
+#define WMI_DATA_HDR_MORE      0x20
 
 enum wmi_data_hdr_data_type {
        WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
@@ -160,6 +159,13 @@ enum wmi_data_hdr_data_type {
        WMI_DATA_HDR_DATA_TYPE_ACL,
 };
 
+/* Bitmap of data header flags */
+enum wmi_data_hdr_flags {
+       WMI_DATA_HDR_FLAGS_MORE = 0x1,
+       WMI_DATA_HDR_FLAGS_EOSP = 0x2,
+       WMI_DATA_HDR_FLAGS_UAPSD = 0x4,
+};
+
 #define WMI_DATA_HDR_DATA_TYPE_MASK     0x3
 #define WMI_DATA_HDR_DATA_TYPE_SHIFT    6
 
@@ -173,8 +179,12 @@ enum wmi_data_hdr_data_type {
 #define WMI_DATA_HDR_META_MASK      0x7
 #define WMI_DATA_HDR_META_SHIFT     13
 
+/* Macros for operating on WMI_DATA_HDR (info3) field */
 #define WMI_DATA_HDR_IF_IDX_MASK    0xF
 
+#define WMI_DATA_HDR_TRIG          0x10
+#define WMI_DATA_HDR_EOSP          0x10
+
 struct wmi_data_hdr {
        s8 rssi;
 
@@ -203,7 +213,8 @@ struct wmi_data_hdr {
        /*
         * usage of info3, 16-bit:
         * b3:b0        - Interface index
-        * b15:b4       - Reserved
+        * b4           - uAPSD trigger in rx & EOSP in tx
+        * b15:b5       - Reserved
         */
        __le16 info3;
 } __packed;
@@ -257,6 +268,9 @@ static inline u8 wmi_data_hdr_get_if_idx(struct wmi_data_hdr *dhdr)
 #define WMI_META_VERSION_1     0x01
 #define WMI_META_VERSION_2     0x02
 
+/* Flag to signal to FW to calculate TCP checksum */
+#define WMI_META_V2_FLAG_CSUM_OFFLOAD 0x01
+
 struct wmi_tx_meta_v1 {
        /* packet ID to identify the tx request */
        u8 pkt_id;
@@ -646,7 +660,6 @@ enum auth_mode {
        WPA2_AUTH_CCKM = 0x40,
 };
 
-#define WMI_MIN_KEY_INDEX   0
 #define WMI_MAX_KEY_INDEX   3
 
 #define WMI_MAX_KEY_LEN     32
@@ -1237,6 +1250,15 @@ enum target_event_report_config {
        NO_DISCONN_EVT_IN_RECONN
 };
 
+struct wmi_mcast_filter_cmd {
+       u8 mcast_all_enable;
+} __packed;
+
+#define ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE 6
+struct wmi_mcast_filter_add_del_cmd {
+       u8 mcast_mac[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
+} __packed;
+
 /* Command Replies */
 
 /* WMI_GET_CHANNEL_LIST_CMDID reply */
@@ -1335,6 +1357,8 @@ enum wmi_event_id {
        WMI_P2P_START_SDPD_EVENTID,
        WMI_P2P_SDPD_RX_EVENTID,
 
+       WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID = 0x1047,
+
        WMI_THIN_RESERVED_START_EVENTID = 0x8000,
        /* Events in this range are reserved for thinmode */
        WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
@@ -1903,7 +1927,7 @@ struct wow_filter {
 
 struct wmi_set_ip_cmd {
        /* IP in network byte order */
-       __le32 ips[MAX_IP_ADDRS];
+       __be32 ips[MAX_IP_ADDRS];
 } __packed;
 
 enum ath6kl_wow_filters {
@@ -2105,6 +2129,19 @@ struct wmi_rx_frame_format_cmd {
 } __packed;
 
 /* AP mode events */
+struct wmi_ap_set_apsd_cmd {
+       u8 enable;
+} __packed;
+
+enum wmi_ap_apsd_buffered_traffic_flags {
+       WMI_AP_APSD_NO_DELIVERY_FRAMES =  0x1,
+};
+
+struct wmi_ap_apsd_buffered_traffic_cmd {
+       __le16 aid;
+       __le16 bitmap;
+       __le32 flags;
+} __packed;
 
 /* WMI_PS_POLL_EVENT */
 struct wmi_pspoll_event {
@@ -2321,7 +2358,7 @@ enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
 void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id);
 int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
 int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
-                           u8 msg_type, bool more_data,
+                           u8 msg_type, u32 flags,
                            enum wmi_data_hdr_data_type data_type,
                            u8 meta_ver, void *tx_meta_info, u8 if_idx);
 
@@ -2417,7 +2454,8 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
 
 s32 ath6kl_wmi_get_rate(s8 rate_index);
 
-int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd);
+int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
+                         __be32 ips0, __be32 ips1);
 int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
                                       enum ath6kl_host_mode host_mode);
 int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
@@ -2425,13 +2463,26 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
                                u32 filter, u16 host_req_delay);
 int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
                                   u8 list_id, u8 filter_size,
-                                  u8 filter_offset, u8 *filter, u8 *mask);
+                                  u8 filter_offset, const u8 *filter,
+                                  const u8 *mask);
 int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
                                   u16 list_id, u16 filter_id);
 int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
 int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
 int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);
+int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
+int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
+                                       u8 *filter, bool add_filter);
+/* AP mode uAPSD */
+int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
+
+int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi,
+                                               u8 if_idx, u16 aid,
+                                               u16 bitmap, u32 flags);
+
+u8 ath6kl_wmi_get_traffic_class(u8 user_priority);
 
+u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri);
 /* AP mode */
 int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx,
                                 struct wmi_connect_cmd *p);
index dc6be4afe8eb96ad1ecce4147db6ff761d1556bc..e507e78398f3dc76b3678fb8d16a8b7282735c14 100644 (file)
@@ -6,6 +6,14 @@ config ATH9K_DFS_DEBUGFS
        def_bool y
        depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
 
+config ATH9K_BTCOEX_SUPPORT
+       bool "Atheros bluetooth coexistence support"
+       depends on (ATH9K || ATH9K_HTC)
+       default y
+       ---help---
+         Say Y, if you want to use the ath9k/ath9k_htc radios together with
+         Bluetooth modules in the same system.
+
 config ATH9K
        tristate "Atheros 802.11n wireless cards support"
        depends on MAC80211
@@ -73,6 +81,14 @@ config ATH9K_DFS_CERTIFIED
          developed. At this point enabling this option won't do anything
          except increase code size.
 
+config ATH9K_MAC_DEBUG
+       bool "Atheros MAC statistics"
+       depends on ATH9K_DEBUGFS
+       default y
+       ---help---
+         This option enables collection of statistics for Rx/Tx status
+         data and some other MAC related statistics
+
 config ATH9K_RATE_CONTROL
        bool "Atheros ath9k rate control"
        depends on ATH9K
@@ -81,14 +97,6 @@ config ATH9K_RATE_CONTROL
          Say Y, if you want to use the ath9k specific rate control
          module instead of minstrel_ht.
 
-config ATH9K_BTCOEX_SUPPORT
-       bool "Atheros ath9k bluetooth coexistence support"
-       depends on ATH9K
-       default y
-       ---help---
-         Say Y, if you want to use the ath9k radios together with
-         Bluetooth modules in the same system.
-
 config ATH9K_HTC
        tristate "Atheros HTC based wireless cards support"
        depends on USB && MAC80211
index da02242499af15d9049b3a2ce7913cb87ade80bc..27d95fe5ade058b234d88a78ebcbe43e0508834d 100644 (file)
@@ -3,9 +3,9 @@ ath9k-y +=      beacon.o \
                init.o \
                main.o \
                recv.o \
-               xmit.o \
-               mci.o \
+               xmit.o
 
+ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
 ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
 ath9k-$(CONFIG_ATH9K_PCI) += pci.o
 ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
@@ -31,14 +31,14 @@ ath9k_hw-y:=        \
                eeprom_4k.o \
                eeprom_9287.o \
                ani.o \
-               btcoex.o \
                mac.o \
                ar9002_mac.o \
                ar9003_mac.o \
                ar9003_eeprom.o \
-               ar9003_paprd.o \
-               ar9003_mci.o
+               ar9003_paprd.o
 
+ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
+                                          ar9003_mci.o
 obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
 
 obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
index f901a17f76baf6da3a2ad3e55880a8aa25df35e8..86a891f93fc9dc70939088e70080af874343f4b4 100644 (file)
@@ -489,8 +489,6 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
        ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
        ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
        ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
-       ATH_ALLOC_BANK(ah->addac5416_21,
-                      ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
        ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
 
        return 0;
@@ -519,7 +517,6 @@ static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah)
        ATH_FREE_BANK(ah->analogBank6Data);
        ATH_FREE_BANK(ah->analogBank6TPCData);
        ATH_FREE_BANK(ah->analogBank7Data);
-       ATH_FREE_BANK(ah->addac5416_21);
        ATH_FREE_BANK(ah->bank6Temp);
 
 #undef ATH_FREE_BANK
@@ -805,27 +802,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
        if (ah->eep_ops->set_addac)
                ah->eep_ops->set_addac(ah, chan);
 
-       if (AR_SREV_5416_22_OR_LATER(ah)) {
-               REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
-       } else {
-               struct ar5416IniArray temp;
-               u32 addacSize =
-                       sizeof(u32) * ah->iniAddac.ia_rows *
-                       ah->iniAddac.ia_columns;
-
-               /* For AR5416 2.0/2.1 */
-               memcpy(ah->addac5416_21,
-                      ah->iniAddac.ia_array, addacSize);
-
-               /* override CLKDRV value at [row, column] = [31, 1] */
-               (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
-
-               temp.ia_array = ah->addac5416_21;
-               temp.ia_columns = ah->iniAddac.ia_columns;
-               temp.ia_rows = ah->iniAddac.ia_rows;
-               REG_WRITE_ARRAY(&temp, 1, regWrites);
-       }
-
+       REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
        REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
 
        ENABLE_REGWRITE_BUFFER(ah);
index e8bdc75405f15df52bb84297916bd3b447a916d0..ea4a230997acc7c34c3e944a9ddf4d8c9e65f914 100644 (file)
@@ -459,97 +459,6 @@ static const u32 ar5416Common_9100[][2] = {
        {0x0000a3e0, 0x000001ce},
 };
 
-static const u32 ar5416Bank0_9100[][2] = {
-       /* Addr      allmodes  */
-       {0x000098b0, 0x1e5795e5},
-       {0x000098e0, 0x02008020},
-};
-
-static const u32 ar5416BB_RfGain_9100[][3] = {
-       /* Addr      5G_HT20     5G_HT40   */
-       {0x00009a00, 0x00000000, 0x00000000},
-       {0x00009a04, 0x00000040, 0x00000040},
-       {0x00009a08, 0x00000080, 0x00000080},
-       {0x00009a0c, 0x000001a1, 0x00000141},
-       {0x00009a10, 0x000001e1, 0x00000181},
-       {0x00009a14, 0x00000021, 0x000001c1},
-       {0x00009a18, 0x00000061, 0x00000001},
-       {0x00009a1c, 0x00000168, 0x00000041},
-       {0x00009a20, 0x000001a8, 0x000001a8},
-       {0x00009a24, 0x000001e8, 0x000001e8},
-       {0x00009a28, 0x00000028, 0x00000028},
-       {0x00009a2c, 0x00000068, 0x00000068},
-       {0x00009a30, 0x00000189, 0x000000a8},
-       {0x00009a34, 0x000001c9, 0x00000169},
-       {0x00009a38, 0x00000009, 0x000001a9},
-       {0x00009a3c, 0x00000049, 0x000001e9},
-       {0x00009a40, 0x00000089, 0x00000029},
-       {0x00009a44, 0x00000170, 0x00000069},
-       {0x00009a48, 0x000001b0, 0x00000190},
-       {0x00009a4c, 0x000001f0, 0x000001d0},
-       {0x00009a50, 0x00000030, 0x00000010},
-       {0x00009a54, 0x00000070, 0x00000050},
-       {0x00009a58, 0x00000191, 0x00000090},
-       {0x00009a5c, 0x000001d1, 0x00000151},
-       {0x00009a60, 0x00000011, 0x00000191},
-       {0x00009a64, 0x00000051, 0x000001d1},
-       {0x00009a68, 0x00000091, 0x00000011},
-       {0x00009a6c, 0x000001b8, 0x00000051},
-       {0x00009a70, 0x000001f8, 0x00000198},
-       {0x00009a74, 0x00000038, 0x000001d8},
-       {0x00009a78, 0x00000078, 0x00000018},
-       {0x00009a7c, 0x00000199, 0x00000058},
-       {0x00009a80, 0x000001d9, 0x00000098},
-       {0x00009a84, 0x00000019, 0x00000159},
-       {0x00009a88, 0x00000059, 0x00000199},
-       {0x00009a8c, 0x00000099, 0x000001d9},
-       {0x00009a90, 0x000000d9, 0x00000019},
-       {0x00009a94, 0x000000f9, 0x00000059},
-       {0x00009a98, 0x000000f9, 0x00000099},
-       {0x00009a9c, 0x000000f9, 0x000000d9},
-       {0x00009aa0, 0x000000f9, 0x000000f9},
-       {0x00009aa4, 0x000000f9, 0x000000f9},
-       {0x00009aa8, 0x000000f9, 0x000000f9},
-       {0x00009aac, 0x000000f9, 0x000000f9},
-       {0x00009ab0, 0x000000f9, 0x000000f9},
-       {0x00009ab4, 0x000000f9, 0x000000f9},
-       {0x00009ab8, 0x000000f9, 0x000000f9},
-       {0x00009abc, 0x000000f9, 0x000000f9},
-       {0x00009ac0, 0x000000f9, 0x000000f9},
-       {0x00009ac4, 0x000000f9, 0x000000f9},
-       {0x00009ac8, 0x000000f9, 0x000000f9},
-       {0x00009acc, 0x000000f9, 0x000000f9},
-       {0x00009ad0, 0x000000f9, 0x000000f9},
-       {0x00009ad4, 0x000000f9, 0x000000f9},
-       {0x00009ad8, 0x000000f9, 0x000000f9},
-       {0x00009adc, 0x000000f9, 0x000000f9},
-       {0x00009ae0, 0x000000f9, 0x000000f9},
-       {0x00009ae4, 0x000000f9, 0x000000f9},
-       {0x00009ae8, 0x000000f9, 0x000000f9},
-       {0x00009aec, 0x000000f9, 0x000000f9},
-       {0x00009af0, 0x000000f9, 0x000000f9},
-       {0x00009af4, 0x000000f9, 0x000000f9},
-       {0x00009af8, 0x000000f9, 0x000000f9},
-       {0x00009afc, 0x000000f9, 0x000000f9},
-};
-
-static const u32 ar5416Bank1_9100[][2] = {
-       /* Addr      allmodes  */
-       {0x000098b0, 0x02108421},
-       {0x000098ec, 0x00000008},
-};
-
-static const u32 ar5416Bank2_9100[][2] = {
-       /* Addr      allmodes  */
-       {0x000098b0, 0x0e73ff17},
-       {0x000098e0, 0x00000420},
-};
-
-static const u32 ar5416Bank3_9100[][3] = {
-       /* Addr      5G_HT20     5G_HT40   */
-       {0x000098f0, 0x01400018, 0x01c00018},
-};
-
 static const u32 ar5416Bank6_9100[][3] = {
        /* Addr      5G_HT20     5G_HT40   */
        {0x0000989c, 0x00000000, 0x00000000},
@@ -624,13 +533,6 @@ static const u32 ar5416Bank6TPC_9100[][3] = {
        {0x000098d0, 0x0000000f, 0x0010000f},
 };
 
-static const u32 ar5416Bank7_9100[][2] = {
-       /* Addr      allmodes  */
-       {0x0000989c, 0x00000500},
-       {0x0000989c, 0x00000800},
-       {0x000098cc, 0x0000000e},
-};
-
 static const u32 ar5416Addac_9100[][2] = {
        /* Addr      allmodes  */
        {0x0000989c, 0x00000000},
@@ -1113,178 +1015,6 @@ static const u32 ar5416Common_9160[][2] = {
        {0x0000a3e0, 0x000001ce},
 };
 
-static const u32 ar5416Bank0_9160[][2] = {
-       /* Addr      allmodes  */
-       {0x000098b0, 0x1e5795e5},
-       {0x000098e0, 0x02008020},
-};
-
-static const u32 ar5416BB_RfGain_9160[][3] = {
-       /* Addr      5G_HT20     5G_HT40   */
-       {0x00009a00, 0x00000000, 0x00000000},
-       {0x00009a04, 0x00000040, 0x00000040},
-       {0x00009a08, 0x00000080, 0x00000080},
-       {0x00009a0c, 0x000001a1, 0x00000141},
-       {0x00009a10, 0x000001e1, 0x00000181},
-       {0x00009a14, 0x00000021, 0x000001c1},
-       {0x00009a18, 0x00000061, 0x00000001},
-       {0x00009a1c, 0x00000168, 0x00000041},
-       {0x00009a20, 0x000001a8, 0x000001a8},
-       {0x00009a24, 0x000001e8, 0x000001e8},
-       {0x00009a28, 0x00000028, 0x00000028},
-       {0x00009a2c, 0x00000068, 0x00000068},
-       {0x00009a30, 0x00000189, 0x000000a8},
-       {0x00009a34, 0x000001c9, 0x00000169},
-       {0x00009a38, 0x00000009, 0x000001a9},
-       {0x00009a3c, 0x00000049, 0x000001e9},
-       {0x00009a40, 0x00000089, 0x00000029},
-       {0x00009a44, 0x00000170, 0x00000069},
-       {0x00009a48, 0x000001b0, 0x00000190},
-       {0x00009a4c, 0x000001f0, 0x000001d0},
-       {0x00009a50, 0x00000030, 0x00000010},
-       {0x00009a54, 0x00000070, 0x00000050},
-       {0x00009a58, 0x00000191, 0x00000090},
-       {0x00009a5c, 0x000001d1, 0x00000151},
-       {0x00009a60, 0x00000011, 0x00000191},
-       {0x00009a64, 0x00000051, 0x000001d1},
-       {0x00009a68, 0x00000091, 0x00000011},
-       {0x00009a6c, 0x000001b8, 0x00000051},
-       {0x00009a70, 0x000001f8, 0x00000198},
-       {0x00009a74, 0x00000038, 0x000001d8},
-       {0x00009a78, 0x00000078, 0x00000018},
-       {0x00009a7c, 0x00000199, 0x00000058},
-       {0x00009a80, 0x000001d9, 0x00000098},
-       {0x00009a84, 0x00000019, 0x00000159},
-       {0x00009a88, 0x00000059, 0x00000199},
-       {0x00009a8c, 0x00000099, 0x000001d9},
-       {0x00009a90, 0x000000d9, 0x00000019},
-       {0x00009a94, 0x000000f9, 0x00000059},
-       {0x00009a98, 0x000000f9, 0x00000099},
-       {0x00009a9c, 0x000000f9, 0x000000d9},
-       {0x00009aa0, 0x000000f9, 0x000000f9},
-       {0x00009aa4, 0x000000f9, 0x000000f9},
-       {0x00009aa8, 0x000000f9, 0x000000f9},
-       {0x00009aac, 0x000000f9, 0x000000f9},
-       {0x00009ab0, 0x000000f9, 0x000000f9},
-       {0x00009ab4, 0x000000f9, 0x000000f9},
-       {0x00009ab8, 0x000000f9, 0x000000f9},
-       {0x00009abc, 0x000000f9, 0x000000f9},
-       {0x00009ac0, 0x000000f9, 0x000000f9},
-       {0x00009ac4, 0x000000f9, 0x000000f9},
-       {0x00009ac8, 0x000000f9, 0x000000f9},
-       {0x00009acc, 0x000000f9, 0x000000f9},
-       {0x00009ad0, 0x000000f9, 0x000000f9},
-       {0x00009ad4, 0x000000f9, 0x000000f9},
-       {0x00009ad8, 0x000000f9, 0x000000f9},
-       {0x00009adc, 0x000000f9, 0x000000f9},
-       {0x00009ae0, 0x000000f9, 0x000000f9},
-       {0x00009ae4, 0x000000f9, 0x000000f9},
-       {0x00009ae8, 0x000000f9, 0x000000f9},
-       {0x00009aec, 0x000000f9, 0x000000f9},
-       {0x00009af0, 0x000000f9, 0x000000f9},
-       {0x00009af4, 0x000000f9, 0x000000f9},
-       {0x00009af8, 0x000000f9, 0x000000f9},
-       {0x00009afc, 0x000000f9, 0x000000f9},
-};
-
-static const u32 ar5416Bank1_9160[][2] = {
-       /* Addr      allmodes  */
-       {0x000098b0, 0x02108421},
-       {0x000098ec, 0x00000008},
-};
-
-static const u32 ar5416Bank2_9160[][2] = {
-       /* Addr      allmodes  */
-       {0x000098b0, 0x0e73ff17},
-       {0x000098e0, 0x00000420},
-};
-
-static const u32 ar5416Bank3_9160[][3] = {
-       /* Addr      5G_HT20     5G_HT40   */
-       {0x000098f0, 0x01400018, 0x01c00018},
-};
-
-static const u32 ar5416Bank6_9160[][3] = {
-       /* Addr      5G_HT20     5G_HT40   */
-       {0x0000989c, 0x00000000, 0x00000000},
-       {0x0000989c, 0x00000000, 0x00000000},
-       {0x0000989c, 0x00000000, 0x00000000},
-       {0x0000989c, 0x00e00000, 0x00e00000},
-       {0x0000989c, 0x005e0000, 0x005e0000},
-       {0x0000989c, 0x00120000, 0x00120000},
-       {0x0000989c, 0x00620000, 0x00620000},
-       {0x0000989c, 0x00020000, 0x00020000},
-       {0x0000989c, 0x00ff0000, 0x00ff0000},
-       {0x0000989c, 0x00ff0000, 0x00ff0000},
-       {0x0000989c, 0x00ff0000, 0x00ff0000},
-       {0x0000989c, 0x40ff0000, 0x40ff0000},
-       {0x0000989c, 0x005f0000, 0x005f0000},
-       {0x0000989c, 0x00870000, 0x00870000},
-       {0x0000989c, 0x00f90000, 0x00f90000},
-       {0x0000989c, 0x007b0000, 0x007b0000},
-       {0x0000989c, 0x00ff0000, 0x00ff0000},
-       {0x0000989c, 0x00f50000, 0x00f50000},
-       {0x0000989c, 0x00dc0000, 0x00dc0000},
-       {0x0000989c, 0x00110000, 0x00110000},
-       {0x0000989c, 0x006100a8, 0x006100a8},
-       {0x0000989c, 0x004210a2, 0x004210a2},
-       {0x0000989c, 0x0014008f, 0x0014008f},
-       {0x0000989c, 0x00c40003, 0x00c40003},
-       {0x0000989c, 0x003000f2, 0x003000f2},
-       {0x0000989c, 0x00440016, 0x00440016},
-       {0x0000989c, 0x00410040, 0x00410040},
-       {0x0000989c, 0x0001805e, 0x0001805e},
-       {0x0000989c, 0x0000c0ab, 0x0000c0ab},
-       {0x0000989c, 0x000000f1, 0x000000f1},
-       {0x0000989c, 0x00002081, 0x00002081},
-       {0x0000989c, 0x000000d4, 0x000000d4},
-       {0x000098d0, 0x0000000f, 0x0010000f},
-};
-
-static const u32 ar5416Bank6TPC_9160[][3] = {
-       /* Addr      5G_HT20     5G_HT40   */
-       {0x0000989c, 0x00000000, 0x00000000},
-       {0x0000989c, 0x00000000, 0x00000000},
-       {0x0000989c, 0x00000000, 0x00000000},
-       {0x0000989c, 0x00e00000, 0x00e00000},
-       {0x0000989c, 0x005e0000, 0x005e0000},
-       {0x0000989c, 0x00120000, 0x00120000},
-       {0x0000989c, 0x00620000, 0x00620000},
-       {0x0000989c, 0x00020000, 0x00020000},
-       {0x0000989c, 0x00ff0000, 0x00ff0000},
-       {0x0000989c, 0x00ff0000, 0x00ff0000},
-       {0x0000989c, 0x00ff0000, 0x00ff0000},
-       {0x0000989c, 0x40ff0000, 0x40ff0000},
-       {0x0000989c, 0x005f0000, 0x005f0000},
-       {0x0000989c, 0x00870000, 0x00870000},
-       {0x0000989c, 0x00f90000, 0x00f90000},
-       {0x0000989c, 0x007b0000, 0x007b0000},
-       {0x0000989c, 0x00ff0000, 0x00ff0000},
-       {0x0000989c, 0x00f50000, 0x00f50000},
-       {0x0000989c, 0x00dc0000, 0x00dc0000},
-       {0x0000989c, 0x00110000, 0x00110000},
-       {0x0000989c, 0x006100a8, 0x006100a8},
-       {0x0000989c, 0x00423022, 0x00423022},
-       {0x0000989c, 0x2014008f, 0x2014008f},
-       {0x0000989c, 0x00c40002, 0x00c40002},
-       {0x0000989c, 0x003000f2, 0x003000f2},
-       {0x0000989c, 0x00440016, 0x00440016},
-       {0x0000989c, 0x00410040, 0x00410040},
-       {0x0000989c, 0x0001805e, 0x0001805e},
-       {0x0000989c, 0x0000c0ab, 0x0000c0ab},
-       {0x0000989c, 0x000000e1, 0x000000e1},
-       {0x0000989c, 0x00007080, 0x00007080},
-       {0x0000989c, 0x000000d4, 0x000000d4},
-       {0x000098d0, 0x0000000f, 0x0010000f},
-};
-
-static const u32 ar5416Bank7_9160[][2] = {
-       /* Addr      allmodes  */
-       {0x0000989c, 0x00000500},
-       {0x0000989c, 0x00000800},
-       {0x000098cc, 0x0000000e},
-};
-
 static const u32 ar5416Addac_9160[][2] = {
        /* Addr      allmodes  */
        {0x0000989c, 0x00000000},
index 11f192a1ceb72d332ccde32cf98f0ef7c3ff41c3..e3f268900763a02374440717ba4490c2ebdca7c1 100644 (file)
@@ -35,11 +35,11 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
                INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
                               ARRAY_SIZE(ar9271Common_9271), 2);
                INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
-                              ar9271Common_normal_cck_fir_coeff_9271,
-                              ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
+                              ar9287Common_normal_cck_fir_coeff_9287_1_1,
+                              ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1), 2);
                INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
-                              ar9271Common_japan_2484_cck_fir_coeff_9271,
-                              ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
+                              ar9287Common_japan_2484_cck_fir_coeff_9287_1_1,
+                              ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1), 2);
                INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
                               ar9271Modes_9271_1_0_only,
                               ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5);
@@ -54,53 +54,31 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
                return;
        }
 
+       if (ah->config.pcie_clock_req)
+               INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                          ar9280PciePhy_clkreq_off_L1_9280,
+                          ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
+       else
+               INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                          ar9280PciePhy_clkreq_always_on_L1_9280,
+                          ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
+
        if (AR_SREV_9287_11_OR_LATER(ah)) {
                INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
                                ARRAY_SIZE(ar9287Modes_9287_1_1), 5);
                INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
                                ARRAY_SIZE(ar9287Common_9287_1_1), 2);
-               if (ah->config.pcie_clock_req)
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9287PciePhy_clkreq_off_L1_9287_1_1,
-                       ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
-               else
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
-                       ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
-                                       2);
        } else if (AR_SREV_9285_12_OR_LATER(ah)) {
-
-
                INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
                               ARRAY_SIZE(ar9285Modes_9285_1_2), 5);
                INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
                               ARRAY_SIZE(ar9285Common_9285_1_2), 2);
-
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_off_L1_9285_1_2,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
-                                 2);
-               }
        } else if (AR_SREV_9280_20_OR_LATER(ah)) {
                INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
                               ARRAY_SIZE(ar9280Modes_9280_2), 5);
                INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
                               ARRAY_SIZE(ar9280Common_9280_2), 2);
 
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                              ar9280PciePhy_clkreq_off_L1_9280,
-                              ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                              ar9280PciePhy_clkreq_always_on_L1_9280,
-                              ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
-               }
                INIT_INI_ARRAY(&ah->iniModesAdditional,
                               ar9280Modes_fast_clock_9280_2,
                               ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
@@ -109,22 +87,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
                               ARRAY_SIZE(ar5416Modes_9160), 5);
                INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
                               ARRAY_SIZE(ar5416Common_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
-                              ARRAY_SIZE(ar5416Bank0_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
-                              ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
-                              ARRAY_SIZE(ar5416Bank1_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
-                              ARRAY_SIZE(ar5416Bank2_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
-                              ARRAY_SIZE(ar5416Bank3_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
-                              ARRAY_SIZE(ar5416Bank6_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
-                              ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
-                              ARRAY_SIZE(ar5416Bank7_9160), 2);
                if (AR_SREV_9160_11(ah)) {
                        INIT_INI_ARRAY(&ah->iniAddac,
                                       ar5416Addac_9160_1_1,
@@ -138,22 +100,8 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
                               ARRAY_SIZE(ar5416Modes_9100), 5);
                INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
                               ARRAY_SIZE(ar5416Common_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
-                              ARRAY_SIZE(ar5416Bank0_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
-                              ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
-                              ARRAY_SIZE(ar5416Bank1_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
-                              ARRAY_SIZE(ar5416Bank2_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
-                              ARRAY_SIZE(ar5416Bank3_9100), 3);
                INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
                               ARRAY_SIZE(ar5416Bank6_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
-                              ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
-                              ARRAY_SIZE(ar5416Bank7_9100), 2);
                INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
                               ARRAY_SIZE(ar5416Addac_9100), 2);
        } else {
@@ -161,24 +109,56 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
                               ARRAY_SIZE(ar5416Modes), 5);
                INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
                               ARRAY_SIZE(ar5416Common), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
-                              ARRAY_SIZE(ar5416Bank0), 2);
+               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
+                              ARRAY_SIZE(ar5416Bank6TPC), 3);
+               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
+                              ARRAY_SIZE(ar5416Addac), 2);
+       }
+
+       if (!AR_SREV_9280_20_OR_LATER(ah)) {
+               /* Common for AR5416, AR913x, AR9160 */
                INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
                               ARRAY_SIZE(ar5416BB_RfGain), 3);
+
+               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
+                              ARRAY_SIZE(ar5416Bank0), 2);
                INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
                               ARRAY_SIZE(ar5416Bank1), 2);
                INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
                               ARRAY_SIZE(ar5416Bank2), 2);
                INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
                               ARRAY_SIZE(ar5416Bank3), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
-                              ARRAY_SIZE(ar5416Bank6), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
-                              ARRAY_SIZE(ar5416Bank6TPC), 3);
                INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
                               ARRAY_SIZE(ar5416Bank7), 2);
-               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
-                              ARRAY_SIZE(ar5416Addac), 2);
+
+               /* Common for AR5416, AR9160 */
+               if (!AR_SREV_9100(ah))
+                       INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
+                                      ARRAY_SIZE(ar5416Bank6), 3);
+
+               /* Common for AR913x, AR9160 */
+               if (!AR_SREV_5416(ah))
+                       INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
+                                      ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
+       }
+
+       /* iniAddac needs to be modified for these chips */
+       if (AR_SREV_9160(ah) || !AR_SREV_5416_22_OR_LATER(ah)) {
+               struct ar5416IniArray *addac = &ah->iniAddac;
+               u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns;
+               u32 *data;
+
+               data = kmalloc(size, GFP_KERNEL);
+               if (!data)
+                       return;
+
+               memcpy(data, addac->ia_array, size);
+               addac->ia_array = data;
+
+               if (!AR_SREV_5416_22_OR_LATER(ah)) {
+                       /* override CLKDRV value */
+                       INI_RA(addac, 31,1) = 0;
+               }
        }
 }
 
index 863db321070d7b31a8c390129ee7e33588a14cef..d571c329ee597c4c32841bd987fc05dafec9fc90 100644 (file)
@@ -925,34 +925,6 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
        {0x00004044, 0x00000000},
 };
 
-static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
-       /* Addr      allmodes  */
-       {0x00004040, 0x9248fd00},
-       {0x00004040, 0x24924924},
-       {0x00004040, 0xa8000019},
-       {0x00004040, 0x13160820},
-       {0x00004040, 0xe5980560},
-       {0x00004040, 0xc01dcffd},
-       {0x00004040, 0x1aaabe41},
-       {0x00004040, 0xbe105554},
-       {0x00004040, 0x00043007},
-       {0x00004044, 0x00000000},
-};
-
-static const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = {
-       /* Addr      allmodes  */
-       {0x00004040, 0x9248fd00},
-       {0x00004040, 0x24924924},
-       {0x00004040, 0xa8000019},
-       {0x00004040, 0x13160820},
-       {0x00004040, 0xe5980560},
-       {0x00004040, 0xc01dcffc},
-       {0x00004040, 0x1aaabe41},
-       {0x00004040, 0xbe105554},
-       {0x00004040, 0x00043007},
-       {0x00004044, 0x00000000},
-};
-
 static const u32 ar9285Modes_9285_1_2[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
@@ -1743,34 +1715,6 @@ static const u32 ar9285Modes_XE2_0_high_power[][5] = {
        {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7},
 };
 
-static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
-       /* Addr      allmodes  */
-       {0x00004040, 0x9248fd00},
-       {0x00004040, 0x24924924},
-       {0x00004040, 0xa8000019},
-       {0x00004040, 0x13160820},
-       {0x00004040, 0xe5980560},
-       {0x00004040, 0xc01dcffd},
-       {0x00004040, 0x1aaabe41},
-       {0x00004040, 0xbe105554},
-       {0x00004040, 0x00043007},
-       {0x00004044, 0x00000000},
-};
-
-static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
-       /* Addr      allmodes  */
-       {0x00004040, 0x9248fd00},
-       {0x00004040, 0x24924924},
-       {0x00004040, 0xa8000019},
-       {0x00004040, 0x13160820},
-       {0x00004040, 0xe5980560},
-       {0x00004040, 0xc01dcffc},
-       {0x00004040, 0x1aaabe41},
-       {0x00004040, 0xbe105554},
-       {0x00004040, 0x00043007},
-       {0x00004044, 0x00000000},
-};
-
 static const u32 ar9287Modes_9287_1_1[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160},
@@ -2512,34 +2456,6 @@ static const u32 ar9287Modes_rx_gain_9287_1_1[][5] = {
        {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067},
 };
 
-static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
-       /* Addr      allmodes  */
-       {0x00004040, 0x9248fd00},
-       {0x00004040, 0x24924924},
-       {0x00004040, 0xa8000019},
-       {0x00004040, 0x13160820},
-       {0x00004040, 0xe5980560},
-       {0x00004040, 0xc01dcffd},
-       {0x00004040, 0x1aaabe41},
-       {0x00004040, 0xbe105554},
-       {0x00004040, 0x00043007},
-       {0x00004044, 0x00000000},
-};
-
-static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
-       /* Addr      allmodes  */
-       {0x00004040, 0x9248fd00},
-       {0x00004040, 0x24924924},
-       {0x00004040, 0xa8000019},
-       {0x00004040, 0x13160820},
-       {0x00004040, 0xe5980560},
-       {0x00004040, 0xc01dcffc},
-       {0x00004040, 0x1aaabe41},
-       {0x00004040, 0xbe105554},
-       {0x00004040, 0x00043007},
-       {0x00004044, 0x00000000},
-};
-
 static const u32 ar9271Modes_9271[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
@@ -3176,20 +3092,6 @@ static const u32 ar9271Common_9271[][2] = {
        {0x0000d384, 0xf3307ff0},
 };
 
-static const u32 ar9271Common_normal_cck_fir_coeff_9271[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a1f4, 0x00fffeff},
-       {0x0000a1f8, 0x00f5f9ff},
-       {0x0000a1fc, 0xb79f6427},
-};
-
-static const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a1f4, 0x00000000},
-       {0x0000a1f8, 0xefff0301},
-       {0x0000a1fc, 0xca9228ee},
-};
-
 static const u32 ar9271Modes_9271_1_0_only[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311},
index 8e70f0bc073e2d12a554428701e67184f538a3c5..63089cc1fafd6366d4209d33e1de28c5b4bd3bb0 100644 (file)
@@ -925,7 +925,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_cal_data *caldata = ah->caldata;
-       struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
        bool txiqcal_done = false, txclcal_done = false;
        bool is_reusable = true, status = true;
        bool run_rtt_cal = false, run_agc_cal;
@@ -998,30 +997,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
        } else if (caldata && !caldata->done_txiqcal_once)
                run_agc_cal = true;
 
-       if (mci && IS_CHAN_2GHZ(chan) &&
-           (mci_hw->bt_state  == MCI_BT_AWAKE) &&
-           run_agc_cal &&
-           !(mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL)) {
-
-               u32 pld[4] = {0, 0, 0, 0};
-
-               /* send CAL_REQ only when BT is AWAKE. */
-               ath_dbg(common, MCI, "MCI send WLAN_CAL_REQ 0x%x\n",
-                       mci_hw->wlan_cal_seq);
-               MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_REQ);
-               pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_seq++;
-               ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
-
-               /* Wait BT_CAL_GRANT for 50ms */
-               ath_dbg(common, MCI, "MCI wait for BT_CAL_GRANT\n");
-
-               if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000))
-                       ath_dbg(common, MCI, "MCI got BT_CAL_GRANT\n");
-               else {
-                       is_reusable = false;
-                       ath_dbg(common, MCI, "\nMCI BT is not responding\n");
-               }
-       }
+       if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal)
+               ar9003_mci_init_cal_req(ah, &is_reusable);
 
        txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
        REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
@@ -1041,19 +1018,8 @@ skip_tx_iqcal:
                                       0, AH_WAIT_TIMEOUT);
        }
 
-       if (mci && IS_CHAN_2GHZ(chan) &&
-           (mci_hw->bt_state  == MCI_BT_AWAKE) &&
-           run_agc_cal &&
-           !(mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL)) {
-
-               u32 pld[4] = {0, 0, 0, 0};
-
-               ath_dbg(common, MCI, "MCI Send WLAN_CAL_DONE 0x%x\n",
-                       mci_hw->wlan_cal_done);
-               MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_DONE);
-               pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_done++;
-               ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
-       }
+       if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal)
+               ar9003_mci_init_cal_done(ah);
 
        if (rtt && !run_rtt_cal) {
                agc_ctrl |= agc_supp_cals;
index 9fbcbddea1658ece3080bc286eec0e8a353ee583..6bb4db052bb0b23aef5d50a607fcafdca9c20a16 100644 (file)
@@ -3603,10 +3603,6 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
        u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
 
        if (AR_SREV_9462(ah)) {
-               if (AR_SREV_9462_10(ah)) {
-                       value &= ~AR_SWITCH_TABLE_COM_SPDT;
-                       value |= 0x00100000;
-               }
                REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
                                AR_SWITCH_TABLE_COM_AR9462_ALL, value);
        } else
index fb937ba93e0c6a763dc82b476917bfc9c0d9409f..7b4aa000cc2ecdb3df3931b96e04dfe4f0597713 100644 (file)
@@ -22,7 +22,6 @@
 #include "ar9330_1p1_initvals.h"
 #include "ar9330_1p2_initvals.h"
 #include "ar9580_1p0_initvals.h"
-#include "ar9462_1p0_initvals.h"
 #include "ar9462_2p0_initvals.h"
 
 /* General hardware code for the AR9003 hadware family */
@@ -264,63 +263,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                                ar9485_1_1_pcie_phy_clkreq_disable_L1,
                                ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
                                2);
-       } else if (AR_SREV_9462_10(ah)) {
-               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
-               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_1p0_mac_core,
-                               ARRAY_SIZE(ar9462_1p0_mac_core), 2);
-               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-                               ar9462_1p0_mac_postamble,
-                               ARRAY_SIZE(ar9462_1p0_mac_postamble),
-                               5);
-
-               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
-               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-                               ar9462_1p0_baseband_core,
-                               ARRAY_SIZE(ar9462_1p0_baseband_core),
-                               2);
-               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-                               ar9462_1p0_baseband_postamble,
-                               ARRAY_SIZE(ar9462_1p0_baseband_postamble), 5);
-
-               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
-               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-                               ar9462_1p0_radio_core,
-                               ARRAY_SIZE(ar9462_1p0_radio_core), 2);
-               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-                               ar9462_1p0_radio_postamble,
-                               ARRAY_SIZE(ar9462_1p0_radio_postamble), 5);
-
-               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-                               ar9462_1p0_soc_preamble,
-                               ARRAY_SIZE(ar9462_1p0_soc_preamble), 2);
-               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
-               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
-                               ar9462_1p0_soc_postamble,
-                               ARRAY_SIZE(ar9462_1p0_soc_postamble), 5);
-
-               INIT_INI_ARRAY(&ah->iniModesRxGain,
-                               ar9462_common_rx_gain_table_1p0,
-                               ARRAY_SIZE(ar9462_common_rx_gain_table_1p0), 2);
-
-               /* Awake -> Sleep Setting */
-               INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9462_pcie_phy_clkreq_disable_L1_1p0,
-                       ARRAY_SIZE(ar9462_pcie_phy_clkreq_disable_L1_1p0),
-                       2);
-
-               /* Sleep -> Awake Setting */
-               INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-                       ar9462_pcie_phy_clkreq_disable_L1_1p0,
-                       ARRAY_SIZE(ar9462_pcie_phy_clkreq_disable_L1_1p0),
-                       2);
-
-               INIT_INI_ARRAY(&ah->iniModesAdditional,
-                               ar9462_modes_fast_clock_1p0,
-                               ARRAY_SIZE(ar9462_modes_fast_clock_1p0), 3);
-               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
-                               AR9462_BB_CTX_COEFJ(1p0),
-                               ARRAY_SIZE(AR9462_BB_CTX_COEFJ(1p0)), 2);
-
        } else if (AR_SREV_9462_20(ah)) {
 
                INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
@@ -537,11 +479,6 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
                        ar9580_1p0_lowest_ob_db_tx_gain_table,
                        ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table),
                        5);
-       else if (AR_SREV_9462_10(ah))
-               INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9462_modes_low_ob_db_tx_gain_table_1p0,
-                       ARRAY_SIZE(ar9462_modes_low_ob_db_tx_gain_table_1p0),
-                       5);
        else if (AR_SREV_9462_20(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                        ar9462_modes_low_ob_db_tx_gain_table_2p0,
@@ -581,11 +518,6 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
                        ar9580_1p0_high_ob_db_tx_gain_table,
                        ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table),
                        5);
-       else if (AR_SREV_9462_10(ah))
-               INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9462_modes_high_ob_db_tx_gain_table_1p0,
-                       ARRAY_SIZE(ar9462_modes_high_ob_db_tx_gain_table_1p0),
-                       5);
        else if (AR_SREV_9462_20(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                        ar9462_modes_high_ob_db_tx_gain_table_2p0,
@@ -712,11 +644,6 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
                                ar9580_1p0_rx_gain_table,
                                ARRAY_SIZE(ar9580_1p0_rx_gain_table),
                                2);
-       else if (AR_SREV_9462_10(ah))
-               INIT_INI_ARRAY(&ah->iniModesRxGain,
-                               ar9462_common_rx_gain_table_1p0,
-                               ARRAY_SIZE(ar9462_common_rx_gain_table_1p0),
-                               2);
        else if (AR_SREV_9462_20(ah))
                INIT_INI_ARRAY(&ah->iniModesRxGain,
                                ar9462_common_rx_gain_table_2p0,
@@ -751,11 +678,6 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
                        ar9485Common_wo_xlna_rx_gain_1_1,
                        ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
                        2);
-       else if (AR_SREV_9462_10(ah))
-               INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9462_common_wo_xlna_rx_gain_table_1p0,
-                       ARRAY_SIZE(ar9462_common_wo_xlna_rx_gain_table_1p0),
-                       2);
        else if (AR_SREV_9462_20(ah))
                INIT_INI_ARRAY(&ah->iniModesRxGain,
                        ar9462_common_wo_xlna_rx_gain_table_2p0,
@@ -775,14 +697,10 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
 
 static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
 {
-       if (AR_SREV_9462_10(ah))
-               INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9462_common_mixed_rx_gain_table_1p0,
-                       ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_1p0), 2);
-       else if (AR_SREV_9462_20(ah))
+       if (AR_SREV_9462_20(ah))
                INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9462_common_mixed_rx_gain_table_2p0,
-                       ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2);
+                              ar9462_common_mixed_rx_gain_table_2p0,
+                              ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2);
 }
 
 static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
index 09b8c9dbf78f5e3267ebfadc2d4bed15f9562487..a66a13b768487746b96c1ebdca96c87df89681f4 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/export.h>
 #include "hw.h"
 #include "ar9003_mac.h"
+#include "ar9003_mci.h"
 
 static void ar9003_hw_rx_enable(struct ath_hw *hw)
 {
@@ -28,11 +29,14 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
        struct ar9003_txc *ads = ds;
        int checksum = 0;
        u32 val, ctl12, ctl17;
+       u8 desc_len;
+
+       desc_len = (AR_SREV_9462(ah) ? 0x18 : 0x17);
 
        val = (ATHEROS_VENDOR_ID << AR_DescId_S) |
              (1 << AR_TxRxDesc_S) |
              (1 << AR_CtrlStat_S) |
-             (i->qcu << AR_TxQcuNum_S) | 0x17;
+             (i->qcu << AR_TxQcuNum_S) | desc_len;
 
        checksum += val;
        ACCESS_ONCE(ads->info) = val;
@@ -81,6 +85,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
        ads->ctl20 = 0;
        ads->ctl21 = 0;
        ads->ctl22 = 0;
+       ads->ctl23 = 0;
 
        ctl17 = SM(i->keytype, AR_EncrType);
        if (!i->is_first) {
@@ -176,7 +181,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
        u32 mask2 = 0;
        struct ath9k_hw_capabilities *pCap = &ah->caps;
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
        u32 sync_cause = 0, async_cause;
 
        async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
@@ -298,32 +302,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
                        ar9003_hw_bb_watchdog_read(ah);
        }
 
-       if (async_cause & AR_INTR_ASYNC_MASK_MCI) {
-               u32 raw_intr, rx_msg_intr;
-
-               rx_msg_intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
-               raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW);
-
-               if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef))
-                       ath_dbg(common, MCI,
-                               "MCI gets 0xdeadbeef during MCI int processing new raw_intr=0x%08x, new rx_msg_raw=0x%08x, raw_intr=0x%08x, rx_msg_raw=0x%08x\n",
-                               raw_intr, rx_msg_intr, mci->raw_intr,
-                               mci->rx_msg_intr);
-               else {
-                       mci->rx_msg_intr |= rx_msg_intr;
-                       mci->raw_intr |= raw_intr;
-                       *masked |= ATH9K_INT_MCI;
-
-                       if (rx_msg_intr & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO)
-                               mci->cont_status =
-                                       REG_READ(ah, AR_MCI_CONT_STATUS);
-
-                       REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr);
-                       REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr);
-                       ath_dbg(common, MCI, "AR_INTR_SYNC_MCI\n");
-
-               }
-       }
+       if (async_cause & AR_INTR_ASYNC_MASK_MCI)
+               ar9003_mci_get_isr(ah, masked);
 
        if (sync_cause) {
                if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
@@ -346,7 +326,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
                                 struct ath_tx_status *ts)
 {
-       struct ar9003_txc *txc = (struct ar9003_txc *) ds;
        struct ar9003_txs *ads;
        u32 status;
 
@@ -356,11 +335,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
        if ((status & AR_TxDone) == 0)
                return -EINPROGRESS;
 
-       ts->qid = MS(ads->ds_info, AR_TxQcuNum);
-       if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid))
-               ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
-       else
-               return -ENOENT;
+       ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
 
        if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
            (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
@@ -374,6 +349,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
        ts->ts_seqnum = MS(status, AR_SeqNum);
        ts->tid = MS(status, AR_TxTid);
 
+       ts->qid = MS(ads->ds_info, AR_TxQcuNum);
        ts->desc_id = MS(ads->status1, AR_TxDescId);
        ts->ts_tstamp = ads->status4;
        ts->ts_status = 0;
@@ -460,20 +436,14 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
        struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
        unsigned int phyerr;
 
-       /* TODO: byte swap on big endian for ar9300_10 */
-
-       if (!rxs) {
-               if ((rxsp->status11 & AR_RxDone) == 0)
-                       return -EINPROGRESS;
-
-               if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
-                       return -EINVAL;
+       if ((rxsp->status11 & AR_RxDone) == 0)
+               return -EINPROGRESS;
 
-               if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
-                       return -EINPROGRESS;
+       if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
+               return -EINVAL;
 
-               return 0;
-       }
+       if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
+               return -EINPROGRESS;
 
        rxs->rs_status = 0;
        rxs->rs_flags =  0;
@@ -530,7 +500,11 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
                 */
                if (rxsp->status11 & AR_CRCErr)
                        rxs->rs_status |= ATH9K_RXERR_CRC;
-               else if (rxsp->status11 & AR_PHYErr) {
+               else if (rxsp->status11 & AR_DecryptCRCErr)
+                       rxs->rs_status |= ATH9K_RXERR_DECRYPT;
+               else if (rxsp->status11 & AR_MichaelErr)
+                       rxs->rs_status |= ATH9K_RXERR_MIC;
+               if (rxsp->status11 & AR_PHYErr) {
                        phyerr = MS(rxsp->status11, AR_PHYErrCode);
                        /*
                         * If we reach a point here where AR_PostDelimCRCErr is
@@ -552,11 +526,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
                                rxs->rs_status |= ATH9K_RXERR_PHY;
                                rxs->rs_phyerr = phyerr;
                        }
-
-               } else if (rxsp->status11 & AR_DecryptCRCErr)
-                       rxs->rs_status |= ATH9K_RXERR_DECRYPT;
-               else if (rxsp->status11 & AR_MichaelErr)
-                       rxs->rs_status |= ATH9K_RXERR_MIC;
+               };
        }
 
        if (rxsp->status11 & AR_KeyMiss)
index e203b51e968bfbee59888697d733a59a5031e742..cbf60b090bd92dc62e3337349765ce7e8e37e68d 100644 (file)
@@ -92,7 +92,8 @@ struct ar9003_txc {
        u32 ctl20;  /* DMA control 20 */
        u32 ctl21;  /* DMA control 21 */
        u32 ctl22;  /* DMA control 22 */
-       u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */
+       u32 ctl23;  /* DMA control 23 */
+       u32 pad[8]; /* pad to cache line (128 bytes/32 dwords) */
 } __packed __aligned(4);
 
 struct ar9003_txs {
index 709520c6835bd62444a8aa1f713fd67264be6985..3cac293a284915c5f53097ac9224742d78557aed 100644 (file)
 
 #include <linux/export.h>
 #include "hw.h"
+#include "hw-ops.h"
 #include "ar9003_phy.h"
 #include "ar9003_mci.h"
 
 static void ar9003_mci_reset_req_wakeup(struct ath_hw *ah)
 {
-       if (!AR_SREV_9462_20(ah))
-               return;
-
        REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
                      AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 1);
        udelay(1);
@@ -37,13 +35,10 @@ static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address,
        struct ath_common *common = ath9k_hw_common(ah);
 
        while (time_out) {
-
                if (REG_READ(ah, address) & bit_position) {
-
                        REG_WRITE(ah, address, bit_position);
 
                        if (address == AR_MCI_INTERRUPT_RX_MSG_RAW) {
-
                                if (bit_position &
                                    AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)
                                        ar9003_mci_reset_req_wakeup(ah);
@@ -81,25 +76,19 @@ static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address,
        return time_out;
 }
 
-void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done)
+static void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done)
 {
        u32 payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};
 
-       if (!ATH9K_HW_CAP_MCI)
-               return;
-
        ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16,
                                wait_done, false);
        udelay(5);
 }
 
-void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done)
+static void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done)
 {
        u32 payload = 0x00000000;
 
-       if (!ATH9K_HW_CAP_MCI)
-               return;
-
        ar9003_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1,
                                wait_done, false);
 }
@@ -111,11 +100,8 @@ static void ar9003_mci_send_req_wake(struct ath_hw *ah, bool wait_done)
        udelay(5);
 }
 
-void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done)
+static void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done)
 {
-       if (!ATH9K_HW_CAP_MCI)
-               return;
-
        ar9003_mci_send_message(ah, MCI_SYS_WAKING, MCI_FLAG_DISABLE_TIMESTAMP,
                                NULL, 0, wait_done, false);
 }
@@ -138,30 +124,27 @@ static void ar9003_mci_send_sys_sleeping(struct ath_hw *ah, bool wait_done)
 static void ar9003_mci_send_coex_version_query(struct ath_hw *ah,
                                               bool wait_done)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
        u32 payload[4] = {0, 0, 0, 0};
 
        if (!mci->bt_version_known &&
-                       (mci->bt_state != MCI_BT_SLEEP)) {
-               ath_dbg(common, MCI, "MCI Send Coex version query\n");
+           (mci->bt_state != MCI_BT_SLEEP)) {
                MCI_GPM_SET_TYPE_OPCODE(payload,
-                               MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_QUERY);
+                                       MCI_GPM_COEX_AGENT,
+                                       MCI_GPM_COEX_VERSION_QUERY);
                ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
-                               wait_done, true);
+                                       wait_done, true);
        }
 }
 
 static void ar9003_mci_send_coex_version_response(struct ath_hw *ah,
-                                                    bool wait_done)
+                                                 bool wait_done)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
        u32 payload[4] = {0, 0, 0, 0};
 
-       ath_dbg(common, MCI, "MCI Send Coex version response\n");
        MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
-                       MCI_GPM_COEX_VERSION_RESPONSE);
+                               MCI_GPM_COEX_VERSION_RESPONSE);
        *(((u8 *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) =
                mci->wlan_ver_major;
        *(((u8 *)payload) + MCI_GPM_COEX_B_MINOR_VERSION) =
@@ -170,15 +153,16 @@ static void ar9003_mci_send_coex_version_response(struct ath_hw *ah,
 }
 
 static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah,
-                                                 bool wait_done)
+                                              bool wait_done)
 {
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
        u32 *payload = &mci->wlan_channels[0];
 
        if ((mci->wlan_channels_update == true) &&
-                       (mci->bt_state != MCI_BT_SLEEP)) {
+           (mci->bt_state != MCI_BT_SLEEP)) {
                MCI_GPM_SET_TYPE_OPCODE(payload,
-               MCI_GPM_COEX_AGENT, MCI_GPM_COEX_WLAN_CHANNELS);
+                                       MCI_GPM_COEX_AGENT,
+                                       MCI_GPM_COEX_WLAN_CHANNELS);
                ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
                                        wait_done, true);
                MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff);
@@ -188,7 +172,6 @@ static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah,
 static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah,
                                                bool wait_done, u8 query_type)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
        u32 payload[4] = {0, 0, 0, 0};
        bool query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO |
@@ -196,25 +179,19 @@ static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah,
 
        if (mci->bt_state != MCI_BT_SLEEP) {
 
-               ath_dbg(common, MCI, "MCI Send Coex BT Status Query 0x%02X\n",
-                       query_type);
-
-               MCI_GPM_SET_TYPE_OPCODE(payload,
-                               MCI_GPM_COEX_AGENT, MCI_GPM_COEX_STATUS_QUERY);
+               MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
+                                       MCI_GPM_COEX_STATUS_QUERY);
 
                *(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type;
+
                /*
                 * If bt_status_query message is  not sent successfully,
                 * then need_flush_btinfo should be set again.
                 */
                if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
                                             wait_done, true)) {
-                       if (query_btinfo) {
+                       if (query_btinfo)
                                mci->need_flush_btinfo = true;
-
-                               ath_dbg(common, MCI,
-                                       "MCI send bt_status_query fail, set flush flag again\n");
-                       }
                }
 
                if (query_btinfo)
@@ -222,21 +199,14 @@ static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah,
        }
 }
 
-void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt,
-                                     bool wait_done)
+static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt,
+                                            bool wait_done)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
        u32 payload[4] = {0, 0, 0, 0};
 
-       if (!ATH9K_HW_CAP_MCI)
-               return;
-
-       ath_dbg(common, MCI, "MCI Send Coex %s BT GPM\n",
-               (halt) ? "halt" : "unhalt");
-
-       MCI_GPM_SET_TYPE_OPCODE(payload,
-                               MCI_GPM_COEX_AGENT, MCI_GPM_COEX_HALT_BT_GPM);
+       MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
+                               MCI_GPM_COEX_HALT_BT_GPM);
 
        if (halt) {
                mci->query_bt = true;
@@ -252,7 +222,6 @@ void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt,
        ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
 }
 
-
 static void ar9003_mci_prep_interface(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
@@ -269,30 +238,14 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah)
        REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
                  REG_READ(ah, AR_MCI_INTERRUPT_RAW));
 
-       /* Remote Reset */
-       ath_dbg(common, MCI, "MCI Reset sequence start\n");
-       ath_dbg(common, MCI, "MCI send REMOTE_RESET\n");
        ar9003_mci_remote_reset(ah, true);
-
-       /*
-        * This delay is required for the reset delay worst case value 255 in
-        * MCI_COMMAND2 register
-        */
-
-       if (AR_SREV_9462_10(ah))
-               udelay(252);
-
-       ath_dbg(common, MCI, "MCI Send REQ_WAKE to remoter(BT)\n");
        ar9003_mci_send_req_wake(ah, true);
 
        if (ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
-                               AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) {
+                                 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) {
 
-               ath_dbg(common, MCI, "MCI SYS_WAKING from remote(BT)\n");
                mci->bt_state = MCI_BT_AWAKE;
 
-               if (AR_SREV_9462_10(ah))
-                       udelay(10);
                /*
                 * we don't need to send more remote_reset at this moment.
                 * If BT receive first remote_reset, then BT HW will
@@ -309,11 +262,6 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah)
                 * Similarly, if in any case, WLAN can receive BT's sys_waking,
                 * that means WLAN's RX is also fine.
                 */
-
-               /* Send SYS_WAKING to BT */
-
-               ath_dbg(common, MCI, "MCI send SW SYS_WAKING to remote BT\n");
-
                ar9003_mci_send_sys_waking(ah, true);
                udelay(10);
 
@@ -321,7 +269,6 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah)
                 * Set BT priority interrupt value to be 0xff to
                 * avoid having too many BT PRIORITY interrupts.
                 */
-
                REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF);
                REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF);
                REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF);
@@ -339,77 +286,70 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah)
                REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
                          AR_MCI_INTERRUPT_BT_PRI);
 
-               if (AR_SREV_9462_10(ah) || mci->is_2g) {
-                       /* Send LNA_TRANS */
-                       ath_dbg(common, MCI, "MCI send LNA_TRANS to BT\n");
+               if (mci->is_2g) {
                        ar9003_mci_send_lna_transfer(ah, true);
                        udelay(5);
                }
 
-               if (AR_SREV_9462_10(ah) || (mci->is_2g &&
-                                           !mci->update_2g5g)) {
+               if ((mci->is_2g && !mci->update_2g5g)) {
                        if (ar9003_mci_wait_for_interrupt(ah,
-                               AR_MCI_INTERRUPT_RX_MSG_RAW,
-                               AR_MCI_INTERRUPT_RX_MSG_LNA_INFO,
-                               mci_timeout))
+                                         AR_MCI_INTERRUPT_RX_MSG_RAW,
+                                         AR_MCI_INTERRUPT_RX_MSG_LNA_INFO,
+                                         mci_timeout))
                                ath_dbg(common, MCI,
                                        "MCI WLAN has control over the LNA & BT obeys it\n");
                        else
                                ath_dbg(common, MCI,
                                        "MCI BT didn't respond to LNA_TRANS\n");
                }
-
-               if (AR_SREV_9462_10(ah)) {
-                       /* Send another remote_reset to deassert BT clk_req. */
-                       ath_dbg(common, MCI,
-                               "MCI another remote_reset to deassert clk_req\n");
-                       ar9003_mci_remote_reset(ah, true);
-                       udelay(252);
-               }
        }
 
        /* Clear the extra redundant SYS_WAKING from BT */
        if ((mci->bt_state == MCI_BT_AWAKE) &&
                (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
                                AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) &&
-               (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
-                               AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) {
-
-                       REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
-                                 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING);
-                       REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
-                                 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
+           (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
+                           AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) {
+               REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
+                         AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING);
+               REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
+                         AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
        }
 
        REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);
 }
 
-void ar9003_mci_disable_interrupt(struct ath_hw *ah)
+void ar9003_mci_set_full_sleep(struct ath_hw *ah)
 {
-       if (!ATH9K_HW_CAP_MCI)
-               return;
+       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
+
+       if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) &&
+           (mci->bt_state != MCI_BT_SLEEP) &&
+           !mci->halted_bt_gpm) {
+               ar9003_mci_send_coex_halt_bt_gpm(ah, true, true);
+       }
+
+       mci->ready = false;
+       REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
+}
 
+static void ar9003_mci_disable_interrupt(struct ath_hw *ah)
+{
        REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
        REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0);
 }
 
-void ar9003_mci_enable_interrupt(struct ath_hw *ah)
+static void ar9003_mci_enable_interrupt(struct ath_hw *ah)
 {
-       if (!ATH9K_HW_CAP_MCI)
-               return;
-
        REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT);
        REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN,
                  AR_MCI_INTERRUPT_RX_MSG_DEFAULT);
 }
 
-bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints)
+static bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints)
 {
        u32 intr;
 
-       if (!ATH9K_HW_CAP_MCI)
-               return false;
-
        intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
        return ((intr & ints) == ints);
 }
@@ -419,9 +359,6 @@ void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
 {
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
 
-       if (!ATH9K_HW_CAP_MCI)
-               return;
-
        *raw_intr = mci->raw_intr;
        *rx_msg_intr = mci->rx_msg_intr;
 
@@ -431,12 +368,34 @@ void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
 }
 EXPORT_SYMBOL(ar9003_mci_get_interrupt);
 
-void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g)
+void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 {
+       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
+       u32 raw_intr, rx_msg_intr;
 
-       if (!ATH9K_HW_CAP_MCI)
-               return;
+       rx_msg_intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
+       raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW);
+
+       if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef)) {
+               ath_dbg(common, MCI,
+                       "MCI gets 0xdeadbeef during int processing\n");
+       } else {
+               mci->rx_msg_intr |= rx_msg_intr;
+               mci->raw_intr |= raw_intr;
+               *masked |= ATH9K_INT_MCI;
+
+               if (rx_msg_intr & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO)
+                       mci->cont_status = REG_READ(ah, AR_MCI_CONT_STATUS);
+
+               REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr);
+               REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr);
+       }
+}
+
+static void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g)
+{
+       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
 
        if (!mci->update_2g5g &&
            (mci->is_2g != is_2g))
@@ -447,7 +406,6 @@ void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g)
 
 static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
        u32 *payload;
        u32 recv_type, offset;
@@ -460,10 +418,8 @@ static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index)
        payload = (u32 *)(mci->gpm_buf + offset);
        recv_type = MCI_GPM_TYPE(payload);
 
-       if (recv_type == MCI_GPM_RSVD_PATTERN) {
-               ath_dbg(common, MCI, "MCI Skip RSVD GPM\n");
+       if (recv_type == MCI_GPM_RSVD_PATTERN)
                return false;
-       }
 
        return true;
 }
@@ -471,42 +427,31 @@ static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index)
 static void ar9003_mci_observation_set_up(struct ath_hw *ah)
 {
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
-       if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MCI) {
 
-               ath9k_hw_cfg_output(ah, 3,
-                                       AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);
+       if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MCI) {
+               ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);
                ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK);
                ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
                ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
-
        } else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_TXRX) {
-
                ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX);
                ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX);
                ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
                ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
                ath9k_hw_cfg_output(ah, 5, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-
        } else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_BT) {
-
                ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
                ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
                ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
                ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
-
        } else
                return;
 
        REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
 
-       if (AR_SREV_9462_20_OR_LATER(ah)) {
-               REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
-                             AR_GLB_DS_JTAG_DISABLE, 1);
-               REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
-                             AR_GLB_WLAN_UART_INTF_EN, 0);
-               REG_SET_BIT(ah, AR_GLB_GPIO_CONTROL,
-                           ATH_MCI_CONFIG_MCI_OBS_GPIO);
-       }
+       REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_GLB_DS_JTAG_DISABLE, 1);
+       REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_GLB_WLAN_UART_INTF_EN, 0);
+       REG_SET_BIT(ah, AR_GLB_GPIO_CONTROL, ATH_MCI_CONFIG_MCI_OBS_GPIO);
 
        REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_GPIO_OBS_SEL, 0);
        REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL, 1);
@@ -520,13 +465,12 @@ static void ar9003_mci_observation_set_up(struct ath_hw *ah)
 }
 
 static bool ar9003_mci_send_coex_bt_flags(struct ath_hw *ah, bool wait_done,
-                                               u8 opcode, u32 bt_flags)
+                                         u8 opcode, u32 bt_flags)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        u32 pld[4] = {0, 0, 0, 0};
 
-       MCI_GPM_SET_TYPE_OPCODE(pld,
-                       MCI_GPM_COEX_AGENT, MCI_GPM_COEX_BT_UPDATE_FLAGS);
+       MCI_GPM_SET_TYPE_OPCODE(pld, MCI_GPM_COEX_AGENT,
+                               MCI_GPM_COEX_BT_UPDATE_FLAGS);
 
        *(((u8 *)pld) + MCI_GPM_COEX_B_BT_FLAGS_OP)  = opcode;
        *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 0) = bt_flags & 0xFF;
@@ -534,222 +478,473 @@ static bool ar9003_mci_send_coex_bt_flags(struct ath_hw *ah, bool wait_done,
        *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) = (bt_flags >> 16) & 0xFF;
        *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) = (bt_flags >> 24) & 0xFF;
 
-       ath_dbg(common, MCI,
-               "MCI BT_MCI_FLAGS: Send Coex BT Update Flags %s 0x%08x\n",
-               opcode == MCI_GPM_COEX_BT_FLAGS_READ ? "READ" :
-               opcode == MCI_GPM_COEX_BT_FLAGS_SET ? "SET" : "CLEAR",
-               bt_flags);
-
        return ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16,
-                                                       wait_done, true);
+                                      wait_done, true);
 }
 
-void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
-                     bool is_full_sleep)
+static void ar9003_mci_sync_bt_state(struct ath_hw *ah)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
-       u32 regval, thresh;
-
-       if (!ATH9K_HW_CAP_MCI)
-               return;
-
-       ath_dbg(common, MCI, "MCI full_sleep = %d, is_2g = %d\n",
-               is_full_sleep, is_2g);
-
-       /*
-        * GPM buffer and scheduling message buffer are not allocated
-        */
-
-       if (!mci->gpm_addr && !mci->sched_addr) {
-               ath_dbg(common, MCI,
-                       "MCI GPM and schedule buffers are not allocated\n");
-               return;
-       }
-
-       if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
-               ath_dbg(common, MCI, "MCI it's deadbeef, quit mci_reset\n");
-               return;
-       }
-
-       /* Program MCI DMA related registers */
-       REG_WRITE(ah, AR_MCI_GPM_0, mci->gpm_addr);
-       REG_WRITE(ah, AR_MCI_GPM_1, mci->gpm_len);
-       REG_WRITE(ah, AR_MCI_SCHD_TABLE_0, mci->sched_addr);
-
-       /*
-       * To avoid MCI state machine be affected by incoming remote MCI msgs,
-       * MCI mode will be enabled later, right before reset the MCI TX and RX.
-       */
-
-       regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
-                SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
-                SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
-                SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
-                SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
-                SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
-                SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
-                SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
-                SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
-
-       if (is_2g && (AR_SREV_9462_20(ah)) &&
-               !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) {
-
-               regval |= SM(1, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
-               ath_dbg(common, MCI, "MCI sched one step look ahead\n");
-
-               if (!(mci->config &
-                     ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) {
-
-                       thresh = MS(mci->config,
-                                   ATH_MCI_CONFIG_AGGR_THRESH);
-                       thresh &= 7;
-                       regval |= SM(1,
-                                    AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN);
-                       regval |= SM(thresh, AR_BTCOEX_CTRL_AGGR_THRESH);
-
-                       REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2,
-                                     AR_MCI_SCHD_TABLE_2_HW_BASED, 1);
-                       REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2,
-                                     AR_MCI_SCHD_TABLE_2_MEM_BASED, 1);
-
-               } else
-                       ath_dbg(common, MCI, "MCI sched aggr thresh: off\n");
-       } else
-               ath_dbg(common, MCI, "MCI SCHED one step look ahead off\n");
-
-       if (AR_SREV_9462_10(ah))
-               regval |= SM(1, AR_BTCOEX_CTRL_SPDT_ENABLE_10);
-
-       REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
-
-       if (AR_SREV_9462_20(ah)) {
-               REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
-                           AR_BTCOEX_CTRL_SPDT_ENABLE);
-               REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3,
-                             AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20);
-       }
-
-       REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 1);
-       REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
+       u32 cur_bt_state;
 
-       thresh = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV);
-       REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, thresh);
-       REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN);
+       cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL);
 
-       /* Resetting the Rx and Tx paths of MCI */
-       regval = REG_READ(ah, AR_MCI_COMMAND2);
-       regval |= SM(1, AR_MCI_COMMAND2_RESET_TX);
-       REG_WRITE(ah, AR_MCI_COMMAND2, regval);
+       if (mci->bt_state != cur_bt_state)
+               mci->bt_state = cur_bt_state;
 
-       udelay(1);
+       if (mci->bt_state != MCI_BT_SLEEP) {
 
-       regval &= ~SM(1, AR_MCI_COMMAND2_RESET_TX);
-       REG_WRITE(ah, AR_MCI_COMMAND2, regval);
+               ar9003_mci_send_coex_version_query(ah, true);
+               ar9003_mci_send_coex_wlan_channels(ah, true);
 
-       if (is_full_sleep) {
-               ar9003_mci_mute_bt(ah);
-               udelay(100);
+               if (mci->unhalt_bt_gpm == true)
+                       ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
        }
-
-       regval |= SM(1, AR_MCI_COMMAND2_RESET_RX);
-       REG_WRITE(ah, AR_MCI_COMMAND2, regval);
-       udelay(1);
-       regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
-       REG_WRITE(ah, AR_MCI_COMMAND2, regval);
-
-       ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
-       REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
-                 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
-                  SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM)));
-
-       REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
-                       AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
-
-       if (AR_SREV_9462_20_OR_LATER(ah))
-               ar9003_mci_observation_set_up(ah);
-
-       mci->ready = true;
-       ar9003_mci_prep_interface(ah);
-
-       if (en_int)
-               ar9003_mci_enable_interrupt(ah);
 }
 
-void ar9003_mci_mute_bt(struct ath_hw *ah)
+void ar9003_mci_check_bt(struct ath_hw *ah)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
 
-       if (!ATH9K_HW_CAP_MCI)
+       if (!mci_hw->ready)
                return;
 
-       /* disable all MCI messages */
-       REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000);
-       REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff);
-       REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff);
-       REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff);
-       REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff);
-       REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
-
-       /* wait pending HW messages to flush out */
-       udelay(10);
-
        /*
-        * Send LNA_TAKE and SYS_SLEEPING when
-        * 1. reset not after resuming from full sleep
-        * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
+        * check BT state again to make
+        * sure it's not changed.
         */
+       ar9003_mci_sync_bt_state(ah);
+       ar9003_mci_2g5g_switch(ah, true);
 
-       ath_dbg(common, MCI, "MCI Send LNA take\n");
-       ar9003_mci_send_lna_take(ah, true);
-
-       udelay(5);
-
-       ath_dbg(common, MCI, "MCI Send sys sleeping\n");
-       ar9003_mci_send_sys_sleeping(ah, true);
+       if ((mci_hw->bt_state == MCI_BT_AWAKE) &&
+           (mci_hw->query_bt == true)) {
+               mci_hw->need_flush_btinfo = true;
+       }
 }
 
-void ar9003_mci_sync_bt_state(struct ath_hw *ah)
+static void ar9003_mci_process_gpm_extra(struct ath_hw *ah, u8 gpm_type,
+                                        u8 gpm_opcode, u32 *p_gpm)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
-       u32 cur_bt_state;
+       u8 *p_data = (u8 *) p_gpm;
 
-       if (!ATH9K_HW_CAP_MCI)
+       if (gpm_type != MCI_GPM_COEX_AGENT)
                return;
 
-       cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL);
-
-       if (mci->bt_state != cur_bt_state) {
+       switch (gpm_opcode) {
+       case MCI_GPM_COEX_VERSION_QUERY:
+               ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n");
+               ar9003_mci_send_coex_version_response(ah, true);
+               break;
+       case MCI_GPM_COEX_VERSION_RESPONSE:
+               ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n");
+               mci->bt_ver_major =
+                       *(p_data + MCI_GPM_COEX_B_MAJOR_VERSION);
+               mci->bt_ver_minor =
+                       *(p_data + MCI_GPM_COEX_B_MINOR_VERSION);
+               mci->bt_version_known = true;
+               ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n",
+                       mci->bt_ver_major, mci->bt_ver_minor);
+               break;
+       case MCI_GPM_COEX_STATUS_QUERY:
                ath_dbg(common, MCI,
-                       "MCI BT state mismatches. old: %d, new: %d\n",
-                       mci->bt_state, cur_bt_state);
-               mci->bt_state = cur_bt_state;
-       }
-
-       if (mci->bt_state != MCI_BT_SLEEP) {
-
-               ar9003_mci_send_coex_version_query(ah, true);
+                       "MCI Recv GPM COEX Status Query = 0x%02X\n",
+                       *(p_data + MCI_GPM_COEX_B_WLAN_BITMAP));
+               mci->wlan_channels_update = true;
                ar9003_mci_send_coex_wlan_channels(ah, true);
-
-               if (mci->unhalt_bt_gpm == true) {
-                       ath_dbg(common, MCI, "MCI unhalt BT GPM\n");
-                       ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
-               }
+               break;
+       case MCI_GPM_COEX_BT_PROFILE_INFO:
+               mci->query_bt = true;
+               ath_dbg(common, MCI, "MCI Recv GPM COEX BT_Profile_Info\n");
+               break;
+       case MCI_GPM_COEX_BT_STATUS_UPDATE:
+               mci->query_bt = true;
+               ath_dbg(common, MCI,
+                       "MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n",
+                       *(p_gpm + 3));
+               break;
+       default:
+               break;
        }
 }
 
-static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done)
+static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
+                                  u8 gpm_opcode, int time_out)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
-       u32 new_flags, to_set, to_clear;
+       u32 *p_gpm = NULL, mismatch = 0, more_data;
+       u32 offset;
+       u8 recv_type = 0, recv_opcode = 0;
+       bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE);
 
-       if (AR_SREV_9462_20(ah) &&
-           mci->update_2g5g &&
-           (mci->bt_state != MCI_BT_SLEEP)) {
+       more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE;
 
-               if (mci->is_2g) {
+       while (time_out > 0) {
+               if (p_gpm) {
+                       MCI_GPM_RECYCLE(p_gpm);
+                       p_gpm = NULL;
+               }
+
+               if (more_data != MCI_GPM_MORE)
+                       time_out = ar9003_mci_wait_for_interrupt(ah,
+                                       AR_MCI_INTERRUPT_RX_MSG_RAW,
+                                       AR_MCI_INTERRUPT_RX_MSG_GPM,
+                                       time_out);
+
+               if (!time_out)
+                       break;
+
+               offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
+                                         &more_data);
+
+               if (offset == MCI_GPM_INVALID)
+                       continue;
+
+               p_gpm = (u32 *) (mci->gpm_buf + offset);
+               recv_type = MCI_GPM_TYPE(p_gpm);
+               recv_opcode = MCI_GPM_OPCODE(p_gpm);
+
+               if (MCI_GPM_IS_CAL_TYPE(recv_type)) {
+                       if (recv_type == gpm_type) {
+                               if ((gpm_type == MCI_GPM_BT_CAL_DONE) &&
+                                   !b_is_bt_cal_done) {
+                                       gpm_type = MCI_GPM_BT_CAL_GRANT;
+                                       continue;
+                               }
+                               break;
+                       }
+               } else if ((recv_type == gpm_type) && (recv_opcode == gpm_opcode)) {
+                       break;
+               }
+
+               /*
+                * check if it's cal_grant
+                *
+                * When we're waiting for cal_grant in reset routine,
+                * it's possible that BT sends out cal_request at the
+                * same time. Since BT's calibration doesn't happen
+                * that often, we'll let BT completes calibration then
+                * we continue to wait for cal_grant from BT.
+                * Orginal: Wait BT_CAL_GRANT.
+                * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait
+                * BT_CAL_DONE -> Wait BT_CAL_GRANT.
+                */
+
+               if ((gpm_type == MCI_GPM_BT_CAL_GRANT) &&
+                   (recv_type == MCI_GPM_BT_CAL_REQ)) {
+
+                       u32 payload[4] = {0, 0, 0, 0};
+
+                       gpm_type = MCI_GPM_BT_CAL_DONE;
+                       MCI_GPM_SET_CAL_TYPE(payload,
+                                            MCI_GPM_WLAN_CAL_GRANT);
+                       ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
+                                               false, false);
+                       continue;
+               } else {
+                       ath_dbg(common, MCI, "MCI GPM subtype not match 0x%x\n",
+                               *(p_gpm + 1));
+                       mismatch++;
+                       ar9003_mci_process_gpm_extra(ah, recv_type,
+                                                    recv_opcode, p_gpm);
+               }
+       }
+
+       if (p_gpm) {
+               MCI_GPM_RECYCLE(p_gpm);
+               p_gpm = NULL;
+       }
+
+       if (time_out <= 0)
+               time_out = 0;
+
+       while (more_data == MCI_GPM_MORE) {
+               offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
+                                         &more_data);
+               if (offset == MCI_GPM_INVALID)
+                       break;
+
+               p_gpm = (u32 *) (mci->gpm_buf + offset);
+               recv_type = MCI_GPM_TYPE(p_gpm);
+               recv_opcode = MCI_GPM_OPCODE(p_gpm);
+
+               if (!MCI_GPM_IS_CAL_TYPE(recv_type))
+                       ar9003_mci_process_gpm_extra(ah, recv_type,
+                                                    recv_opcode, p_gpm);
+
+               MCI_GPM_RECYCLE(p_gpm);
+       }
+
+       return time_out;
+}
+
+bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
+       u32 payload[4] = {0, 0, 0, 0};
+
+       ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan));
+
+       if (mci_hw->bt_state != MCI_BT_CAL_START)
+               return false;
+
+       mci_hw->bt_state = MCI_BT_CAL;
+
+       /*
+        * MCI FIX: disable mci interrupt here. This is to avoid
+        * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
+        * lead to mci_intr reentry.
+        */
+       ar9003_mci_disable_interrupt(ah);
+
+       MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
+       ar9003_mci_send_message(ah, MCI_GPM, 0, payload,
+                               16, true, false);
+
+       /* Wait BT calibration to be completed for 25ms */
+
+       if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE,
+                                   0, 25000))
+               ath_dbg(common, MCI, "MCI BT_CAL_DONE received\n");
+       else
+               ath_dbg(common, MCI,
+                       "MCI BT_CAL_DONE not received\n");
+
+       mci_hw->bt_state = MCI_BT_AWAKE;
+       /* MCI FIX: enable mci interrupt here */
+       ar9003_mci_enable_interrupt(ah);
+
+       return true;
+}
+
+int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+                        struct ath9k_hw_cal_data *caldata)
+{
+       struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
+
+       if (!mci_hw->ready)
+               return 0;
+
+       if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP))
+               goto exit;
+
+       if (ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
+           ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) {
+
+               /*
+                * BT is sleeping. Check if BT wakes up during
+                * WLAN calibration. If BT wakes up during
+                * WLAN calibration, need to go through all
+                * message exchanges again and recal.
+                */
+               REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
+                         AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
+                         AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
+
+               ar9003_mci_remote_reset(ah, true);
+               ar9003_mci_send_sys_waking(ah, true);
+               udelay(1);
+
+               if (IS_CHAN_2GHZ(chan))
+                       ar9003_mci_send_lna_transfer(ah, true);
+
+               mci_hw->bt_state = MCI_BT_AWAKE;
+
+               if (caldata) {
+                       caldata->done_txiqcal_once = false;
+                       caldata->done_txclcal_once = false;
+                       caldata->rtt_hist.num_readings = 0;
+               }
+
+               if (!ath9k_hw_init_cal(ah, chan))
+                       return -EIO;
+
+       }
+exit:
+       ar9003_mci_enable_interrupt(ah);
+       return 0;
+}
+
+static void ar9003_mci_mute_bt(struct ath_hw *ah)
+{
+       /* disable all MCI messages */
+       REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000);
+       REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff);
+       REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff);
+       REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff);
+       REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff);
+       REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
+
+       /* wait pending HW messages to flush out */
+       udelay(10);
+
+       /*
+        * Send LNA_TAKE and SYS_SLEEPING when
+        * 1. reset not after resuming from full sleep
+        * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
+        */
+       ar9003_mci_send_lna_take(ah, true);
+
+       udelay(5);
+
+       ar9003_mci_send_sys_sleeping(ah, true);
+}
+
+static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable)
+{
+       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
+       u32 thresh;
+
+       if (enable) {
+               REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2,
+                             AR_MCI_SCHD_TABLE_2_HW_BASED, 1);
+               REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2,
+                             AR_MCI_SCHD_TABLE_2_MEM_BASED, 1);
+
+               if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) {
+                       thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH);
+                       REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
+                                     AR_BTCOEX_CTRL_AGGR_THRESH, thresh);
+                       REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
+                                     AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1);
+               } else {
+                       REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
+                                     AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0);
+               }
+
+               REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
+                             AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);
+       } else {
+               REG_CLR_BIT(ah, AR_BTCOEX_CTRL,
+                           AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
+       }
+}
+
+void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
+                     bool is_full_sleep)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
+       u32 regval;
+
+       ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n",
+               is_full_sleep, is_2g);
+
+       if (!mci->gpm_addr && !mci->sched_addr) {
+               ath_dbg(common, MCI,
+                       "MCI GPM and schedule buffers are not allocated\n");
+               return;
+       }
+
+       if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
+               ath_dbg(common, MCI, "BTCOEX control register is dead\n");
+               return;
+       }
+
+       /* Program MCI DMA related registers */
+       REG_WRITE(ah, AR_MCI_GPM_0, mci->gpm_addr);
+       REG_WRITE(ah, AR_MCI_GPM_1, mci->gpm_len);
+       REG_WRITE(ah, AR_MCI_SCHD_TABLE_0, mci->sched_addr);
+
+       /*
+       * To avoid MCI state machine be affected by incoming remote MCI msgs,
+       * MCI mode will be enabled later, right before reset the MCI TX and RX.
+       */
+
+       regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
+                SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
+                SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
+                SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
+                SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
+                SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
+                SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
+                SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
+                SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
+
+       REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
+
+       if (is_2g && !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA))
+               ar9003_mci_osla_setup(ah, true);
+       else
+               ar9003_mci_osla_setup(ah, false);
+
+       REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
+                   AR_BTCOEX_CTRL_SPDT_ENABLE);
+       REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3,
+                     AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20);
+
+       REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 1);
+       REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
+
+       regval = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV);
+       REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval);
+       REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN);
+
+       /* Resetting the Rx and Tx paths of MCI */
+       regval = REG_READ(ah, AR_MCI_COMMAND2);
+       regval |= SM(1, AR_MCI_COMMAND2_RESET_TX);
+       REG_WRITE(ah, AR_MCI_COMMAND2, regval);
+
+       udelay(1);
+
+       regval &= ~SM(1, AR_MCI_COMMAND2_RESET_TX);
+       REG_WRITE(ah, AR_MCI_COMMAND2, regval);
+
+       if (is_full_sleep) {
+               ar9003_mci_mute_bt(ah);
+               udelay(100);
+       }
+
+       regval |= SM(1, AR_MCI_COMMAND2_RESET_RX);
+       REG_WRITE(ah, AR_MCI_COMMAND2, regval);
+       udelay(1);
+       regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
+       REG_WRITE(ah, AR_MCI_COMMAND2, regval);
+
+       ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
+
+       REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
+                 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
+                  SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM)));
+
+       REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
+                   AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
+
+       ar9003_mci_observation_set_up(ah);
+
+       mci->ready = true;
+       ar9003_mci_prep_interface(ah);
+
+       if (en_int)
+               ar9003_mci_enable_interrupt(ah);
+}
+
+void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep)
+{
+       struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
+
+       ar9003_mci_disable_interrupt(ah);
+
+       if (mci_hw->ready && !save_fullsleep) {
+               ar9003_mci_mute_bt(ah);
+               udelay(20);
+               REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
+       }
+
+       mci_hw->bt_state = MCI_BT_SLEEP;
+       mci_hw->ready = false;
+}
+
+static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done)
+{
+       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
+       u32 new_flags, to_set, to_clear;
+
+       if (mci->update_2g5g && (mci->bt_state != MCI_BT_SLEEP)) {
+               if (mci->is_2g) {
                        new_flags = MCI_2G_FLAGS;
                        to_clear = MCI_2G_FLAGS_CLEAR_MASK;
                        to_set = MCI_2G_FLAGS_SET_MASK;
@@ -759,44 +954,23 @@ static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done)
                        to_set = MCI_5G_FLAGS_SET_MASK;
                }
 
-               ath_dbg(common, MCI,
-                       "MCI BT_MCI_FLAGS: %s 0x%08x clr=0x%08x, set=0x%08x\n",
-               mci->is_2g ? "2G" : "5G", new_flags, to_clear, to_set);
-
                if (to_clear)
                        ar9003_mci_send_coex_bt_flags(ah, wait_done,
-                                       MCI_GPM_COEX_BT_FLAGS_CLEAR, to_clear);
-
+                                             MCI_GPM_COEX_BT_FLAGS_CLEAR,
+                                             to_clear);
                if (to_set)
                        ar9003_mci_send_coex_bt_flags(ah, wait_done,
-                                       MCI_GPM_COEX_BT_FLAGS_SET, to_set);
+                                             MCI_GPM_COEX_BT_FLAGS_SET,
+                                             to_set);
        }
-
-       if (AR_SREV_9462_10(ah) && (mci->bt_state != MCI_BT_SLEEP))
-               mci->update_2g5g = false;
 }
 
 static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header,
                                        u32 *payload, bool queue)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
        u8 type, opcode;
 
-       if (queue) {
-
-               if (payload)
-                       ath_dbg(common, MCI,
-                               "MCI ERROR: Send fail: %02x: %02x %02x %02x\n",
-                               header,
-                               *(((u8 *)payload) + 4),
-                               *(((u8 *)payload) + 5),
-                               *(((u8 *)payload) + 6));
-               else
-                       ath_dbg(common, MCI, "MCI ERROR: Send fail: %02x\n",
-                               header);
-       }
-
        /* check if the message is to be queued */
        if (header != MCI_GPM)
                return;
@@ -809,64 +983,29 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header,
 
        switch (opcode) {
        case MCI_GPM_COEX_BT_UPDATE_FLAGS:
-
-               if (AR_SREV_9462_10(ah))
-                       break;
-
                if (*(((u8 *)payload) + MCI_GPM_COEX_B_BT_FLAGS_OP) ==
-                               MCI_GPM_COEX_BT_FLAGS_READ)
+                   MCI_GPM_COEX_BT_FLAGS_READ)
                        break;
 
                mci->update_2g5g = queue;
 
-               if (queue)
-                       ath_dbg(common, MCI,
-                               "MCI BT_MCI_FLAGS: 2G5G status <queued> %s\n",
-                               mci->is_2g ? "2G" : "5G");
-               else
-                       ath_dbg(common, MCI,
-                               "MCI BT_MCI_FLAGS: 2G5G status <sent> %s\n",
-                               mci->is_2g ? "2G" : "5G");
-
                break;
-
        case MCI_GPM_COEX_WLAN_CHANNELS:
-
                mci->wlan_channels_update = queue;
-               if (queue)
-                       ath_dbg(common, MCI, "MCI WLAN channel map <queued>\n");
-               else
-                       ath_dbg(common, MCI, "MCI WLAN channel map <sent>\n");
                break;
-
        case MCI_GPM_COEX_HALT_BT_GPM:
-
                if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
-                               MCI_GPM_COEX_BT_GPM_UNHALT) {
-
+                   MCI_GPM_COEX_BT_GPM_UNHALT) {
                        mci->unhalt_bt_gpm = queue;
 
-                       if (queue)
-                               ath_dbg(common, MCI,
-                                       "MCI UNHALT BT GPM <queued>\n");
-                       else {
+                       if (!queue)
                                mci->halted_bt_gpm = false;
-                               ath_dbg(common, MCI,
-                                       "MCI UNHALT BT GPM <sent>\n");
-                       }
                }
 
                if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
                                MCI_GPM_COEX_BT_GPM_HALT) {
 
                        mci->halted_bt_gpm = !queue;
-
-                       if (queue)
-                               ath_dbg(common, MCI,
-                                       "MCI HALT BT GPM <not sent>\n");
-                       else
-                               ath_dbg(common, MCI,
-                                       "MCI UNHALT BT GPM <sent>\n");
                }
 
                break;
@@ -877,46 +1016,33 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header,
 
 void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
 
-       if (!ATH9K_HW_CAP_MCI)
-               return;
-
        if (mci->update_2g5g) {
                if (mci->is_2g) {
-
                        ar9003_mci_send_2g5g_status(ah, true);
-                       ath_dbg(common, MCI, "MCI Send LNA trans\n");
                        ar9003_mci_send_lna_transfer(ah, true);
                        udelay(5);
 
                        REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
                                    AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
+                       REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL,
+                                   AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
 
-                       if (AR_SREV_9462_20(ah)) {
-                               REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL,
-                                           AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
-                               if (!(mci->config &
-                                     ATH_MCI_CONFIG_DISABLE_OSLA)) {
-                                       REG_SET_BIT(ah, AR_BTCOEX_CTRL,
-                                       AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
-                               }
+                       if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) {
+                               REG_SET_BIT(ah, AR_BTCOEX_CTRL,
+                                           AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
                        }
                } else {
-                       ath_dbg(common, MCI, "MCI Send LNA take\n");
                        ar9003_mci_send_lna_take(ah, true);
                        udelay(5);
 
                        REG_SET_BIT(ah, AR_MCI_TX_CTRL,
                                    AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
-
-                       if (AR_SREV_9462_20(ah)) {
-                               REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
-                                           AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
-                               REG_CLR_BIT(ah, AR_BTCOEX_CTRL,
-                                       AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
-                       }
+                       REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
+                                   AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
+                       REG_CLR_BIT(ah, AR_BTCOEX_CTRL,
+                                   AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
 
                        ar9003_mci_send_2g5g_status(ah, true);
                }
@@ -934,28 +1060,19 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
        u32 saved_mci_int_en;
        int i;
 
-       if (!ATH9K_HW_CAP_MCI)
-               return false;
-
        saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN);
        regval = REG_READ(ah, AR_BTCOEX_CTRL);
 
        if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) {
-
                ath_dbg(common, MCI,
                        "MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n",
-                       header,
-                       (ah->power_mode == ATH9K_PM_FULL_SLEEP) ? 1 : 0);
-
+                       header, (ah->power_mode == ATH9K_PM_FULL_SLEEP) ? 1 : 0);
                ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
                return false;
-
        } else if (check_bt && (mci->bt_state == MCI_BT_SLEEP)) {
-
                ath_dbg(common, MCI,
                        "MCI Don't send message 0x%x. BT is in sleep state\n",
                        header);
-
                ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
                return false;
        }
@@ -983,7 +1100,7 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
 
        if (wait_done &&
            !(ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RAW,
-                                       AR_MCI_INTERRUPT_SW_MSG_DONE, 500)))
+                                           AR_MCI_INTERRUPT_SW_MSG_DONE, 500)))
                ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
        else {
                ar9003_mci_queue_unsent_gpm(ah, header, payload, false);
@@ -997,220 +1114,64 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
 }
 EXPORT_SYMBOL(ar9003_mci_send_message);
 
-void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
-                     u16 len, u32 sched_addr)
+void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable)
 {
-       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
-       void *sched_buf = (void *)((char *) gpm_buf + (sched_addr - gpm_addr));
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
+       u32 pld[4] = {0, 0, 0, 0};
 
-       if (!ATH9K_HW_CAP_MCI)
+       if ((mci_hw->bt_state != MCI_BT_AWAKE) ||
+           (mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL))
                return;
 
-       mci->gpm_addr = gpm_addr;
-       mci->gpm_buf = gpm_buf;
-       mci->gpm_len = len;
-       mci->sched_addr = sched_addr;
-       mci->sched_buf = sched_buf;
+       MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_REQ);
+       pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_seq++;
 
-       ar9003_mci_reset(ah, true, true, true);
+       ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
+
+       if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) {
+               ath_dbg(common, MCI, "MCI BT_CAL_GRANT received\n");
+       } else {
+               is_reusable = false;
+               ath_dbg(common, MCI, "MCI BT_CAL_GRANT not received\n");
+       }
 }
-EXPORT_SYMBOL(ar9003_mci_setup);
 
-void ar9003_mci_cleanup(struct ath_hw *ah)
+void ar9003_mci_init_cal_done(struct ath_hw *ah)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
+       u32 pld[4] = {0, 0, 0, 0};
 
-       if (!ATH9K_HW_CAP_MCI)
+       if ((mci_hw->bt_state != MCI_BT_AWAKE) ||
+           (mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL))
                return;
 
-       /* Turn off MCI and Jupiter mode. */
-       REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00);
-       ath_dbg(common, MCI, "MCI ar9003_mci_cleanup\n");
-       ar9003_mci_disable_interrupt(ah);
+       MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_DONE);
+       pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_done++;
+       ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
 }
-EXPORT_SYMBOL(ar9003_mci_cleanup);
 
-static void ar9003_mci_process_gpm_extra(struct ath_hw *ah, u8 gpm_type,
-                                        u8 gpm_opcode, u32 *p_gpm)
+void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
+                     u16 len, u32 sched_addr)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
-       u8 *p_data = (u8 *) p_gpm;
 
-       if (gpm_type != MCI_GPM_COEX_AGENT)
-               return;
+       mci->gpm_addr = gpm_addr;
+       mci->gpm_buf = gpm_buf;
+       mci->gpm_len = len;
+       mci->sched_addr = sched_addr;
 
-       switch (gpm_opcode) {
-       case MCI_GPM_COEX_VERSION_QUERY:
-               ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n");
-               ar9003_mci_send_coex_version_response(ah, true);
-               break;
-       case MCI_GPM_COEX_VERSION_RESPONSE:
-               ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n");
-               mci->bt_ver_major =
-                       *(p_data + MCI_GPM_COEX_B_MAJOR_VERSION);
-               mci->bt_ver_minor =
-                       *(p_data + MCI_GPM_COEX_B_MINOR_VERSION);
-               mci->bt_version_known = true;
-               ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n",
-                       mci->bt_ver_major, mci->bt_ver_minor);
-               break;
-       case MCI_GPM_COEX_STATUS_QUERY:
-               ath_dbg(common, MCI,
-                       "MCI Recv GPM COEX Status Query = 0x%02X\n",
-                       *(p_data + MCI_GPM_COEX_B_WLAN_BITMAP));
-               mci->wlan_channels_update = true;
-               ar9003_mci_send_coex_wlan_channels(ah, true);
-               break;
-       case MCI_GPM_COEX_BT_PROFILE_INFO:
-               mci->query_bt = true;
-               ath_dbg(common, MCI, "MCI Recv GPM COEX BT_Profile_Info\n");
-               break;
-       case MCI_GPM_COEX_BT_STATUS_UPDATE:
-               mci->query_bt = true;
-               ath_dbg(common, MCI,
-                       "MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n",
-                       *(p_gpm + 3));
-               break;
-       default:
-               break;
-       }
+       ar9003_mci_reset(ah, true, true, true);
 }
+EXPORT_SYMBOL(ar9003_mci_setup);
 
-u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
-                           u8 gpm_opcode, int time_out)
+void ar9003_mci_cleanup(struct ath_hw *ah)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
-       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
-       u32 *p_gpm = NULL, mismatch = 0, more_data;
-       u32 offset;
-       u8 recv_type = 0, recv_opcode = 0;
-       bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE);
-
-       if (!ATH9K_HW_CAP_MCI)
-               return 0;
-
-       more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE;
-
-       while (time_out > 0) {
-               if (p_gpm) {
-                       MCI_GPM_RECYCLE(p_gpm);
-                       p_gpm = NULL;
-               }
-
-               if (more_data != MCI_GPM_MORE)
-                       time_out = ar9003_mci_wait_for_interrupt(ah,
-                                       AR_MCI_INTERRUPT_RX_MSG_RAW,
-                                       AR_MCI_INTERRUPT_RX_MSG_GPM,
-                                       time_out);
-
-               if (!time_out)
-                       break;
-
-               offset = ar9003_mci_state(ah,
-                               MCI_STATE_NEXT_GPM_OFFSET, &more_data);
-
-               if (offset == MCI_GPM_INVALID)
-                       continue;
-
-               p_gpm = (u32 *) (mci->gpm_buf + offset);
-               recv_type = MCI_GPM_TYPE(p_gpm);
-               recv_opcode = MCI_GPM_OPCODE(p_gpm);
-
-               if (MCI_GPM_IS_CAL_TYPE(recv_type)) {
-
-                       if (recv_type == gpm_type) {
-
-                               if ((gpm_type == MCI_GPM_BT_CAL_DONE) &&
-                                   !b_is_bt_cal_done) {
-                                       gpm_type = MCI_GPM_BT_CAL_GRANT;
-                                       ath_dbg(common, MCI,
-                                               "MCI Recv BT_CAL_DONE wait BT_CAL_GRANT\n");
-                                       continue;
-                               }
-
-                               break;
-                       }
-               } else if ((recv_type == gpm_type) &&
-                          (recv_opcode == gpm_opcode))
-                       break;
-
-               /* not expected message */
-
-               /*
-                * check if it's cal_grant
-                *
-                * When we're waiting for cal_grant in reset routine,
-                * it's possible that BT sends out cal_request at the
-                * same time. Since BT's calibration doesn't happen
-                * that often, we'll let BT completes calibration then
-                * we continue to wait for cal_grant from BT.
-                * Orginal: Wait BT_CAL_GRANT.
-                * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait
-                * BT_CAL_DONE -> Wait BT_CAL_GRANT.
-                */
-
-               if ((gpm_type == MCI_GPM_BT_CAL_GRANT) &&
-                   (recv_type == MCI_GPM_BT_CAL_REQ)) {
-
-                       u32 payload[4] = {0, 0, 0, 0};
-
-                       gpm_type = MCI_GPM_BT_CAL_DONE;
-                       ath_dbg(common, MCI,
-                               "MCI Rcv BT_CAL_REQ, send WLAN_CAL_GRANT\n");
-
-                       MCI_GPM_SET_CAL_TYPE(payload,
-                                       MCI_GPM_WLAN_CAL_GRANT);
-
-                       ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
-                                               false, false);
-
-                       ath_dbg(common, MCI, "MCI now wait for BT_CAL_DONE\n");
-
-                       continue;
-               } else {
-                       ath_dbg(common, MCI, "MCI GPM subtype not match 0x%x\n",
-                               *(p_gpm + 1));
-                       mismatch++;
-                       ar9003_mci_process_gpm_extra(ah, recv_type,
-                                       recv_opcode, p_gpm);
-               }
-       }
-       if (p_gpm) {
-               MCI_GPM_RECYCLE(p_gpm);
-               p_gpm = NULL;
-       }
-
-       if (time_out <= 0) {
-               time_out = 0;
-               ath_dbg(common, MCI,
-                       "MCI GPM received timeout, mismatch = %d\n", mismatch);
-       } else
-               ath_dbg(common, MCI, "MCI Receive GPM type=0x%x, code=0x%x\n",
-                       gpm_type, gpm_opcode);
-
-       while (more_data == MCI_GPM_MORE) {
-
-               ath_dbg(common, MCI, "MCI discard remaining GPM\n");
-               offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
-                                         &more_data);
-
-               if (offset == MCI_GPM_INVALID)
-                       break;
-
-               p_gpm = (u32 *) (mci->gpm_buf + offset);
-               recv_type = MCI_GPM_TYPE(p_gpm);
-               recv_opcode = MCI_GPM_OPCODE(p_gpm);
-
-               if (!MCI_GPM_IS_CAL_TYPE(recv_type))
-                       ar9003_mci_process_gpm_extra(ah, recv_type,
-                                                    recv_opcode, p_gpm);
-
-               MCI_GPM_RECYCLE(p_gpm);
-       }
-
-       return time_out;
+       /* Turn off MCI and Jupiter mode. */
+       REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00);
+       ar9003_mci_disable_interrupt(ah);
 }
+EXPORT_SYMBOL(ar9003_mci_cleanup);
 
 u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
 {
@@ -1219,13 +1180,9 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
        u32 value = 0, more_gpm = 0, gpm_ptr;
        u8 query_type;
 
-       if (!ATH9K_HW_CAP_MCI)
-               return 0;
-
        switch (state_type) {
        case MCI_STATE_ENABLE:
                if (mci->ready) {
-
                        value = REG_READ(ah, AR_BTCOEX_CTRL);
 
                        if ((value == 0xdeadbeef) || (value == 0xffffffff))
@@ -1235,7 +1192,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
                break;
        case MCI_STATE_INIT_GPM_OFFSET:
                value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
-               ath_dbg(common, MCI, "MCI GPM initial WRITE_PTR=%d\n", value);
                mci->gpm_idx = value;
                break;
        case MCI_STATE_NEXT_GPM_OFFSET:
@@ -1258,32 +1214,21 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
                if (value == 0)
                        value = mci->gpm_len - 1;
                else if (value >= mci->gpm_len) {
-                       if (value != 0xFFFF) {
+                       if (value != 0xFFFF)
                                value = 0;
-                               ath_dbg(common, MCI,
-                                       "MCI GPM offset out of range\n");
-                       }
-               } else
+               } else {
                        value--;
+               }
 
                if (value == 0xFFFF) {
                        value = MCI_GPM_INVALID;
                        more_gpm = MCI_GPM_NOMORE;
-                       ath_dbg(common, MCI,
-                               "MCI GPM ptr invalid @ptr=%d, offset=%d, more=GPM_NOMORE\n",
-                               gpm_ptr, value);
                } else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) {
-
                        if (gpm_ptr == mci->gpm_idx) {
                                value = MCI_GPM_INVALID;
                                more_gpm = MCI_GPM_NOMORE;
-
-                               ath_dbg(common, MCI,
-                                       "MCI GPM message not available @ptr=%d, @offset=%d, more=GPM_NOMORE\n",
-                                       gpm_ptr, value);
                        } else {
                                for (;;) {
-
                                        u32 temp_index;
 
                                        /* skip reserved GPM if any */
@@ -1300,13 +1245,8 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
                                            mci->gpm_len)
                                                mci->gpm_idx = 0;
 
-                                       ath_dbg(common, MCI,
-                                               "MCI GPM message got ptr=%d, @offset=%d, more=%d\n",
-                                               gpm_ptr, temp_index,
-                                               (more_gpm == MCI_GPM_MORE));
-
                                        if (ar9003_mci_is_gpm_valid(ah,
-                                                               temp_index)) {
+                                                                   temp_index)) {
                                                value = temp_index;
                                                break;
                                        }
@@ -1331,79 +1271,59 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
                /* Make it in bytes */
                value <<= 4;
                break;
-
        case MCI_STATE_REMOTE_SLEEP:
                value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
                           AR_MCI_RX_REMOTE_SLEEP) ?
                        MCI_BT_SLEEP : MCI_BT_AWAKE;
                break;
-
        case MCI_STATE_CONT_RSSI_POWER:
                value = MS(mci->cont_status, AR_MCI_CONT_RSSI_POWER);
-                       break;
-
+               break;
        case MCI_STATE_CONT_PRIORITY:
                value = MS(mci->cont_status, AR_MCI_CONT_RRIORITY);
                break;
-
        case MCI_STATE_CONT_TXRX:
                value = MS(mci->cont_status, AR_MCI_CONT_TXRX);
                break;
-
        case MCI_STATE_BT:
                value = mci->bt_state;
                break;
-
        case MCI_STATE_SET_BT_SLEEP:
                mci->bt_state = MCI_BT_SLEEP;
                break;
-
        case MCI_STATE_SET_BT_AWAKE:
                mci->bt_state = MCI_BT_AWAKE;
                ar9003_mci_send_coex_version_query(ah, true);
                ar9003_mci_send_coex_wlan_channels(ah, true);
 
-               if (mci->unhalt_bt_gpm) {
-
-                       ath_dbg(common, MCI, "MCI unhalt BT GPM\n");
+               if (mci->unhalt_bt_gpm)
                        ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
-               }
 
                ar9003_mci_2g5g_switch(ah, true);
                break;
-
        case MCI_STATE_SET_BT_CAL_START:
                mci->bt_state = MCI_BT_CAL_START;
                break;
-
        case MCI_STATE_SET_BT_CAL:
                mci->bt_state = MCI_BT_CAL;
                break;
-
        case MCI_STATE_RESET_REQ_WAKE:
                ar9003_mci_reset_req_wakeup(ah);
                mci->update_2g5g = true;
 
-               if ((AR_SREV_9462_20_OR_LATER(ah)) &&
-                   (mci->config & ATH_MCI_CONFIG_MCI_OBS_MASK)) {
+               if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MASK) {
                        /* Check if we still have control of the GPIOs */
                        if ((REG_READ(ah, AR_GLB_GPIO_CONTROL) &
-                                     ATH_MCI_CONFIG_MCI_OBS_GPIO) !=
-                                       ATH_MCI_CONFIG_MCI_OBS_GPIO) {
-
-                               ath_dbg(common, MCI,
-                                       "MCI reconfigure observation\n");
+                            ATH_MCI_CONFIG_MCI_OBS_GPIO) !=
+                           ATH_MCI_CONFIG_MCI_OBS_GPIO) {
                                ar9003_mci_observation_set_up(ah);
                        }
                }
                break;
-
        case MCI_STATE_SEND_WLAN_COEX_VERSION:
                ar9003_mci_send_coex_version_response(ah, true);
                break;
-
        case MCI_STATE_SET_BT_COEX_VERSION:
-
                if (!p_data)
                        ath_dbg(common, MCI,
                                "MCI Set BT Coex version with NULL data!!\n");
@@ -1415,7 +1335,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
                                mci->bt_ver_major, mci->bt_ver_minor);
                }
                break;
-
        case MCI_STATE_SEND_WLAN_CHANNELS:
                if (p_data) {
                        if (((mci->wlan_channels[1] & 0xffff0000) ==
@@ -1432,19 +1351,13 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
                mci->wlan_channels_update = true;
                ar9003_mci_send_coex_wlan_channels(ah, true);
                break;
-
        case MCI_STATE_SEND_VERSION_QUERY:
                ar9003_mci_send_coex_version_query(ah, true);
                break;
-
        case MCI_STATE_SEND_STATUS_QUERY:
-               query_type = (AR_SREV_9462_10(ah)) ?
-                               MCI_GPM_COEX_QUERY_BT_ALL_INFO :
-                               MCI_GPM_COEX_QUERY_BT_TOPOLOGY;
-
+               query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY;
                ar9003_mci_send_coex_bt_status_query(ah, true, query_type);
                break;
-
        case MCI_STATE_NEED_FLUSH_BT_INFO:
                        /*
                         * btcoex_hw.mci.unhalt_bt_gpm means whether it's
@@ -1464,28 +1377,21 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
                                mci->need_flush_btinfo =
                                        (*p_data != 0) ? true : false;
                        break;
-
        case MCI_STATE_RECOVER_RX:
-
-               ath_dbg(common, MCI, "MCI hw RECOVER_RX\n");
                ar9003_mci_prep_interface(ah);
                mci->query_bt = true;
                mci->need_flush_btinfo = true;
                ar9003_mci_send_coex_wlan_channels(ah, true);
                ar9003_mci_2g5g_switch(ah, true);
                break;
-
        case MCI_STATE_NEED_FTP_STOMP:
                value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP);
                break;
-
        case MCI_STATE_NEED_TUNING:
                value = !(mci->config & ATH_MCI_CONFIG_DISABLE_TUNING);
                break;
-
        default:
                break;
-
        }
 
        return value;
index 798da116a44c4b8f720cd22676e0519f482ce2ef..4842f6c06b8c3bc1640b17c7d90d606997a8b840 100644 (file)
@@ -99,4 +99,237 @@ enum mci_gpm_coex_bt_update_flags_op {
                                         ATH_MCI_CONFIG_MCI_OBS_BT)
 #define ATH_MCI_CONFIG_MCI_OBS_GPIO     0x0000002F
 
+enum mci_message_header {              /* length of payload */
+       MCI_LNA_CTRL     = 0x10,        /* len = 0 */
+       MCI_CONT_NACK    = 0x20,        /* len = 0 */
+       MCI_CONT_INFO    = 0x30,        /* len = 4 */
+       MCI_CONT_RST     = 0x40,        /* len = 0 */
+       MCI_SCHD_INFO    = 0x50,        /* len = 16 */
+       MCI_CPU_INT      = 0x60,        /* len = 4 */
+       MCI_SYS_WAKING   = 0x70,        /* len = 0 */
+       MCI_GPM          = 0x80,        /* len = 16 */
+       MCI_LNA_INFO     = 0x90,        /* len = 1 */
+       MCI_LNA_STATE    = 0x94,
+       MCI_LNA_TAKE     = 0x98,
+       MCI_LNA_TRANS    = 0x9c,
+       MCI_SYS_SLEEPING = 0xa0,        /* len = 0 */
+       MCI_REQ_WAKE     = 0xc0,        /* len = 0 */
+       MCI_DEBUG_16     = 0xfe,        /* len = 2 */
+       MCI_REMOTE_RESET = 0xff         /* len = 16 */
+};
+
+enum ath_mci_gpm_coex_profile_type {
+       MCI_GPM_COEX_PROFILE_UNKNOWN,
+       MCI_GPM_COEX_PROFILE_RFCOMM,
+       MCI_GPM_COEX_PROFILE_A2DP,
+       MCI_GPM_COEX_PROFILE_HID,
+       MCI_GPM_COEX_PROFILE_BNEP,
+       MCI_GPM_COEX_PROFILE_VOICE,
+       MCI_GPM_COEX_PROFILE_MAX
+};
+
+/* MCI GPM/Coex opcode/type definitions */
+enum {
+       MCI_GPM_COEX_W_GPM_PAYLOAD      = 1,
+       MCI_GPM_COEX_B_GPM_TYPE         = 4,
+       MCI_GPM_COEX_B_GPM_OPCODE       = 5,
+       /* MCI_GPM_WLAN_CAL_REQ, MCI_GPM_WLAN_CAL_DONE */
+       MCI_GPM_WLAN_CAL_W_SEQUENCE     = 2,
+
+       /* MCI_GPM_COEX_VERSION_QUERY */
+       /* MCI_GPM_COEX_VERSION_RESPONSE */
+       MCI_GPM_COEX_B_MAJOR_VERSION    = 6,
+       MCI_GPM_COEX_B_MINOR_VERSION    = 7,
+       /* MCI_GPM_COEX_STATUS_QUERY */
+       MCI_GPM_COEX_B_BT_BITMAP        = 6,
+       MCI_GPM_COEX_B_WLAN_BITMAP      = 7,
+       /* MCI_GPM_COEX_HALT_BT_GPM */
+       MCI_GPM_COEX_B_HALT_STATE       = 6,
+       /* MCI_GPM_COEX_WLAN_CHANNELS */
+       MCI_GPM_COEX_B_CHANNEL_MAP      = 6,
+       /* MCI_GPM_COEX_BT_PROFILE_INFO */
+       MCI_GPM_COEX_B_PROFILE_TYPE     = 6,
+       MCI_GPM_COEX_B_PROFILE_LINKID   = 7,
+       MCI_GPM_COEX_B_PROFILE_STATE    = 8,
+       MCI_GPM_COEX_B_PROFILE_ROLE     = 9,
+       MCI_GPM_COEX_B_PROFILE_RATE     = 10,
+       MCI_GPM_COEX_B_PROFILE_VOTYPE   = 11,
+       MCI_GPM_COEX_H_PROFILE_T        = 12,
+       MCI_GPM_COEX_B_PROFILE_W        = 14,
+       MCI_GPM_COEX_B_PROFILE_A        = 15,
+       /* MCI_GPM_COEX_BT_STATUS_UPDATE */
+       MCI_GPM_COEX_B_STATUS_TYPE      = 6,
+       MCI_GPM_COEX_B_STATUS_LINKID    = 7,
+       MCI_GPM_COEX_B_STATUS_STATE     = 8,
+       /* MCI_GPM_COEX_BT_UPDATE_FLAGS */
+       MCI_GPM_COEX_W_BT_FLAGS         = 6,
+       MCI_GPM_COEX_B_BT_FLAGS_OP      = 10
+};
+
+enum mci_gpm_subtype {
+       MCI_GPM_BT_CAL_REQ      = 0,
+       MCI_GPM_BT_CAL_GRANT    = 1,
+       MCI_GPM_BT_CAL_DONE     = 2,
+       MCI_GPM_WLAN_CAL_REQ    = 3,
+       MCI_GPM_WLAN_CAL_GRANT  = 4,
+       MCI_GPM_WLAN_CAL_DONE   = 5,
+       MCI_GPM_COEX_AGENT      = 0x0c,
+       MCI_GPM_RSVD_PATTERN    = 0xfe,
+       MCI_GPM_RSVD_PATTERN32  = 0xfefefefe,
+       MCI_GPM_BT_DEBUG        = 0xff
+};
+
+enum mci_bt_state {
+       MCI_BT_SLEEP,
+       MCI_BT_AWAKE,
+       MCI_BT_CAL_START,
+       MCI_BT_CAL
+};
+
+/* Type of state query */
+enum mci_state_type {
+       MCI_STATE_ENABLE,
+       MCI_STATE_INIT_GPM_OFFSET,
+       MCI_STATE_NEXT_GPM_OFFSET,
+       MCI_STATE_LAST_GPM_OFFSET,
+       MCI_STATE_BT,
+       MCI_STATE_SET_BT_SLEEP,
+       MCI_STATE_SET_BT_AWAKE,
+       MCI_STATE_SET_BT_CAL_START,
+       MCI_STATE_SET_BT_CAL,
+       MCI_STATE_LAST_SCHD_MSG_OFFSET,
+       MCI_STATE_REMOTE_SLEEP,
+       MCI_STATE_CONT_RSSI_POWER,
+       MCI_STATE_CONT_PRIORITY,
+       MCI_STATE_CONT_TXRX,
+       MCI_STATE_RESET_REQ_WAKE,
+       MCI_STATE_SEND_WLAN_COEX_VERSION,
+       MCI_STATE_SET_BT_COEX_VERSION,
+       MCI_STATE_SEND_WLAN_CHANNELS,
+       MCI_STATE_SEND_VERSION_QUERY,
+       MCI_STATE_SEND_STATUS_QUERY,
+       MCI_STATE_NEED_FLUSH_BT_INFO,
+       MCI_STATE_SET_CONCUR_TX_PRI,
+       MCI_STATE_RECOVER_RX,
+       MCI_STATE_NEED_FTP_STOMP,
+       MCI_STATE_NEED_TUNING,
+       MCI_STATE_DEBUG,
+       MCI_STATE_MAX
+};
+
+enum mci_gpm_coex_opcode {
+       MCI_GPM_COEX_VERSION_QUERY,
+       MCI_GPM_COEX_VERSION_RESPONSE,
+       MCI_GPM_COEX_STATUS_QUERY,
+       MCI_GPM_COEX_HALT_BT_GPM,
+       MCI_GPM_COEX_WLAN_CHANNELS,
+       MCI_GPM_COEX_BT_PROFILE_INFO,
+       MCI_GPM_COEX_BT_STATUS_UPDATE,
+       MCI_GPM_COEX_BT_UPDATE_FLAGS
+};
+
+#define MCI_GPM_NOMORE  0
+#define MCI_GPM_MORE    1
+#define MCI_GPM_INVALID 0xffffffff
+
+#define MCI_GPM_RECYCLE(_p_gpm)        do {                      \
+       *(((u32 *)_p_gpm) + MCI_GPM_COEX_W_GPM_PAYLOAD) = \
+                               MCI_GPM_RSVD_PATTERN32;   \
+} while (0)
+
+#define MCI_GPM_TYPE(_p_gpm)   \
+       (*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) & 0xff)
+
+#define MCI_GPM_OPCODE(_p_gpm) \
+       (*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) & 0xff)
+
+#define MCI_GPM_SET_CAL_TYPE(_p_gpm, _cal_type)        do {                       \
+       *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_cal_type) & 0xff;\
+} while (0)
+
+#define MCI_GPM_SET_TYPE_OPCODE(_p_gpm, _type, _opcode) do {              \
+       *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_type) & 0xff;    \
+       *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) = (_opcode) & 0xff;\
+} while (0)
+
+#define MCI_GPM_IS_CAL_TYPE(_type) ((_type) <= MCI_GPM_WLAN_CAL_DONE)
+
+/*
+ * Functions that are available to the MCI driver core.
+ */
+bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
+                            u32 *payload, u8 len, bool wait_done,
+                            bool check_bt);
+u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data);
+void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
+                     u16 len, u32 sched_addr);
+void ar9003_mci_cleanup(struct ath_hw *ah);
+void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
+                             u32 *rx_msg_intr);
+
+/*
+ * These functions are used by ath9k_hw.
+ */
+
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+
+static inline bool ar9003_mci_is_ready(struct ath_hw *ah)
+{
+       return ah->btcoex_hw.mci.ready;
+}
+void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep);
+void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable);
+void ar9003_mci_init_cal_done(struct ath_hw *ah);
+void ar9003_mci_set_full_sleep(struct ath_hw *ah);
+void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done);
+void ar9003_mci_check_bt(struct ath_hw *ah);
+bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan);
+int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+                        struct ath9k_hw_cal_data *caldata);
+void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
+                     bool is_full_sleep);
+void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked);
+
+#else
+
+static inline bool ar9003_mci_is_ready(struct ath_hw *ah)
+{
+       return false;
+}
+static inline void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep)
+{
+}
+static inline void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable)
+{
+}
+static inline void ar9003_mci_init_cal_done(struct ath_hw *ah)
+{
+}
+static inline void ar9003_mci_set_full_sleep(struct ath_hw *ah)
+{
+}
+static inline void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done)
+{
+}
+static inline void ar9003_mci_check_bt(struct ath_hw *ah)
+{
+}
+static inline bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       return false;
+}
+static inline int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+                                      struct ath9k_hw_cal_data *caldata)
+{
+       return 0;
+}
+static inline void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
+                                   bool is_full_sleep)
+{
+}
+static inline void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
+{
+}
+#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
+
 #endif
index 2b0bfb8cca02d023da420b842f058b904807f646..70e27d2a5e43e76d4a59859c6ea26f6c7830c76e 100644 (file)
@@ -1099,13 +1099,20 @@ static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
 {
        ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
        ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
-       if (AR_SREV_9330(ah))
-               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ;
-       else
-               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ;
+       ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ;
        ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
        ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
        ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ;
+
+       if (AR_SREV_9330(ah))
+               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ;
+
+       if (AR_SREV_9462(ah)) {
+               ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ;
+               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9462_2GHZ;
+               ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ;
+               ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9462_5GHZ;
+       }
 }
 
 /*
index ed64114571fcc133dffb3e1279015c51c82b0c27..d834d97fe7276e279402d4e3a75e6e6db1ac983f 100644 (file)
 
 #define AR_PHY_RX_OCGAIN        (AR_AGC_BASE + 0x200)
 
-#define AR_PHY_CCA_NOM_VAL_9300_2GHZ          (AR_SREV_9462(ah) ? -127 : -110)
-#define AR_PHY_CCA_NOM_VAL_9300_5GHZ          (AR_SREV_9462(ah) ? -127 : -115)
-#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ     (AR_SREV_9462(ah) ? -127 : -125)
-#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ     (AR_SREV_9462(ah) ? -127 : -125)
+#define AR_PHY_CCA_NOM_VAL_9300_2GHZ          -110
+#define AR_PHY_CCA_NOM_VAL_9300_5GHZ          -115
+#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ     -125
+#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ     -125
 #define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ     -95
 #define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ     -100
 
+#define AR_PHY_CCA_NOM_VAL_9462_2GHZ          -127
+#define AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ     -127
+#define AR_PHY_CCA_NOM_VAL_9462_5GHZ          -127
+#define AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ     -127
+
 #define AR_PHY_CCA_NOM_VAL_9330_2GHZ          -118
 
 /*
 #define AR_PHY_AIC_CTRL_1_B0   (AR_SM_BASE + 0x4b4)
 #define AR_PHY_AIC_CTRL_2_B0   (AR_SM_BASE + 0x4b8)
 #define AR_PHY_AIC_CTRL_3_B0   (AR_SM_BASE + 0x4bc)
-#define AR_PHY_AIC_STAT_0_B0   (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \
-                                       0x4c0 : 0x4c4))
-#define AR_PHY_AIC_STAT_1_B0   (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \
-                                       0x4c4 : 0x4c8))
+#define AR_PHY_AIC_STAT_0_B0   (AR_SM_BASE + 0x4c4))
+#define AR_PHY_AIC_STAT_1_B0   (AR_SM_BASE + 0x4c8))
 #define AR_PHY_AIC_CTRL_4_B0   (AR_SM_BASE + 0x4c0)
 #define AR_PHY_AIC_STAT_2_B0   (AR_SM_BASE + 0x4cc)
 
 #define AR_PHY_65NM_CH0_SYNTH4      0x1608c
-#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT   0x00000002
-#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S 1
+#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT   (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002)
+#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1)
 #define AR_PHY_65NM_CH0_SYNTH7      0x16098
 #define AR_PHY_65NM_CH0_BIAS1       0x160c0
 #define AR_PHY_65NM_CH0_BIAS2       0x160c4
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_1p0_initvals.h
deleted file mode 100644 (file)
index 5c55ae3..0000000
+++ /dev/null
@@ -1,1833 +0,0 @@
-/*
- * Copyright (c) 2010 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef INITVALS_9462_1P0_H
-#define INITVALS_9462_1P0_H
-
-/* AR9462 1.0 */
-
-static const u32 ar9462_1p0_mac_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00000008, 0x00000000},
-       {0x00000030, 0x00060085},
-       {0x00000034, 0x00000005},
-       {0x00000040, 0x00000000},
-       {0x00000044, 0x00000000},
-       {0x00000048, 0x00000008},
-       {0x0000004c, 0x00000010},
-       {0x00000050, 0x00000000},
-       {0x00001040, 0x002ffc0f},
-       {0x00001044, 0x002ffc0f},
-       {0x00001048, 0x002ffc0f},
-       {0x0000104c, 0x002ffc0f},
-       {0x00001050, 0x002ffc0f},
-       {0x00001054, 0x002ffc0f},
-       {0x00001058, 0x002ffc0f},
-       {0x0000105c, 0x002ffc0f},
-       {0x00001060, 0x002ffc0f},
-       {0x00001064, 0x002ffc0f},
-       {0x000010f0, 0x00000100},
-       {0x00001270, 0x00000000},
-       {0x000012b0, 0x00000000},
-       {0x000012f0, 0x00000000},
-       {0x0000143c, 0x00000000},
-       {0x0000147c, 0x00000000},
-       {0x00001810, 0x0f000003},
-       {0x00008000, 0x00000000},
-       {0x00008004, 0x00000000},
-       {0x00008008, 0x00000000},
-       {0x0000800c, 0x00000000},
-       {0x00008018, 0x00000000},
-       {0x00008020, 0x00000000},
-       {0x00008038, 0x00000000},
-       {0x0000803c, 0x00080000},
-       {0x00008040, 0x00000000},
-       {0x00008044, 0x00000000},
-       {0x00008048, 0x00000000},
-       {0x0000804c, 0xffffffff},
-       {0x00008050, 0xffffffff},
-       {0x00008054, 0x00000000},
-       {0x00008058, 0x00000000},
-       {0x0000805c, 0x000fc78f},
-       {0x00008060, 0x0000000f},
-       {0x00008064, 0x00000000},
-       {0x00008070, 0x00000310},
-       {0x00008074, 0x00000020},
-       {0x00008078, 0x00000000},
-       {0x0000809c, 0x0000000f},
-       {0x000080a0, 0x00000000},
-       {0x000080a4, 0x02ff0000},
-       {0x000080a8, 0x0e070605},
-       {0x000080ac, 0x0000000d},
-       {0x000080b0, 0x00000000},
-       {0x000080b4, 0x00000000},
-       {0x000080b8, 0x00000000},
-       {0x000080bc, 0x00000000},
-       {0x000080c0, 0x2a800000},
-       {0x000080c4, 0x06900168},
-       {0x000080c8, 0x13881c20},
-       {0x000080cc, 0x01f40000},
-       {0x000080d0, 0x00252500},
-       {0x000080d4, 0x00a00005},
-       {0x000080d8, 0x00400002},
-       {0x000080dc, 0x00000000},
-       {0x000080e0, 0xffffffff},
-       {0x000080e4, 0x0000ffff},
-       {0x000080e8, 0x3f3f3f3f},
-       {0x000080ec, 0x00000000},
-       {0x000080f0, 0x00000000},
-       {0x000080f4, 0x00000000},
-       {0x000080fc, 0x00020000},
-       {0x00008100, 0x00000000},
-       {0x00008108, 0x00000052},
-       {0x0000810c, 0x00000000},
-       {0x00008110, 0x00000000},
-       {0x00008114, 0x000007ff},
-       {0x00008118, 0x000000aa},
-       {0x0000811c, 0x00003210},
-       {0x00008124, 0x00000000},
-       {0x00008128, 0x00000000},
-       {0x0000812c, 0x00000000},
-       {0x00008130, 0x00000000},
-       {0x00008134, 0x00000000},
-       {0x00008138, 0x00000000},
-       {0x0000813c, 0x0000ffff},
-       {0x00008144, 0xffffffff},
-       {0x00008168, 0x00000000},
-       {0x0000816c, 0x00000000},
-       {0x00008170, 0x18486e00},
-       {0x00008174, 0x33332210},
-       {0x00008178, 0x00000000},
-       {0x0000817c, 0x00020000},
-       {0x000081c4, 0x33332210},
-       {0x000081c8, 0x00000000},
-       {0x000081cc, 0x00000000},
-       {0x000081d4, 0x00000000},
-       {0x000081ec, 0x00000000},
-       {0x000081f0, 0x00000000},
-       {0x000081f4, 0x00000000},
-       {0x000081f8, 0x00000000},
-       {0x000081fc, 0x00000000},
-       {0x00008240, 0x00100000},
-       {0x00008244, 0x0010f400},
-       {0x00008248, 0x00000800},
-       {0x0000824c, 0x0001e800},
-       {0x00008250, 0x00000000},
-       {0x00008254, 0x00000000},
-       {0x00008258, 0x00000000},
-       {0x0000825c, 0x40000000},
-       {0x00008260, 0x00080922},
-       {0x00008264, 0x99c00010},
-       {0x00008268, 0xffffffff},
-       {0x0000826c, 0x0000ffff},
-       {0x00008270, 0x00000000},
-       {0x00008274, 0x40000000},
-       {0x00008278, 0x003e4180},
-       {0x0000827c, 0x00000004},
-       {0x00008284, 0x0000002c},
-       {0x00008288, 0x0000002c},
-       {0x0000828c, 0x000000ff},
-       {0x00008294, 0x00000000},
-       {0x00008298, 0x00000000},
-       {0x0000829c, 0x00000000},
-       {0x00008300, 0x00000140},
-       {0x00008314, 0x00000000},
-       {0x0000831c, 0x0000010d},
-       {0x00008328, 0x00000000},
-       {0x0000832c, 0x0000001f},
-       {0x00008330, 0x00000302},
-       {0x00008334, 0x00000700},
-       {0x00008338, 0xffff0000},
-       {0x0000833c, 0x02400000},
-       {0x00008340, 0x000107ff},
-       {0x00008344, 0xaa48105b},
-       {0x00008348, 0x008f0000},
-       {0x0000835c, 0x00000000},
-       {0x00008360, 0xffffffff},
-       {0x00008364, 0xffffffff},
-       {0x00008368, 0x00000000},
-       {0x00008370, 0x00000000},
-       {0x00008374, 0x000000ff},
-       {0x00008378, 0x00000000},
-       {0x0000837c, 0x00000000},
-       {0x00008380, 0xffffffff},
-       {0x00008384, 0xffffffff},
-       {0x00008390, 0xffffffff},
-       {0x00008394, 0xffffffff},
-       {0x00008398, 0x00000000},
-       {0x0000839c, 0x00000000},
-       {0x000083a4, 0x0000fa14},
-       {0x000083a8, 0x000f0c00},
-       {0x000083ac, 0x33332210},
-       {0x000083b0, 0x33332210},
-       {0x000083b4, 0x33332210},
-       {0x000083b8, 0x33332210},
-       {0x000083bc, 0x00000000},
-       {0x000083c0, 0x00000000},
-       {0x000083c4, 0x00000000},
-       {0x000083c8, 0x00000000},
-       {0x000083cc, 0x00000200},
-       {0x000083d0, 0x000301ff},
-};
-
-static const u32 ar9462_1p0_baseband_core_txfir_coeff_japan_2484[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a398, 0x00000000},
-       {0x0000a39c, 0x6f7f0301},
-       {0x0000a3a0, 0xca9228ee},
-};
-
-static const u32 ar9462_1p0_sys3ant[][2] = {
-       /* Addr      allmodes  */
-       {0x00063280, 0x00040807},
-       {0x00063284, 0x104ccccc},
-};
-
-static const u32 ar9462_pcie_phy_clkreq_enable_L1_1p0[][2] = {
-       /* Addr      allmodes  */
-       {0x00018c00, 0x10053e5e},
-       {0x00018c04, 0x000801d8},
-       {0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9462_1p0_mac_core_emulation[][2] = {
-       /* Addr      allmodes  */
-       {0x00000030, 0x00060085},
-       {0x00000044, 0x00000008},
-       {0x0000805c, 0xffffc7ff},
-       {0x00008344, 0xaa4a105b},
-};
-
-static const u32 ar9462_common_rx_gain_table_ar9280_2p0_1p0[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x02000101},
-       {0x0000a004, 0x02000102},
-       {0x0000a008, 0x02000103},
-       {0x0000a00c, 0x02000104},
-       {0x0000a010, 0x02000200},
-       {0x0000a014, 0x02000201},
-       {0x0000a018, 0x02000202},
-       {0x0000a01c, 0x02000203},
-       {0x0000a020, 0x02000204},
-       {0x0000a024, 0x02000205},
-       {0x0000a028, 0x02000208},
-       {0x0000a02c, 0x02000302},
-       {0x0000a030, 0x02000303},
-       {0x0000a034, 0x02000304},
-       {0x0000a038, 0x02000400},
-       {0x0000a03c, 0x02010300},
-       {0x0000a040, 0x02010301},
-       {0x0000a044, 0x02010302},
-       {0x0000a048, 0x02000500},
-       {0x0000a04c, 0x02010400},
-       {0x0000a050, 0x02020300},
-       {0x0000a054, 0x02020301},
-       {0x0000a058, 0x02020302},
-       {0x0000a05c, 0x02020303},
-       {0x0000a060, 0x02020400},
-       {0x0000a064, 0x02030300},
-       {0x0000a068, 0x02030301},
-       {0x0000a06c, 0x02030302},
-       {0x0000a070, 0x02030303},
-       {0x0000a074, 0x02030400},
-       {0x0000a078, 0x02040300},
-       {0x0000a07c, 0x02040301},
-       {0x0000a080, 0x02040302},
-       {0x0000a084, 0x02040303},
-       {0x0000a088, 0x02030500},
-       {0x0000a08c, 0x02040400},
-       {0x0000a090, 0x02050203},
-       {0x0000a094, 0x02050204},
-       {0x0000a098, 0x02050205},
-       {0x0000a09c, 0x02040500},
-       {0x0000a0a0, 0x02050301},
-       {0x0000a0a4, 0x02050302},
-       {0x0000a0a8, 0x02050303},
-       {0x0000a0ac, 0x02050400},
-       {0x0000a0b0, 0x02050401},
-       {0x0000a0b4, 0x02050402},
-       {0x0000a0b8, 0x02050403},
-       {0x0000a0bc, 0x02050500},
-       {0x0000a0c0, 0x02050501},
-       {0x0000a0c4, 0x02050502},
-       {0x0000a0c8, 0x02050503},
-       {0x0000a0cc, 0x02050504},
-       {0x0000a0d0, 0x02050600},
-       {0x0000a0d4, 0x02050601},
-       {0x0000a0d8, 0x02050602},
-       {0x0000a0dc, 0x02050603},
-       {0x0000a0e0, 0x02050604},
-       {0x0000a0e4, 0x02050700},
-       {0x0000a0e8, 0x02050701},
-       {0x0000a0ec, 0x02050702},
-       {0x0000a0f0, 0x02050703},
-       {0x0000a0f4, 0x02050704},
-       {0x0000a0f8, 0x02050705},
-       {0x0000a0fc, 0x02050708},
-       {0x0000a100, 0x02050709},
-       {0x0000a104, 0x0205070a},
-       {0x0000a108, 0x0205070b},
-       {0x0000a10c, 0x0205070c},
-       {0x0000a110, 0x0205070d},
-       {0x0000a114, 0x02050710},
-       {0x0000a118, 0x02050711},
-       {0x0000a11c, 0x02050712},
-       {0x0000a120, 0x02050713},
-       {0x0000a124, 0x02050714},
-       {0x0000a128, 0x02050715},
-       {0x0000a12c, 0x02050730},
-       {0x0000a130, 0x02050731},
-       {0x0000a134, 0x02050732},
-       {0x0000a138, 0x02050733},
-       {0x0000a13c, 0x02050734},
-       {0x0000a140, 0x02050735},
-       {0x0000a144, 0x02050750},
-       {0x0000a148, 0x02050751},
-       {0x0000a14c, 0x02050752},
-       {0x0000a150, 0x02050753},
-       {0x0000a154, 0x02050754},
-       {0x0000a158, 0x02050755},
-       {0x0000a15c, 0x02050770},
-       {0x0000a160, 0x02050771},
-       {0x0000a164, 0x02050772},
-       {0x0000a168, 0x02050773},
-       {0x0000a16c, 0x02050774},
-       {0x0000a170, 0x02050775},
-       {0x0000a174, 0x00000776},
-       {0x0000a178, 0x00000776},
-       {0x0000a17c, 0x00000776},
-       {0x0000a180, 0x00000776},
-       {0x0000a184, 0x00000776},
-       {0x0000a188, 0x00000776},
-       {0x0000a18c, 0x00000776},
-       {0x0000a190, 0x00000776},
-       {0x0000a194, 0x00000776},
-       {0x0000a198, 0x00000776},
-       {0x0000a19c, 0x00000776},
-       {0x0000a1a0, 0x00000776},
-       {0x0000a1a4, 0x00000776},
-       {0x0000a1a8, 0x00000776},
-       {0x0000a1ac, 0x00000776},
-       {0x0000a1b0, 0x00000776},
-       {0x0000a1b4, 0x00000776},
-       {0x0000a1b8, 0x00000776},
-       {0x0000a1bc, 0x00000776},
-       {0x0000a1c0, 0x00000776},
-       {0x0000a1c4, 0x00000776},
-       {0x0000a1c8, 0x00000776},
-       {0x0000a1cc, 0x00000776},
-       {0x0000a1d0, 0x00000776},
-       {0x0000a1d4, 0x00000776},
-       {0x0000a1d8, 0x00000776},
-       {0x0000a1dc, 0x00000776},
-       {0x0000a1e0, 0x00000776},
-       {0x0000a1e4, 0x00000776},
-       {0x0000a1e8, 0x00000776},
-       {0x0000a1ec, 0x00000776},
-       {0x0000a1f0, 0x00000776},
-       {0x0000a1f4, 0x00000776},
-       {0x0000a1f8, 0x00000776},
-       {0x0000a1fc, 0x00000776},
-       {0x0000b000, 0x02000101},
-       {0x0000b004, 0x02000102},
-       {0x0000b008, 0x02000103},
-       {0x0000b00c, 0x02000104},
-       {0x0000b010, 0x02000200},
-       {0x0000b014, 0x02000201},
-       {0x0000b018, 0x02000202},
-       {0x0000b01c, 0x02000203},
-       {0x0000b020, 0x02000204},
-       {0x0000b024, 0x02000205},
-       {0x0000b028, 0x02000208},
-       {0x0000b02c, 0x02000302},
-       {0x0000b030, 0x02000303},
-       {0x0000b034, 0x02000304},
-       {0x0000b038, 0x02000400},
-       {0x0000b03c, 0x02010300},
-       {0x0000b040, 0x02010301},
-       {0x0000b044, 0x02010302},
-       {0x0000b048, 0x02000500},
-       {0x0000b04c, 0x02010400},
-       {0x0000b050, 0x02020300},
-       {0x0000b054, 0x02020301},
-       {0x0000b058, 0x02020302},
-       {0x0000b05c, 0x02020303},
-       {0x0000b060, 0x02020400},
-       {0x0000b064, 0x02030300},
-       {0x0000b068, 0x02030301},
-       {0x0000b06c, 0x02030302},
-       {0x0000b070, 0x02030303},
-       {0x0000b074, 0x02030400},
-       {0x0000b078, 0x02040300},
-       {0x0000b07c, 0x02040301},
-       {0x0000b080, 0x02040302},
-       {0x0000b084, 0x02040303},
-       {0x0000b088, 0x02030500},
-       {0x0000b08c, 0x02040400},
-       {0x0000b090, 0x02050203},
-       {0x0000b094, 0x02050204},
-       {0x0000b098, 0x02050205},
-       {0x0000b09c, 0x02040500},
-       {0x0000b0a0, 0x02050301},
-       {0x0000b0a4, 0x02050302},
-       {0x0000b0a8, 0x02050303},
-       {0x0000b0ac, 0x02050400},
-       {0x0000b0b0, 0x02050401},
-       {0x0000b0b4, 0x02050402},
-       {0x0000b0b8, 0x02050403},
-       {0x0000b0bc, 0x02050500},
-       {0x0000b0c0, 0x02050501},
-       {0x0000b0c4, 0x02050502},
-       {0x0000b0c8, 0x02050503},
-       {0x0000b0cc, 0x02050504},
-       {0x0000b0d0, 0x02050600},
-       {0x0000b0d4, 0x02050601},
-       {0x0000b0d8, 0x02050602},
-       {0x0000b0dc, 0x02050603},
-       {0x0000b0e0, 0x02050604},
-       {0x0000b0e4, 0x02050700},
-       {0x0000b0e8, 0x02050701},
-       {0x0000b0ec, 0x02050702},
-       {0x0000b0f0, 0x02050703},
-       {0x0000b0f4, 0x02050704},
-       {0x0000b0f8, 0x02050705},
-       {0x0000b0fc, 0x02050708},
-       {0x0000b100, 0x02050709},
-       {0x0000b104, 0x0205070a},
-       {0x0000b108, 0x0205070b},
-       {0x0000b10c, 0x0205070c},
-       {0x0000b110, 0x0205070d},
-       {0x0000b114, 0x02050710},
-       {0x0000b118, 0x02050711},
-       {0x0000b11c, 0x02050712},
-       {0x0000b120, 0x02050713},
-       {0x0000b124, 0x02050714},
-       {0x0000b128, 0x02050715},
-       {0x0000b12c, 0x02050730},
-       {0x0000b130, 0x02050731},
-       {0x0000b134, 0x02050732},
-       {0x0000b138, 0x02050733},
-       {0x0000b13c, 0x02050734},
-       {0x0000b140, 0x02050735},
-       {0x0000b144, 0x02050750},
-       {0x0000b148, 0x02050751},
-       {0x0000b14c, 0x02050752},
-       {0x0000b150, 0x02050753},
-       {0x0000b154, 0x02050754},
-       {0x0000b158, 0x02050755},
-       {0x0000b15c, 0x02050770},
-       {0x0000b160, 0x02050771},
-       {0x0000b164, 0x02050772},
-       {0x0000b168, 0x02050773},
-       {0x0000b16c, 0x02050774},
-       {0x0000b170, 0x02050775},
-       {0x0000b174, 0x00000776},
-       {0x0000b178, 0x00000776},
-       {0x0000b17c, 0x00000776},
-       {0x0000b180, 0x00000776},
-       {0x0000b184, 0x00000776},
-       {0x0000b188, 0x00000776},
-       {0x0000b18c, 0x00000776},
-       {0x0000b190, 0x00000776},
-       {0x0000b194, 0x00000776},
-       {0x0000b198, 0x00000776},
-       {0x0000b19c, 0x00000776},
-       {0x0000b1a0, 0x00000776},
-       {0x0000b1a4, 0x00000776},
-       {0x0000b1a8, 0x00000776},
-       {0x0000b1ac, 0x00000776},
-       {0x0000b1b0, 0x00000776},
-       {0x0000b1b4, 0x00000776},
-       {0x0000b1b8, 0x00000776},
-       {0x0000b1bc, 0x00000776},
-       {0x0000b1c0, 0x00000776},
-       {0x0000b1c4, 0x00000776},
-       {0x0000b1c8, 0x00000776},
-       {0x0000b1cc, 0x00000776},
-       {0x0000b1d0, 0x00000776},
-       {0x0000b1d4, 0x00000776},
-       {0x0000b1d8, 0x00000776},
-       {0x0000b1dc, 0x00000776},
-       {0x0000b1e0, 0x00000776},
-       {0x0000b1e4, 0x00000776},
-       {0x0000b1e8, 0x00000776},
-       {0x0000b1ec, 0x00000776},
-       {0x0000b1f0, 0x00000776},
-       {0x0000b1f4, 0x00000776},
-       {0x0000b1f8, 0x00000776},
-       {0x0000b1fc, 0x00000776},
-};
-
-static const u32 ar9200_ar9280_2p0_radio_core_1p0[][2] = {
-       /* Addr      allmodes  */
-       {0x00007800, 0x00040000},
-       {0x00007804, 0xdb005012},
-       {0x00007808, 0x04924914},
-       {0x0000780c, 0x21084210},
-       {0x00007810, 0x6d801300},
-       {0x00007814, 0x0019beff},
-       {0x00007818, 0x07e41000},
-       {0x0000781c, 0x00392000},
-       {0x00007820, 0x92592480},
-       {0x00007824, 0x00040000},
-       {0x00007828, 0xdb005012},
-       {0x0000782c, 0x04924914},
-       {0x00007830, 0x21084210},
-       {0x00007834, 0x6d801300},
-       {0x00007838, 0x0019beff},
-       {0x0000783c, 0x07e40000},
-       {0x00007840, 0x00392000},
-       {0x00007844, 0x92592480},
-       {0x00007848, 0x00100000},
-       {0x0000784c, 0x773f0567},
-       {0x00007850, 0x54214514},
-       {0x00007854, 0x12035828},
-       {0x00007858, 0x92592692},
-       {0x0000785c, 0x00000000},
-       {0x00007860, 0x56400000},
-       {0x00007864, 0x0a8e370e},
-       {0x00007868, 0xc0102850},
-       {0x0000786c, 0x812d4000},
-       {0x00007870, 0x807ec400},
-       {0x00007874, 0x001b6db0},
-       {0x00007878, 0x00376b63},
-       {0x0000787c, 0x06db6db6},
-       {0x00007880, 0x006d8000},
-       {0x00007884, 0xffeffffe},
-       {0x00007888, 0xffeffffe},
-       {0x0000788c, 0x00010000},
-       {0x00007890, 0x02060aeb},
-       {0x00007894, 0x5a108000},
-};
-
-static const u32 ar9462_1p0_baseband_postamble_emulation[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221},
-       {0x00009e44, 0x005c0000, 0x005c0000, 0x005c0000, 0x005c0000},
-       {0x0000a258, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
-       {0x0000a25c, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
-       {0x0000a28c, 0x00011111, 0x00011111, 0x00011111, 0x00011111},
-       {0x0000a2c4, 0x00148d18, 0x00148d18, 0x00148d20, 0x00148d20},
-       {0x0000a2d8, 0xf999a800, 0xf999a800, 0xf999a80c, 0xf999a80c},
-       {0x0000a50c, 0x0000c00a, 0x0000c00a, 0x0000c00a, 0x0000c00a},
-       {0x0000a538, 0x00038e8c, 0x00038e8c, 0x00038e8c, 0x00038e8c},
-       {0x0000a53c, 0x0003cecc, 0x0003cecc, 0x0003cecc, 0x0003cecc},
-       {0x0000a540, 0x00040ed4, 0x00040ed4, 0x00040ed4, 0x00040ed4},
-       {0x0000a544, 0x00044edc, 0x00044edc, 0x00044edc, 0x00044edc},
-       {0x0000a548, 0x00048ede, 0x00048ede, 0x00048ede, 0x00048ede},
-       {0x0000a54c, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e},
-       {0x0000a550, 0x00050f5e, 0x00050f5e, 0x00050f5e, 0x00050f5e},
-       {0x0000a554, 0x00054f9e, 0x00054f9e, 0x00054f9e, 0x00054f9e},
-       {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-};
-
-static const u32 ar9462_pcie_phy_pll_on_clkreq_disable_L1_1p0[][2] = {
-       /* Addr      allmodes  */
-       {0x00018c00, 0x10012e5e},
-       {0x00018c04, 0x000801d8},
-       {0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9462_common_rx_gain_table_1p0[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x00830082},
-       {0x0000a014, 0x01810180},
-       {0x0000a018, 0x01830182},
-       {0x0000a01c, 0x01850184},
-       {0x0000a020, 0x01890188},
-       {0x0000a024, 0x018b018a},
-       {0x0000a028, 0x018d018c},
-       {0x0000a02c, 0x01910190},
-       {0x0000a030, 0x01930192},
-       {0x0000a034, 0x01950194},
-       {0x0000a038, 0x038a0196},
-       {0x0000a03c, 0x038c038b},
-       {0x0000a040, 0x0390038d},
-       {0x0000a044, 0x03920391},
-       {0x0000a048, 0x03940393},
-       {0x0000a04c, 0x03960395},
-       {0x0000a050, 0x00000000},
-       {0x0000a054, 0x00000000},
-       {0x0000a058, 0x00000000},
-       {0x0000a05c, 0x00000000},
-       {0x0000a060, 0x00000000},
-       {0x0000a064, 0x00000000},
-       {0x0000a068, 0x00000000},
-       {0x0000a06c, 0x00000000},
-       {0x0000a070, 0x00000000},
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x22222229},
-       {0x0000a084, 0x1d1d1d1d},
-       {0x0000a088, 0x1d1d1d1d},
-       {0x0000a08c, 0x1d1d1d1d},
-       {0x0000a090, 0x171d1d1d},
-       {0x0000a094, 0x11111717},
-       {0x0000a098, 0x00030311},
-       {0x0000a09c, 0x00000000},
-       {0x0000a0a0, 0x00000000},
-       {0x0000a0a4, 0x00000000},
-       {0x0000a0a8, 0x00000000},
-       {0x0000a0ac, 0x00000000},
-       {0x0000a0b0, 0x00000000},
-       {0x0000a0b4, 0x00000000},
-       {0x0000a0b8, 0x00000000},
-       {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
-       {0x0000a114, 0x00000000},
-       {0x0000a118, 0x00000000},
-       {0x0000a11c, 0x00000000},
-       {0x0000a120, 0x00000000},
-       {0x0000a124, 0x00000000},
-       {0x0000a128, 0x00000000},
-       {0x0000a12c, 0x00000000},
-       {0x0000a130, 0x00000000},
-       {0x0000a134, 0x00000000},
-       {0x0000a138, 0x00000000},
-       {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
-       {0x0000a194, 0x00000000},
-       {0x0000a198, 0x00000000},
-       {0x0000a19c, 0x00000000},
-       {0x0000a1a0, 0x00000000},
-       {0x0000a1a4, 0x00000000},
-       {0x0000a1a8, 0x00000000},
-       {0x0000a1ac, 0x00000000},
-       {0x0000a1b0, 0x00000000},
-       {0x0000a1b4, 0x00000000},
-       {0x0000a1b8, 0x00000000},
-       {0x0000a1bc, 0x00000000},
-       {0x0000a1c0, 0x00000000},
-       {0x0000a1c4, 0x00000000},
-       {0x0000a1c8, 0x00000000},
-       {0x0000a1cc, 0x00000000},
-       {0x0000a1d0, 0x00000000},
-       {0x0000a1d4, 0x00000000},
-       {0x0000a1d8, 0x00000000},
-       {0x0000a1dc, 0x00000000},
-       {0x0000a1e0, 0x00000000},
-       {0x0000a1e4, 0x00000000},
-       {0x0000a1e8, 0x00000000},
-       {0x0000a1ec, 0x00000000},
-       {0x0000a1f0, 0x00000396},
-       {0x0000a1f4, 0x00000396},
-       {0x0000a1f8, 0x00000396},
-       {0x0000a1fc, 0x00000196},
-       {0x0000b000, 0x00010000},
-       {0x0000b004, 0x00030002},
-       {0x0000b008, 0x00050004},
-       {0x0000b00c, 0x00810080},
-       {0x0000b010, 0x00830082},
-       {0x0000b014, 0x01810180},
-       {0x0000b018, 0x01830182},
-       {0x0000b01c, 0x01850184},
-       {0x0000b020, 0x02810280},
-       {0x0000b024, 0x02830282},
-       {0x0000b028, 0x02850284},
-       {0x0000b02c, 0x02890288},
-       {0x0000b030, 0x028b028a},
-       {0x0000b034, 0x0388028c},
-       {0x0000b038, 0x038a0389},
-       {0x0000b03c, 0x038c038b},
-       {0x0000b040, 0x0390038d},
-       {0x0000b044, 0x03920391},
-       {0x0000b048, 0x03940393},
-       {0x0000b04c, 0x03960395},
-       {0x0000b050, 0x00000000},
-       {0x0000b054, 0x00000000},
-       {0x0000b058, 0x00000000},
-       {0x0000b05c, 0x00000000},
-       {0x0000b060, 0x00000000},
-       {0x0000b064, 0x00000000},
-       {0x0000b068, 0x00000000},
-       {0x0000b06c, 0x00000000},
-       {0x0000b070, 0x00000000},
-       {0x0000b074, 0x00000000},
-       {0x0000b078, 0x00000000},
-       {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x2a2d2f32},
-       {0x0000b084, 0x21232328},
-       {0x0000b088, 0x19191c1e},
-       {0x0000b08c, 0x12141417},
-       {0x0000b090, 0x07070e0e},
-       {0x0000b094, 0x03030305},
-       {0x0000b098, 0x00000003},
-       {0x0000b09c, 0x00000000},
-       {0x0000b0a0, 0x00000000},
-       {0x0000b0a4, 0x00000000},
-       {0x0000b0a8, 0x00000000},
-       {0x0000b0ac, 0x00000000},
-       {0x0000b0b0, 0x00000000},
-       {0x0000b0b4, 0x00000000},
-       {0x0000b0b8, 0x00000000},
-       {0x0000b0bc, 0x00000000},
-       {0x0000b0c0, 0x003f0020},
-       {0x0000b0c4, 0x00400041},
-       {0x0000b0c8, 0x0140005f},
-       {0x0000b0cc, 0x0160015f},
-       {0x0000b0d0, 0x017e017f},
-       {0x0000b0d4, 0x02410242},
-       {0x0000b0d8, 0x025f0240},
-       {0x0000b0dc, 0x027f0260},
-       {0x0000b0e0, 0x0341027e},
-       {0x0000b0e4, 0x035f0340},
-       {0x0000b0e8, 0x037f0360},
-       {0x0000b0ec, 0x04400441},
-       {0x0000b0f0, 0x0460045f},
-       {0x0000b0f4, 0x0541047f},
-       {0x0000b0f8, 0x055f0540},
-       {0x0000b0fc, 0x057f0560},
-       {0x0000b100, 0x06400641},
-       {0x0000b104, 0x0660065f},
-       {0x0000b108, 0x067e067f},
-       {0x0000b10c, 0x07410742},
-       {0x0000b110, 0x075f0740},
-       {0x0000b114, 0x077f0760},
-       {0x0000b118, 0x07800781},
-       {0x0000b11c, 0x07a0079f},
-       {0x0000b120, 0x07c107bf},
-       {0x0000b124, 0x000007c0},
-       {0x0000b128, 0x00000000},
-       {0x0000b12c, 0x00000000},
-       {0x0000b130, 0x00000000},
-       {0x0000b134, 0x00000000},
-       {0x0000b138, 0x00000000},
-       {0x0000b13c, 0x00000000},
-       {0x0000b140, 0x003f0020},
-       {0x0000b144, 0x00400041},
-       {0x0000b148, 0x0140005f},
-       {0x0000b14c, 0x0160015f},
-       {0x0000b150, 0x017e017f},
-       {0x0000b154, 0x02410242},
-       {0x0000b158, 0x025f0240},
-       {0x0000b15c, 0x027f0260},
-       {0x0000b160, 0x0341027e},
-       {0x0000b164, 0x035f0340},
-       {0x0000b168, 0x037f0360},
-       {0x0000b16c, 0x04400441},
-       {0x0000b170, 0x0460045f},
-       {0x0000b174, 0x0541047f},
-       {0x0000b178, 0x055f0540},
-       {0x0000b17c, 0x057f0560},
-       {0x0000b180, 0x06400641},
-       {0x0000b184, 0x0660065f},
-       {0x0000b188, 0x067e067f},
-       {0x0000b18c, 0x07410742},
-       {0x0000b190, 0x075f0740},
-       {0x0000b194, 0x077f0760},
-       {0x0000b198, 0x07800781},
-       {0x0000b19c, 0x07a0079f},
-       {0x0000b1a0, 0x07c107bf},
-       {0x0000b1a4, 0x000007c0},
-       {0x0000b1a8, 0x00000000},
-       {0x0000b1ac, 0x00000000},
-       {0x0000b1b0, 0x00000000},
-       {0x0000b1b4, 0x00000000},
-       {0x0000b1b8, 0x00000000},
-       {0x0000b1bc, 0x00000000},
-       {0x0000b1c0, 0x00000000},
-       {0x0000b1c4, 0x00000000},
-       {0x0000b1c8, 0x00000000},
-       {0x0000b1cc, 0x00000000},
-       {0x0000b1d0, 0x00000000},
-       {0x0000b1d4, 0x00000000},
-       {0x0000b1d8, 0x00000000},
-       {0x0000b1dc, 0x00000000},
-       {0x0000b1e0, 0x00000000},
-       {0x0000b1e4, 0x00000000},
-       {0x0000b1e8, 0x00000000},
-       {0x0000b1ec, 0x00000000},
-       {0x0000b1f0, 0x00000396},
-       {0x0000b1f4, 0x00000396},
-       {0x0000b1f8, 0x00000396},
-       {0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9462_modes_high_ob_db_tx_gain_table_1p0[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
-       {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
-       {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
-       {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
-       {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400},
-       {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402},
-       {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
-       {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603},
-       {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02},
-       {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04},
-       {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20},
-       {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20},
-       {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22},
-       {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24},
-       {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
-       {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
-       {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
-       {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81},
-       {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83},
-       {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84},
-       {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
-       {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
-       {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
-       {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
-       {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
-       {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
-       {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
-       {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
-       {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
-       {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
-       {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
-       {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
-       {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
-       {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
-       {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060},
-       {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
-       {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000},
-};
-
-static const u32 ar9462_common_wo_xlna_rx_gain_table_1p0[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x00830082},
-       {0x0000a014, 0x01810180},
-       {0x0000a018, 0x01830182},
-       {0x0000a01c, 0x01850184},
-       {0x0000a020, 0x01890188},
-       {0x0000a024, 0x018b018a},
-       {0x0000a028, 0x018d018c},
-       {0x0000a02c, 0x03820190},
-       {0x0000a030, 0x03840383},
-       {0x0000a034, 0x03880385},
-       {0x0000a038, 0x038a0389},
-       {0x0000a03c, 0x038c038b},
-       {0x0000a040, 0x0390038d},
-       {0x0000a044, 0x03920391},
-       {0x0000a048, 0x03940393},
-       {0x0000a04c, 0x03960395},
-       {0x0000a050, 0x00000000},
-       {0x0000a054, 0x00000000},
-       {0x0000a058, 0x00000000},
-       {0x0000a05c, 0x00000000},
-       {0x0000a060, 0x00000000},
-       {0x0000a064, 0x00000000},
-       {0x0000a068, 0x00000000},
-       {0x0000a06c, 0x00000000},
-       {0x0000a070, 0x00000000},
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x29292929},
-       {0x0000a084, 0x29292929},
-       {0x0000a088, 0x29292929},
-       {0x0000a08c, 0x29292929},
-       {0x0000a090, 0x22292929},
-       {0x0000a094, 0x1d1d2222},
-       {0x0000a098, 0x0c111117},
-       {0x0000a09c, 0x00030303},
-       {0x0000a0a0, 0x00000000},
-       {0x0000a0a4, 0x00000000},
-       {0x0000a0a8, 0x00000000},
-       {0x0000a0ac, 0x00000000},
-       {0x0000a0b0, 0x00000000},
-       {0x0000a0b4, 0x00000000},
-       {0x0000a0b8, 0x00000000},
-       {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
-       {0x0000a114, 0x00000000},
-       {0x0000a118, 0x00000000},
-       {0x0000a11c, 0x00000000},
-       {0x0000a120, 0x00000000},
-       {0x0000a124, 0x00000000},
-       {0x0000a128, 0x00000000},
-       {0x0000a12c, 0x00000000},
-       {0x0000a130, 0x00000000},
-       {0x0000a134, 0x00000000},
-       {0x0000a138, 0x00000000},
-       {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
-       {0x0000a194, 0x00000000},
-       {0x0000a198, 0x00000000},
-       {0x0000a19c, 0x00000000},
-       {0x0000a1a0, 0x00000000},
-       {0x0000a1a4, 0x00000000},
-       {0x0000a1a8, 0x00000000},
-       {0x0000a1ac, 0x00000000},
-       {0x0000a1b0, 0x00000000},
-       {0x0000a1b4, 0x00000000},
-       {0x0000a1b8, 0x00000000},
-       {0x0000a1bc, 0x00000000},
-       {0x0000a1c0, 0x00000000},
-       {0x0000a1c4, 0x00000000},
-       {0x0000a1c8, 0x00000000},
-       {0x0000a1cc, 0x00000000},
-       {0x0000a1d0, 0x00000000},
-       {0x0000a1d4, 0x00000000},
-       {0x0000a1d8, 0x00000000},
-       {0x0000a1dc, 0x00000000},
-       {0x0000a1e0, 0x00000000},
-       {0x0000a1e4, 0x00000000},
-       {0x0000a1e8, 0x00000000},
-       {0x0000a1ec, 0x00000000},
-       {0x0000a1f0, 0x00000396},
-       {0x0000a1f4, 0x00000396},
-       {0x0000a1f8, 0x00000396},
-       {0x0000a1fc, 0x00000196},
-       {0x0000b000, 0x00010000},
-       {0x0000b004, 0x00030002},
-       {0x0000b008, 0x00050004},
-       {0x0000b00c, 0x00810080},
-       {0x0000b010, 0x00830082},
-       {0x0000b014, 0x01810180},
-       {0x0000b018, 0x01830182},
-       {0x0000b01c, 0x01850184},
-       {0x0000b020, 0x02810280},
-       {0x0000b024, 0x02830282},
-       {0x0000b028, 0x02850284},
-       {0x0000b02c, 0x02890288},
-       {0x0000b030, 0x028b028a},
-       {0x0000b034, 0x0388028c},
-       {0x0000b038, 0x038a0389},
-       {0x0000b03c, 0x038c038b},
-       {0x0000b040, 0x0390038d},
-       {0x0000b044, 0x03920391},
-       {0x0000b048, 0x03940393},
-       {0x0000b04c, 0x03960395},
-       {0x0000b050, 0x00000000},
-       {0x0000b054, 0x00000000},
-       {0x0000b058, 0x00000000},
-       {0x0000b05c, 0x00000000},
-       {0x0000b060, 0x00000000},
-       {0x0000b064, 0x00000000},
-       {0x0000b068, 0x00000000},
-       {0x0000b06c, 0x00000000},
-       {0x0000b070, 0x00000000},
-       {0x0000b074, 0x00000000},
-       {0x0000b078, 0x00000000},
-       {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x32323232},
-       {0x0000b084, 0x2f2f3232},
-       {0x0000b088, 0x23282a2d},
-       {0x0000b08c, 0x1c1e2123},
-       {0x0000b090, 0x14171919},
-       {0x0000b094, 0x0e0e1214},
-       {0x0000b098, 0x03050707},
-       {0x0000b09c, 0x00030303},
-       {0x0000b0a0, 0x00000000},
-       {0x0000b0a4, 0x00000000},
-       {0x0000b0a8, 0x00000000},
-       {0x0000b0ac, 0x00000000},
-       {0x0000b0b0, 0x00000000},
-       {0x0000b0b4, 0x00000000},
-       {0x0000b0b8, 0x00000000},
-       {0x0000b0bc, 0x00000000},
-       {0x0000b0c0, 0x003f0020},
-       {0x0000b0c4, 0x00400041},
-       {0x0000b0c8, 0x0140005f},
-       {0x0000b0cc, 0x0160015f},
-       {0x0000b0d0, 0x017e017f},
-       {0x0000b0d4, 0x02410242},
-       {0x0000b0d8, 0x025f0240},
-       {0x0000b0dc, 0x027f0260},
-       {0x0000b0e0, 0x0341027e},
-       {0x0000b0e4, 0x035f0340},
-       {0x0000b0e8, 0x037f0360},
-       {0x0000b0ec, 0x04400441},
-       {0x0000b0f0, 0x0460045f},
-       {0x0000b0f4, 0x0541047f},
-       {0x0000b0f8, 0x055f0540},
-       {0x0000b0fc, 0x057f0560},
-       {0x0000b100, 0x06400641},
-       {0x0000b104, 0x0660065f},
-       {0x0000b108, 0x067e067f},
-       {0x0000b10c, 0x07410742},
-       {0x0000b110, 0x075f0740},
-       {0x0000b114, 0x077f0760},
-       {0x0000b118, 0x07800781},
-       {0x0000b11c, 0x07a0079f},
-       {0x0000b120, 0x07c107bf},
-       {0x0000b124, 0x000007c0},
-       {0x0000b128, 0x00000000},
-       {0x0000b12c, 0x00000000},
-       {0x0000b130, 0x00000000},
-       {0x0000b134, 0x00000000},
-       {0x0000b138, 0x00000000},
-       {0x0000b13c, 0x00000000},
-       {0x0000b140, 0x003f0020},
-       {0x0000b144, 0x00400041},
-       {0x0000b148, 0x0140005f},
-       {0x0000b14c, 0x0160015f},
-       {0x0000b150, 0x017e017f},
-       {0x0000b154, 0x02410242},
-       {0x0000b158, 0x025f0240},
-       {0x0000b15c, 0x027f0260},
-       {0x0000b160, 0x0341027e},
-       {0x0000b164, 0x035f0340},
-       {0x0000b168, 0x037f0360},
-       {0x0000b16c, 0x04400441},
-       {0x0000b170, 0x0460045f},
-       {0x0000b174, 0x0541047f},
-       {0x0000b178, 0x055f0540},
-       {0x0000b17c, 0x057f0560},
-       {0x0000b180, 0x06400641},
-       {0x0000b184, 0x0660065f},
-       {0x0000b188, 0x067e067f},
-       {0x0000b18c, 0x07410742},
-       {0x0000b190, 0x075f0740},
-       {0x0000b194, 0x077f0760},
-       {0x0000b198, 0x07800781},
-       {0x0000b19c, 0x07a0079f},
-       {0x0000b1a0, 0x07c107bf},
-       {0x0000b1a4, 0x000007c0},
-       {0x0000b1a8, 0x00000000},
-       {0x0000b1ac, 0x00000000},
-       {0x0000b1b0, 0x00000000},
-       {0x0000b1b4, 0x00000000},
-       {0x0000b1b8, 0x00000000},
-       {0x0000b1bc, 0x00000000},
-       {0x0000b1c0, 0x00000000},
-       {0x0000b1c4, 0x00000000},
-       {0x0000b1c8, 0x00000000},
-       {0x0000b1cc, 0x00000000},
-       {0x0000b1d0, 0x00000000},
-       {0x0000b1d4, 0x00000000},
-       {0x0000b1d8, 0x00000000},
-       {0x0000b1dc, 0x00000000},
-       {0x0000b1e0, 0x00000000},
-       {0x0000b1e4, 0x00000000},
-       {0x0000b1e8, 0x00000000},
-       {0x0000b1ec, 0x00000000},
-       {0x0000b1f0, 0x00000396},
-       {0x0000b1f4, 0x00000396},
-       {0x0000b1f8, 0x00000396},
-       {0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9462_1p0_mac_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
-       {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
-       {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
-       {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
-       {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
-       {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
-       {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
-       {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
-};
-
-static const u32 ar9462_1p0_mac_postamble_emulation[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8},
-       {0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017},
-};
-
-static const u32 ar9462_1p0_tx_gain_table_baseband_postamble_emulation[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5},
-       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a504, 0x00004002, 0x00004002, 0x00004002, 0x00004002},
-       {0x0000a508, 0x00008004, 0x00008004, 0x00008004, 0x00008004},
-       {0x0000a510, 0x0001000c, 0x0001000c, 0x0001000c, 0x0001000c},
-       {0x0000a514, 0x0001420b, 0x0001420b, 0x0001420b, 0x0001420b},
-       {0x0000a518, 0x0001824a, 0x0001824a, 0x0001824a, 0x0001824a},
-       {0x0000a51c, 0x0001c44a, 0x0001c44a, 0x0001c44a, 0x0001c44a},
-       {0x0000a520, 0x0002064a, 0x0002064a, 0x0002064a, 0x0002064a},
-       {0x0000a524, 0x0002484a, 0x0002484a, 0x0002484a, 0x0002484a},
-       {0x0000a528, 0x00028a4a, 0x00028a4a, 0x00028a4a, 0x00028a4a},
-       {0x0000a52c, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a},
-       {0x0000a530, 0x00030e4a, 0x00030e4a, 0x00030e4a, 0x00030e4a},
-       {0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a},
-};
-
-static const u32 ar9462_1p0_radio_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
-       {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24646c08, 0x24646c08},
-       {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
-       {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
-       {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-       {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
-       {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-};
-
-static const u32 ar9462_1p0_soc_postamble_emulation[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00007010, 0x00001133, 0x00001133, 0x00001133, 0x00001133},
-};
-
-static const u32 ar9462_1p0_baseband_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00009800, 0xafe68e30},
-       {0x00009804, 0xfd14e000},
-       {0x00009808, 0x9c0a9f6b},
-       {0x0000980c, 0x04900000},
-       {0x00009814, 0x9280c00a},
-       {0x00009818, 0x00000000},
-       {0x0000981c, 0x00020028},
-       {0x00009834, 0x6400a290},
-       {0x00009838, 0x0108ecff},
-       {0x0000983c, 0x0d000600},
-       {0x00009880, 0x201fff00},
-       {0x00009884, 0x00001042},
-       {0x000098a4, 0x00200400},
-       {0x000098b0, 0x32840bbe},
-       {0x000098d0, 0x004b6a8e},
-       {0x000098d4, 0x00000820},
-       {0x000098dc, 0x00000000},
-       {0x000098e4, 0x01ffffff},
-       {0x000098e8, 0x01ffffff},
-       {0x000098ec, 0x01ffffff},
-       {0x000098f0, 0x00000000},
-       {0x000098f4, 0x00000000},
-       {0x00009c04, 0xff55ff55},
-       {0x00009c08, 0x0320ff55},
-       {0x00009c0c, 0x00000000},
-       {0x00009c10, 0x00000000},
-       {0x00009c14, 0x00046384},
-       {0x00009c18, 0x05b6b440},
-       {0x00009c1c, 0x00b6b440},
-       {0x00009d00, 0xc080a333},
-       {0x00009d04, 0x40206c10},
-       {0x00009d08, 0x009c4060},
-       {0x00009d0c, 0x9883800a},
-       {0x00009d10, 0x01834061},
-       {0x00009d14, 0x00c0040b},
-       {0x00009d18, 0x00000000},
-       {0x00009e08, 0x0038230c},
-       {0x00009e24, 0x990bb514},
-       {0x00009e28, 0x0c6f0000},
-       {0x00009e30, 0x06336f77},
-       {0x00009e34, 0x6af6532f},
-       {0x00009e38, 0x0cc80c00},
-       {0x00009e40, 0x0d261820},
-       {0x00009e4c, 0x00001004},
-       {0x00009e50, 0x00ff03f1},
-       {0x00009e54, 0x64c355c7},
-       {0x00009e58, 0xfd897735},
-       {0x00009e5c, 0xe9198724},
-       {0x00009fc0, 0x803e4788},
-       {0x00009fc4, 0x0001efb5},
-       {0x00009fcc, 0x40000014},
-       {0x00009fd0, 0x01193b93},
-       {0x0000a20c, 0x00000000},
-       {0x0000a220, 0x00000000},
-       {0x0000a224, 0x00000000},
-       {0x0000a228, 0x10002310},
-       {0x0000a23c, 0x00000000},
-       {0x0000a244, 0x0c000000},
-       {0x0000a2a0, 0x00000001},
-       {0x0000a2c0, 0x00000001},
-       {0x0000a2c8, 0x00000000},
-       {0x0000a2cc, 0x18c43433},
-       {0x0000a2d4, 0x00000000},
-       {0x0000a2ec, 0x00000000},
-       {0x0000a2f0, 0x00000000},
-       {0x0000a2f4, 0x00000000},
-       {0x0000a2f8, 0x00000000},
-       {0x0000a344, 0x00000000},
-       {0x0000a34c, 0x00000000},
-       {0x0000a350, 0x0000a000},
-       {0x0000a364, 0x00000000},
-       {0x0000a370, 0x00000000},
-       {0x0000a390, 0x00000001},
-       {0x0000a394, 0x00000444},
-       {0x0000a398, 0x001f0e0f},
-       {0x0000a39c, 0x0075393f},
-       {0x0000a3a0, 0xb79f6427},
-       {0x0000a3a4, 0x00000000},
-       {0x0000a3a8, 0xaaaaaaaa},
-       {0x0000a3ac, 0x3c466478},
-       {0x0000a3c0, 0x20202020},
-       {0x0000a3c4, 0x22222220},
-       {0x0000a3c8, 0x20200020},
-       {0x0000a3cc, 0x20202020},
-       {0x0000a3d0, 0x20202020},
-       {0x0000a3d4, 0x20202020},
-       {0x0000a3d8, 0x20202020},
-       {0x0000a3dc, 0x20202020},
-       {0x0000a3e0, 0x20202020},
-       {0x0000a3e4, 0x20202020},
-       {0x0000a3e8, 0x20202020},
-       {0x0000a3ec, 0x20202020},
-       {0x0000a3f0, 0x00000000},
-       {0x0000a3f4, 0x00000006},
-       {0x0000a3f8, 0x0c9bd380},
-       {0x0000a3fc, 0x000f0f01},
-       {0x0000a400, 0x8fa91f01},
-       {0x0000a404, 0x00000000},
-       {0x0000a408, 0x0e79e5c6},
-       {0x0000a40c, 0x00820820},
-       {0x0000a414, 0x1ce739ce},
-       {0x0000a418, 0x2d001dce},
-       {0x0000a41c, 0x1ce739ce},
-       {0x0000a420, 0x000001ce},
-       {0x0000a424, 0x1ce739ce},
-       {0x0000a428, 0x000001ce},
-       {0x0000a42c, 0x1ce739ce},
-       {0x0000a430, 0x1ce739ce},
-       {0x0000a434, 0x00000000},
-       {0x0000a438, 0x00001801},
-       {0x0000a43c, 0x00100000},
-       {0x0000a440, 0x00000000},
-       {0x0000a444, 0x00000000},
-       {0x0000a448, 0x05000080},
-       {0x0000a44c, 0x00000001},
-       {0x0000a450, 0x00010000},
-       {0x0000a458, 0x00000000},
-       {0x0000a644, 0xbfad9d74},
-       {0x0000a648, 0x0048060a},
-       {0x0000a64c, 0x00003c37},
-       {0x0000a670, 0x03020100},
-       {0x0000a674, 0x09080504},
-       {0x0000a678, 0x0d0c0b0a},
-       {0x0000a67c, 0x13121110},
-       {0x0000a680, 0x31301514},
-       {0x0000a684, 0x35343332},
-       {0x0000a688, 0x00000036},
-       {0x0000a690, 0x00000838},
-       {0x0000a6b0, 0x0000000a},
-       {0x0000a6b4, 0x28f12c01},
-       {0x0000a7c0, 0x00000000},
-       {0x0000a7c4, 0xfffffffc},
-       {0x0000a7c8, 0x00000000},
-       {0x0000a7cc, 0x00000000},
-       {0x0000a7d0, 0x00000000},
-       {0x0000a7d4, 0x00000004},
-       {0x0000a7dc, 0x00000001},
-       {0x0000a8d0, 0x004b6a8e},
-       {0x0000a8d4, 0x00000820},
-       {0x0000a8dc, 0x00000000},
-       {0x0000a8f0, 0x00000000},
-       {0x0000a8f4, 0x00000000},
-       {0x0000b2d0, 0x00000080},
-       {0x0000b2d4, 0x00000000},
-       {0x0000b2ec, 0x00000000},
-       {0x0000b2f0, 0x00000000},
-       {0x0000b2f4, 0x00000000},
-       {0x0000b2f8, 0x00000000},
-       {0x0000b408, 0x0e79e5c0},
-       {0x0000b40c, 0x00820820},
-       {0x0000b420, 0x00000000},
-       {0x0000b6b0, 0x0000000a},
-       {0x0000b6b4, 0x00c00001},
-};
-
-static const u32 ar9462_1p0_baseband_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
-       {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
-       {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
-       {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
-       {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
-       {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
-       {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
-       {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
-       {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
-       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
-       {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
-       {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e},
-       {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
-       {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
-       {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
-       {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c782},
-       {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
-       {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
-       {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
-       {0x0000a204, 0x0131b7c0, 0x0131b7c4, 0x0131b7c4, 0x0131b7c0},
-       {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
-       {0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f},
-       {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
-       {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
-       {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
-       {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
-       {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
-       {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
-       {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
-       {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
-       {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
-       {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
-       {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
-       {0x0000a288, 0x00000110, 0x00000110, 0x00100110, 0x00100110},
-       {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
-       {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
-       {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
-       {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
-       {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
-       {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000},
-       {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
-       {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
-       {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
-};
-
-static const u32 ar9462_modes_fast_clock_1p0[][3] = {
-       /* Addr      5G_HT20     5G_HT40   */
-       {0x00001030, 0x00000268, 0x000004d0},
-       {0x00001070, 0x0000018c, 0x00000318},
-       {0x000010b0, 0x00000fd0, 0x00001fa0},
-       {0x00008014, 0x044c044c, 0x08980898},
-       {0x0000801c, 0x148ec02b, 0x148ec057},
-       {0x00008318, 0x000044c0, 0x00008980},
-       {0x00009e00, 0x0372131c, 0x0372131c},
-       {0x0000a230, 0x0000400b, 0x00004016},
-       {0x0000a254, 0x00000898, 0x00001130},
-};
-
-static const u32 ar9462_modes_low_ob_db_tx_gain_table_1p0[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
-       {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
-       {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
-       {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
-       {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
-       {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
-       {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
-       {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
-       {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
-       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
-       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
-       {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
-       {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
-       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
-       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
-       {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
-       {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
-       {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
-       {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
-       {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
-       {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
-       {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
-       {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
-       {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
-       {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
-       {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
-       {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
-       {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
-       {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
-       {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
-       {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-       {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-       {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-       {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-       {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
-       {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
-       {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
-       {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060},
-       {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
-       {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000},
-};
-
-static const u32 ar9462_1p0_soc_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233},
-};
-
-static const u32 ar9462_common_mixed_rx_gain_table_1p0[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x00830082},
-       {0x0000a014, 0x01810180},
-       {0x0000a018, 0x01830182},
-       {0x0000a01c, 0x01850184},
-       {0x0000a020, 0x01890188},
-       {0x0000a024, 0x018b018a},
-       {0x0000a028, 0x018d018c},
-       {0x0000a02c, 0x03820190},
-       {0x0000a030, 0x03840383},
-       {0x0000a034, 0x03880385},
-       {0x0000a038, 0x038a0389},
-       {0x0000a03c, 0x038c038b},
-       {0x0000a040, 0x0390038d},
-       {0x0000a044, 0x03920391},
-       {0x0000a048, 0x03940393},
-       {0x0000a04c, 0x03960395},
-       {0x0000a050, 0x00000000},
-       {0x0000a054, 0x00000000},
-       {0x0000a058, 0x00000000},
-       {0x0000a05c, 0x00000000},
-       {0x0000a060, 0x00000000},
-       {0x0000a064, 0x00000000},
-       {0x0000a068, 0x00000000},
-       {0x0000a06c, 0x00000000},
-       {0x0000a070, 0x00000000},
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x29292929},
-       {0x0000a084, 0x29292929},
-       {0x0000a088, 0x29292929},
-       {0x0000a08c, 0x29292929},
-       {0x0000a090, 0x22292929},
-       {0x0000a094, 0x1d1d2222},
-       {0x0000a098, 0x0c111117},
-       {0x0000a09c, 0x00030303},
-       {0x0000a0a0, 0x00000000},
-       {0x0000a0a4, 0x00000000},
-       {0x0000a0a8, 0x00000000},
-       {0x0000a0ac, 0x00000000},
-       {0x0000a0b0, 0x00000000},
-       {0x0000a0b4, 0x00000000},
-       {0x0000a0b8, 0x00000000},
-       {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
-       {0x0000a114, 0x00000000},
-       {0x0000a118, 0x00000000},
-       {0x0000a11c, 0x00000000},
-       {0x0000a120, 0x00000000},
-       {0x0000a124, 0x00000000},
-       {0x0000a128, 0x00000000},
-       {0x0000a12c, 0x00000000},
-       {0x0000a130, 0x00000000},
-       {0x0000a134, 0x00000000},
-       {0x0000a138, 0x00000000},
-       {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
-       {0x0000a194, 0x00000000},
-       {0x0000a198, 0x00000000},
-       {0x0000a19c, 0x00000000},
-       {0x0000a1a0, 0x00000000},
-       {0x0000a1a4, 0x00000000},
-       {0x0000a1a8, 0x00000000},
-       {0x0000a1ac, 0x00000000},
-       {0x0000a1b0, 0x00000000},
-       {0x0000a1b4, 0x00000000},
-       {0x0000a1b8, 0x00000000},
-       {0x0000a1bc, 0x00000000},
-       {0x0000a1c0, 0x00000000},
-       {0x0000a1c4, 0x00000000},
-       {0x0000a1c8, 0x00000000},
-       {0x0000a1cc, 0x00000000},
-       {0x0000a1d0, 0x00000000},
-       {0x0000a1d4, 0x00000000},
-       {0x0000a1d8, 0x00000000},
-       {0x0000a1dc, 0x00000000},
-       {0x0000a1e0, 0x00000000},
-       {0x0000a1e4, 0x00000000},
-       {0x0000a1e8, 0x00000000},
-       {0x0000a1ec, 0x00000000},
-       {0x0000a1f0, 0x00000396},
-       {0x0000a1f4, 0x00000396},
-       {0x0000a1f8, 0x00000396},
-       {0x0000a1fc, 0x00000196},
-       {0x0000b000, 0x00010000},
-       {0x0000b004, 0x00030002},
-       {0x0000b008, 0x00050004},
-       {0x0000b00c, 0x00810080},
-       {0x0000b010, 0x00830082},
-       {0x0000b014, 0x01810180},
-       {0x0000b018, 0x01830182},
-       {0x0000b01c, 0x01850184},
-       {0x0000b020, 0x02810280},
-       {0x0000b024, 0x02830282},
-       {0x0000b028, 0x02850284},
-       {0x0000b02c, 0x02890288},
-       {0x0000b030, 0x028b028a},
-       {0x0000b034, 0x0388028c},
-       {0x0000b038, 0x038a0389},
-       {0x0000b03c, 0x038c038b},
-       {0x0000b040, 0x0390038d},
-       {0x0000b044, 0x03920391},
-       {0x0000b048, 0x03940393},
-       {0x0000b04c, 0x03960395},
-       {0x0000b050, 0x00000000},
-       {0x0000b054, 0x00000000},
-       {0x0000b058, 0x00000000},
-       {0x0000b05c, 0x00000000},
-       {0x0000b060, 0x00000000},
-       {0x0000b064, 0x00000000},
-       {0x0000b068, 0x00000000},
-       {0x0000b06c, 0x00000000},
-       {0x0000b070, 0x00000000},
-       {0x0000b074, 0x00000000},
-       {0x0000b078, 0x00000000},
-       {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x2a2d2f32},
-       {0x0000b084, 0x21232328},
-       {0x0000b088, 0x19191c1e},
-       {0x0000b08c, 0x12141417},
-       {0x0000b090, 0x07070e0e},
-       {0x0000b094, 0x03030305},
-       {0x0000b098, 0x00000003},
-       {0x0000b09c, 0x00000000},
-       {0x0000b0a0, 0x00000000},
-       {0x0000b0a4, 0x00000000},
-       {0x0000b0a8, 0x00000000},
-       {0x0000b0ac, 0x00000000},
-       {0x0000b0b0, 0x00000000},
-       {0x0000b0b4, 0x00000000},
-       {0x0000b0b8, 0x00000000},
-       {0x0000b0bc, 0x00000000},
-       {0x0000b0c0, 0x003f0020},
-       {0x0000b0c4, 0x00400041},
-       {0x0000b0c8, 0x0140005f},
-       {0x0000b0cc, 0x0160015f},
-       {0x0000b0d0, 0x017e017f},
-       {0x0000b0d4, 0x02410242},
-       {0x0000b0d8, 0x025f0240},
-       {0x0000b0dc, 0x027f0260},
-       {0x0000b0e0, 0x0341027e},
-       {0x0000b0e4, 0x035f0340},
-       {0x0000b0e8, 0x037f0360},
-       {0x0000b0ec, 0x04400441},
-       {0x0000b0f0, 0x0460045f},
-       {0x0000b0f4, 0x0541047f},
-       {0x0000b0f8, 0x055f0540},
-       {0x0000b0fc, 0x057f0560},
-       {0x0000b100, 0x06400641},
-       {0x0000b104, 0x0660065f},
-       {0x0000b108, 0x067e067f},
-       {0x0000b10c, 0x07410742},
-       {0x0000b110, 0x075f0740},
-       {0x0000b114, 0x077f0760},
-       {0x0000b118, 0x07800781},
-       {0x0000b11c, 0x07a0079f},
-       {0x0000b120, 0x07c107bf},
-       {0x0000b124, 0x000007c0},
-       {0x0000b128, 0x00000000},
-       {0x0000b12c, 0x00000000},
-       {0x0000b130, 0x00000000},
-       {0x0000b134, 0x00000000},
-       {0x0000b138, 0x00000000},
-       {0x0000b13c, 0x00000000},
-       {0x0000b140, 0x003f0020},
-       {0x0000b144, 0x00400041},
-       {0x0000b148, 0x0140005f},
-       {0x0000b14c, 0x0160015f},
-       {0x0000b150, 0x017e017f},
-       {0x0000b154, 0x02410242},
-       {0x0000b158, 0x025f0240},
-       {0x0000b15c, 0x027f0260},
-       {0x0000b160, 0x0341027e},
-       {0x0000b164, 0x035f0340},
-       {0x0000b168, 0x037f0360},
-       {0x0000b16c, 0x04400441},
-       {0x0000b170, 0x0460045f},
-       {0x0000b174, 0x0541047f},
-       {0x0000b178, 0x055f0540},
-       {0x0000b17c, 0x057f0560},
-       {0x0000b180, 0x06400641},
-       {0x0000b184, 0x0660065f},
-       {0x0000b188, 0x067e067f},
-       {0x0000b18c, 0x07410742},
-       {0x0000b190, 0x075f0740},
-       {0x0000b194, 0x077f0760},
-       {0x0000b198, 0x07800781},
-       {0x0000b19c, 0x07a0079f},
-       {0x0000b1a0, 0x07c107bf},
-       {0x0000b1a4, 0x000007c0},
-       {0x0000b1a8, 0x00000000},
-       {0x0000b1ac, 0x00000000},
-       {0x0000b1b0, 0x00000000},
-       {0x0000b1b4, 0x00000000},
-       {0x0000b1b8, 0x00000000},
-       {0x0000b1bc, 0x00000000},
-       {0x0000b1c0, 0x00000000},
-       {0x0000b1c4, 0x00000000},
-       {0x0000b1c8, 0x00000000},
-       {0x0000b1cc, 0x00000000},
-       {0x0000b1d0, 0x00000000},
-       {0x0000b1d4, 0x00000000},
-       {0x0000b1d8, 0x00000000},
-       {0x0000b1dc, 0x00000000},
-       {0x0000b1e0, 0x00000000},
-       {0x0000b1e4, 0x00000000},
-       {0x0000b1e8, 0x00000000},
-       {0x0000b1ec, 0x00000000},
-       {0x0000b1f0, 0x00000396},
-       {0x0000b1f4, 0x00000396},
-       {0x0000b1f8, 0x00000396},
-       {0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9462_pcie_phy_clkreq_disable_L1_1p0[][2] = {
-       /* Addr      allmodes  */
-       {0x00018c00, 0x10013e5e},
-       {0x00018c04, 0x000801d8},
-       {0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9462_1p0_baseband_core_emulation[][2] = {
-       /* Addr      allmodes  */
-       {0x00009800, 0xafa68e30},
-       {0x00009884, 0x00002842},
-       {0x00009c04, 0xff55ff55},
-       {0x00009c08, 0x0320ff55},
-       {0x00009e50, 0x00000000},
-       {0x00009fcc, 0x00000014},
-       {0x0000a344, 0x00000010},
-       {0x0000a398, 0x00000000},
-       {0x0000a39c, 0x71733d01},
-       {0x0000a3a0, 0xd0ad5c12},
-       {0x0000a3c0, 0x22222220},
-       {0x0000a3c4, 0x22222222},
-       {0x0000a404, 0x00418a11},
-       {0x0000a418, 0x050001ce},
-       {0x0000a438, 0x00001800},
-       {0x0000a458, 0x01444452},
-       {0x0000a644, 0x3fad9d74},
-       {0x0000a690, 0x00000038},
-};
-
-static const u32 ar9462_1p0_radio_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00016000, 0x36db6db6},
-       {0x00016004, 0x6db6db40},
-       {0x00016008, 0x73f00000},
-       {0x0001600c, 0x00000000},
-       {0x00016010, 0x6d820001},
-       {0x00016040, 0x7f80fff8},
-       {0x0001604c, 0x2699e04f},
-       {0x00016050, 0x6db6db6c},
-       {0x00016054, 0x6db60000},
-       {0x00016058, 0x6c200000},
-       {0x00016080, 0x00040000},
-       {0x00016084, 0x9a68048c},
-       {0x00016088, 0x54214514},
-       {0x0001608c, 0x12030409},
-       {0x00016090, 0x24926490},
-       {0x00016098, 0xd2888888},
-       {0x000160a0, 0x0a108ffe},
-       {0x000160a4, 0x812fc490},
-       {0x000160a8, 0x423c8000},
-       {0x000160b4, 0x92000000},
-       {0x000160b8, 0x0285dddc},
-       {0x000160bc, 0x02908888},
-       {0x000160c0, 0x00adb6d0},
-       {0x000160c4, 0x6db6db60},
-       {0x000160c8, 0x6db6db6c},
-       {0x000160cc, 0x0de6c1b0},
-       {0x00016100, 0x3fffbe04},
-       {0x00016104, 0xfff80000},
-       {0x00016108, 0x00200400},
-       {0x00016110, 0x00000000},
-       {0x00016144, 0x02084080},
-       {0x00016148, 0x000080c0},
-       {0x00016280, 0x050a0001},
-       {0x00016284, 0x3d841400},
-       {0x00016288, 0x00000000},
-       {0x0001628c, 0xe3000000},
-       {0x00016290, 0xa1005080},
-       {0x00016294, 0x00000020},
-       {0x00016298, 0x50a02900},
-       {0x00016340, 0x121e4276},
-       {0x00016344, 0x00300000},
-       {0x00016400, 0x36db6db6},
-       {0x00016404, 0x6db6db40},
-       {0x00016408, 0x73f00000},
-       {0x0001640c, 0x00000000},
-       {0x00016410, 0x6c800001},
-       {0x00016440, 0x7f80fff8},
-       {0x0001644c, 0x4699e04f},
-       {0x00016450, 0x6db6db6c},
-       {0x00016454, 0x6db60000},
-       {0x00016500, 0x3fffbe04},
-       {0x00016504, 0xfff80000},
-       {0x00016508, 0x00200400},
-       {0x00016510, 0x00000000},
-       {0x00016544, 0x02084080},
-       {0x00016548, 0x000080c0},
-};
-
-static const u32 ar9462_1p0_soc_preamble[][2] = {
-       /* Addr      allmodes  */
-       {0x00007020, 0x00000000},
-       {0x00007034, 0x00000002},
-       {0x00007038, 0x000004c2},
-};
-
-static const u32 ar9462_1p0_sys2ant[][2] = {
-       /* Addr      allmodes  */
-       {0x00063120, 0x00801980},
-};
-
-#endif /* INITVALS_9462_1P0_H */
index dc2054f0378ee46344d30607159214887bc3f89c..b6ba1e8149be5eaf85022eaecf662c9d016d452e 100644 (file)
@@ -98,14 +98,6 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
        {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
 };
 
-static const u32 ar9462_2p0_mac_core_emulation[][2] = {
-       /* Addr      allmodes  */
-       {0x00000030, 0x000e0085},
-       {0x00000044, 0x00000008},
-       {0x0000805c, 0xffffc7ff},
-       {0x00008344, 0xaa4a105b},
-};
-
 static const u32 ar9462_common_rx_gain_table_2p0[][2] = {
        /* Addr      allmodes  */
        {0x0000a000, 0x00010000},
@@ -380,349 +372,6 @@ static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
        {0x00018c08, 0x0003580c},
 };
 
-static const u32 ar9462_2p0_sys3ant[][2] = {
-       /* Addr      allmodes  */
-       {0x00063280, 0x00040807},
-       {0x00063284, 0x104ccccc},
-};
-
-static const u32 ar9462_common_rx_gain_table_ar9280_2p0[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x02000101},
-       {0x0000a004, 0x02000102},
-       {0x0000a008, 0x02000103},
-       {0x0000a00c, 0x02000104},
-       {0x0000a010, 0x02000200},
-       {0x0000a014, 0x02000201},
-       {0x0000a018, 0x02000202},
-       {0x0000a01c, 0x02000203},
-       {0x0000a020, 0x02000204},
-       {0x0000a024, 0x02000205},
-       {0x0000a028, 0x02000208},
-       {0x0000a02c, 0x02000302},
-       {0x0000a030, 0x02000303},
-       {0x0000a034, 0x02000304},
-       {0x0000a038, 0x02000400},
-       {0x0000a03c, 0x02010300},
-       {0x0000a040, 0x02010301},
-       {0x0000a044, 0x02010302},
-       {0x0000a048, 0x02000500},
-       {0x0000a04c, 0x02010400},
-       {0x0000a050, 0x02020300},
-       {0x0000a054, 0x02020301},
-       {0x0000a058, 0x02020302},
-       {0x0000a05c, 0x02020303},
-       {0x0000a060, 0x02020400},
-       {0x0000a064, 0x02030300},
-       {0x0000a068, 0x02030301},
-       {0x0000a06c, 0x02030302},
-       {0x0000a070, 0x02030303},
-       {0x0000a074, 0x02030400},
-       {0x0000a078, 0x02040300},
-       {0x0000a07c, 0x02040301},
-       {0x0000a080, 0x02040302},
-       {0x0000a084, 0x02040303},
-       {0x0000a088, 0x02030500},
-       {0x0000a08c, 0x02040400},
-       {0x0000a090, 0x02050203},
-       {0x0000a094, 0x02050204},
-       {0x0000a098, 0x02050205},
-       {0x0000a09c, 0x02040500},
-       {0x0000a0a0, 0x02050301},
-       {0x0000a0a4, 0x02050302},
-       {0x0000a0a8, 0x02050303},
-       {0x0000a0ac, 0x02050400},
-       {0x0000a0b0, 0x02050401},
-       {0x0000a0b4, 0x02050402},
-       {0x0000a0b8, 0x02050403},
-       {0x0000a0bc, 0x02050500},
-       {0x0000a0c0, 0x02050501},
-       {0x0000a0c4, 0x02050502},
-       {0x0000a0c8, 0x02050503},
-       {0x0000a0cc, 0x02050504},
-       {0x0000a0d0, 0x02050600},
-       {0x0000a0d4, 0x02050601},
-       {0x0000a0d8, 0x02050602},
-       {0x0000a0dc, 0x02050603},
-       {0x0000a0e0, 0x02050604},
-       {0x0000a0e4, 0x02050700},
-       {0x0000a0e8, 0x02050701},
-       {0x0000a0ec, 0x02050702},
-       {0x0000a0f0, 0x02050703},
-       {0x0000a0f4, 0x02050704},
-       {0x0000a0f8, 0x02050705},
-       {0x0000a0fc, 0x02050708},
-       {0x0000a100, 0x02050709},
-       {0x0000a104, 0x0205070a},
-       {0x0000a108, 0x0205070b},
-       {0x0000a10c, 0x0205070c},
-       {0x0000a110, 0x0205070d},
-       {0x0000a114, 0x02050710},
-       {0x0000a118, 0x02050711},
-       {0x0000a11c, 0x02050712},
-       {0x0000a120, 0x02050713},
-       {0x0000a124, 0x02050714},
-       {0x0000a128, 0x02050715},
-       {0x0000a12c, 0x02050730},
-       {0x0000a130, 0x02050731},
-       {0x0000a134, 0x02050732},
-       {0x0000a138, 0x02050733},
-       {0x0000a13c, 0x02050734},
-       {0x0000a140, 0x02050735},
-       {0x0000a144, 0x02050750},
-       {0x0000a148, 0x02050751},
-       {0x0000a14c, 0x02050752},
-       {0x0000a150, 0x02050753},
-       {0x0000a154, 0x02050754},
-       {0x0000a158, 0x02050755},
-       {0x0000a15c, 0x02050770},
-       {0x0000a160, 0x02050771},
-       {0x0000a164, 0x02050772},
-       {0x0000a168, 0x02050773},
-       {0x0000a16c, 0x02050774},
-       {0x0000a170, 0x02050775},
-       {0x0000a174, 0x00000776},
-       {0x0000a178, 0x00000776},
-       {0x0000a17c, 0x00000776},
-       {0x0000a180, 0x00000776},
-       {0x0000a184, 0x00000776},
-       {0x0000a188, 0x00000776},
-       {0x0000a18c, 0x00000776},
-       {0x0000a190, 0x00000776},
-       {0x0000a194, 0x00000776},
-       {0x0000a198, 0x00000776},
-       {0x0000a19c, 0x00000776},
-       {0x0000a1a0, 0x00000776},
-       {0x0000a1a4, 0x00000776},
-       {0x0000a1a8, 0x00000776},
-       {0x0000a1ac, 0x00000776},
-       {0x0000a1b0, 0x00000776},
-       {0x0000a1b4, 0x00000776},
-       {0x0000a1b8, 0x00000776},
-       {0x0000a1bc, 0x00000776},
-       {0x0000a1c0, 0x00000776},
-       {0x0000a1c4, 0x00000776},
-       {0x0000a1c8, 0x00000776},
-       {0x0000a1cc, 0x00000776},
-       {0x0000a1d0, 0x00000776},
-       {0x0000a1d4, 0x00000776},
-       {0x0000a1d8, 0x00000776},
-       {0x0000a1dc, 0x00000776},
-       {0x0000a1e0, 0x00000776},
-       {0x0000a1e4, 0x00000776},
-       {0x0000a1e8, 0x00000776},
-       {0x0000a1ec, 0x00000776},
-       {0x0000a1f0, 0x00000776},
-       {0x0000a1f4, 0x00000776},
-       {0x0000a1f8, 0x00000776},
-       {0x0000a1fc, 0x00000776},
-       {0x0000b000, 0x02000101},
-       {0x0000b004, 0x02000102},
-       {0x0000b008, 0x02000103},
-       {0x0000b00c, 0x02000104},
-       {0x0000b010, 0x02000200},
-       {0x0000b014, 0x02000201},
-       {0x0000b018, 0x02000202},
-       {0x0000b01c, 0x02000203},
-       {0x0000b020, 0x02000204},
-       {0x0000b024, 0x02000205},
-       {0x0000b028, 0x02000208},
-       {0x0000b02c, 0x02000302},
-       {0x0000b030, 0x02000303},
-       {0x0000b034, 0x02000304},
-       {0x0000b038, 0x02000400},
-       {0x0000b03c, 0x02010300},
-       {0x0000b040, 0x02010301},
-       {0x0000b044, 0x02010302},
-       {0x0000b048, 0x02000500},
-       {0x0000b04c, 0x02010400},
-       {0x0000b050, 0x02020300},
-       {0x0000b054, 0x02020301},
-       {0x0000b058, 0x02020302},
-       {0x0000b05c, 0x02020303},
-       {0x0000b060, 0x02020400},
-       {0x0000b064, 0x02030300},
-       {0x0000b068, 0x02030301},
-       {0x0000b06c, 0x02030302},
-       {0x0000b070, 0x02030303},
-       {0x0000b074, 0x02030400},
-       {0x0000b078, 0x02040300},
-       {0x0000b07c, 0x02040301},
-       {0x0000b080, 0x02040302},
-       {0x0000b084, 0x02040303},
-       {0x0000b088, 0x02030500},
-       {0x0000b08c, 0x02040400},
-       {0x0000b090, 0x02050203},
-       {0x0000b094, 0x02050204},
-       {0x0000b098, 0x02050205},
-       {0x0000b09c, 0x02040500},
-       {0x0000b0a0, 0x02050301},
-       {0x0000b0a4, 0x02050302},
-       {0x0000b0a8, 0x02050303},
-       {0x0000b0ac, 0x02050400},
-       {0x0000b0b0, 0x02050401},
-       {0x0000b0b4, 0x02050402},
-       {0x0000b0b8, 0x02050403},
-       {0x0000b0bc, 0x02050500},
-       {0x0000b0c0, 0x02050501},
-       {0x0000b0c4, 0x02050502},
-       {0x0000b0c8, 0x02050503},
-       {0x0000b0cc, 0x02050504},
-       {0x0000b0d0, 0x02050600},
-       {0x0000b0d4, 0x02050601},
-       {0x0000b0d8, 0x02050602},
-       {0x0000b0dc, 0x02050603},
-       {0x0000b0e0, 0x02050604},
-       {0x0000b0e4, 0x02050700},
-       {0x0000b0e8, 0x02050701},
-       {0x0000b0ec, 0x02050702},
-       {0x0000b0f0, 0x02050703},
-       {0x0000b0f4, 0x02050704},
-       {0x0000b0f8, 0x02050705},
-       {0x0000b0fc, 0x02050708},
-       {0x0000b100, 0x02050709},
-       {0x0000b104, 0x0205070a},
-       {0x0000b108, 0x0205070b},
-       {0x0000b10c, 0x0205070c},
-       {0x0000b110, 0x0205070d},
-       {0x0000b114, 0x02050710},
-       {0x0000b118, 0x02050711},
-       {0x0000b11c, 0x02050712},
-       {0x0000b120, 0x02050713},
-       {0x0000b124, 0x02050714},
-       {0x0000b128, 0x02050715},
-       {0x0000b12c, 0x02050730},
-       {0x0000b130, 0x02050731},
-       {0x0000b134, 0x02050732},
-       {0x0000b138, 0x02050733},
-       {0x0000b13c, 0x02050734},
-       {0x0000b140, 0x02050735},
-       {0x0000b144, 0x02050750},
-       {0x0000b148, 0x02050751},
-       {0x0000b14c, 0x02050752},
-       {0x0000b150, 0x02050753},
-       {0x0000b154, 0x02050754},
-       {0x0000b158, 0x02050755},
-       {0x0000b15c, 0x02050770},
-       {0x0000b160, 0x02050771},
-       {0x0000b164, 0x02050772},
-       {0x0000b168, 0x02050773},
-       {0x0000b16c, 0x02050774},
-       {0x0000b170, 0x02050775},
-       {0x0000b174, 0x00000776},
-       {0x0000b178, 0x00000776},
-       {0x0000b17c, 0x00000776},
-       {0x0000b180, 0x00000776},
-       {0x0000b184, 0x00000776},
-       {0x0000b188, 0x00000776},
-       {0x0000b18c, 0x00000776},
-       {0x0000b190, 0x00000776},
-       {0x0000b194, 0x00000776},
-       {0x0000b198, 0x00000776},
-       {0x0000b19c, 0x00000776},
-       {0x0000b1a0, 0x00000776},
-       {0x0000b1a4, 0x00000776},
-       {0x0000b1a8, 0x00000776},
-       {0x0000b1ac, 0x00000776},
-       {0x0000b1b0, 0x00000776},
-       {0x0000b1b4, 0x00000776},
-       {0x0000b1b8, 0x00000776},
-       {0x0000b1bc, 0x00000776},
-       {0x0000b1c0, 0x00000776},
-       {0x0000b1c4, 0x00000776},
-       {0x0000b1c8, 0x00000776},
-       {0x0000b1cc, 0x00000776},
-       {0x0000b1d0, 0x00000776},
-       {0x0000b1d4, 0x00000776},
-       {0x0000b1d8, 0x00000776},
-       {0x0000b1dc, 0x00000776},
-       {0x0000b1e0, 0x00000776},
-       {0x0000b1e4, 0x00000776},
-       {0x0000b1e8, 0x00000776},
-       {0x0000b1ec, 0x00000776},
-       {0x0000b1f0, 0x00000776},
-       {0x0000b1f4, 0x00000776},
-       {0x0000b1f8, 0x00000776},
-       {0x0000b1fc, 0x00000776},
-};
-
-static const u32 ar9200_ar9280_2p0_radio_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00007800, 0x00040000},
-       {0x00007804, 0xdb005012},
-       {0x00007808, 0x04924914},
-       {0x0000780c, 0x21084210},
-       {0x00007810, 0x6d801300},
-       {0x00007814, 0x0019beff},
-       {0x00007818, 0x07e41000},
-       {0x0000781c, 0x00392000},
-       {0x00007820, 0x92592480},
-       {0x00007824, 0x00040000},
-       {0x00007828, 0xdb005012},
-       {0x0000782c, 0x04924914},
-       {0x00007830, 0x21084210},
-       {0x00007834, 0x6d801300},
-       {0x00007838, 0x0019beff},
-       {0x0000783c, 0x07e40000},
-       {0x00007840, 0x00392000},
-       {0x00007844, 0x92592480},
-       {0x00007848, 0x00100000},
-       {0x0000784c, 0x773f0567},
-       {0x00007850, 0x54214514},
-       {0x00007854, 0x12035828},
-       {0x00007858, 0x92592692},
-       {0x0000785c, 0x00000000},
-       {0x00007860, 0x56400000},
-       {0x00007864, 0x0a8e370e},
-       {0x00007868, 0xc0102850},
-       {0x0000786c, 0x812d4000},
-       {0x00007870, 0x807ec400},
-       {0x00007874, 0x001b6db0},
-       {0x00007878, 0x00376b63},
-       {0x0000787c, 0x06db6db6},
-       {0x00007880, 0x006d8000},
-       {0x00007884, 0xffeffffe},
-       {0x00007888, 0xffeffffe},
-       {0x0000788c, 0x00010000},
-       {0x00007890, 0x02060aeb},
-       {0x00007894, 0x5a108000},
-};
-
-static const u32 ar9462_2p0_mac_postamble_emulation[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8},
-       {0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017},
-};
-
-static const u32 ar9462_2p0_radio_postamble_sys3ant[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
-       {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-       {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-};
-
-static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221},
-       {0x00009e44, 0xfc5c0000, 0xfc5c0000, 0xfc5c0000, 0xfc5c0000},
-       {0x0000a258, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
-       {0x0000a25c, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
-       {0x0000a28c, 0x00011111, 0x00011111, 0x00011111, 0x00011111},
-       {0x0000a2c4, 0x00148d18, 0x00148d18, 0x00148d20, 0x00148d20},
-       {0x0000a2d8, 0xf999a800, 0xf999a800, 0xf999a80c, 0xf999a80c},
-       {0x0000a50c, 0x0000c00a, 0x0000c00a, 0x0000c00a, 0x0000c00a},
-       {0x0000a538, 0x00038e8c, 0x00038e8c, 0x00038e8c, 0x00038e8c},
-       {0x0000a53c, 0x0003cecc, 0x0003cecc, 0x0003cecc, 0x0003cecc},
-       {0x0000a540, 0x00040ed4, 0x00040ed4, 0x00040ed4, 0x00040ed4},
-       {0x0000a544, 0x00044edc, 0x00044edc, 0x00044edc, 0x00044edc},
-       {0x0000a548, 0x00048ede, 0x00048ede, 0x00048ede, 0x00048ede},
-       {0x0000a54c, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e},
-       {0x0000a550, 0x00050f5e, 0x00050f5e, 0x00050f5e, 0x00050f5e},
-       {0x0000a554, 0x00054f9e, 0x00054f9e, 0x00054f9e, 0x00054f9e},
-       {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-};
-
 static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
@@ -1356,24 +1005,6 @@ static const u32 ar9462_2p0_radio_core[][2] = {
        {0x00016548, 0x000080c0},
 };
 
-static const u32 ar9462_2p0_tx_gain_table_baseband_postamble_emulation[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5},
-       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a504, 0x00004002, 0x00004002, 0x00004002, 0x00004002},
-       {0x0000a508, 0x00008004, 0x00008004, 0x00008004, 0x00008004},
-       {0x0000a510, 0x0001000c, 0x0001000c, 0x0001000c, 0x0001000c},
-       {0x0000a514, 0x0001420b, 0x0001420b, 0x0001420b, 0x0001420b},
-       {0x0000a518, 0x0001824a, 0x0001824a, 0x0001824a, 0x0001824a},
-       {0x0000a51c, 0x0001c44a, 0x0001c44a, 0x0001c44a, 0x0001c44a},
-       {0x0000a520, 0x0002064a, 0x0002064a, 0x0002064a, 0x0002064a},
-       {0x0000a524, 0x0002484a, 0x0002484a, 0x0002484a, 0x0002484a},
-       {0x0000a528, 0x00028a4a, 0x00028a4a, 0x00028a4a, 0x00028a4a},
-       {0x0000a52c, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a},
-       {0x0000a530, 0x00030e4a, 0x00030e4a, 0x00030e4a, 0x00030e4a},
-       {0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a},
-};
-
 static const u32 ar9462_2p0_soc_preamble[][2] = {
        /* Addr      allmodes  */
        {0x00007020, 0x00000000},
@@ -1381,11 +1012,6 @@ static const u32 ar9462_2p0_soc_preamble[][2] = {
        {0x00007038, 0x000004c2},
 };
 
-static const u32 ar9462_2p0_sys2ant[][2] = {
-       /* Addr      allmodes  */
-       {0x00063120, 0x00801980},
-};
-
 static const u32 ar9462_2p0_mac_core[][2] = {
        /* Addr      allmodes  */
        {0x00000008, 0x00000000},
@@ -1822,75 +1448,6 @@ static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = {
        {0x0000b1fc, 0x00000196},
 };
 
-static const u32 ar9462_modes_green_ob_db_tx_gain_table_2p0[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
-       {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
-       {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
-       {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-       {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
-       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
-       {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
-       {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400},
-       {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402},
-       {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
-       {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603},
-       {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02},
-       {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04},
-       {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20},
-       {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20},
-       {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22},
-       {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24},
-       {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
-       {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
-       {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
-       {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81},
-       {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83},
-       {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84},
-       {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
-       {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
-       {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
-       {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
-       {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
-       {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
-       {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
-       {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
-       {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
-       {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
-       {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
-       {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
-       {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
-       {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
-       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
-       {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060},
-       {0x00016054, 0x6db60180, 0x6db60180, 0x6db60180, 0x6db60180},
-       {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
-       {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000},
-       {0x00016454, 0x6db60180, 0x6db60180, 0x6db60180, 0x6db60180},
-};
-
 static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
        /* Addr      allmodes  */
        {0x000018c0, 0x10101010},
@@ -1903,26 +1460,4 @@ static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
        {0x000018dc, 0x10101010},
 };
 
-static const u32 ar9462_2p0_baseband_core_emulation[][2] = {
-       /* Addr      allmodes  */
-       {0x00009800, 0xafa68e30},
-       {0x00009884, 0x00002842},
-       {0x00009c04, 0xff55ff55},
-       {0x00009c08, 0x0320ff55},
-       {0x00009e50, 0x00000000},
-       {0x00009fcc, 0x00000014},
-       {0x0000a344, 0x00000010},
-       {0x0000a398, 0x00000000},
-       {0x0000a39c, 0x71733d01},
-       {0x0000a3a0, 0xd0ad5c12},
-       {0x0000a3c0, 0x22222220},
-       {0x0000a3c4, 0x22222222},
-       {0x0000a404, 0x00418a11},
-       {0x0000a418, 0x050001ce},
-       {0x0000a438, 0x00001800},
-       {0x0000a458, 0x01444452},
-       {0x0000a644, 0x3fad9d74},
-       {0x0000a690, 0x00000038},
-};
-
 #endif /* INITVALS_9462_2P0_H */
index 171ccf7c972ff1cc228dca2019122ff6e79bdc0c..3d8e51cd5d8f1bbd9227fbf394433d3742193753 100644 (file)
@@ -299,7 +299,6 @@ struct ath_tx {
 
 struct ath_rx_edma {
        struct sk_buff_head rx_fifo;
-       struct sk_buff_head rx_buffers;
        u32 rx_fifo_hwsize;
 };
 
@@ -454,9 +453,39 @@ struct ath_btcoex {
        struct ath_mci_profile mci;
 };
 
-int ath_init_btcoex_timer(struct ath_softc *sc);
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+int ath9k_init_btcoex(struct ath_softc *sc);
+void ath9k_deinit_btcoex(struct ath_softc *sc);
+void ath9k_start_btcoex(struct ath_softc *sc);
+void ath9k_stop_btcoex(struct ath_softc *sc);
 void ath9k_btcoex_timer_resume(struct ath_softc *sc);
 void ath9k_btcoex_timer_pause(struct ath_softc *sc);
+void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status);
+u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen);
+#else
+static inline int ath9k_init_btcoex(struct ath_softc *sc)
+{
+       return 0;
+}
+static inline void ath9k_deinit_btcoex(struct ath_softc *sc)
+{
+}
+static inline void ath9k_start_btcoex(struct ath_softc *sc)
+{
+}
+static inline void ath9k_stop_btcoex(struct ath_softc *sc)
+{
+}
+static inline void ath9k_btcoex_handle_interrupt(struct ath_softc *sc,
+                                                u32 status)
+{
+}
+static inline u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc,
+                                         u32 max_4ms_framelen)
+{
+       return 0;
+}
+#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
 
 /********************/
 /*   LED Control    */
@@ -650,8 +679,11 @@ struct ath_softc {
        struct ath_beacon_config cur_beacon_conf;
        struct delayed_work tx_complete_work;
        struct delayed_work hw_pll_work;
+
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
        struct ath_btcoex btcoex;
        struct ath_mci_coex mci_coex;
+#endif
 
        struct ath_descdma txsdma;
 
index b8967e482e6ef952ea97317bac7d4f34322d4e7e..43882f9e25c46d02b9b70180e1258d15f35e5255 100644 (file)
@@ -91,7 +91,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
        info.txpower = MAX_RATE_POWER;
        info.keyix = ATH9K_TXKEYIX_INVALID;
        info.keytype = ATH9K_KEY_TYPE_CLEAR;
-       info.flags = ATH9K_TXDESC_NOACK;
+       info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_INTREQ;
 
        info.buf_addr[0] = bf->bf_buf_addr;
        info.buf_len[0] = roundup(skb->len, 4);
@@ -355,7 +355,6 @@ void ath_beacon_tasklet(unsigned long data)
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_buf *bf = NULL;
        struct ieee80211_vif *vif;
-       struct ath_tx_status ts;
        bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
        int slot;
        u32 bfaddr, bc = 0;
@@ -462,11 +461,6 @@ void ath_beacon_tasklet(unsigned long data)
                        ath9k_hw_txstart(ah, sc->beacon.beaconq);
 
                sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
-               if (edma) {
-                       spin_lock_bh(&sc->sc_pcu_lock);
-                       ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts);
-                       spin_unlock_bh(&sc->sc_pcu_lock);
-               }
        }
 }
 
index a6712a95d76a24da330c4d628fc15455afce5536..ec32719934116e9252efeb840ae6925bf0819ac4 100644 (file)
@@ -68,9 +68,6 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
        u32 i, idx;
        bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        if (AR_SREV_9300_20_OR_LATER(ah))
                rxclear_polarity = !ath_bt_config.bt_rxclear_polarity;
 
@@ -98,12 +95,43 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
 }
 EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw);
 
-void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
+void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah)
 {
+       struct ath_common *common = ath9k_hw_common(ah);
        struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+       /*
+        * Check if BTCOEX is globally disabled.
+        */
+       if (!common->btcoex_enabled) {
+               btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
                return;
+       }
+
+       if (AR_SREV_9462(ah)) {
+               btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI;
+       } else if (AR_SREV_9300_20_OR_LATER(ah)) {
+               btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
+               btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
+               btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
+               btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300;
+       } else if (AR_SREV_9280_20_OR_LATER(ah)) {
+               btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280;
+               btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280;
+
+               if (AR_SREV_9285(ah)) {
+                       btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
+                       btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9285;
+               } else {
+                       btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
+               }
+       }
+}
+EXPORT_SYMBOL(ath9k_hw_btcoex_init_scheme);
+
+void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
+{
+       struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
        /* connect bt_active to baseband */
        REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
@@ -127,9 +155,6 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
 {
        struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        /* btcoex 3-wire */
        REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
                        (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB |
@@ -152,13 +177,34 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
 }
 EXPORT_SYMBOL(ath9k_hw_btcoex_init_3wire);
 
+void ath9k_hw_btcoex_init_mci(struct ath_hw *ah)
+{
+       ah->btcoex_hw.mci.ready = false;
+       ah->btcoex_hw.mci.bt_state = 0;
+       ah->btcoex_hw.mci.bt_ver_major = 3;
+       ah->btcoex_hw.mci.bt_ver_minor = 0;
+       ah->btcoex_hw.mci.bt_version_known = false;
+       ah->btcoex_hw.mci.update_2g5g = true;
+       ah->btcoex_hw.mci.is_2g = true;
+       ah->btcoex_hw.mci.wlan_channels_update = false;
+       ah->btcoex_hw.mci.wlan_channels[0] = 0x00000000;
+       ah->btcoex_hw.mci.wlan_channels[1] = 0xffffffff;
+       ah->btcoex_hw.mci.wlan_channels[2] = 0xffffffff;
+       ah->btcoex_hw.mci.wlan_channels[3] = 0x7fffffff;
+       ah->btcoex_hw.mci.query_bt = true;
+       ah->btcoex_hw.mci.unhalt_bt_gpm = true;
+       ah->btcoex_hw.mci.halted_bt_gpm = false;
+       ah->btcoex_hw.mci.need_flush_btinfo = false;
+       ah->btcoex_hw.mci.wlan_cal_seq = 0;
+       ah->btcoex_hw.mci.wlan_cal_done = 0;
+       ah->btcoex_hw.mci.config = 0x2201;
+}
+EXPORT_SYMBOL(ath9k_hw_btcoex_init_mci);
+
 static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah)
 {
        struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        /* Configure the desired GPIO port for TX_FRAME output */
        ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
                            AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
@@ -170,9 +216,6 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
 {
        struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
                                     SM(wlan_weight, AR_BTCOEX_WL_WGHT);
 }
@@ -261,9 +304,6 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
        struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
        int i;
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        btcoex_hw->enabled = false;
        if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) {
                ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
@@ -312,9 +352,6 @@ static void ar9003_btcoex_bt_stomp(struct ath_hw *ah,
 void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
                              enum ath_stomp_type stomp_type)
 {
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        if (AR_SREV_9300_20_OR_LATER(ah)) {
                ar9003_btcoex_bt_stomp(ah, stomp_type);
                return;
index 278361c867ca265171e900d5635b62b9bdfbeede..8f93aef4414fabe2a5897c1e4f1e67df4746930b 100644 (file)
@@ -67,7 +67,6 @@ struct ath9k_hw_mci {
        u32 wlan_cal_done;
        u32 config;
        u8 *gpm_buf;
-       u8 *sched_buf;
        bool ready;
        bool update_2g5g;
        bool is_2g;
@@ -98,13 +97,14 @@ struct ath_btcoex_hw {
        u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS];
 };
 
+void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah);
 void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
 void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
+void ath9k_hw_btcoex_init_mci(struct ath_hw *ah);
 void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
 void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
                                u32 bt_weight,
                                u32 wlan_weight);
-void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 void ath9k_hw_btcoex_disable(struct ath_hw *ah);
 void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
                              enum ath_stomp_type stomp_type);
index 68d972bf232d20fbc431c291853288c4b20e7fd1..c2edf688da49497159a8962bcbb46a723e4e80c9 100644 (file)
@@ -451,109 +451,6 @@ static const struct file_operations fops_interrupt = {
        .llseek = default_llseek,
 };
 
-static const char *channel_type_str(enum nl80211_channel_type t)
-{
-       switch (t) {
-       case NL80211_CHAN_NO_HT:
-               return "no ht";
-       case NL80211_CHAN_HT20:
-               return "ht20";
-       case NL80211_CHAN_HT40MINUS:
-               return "ht40-";
-       case NL80211_CHAN_HT40PLUS:
-               return "ht40+";
-       default:
-               return "???";
-       }
-}
-
-static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
-                              size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       struct ieee80211_channel *chan = sc->hw->conf.channel;
-       struct ieee80211_conf *conf = &(sc->hw->conf);
-       char buf[512];
-       unsigned int len = 0;
-       u8 addr[ETH_ALEN];
-       u32 tmp;
-
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "%s (chan=%d  center-freq: %d MHz  channel-type: %d (%s))\n",
-                       wiphy_name(sc->hw->wiphy),
-                       ieee80211_frequency_to_channel(chan->center_freq),
-                       chan->center_freq,
-                       conf->channel_type,
-                       channel_type_str(conf->channel_type));
-
-       ath9k_ps_wakeup(sc);
-       put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr);
-       put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "addr: %pM\n", addr);
-       put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_BSSMSKL), addr);
-       put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "addrmask: %pM\n", addr);
-       tmp = ath9k_hw_getrxfilter(sc->sc_ah);
-       ath9k_ps_restore(sc);
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "rfilt: 0x%x", tmp);
-       if (tmp & ATH9K_RX_FILTER_UCAST)
-               len += snprintf(buf + len, sizeof(buf) - len, " UCAST");
-       if (tmp & ATH9K_RX_FILTER_MCAST)
-               len += snprintf(buf + len, sizeof(buf) - len, " MCAST");
-       if (tmp & ATH9K_RX_FILTER_BCAST)
-               len += snprintf(buf + len, sizeof(buf) - len, " BCAST");
-       if (tmp & ATH9K_RX_FILTER_CONTROL)
-               len += snprintf(buf + len, sizeof(buf) - len, " CONTROL");
-       if (tmp & ATH9K_RX_FILTER_BEACON)
-               len += snprintf(buf + len, sizeof(buf) - len, " BEACON");
-       if (tmp & ATH9K_RX_FILTER_PROM)
-               len += snprintf(buf + len, sizeof(buf) - len, " PROM");
-       if (tmp & ATH9K_RX_FILTER_PROBEREQ)
-               len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ");
-       if (tmp & ATH9K_RX_FILTER_PHYERR)
-               len += snprintf(buf + len, sizeof(buf) - len, " PHYERR");
-       if (tmp & ATH9K_RX_FILTER_MYBEACON)
-               len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON");
-       if (tmp & ATH9K_RX_FILTER_COMP_BAR)
-               len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR");
-       if (tmp & ATH9K_RX_FILTER_PSPOLL)
-               len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL");
-       if (tmp & ATH9K_RX_FILTER_PHYRADAR)
-               len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR");
-       if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL)
-               len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL");
-
-       len += snprintf(buf + len, sizeof(buf) - len,
-                      "\n\nReset causes:\n"
-                      "  baseband hang: %d\n"
-                      "  baseband watchdog: %d\n"
-                      "  fatal hardware error interrupt: %d\n"
-                      "  tx hardware error: %d\n"
-                      "  tx path hang: %d\n"
-                      "  pll rx hang: %d\n",
-                      sc->debug.stats.reset[RESET_TYPE_BB_HANG],
-                      sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG],
-                      sc->debug.stats.reset[RESET_TYPE_FATAL_INT],
-                      sc->debug.stats.reset[RESET_TYPE_TX_ERROR],
-                      sc->debug.stats.reset[RESET_TYPE_TX_HANG],
-                      sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
-
-       if (len > sizeof(buf))
-               len = sizeof(buf);
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_wiphy = {
-       .read = read_file_wiphy,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE,
-       .llseek = default_llseek,
-};
-
 #define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum
 #define PR(str, elem)                                                  \
        do {                                                            \
@@ -763,87 +660,128 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
 {
        struct ath_softc *sc = file->private_data;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       struct ath_hw *ah = sc->sc_ah;
        struct ieee80211_hw *hw = sc->hw;
-       char *buf;
-       unsigned int len = 0, size = 8000;
+       struct ath9k_vif_iter_data iter_data;
+       char buf[512];
+       unsigned int len = 0;
        ssize_t retval = 0;
        unsigned int reg;
-       struct ath9k_vif_iter_data iter_data;
+       u32 rxfilter;
 
-       ath9k_calculate_iter_data(hw, NULL, &iter_data);
-       
-       buf = kzalloc(size, GFP_KERNEL);
-       if (buf == NULL)
-               return -ENOMEM;
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "BSSID: %pM\n", common->curbssid);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "BSSID-MASK: %pM\n", common->bssidmask);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "OPMODE: %s\n", ath_opmode_to_string(sc->sc_ah->opmode));
 
        ath9k_ps_wakeup(sc);
-       len += snprintf(buf + len, size - len,
-                       "curbssid: %pM\n"
-                       "OP-Mode: %s(%i)\n"
-                       "Beacon-Timer-Register: 0x%x\n",
-                       common->curbssid,
-                       ath_opmode_to_string(sc->sc_ah->opmode),
-                       (int)(sc->sc_ah->opmode),
-                       REG_READ(ah, AR_BEACON_PERIOD));
-
-       reg = REG_READ(ah, AR_TIMER_MODE);
+       rxfilter = ath9k_hw_getrxfilter(sc->sc_ah);
        ath9k_ps_restore(sc);
-       len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (",
-                       reg);
-       if (reg & AR_TBTT_TIMER_EN)
-               len += snprintf(buf + len, size - len, "TBTT ");
-       if (reg & AR_DBA_TIMER_EN)
-               len += snprintf(buf + len, size - len, "DBA ");
-       if (reg & AR_SWBA_TIMER_EN)
-               len += snprintf(buf + len, size - len, "SWBA ");
-       if (reg & AR_HCF_TIMER_EN)
-               len += snprintf(buf + len, size - len, "HCF ");
-       if (reg & AR_TIM_TIMER_EN)
-               len += snprintf(buf + len, size - len, "TIM ");
-       if (reg & AR_DTIM_TIMER_EN)
-               len += snprintf(buf + len, size - len, "DTIM ");
-       len += snprintf(buf + len, size - len, ")\n");
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "RXFILTER: 0x%x", rxfilter);
+
+       if (rxfilter & ATH9K_RX_FILTER_UCAST)
+               len += snprintf(buf + len, sizeof(buf) - len, " UCAST");
+       if (rxfilter & ATH9K_RX_FILTER_MCAST)
+               len += snprintf(buf + len, sizeof(buf) - len, " MCAST");
+       if (rxfilter & ATH9K_RX_FILTER_BCAST)
+               len += snprintf(buf + len, sizeof(buf) - len, " BCAST");
+       if (rxfilter & ATH9K_RX_FILTER_CONTROL)
+               len += snprintf(buf + len, sizeof(buf) - len, " CONTROL");
+       if (rxfilter & ATH9K_RX_FILTER_BEACON)
+               len += snprintf(buf + len, sizeof(buf) - len, " BEACON");
+       if (rxfilter & ATH9K_RX_FILTER_PROM)
+               len += snprintf(buf + len, sizeof(buf) - len, " PROM");
+       if (rxfilter & ATH9K_RX_FILTER_PROBEREQ)
+               len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ");
+       if (rxfilter & ATH9K_RX_FILTER_PHYERR)
+               len += snprintf(buf + len, sizeof(buf) - len, " PHYERR");
+       if (rxfilter & ATH9K_RX_FILTER_MYBEACON)
+               len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON");
+       if (rxfilter & ATH9K_RX_FILTER_COMP_BAR)
+               len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR");
+       if (rxfilter & ATH9K_RX_FILTER_PSPOLL)
+               len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL");
+       if (rxfilter & ATH9K_RX_FILTER_PHYRADAR)
+               len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR");
+       if (rxfilter & ATH9K_RX_FILTER_MCAST_BCAST_ALL)
+               len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL");
+       if (rxfilter & ATH9K_RX_FILTER_CONTROL_WRAPPER)
+               len += snprintf(buf + len, sizeof(buf) - len, " CONTROL_WRAPPER");
+
+       len += snprintf(buf + len, sizeof(buf) - len, "\n");
 
        reg = sc->sc_ah->imask;
-       len += snprintf(buf + len, size - len, "imask: 0x%x (", reg);
+
+       len += snprintf(buf + len, sizeof(buf) - len, "INTERRUPT-MASK: 0x%x", reg);
+
        if (reg & ATH9K_INT_SWBA)
-               len += snprintf(buf + len, size - len, "SWBA ");
+               len += snprintf(buf + len, sizeof(buf) - len, " SWBA");
        if (reg & ATH9K_INT_BMISS)
-               len += snprintf(buf + len, size - len, "BMISS ");
+               len += snprintf(buf + len, sizeof(buf) - len, " BMISS");
        if (reg & ATH9K_INT_CST)
-               len += snprintf(buf + len, size - len, "CST ");
+               len += snprintf(buf + len, sizeof(buf) - len, " CST");
        if (reg & ATH9K_INT_RX)
-               len += snprintf(buf + len, size - len, "RX ");
+               len += snprintf(buf + len, sizeof(buf) - len, " RX");
        if (reg & ATH9K_INT_RXHP)
-               len += snprintf(buf + len, size - len, "RXHP ");
+               len += snprintf(buf + len, sizeof(buf) - len, " RXHP");
        if (reg & ATH9K_INT_RXLP)
-               len += snprintf(buf + len, size - len, "RXLP ");
+               len += snprintf(buf + len, sizeof(buf) - len, " RXLP");
        if (reg & ATH9K_INT_BB_WATCHDOG)
-               len += snprintf(buf + len, size - len, "BB_WATCHDOG ");
-       /* there are other IRQs if one wanted to add them. */
-       len += snprintf(buf + len, size - len, ")\n");
+               len += snprintf(buf + len, sizeof(buf) - len, " BB_WATCHDOG");
 
-       len += snprintf(buf + len, size - len,
-                       "VIF Counts: AP: %i STA: %i MESH: %i WDS: %i"
-                       " ADHOC: %i OTHER: %i nvifs: %hi beacon-vifs: %hi\n",
+       len += snprintf(buf + len, sizeof(buf) - len, "\n");
+
+       ath9k_calculate_iter_data(hw, NULL, &iter_data);
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i"
+                       " ADHOC: %i OTHER: %i TOTAL: %hi BEACON-VIF: %hi\n",
                        iter_data.naps, iter_data.nstations, iter_data.nmeshes,
                        iter_data.nwds, iter_data.nadhocs, iter_data.nothers,
                        sc->nvifs, sc->nbcnvifs);
 
-       len += snprintf(buf + len, size - len,
-                       "Calculated-BSSID-Mask: %pM\n",
-                       iter_data.mask);
-
-       if (len > size)
-               len = size;
+       if (len > sizeof(buf))
+               len = sizeof(buf);
 
        retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-       kfree(buf);
-
        return retval;
 }
 
+static ssize_t read_file_reset(struct file *file, char __user *user_buf,
+                              size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[512];
+       unsigned int len = 0;
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "%17s: %2d\n", "Baseband Hang",
+                       sc->debug.stats.reset[RESET_TYPE_BB_HANG]);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "%17s: %2d\n", "Baseband Watchdog",
+                       sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "%17s: %2d\n", "Fatal HW Error",
+                       sc->debug.stats.reset[RESET_TYPE_FATAL_INT]);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "%17s: %2d\n", "TX HW error",
+                       sc->debug.stats.reset[RESET_TYPE_TX_ERROR]);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "%17s: %2d\n", "TX Path Hang",
+                       sc->debug.stats.reset[RESET_TYPE_TX_HANG]);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "%17s: %2d\n", "PLL RX Hang",
+                       sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
+
+       if (len > sizeof(buf))
+               len = sizeof(buf);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
                       struct ath_tx_status *ts, struct ath_txq *txq,
                       unsigned int flags)
@@ -880,6 +818,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
        if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
                TX_STAT_INC(qnum, delim_underrun);
 
+#ifdef CONFIG_ATH9K_MAC_DEBUG
        spin_lock(&sc->debug.samp_lock);
        TX_SAMP_DBG(jiffies) = jiffies;
        TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0;
@@ -906,6 +845,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
 
        sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES;
        spin_unlock(&sc->debug.samp_lock);
+#endif
 
 #undef TX_SAMP_DBG
 }
@@ -931,16 +871,23 @@ static const struct file_operations fops_misc = {
        .llseek = default_llseek,
 };
 
+static const struct file_operations fops_reset = {
+       .read = read_file_reset,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
 static ssize_t read_file_recv(struct file *file, char __user *user_buf,
                              size_t count, loff_t *ppos)
 {
 #define PHY_ERR(s, p) \
-       len += snprintf(buf + len, size - len, "%18s : %10u\n", s, \
+       len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \
                        sc->debug.stats.rxstats.phy_err_stats[p]);
 
        struct ath_softc *sc = file->private_data;
        char *buf;
-       unsigned int len = 0, size = 1400;
+       unsigned int len = 0, size = 1600;
        ssize_t retval = 0;
 
        buf = kzalloc(size, GFP_KERNEL);
@@ -948,87 +895,59 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
                return -ENOMEM;
 
        len += snprintf(buf + len, size - len,
-                       "%18s : %10u\n", "CRC ERR",
+                       "%22s : %10u\n", "CRC ERR",
                        sc->debug.stats.rxstats.crc_err);
        len += snprintf(buf + len, size - len,
-                       "%18s : %10u\n", "DECRYPT CRC ERR",
+                       "%22s : %10u\n", "DECRYPT CRC ERR",
                        sc->debug.stats.rxstats.decrypt_crc_err);
        len += snprintf(buf + len, size - len,
-                       "%18s : %10u\n", "PHY ERR",
+                       "%22s : %10u\n", "PHY ERR",
                        sc->debug.stats.rxstats.phy_err);
        len += snprintf(buf + len, size - len,
-                       "%18s : %10u\n", "MIC ERR",
+                       "%22s : %10u\n", "MIC ERR",
                        sc->debug.stats.rxstats.mic_err);
        len += snprintf(buf + len, size - len,
-                       "%18s : %10u\n", "PRE-DELIM CRC ERR",
+                       "%22s : %10u\n", "PRE-DELIM CRC ERR",
                        sc->debug.stats.rxstats.pre_delim_crc_err);
        len += snprintf(buf + len, size - len,
-                       "%18s : %10u\n", "POST-DELIM CRC ERR",
+                       "%22s : %10u\n", "POST-DELIM CRC ERR",
                        sc->debug.stats.rxstats.post_delim_crc_err);
        len += snprintf(buf + len, size - len,
-                       "%18s : %10u\n", "DECRYPT BUSY ERR",
+                       "%22s : %10u\n", "DECRYPT BUSY ERR",
                        sc->debug.stats.rxstats.decrypt_busy_err);
 
-       len += snprintf(buf + len, size - len,
-                       "%18s : %10d\n", "RSSI-CTL0",
-                       sc->debug.stats.rxstats.rs_rssi_ctl0);
-
-       len += snprintf(buf + len, size - len,
-                       "%18s : %10d\n", "RSSI-CTL1",
-                       sc->debug.stats.rxstats.rs_rssi_ctl1);
-
-       len += snprintf(buf + len, size - len,
-                       "%18s : %10d\n", "RSSI-CTL2",
-                       sc->debug.stats.rxstats.rs_rssi_ctl2);
-
-       len += snprintf(buf + len, size - len,
-                       "%18s : %10d\n", "RSSI-EXT0",
-                       sc->debug.stats.rxstats.rs_rssi_ext0);
+       PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
+       PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
+       PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY);
+       PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE);
+       PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH);
+       PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
+       PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
+       PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
+       PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
+       PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
+       PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
+       PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
+       PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
+       PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
+       PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
+       PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
+       PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
+       PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
+       PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
+       PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
+       PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
+       PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
+       PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
+       PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
+       PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
+       PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
 
        len += snprintf(buf + len, size - len,
-                       "%18s : %10d\n", "RSSI-EXT1",
-                       sc->debug.stats.rxstats.rs_rssi_ext1);
-
-       len += snprintf(buf + len, size - len,
-                       "%18s : %10d\n", "RSSI-EXT2",
-                       sc->debug.stats.rxstats.rs_rssi_ext2);
-
-       len += snprintf(buf + len, size - len,
-                       "%18s : %10d\n", "Rx Antenna",
-                       sc->debug.stats.rxstats.rs_antenna);
-
-       PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
-       PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
-       PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
-       PHY_ERR("RATE", ATH9K_PHYERR_RATE);
-       PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
-       PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
-       PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
-       PHY_ERR("TOR", ATH9K_PHYERR_TOR);
-       PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
-       PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
-       PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
-       PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
-       PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
-       PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
-       PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
-       PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
-       PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
-       PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
-       PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
-       PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
-       PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
-       PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
-       PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
-       PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
-       PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
-       PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
-
-       len += snprintf(buf + len, size - len,
-                       "%18s : %10u\n", "RX-Pkts-All",
+                       "%22s : %10u\n", "RX-Pkts-All",
                        sc->debug.stats.rxstats.rx_pkts_all);
        len += snprintf(buf + len, size - len,
-                       "%18s : %10u\n", "RX-Bytes-All",
+                       "%22s : %10u\n", "RX-Bytes-All",
                        sc->debug.stats.rxstats.rx_bytes_all);
 
        if (len > size)
@@ -1049,8 +968,6 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
 #define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\
                        [sc->debug.rsidx].c)
 
-       u32 phyerr;
-
        RX_STAT_INC(rx_pkts_all);
        sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen;
 
@@ -1069,20 +986,11 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
 
        if (rs->rs_status & ATH9K_RXERR_PHY) {
                RX_STAT_INC(phy_err);
-               phyerr = rs->rs_phyerr & 0x24;
-               RX_PHY_ERR_INC(phyerr);
+               if (rs->rs_phyerr < ATH9K_PHYERR_MAX)
+                       RX_PHY_ERR_INC(rs->rs_phyerr);
        }
 
-       sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0;
-       sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1;
-       sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2;
-
-       sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0;
-       sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1;
-       sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2;
-
-       sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna;
-
+#ifdef CONFIG_ATH9K_MAC_DEBUG
        spin_lock(&sc->debug.samp_lock);
        RX_SAMP_DBG(jiffies) = jiffies;
        RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
@@ -1099,6 +1007,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
        sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES;
        spin_unlock(&sc->debug.samp_lock);
 
+#endif
+
 #undef RX_STAT_INC
 #undef RX_PHY_ERR_INC
 #undef RX_SAMP_DBG
@@ -1342,6 +1252,8 @@ static const struct file_operations fops_modal_eeprom = {
        .llseek = default_llseek,
 };
 
+#ifdef CONFIG_ATH9K_MAC_DEBUG
+
 void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
 {
 #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c)
@@ -1615,6 +1527,7 @@ static const struct file_operations fops_samps = {
        .llseek = default_llseek,
 };
 
+#endif
 
 int ath9k_init_debug(struct ath_hw *ah)
 {
@@ -1637,14 +1550,14 @@ int ath9k_init_debug(struct ath_hw *ah)
                            &fops_dma);
        debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_interrupt);
-       debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
-                           sc, &fops_wiphy);
        debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_xmit);
        debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_stations);
        debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_misc);
+       debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc,
+                           &fops_reset);
        debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_recv);
        debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
@@ -1668,8 +1581,10 @@ int ath9k_init_debug(struct ath_hw *ah)
                            &fops_base_eeprom);
        debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_modal_eeprom);
+#ifdef CONFIG_ATH9K_MAC_DEBUG
        debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_samps);
+#endif
 
        debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
                           sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
@@ -1677,10 +1592,5 @@ int ath9k_init_debug(struct ath_hw *ah)
        debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
                           sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
 
-       sc->debug.regidx = 0;
-       memset(&sc->debug.bb_mac_samp, 0, sizeof(sc->debug.bb_mac_samp));
-       sc->debug.sampidx = 0;
-       sc->debug.tsidx = 0;
-       sc->debug.rsidx = 0;
        return 0;
 }
index 776a24ada600fc377940851a4abbe7e3fa8a2001..64fcfad467bf44a38e325d2aed6a4bbee4adfc37 100644 (file)
@@ -165,13 +165,6 @@ struct ath_rx_stats {
        u32 post_delim_crc_err;
        u32 decrypt_busy_err;
        u32 phy_err_stats[ATH9K_PHYERR_MAX];
-       int8_t rs_rssi_ctl0;
-       int8_t rs_rssi_ctl1;
-       int8_t rs_rssi_ctl2;
-       int8_t rs_rssi_ext0;
-       int8_t rs_rssi_ext1;
-       int8_t rs_rssi_ext2;
-       u8 rs_antenna;
 };
 
 enum ath_reset_type {
@@ -235,16 +228,17 @@ struct ath9k_debug {
        struct dentry *debugfs_phy;
        u32 regidx;
        struct ath_stats stats;
+#ifdef CONFIG_ATH9K_MAC_DEBUG
        spinlock_t samp_lock;
        struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES];
        u8 sampidx;
        u8 tsidx;
        u8 rsidx;
+#endif
 };
 
 int ath9k_init_debug(struct ath_hw *ah);
 
-void ath9k_debug_samp_bb_mac(struct ath_softc *sc);
 void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
                       struct ath_tx_status *ts, struct ath_txq *txq,
@@ -258,10 +252,6 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
        return 0;
 }
 
-static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
-{
-}
-
 static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
                                            enum ath9k_int status)
 {
@@ -282,4 +272,17 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
 
 #endif /* CONFIG_ATH9K_DEBUGFS */
 
+#ifdef CONFIG_ATH9K_MAC_DEBUG
+
+void ath9k_debug_samp_bb_mac(struct ath_softc *sc);
+
+#else
+
+static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
+{
+}
+
+#endif
+
+
 #endif /* DEBUG_H */
index 597c84e31adb3b30a69ea7beb4f91b9890a2a662..63e4c4b1cb3d7a160c39a0d23224c0d472670d7a 100644 (file)
@@ -110,6 +110,8 @@ void ath_start_rfkill_poll(struct ath_softc *sc)
                wiphy_rfkill_start_polling(sc->hw->wiphy);
 }
 
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+
 /******************/
 /*     BTCOEX     */
 /******************/
@@ -245,13 +247,10 @@ static void ath_btcoex_no_stomp_timer(void *arg)
        ath9k_ps_restore(sc);
 }
 
-int ath_init_btcoex_timer(struct ath_softc *sc)
+static int ath_init_btcoex_timer(struct ath_softc *sc)
 {
        struct ath_btcoex *btcoex = &sc->btcoex;
 
-       if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_NONE)
-               return 0;
-
        btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
        btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
                btcoex->btcoex_period / 100;
@@ -284,9 +283,6 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
 
        ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n");
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        /* make sure duty cycle timer is also stopped when resuming */
        if (btcoex->hw_timer_enabled)
                ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
@@ -307,9 +303,6 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc)
        struct ath_btcoex *btcoex = &sc->btcoex;
        struct ath_hw *ah = sc->sc_ah;
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        del_timer_sync(&btcoex->period_timer);
 
        if (btcoex->hw_timer_enabled)
@@ -317,3 +310,113 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc)
 
        btcoex->hw_timer_enabled = false;
 }
+
+u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen)
+{
+       struct ath_mci_profile *mci = &sc->btcoex.mci;
+       u16 aggr_limit = 0;
+
+       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit)
+               aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4;
+       else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED)
+               aggr_limit = min((max_4ms_framelen * 3) / 8,
+                                (u32)ATH_AMPDU_LIMIT_MAX);
+
+       return aggr_limit;
+}
+
+void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status)
+{
+       struct ath_hw *ah = sc->sc_ah;
+
+       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
+               if (status & ATH9K_INT_GENTIMER)
+                       ath_gen_timer_isr(sc->sc_ah);
+
+       if (status & ATH9K_INT_MCI)
+               ath_mci_intr(sc);
+}
+
+void ath9k_start_btcoex(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+
+       if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) &&
+           !ah->btcoex_hw.enabled) {
+               if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
+                       ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+                                                  AR_STOMP_LOW_WLAN_WGHT);
+               ath9k_hw_btcoex_enable(ah);
+
+               if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
+                       ath9k_btcoex_timer_resume(sc);
+       }
+}
+
+void ath9k_stop_btcoex(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+
+       if (ah->btcoex_hw.enabled &&
+           ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
+               ath9k_hw_btcoex_disable(ah);
+               if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
+                       ath9k_btcoex_timer_pause(sc);
+               ath_mci_flush_profile(&sc->btcoex.mci);
+       }
+}
+
+void ath9k_deinit_btcoex(struct ath_softc *sc)
+{
+        if ((sc->btcoex.no_stomp_timer) &&
+           ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE)
+               ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
+
+       if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI)
+               ath_mci_cleanup(sc);
+}
+
+int ath9k_init_btcoex(struct ath_softc *sc)
+{
+       struct ath_txq *txq;
+       struct ath_hw *ah = sc->sc_ah;
+       int r;
+
+       ath9k_hw_btcoex_init_scheme(ah);
+
+       switch (ath9k_hw_get_btcoex_scheme(sc->sc_ah)) {
+       case ATH_BTCOEX_CFG_NONE:
+               break;
+       case ATH_BTCOEX_CFG_2WIRE:
+               ath9k_hw_btcoex_init_2wire(sc->sc_ah);
+               break;
+       case ATH_BTCOEX_CFG_3WIRE:
+               ath9k_hw_btcoex_init_3wire(sc->sc_ah);
+               r = ath_init_btcoex_timer(sc);
+               if (r)
+                       return -1;
+               txq = sc->tx.txq_map[WME_AC_BE];
+               ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
+               sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+               break;
+       case ATH_BTCOEX_CFG_MCI:
+               sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+               sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
+               INIT_LIST_HEAD(&sc->btcoex.mci.info);
+
+               r = ath_mci_setup(sc);
+               if (r)
+                       return r;
+
+               ath9k_hw_btcoex_init_mci(ah);
+
+               break;
+       default:
+               WARN_ON(1);
+               break;
+       }
+
+       return 0;
+}
+
+#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
index 77c8ded8de57bd7738bf62925383414cb01da951..424aabb2c7302db2bc74d4ca52256ae61fcac222 100644 (file)
@@ -968,8 +968,7 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
        ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
 }
 
-static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
-                                    u32 drv_info)
+static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
 {
        int transfer, err;
        const void *data = hif_dev->firmware->data;
@@ -982,7 +981,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
                return -ENOMEM;
 
        while (len) {
-               transfer = min_t(int, len, 4096);
+               transfer = min_t(size_t, len, 4096);
                memcpy(buf, data, transfer);
 
                err = usb_control_msg(hif_dev->udev,
@@ -1000,7 +999,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
        }
        kfree(buf);
 
-       if (IS_AR7010_DEVICE(drv_info))
+       if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info))
                firm_offset = AR7010_FIRMWARE_TEXT;
        else
                firm_offset = AR9271_FIRMWARE_TEXT;
@@ -1021,28 +1020,18 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
        return 0;
 }
 
-static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info)
+static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
 {
-       int ret, idx;
        struct usb_host_interface *alt = &hif_dev->interface->altsetting[0];
        struct usb_endpoint_descriptor *endp;
+       int ret, idx;
 
-       /* Request firmware */
-       ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name,
-                              &hif_dev->udev->dev);
-       if (ret) {
-               dev_err(&hif_dev->udev->dev,
-                       "ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name);
-               goto err_fw_req;
-       }
-
-       /* Download firmware */
-       ret = ath9k_hif_usb_download_fw(hif_dev, drv_info);
+       ret = ath9k_hif_usb_download_fw(hif_dev);
        if (ret) {
                dev_err(&hif_dev->udev->dev,
                        "ath9k_htc: Firmware - %s download failed\n",
                        hif_dev->fw_name);
-               goto err_fw_download;
+               return ret;
        }
 
        /* On downloading the firmware to the target, the USB descriptor of EP4
@@ -1064,23 +1053,84 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info)
        if (ret) {
                dev_err(&hif_dev->udev->dev,
                        "ath9k_htc: Unable to allocate URBs\n");
-               goto err_fw_download;
+               return ret;
        }
 
        return 0;
-
-err_fw_download:
-       release_firmware(hif_dev->firmware);
-err_fw_req:
-       hif_dev->firmware = NULL;
-       return ret;
 }
 
 static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
 {
        ath9k_hif_usb_dealloc_urbs(hif_dev);
-       if (hif_dev->firmware)
-               release_firmware(hif_dev->firmware);
+}
+
+/*
+ * If initialization fails or the FW cannot be retrieved,
+ * detach the device.
+ */
+static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev)
+{
+       struct device *parent = hif_dev->udev->dev.parent;
+
+       complete(&hif_dev->fw_done);
+
+       if (parent)
+               device_lock(parent);
+
+       device_release_driver(&hif_dev->udev->dev);
+
+       if (parent)
+               device_unlock(parent);
+}
+
+static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
+{
+       struct hif_device_usb *hif_dev = context;
+       int ret;
+
+       if (!fw) {
+               dev_err(&hif_dev->udev->dev,
+                       "ath9k_htc: Failed to get firmware %s\n",
+                       hif_dev->fw_name);
+               goto err_fw;
+       }
+
+       hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb,
+                                                &hif_dev->udev->dev);
+       if (hif_dev->htc_handle == NULL) {
+               goto err_fw;
+       }
+
+       hif_dev->firmware = fw;
+
+       /* Proceed with initialization */
+
+       ret = ath9k_hif_usb_dev_init(hif_dev);
+       if (ret)
+               goto err_dev_init;
+
+       ret = ath9k_htc_hw_init(hif_dev->htc_handle,
+                               &hif_dev->interface->dev,
+                               hif_dev->usb_device_id->idProduct,
+                               hif_dev->udev->product,
+                               hif_dev->usb_device_id->driver_info);
+       if (ret) {
+               ret = -EINVAL;
+               goto err_htc_hw_init;
+       }
+
+       complete(&hif_dev->fw_done);
+
+       return;
+
+err_htc_hw_init:
+       ath9k_hif_usb_dev_deinit(hif_dev);
+err_dev_init:
+       ath9k_htc_hw_free(hif_dev->htc_handle);
+       release_firmware(fw);
+       hif_dev->firmware = NULL;
+err_fw:
+       ath9k_hif_usb_firmware_fail(hif_dev);
 }
 
 /*
@@ -1155,20 +1205,16 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
        }
 
        usb_get_dev(udev);
+
        hif_dev->udev = udev;
        hif_dev->interface = interface;
-       hif_dev->device_id = id->idProduct;
+       hif_dev->usb_device_id = id;
 #ifdef CONFIG_PM
        udev->reset_resume = 1;
 #endif
        usb_set_intfdata(interface, hif_dev);
 
-       hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb,
-                                                &hif_dev->udev->dev);
-       if (hif_dev->htc_handle == NULL) {
-               ret = -ENOMEM;
-               goto err_htc_hw_alloc;
-       }
+       init_completion(&hif_dev->fw_done);
 
        /* Find out which firmware to load */
 
@@ -1177,29 +1223,22 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
        else
                hif_dev->fw_name = FIRMWARE_AR9271;
 
-       ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info);
-       if (ret) {
-               ret = -EINVAL;
-               goto err_hif_init_usb;
-       }
-
-       ret = ath9k_htc_hw_init(hif_dev->htc_handle,
-                               &interface->dev, hif_dev->device_id,
-                               hif_dev->udev->product, id->driver_info);
+       ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name,
+                                     &hif_dev->udev->dev, GFP_KERNEL,
+                                     hif_dev, ath9k_hif_usb_firmware_cb);
        if (ret) {
-               ret = -EINVAL;
-               goto err_htc_hw_init;
+               dev_err(&hif_dev->udev->dev,
+                       "ath9k_htc: Async request for firmware %s failed\n",
+                       hif_dev->fw_name);
+               goto err_fw_req;
        }
 
-       dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n");
+       dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n",
+                hif_dev->fw_name);
 
        return 0;
 
-err_htc_hw_init:
-       ath9k_hif_usb_dev_deinit(hif_dev);
-err_hif_init_usb:
-       ath9k_htc_hw_free(hif_dev->htc_handle);
-err_htc_hw_alloc:
+err_fw_req:
        usb_set_intfdata(interface, NULL);
        kfree(hif_dev);
        usb_put_dev(udev);
@@ -1234,9 +1273,15 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
        if (!hif_dev)
                return;
 
-       ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
-       ath9k_htc_hw_free(hif_dev->htc_handle);
-       ath9k_hif_usb_dev_deinit(hif_dev);
+       wait_for_completion(&hif_dev->fw_done);
+
+       if (hif_dev->firmware) {
+               ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
+               ath9k_htc_hw_free(hif_dev->htc_handle);
+               ath9k_hif_usb_dev_deinit(hif_dev);
+               release_firmware(hif_dev->firmware);
+       }
+
        usb_set_intfdata(interface, NULL);
 
        if (!unplugged && (hif_dev->flags & HIF_USB_START))
@@ -1276,8 +1321,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface)
                return ret;
 
        if (hif_dev->firmware) {
-               ret = ath9k_hif_usb_download_fw(hif_dev,
-                               htc_handle->drv_priv->ah->hw_version.usbdev);
+               ret = ath9k_hif_usb_download_fw(hif_dev);
                if (ret)
                        goto fail_resume;
        } else {
index 794f63094e5d66db28189cc248e106474358497e..487ff658b4c1890f597045c739d919ff6dd16689 100644 (file)
@@ -87,10 +87,11 @@ struct cmd_buf {
 #define HIF_USB_START BIT(0)
 
 struct hif_device_usb {
-       u16 device_id;
        struct usb_device *udev;
        struct usb_interface *interface;
+       const struct usb_device_id *usb_device_id;
        const struct firmware *firmware;
+       struct completion fw_done;
        struct htc_target *htc_handle;
        struct hif_usb_tx tx;
        struct usb_anchor regout_submitted;
index da5596766d8219791948a2f2ca26c719ec9ee7aa..135795257d95ab2a13ef684598a4ca3d57912470 100644 (file)
@@ -400,9 +400,21 @@ struct ath_btcoex {
        u32 btscan_no_stomp;
 };
 
-void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv);
-void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv);
-void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product);
+void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv);
+void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv);
+#else
+static inline void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product)
+{
+}
+static inline void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv)
+{
+}
+static inline void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)
+{
+}
+#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
 
 #define OP_INVALID                BIT(0)
 #define OP_SCANNING               BIT(1)
@@ -483,7 +495,10 @@ struct ath9k_htc_priv {
        int cabq;
        int hwq_map[WME_NUM_AC];
 
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
        struct ath_btcoex btcoex;
+#endif
+
        struct delayed_work coex_period_work;
        struct delayed_work duty_cycle_work;
 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
index 6506e1fd503649ad42246b84c49c618b5b818ad9..1c10e2e5c237d2a8233b8a09ae056b0a909f7bb2 100644 (file)
 /*     BTCOEX     */
 /******************/
 
+#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193"
+
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+
 /*
  * Detects if there is any priority bt traffic
  */
@@ -111,13 +115,10 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work)
        ath9k_hw_btcoex_enable(priv->ah);
 }
 
-void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
+static void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
 {
        struct ath_btcoex *btcoex = &priv->btcoex;
 
-       if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD;
        btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
                btcoex->btcoex_period / 100;
@@ -131,14 +132,11 @@ void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
  * (Re)start btcoex work
  */
 
-void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv)
+static void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv)
 {
        struct ath_btcoex *btcoex = &priv->btcoex;
        struct ath_hw *ah = priv->ah;
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex work\n");
 
        btcoex->bt_priority_cnt = 0;
@@ -151,15 +149,66 @@ void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv)
 /*
  * Cancel btcoex and bt duty cycle work.
  */
-void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
+static void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
 {
-       if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE)
-               return;
-
        cancel_delayed_work_sync(&priv->coex_period_work);
        cancel_delayed_work_sync(&priv->duty_cycle_work);
 }
 
+void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv)
+{
+       struct ath_hw *ah = priv->ah;
+
+       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) {
+               ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+                                          AR_STOMP_LOW_WLAN_WGHT);
+               ath9k_hw_btcoex_enable(ah);
+               ath_htc_resume_btcoex_work(priv);
+       }
+}
+
+void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)
+{
+       struct ath_hw *ah = priv->ah;
+
+       if (ah->btcoex_hw.enabled &&
+           ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
+               ath9k_hw_btcoex_disable(ah);
+               if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+                       ath_htc_cancel_btcoex_work(priv);
+       }
+}
+
+void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product)
+{
+       struct ath_hw *ah = priv->ah;
+       int qnum;
+
+       if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) {
+               ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE;
+       }
+
+       switch (ath9k_hw_get_btcoex_scheme(priv->ah)) {
+       case ATH_BTCOEX_CFG_NONE:
+               break;
+       case ATH_BTCOEX_CFG_3WIRE:
+               priv->ah->btcoex_hw.btactive_gpio = 7;
+               priv->ah->btcoex_hw.btpriority_gpio = 6;
+               priv->ah->btcoex_hw.wlanactive_gpio = 8;
+               priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+               ath9k_hw_btcoex_init_3wire(priv->ah);
+               ath_htc_init_btcoex_work(priv);
+               qnum = priv->hwq_map[WME_AC_BE];
+               ath9k_hw_init_btcoex_hw(priv->ah, qnum);
+               break;
+       default:
+               WARN_ON(1);
+               break;
+       }
+}
+
+#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
+
 /*******/
 /* LED */
 /*******/
index 9be10a2da1c29cc48f6a96656a596c8cf6e6c5c4..de5ee15ee639f7964509c679580cadb2b3d95417 100644 (file)
@@ -41,8 +41,6 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
        .max_power = 20, \
 }
 
-#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193"
-
 static struct ieee80211_channel ath9k_2ghz_channels[] = {
        CHAN2G(2412, 0), /* Channel 1 */
        CHAN2G(2417, 1), /* Channel 2 */
@@ -603,29 +601,6 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv)
        priv->ah->opmode = NL80211_IFTYPE_STATION;
 }
 
-static void ath9k_init_btcoex(struct ath9k_htc_priv *priv)
-{
-       int qnum;
-
-       switch (ath9k_hw_get_btcoex_scheme(priv->ah)) {
-       case ATH_BTCOEX_CFG_NONE:
-               break;
-       case ATH_BTCOEX_CFG_3WIRE:
-               priv->ah->btcoex_hw.btactive_gpio = 7;
-               priv->ah->btcoex_hw.btpriority_gpio = 6;
-               priv->ah->btcoex_hw.wlanactive_gpio = 8;
-               priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
-               ath9k_hw_btcoex_init_3wire(priv->ah);
-               ath_htc_init_btcoex_work(priv);
-               qnum = priv->hwq_map[WME_AC_BE];
-               ath9k_hw_init_btcoex_hw(priv->ah, qnum);
-               break;
-       default:
-               WARN_ON(1);
-               break;
-       }
-}
-
 static int ath9k_init_priv(struct ath9k_htc_priv *priv,
                           u16 devid, char *product,
                           u32 drv_info)
@@ -698,12 +673,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
        ath9k_cmn_init_crypto(ah);
        ath9k_init_channels_rates(priv);
        ath9k_init_misc(priv);
-
-       if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) {
-               ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE;
-               if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE)
-                       ath9k_init_btcoex(priv);
-       }
+       ath9k_htc_init_btcoex(priv, product);
 
        return 0;
 
@@ -741,6 +711,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
 
        hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
+       hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
        hw->queues = 4;
        hw->channel_change_time = 5000;
        hw->max_listen_interval = 10;
index ef4c6066129022d90bda90416a65bdab93d59c27..2a29a7cdef18f34630098025a916314b7600d9af 100644 (file)
@@ -957,12 +957,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
        mod_timer(&priv->tx.cleanup_timer,
                  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) {
-               ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
-                                          AR_STOMP_LOW_WLAN_WGHT);
-               ath9k_hw_btcoex_enable(ah);
-               ath_htc_resume_btcoex_work(priv);
-       }
+       ath9k_htc_start_btcoex(priv);
+
        mutex_unlock(&priv->mutex);
 
        return ret;
@@ -1009,12 +1005,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
 
        mutex_lock(&priv->mutex);
 
-       if (ah->btcoex_hw.enabled &&
-           ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
-               ath9k_hw_btcoex_disable(ah);
-               if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
-                       ath_htc_cancel_btcoex_work(priv);
-       }
+       ath9k_htc_stop_btcoex(priv);
 
        /* Remove a monitor interface if it's present. */
        if (priv->ah->is_monitoring)
@@ -1409,6 +1400,21 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw,
        if (htc_modparam_nohwcrypt)
                return -ENOSPC;
 
+       if ((vif->type == NL80211_IFTYPE_ADHOC ||
+            vif->type == NL80211_IFTYPE_MESH_POINT) &&
+           (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
+            key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
+           !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+               /*
+                * For now, disable hw crypto for the RSN IBSS group keys. This
+                * could be optimized in the future to use a modified key cache
+                * design to support per-STA RX GTK, but until that gets
+                * implemented, use of software crypto for group addressed
+                * frames is a acceptable to allow RSN IBSS to be used.
+                */
+               return -EOPNOTSUPP;
+       }
+
        mutex_lock(&priv->mutex);
        ath_dbg(common, CONFIG, "Set HW Key\n");
        ath9k_htc_ps_wakeup(priv);
index 87db1ee1c298ae32ac1434e7f3db58e25bfbee92..d582cf73098fec9b06595babeaa2036c3ad6992b 100644 (file)
@@ -23,6 +23,7 @@
 #include "hw-ops.h"
 #include "rc.h"
 #include "ar9003_mac.h"
+#include "ar9003_mci.h"
 
 static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
 
@@ -1385,10 +1386,16 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
 static bool ath9k_hw_chip_reset(struct ath_hw *ah,
                                struct ath9k_channel *chan)
 {
-       if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) {
-               if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
-                       return false;
-       } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+       int reset_type = ATH9K_RESET_WARM;
+
+       if (AR_SREV_9280(ah)) {
+               if (ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+                       reset_type = ATH9K_RESET_POWER_ON;
+               else
+                       reset_type = ATH9K_RESET_COLD;
+       }
+
+       if (!ath9k_hw_set_reset_reg(ah, reset_type))
                return false;
 
        if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
@@ -1518,61 +1525,22 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                   struct ath9k_hw_cal_data *caldata, bool bChannelChange)
 {
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
        u32 saveLedState;
        struct ath9k_channel *curchan = ah->curchan;
        u32 saveDefAntenna;
        u32 macStaId1;
        u64 tsf = 0;
        int i, r;
-       bool allow_fbs = false;
+       bool allow_fbs = false, start_mci_reset = false;
        bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI);
        bool save_fullsleep = ah->chip_fullsleep;
 
        if (mci) {
-
-               ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan));
-
-               if (mci_hw->bt_state == MCI_BT_CAL_START) {
-                       u32 payload[4] = {0, 0, 0, 0};
-
-                       ath_dbg(common, MCI, "MCI stop rx for BT CAL\n");
-
-                       mci_hw->bt_state = MCI_BT_CAL;
-
-                       /*
-                        * MCI FIX: disable mci interrupt here. This is to avoid
-                        * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
-                        * lead to mci_intr reentry.
-                        */
-
-                       ar9003_mci_disable_interrupt(ah);
-
-                       ath_dbg(common, MCI, "send WLAN_CAL_GRANT\n");
-                       MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
-                       ar9003_mci_send_message(ah, MCI_GPM, 0, payload,
-                                               16, true, false);
-
-                       ath_dbg(common, MCI, "\nMCI BT is calibrating\n");
-
-                       /* Wait BT calibration to be completed for 25ms */
-
-                       if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE,
-                                                                 0, 25000))
-                               ath_dbg(common, MCI,
-                                       "MCI got BT_CAL_DONE\n");
-                       else
-                               ath_dbg(common, MCI,
-                                       "MCI ### BT cal takes to long, force bt_state to be bt_awake\n");
-                       mci_hw->bt_state = MCI_BT_AWAKE;
-                       /* MCI FIX: enable mci interrupt here */
-                       ar9003_mci_enable_interrupt(ah);
-
-                       return true;
-               }
+               start_mci_reset = ar9003_mci_start_reset(ah, chan);
+               if (start_mci_reset)
+                       return 0;
        }
 
-
        if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
                return -EIO;
 
@@ -1609,7 +1577,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                if (ath9k_hw_channel_change(ah, chan)) {
                        ath9k_hw_loadnf(ah, ah->curchan);
                        ath9k_hw_start_nfcal(ah, true);
-                       if (mci && mci_hw->ready)
+                       if (mci && ar9003_mci_is_ready(ah))
                                ar9003_mci_2g5g_switch(ah, true);
 
                        if (AR_SREV_9271(ah))
@@ -1618,19 +1586,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                }
        }
 
-       if (mci) {
-               ar9003_mci_disable_interrupt(ah);
-
-               if (mci_hw->ready && !save_fullsleep) {
-                       ar9003_mci_mute_bt(ah);
-                       udelay(20);
-                       REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
-               }
-
-               mci_hw->bt_state = MCI_BT_SLEEP;
-               mci_hw->ready = false;
-       }
-
+       if (mci)
+               ar9003_mci_stop_bt(ah, save_fullsleep);
 
        saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
        if (saveDefAntenna == 0)
@@ -1807,53 +1764,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        ath9k_hw_loadnf(ah, chan);
        ath9k_hw_start_nfcal(ah, true);
 
-       if (mci && mci_hw->ready) {
-
-               if (IS_CHAN_2GHZ(chan) &&
-                   (mci_hw->bt_state == MCI_BT_SLEEP)) {
-
-                       if (ar9003_mci_check_int(ah,
-                           AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
-                           ar9003_mci_check_int(ah,
-                           AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) {
-
-                               /*
-                                * BT is sleeping. Check if BT wakes up during
-                                * WLAN calibration. If BT wakes up during
-                                * WLAN calibration, need to go through all
-                                * message exchanges again and recal.
-                                */
-
-                               ath_dbg(common, MCI,
-                                       "MCI BT wakes up during WLAN calibration\n");
-
-                               REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
-                                         AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
-                                         AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
-                               ath_dbg(common, MCI, "MCI send REMOTE_RESET\n");
-                               ar9003_mci_remote_reset(ah, true);
-                               ar9003_mci_send_sys_waking(ah, true);
-                               udelay(1);
-                               if (IS_CHAN_2GHZ(chan))
-                                       ar9003_mci_send_lna_transfer(ah, true);
-
-                               mci_hw->bt_state = MCI_BT_AWAKE;
-
-                               ath_dbg(common, MCI, "MCI re-cal\n");
-
-                               if (caldata) {
-                                       caldata->done_txiqcal_once = false;
-                                       caldata->done_txclcal_once = false;
-                                       caldata->rtt_hist.num_readings = 0;
-                               }
-
-                               if (!ath9k_hw_init_cal(ah, chan))
-                                       return -EIO;
-
-                       }
-               }
-               ar9003_mci_enable_interrupt(ah);
-       }
+       if (mci && ar9003_mci_end_reset(ah, chan, caldata))
+               return -EIO;
 
        ENABLE_REGWRITE_BUFFER(ah);
 
@@ -1894,24 +1806,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 #endif
        }
 
-       if (ah->btcoex_hw.enabled &&
-           ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE)
+       if (ath9k_hw_btcoex_is_enabled(ah))
                ath9k_hw_btcoex_enable(ah);
 
-       if (mci && mci_hw->ready) {
-               /*
-                * check BT state again to make
-                * sure it's not changed.
-                */
-
-               ar9003_mci_sync_bt_state(ah);
-               ar9003_mci_2g5g_switch(ah, true);
-
-               if ((mci_hw->bt_state == MCI_BT_AWAKE) &&
-                               (mci_hw->query_bt == true)) {
-                       mci_hw->need_flush_btinfo = true;
-               }
-       }
+       if (mci)
+               ar9003_mci_check_bt(ah);
 
        if (AR_SREV_9300_20_OR_LATER(ah)) {
                ar9003_hw_bb_watchdog_config(ah);
@@ -1962,8 +1861,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
                        REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
 
                /* Shutdown chip. Active low */
-               if (!AR_SREV_5416(ah) &&
-                               !AR_SREV_9271(ah) && !AR_SREV_9462_10(ah)) {
+               if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) {
                        REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN);
                        udelay(2);
                }
@@ -2077,7 +1975,6 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
 bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 {
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
        int status = true, setChip = true;
        static const char *modes[] = {
                "AWAKE",
@@ -2101,20 +1998,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 
                break;
        case ATH9K_PM_FULL_SLEEP:
-
-               if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) {
-                       if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) &&
-                               (mci->bt_state != MCI_BT_SLEEP) &&
-                               !mci->halted_bt_gpm) {
-                               ath_dbg(common, MCI,
-                                       "MCI halt BT GPM (full_sleep)\n");
-                               ar9003_mci_send_coex_halt_bt_gpm(ah,
-                                                                true, true);
-                       }
-
-                       mci->ready = false;
-                       REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
-               }
+               if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI)
+                       ar9003_mci_set_full_sleep(ah);
 
                ath9k_set_power_sleep(ah, setChip);
                ah->chip_fullsleep = true;
@@ -2304,7 +2189,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
        struct ath9k_hw_capabilities *pCap = &ah->caps;
        struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
        unsigned int chip_chainmask;
 
        u16 eeval;
@@ -2423,30 +2307,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
        else
                pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
 
-       if (common->btcoex_enabled) {
-               if (AR_SREV_9462(ah))
-                       btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI;
-               else if (AR_SREV_9300_20_OR_LATER(ah)) {
-                       btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
-                       btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
-                       btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
-                       btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300;
-               } else if (AR_SREV_9280_20_OR_LATER(ah)) {
-                       btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280;
-                       btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280;
-
-                       if (AR_SREV_9285(ah)) {
-                               btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
-                               btcoex_hw->btpriority_gpio =
-                                               ATH_BTPRIORITY_GPIO_9285;
-                       } else {
-                               btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
-                       }
-               }
-       } else {
-               btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
-       }
-
        if (AR_SREV_9300_20_OR_LATER(ah)) {
                pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK;
                if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah))
index 6a29004a71b0864afe06f6c5a4b82b77f8c3d050..1707137e0a30a20fd117ad2826daf3636c39c62b 100644 (file)
@@ -209,11 +209,7 @@ enum ath9k_hw_caps {
        ATH9K_HW_CAP_5GHZ                       = BIT(12),
        ATH9K_HW_CAP_APM                        = BIT(13),
        ATH9K_HW_CAP_RTT                        = BIT(14),
-#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
        ATH9K_HW_CAP_MCI                        = BIT(15),
-#else
-       ATH9K_HW_CAP_MCI                        = 0,
-#endif
        ATH9K_HW_CAP_DFS                        = BIT(16),
 };
 
@@ -432,161 +428,6 @@ enum ath9k_rx_qtype {
        ATH9K_RX_QUEUE_MAX,
 };
 
-enum mci_message_header {              /* length of payload */
-       MCI_LNA_CTRL     = 0x10,        /* len = 0 */
-       MCI_CONT_NACK    = 0x20,        /* len = 0 */
-       MCI_CONT_INFO    = 0x30,        /* len = 4 */
-       MCI_CONT_RST     = 0x40,        /* len = 0 */
-       MCI_SCHD_INFO    = 0x50,        /* len = 16 */
-       MCI_CPU_INT      = 0x60,        /* len = 4 */
-       MCI_SYS_WAKING   = 0x70,        /* len = 0 */
-       MCI_GPM          = 0x80,        /* len = 16 */
-       MCI_LNA_INFO     = 0x90,        /* len = 1 */
-       MCI_LNA_STATE    = 0x94,
-       MCI_LNA_TAKE     = 0x98,
-       MCI_LNA_TRANS    = 0x9c,
-       MCI_SYS_SLEEPING = 0xa0,        /* len = 0 */
-       MCI_REQ_WAKE     = 0xc0,        /* len = 0 */
-       MCI_DEBUG_16     = 0xfe,        /* len = 2 */
-       MCI_REMOTE_RESET = 0xff         /* len = 16 */
-};
-
-enum ath_mci_gpm_coex_profile_type {
-       MCI_GPM_COEX_PROFILE_UNKNOWN,
-       MCI_GPM_COEX_PROFILE_RFCOMM,
-       MCI_GPM_COEX_PROFILE_A2DP,
-       MCI_GPM_COEX_PROFILE_HID,
-       MCI_GPM_COEX_PROFILE_BNEP,
-       MCI_GPM_COEX_PROFILE_VOICE,
-       MCI_GPM_COEX_PROFILE_MAX
-};
-
-/* MCI GPM/Coex opcode/type definitions */
-enum {
-       MCI_GPM_COEX_W_GPM_PAYLOAD      = 1,
-       MCI_GPM_COEX_B_GPM_TYPE         = 4,
-       MCI_GPM_COEX_B_GPM_OPCODE       = 5,
-       /* MCI_GPM_WLAN_CAL_REQ, MCI_GPM_WLAN_CAL_DONE */
-       MCI_GPM_WLAN_CAL_W_SEQUENCE     = 2,
-
-       /* MCI_GPM_COEX_VERSION_QUERY */
-       /* MCI_GPM_COEX_VERSION_RESPONSE */
-       MCI_GPM_COEX_B_MAJOR_VERSION    = 6,
-       MCI_GPM_COEX_B_MINOR_VERSION    = 7,
-       /* MCI_GPM_COEX_STATUS_QUERY */
-       MCI_GPM_COEX_B_BT_BITMAP        = 6,
-       MCI_GPM_COEX_B_WLAN_BITMAP      = 7,
-       /* MCI_GPM_COEX_HALT_BT_GPM */
-       MCI_GPM_COEX_B_HALT_STATE       = 6,
-       /* MCI_GPM_COEX_WLAN_CHANNELS */
-       MCI_GPM_COEX_B_CHANNEL_MAP      = 6,
-       /* MCI_GPM_COEX_BT_PROFILE_INFO */
-       MCI_GPM_COEX_B_PROFILE_TYPE     = 6,
-       MCI_GPM_COEX_B_PROFILE_LINKID   = 7,
-       MCI_GPM_COEX_B_PROFILE_STATE    = 8,
-       MCI_GPM_COEX_B_PROFILE_ROLE     = 9,
-       MCI_GPM_COEX_B_PROFILE_RATE     = 10,
-       MCI_GPM_COEX_B_PROFILE_VOTYPE   = 11,
-       MCI_GPM_COEX_H_PROFILE_T        = 12,
-       MCI_GPM_COEX_B_PROFILE_W        = 14,
-       MCI_GPM_COEX_B_PROFILE_A        = 15,
-       /* MCI_GPM_COEX_BT_STATUS_UPDATE */
-       MCI_GPM_COEX_B_STATUS_TYPE      = 6,
-       MCI_GPM_COEX_B_STATUS_LINKID    = 7,
-       MCI_GPM_COEX_B_STATUS_STATE     = 8,
-       /* MCI_GPM_COEX_BT_UPDATE_FLAGS */
-       MCI_GPM_COEX_W_BT_FLAGS         = 6,
-       MCI_GPM_COEX_B_BT_FLAGS_OP      = 10
-};
-
-enum mci_gpm_subtype {
-       MCI_GPM_BT_CAL_REQ      = 0,
-       MCI_GPM_BT_CAL_GRANT    = 1,
-       MCI_GPM_BT_CAL_DONE     = 2,
-       MCI_GPM_WLAN_CAL_REQ    = 3,
-       MCI_GPM_WLAN_CAL_GRANT  = 4,
-       MCI_GPM_WLAN_CAL_DONE   = 5,
-       MCI_GPM_COEX_AGENT      = 0x0c,
-       MCI_GPM_RSVD_PATTERN    = 0xfe,
-       MCI_GPM_RSVD_PATTERN32  = 0xfefefefe,
-       MCI_GPM_BT_DEBUG        = 0xff
-};
-
-enum mci_bt_state {
-       MCI_BT_SLEEP,
-       MCI_BT_AWAKE,
-       MCI_BT_CAL_START,
-       MCI_BT_CAL
-};
-
-/* Type of state query */
-enum mci_state_type {
-       MCI_STATE_ENABLE,
-       MCI_STATE_INIT_GPM_OFFSET,
-       MCI_STATE_NEXT_GPM_OFFSET,
-       MCI_STATE_LAST_GPM_OFFSET,
-       MCI_STATE_BT,
-       MCI_STATE_SET_BT_SLEEP,
-       MCI_STATE_SET_BT_AWAKE,
-       MCI_STATE_SET_BT_CAL_START,
-       MCI_STATE_SET_BT_CAL,
-       MCI_STATE_LAST_SCHD_MSG_OFFSET,
-       MCI_STATE_REMOTE_SLEEP,
-       MCI_STATE_CONT_RSSI_POWER,
-       MCI_STATE_CONT_PRIORITY,
-       MCI_STATE_CONT_TXRX,
-       MCI_STATE_RESET_REQ_WAKE,
-       MCI_STATE_SEND_WLAN_COEX_VERSION,
-       MCI_STATE_SET_BT_COEX_VERSION,
-       MCI_STATE_SEND_WLAN_CHANNELS,
-       MCI_STATE_SEND_VERSION_QUERY,
-       MCI_STATE_SEND_STATUS_QUERY,
-       MCI_STATE_NEED_FLUSH_BT_INFO,
-       MCI_STATE_SET_CONCUR_TX_PRI,
-       MCI_STATE_RECOVER_RX,
-       MCI_STATE_NEED_FTP_STOMP,
-       MCI_STATE_NEED_TUNING,
-       MCI_STATE_DEBUG,
-       MCI_STATE_MAX
-};
-
-enum mci_gpm_coex_opcode {
-       MCI_GPM_COEX_VERSION_QUERY,
-       MCI_GPM_COEX_VERSION_RESPONSE,
-       MCI_GPM_COEX_STATUS_QUERY,
-       MCI_GPM_COEX_HALT_BT_GPM,
-       MCI_GPM_COEX_WLAN_CHANNELS,
-       MCI_GPM_COEX_BT_PROFILE_INFO,
-       MCI_GPM_COEX_BT_STATUS_UPDATE,
-       MCI_GPM_COEX_BT_UPDATE_FLAGS
-};
-
-#define MCI_GPM_NOMORE  0
-#define MCI_GPM_MORE    1
-#define MCI_GPM_INVALID 0xffffffff
-
-#define MCI_GPM_RECYCLE(_p_gpm)        do {                      \
-       *(((u32 *)_p_gpm) + MCI_GPM_COEX_W_GPM_PAYLOAD) = \
-                               MCI_GPM_RSVD_PATTERN32;   \
-} while (0)
-
-#define MCI_GPM_TYPE(_p_gpm)   \
-       (*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) & 0xff)
-
-#define MCI_GPM_OPCODE(_p_gpm) \
-       (*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) & 0xff)
-
-#define MCI_GPM_SET_CAL_TYPE(_p_gpm, _cal_type)        do {                       \
-       *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_cal_type) & 0xff;\
-} while (0)
-
-#define MCI_GPM_SET_TYPE_OPCODE(_p_gpm, _type, _opcode) do {              \
-       *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_type) & 0xff;    \
-       *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) = (_opcode) & 0xff;\
-} while (0)
-
-#define MCI_GPM_IS_CAL_TYPE(_type) ((_type) <= MCI_GPM_WLAN_CAL_DONE)
-
 struct ath9k_beacon_state {
        u32 bs_nexttbtt;
        u32 bs_nextdtim;
@@ -940,7 +781,6 @@ struct ath_hw {
        u32 *analogBank6Data;
        u32 *analogBank6TPCData;
        u32 *analogBank7Data;
-       u32 *addac5416_21;
        u32 *bank6Temp;
 
        u8 txpower_limit;
@@ -957,8 +797,9 @@ struct ath_hw {
        int firpwr[5];
        enum ath9k_ani_cmd ani_function;
 
-       /* Bluetooth coexistance */
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
        struct ath_btcoex_hw btcoex_hw;
+#endif
 
        u32 intr_txqs;
        u8 txchainmask;
@@ -1206,41 +1047,31 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
 void ath9k_hw_proc_mib_event(struct ath_hw *ah);
 void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
 
-bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
-                            u32 *payload, u8 len, bool wait_done,
-                            bool check_bt);
-void ar9003_mci_mute_bt(struct ath_hw *ah);
-u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data);
-void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
-                     u16 len, u32 sched_addr);
-void ar9003_mci_cleanup(struct ath_hw *ah);
-void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt,
-                                     bool wait_done);
-u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
-                           u8 gpm_opcode, int time_out);
-void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g);
-void ar9003_mci_disable_interrupt(struct ath_hw *ah);
-void ar9003_mci_enable_interrupt(struct ath_hw *ah);
-void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done);
-void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
-                     bool is_full_sleep);
-bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints);
-void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done);
-void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done);
-void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done);
-void ar9003_mci_sync_bt_state(struct ath_hw *ah);
-void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
-                             u32 *rx_msg_intr);
-
 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah)
+{
+       return ah->btcoex_hw.enabled;
+}
+void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 static inline enum ath_btcoex_scheme
 ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
 {
        return ah->btcoex_hw.scheme;
 }
 #else
-#define ath9k_hw_get_btcoex_scheme(...) ATH_BTCOEX_CFG_NONE
-#endif
+static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah)
+{
+       return false;
+}
+static inline void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+{
+}
+static inline enum ath_btcoex_scheme
+ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
+{
+       return ATH_BTCOEX_CFG_NONE;
+}
+#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
 
 #define ATH9K_CLOCK_RATE_CCK           22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM     40
index 53a005d288aa53949da6e1317c57e294a092a907..944e9b518f1935ba61111d1ca1d6c6aa8eb89b24 100644 (file)
@@ -419,66 +419,6 @@ fail:
        return error;
 }
 
-static int ath9k_init_btcoex(struct ath_softc *sc)
-{
-       struct ath_txq *txq;
-       struct ath_hw *ah = sc->sc_ah;
-       int r;
-
-       switch (ath9k_hw_get_btcoex_scheme(sc->sc_ah)) {
-       case ATH_BTCOEX_CFG_NONE:
-               break;
-       case ATH_BTCOEX_CFG_2WIRE:
-               ath9k_hw_btcoex_init_2wire(sc->sc_ah);
-               break;
-       case ATH_BTCOEX_CFG_3WIRE:
-               ath9k_hw_btcoex_init_3wire(sc->sc_ah);
-               r = ath_init_btcoex_timer(sc);
-               if (r)
-                       return -1;
-               txq = sc->tx.txq_map[WME_AC_BE];
-               ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
-               sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
-               break;
-       case ATH_BTCOEX_CFG_MCI:
-               sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
-               sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
-               INIT_LIST_HEAD(&sc->btcoex.mci.info);
-
-               r = ath_mci_setup(sc);
-               if (r)
-                       return r;
-
-               if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) {
-                       ah->btcoex_hw.mci.ready = false;
-                       ah->btcoex_hw.mci.bt_state = 0;
-                       ah->btcoex_hw.mci.bt_ver_major = 3;
-                       ah->btcoex_hw.mci.bt_ver_minor = 0;
-                       ah->btcoex_hw.mci.bt_version_known = false;
-                       ah->btcoex_hw.mci.update_2g5g = true;
-                       ah->btcoex_hw.mci.is_2g = true;
-                       ah->btcoex_hw.mci.wlan_channels_update = false;
-                       ah->btcoex_hw.mci.wlan_channels[0] = 0x00000000;
-                       ah->btcoex_hw.mci.wlan_channels[1] = 0xffffffff;
-                       ah->btcoex_hw.mci.wlan_channels[2] = 0xffffffff;
-                       ah->btcoex_hw.mci.wlan_channels[3] = 0x7fffffff;
-                       ah->btcoex_hw.mci.query_bt = true;
-                       ah->btcoex_hw.mci.unhalt_bt_gpm = true;
-                       ah->btcoex_hw.mci.halted_bt_gpm = false;
-                       ah->btcoex_hw.mci.need_flush_btinfo = false;
-                       ah->btcoex_hw.mci.wlan_cal_seq = 0;
-                       ah->btcoex_hw.mci.wlan_cal_done = 0;
-                       ah->btcoex_hw.mci.config = 0x2201;
-               }
-               break;
-       default:
-               WARN_ON(1);
-               break;
-       }
-
-       return 0;
-}
-
 static int ath9k_init_queues(struct ath_softc *sc)
 {
        int i = 0;
@@ -615,8 +555,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
        mutex_init(&sc->mutex);
 #ifdef CONFIG_ATH9K_DEBUGFS
        spin_lock_init(&sc->nodes_lock);
-       spin_lock_init(&sc->debug.samp_lock);
        INIT_LIST_HEAD(&sc->nodes);
+#endif
+#ifdef CONFIG_ATH9K_MAC_DEBUG
+       spin_lock_init(&sc->debug.samp_lock);
 #endif
        tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
        tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
@@ -880,12 +822,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
        if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
                kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
 
-        if ((sc->btcoex.no_stomp_timer) &&
-           ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE)
-               ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
-
-       if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI)
-               ath_mci_cleanup(sc);
+       ath9k_deinit_btcoex(sc);
 
        for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
                if (ATH_TXQ_SETUP(sc, i))
index e196aba77acf568387d7a4b2b5852e316d801e4f..5f4ae6c9a93c69f4605bf7af447bc29e1c8cb583 100644 (file)
@@ -745,7 +745,11 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah)
        qi.tqi_aifs = 1;
        qi.tqi_cwmin = 0;
        qi.tqi_cwmax = 0;
-       /* NB: don't enable any interrupts */
+
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE |
+                               TXQ_FLAG_TXERRINT_ENABLE;
+
        return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
 }
 EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
index 4a00806e2852af4e88638076f8b60c85fb82426b..cc2535c38beddd6a9adb2db9be3a2fe8683ec51c 100644 (file)
@@ -340,9 +340,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
                fastcc = false;
 
        ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
-               hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS |
-                                                         CHANNEL_HT40PLUS)),
-               fastcc);
+               hchan->channel, IS_CHAN_HT40(hchan), fastcc);
 
        r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
        if (r) {
@@ -373,12 +371,8 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
        if (sc->sc_flags & SC_OP_INVALID)
                return -EIO;
 
-       ath9k_ps_wakeup(sc);
-
        r = ath_reset_internal(sc, hchan, false);
 
-       ath9k_ps_restore(sc);
-
        return r;
 }
 
@@ -741,12 +735,7 @@ void ath9k_tasklet(unsigned long data)
                        ath_tx_tasklet(sc);
        }
 
-       if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
-               if (status & ATH9K_INT_GENTIMER)
-                       ath_gen_timer_isr(sc->sc_ah);
-
-       if ((status & ATH9K_INT_MCI) && ATH9K_HW_CAP_MCI)
-               ath_mci_intr(sc);
+       ath9k_btcoex_handle_interrupt(sc, status);
 
 out:
        /* re-enable hardware interrupt */
@@ -1081,16 +1070,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
 
        spin_unlock_bh(&sc->sc_pcu_lock);
 
-       if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) &&
-           !ah->btcoex_hw.enabled) {
-               if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
-                       ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
-                                                  AR_STOMP_LOW_WLAN_WGHT);
-               ath9k_hw_btcoex_enable(ah);
-
-               if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
-                       ath9k_btcoex_timer_resume(sc);
-       }
+       ath9k_start_btcoex(sc);
 
        if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
                common->bus_ops->extn_synch_en(common);
@@ -1191,13 +1171,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
        /* Ensure HW is awake when we try to shut it down. */
        ath9k_ps_wakeup(sc);
 
-       if (ah->btcoex_hw.enabled &&
-           ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
-               ath9k_hw_btcoex_disable(ah);
-               if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
-                       ath9k_btcoex_timer_pause(sc);
-               ath_mci_flush_profile(&sc->btcoex.mci);
-       }
+       ath9k_stop_btcoex(sc);
 
        spin_lock_bh(&sc->sc_pcu_lock);
 
@@ -1589,12 +1563,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
        ath9k_ps_wakeup(sc);
        mutex_lock(&sc->mutex);
 
-       /*
-        * Leave this as the first check because we need to turn on the
-        * radio if it was disabled before prior to processing the rest
-        * of the changes. Likewise we must only disable the radio towards
-        * the end.
-        */
        if (changed & IEEE80211_CONF_CHANGE_IDLE) {
                sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
                if (sc->ps_idle)
@@ -2332,6 +2300,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
        struct ath_vif *avp;
        struct ath_buf *bf;
        struct ath_tx_status ts;
+       bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
        int status;
 
        vif = sc->beacon.bslot[0];
@@ -2342,7 +2311,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
        if (!avp->is_bslot_active)
                return 0;
 
-       if (!sc->beacon.tx_processed) {
+       if (!sc->beacon.tx_processed && !edma) {
                tasklet_disable(&sc->bcon_tasklet);
 
                bf = avp->av_bcbuf;
index 05c23ea4c63362a36072b699719ecd4ce2810173..29fe52d6997350777afb8660f41910738fffedb4 100644 (file)
@@ -42,24 +42,18 @@ static bool ath_mci_add_profile(struct ath_common *common,
        struct ath_mci_profile_info *entry;
 
        if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) &&
-           (info->type == MCI_GPM_COEX_PROFILE_VOICE)) {
-               ath_dbg(common, MCI,
-                       "Too many SCO profile, failed to add new profile\n");
+           (info->type == MCI_GPM_COEX_PROFILE_VOICE))
                return false;
-       }
 
        if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) &&
-           (info->type != MCI_GPM_COEX_PROFILE_VOICE)) {
-               ath_dbg(common, MCI,
-                       "Too many ACL profile, failed to add new profile\n");
+           (info->type != MCI_GPM_COEX_PROFILE_VOICE))
                return false;
-       }
 
        entry = ath_mci_find_profile(mci, info);
 
-       if (entry)
+       if (entry) {
                memcpy(entry, info, 10);
-       else {
+       else {
                entry = kzalloc(sizeof(*entry), GFP_KERNEL);
                if (!entry)
                        return false;
@@ -68,6 +62,7 @@ static bool ath_mci_add_profile(struct ath_common *common,
                INC_PROF(mci, info);
                list_add_tail(&info->list, &mci->info);
        }
+
        return true;
 }
 
@@ -79,10 +74,9 @@ static void ath_mci_del_profile(struct ath_common *common,
 
        entry = ath_mci_find_profile(mci, info);
 
-       if (!entry) {
-               ath_dbg(common, MCI, "Profile to be deleted not found\n");
+       if (!entry)
                return;
-       }
+
        DEC_PROF(mci, entry);
        list_del(&entry->list);
        kfree(entry);
@@ -177,13 +171,12 @@ static void ath_mci_update_scheme(struct ath_softc *sc)
 
        btcoex->btcoex_period *= 1000;
        btcoex->btcoex_no_stomp =  btcoex->btcoex_period *
-                                       (100 - btcoex->duty_cycle) / 100;
+               (100 - btcoex->duty_cycle) / 100;
 
        ath9k_hw_btcoex_enable(sc->sc_ah);
        ath9k_btcoex_timer_resume(sc);
 }
 
-
 static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
 {
        struct ath_hw *ah = sc->sc_ah;
@@ -192,42 +185,24 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
 
        switch (opcode) {
        case MCI_GPM_BT_CAL_REQ:
-
-               ath_dbg(common, MCI, "MCI received BT_CAL_REQ\n");
-
                if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) {
                        ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL);
                        ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
-               } else
-                       ath_dbg(common, MCI, "MCI State mismatches: %d\n",
+               } else {
+                       ath_dbg(common, MCI, "MCI State mismatch: %d\n",
                                ar9003_mci_state(ah, MCI_STATE_BT, NULL));
-
+               }
                break;
-
        case MCI_GPM_BT_CAL_DONE:
-
-               ath_dbg(common, MCI, "MCI received BT_CAL_DONE\n");
-
-               if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_CAL)
-                       ath_dbg(common, MCI, "MCI error illegal!\n");
-               else
-                       ath_dbg(common, MCI, "MCI BT not in CAL state\n");
-
+               ar9003_mci_state(ah, MCI_STATE_BT, NULL);
                break;
-
        case MCI_GPM_BT_CAL_GRANT:
-
-               ath_dbg(common, MCI, "MCI received BT_CAL_GRANT\n");
-
-               /* Send WLAN_CAL_DONE for now */
-               ath_dbg(common, MCI, "MCI send WLAN_CAL_DONE\n");
                MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE);
                ar9003_mci_send_message(sc->sc_ah, MCI_GPM, 0, payload,
                                        16, false, true);
                break;
-
        default:
-               ath_dbg(common, MCI, "MCI Unknown GPM CAL message\n");
+               ath_dbg(common, MCI, "Unknown GPM CAL message\n");
                break;
        }
 }
@@ -247,6 +222,7 @@ static void ath_mci_process_profile(struct ath_softc *sc,
 
        btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD;
        mci->aggr_limit = mci->num_sco ? 6 : 0;
+
        if (NUM_PROF(mci)) {
                btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
                btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)];
@@ -262,31 +238,24 @@ static void ath_mci_process_profile(struct ath_softc *sc,
 static void ath_mci_process_status(struct ath_softc *sc,
                                   struct ath_mci_profile_status *status)
 {
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_btcoex *btcoex = &sc->btcoex;
        struct ath_mci_profile *mci = &btcoex->mci;
        struct ath_mci_profile_info info;
        int i = 0, old_num_mgmt = mci->num_mgmt;
 
        /* Link status type are not handled */
-       if (status->is_link) {
-               ath_dbg(common, MCI, "Skip link type status update\n");
+       if (status->is_link)
                return;
-       }
 
        memset(&info, 0, sizeof(struct ath_mci_profile_info));
 
        info.conn_handle = status->conn_handle;
-       if (ath_mci_find_profile(mci, &info)) {
-               ath_dbg(common, MCI,
-                       "Skip non link state update for existing profile %d\n",
-                       status->conn_handle);
+       if (ath_mci_find_profile(mci, &info))
                return;
-       }
-       if (status->conn_handle >= ATH_MCI_MAX_PROFILE) {
-               ath_dbg(common, MCI, "Ignore too many non-link update\n");
+
+       if (status->conn_handle >= ATH_MCI_MAX_PROFILE)
                return;
-       }
+
        if (status->is_critical)
                __set_bit(status->conn_handle, mci->status);
        else
@@ -314,43 +283,28 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
        u32 seq_num;
 
        switch (opcode) {
-
        case MCI_GPM_COEX_VERSION_QUERY:
-               ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n");
-               version = ar9003_mci_state(ah,
-                               MCI_STATE_SEND_WLAN_COEX_VERSION, NULL);
+               version = ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION,
+                                          NULL);
                break;
-
        case MCI_GPM_COEX_VERSION_RESPONSE:
-               ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n");
                major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION);
                minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION);
-               ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n",
-                       major, minor);
                version = (major << 8) + minor;
-               version = ar9003_mci_state(ah,
-                         MCI_STATE_SET_BT_COEX_VERSION, &version);
+               version = ar9003_mci_state(ah, MCI_STATE_SET_BT_COEX_VERSION,
+                                          &version);
                break;
-
        case MCI_GPM_COEX_STATUS_QUERY:
-               ath_dbg(common, MCI,
-                       "MCI Recv GPM COEX Status Query = 0x%02x\n",
-                       *(rx_payload + MCI_GPM_COEX_B_WLAN_BITMAP));
-               ar9003_mci_state(ah,
-               MCI_STATE_SEND_WLAN_CHANNELS, NULL);
+               ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_CHANNELS, NULL);
                break;
-
        case MCI_GPM_COEX_BT_PROFILE_INFO:
-               ath_dbg(common, MCI, "MCI Recv GPM Coex BT profile info\n");
                memcpy(&profile_info,
                       (rx_payload + MCI_GPM_COEX_B_PROFILE_TYPE), 10);
 
-               if ((profile_info.type == MCI_GPM_COEX_PROFILE_UNKNOWN)
-                   || (profile_info.type >=
-                                           MCI_GPM_COEX_PROFILE_MAX)) {
-
+               if ((profile_info.type == MCI_GPM_COEX_PROFILE_UNKNOWN) ||
+                   (profile_info.type >= MCI_GPM_COEX_PROFILE_MAX)) {
                        ath_dbg(common, MCI,
-                               "illegal profile type = %d, state = %d\n",
+                               "Illegal profile type = %d, state = %d\n",
                                profile_info.type,
                                profile_info.start);
                        break;
@@ -358,7 +312,6 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
 
                ath_mci_process_profile(sc, &profile_info);
                break;
-
        case MCI_GPM_COEX_BT_STATUS_UPDATE:
                profile_status.is_link = *(rx_payload +
                                           MCI_GPM_COEX_B_STATUS_TYPE);
@@ -369,98 +322,66 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
 
                seq_num = *((u32 *)(rx_payload + 12));
                ath_dbg(common, MCI,
-                       "MCI Recv GPM COEX BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%d\n",
+                       "BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%d\n",
                        profile_status.is_link, profile_status.conn_handle,
                        profile_status.is_critical, seq_num);
 
                ath_mci_process_status(sc, &profile_status);
                break;
-
        default:
-               ath_dbg(common, MCI, "MCI Unknown GPM COEX message = 0x%02x\n",
-                       opcode);
+               ath_dbg(common, MCI, "Unknown GPM COEX message = 0x%02x\n", opcode);
                break;
        }
 }
 
-static int ath_mci_buf_alloc(struct ath_softc *sc, struct ath_mci_buf *buf)
-{
-       int error = 0;
-
-       buf->bf_addr = dma_alloc_coherent(sc->dev, buf->bf_len,
-                                         &buf->bf_paddr, GFP_KERNEL);
-
-       if (buf->bf_addr == NULL) {
-               error = -ENOMEM;
-               goto fail;
-       }
-
-       return 0;
-
-fail:
-       memset(buf, 0, sizeof(*buf));
-       return error;
-}
-
-static void ath_mci_buf_free(struct ath_softc *sc, struct ath_mci_buf *buf)
-{
-       if (buf->bf_addr) {
-               dma_free_coherent(sc->dev, buf->bf_len, buf->bf_addr,
-                                                       buf->bf_paddr);
-               memset(buf, 0, sizeof(*buf));
-       }
-}
-
 int ath_mci_setup(struct ath_softc *sc)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_mci_coex *mci = &sc->mci_coex;
-       int error = 0;
-
-       if (!ATH9K_HW_CAP_MCI)
-               return 0;
+       struct ath_mci_buf *buf = &mci->sched_buf;
 
-       mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE;
+       buf->bf_addr = dma_alloc_coherent(sc->dev,
+                                 ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE,
+                                 &buf->bf_paddr, GFP_KERNEL);
 
-       if (ath_mci_buf_alloc(sc, &mci->sched_buf)) {
+       if (buf->bf_addr == NULL) {
                ath_dbg(common, FATAL, "MCI buffer alloc failed\n");
-               error = -ENOMEM;
-               goto fail;
+               return -ENOMEM;
        }
 
-       mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE;
+       memset(buf->bf_addr, MCI_GPM_RSVD_PATTERN,
+              ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE);
 
-       memset(mci->sched_buf.bf_addr, MCI_GPM_RSVD_PATTERN,
-                                               mci->sched_buf.bf_len);
+       mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE;
 
        mci->gpm_buf.bf_len = ATH_MCI_GPM_BUF_SIZE;
-       mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr +
-                                                       mci->sched_buf.bf_len;
+       mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + mci->sched_buf.bf_len;
        mci->gpm_buf.bf_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len;
 
-       /* initialize the buffer */
-       memset(mci->gpm_buf.bf_addr, MCI_GPM_RSVD_PATTERN, mci->gpm_buf.bf_len);
-
        ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr,
                         mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4),
                         mci->sched_buf.bf_paddr);
-fail:
-       return error;
+
+       ath_dbg(common, MCI, "MCI Initialized\n");
+
+       return 0;
 }
 
 void ath_mci_cleanup(struct ath_softc *sc)
 {
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_hw *ah = sc->sc_ah;
        struct ath_mci_coex *mci = &sc->mci_coex;
+       struct ath_mci_buf *buf = &mci->sched_buf;
 
-       if (!ATH9K_HW_CAP_MCI)
-               return;
+       if (buf->bf_addr)
+               dma_free_coherent(sc->dev,
+                                 ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE,
+                                 buf->bf_addr, buf->bf_paddr);
 
-       /*
-        * both schedule and gpm buffers will be released
-        */
-       ath_mci_buf_free(sc, &mci->sched_buf);
        ar9003_mci_cleanup(ah);
+
+       ath_dbg(common, MCI, "MCI De-Initialized\n");
 }
 
 void ath_mci_intr(struct ath_softc *sc)
@@ -474,19 +395,10 @@ void ath_mci_intr(struct ath_softc *sc)
        u32 more_data = MCI_GPM_MORE;
        bool skip_gpm = false;
 
-       if (!ATH9K_HW_CAP_MCI)
-               return;
-
        ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg);
 
        if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) {
-
-               ar9003_mci_state(sc->sc_ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
-               ath_dbg(common, MCI, "MCI interrupt but MCI disabled\n");
-
-               ath_dbg(common, MCI,
-                       "MCI interrupt: intr = 0x%x, intr_rxmsg = 0x%x\n",
-                       mci_int, mci_int_rxmsg);
+               ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
                return;
        }
 
@@ -499,11 +411,8 @@ void ath_mci_intr(struct ath_softc *sc)
                 * only when BT wake up. Now they are always sent, as a
                 * recovery method to reset BT MCI's RX alignment.
                 */
-               ath_dbg(common, MCI, "MCI interrupt send REMOTE_RESET\n");
-
                ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0,
                                        payload, 16, true, false);
-               ath_dbg(common, MCI, "MCI interrupt send SYS_WAKING\n");
                ar9003_mci_send_message(ah, MCI_SYS_WAKING, 0,
                                        NULL, 0, true, false);
 
@@ -513,74 +422,51 @@ void ath_mci_intr(struct ath_softc *sc)
                /*
                 * always do this for recovery and 2G/5G toggling and LNA_TRANS
                 */
-               ath_dbg(common, MCI, "MCI Set BT state to AWAKE\n");
                ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, NULL);
        }
 
-       /* Processing SYS_WAKING/SYS_SLEEPING */
        if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) {
                mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING;
 
                if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_SLEEP) {
-
-                       if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL)
-                                       == MCI_BT_SLEEP)
-                               ath_dbg(common, MCI,
-                                       "MCI BT stays in sleep mode\n");
-                       else {
-                               ath_dbg(common, MCI,
-                                       "MCI Set BT state to AWAKE\n");
-                               ar9003_mci_state(ah,
-                                                MCI_STATE_SET_BT_AWAKE, NULL);
-                       }
-               } else
-                       ath_dbg(common, MCI, "MCI BT stays in AWAKE mode\n");
+                       if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) !=
+                           MCI_BT_SLEEP)
+                               ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE,
+                                                NULL);
+               }
        }
 
        if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) {
-
                mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING;
 
                if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) {
-
-                       if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL)
-                                       == MCI_BT_AWAKE)
-                               ath_dbg(common, MCI,
-                                       "MCI BT stays in AWAKE mode\n");
-                       else {
-                               ath_dbg(common, MCI,
-                                       "MCI SetBT state to SLEEP\n");
+                       if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) !=
+                           MCI_BT_AWAKE)
                                ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP,
                                                 NULL);
-                       }
-               } else
-                       ath_dbg(common, MCI, "MCI BT stays in SLEEP mode\n");
+               }
        }
 
        if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) ||
            (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) {
-
-               ath_dbg(common, MCI, "MCI RX broken, skip GPM msgs\n");
                ar9003_mci_state(ah, MCI_STATE_RECOVER_RX, NULL);
                skip_gpm = true;
        }
 
        if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO) {
-
                mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO;
                offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET,
                                          NULL);
        }
 
        if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) {
-
                mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM;
 
                while (more_data == MCI_GPM_MORE) {
 
                        pgpm = mci->gpm_buf.bf_addr;
-                       offset = ar9003_mci_state(ah,
-                                       MCI_STATE_NEXT_GPM_OFFSET, &more_data);
+                       offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
+                                                 &more_data);
 
                        if (offset == MCI_GPM_INVALID)
                                break;
@@ -591,44 +477,38 @@ void ath_mci_intr(struct ath_softc *sc)
                         * The first dword is timer.
                         * The real data starts from 2nd dword.
                         */
-
                        subtype = MCI_GPM_TYPE(pgpm);
                        opcode = MCI_GPM_OPCODE(pgpm);
 
-                       if (!skip_gpm) {
-
-                               if (MCI_GPM_IS_CAL_TYPE(subtype))
-                                       ath_mci_cal_msg(sc, subtype,
-                                                       (u8 *) pgpm);
-                               else {
-                                       switch (subtype) {
-                                       case MCI_GPM_COEX_AGENT:
-                                               ath_mci_msg(sc, opcode,
-                                                           (u8 *) pgpm);
-                                               break;
-                                       default:
-                                               break;
-                                       }
+                       if (skip_gpm)
+                               goto recycle;
+
+                       if (MCI_GPM_IS_CAL_TYPE(subtype)) {
+                               ath_mci_cal_msg(sc, subtype, (u8 *)pgpm);
+                       } else {
+                               switch (subtype) {
+                               case MCI_GPM_COEX_AGENT:
+                                       ath_mci_msg(sc, opcode, (u8 *)pgpm);
+                                       break;
+                               default:
+                                       break;
                                }
                        }
+               recycle:
                        MCI_GPM_RECYCLE(pgpm);
                }
        }
 
        if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_HW_MSG_MASK) {
-
                if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL)
                        mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL;
 
-               if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_INFO) {
+               if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_INFO)
                        mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO;
-                       ath_dbg(common, MCI, "MCI LNA_INFO\n");
-               }
 
                if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) {
-
                        int value_dbm = ar9003_mci_state(ah,
-                                       MCI_STATE_CONT_RSSI_POWER, NULL);
+                                                MCI_STATE_CONT_RSSI_POWER, NULL);
 
                        mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO;
 
@@ -636,33 +516,25 @@ void ath_mci_intr(struct ath_softc *sc)
                                ath_dbg(common, MCI,
                                        "MCI CONT_INFO: (tx) pri = %d, pwr = %d dBm\n",
                                        ar9003_mci_state(ah,
-                                               MCI_STATE_CONT_PRIORITY, NULL),
+                                                MCI_STATE_CONT_PRIORITY, NULL),
                                        value_dbm);
                        else
                                ath_dbg(common, MCI,
                                        "MCI CONT_INFO: (rx) pri = %d,pwr = %d dBm\n",
                                        ar9003_mci_state(ah,
-                                               MCI_STATE_CONT_PRIORITY, NULL),
+                                                MCI_STATE_CONT_PRIORITY, NULL),
                                        value_dbm);
                }
 
-               if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) {
+               if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK)
                        mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_NACK;
-                       ath_dbg(common, MCI, "MCI CONT_NACK\n");
-               }
 
-               if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_RST) {
+               if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_RST)
                        mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_RST;
-                       ath_dbg(common, MCI, "MCI CONT_RST\n");
-               }
        }
 
        if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) ||
            (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT))
                mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR |
                             AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT);
-
-       if (mci_int_rxmsg & 0xfffffffe)
-               ath_dbg(common, MCI, "MCI not processed mci_int_rxmsg = 0x%x\n",
-                       mci_int_rxmsg);
 }
index 29e3e51d078f52e661f0693f267d6e2f031f4479..c841444f53c2c91d2a02140c11f5cadf97f421c3 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef MCI_H
 #define MCI_H
 
+#include "ar9003_mci.h"
+
 #define ATH_MCI_SCHED_BUF_SIZE         (16 * 16) /* 16 entries, 4 dword each */
 #define ATH_MCI_GPM_MAX_ENTRY          16
 #define ATH_MCI_GPM_BUF_SIZE           (ATH_MCI_GPM_MAX_ENTRY * 16)
@@ -113,7 +115,6 @@ struct ath_mci_profile {
        u8 num_bdr;
 };
 
-
 struct ath_mci_buf {
        void *bf_addr;          /* virtual addr of desc */
        dma_addr_t bf_paddr;    /* physical addr of buffer */
@@ -121,10 +122,8 @@ struct ath_mci_buf {
 };
 
 struct ath_mci_coex {
-       atomic_t mci_cal_flag;
        struct ath_mci_buf sched_buf;
        struct ath_mci_buf gpm_buf;
-       u32 bt_cal_start;
 };
 
 void ath_mci_flush_profile(struct ath_mci_profile *mci);
index 635b592ad96181478af45cb2697ea05dbd823077..6407af22f7b90b216752198703574670f48726c9 100644 (file)
@@ -567,10 +567,8 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
 
 static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
                                  const struct ath_rate_table *rate_table,
-                                 u8 *mcs_set, u32 capflag)
+                                 struct ath_rateset *rateset, u32 capflag)
 {
-       struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
-
        u8 i, j, hi = 0;
 
        /* Use intersection of working rates and valid rates */
@@ -1212,7 +1210,7 @@ static void ath_rc_init(struct ath_softc *sc,
 {
        struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
+       struct ath_rateset *ht_mcs = &ath_rc_priv->neg_ht_rates;
        u8 i, j, k, hi = 0, hthi = 0;
 
        /* Initial rate table size. Will change depending
@@ -1228,7 +1226,7 @@ static void ath_rc_init(struct ath_softc *sc,
        ath_rc_init_valid_rate_idx(ath_rc_priv);
 
        for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
-               for (j = 0; j < MAX_TX_RATE_PHY; j++)
+               for (j = 0; j < RATE_TABLE_SIZE; j++)
                        ath_rc_priv->valid_phy_rateidx[i][j] = 0;
                ath_rc_priv->valid_phy_ratecnt[i] = 0;
        }
@@ -1346,7 +1344,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
        fc = hdr->frame_control;
        for (i = 0; i < sc->hw->max_rates; i++) {
                struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
-               if (!rate->count)
+               if (rate->idx < 0 || !rate->count)
                        break;
 
                final_ts_idx = i;
index b7a4bcd3eec70f02c62f11e0a23ea7ff843813f2..75f8e9b06b2859d2866f16653c3a22913ee6baf5 100644 (file)
@@ -25,8 +25,6 @@ struct ath_softc;
 
 #define ATH_RATE_MAX     30
 #define RATE_TABLE_SIZE  72
-#define MAX_TX_RATE_PHY  48
-
 
 #define RC_INVALID     0x0000
 #define RC_LEGACY      0x0001
index 7e1a91af149751b13a53ee9d6dab5c16fcd2f01f..1b1b279c304aa5e3794c8e13f8ac2fec4b3b2e37 100644 (file)
@@ -169,22 +169,17 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc,
                                  enum ath9k_rx_qtype qtype, int size)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       u32 nbuf = 0;
+       struct ath_buf *bf, *tbf;
 
        if (list_empty(&sc->rx.rxbuf)) {
                ath_dbg(common, QUEUE, "No free rx buf available\n");
                return;
        }
 
-       while (!list_empty(&sc->rx.rxbuf)) {
-               nbuf++;
-
+       list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list)
                if (!ath_rx_edma_buf_link(sc, qtype))
                        break;
 
-               if (nbuf >= size)
-                       break;
-       }
 }
 
 static void ath_rx_remove_buffer(struct ath_softc *sc,
@@ -232,7 +227,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc)
 static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size)
 {
        skb_queue_head_init(&rx_edma->rx_fifo);
-       skb_queue_head_init(&rx_edma->rx_buffers);
        rx_edma->rx_fifo_hwsize = size;
 }
 
@@ -658,7 +652,9 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon)
 }
 
 static bool ath_edma_get_buffers(struct ath_softc *sc,
-                                enum ath9k_rx_qtype qtype)
+                                enum ath9k_rx_qtype qtype,
+                                struct ath_rx_status *rs,
+                                struct ath_buf **dest)
 {
        struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
        struct ath_hw *ah = sc->sc_ah;
@@ -677,7 +673,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
        dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
                                common->rx_bufsize, DMA_FROM_DEVICE);
 
-       ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data);
+       ret = ath9k_hw_process_rxdesc_edma(ah, rs, skb->data);
        if (ret == -EINPROGRESS) {
                /*let device gain the buffer again*/
                dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
@@ -690,20 +686,21 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
                /* corrupt descriptor, skip this one and the following one */
                list_add_tail(&bf->list, &sc->rx.rxbuf);
                ath_rx_edma_buf_link(sc, qtype);
-               skb = skb_peek(&rx_edma->rx_fifo);
-               if (!skb)
-                       return true;
 
-               bf = SKB_CB_ATHBUF(skb);
-               BUG_ON(!bf);
+               skb = skb_peek(&rx_edma->rx_fifo);
+               if (skb) {
+                       bf = SKB_CB_ATHBUF(skb);
+                       BUG_ON(!bf);
 
-               __skb_unlink(skb, &rx_edma->rx_fifo);
-               list_add_tail(&bf->list, &sc->rx.rxbuf);
-               ath_rx_edma_buf_link(sc, qtype);
-               return true;
+                       __skb_unlink(skb, &rx_edma->rx_fifo);
+                       list_add_tail(&bf->list, &sc->rx.rxbuf);
+                       ath_rx_edma_buf_link(sc, qtype);
+               } else {
+                       bf = NULL;
+               }
        }
-       skb_queue_tail(&rx_edma->rx_buffers, skb);
 
+       *dest = bf;
        return true;
 }
 
@@ -711,18 +708,15 @@ static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
                                                struct ath_rx_status *rs,
                                                enum ath9k_rx_qtype qtype)
 {
-       struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
-       struct sk_buff *skb;
-       struct ath_buf *bf;
+       struct ath_buf *bf = NULL;
 
-       while (ath_edma_get_buffers(sc, qtype));
-       skb = __skb_dequeue(&rx_edma->rx_buffers);
-       if (!skb)
-               return NULL;
+       while (ath_edma_get_buffers(sc, qtype, rs, &bf)) {
+               if (!bf)
+                       continue;
 
-       bf = SKB_CB_ATHBUF(skb);
-       ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data);
-       return bf;
+               return bf;
+       }
+       return NULL;
 }
 
 static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
@@ -954,6 +948,7 @@ static void ath9k_process_rssi(struct ath_common *common,
        struct ath_softc *sc = hw->priv;
        struct ath_hw *ah = common->ah;
        int last_rssi;
+       int rssi = rx_stats->rs_rssi;
 
        if (!rx_stats->is_mybeacon ||
            ((ah->opmode != NL80211_IFTYPE_STATION) &&
@@ -965,13 +960,12 @@ static void ath9k_process_rssi(struct ath_common *common,
 
        last_rssi = sc->last_rssi;
        if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-               rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
-                                             ATH_RSSI_EP_MULTIPLIER);
-       if (rx_stats->rs_rssi < 0)
-               rx_stats->rs_rssi = 0;
+               rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
+       if (rssi < 0)
+               rssi = 0;
 
        /* Update Beacon RSSI, this is used by ANI. */
-       ah->stats.avgbrssi = rx_stats->rs_rssi;
+       ah->stats.avgbrssi = rssi;
 }
 
 /*
@@ -1011,6 +1005,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
        rx_status->signal = ah->noise + rx_stats->rs_rssi;
        rx_status->antenna = rx_stats->rs_antenna;
        rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+       if (rx_stats->rs_moreaggr)
+               rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
 
        return 0;
 }
index 6e2f18861f5d991d62b84b854f633443ba961d4a..80b1856f817deff8522ef0c32aee21d9b57c1de8 100644 (file)
 #define AR_SREV_VERSION_9580           0x1C0
 #define AR_SREV_REVISION_9580_10       4 /* AR9580 1.0 */
 #define AR_SREV_VERSION_9462           0x280
-#define AR_SREV_REVISION_9462_10       0
 #define AR_SREV_REVISION_9462_20       2
 
 #define AR_SREV_5416(_ah) \
 #define AR_SREV_9462(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
 
-#define AR_SREV_9462_10(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
-       ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_10))
-
 #define AR_SREV_9462_20(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20))
index 3182408ffe35abcc08c075d8f950cf433d1ca9cf..9f785015a7dcef6acbe75eb74e044a7dcfb463ad 100644 (file)
@@ -647,9 +647,8 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
        struct sk_buff *skb;
        struct ieee80211_tx_info *tx_info;
        struct ieee80211_tx_rate *rates;
-       struct ath_mci_profile *mci = &sc->btcoex.mci;
        u32 max_4ms_framelen, frmlen;
-       u16 aggr_limit, legacy = 0;
+       u16 aggr_limit, bt_aggr_limit, legacy = 0;
        int i;
 
        skb = bf->bf_mpdu;
@@ -694,14 +693,14 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
        if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
                return 0;
 
-       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit)
-               aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4;
-       else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED)
-               aggr_limit = min((max_4ms_framelen * 3) / 8,
-                                (u32)ATH_AMPDU_LIMIT_MAX);
-       else
-               aggr_limit = min(max_4ms_framelen,
-                                (u32)ATH_AMPDU_LIMIT_MAX);
+       aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_MAX);
+
+       /*
+        * Override the default aggregation limit for BTCOEX.
+        */
+       bt_aggr_limit = ath9k_btcoex_aggr_limit(sc, max_4ms_framelen);
+       if (bt_aggr_limit)
+               aggr_limit = bt_aggr_limit;
 
        /*
         * h/w can accept aggregates up to 16 bit lengths (65535).
@@ -2297,9 +2296,12 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
                        break;
                }
 
-               /* Skip beacon completions */
-               if (ts.qid == sc->beacon.beaconq)
+               /* Process beacon completions separately */
+               if (ts.qid == sc->beacon.beaconq) {
+                       sc->beacon.tx_processed = true;
+                       sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK);
                        continue;
+               }
 
                txq = &sc->tx.txq[ts.qid];
 
index 6cfbb419e2f6d1efe8ddf7e2d551928efcd95f9d..0cea20e3e250049d58b96466bcfed59927ae158b 100644 (file)
@@ -559,6 +559,7 @@ int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry);
 int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
        const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen);
 int carl9170_disable_key(struct ar9170 *ar, const u8 id);
+int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel);
 
 /* RX */
 void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len);
@@ -593,7 +594,6 @@ int carl9170_get_noisefloor(struct ar9170 *ar);
 
 /* FW */
 int carl9170_parse_firmware(struct ar9170 *ar);
-int carl9170_fw_fix_eeprom(struct ar9170 *ar);
 
 extern struct ieee80211_rate __carl9170_ratetable[];
 extern int modparam_noht;
index 3de61adacd34af2f28c24ef2149e8d7c0b51d234..cffde8d9a521d26ed6ea5886daad4693c15fc108 100644 (file)
@@ -389,39 +389,6 @@ carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len)
        return (void *)&fw_data[scan - found];
 }
 
-int carl9170_fw_fix_eeprom(struct ar9170 *ar)
-{
-       const struct carl9170fw_fix_desc *fix_desc = NULL;
-       unsigned int i, n, off;
-       u32 *data = (void *)&ar->eeprom;
-
-       fix_desc = carl9170_fw_find_desc(ar, FIX_MAGIC,
-               sizeof(*fix_desc), CARL9170FW_FIX_DESC_CUR_VER);
-
-       if (!fix_desc)
-               return 0;
-
-       n = (le16_to_cpu(fix_desc->head.length) - sizeof(*fix_desc)) /
-           sizeof(struct carl9170fw_fix_entry);
-
-       for (i = 0; i < n; i++) {
-               off = le32_to_cpu(fix_desc->data[i].address) -
-                     AR9170_EEPROM_START;
-
-               if (off >= sizeof(struct ar9170_eeprom) || (off & 3)) {
-                       dev_err(&ar->udev->dev, "Skip invalid entry %d\n", i);
-                       continue;
-               }
-
-               data[off / sizeof(*data)] &=
-                       le32_to_cpu(fix_desc->data[i].mask);
-               data[off / sizeof(*data)] |=
-                       le32_to_cpu(fix_desc->data[i].value);
-       }
-
-       return 0;
-}
-
 int carl9170_parse_firmware(struct ar9170 *ar)
 {
        const struct carl9170fw_desc_head *fw_desc = NULL;
index dfda919709954d27cb0a288c556c9933e55c731c..53415bfd8bef7e673749904369775520ff74beae 100644 (file)
@@ -485,3 +485,38 @@ int carl9170_disable_key(struct ar9170 *ar, const u8 id)
        return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY,
                sizeof(key), (u8 *)&key, 0, NULL);
 }
+
+int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel)
+{
+       unsigned int power, chains;
+
+       if (ar->eeprom.tx_mask != 1)
+               chains = AR9170_TX_PHY_TXCHAIN_2;
+       else
+               chains = AR9170_TX_PHY_TXCHAIN_1;
+
+       switch (channel->band) {
+       case IEEE80211_BAND_2GHZ:
+               power = ar->power_2G_ofdm[0] & 0x3f;
+               break;
+       case IEEE80211_BAND_5GHZ:
+               power = ar->power_5G_leg[0] & 0x3f;
+               break;
+       default:
+               BUG_ON(1);
+       }
+
+       power = min_t(unsigned int, power, ar->hw->conf.power_level * 2);
+
+       carl9170_regwrite_begin(ar);
+       carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
+                         0x3c1e | power << 20 | chains << 26);
+       carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
+                         power << 5 | chains << 11 |
+                         power << 21 | chains << 27);
+       carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
+                         power << 5 | chains << 11 |
+                         power << 21 | chains << 27);
+       carl9170_regwrite_finish();
+       return carl9170_regwrite_result();
+}
index db774212161bc820225fb9f14564302be55cc3be..8d2523b3f722ea39785876333a687cfd9597bfd9 100644 (file)
@@ -853,11 +853,6 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
                        goto out;
        }
 
-       if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               /* TODO */
-               err = 0;
-       }
-
        if (changed & IEEE80211_CONF_CHANGE_SMPS) {
                /* TODO */
                err = 0;
@@ -891,6 +886,12 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
                        goto out;
        }
 
+       if (changed & IEEE80211_CONF_CHANGE_POWER) {
+               err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel);
+               if (err)
+                       goto out;
+       }
+
 out:
        mutex_unlock(&ar->mutex);
        return err;
@@ -1796,6 +1797,9 @@ void *carl9170_alloc(size_t priv_size)
                ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
 
        hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
+       /* As IBSS Encryption is software-based, IBSS RSN is supported. */
+       hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
        return ar;
 
 err_nomem:
@@ -1931,10 +1935,6 @@ int carl9170_register(struct ar9170 *ar)
        if (err)
                return err;
 
-       err = carl9170_fw_fix_eeprom(ar);
-       if (err)
-               return err;
-
        err = carl9170_parse_eeprom(ar);
        if (err)
                return err;
index 472efc7e34022ffbc9162afb9752069803833edd..b72c09cf43a4c614a56d5b63ca1f34f11b28d4f0 100644 (file)
@@ -1426,15 +1426,15 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
 #undef EDGES
 }
 
-static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
-                                 enum carl9170_bw bw)
+static void carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
+                                  enum carl9170_bw bw)
 {
        struct ar9170_calibration_target_power_legacy *ctpl;
        struct ar9170_calibration_target_power_ht *ctph;
        u8 *ctpres;
        int ntargets;
        int idx, i, n;
-       u8 ackpower, ackchains, f;
+       u8 f;
        u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
 
        if (freq < 3000)
@@ -1523,32 +1523,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
 
        /* calc. conformance test limits and apply to ar->power*[] */
        carl9170_calc_ctl(ar, freq, bw);
-
-       /* set ACK/CTS TX power */
-       carl9170_regwrite_begin(ar);
-
-       if (ar->eeprom.tx_mask != 1)
-               ackchains = AR9170_TX_PHY_TXCHAIN_2;
-       else
-               ackchains = AR9170_TX_PHY_TXCHAIN_1;
-
-       if (freq < 3000)
-               ackpower = ar->power_2G_ofdm[0] & 0x3f;
-       else
-               ackpower = ar->power_5G_leg[0] & 0x3f;
-
-       carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
-                         0x3c1e | ackpower << 20 | ackchains << 26);
-       carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
-                         ackpower << 5 | ackchains << 11 |
-                         ackpower << 21 | ackchains << 27);
-
-       carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
-                         ackpower << 5 | ackchains << 11 |
-                         ackpower << 21 | ackchains << 27);
-
-       carl9170_regwrite_finish();
-       return carl9170_regwrite_result();
 }
 
 int carl9170_get_noisefloor(struct ar9170 *ar)
@@ -1712,7 +1686,9 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
        if (err)
                return err;
 
-       err = carl9170_set_power_cal(ar, channel->center_freq, bw);
+       carl9170_set_power_cal(ar, channel->center_freq, bw);
+
+       err = carl9170_set_mac_tpc(ar, channel);
        if (err)
                return err;
 
index d19a9ee9d057a904577d9497435911bc2867e978..aed305177af6a92ba784a8014c66bee117f5bea4 100644 (file)
@@ -719,6 +719,8 @@ static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar,
                else
                        *chains = AR9170_TX_PHY_TXCHAIN_2;
        }
+
+       *tpc = min_t(unsigned int, *tpc, ar->hw->conf.power_level * 2);
 }
 
 static __le32 carl9170_tx_physet(struct ar9170 *ar,
@@ -1234,6 +1236,7 @@ static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb)
 {
        struct ieee80211_sta *sta;
        struct carl9170_sta_info *sta_info;
+       struct ieee80211_tx_info *tx_info;
 
        rcu_read_lock();
        sta = __carl9170_get_tx_sta(ar, skb);
@@ -1241,16 +1244,18 @@ static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb)
                goto out_rcu;
 
        sta_info = (void *) sta->drv_priv;
-       if (unlikely(sta_info->sleeping)) {
-               struct ieee80211_tx_info *tx_info;
+       tx_info = IEEE80211_SKB_CB(skb);
 
+       if (unlikely(sta_info->sleeping) &&
+           !(tx_info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
+                               IEEE80211_TX_CTL_CLEAR_PS_FILT))) {
                rcu_read_unlock();
 
-               tx_info = IEEE80211_SKB_CB(skb);
                if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
                        atomic_dec(&ar->tx_ampdu_upload);
 
                tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+               carl9170_release_dev_space(ar, skb);
                carl9170_tx_status(ar, skb, false);
                return true;
        }
index 16e8f8058155464d1537f4bfc3b6bdc3af344f75..835462dc1206fe4757b0549d86a83f9e5c7d458d 100644 (file)
@@ -999,6 +999,12 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
        dev->dev->write16(dev->dev, offset, value);
 }
 
+static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask,
+                                u16 set)
+{
+       b43_write16(dev, offset, (b43_read16(dev, offset) & mask) | set);
+}
+
 static inline u32 b43_read32(struct b43_wldev *dev, u16 offset)
 {
        return dev->dev->read32(dev->dev, offset);
@@ -1009,6 +1015,12 @@ static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value)
        dev->dev->write32(dev->dev, offset, value);
 }
 
+static inline void b43_maskset32(struct b43_wldev *dev, u16 offset, u32 mask,
+                                u32 set)
+{
+       b43_write32(dev, offset, (b43_read32(dev, offset) & mask) | set);
+}
+
 static inline void b43_block_read(struct b43_wldev *dev, void *buffer,
                                 size_t count, u16 offset, u8 reg_width)
 {
index 23ffb1b9a86f441f771c8f2ac200d823d76cf440..1d633f3b3274f15583f033ba2faea7ae3d203d5f 100644 (file)
@@ -580,22 +580,14 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
 
 static void b43_time_lock(struct b43_wldev *dev)
 {
-       u32 macctl;
-
-       macctl = b43_read32(dev, B43_MMIO_MACCTL);
-       macctl |= B43_MACCTL_TBTTHOLD;
-       b43_write32(dev, B43_MMIO_MACCTL, macctl);
+       b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_TBTTHOLD);
        /* Commit the write */
        b43_read32(dev, B43_MMIO_MACCTL);
 }
 
 static void b43_time_unlock(struct b43_wldev *dev)
 {
-       u32 macctl;
-
-       macctl = b43_read32(dev, B43_MMIO_MACCTL);
-       macctl &= ~B43_MACCTL_TBTTHOLD;
-       b43_write32(dev, B43_MMIO_MACCTL, macctl);
+       b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_TBTTHOLD, 0);
        /* Commit the write */
        b43_read32(dev, B43_MMIO_MACCTL);
 }
@@ -2487,10 +2479,8 @@ static int b43_upload_microcode(struct b43_wldev *dev)
        b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_ALL);
 
        /* Start the microcode PSM */
-       macctl = b43_read32(dev, B43_MMIO_MACCTL);
-       macctl &= ~B43_MACCTL_PSM_JMP0;
-       macctl |= B43_MACCTL_PSM_RUN;
-       b43_write32(dev, B43_MMIO_MACCTL, macctl);
+       b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_JMP0,
+                     B43_MACCTL_PSM_RUN);
 
        /* Wait for the microcode to load and respond */
        i = 0;
@@ -2590,10 +2580,9 @@ static int b43_upload_microcode(struct b43_wldev *dev)
        return 0;
 
 error:
-       macctl = b43_read32(dev, B43_MMIO_MACCTL);
-       macctl &= ~B43_MACCTL_PSM_RUN;
-       macctl |= B43_MACCTL_PSM_JMP0;
-       b43_write32(dev, B43_MMIO_MACCTL, macctl);
+       /* Stop the microcode PSM. */
+       b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN,
+                     B43_MACCTL_PSM_JMP0);
 
        return err;
 }
@@ -2708,11 +2697,8 @@ static int b43_gpio_init(struct b43_wldev *dev)
        struct ssb_device *gpiodev;
        u32 mask, set;
 
-       b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
-                   & ~B43_MACCTL_GPOUTSMSK);
-
-       b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK)
-                   | 0x000F);
+       b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
+       b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF);
 
        mask = 0x0000001F;
        set = 0x0000000F;
@@ -2720,6 +2706,8 @@ static int b43_gpio_init(struct b43_wldev *dev)
                mask |= 0x0060;
                set |= 0x0060;
        }
+       if (dev->dev->chip_id == 0x5354)
+               set &= 0xff02;
        if (0 /* FIXME: conditional unknown */ ) {
                b43_write16(dev, B43_MMIO_GPIO_MASK,
                            b43_read16(dev, B43_MMIO_GPIO_MASK)
@@ -2800,9 +2788,7 @@ void b43_mac_enable(struct b43_wldev *dev)
        dev->mac_suspended--;
        B43_WARN_ON(dev->mac_suspended < 0);
        if (dev->mac_suspended == 0) {
-               b43_write32(dev, B43_MMIO_MACCTL,
-                           b43_read32(dev, B43_MMIO_MACCTL)
-                           | B43_MACCTL_ENABLED);
+               b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_ENABLED);
                b43_write32(dev, B43_MMIO_GEN_IRQ_REASON,
                            B43_IRQ_MAC_SUSPENDED);
                /* Commit writes */
@@ -2823,9 +2809,7 @@ void b43_mac_suspend(struct b43_wldev *dev)
 
        if (dev->mac_suspended == 0) {
                b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
-               b43_write32(dev, B43_MMIO_MACCTL,
-                           b43_read32(dev, B43_MMIO_MACCTL)
-                           & ~B43_MACCTL_ENABLED);
+               b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_ENABLED, 0);
                /* force pci to flush the write */
                b43_read32(dev, B43_MMIO_MACCTL);
                for (i = 35; i; i--) {
@@ -2931,15 +2915,10 @@ static void b43_adjust_opmode(struct b43_wldev *dev)
         *        so always disable it. If we want to implement PMQ,
         *        we need to enable it here (clear DISCPMQ) in AP mode.
         */
-       if (0  /* ctl & B43_MACCTL_AP */) {
-               b43_write32(dev, B43_MMIO_MACCTL,
-                           b43_read32(dev, B43_MMIO_MACCTL)
-                           & ~B43_MACCTL_DISCPMQ);
-       } else {
-               b43_write32(dev, B43_MMIO_MACCTL,
-                           b43_read32(dev, B43_MMIO_MACCTL)
-                           | B43_MACCTL_DISCPMQ);
-       }
+       if (0  /* ctl & B43_MACCTL_AP */)
+               b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_DISCPMQ, 0);
+       else
+               b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_DISCPMQ);
 }
 
 static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm)
@@ -3083,10 +3062,8 @@ static int b43_chip_init(struct b43_wldev *dev)
        if (dev->dev->core_rev < 5)
                b43_write32(dev, 0x010C, 0x01000000);
 
-       b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
-                   & ~B43_MACCTL_INFRA);
-       b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
-                   | B43_MACCTL_INFRA);
+       b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_INFRA, 0);
+       b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_INFRA);
 
        /* Probe Response Timeout value */
        /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
@@ -4564,8 +4541,6 @@ static void b43_set_pretbtt(struct b43_wldev *dev)
 /* Locking: wl->mutex */
 static void b43_wireless_core_exit(struct b43_wldev *dev)
 {
-       u32 macctl;
-
        B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED);
        if (!dev || b43_status(dev) != B43_STAT_INITIALIZED)
                return;
@@ -4576,10 +4551,8 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
        b43_set_status(dev, B43_STAT_UNINIT);
 
        /* Stop the microcode PSM. */
-       macctl = b43_read32(dev, B43_MMIO_MACCTL);
-       macctl &= ~B43_MACCTL_PSM_RUN;
-       macctl |= B43_MACCTL_PSM_JMP0;
-       b43_write32(dev, B43_MMIO_MACCTL, macctl);
+       b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN,
+                     B43_MACCTL_PSM_JMP0);
 
        b43_dma_free(dev);
        b43_pio_free(dev);
index bf5a43855358319991f94e9e0c43f341dcb161bb..108118820b3635dc5c4ebdd0bd5239630734850f 100644 (file)
@@ -85,22 +85,11 @@ static inline bool b43_nphy_ipa(struct b43_wldev *dev)
                (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ));
 }
 
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
-static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreGetState */
+static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev)
 {
-       if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-               if (dev->phy.rev >= 6) {
-                       if (dev->dev->chip_id == 47162)
-                               return txpwrctrl_tx_gain_ipa_rev5;
-                       return txpwrctrl_tx_gain_ipa_rev6;
-               } else if (dev->phy.rev >= 5) {
-                       return txpwrctrl_tx_gain_ipa_rev5;
-               } else {
-                       return txpwrctrl_tx_gain_ipa;
-               }
-       } else {
-               return txpwrctrl_tx_gain_ipa_5g;
-       }
+       return (b43_phy_read(dev, B43_NPHY_RFSEQCA) & B43_NPHY_RFSEQCA_RXEN) >>
+               B43_NPHY_RFSEQCA_RXEN_SHIFT;
 }
 
 /**************************************************
@@ -229,7 +218,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
 
                reg = (i == 0) ?
                        B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2;
-               b43_phy_mask(dev, reg, 0xFBFF);
+               b43_phy_set(dev, reg, 0x400);
 
                switch (field) {
                case 0:
@@ -245,7 +234,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
                                b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
                                                B43_NPHY_RFCTL_CMD_START);
                                for (j = 0; j < 100; j++) {
-                                       if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) {
+                                       if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START)) {
                                                j = 0;
                                                break;
                                        }
@@ -264,7 +253,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
                                b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
                                                B43_NPHY_RFCTL_CMD_RXTX);
                                for (j = 0; j < 100; j++) {
-                                       if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) {
+                                       if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX)) {
                                                j = 0;
                                                break;
                                        }
@@ -1231,12 +1220,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
        u16 s[2];
 
        if (dev->phy.rev >= 3) {
-               save_regs_phy[0] = b43_phy_read(dev,
+               save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
+               save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
+               save_regs_phy[2] = b43_phy_read(dev,
                                                B43_NPHY_RFCTL_LUT_TRSW_UP1);
-               save_regs_phy[1] = b43_phy_read(dev,
+               save_regs_phy[3] = b43_phy_read(dev,
                                                B43_NPHY_RFCTL_LUT_TRSW_UP2);
-               save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
-               save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
                save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
                save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
                save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
@@ -1285,12 +1274,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
                b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
 
        if (dev->phy.rev >= 3) {
+               b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
+               b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
                b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
-                               save_regs_phy[0]);
+                               save_regs_phy[2]);
                b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
-                               save_regs_phy[1]);
-               b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]);
-               b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]);
+                               save_regs_phy[3]);
                b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]);
                b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
                b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
@@ -1308,6 +1297,186 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
        return out;
 }
 
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
+static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
+{
+       struct b43_phy_n *nphy = dev->phy.n;
+
+       u16 saved_regs_phy_rfctl[2];
+       u16 saved_regs_phy[13];
+       u16 regs_to_store[] = {
+               B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
+               B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
+               B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
+               B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
+               B43_NPHY_RFCTL_CMD,
+               B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
+               B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
+       };
+
+       u16 class;
+
+       u16 clip_state[2];
+       u16 clip_off[2] = { 0xFFFF, 0xFFFF };
+
+       u8 vcm_final = 0;
+       s8 offset[4];
+       s32 results[8][4] = { };
+       s32 results_min[4] = { };
+       s32 poll_results[4] = { };
+
+       u16 *rssical_radio_regs = NULL;
+       u16 *rssical_phy_regs = NULL;
+
+       u16 r; /* routing */
+       u8 rx_core_state;
+       u8 core, i, j;
+
+       class = b43_nphy_classifier(dev, 0, 0);
+       b43_nphy_classifier(dev, 7, 4);
+       b43_nphy_read_clip_detection(dev, clip_state);
+       b43_nphy_write_clip_detection(dev, clip_off);
+
+       saved_regs_phy_rfctl[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
+       saved_regs_phy_rfctl[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
+       for (i = 0; i < ARRAY_SIZE(regs_to_store); i++)
+               saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]);
+
+       b43_nphy_rf_control_intc_override(dev, 0, 0, 7);
+       b43_nphy_rf_control_intc_override(dev, 1, 1, 7);
+       b43_nphy_rf_control_override(dev, 0x1, 0, 0, false);
+       b43_nphy_rf_control_override(dev, 0x2, 1, 0, false);
+       b43_nphy_rf_control_override(dev, 0x80, 1, 0, false);
+       b43_nphy_rf_control_override(dev, 0x40, 1, 0, false);
+
+       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+               b43_nphy_rf_control_override(dev, 0x20, 0, 0, false);
+               b43_nphy_rf_control_override(dev, 0x10, 1, 0, false);
+       } else {
+               b43_nphy_rf_control_override(dev, 0x10, 0, 0, false);
+               b43_nphy_rf_control_override(dev, 0x20, 1, 0, false);
+       }
+
+       rx_core_state = b43_nphy_get_rx_core_state(dev);
+       for (core = 0; core < 2; core++) {
+               if (!(rx_core_state & (1 << core)))
+                       continue;
+               r = core ? B2056_RX1 : B2056_RX0;
+               b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, 2);
+               b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, 2);
+               for (i = 0; i < 8; i++) {
+                       b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3,
+                                       i << 2);
+                       b43_nphy_poll_rssi(dev, 2, results[i], 8);
+               }
+               for (i = 0; i < 4; i++) {
+                       s32 curr;
+                       s32 mind = 40;
+                       s32 minpoll = 249;
+                       u8 minvcm = 0;
+                       if (2 * core != i)
+                               continue;
+                       for (j = 0; j < 8; j++) {
+                               curr = results[j][i] * results[j][i] +
+                                       results[j][i + 1] * results[j][i];
+                               if (curr < mind) {
+                                       mind = curr;
+                                       minvcm = j;
+                               }
+                               if (results[j][i] < minpoll)
+                                       minpoll = results[j][i];
+                       }
+                       vcm_final = minvcm;
+                       results_min[i] = minpoll;
+               }
+               b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3,
+                                 vcm_final << 2);
+               for (i = 0; i < 4; i++) {
+                       if (core != i / 2)
+                               continue;
+                       offset[i] = -results[vcm_final][i];
+                       if (offset[i] < 0)
+                               offset[i] = -((abs(offset[i]) + 4) / 8);
+                       else
+                               offset[i] = (offset[i] + 4) / 8;
+                       if (results_min[i] == 248)
+                               offset[i] = -32;
+                       b43_nphy_scale_offset_rssi(dev, 0, offset[i],
+                                                  (i / 2 == 0) ? 1 : 2,
+                                                  (i % 2 == 0) ? 0 : 1,
+                                                  2);
+               }
+       }
+       for (core = 0; core < 2; core++) {
+               if (!(rx_core_state & (1 << core)))
+                       continue;
+               for (i = 0; i < 2; i++) {
+                       b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, i);
+                       b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, i);
+                       b43_nphy_poll_rssi(dev, i, poll_results, 8);
+                       for (j = 0; j < 4; j++) {
+                               if (j / 2 == core)
+                                       offset[j] = 232 - poll_results[j];
+                               if (offset[j] < 0)
+                                       offset[j] = -(abs(offset[j] + 4) / 8);
+                               else
+                                       offset[j] = (offset[j] + 4) / 8;
+                               b43_nphy_scale_offset_rssi(dev, 0,
+                                       offset[2 * core], core + 1, j % 2, i);
+                       }
+               }
+       }
+
+       b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, saved_regs_phy_rfctl[0]);
+       b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, saved_regs_phy_rfctl[1]);
+
+       b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+
+       b43_phy_set(dev, B43_NPHY_TXF_40CO_B1S1, 0x1);
+       b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_START);
+       b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1);
+
+       b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
+       b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX);
+       b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1);
+
+       for (i = 0; i < ARRAY_SIZE(regs_to_store); i++)
+               b43_phy_write(dev, regs_to_store[i], saved_regs_phy[i]);
+
+       /* Store for future configuration */
+       if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+               rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
+               rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
+       } else {
+               rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
+               rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
+       }
+       rssical_radio_regs[0] = b43_radio_read(dev, 0x602B);
+       rssical_radio_regs[0] = b43_radio_read(dev, 0x702B);
+       rssical_phy_regs[0] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Z);
+       rssical_phy_regs[1] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z);
+       rssical_phy_regs[2] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Z);
+       rssical_phy_regs[3] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z);
+       rssical_phy_regs[4] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_X);
+       rssical_phy_regs[5] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_X);
+       rssical_phy_regs[6] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_X);
+       rssical_phy_regs[7] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_X);
+       rssical_phy_regs[8] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Y);
+       rssical_phy_regs[9] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y);
+       rssical_phy_regs[10] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Y);
+       rssical_phy_regs[11] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y);
+
+       /* Remember for which channel we store configuration */
+       if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+               nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq;
+       else
+               nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
+
+       /* End of calibration, restore configuration */
+       b43_nphy_classifier(dev, 7, class);
+       b43_nphy_write_clip_detection(dev, clip_state);
+}
+
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
 static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
 {
@@ -1472,12 +1641,6 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
        b43_nphy_reset_cca(dev);
 }
 
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
-static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
-{
-       /* TODO */
-}
-
 /*
  * RSSI Calibration
  * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
@@ -2229,27 +2392,12 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
        */
 
        for (i = 0; i < 2; i++) {
-               if (dev->phy.rev >= 3) {
-                       if (b43_nphy_ipa(dev)) {
-                               txgain = *(b43_nphy_get_ipa_gain_table(dev) +
-                                               txpi[i]);
-                       } else if (b43_current_band(dev->wl) ==
-                                  IEEE80211_BAND_5GHZ) {
-                               /* FIXME: use 5GHz tables */
-                               txgain =
-                                       b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
-                       } else {
-                               if (dev->phy.rev >= 5 &&
-                                   sprom->fem.ghz5.extpa_gain == 3)
-                                       ; /* FIXME: 5GHz_txgain_HiPwrEPA */
-                               txgain =
-                                       b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
-                       }
+               txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]);
+
+               if (dev->phy.rev >= 3)
                        radio_gain = (txgain >> 16) & 0x1FFFF;
-               } else {
-                       txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]];
+               else
                        radio_gain = (txgain >> 16) & 0x1FFF;
-               }
 
                if (dev->phy.rev >= 7)
                        dac_gain = (txgain >> 8) & 0x7;
@@ -2420,55 +2568,252 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
        nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF;
 }
 
-static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
+/* http://bcm-v4.sipsolutions.net/PHY/N/TxPwrLimitToTbl */
+static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
 {
-       struct b43_phy *phy = &dev->phy;
+       struct b43_phy_n *nphy = dev->phy.n;
 
-       const u32 *table = NULL;
-#if 0
-       TODO: b43_ntab_papd_pga_gain_delta_ipa_2*
-       u32 rfpwr_offset;
-       u8 pga_gain;
-       int i;
-#endif
+       u8 idx, delta;
+       u8 i, stf_mode;
 
-       if (phy->rev >= 3) {
-               if (b43_nphy_ipa(dev)) {
-                       table = b43_nphy_get_ipa_gain_table(dev);
+       for (i = 0; i < 4; i++)
+               nphy->adj_pwr_tbl[i] = nphy->tx_power_offset[i];
+
+       for (stf_mode = 0; stf_mode < 4; stf_mode++) {
+               delta = 0;
+               switch (stf_mode) {
+               case 0:
+                       if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
+                               idx = 68;
+                       } else {
+                               delta = 1;
+                               idx = dev->phy.is_40mhz ? 52 : 4;
+                       }
+                       break;
+               case 1:
+                       idx = dev->phy.is_40mhz ? 76 : 28;
+                       break;
+               case 2:
+                       idx = dev->phy.is_40mhz ? 84 : 36;
+                       break;
+               case 3:
+                       idx = dev->phy.is_40mhz ? 92 : 44;
+                       break;
+               }
+
+               for (i = 0; i < 20; i++) {
+                       nphy->adj_pwr_tbl[4 + 4 * i + stf_mode] =
+                               nphy->tx_power_offset[idx];
+                       if (i == 0)
+                               idx += delta;
+                       if (i == 14)
+                               idx += 1 - delta;
+                       if (i == 3 || i == 4 || i == 7 || i == 8 || i == 11 ||
+                           i == 13)
+                               idx += 1;
+               }
+       }
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
+static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
+{
+       struct b43_phy_n *nphy = dev->phy.n;
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
+
+       s16 a1[2], b0[2], b1[2];
+       u8 idle[2];
+       s8 target[2];
+       s32 num, den, pwr;
+       u32 regval[64];
+
+       u16 freq = dev->phy.channel_freq;
+       u16 tmp;
+       u16 r; /* routing */
+       u8 i, c;
+
+       if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
+               b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000);
+               b43_read32(dev, B43_MMIO_MACCTL);
+               udelay(1);
+       }
+
+       if (nphy->hang_avoid)
+               b43_nphy_stay_in_carrier_search(dev, true);
+
+       b43_phy_set(dev, B43_NPHY_TSSIMODE, B43_NPHY_TSSIMODE_EN);
+       if (dev->phy.rev >= 3)
+               b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD,
+                            ~B43_NPHY_TXPCTL_CMD_PCTLEN & 0xFFFF);
+       else
+               b43_phy_set(dev, B43_NPHY_TXPCTL_CMD,
+                           B43_NPHY_TXPCTL_CMD_PCTLEN);
+
+       if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
+               b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0);
+
+       if (sprom->revision < 4) {
+               idle[0] = nphy->pwr_ctl_info[0].idle_tssi_2g;
+               idle[1] = nphy->pwr_ctl_info[1].idle_tssi_2g;
+               target[0] = target[1] = 52;
+               a1[0] = a1[1] = -424;
+               b0[0] = b0[1] = 5612;
+               b1[0] = b1[1] = -1393;
+       } else {
+               if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+                       for (c = 0; c < 2; c++) {
+                               idle[c] = nphy->pwr_ctl_info[c].idle_tssi_2g;
+                               target[c] = sprom->core_pwr_info[c].maxpwr_2g;
+                               a1[c] = sprom->core_pwr_info[c].pa_2g[0];
+                               b0[c] = sprom->core_pwr_info[c].pa_2g[1];
+                               b1[c] = sprom->core_pwr_info[c].pa_2g[2];
+                       }
+               } else if (freq >= 4900 && freq < 5100) {
+                       for (c = 0; c < 2; c++) {
+                               idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
+                               target[c] = sprom->core_pwr_info[c].maxpwr_5gl;
+                               a1[c] = sprom->core_pwr_info[c].pa_5gl[0];
+                               b0[c] = sprom->core_pwr_info[c].pa_5gl[1];
+                               b1[c] = sprom->core_pwr_info[c].pa_5gl[2];
+                       }
+               } else if (freq >= 5100 && freq < 5500) {
+                       for (c = 0; c < 2; c++) {
+                               idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
+                               target[c] = sprom->core_pwr_info[c].maxpwr_5g;
+                               a1[c] = sprom->core_pwr_info[c].pa_5g[0];
+                               b0[c] = sprom->core_pwr_info[c].pa_5g[1];
+                               b1[c] = sprom->core_pwr_info[c].pa_5g[2];
+                       }
+               } else if (freq >= 5500) {
+                       for (c = 0; c < 2; c++) {
+                               idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
+                               target[c] = sprom->core_pwr_info[c].maxpwr_5gh;
+                               a1[c] = sprom->core_pwr_info[c].pa_5gh[0];
+                               b0[c] = sprom->core_pwr_info[c].pa_5gh[1];
+                               b1[c] = sprom->core_pwr_info[c].pa_5gh[2];
+                       }
                } else {
-                       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
-                               if (phy->rev == 3)
-                                       table = b43_ntab_tx_gain_rev3_5ghz;
-                               if (phy->rev == 4)
-                                       table = b43_ntab_tx_gain_rev4_5ghz;
-                               else
-                                       table = b43_ntab_tx_gain_rev5plus_5ghz;
+                       idle[0] = nphy->pwr_ctl_info[0].idle_tssi_5g;
+                       idle[1] = nphy->pwr_ctl_info[1].idle_tssi_5g;
+                       target[0] = target[1] = 52;
+                       a1[0] = a1[1] = -424;
+                       b0[0] = b0[1] = 5612;
+                       b1[0] = b1[1] = -1393;
+               }
+       }
+       /* target[0] = target[1] = nphy->tx_power_max; */
+
+       if (dev->phy.rev >= 3) {
+               if (sprom->fem.ghz2.tssipos)
+                       b43_phy_set(dev, B43_NPHY_TXPCTL_ITSSI, 0x4000);
+               if (dev->phy.rev >= 7) {
+                       for (c = 0; c < 2; c++) {
+                               r = c ? 0x190 : 0x170;
+                               if (b43_nphy_ipa(dev))
+                                       b43_radio_write(dev, r + 0x9, (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? 0xE : 0xC);
+                       }
+               } else {
+                       if (b43_nphy_ipa(dev)) {
+                               tmp = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
+                               b43_radio_write(dev,
+                                       B2056_TX0 | B2056_TX_TX_SSI_MUX, tmp);
+                               b43_radio_write(dev,
+                                       B2056_TX1 | B2056_TX_TX_SSI_MUX, tmp);
                        } else {
-                               table = b43_ntab_tx_gain_rev3plus_2ghz;
+                               b43_radio_write(dev,
+                                       B2056_TX0 | B2056_TX_TX_SSI_MUX, 0x11);
+                               b43_radio_write(dev,
+                                       B2056_TX1 | B2056_TX_TX_SSI_MUX, 0x11);
                        }
                }
+       }
+
+       if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
+               b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000);
+               b43_read32(dev, B43_MMIO_MACCTL);
+               udelay(1);
+       }
+
+       if (dev->phy.rev >= 7) {
+               b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
+                               ~B43_NPHY_TXPCTL_CMD_INIT, 0x19);
+               b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
+                               ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x19);
        } else {
-               table = b43_ntab_tx_gain_rev0_1_2;
+               b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
+                               ~B43_NPHY_TXPCTL_CMD_INIT, 0x40);
+               if (dev->phy.rev > 1)
+                       b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
+                               ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x40);
+       }
+
+       if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
+               b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0);
+
+       b43_phy_write(dev, B43_NPHY_TXPCTL_N,
+                     0xF0 << B43_NPHY_TXPCTL_N_TSSID_SHIFT |
+                     3 << B43_NPHY_TXPCTL_N_NPTIL2_SHIFT);
+       b43_phy_write(dev, B43_NPHY_TXPCTL_ITSSI,
+                     idle[0] << B43_NPHY_TXPCTL_ITSSI_0_SHIFT |
+                     idle[1] << B43_NPHY_TXPCTL_ITSSI_1_SHIFT |
+                     B43_NPHY_TXPCTL_ITSSI_BINF);
+       b43_phy_write(dev, B43_NPHY_TXPCTL_TPWR,
+                     target[0] << B43_NPHY_TXPCTL_TPWR_0_SHIFT |
+                     target[1] << B43_NPHY_TXPCTL_TPWR_1_SHIFT);
+
+       for (c = 0; c < 2; c++) {
+               for (i = 0; i < 64; i++) {
+                       num = 8 * (16 * b0[c] + b1[c] * i);
+                       den = 32768 + a1[c] * i;
+                       pwr = max((4 * num + den / 2) / den, -8);
+                       if (dev->phy.rev < 3 && (i <= (31 - idle[c] + 1)))
+                               pwr = max(pwr, target[c] + 1);
+                       regval[i] = pwr;
+               }
+               b43_ntab_write_bulk(dev, B43_NTAB32(26 + c, 0), 64, regval);
        }
+
+       b43_nphy_tx_prepare_adjusted_power_table(dev);
+       /*
+       b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, nphy->adj_pwr_tbl);
+       b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, nphy->adj_pwr_tbl);
+       */
+
+       if (nphy->hang_avoid)
+               b43_nphy_stay_in_carrier_search(dev, false);
+}
+
+static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
+{
+       struct b43_phy *phy = &dev->phy;
+
+       const u32 *table = NULL;
+       u32 rfpwr_offset;
+       u8 pga_gain;
+       int i;
+
+       table = b43_nphy_get_tx_gain_table(dev);
        b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
        b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
 
        if (phy->rev >= 3) {
 #if 0
                nphy->gmval = (table[0] >> 16) & 0x7000;
+#endif
 
                for (i = 0; i < 128; i++) {
                        pga_gain = (table[i] >> 24) & 0xF;
                        if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
-                               rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
+                               rfpwr_offset =
+                                b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
                        else
-                               rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_5g[pga_gain];
+                               rfpwr_offset =
+                                0; /* FIXME */
                        b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
                                       rfpwr_offset);
                        b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
                                       rfpwr_offset);
                }
-#endif
        }
 }
 
@@ -3139,32 +3484,13 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
                        B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
 
                for (i = 0; i < 2; ++i) {
+                       table = b43_nphy_get_tx_gain_table(dev);
                        if (dev->phy.rev >= 3) {
-                               enum ieee80211_band band =
-                                       b43_current_band(dev->wl);
-
-                               if (b43_nphy_ipa(dev)) {
-                                       table = b43_nphy_get_ipa_gain_table(dev);
-                               } else {
-                                       if (band == IEEE80211_BAND_5GHZ) {
-                                               if (dev->phy.rev == 3)
-                                                       table = b43_ntab_tx_gain_rev3_5ghz;
-                                               else if (dev->phy.rev == 4)
-                                                       table = b43_ntab_tx_gain_rev4_5ghz;
-                                               else
-                                                       table = b43_ntab_tx_gain_rev5plus_5ghz;
-                                       } else {
-                                               table = b43_ntab_tx_gain_rev3plus_2ghz;
-                                       }
-                               }
-
                                target.ipa[i] = (table[index[i]] >> 16) & 0xF;
                                target.pad[i] = (table[index[i]] >> 20) & 0xF;
                                target.pga[i] = (table[index[i]] >> 24) & 0xF;
                                target.txgm[i] = (table[index[i]] >> 28) & 0xF;
                        } else {
-                               table = b43_ntab_tx_gain_rev0_1_2;
-
                                target.ipa[i] = (table[index[i]] >> 16) & 0x3;
                                target.pad[i] = (table[index[i]] >> 18) & 0x3;
                                target.pga[i] = (table[index[i]] >> 20) & 0x7;
@@ -3968,13 +4294,10 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
 #endif
                }
 
-               b43_write32(dev, B43_MMIO_MACCTL,
-                       b43_read32(dev, B43_MMIO_MACCTL) &
-                       ~B43_MACCTL_GPOUTSMSK);
-               b43_write16(dev, B43_MMIO_GPIO_MASK,
-                       b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00);
-               b43_write16(dev, B43_MMIO_GPIO_CONTROL,
-                       b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00);
+               b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
+               b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xFC00);
+               b43_maskset16(dev, B43_MMIO_GPIO_CONTROL, (~0xFC00 & 0xFFFF),
+                             0);
 
                if (init) {
                        b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
@@ -4110,7 +4433,7 @@ int b43_phy_initn(struct b43_wldev *dev)
        b43_nphy_tx_power_ctrl(dev, false);
        b43_nphy_tx_power_fix(dev);
        b43_nphy_tx_power_ctl_idle_tssi(dev);
-       /* TODO N PHY TX Power Control Setup */
+       b43_nphy_tx_power_ctl_setup(dev);
        b43_nphy_tx_gain_table_upload(dev);
 
        if (nphy->phyrxchain != 3)
@@ -4530,8 +4853,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 {
        check_phyreg(dev, reg);
        b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-       b43_write16(dev, B43_MMIO_PHY_DATA,
-                   (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
+       b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
 }
 
 static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
index 5de8f74cc02f5815f973855c0e1c0cdfd20f09e2..fd12b386fea1cc5a1c0796589b650d12e6917fcf 100644 (file)
@@ -798,6 +798,7 @@ struct b43_phy_n {
        bool txpwrctrl;
        bool pwg_gain_5ghz;
        u8 tx_pwr_idx[2];
+       s8 tx_power_offset[101];
        u16 adj_pwr_tbl[84];
        u16 txcal_bbmult;
        u16 txiqlocal_bestc[11];
index f7def13524dd72dca17eef3219fb9cdb5580e531..f0d8377429c695dc6d5cbe4342d49a4bc513ef5d 100644 (file)
@@ -2214,7 +2214,7 @@ static const u16 b43_ntab_antswctl2g_r3[4][32] = {
 };
 
 /* TX gain tables */
-const u32 b43_ntab_tx_gain_rev0_1_2[] = {
+static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
        0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
        0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
        0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
@@ -2249,7 +2249,7 @@ const u32 b43_ntab_tx_gain_rev0_1_2[] = {
        0x03801442, 0x03801344, 0x03801342, 0x00002b00,
 };
 
-const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
+static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
        0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
        0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
        0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
@@ -2284,7 +2284,7 @@ const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
        0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
 };
 
-const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
+static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
        0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
        0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
        0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
@@ -2319,7 +2319,7 @@ const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
        0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
 };
 
-const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
+static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
        0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
        0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
        0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
@@ -2354,7 +2354,7 @@ const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
        0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
 };
 
-const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
+static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
        0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
        0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
        0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
@@ -2389,7 +2389,7 @@ const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
        0x0062003b, 0x00620039, 0x00620037, 0x00620035,
 };
 
-const u32 txpwrctrl_tx_gain_ipa[] = {
+static const u32 txpwrctrl_tx_gain_ipa[] = {
        0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
        0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
        0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
@@ -2424,7 +2424,7 @@ const u32 txpwrctrl_tx_gain_ipa[] = {
        0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
 };
 
-const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
+static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
        0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
        0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
        0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
@@ -2459,7 +2459,7 @@ const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
        0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
 };
 
-const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
+static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
        0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
        0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
        0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
@@ -2494,7 +2494,7 @@ const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
        0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
 };
 
-const u32 txpwrctrl_tx_gain_ipa_5g[] = {
+static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
        0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
        0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
        0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
@@ -2529,6 +2529,11 @@ const u32 txpwrctrl_tx_gain_ipa_5g[] = {
        0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
 };
 
+const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
+       -114, -108, -98, -91, -84, -78, -70, -62,
+       -54, -46, -39, -31, -23, -15, -8, 0
+};
+
 const u16 tbl_iqcal_gainparams[2][9][8] = {
        {
                { 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 },
@@ -2739,11 +2744,11 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = {
        { 0x0001,  0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */
        { 0x0002,  1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */
        { 0x0004,  2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */
-       { 0x0016,  4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */
+       { 0x0010,  4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */
        { 0x0020,  5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */
        { 0x0040,  6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */
-       { 0x0080,  6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */
-       { 0x0100,  7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */
+       { 0x0080,  7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */
+       { 0x0100,  8, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */
        { 0x0007,  0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */
        { 0x0070,  4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */
        { 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */
@@ -3126,6 +3131,53 @@ void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev)
                B43_WARN_ON(1);
 }
 
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
+static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
+{
+       if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+               if (dev->phy.rev >= 6) {
+                       if (dev->dev->chip_id == 47162)
+                               return txpwrctrl_tx_gain_ipa_rev5;
+                       return txpwrctrl_tx_gain_ipa_rev6;
+               } else if (dev->phy.rev >= 5) {
+                       return txpwrctrl_tx_gain_ipa_rev5;
+               } else {
+                       return txpwrctrl_tx_gain_ipa;
+               }
+       } else {
+               return txpwrctrl_tx_gain_ipa_5g;
+       }
+}
+
+const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
+{
+       enum ieee80211_band band = b43_current_band(dev->wl);
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
+
+       if (dev->phy.rev < 3)
+               return b43_ntab_tx_gain_rev0_1_2;
+
+       /* rev 3+ */
+       if ((dev->phy.n->ipa2g_on && band == IEEE80211_BAND_2GHZ) ||
+           (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) {
+               return b43_nphy_get_ipa_gain_table(dev);
+       } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+               if (dev->phy.rev == 3)
+                       return b43_ntab_tx_gain_rev3_5ghz;
+               if (dev->phy.rev == 4)
+                       return sprom->fem.ghz5.extpa_gain == 3 ?
+                               b43_ntab_tx_gain_rev4_5ghz :
+                               b43_ntab_tx_gain_rev4_5ghz; /* FIXME */
+               else
+                       return b43_ntab_tx_gain_rev5plus_5ghz;
+       } else {
+               if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3)
+                       return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */
+               else
+                       return b43_ntab_tx_gain_rev3plus_2ghz;
+       }
+}
+
 struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
        struct b43_wldev *dev, bool ghz5, bool ext_lna)
 {
index 97038c4819304938a6d41fed53ae3b0d65ce5a6c..f348953c02308b5c29f4048f5e4e87ebff8a37cb 100644 (file)
@@ -177,16 +177,10 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
 void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev);
 void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev);
 
-extern const u32 b43_ntab_tx_gain_rev0_1_2[];
-extern const u32 b43_ntab_tx_gain_rev3plus_2ghz[];
-extern const u32 b43_ntab_tx_gain_rev3_5ghz[];
-extern const u32 b43_ntab_tx_gain_rev4_5ghz[];
-extern const u32 b43_ntab_tx_gain_rev5plus_5ghz[];
-
-extern const u32 txpwrctrl_tx_gain_ipa[];
-extern const u32 txpwrctrl_tx_gain_ipa_rev5[];
-extern const u32 txpwrctrl_tx_gain_ipa_rev6[];
-extern const u32 txpwrctrl_tx_gain_ipa_5g[];
+const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev);
+
+extern const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[];
+
 extern const u16 tbl_iqcal_gainparams[2][9][8];
 extern const struct nphy_txiqcal_ladder ladder_lo[];
 extern const struct nphy_txiqcal_ladder ladder_iq[];
index 96faaef3661b075fc2a3b52f8c08a7d91b708d20..950334197f403e12daaaf274b31bb78c9a792cee 100644 (file)
@@ -1860,7 +1860,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
         * which accounts for the factor of 4 */
 #define REG_MAX_PWR 20
        max_pwr = min(REG_MAX_PWR * 4
-                     - dev->dev->bus->sprom.antenna_gain.ghz24.a0
+                     - dev->dev->bus->sprom.antenna_gain.a0
                      - 0x6, max_pwr);
 
        /* find the desired power in Q5.2 - power_level is in dBm
index cd6375de2a606a2662ba2c5a63e5906c88b4656c..c5104533e24e7a7986e6445d8108f91e0cc73e40 100644 (file)
@@ -26,16 +26,25 @@ config BRCMFMAC
          it'll be called brcmfmac.ko.
 
 config BRCMFMAC_SDIO
-       bool "SDIO bus interface support for FullMAC"
+       bool "SDIO bus interface support for FullMAC driver"
        depends on MMC
        depends on BRCMFMAC
        select FW_LOADER
        default y
        ---help---
          This option enables the SDIO bus interface support for Broadcom
-         FullMAC WLAN driver.
-         Say Y if you want to use brcmfmac for a compatible SDIO interface
-         wireless card.
+         IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
+         use the driver for a SDIO wireless card.
+
+config BRCMFMAC_USB
+       bool "USB bus interface support for FullMAC driver"
+       depends on USB
+       depends on BRCMFMAC
+       select FW_LOADER
+       ---help---
+         This option enables the USB bus interface support for Broadcom
+         IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
+         use the driver for an USB wireless card.
 
 config BRCMDBG
        bool "Broadcom driver debug functions"
index f41c047eca8292652204b6c43e8de19c39503445..b987920e982e2db07aa49dc9ffadf5070addfa98 100644 (file)
@@ -16,7 +16,7 @@
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 # common flags
-subdir-ccflags-$(CONFIG_BRCMDBG)       += -DBCMDBG
+subdir-ccflags-$(CONFIG_BRCMDBG)       += -DDEBUG
 
 obj-$(CONFIG_BRCMUTIL) += brcmutil/
 obj-$(CONFIG_BRCMFMAC) += brcmfmac/
index 9ca9ea1135ea3c311938bf9d86d6b98a557deeba..abb48032753b1d1b1a11ec1b1a67feb2a92c53f5 100644 (file)
@@ -19,6 +19,8 @@ ccflags-y += \
        -Idrivers/net/wireless/brcm80211/brcmfmac       \
        -Idrivers/net/wireless/brcm80211/include
 
+ccflags-y += -D__CHECK_ENDIAN__
+
 obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
 brcmfmac-objs += \
                wl_cfg80211.o \
@@ -30,5 +32,5 @@ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
                bcmsdh.o \
                bcmsdh_sdmmc.o \
                sdio_chip.o
-
-ccflags-y += -D__CHECK_ENDIAN__
+brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
+               usb.o
index 4bc8d251acf8ed79d446b0dce22c938ca9bcb709..e925290b432bc104057be312664e322a18a66ac6 100644 (file)
@@ -15,6 +15,8 @@
  */
 /* ****************** SDIO CARD Interface Functions **************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/export.h>
index 9b8c0ed833d40f523ffbb9ea9f3388ad610daa71..4688904908ec464b3b9895504e8566eb61d6c5e7 100644 (file)
@@ -13,6 +13,9 @@
  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/mmc/sdio.h>
@@ -291,13 +294,14 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
                               struct sk_buff *pkt)
 {
        int status;
-       uint pkt_len = pkt->len;
+       uint pkt_len;
        bool fifo = (fix_inc == SDIOH_DATA_FIX);
 
        brcmf_dbg(TRACE, "Enter\n");
 
        if (pkt == NULL)
                return -EINVAL;
+       pkt_len = pkt->len;
 
        brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
        if (brcmf_pm_resume_error(sdiodev))
@@ -485,7 +489,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
                sdiodev->func[0] = func->card->sdio_func[0];
                sdiodev->func[1] = func;
                sdiodev->bus_if = bus_if;
-               bus_if->bus_priv = sdiodev;
+               bus_if->bus_priv.sdio = sdiodev;
                bus_if->type = SDIO_BUS;
                bus_if->align = BRCMF_SDALIGN;
                dev_set_drvdata(&func->card->dev, sdiodev);
@@ -526,7 +530,7 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
 
        if (func->num == 2) {
                bus_if = dev_get_drvdata(&func->dev);
-               sdiodev = bus_if->bus_priv;
+               sdiodev = bus_if->bus_priv.sdio;
                brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
                brcmf_sdio_remove(sdiodev);
                dev_set_drvdata(&func->card->dev, NULL);
@@ -593,14 +597,14 @@ static struct sdio_driver brcmf_sdmmc_driver = {
 #endif /* CONFIG_PM_SLEEP */
 };
 
-static void __exit brcmf_sdio_exit(void)
+void brcmf_sdio_exit(void)
 {
        brcmf_dbg(TRACE, "Enter\n");
 
        sdio_unregister_driver(&brcmf_sdmmc_driver);
 }
 
-static int __init brcmf_sdio_init(void)
+void brcmf_sdio_init(void)
 {
        int ret;
 
@@ -610,9 +614,4 @@ static int __init brcmf_sdio_init(void)
 
        if (ret)
                brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret);
-
-       return ret;
 }
-
-module_init(brcmf_sdio_init);
-module_exit(brcmf_sdio_exit);
index e58ea40a75b0679645a983a715fbfa1e71fb0fe3..07686a748d3cf3ae3746784d34f40d796f93fbc2 100644 (file)
@@ -644,9 +644,9 @@ extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
 extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
                                       uint cmd, void *buf, uint len);
 
-#ifdef BCMDBG
+#ifdef DEBUG
 extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size);
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
 extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name);
 extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx,
index ad9be2410b59337158879fe301673433d68d6320..366916494be402a90ffdc5654cc286f075bdc795 100644 (file)
@@ -39,8 +39,11 @@ struct dngl_stats {
 /* interface structure between common and bus layer */
 struct brcmf_bus {
        u8 type;                /* bus type */
-       void *bus_priv;         /* pointer to bus private structure */
-       void *drvr;             /* pointer to driver pub structure brcmf_pub */
+       union {
+               struct brcmf_sdio_dev *sdio;
+               struct brcmf_usbdev *usb;
+       } bus_priv;
+       struct brcmf_pub *drvr; /* pointer to driver pub structure brcmf_pub */
        enum brcmf_bus_state state;
        uint maxctl;            /* Max size rxctl request from proto to bus */
        bool drvr_up;           /* Status flag of driver up/down */
@@ -102,4 +105,14 @@ extern int brcmf_bus_start(struct device *dev);
 
 extern int brcmf_add_if(struct device *dev, int ifidx,
                        char *name, u8 *mac_addr);
+
+#ifdef CONFIG_BRCMFMAC_SDIO
+extern void brcmf_sdio_exit(void);
+extern void brcmf_sdio_init(void);
+#endif
+#ifdef CONFIG_BRCMFMAC_USB
+extern void brcmf_usb_exit(void);
+extern void brcmf_usb_init(void);
+#endif
+
 #endif                         /* _BRCMF_BUS_H_ */
index ac8d1f4378886c53d2678c5ab763a9bfd6b87951..b3e3b7f25d82332226be904263de4b7109b84823 100644 (file)
@@ -19,6 +19,8 @@
  * For certain dcmd codes, the dongle interprets string data from the host.
  ******************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/sched.h>
index a51d8f5d36fcf843bf311e5e257d560bb134e134..4187435220f34fbbb5b33fb9d266ffaff121c713 100644 (file)
@@ -13,6 +13,9 @@
  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/sched.h>
@@ -38,7 +41,7 @@
 #define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN     \
        offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern)
 
-#ifdef BCMDBG
+#ifdef DEBUG
 static const char brcmf_version[] =
        "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
        __DATE__ " at " __TIME__;
@@ -133,7 +136,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
        return p != NULL;
 }
 
-#ifdef BCMDBG
+#ifdef DEBUG
 static void
 brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
 {
@@ -399,10 +402,10 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
                p = (char *)&buf[sizeof(struct msgtrace_hdr)];
                while ((s = strstr(p, "\n")) != NULL) {
                        *s = '\0';
-                       printk(KERN_DEBUG"%s\n", p);
+                       pr_debug("%s\n", p);
                        p = s + 1;
                }
-               printk(KERN_DEBUG "%s\n", p);
+               pr_debug("%s\n", p);
 
                /* Reset datalen to avoid display below */
                datalen = 0;
@@ -430,7 +433,7 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
                brcmf_dbg(EVENT, "\n");
        }
 }
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
 int
 brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
@@ -518,9 +521,9 @@ brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
                break;
        }
 
-#ifdef BCMDBG
+#ifdef DEBUG
        brcmf_c_show_host_event(event, event_data);
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
        return 0;
 }
index bb26ee36bc6894e3223f35b2838e391892a947c4..a2c4576cf9ff3fa50e303cf03d1c042a40b45f75 100644 (file)
 #define BRCMF_BTA_VAL  0x1000
 #define BRCMF_ISCAN_VAL 0x2000
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 
 #define brcmf_dbg(level, fmt, ...)                                     \
 do {                                                                   \
        if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) {                   \
                if (brcmf_msg_level & BRCMF_##level##_VAL) {            \
                        if (net_ratelimit())                            \
-                               printk(KERN_DEBUG "%s: " fmt,           \
-                                      __func__, ##__VA_ARGS__);        \
+                               pr_debug("%s: " fmt,                    \
+                                        __func__, ##__VA_ARGS__);      \
                }                                                       \
        } else {                                                        \
                if (brcmf_msg_level & BRCMF_##level##_VAL) {            \
-                       printk(KERN_DEBUG "%s: " fmt,                   \
-                              __func__, ##__VA_ARGS__);                \
+                       pr_debug("%s: " fmt,                            \
+                                __func__, ##__VA_ARGS__);              \
                }                                                       \
        }                                                               \
 } while (0)
@@ -56,7 +56,7 @@ do {                                                                  \
 #define BRCMF_BYTES_ON()       (brcmf_msg_level & BRCMF_BYTES_VAL)
 #define BRCMF_GLOM_ON()                (brcmf_msg_level & BRCMF_GLOM_VAL)
 
-#else  /* (defined BCMDBG) || (defined BCMDBG) */
+#else  /* (defined DEBUG) || (defined DEBUG) */
 
 #define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
 
@@ -66,7 +66,13 @@ do {                                                                 \
 #define BRCMF_BYTES_ON()       0
 #define BRCMF_GLOM_ON()                0
 
-#endif                         /* defined(BCMDBG) */
+#endif                         /* defined(DEBUG) */
+
+#define brcmf_dbg_hex_dump(test, data, len, fmt, ...)                  \
+do {                                                                   \
+       if (test)                                                       \
+               brcmu_dbg_hex_dump(data, len, fmt, ##__VA_ARGS__);      \
+} while (0)
 
 extern int brcmf_msg_level;
 
index eb9eb766ac270d5e3011b98568343eeba12c5833..2a1e5ae0c4024ff560b40dade098c4599894feb5 100644 (file)
@@ -14,6 +14,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
@@ -590,8 +592,8 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
        sprintf(info->bus_info, "%s", dev_name(drvr->dev));
 }
 
-static struct ethtool_ops brcmf_ethtool_ops = {
-       .get_drvinfo = brcmf_ethtool_get_drvinfo
+static const struct ethtool_ops brcmf_ethtool_ops = {
+       .get_drvinfo = brcmf_ethtool_get_drvinfo,
 };
 
 static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
@@ -794,18 +796,19 @@ static int brcmf_netdev_open(struct net_device *ndev)
 {
        struct brcmf_if *ifp = netdev_priv(ndev);
        struct brcmf_pub *drvr = ifp->drvr;
+       struct brcmf_bus *bus_if = drvr->bus_if;
        u32 toe_ol;
        s32 ret = 0;
 
        brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
 
        if (ifp->idx == 0) {    /* do it only for primary eth0 */
-               /* try to bring up bus */
-               ret = brcmf_bus_start(drvr->dev);
-               if (ret != 0) {
-                       brcmf_dbg(ERROR, "failed with code %d\n", ret);
-                       return -1;
+               /* If bus is not ready, can't continue */
+               if (bus_if->state != BRCMF_BUS_DATA) {
+                       brcmf_dbg(ERROR, "failed bus is not ready\n");
+                       return -EAGAIN;
                }
+
                atomic_set(&drvr->pend_8021x_cnt, 0);
 
                memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
@@ -977,12 +980,6 @@ int brcmf_bus_start(struct device *dev)
                return ret;
        }
 
-       /* If bus is not ready, can't come up */
-       if (bus_if->state != BRCMF_BUS_DATA) {
-               brcmf_dbg(ERROR, "failed bus is not ready\n");
-               return -ENODEV;
-       }
-
        brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
                      iovbuf, sizeof(iovbuf));
        brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
@@ -1019,6 +1016,8 @@ int brcmf_bus_start(struct device *dev)
        if (ret < 0)
                return ret;
 
+       /* signal bus ready */
+       bus_if->state = BRCMF_BUS_DATA;
        return 0;
 }
 
@@ -1107,13 +1106,13 @@ void brcmf_detach(struct device *dev)
                if (drvr->iflist[i])
                        brcmf_del_if(drvr, i);
 
-       cancel_work_sync(&drvr->setmacaddr_work);
-       cancel_work_sync(&drvr->multicast_work);
-
        brcmf_bus_detach(drvr);
 
-       if (drvr->prot)
+       if (drvr->prot) {
+               cancel_work_sync(&drvr->setmacaddr_work);
+               cancel_work_sync(&drvr->multicast_work);
                brcmf_proto_detach(drvr);
+       }
 
        bus_if->drvr = NULL;
        kfree(drvr);
@@ -1146,7 +1145,7 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
        return pend;
 }
 
-#ifdef BCMDBG
+#ifdef DEBUG
 int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size)
 {
        int ret = 0;
@@ -1180,4 +1179,38 @@ exit:
 
        return ret;
 }
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
+
+static void brcmf_driver_init(struct work_struct *work)
+{
+#ifdef CONFIG_BRCMFMAC_SDIO
+       brcmf_sdio_init();
+#endif
+#ifdef CONFIG_BRCMFMAC_USB
+       brcmf_usb_init();
+#endif
+}
+static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);
+
+static int __init brcmfmac_module_init(void)
+{
+       if (!schedule_work(&brcmf_driver_work))
+               return -EBUSY;
+
+       return 0;
+}
+
+static void __exit brcmfmac_module_exit(void)
+{
+       cancel_work_sync(&brcmf_driver_work);
+
+#ifdef CONFIG_BRCMFMAC_SDIO
+       brcmf_sdio_exit();
+#endif
+#ifdef CONFIG_BRCMFMAC_USB
+       brcmf_usb_exit();
+#endif
+}
+
+module_init(brcmfmac_module_init);
+module_exit(brcmfmac_module_exit);
index f7eeee1dcdb66a8b3a09c5534bb8f15a15f09e91..0b467b08604db3a0cb9e3eb62500266d1ac20e16 100644 (file)
@@ -14,6 +14,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
@@ -40,7 +42,7 @@
 
 #define DCMD_RESP_TIMEOUT  2000        /* In milli second */
 
-#ifdef BCMDBG
+#ifdef DEBUG
 
 #define BRCMF_TRAP_INFO_SIZE   80
 
@@ -84,7 +86,7 @@ struct rte_console {
        char cbuf[CBUF_LEN];
 };
 
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 #include <chipcommon.h>
 
 #include "dhd_bus.h"
@@ -307,10 +309,10 @@ struct rte_console {
 /* Flags for SDH calls */
 #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
 
-#define BRCMFMAC_FW_NAME       "brcm/brcmfmac.bin"
-#define BRCMFMAC_NV_NAME       "brcm/brcmfmac.txt"
-MODULE_FIRMWARE(BRCMFMAC_FW_NAME);
-MODULE_FIRMWARE(BRCMFMAC_NV_NAME);
+#define BRCMF_SDIO_FW_NAME     "brcm/brcmfmac-sdio.bin"
+#define BRCMF_SDIO_NV_NAME     "brcm/brcmfmac-sdio.txt"
+MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME);
+MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME);
 
 #define BRCMF_IDLE_IMMEDIATE   (-1)    /* Enter idle immediately */
 #define BRCMF_IDLE_ACTIVE      0       /* Do not request any SD clock change
@@ -416,7 +418,7 @@ struct sdpcmd_regs {
        u16 PAD[0x80];
 };
 
-#ifdef BCMDBG
+#ifdef DEBUG
 /* Device console log buffer state */
 struct brcmf_console {
        uint count;             /* Poll interval msec counter */
@@ -426,7 +428,7 @@ struct brcmf_console {
        u8 *buf;                /* Log buffer (host copy) */
        uint last;              /* Last buffer read index */
 };
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
 struct sdpcm_shared {
        u32 flags;
@@ -507,11 +509,11 @@ struct brcmf_sdio {
        uint polltick;          /* Tick counter */
        uint pollcnt;           /* Count of active polls */
 
-#ifdef BCMDBG
+#ifdef DEBUG
        uint console_interval;
        struct brcmf_console console;   /* Console output polling support */
        uint console_addr;      /* Console address from shared struct */
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
        uint regfails;          /* Count of R_REG failures */
 
@@ -587,10 +589,10 @@ struct brcmf_sdio {
 #define CLK_PENDING    2       /* Not used yet */
 #define CLK_AVAIL      3
 
-#ifdef BCMDBG
+#ifdef DEBUG
 static int qcount[NUMPRIO];
 static int tx_packets[NUMPRIO];
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
 #define SDIO_DRIVE_STRENGTH    6       /* in milliamps */
 
@@ -764,12 +766,12 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
                bus->clkstate = CLK_AVAIL;
                brcmf_dbg(INFO, "CLKCTL: turned ON\n");
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
                if (bus->alp_only != true) {
                        if (SBSDIO_ALPONLY(clkctl))
                                brcmf_dbg(ERROR, "HT Clock should be on\n");
                }
-#endif                         /* defined (BCMDBG) */
+#endif                         /* defined (DEBUG) */
 
                bus->activity = true;
        } else {
@@ -814,9 +816,9 @@ static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on)
 /* Transition SD and backplane clock readiness */
 static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
 {
-#ifdef BCMDBG
+#ifdef DEBUG
        uint oldstate = bus->clkstate;
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
        brcmf_dbg(TRACE, "Enter\n");
 
@@ -861,9 +863,9 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
                brcmf_sdbrcm_wd_timer(bus, 0);
                break;
        }
-#ifdef BCMDBG
+#ifdef DEBUG
        brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate);
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
        return 0;
 }
@@ -1279,13 +1281,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
                        }
                        return 0;
                }
-#ifdef BCMDBG
-               if (BRCMF_GLOM_ON()) {
-                       printk(KERN_DEBUG "SUPERFRAME:\n");
-                       print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                               pfirst->data, min_t(int, pfirst->len, 48));
-               }
-#endif
+
+               brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
+                                  pfirst->data, min_t(int, pfirst->len, 48),
+                                  "SUPERFRAME:\n");
 
                /* Validate the superframe header */
                dptr = (u8 *) (pfirst->data);
@@ -1362,13 +1361,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
                        check = get_unaligned_le16(dptr + sizeof(u16));
                        chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
                        doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
-#ifdef BCMDBG
-                       if (BRCMF_GLOM_ON()) {
-                               printk(KERN_DEBUG "subframe:\n");
-                               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                                                    dptr, 32);
-                       }
-#endif
+                       brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
+                                          dptr, 32, "subframe:\n");
 
                        if ((u16)~(sublen ^ check)) {
                                brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n",
@@ -1433,13 +1427,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
                        }
                        rxseq++;
 
-#ifdef BCMDBG
-                       if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
-                               printk(KERN_DEBUG "Rx Subframe Data:\n");
-                               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                                                    dptr, dlen);
-                       }
-#endif
+                       brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
+                                          dptr, dlen, "Rx Subframe Data:\n");
 
                        __skb_trim(pfirst, sublen);
                        skb_pull(pfirst, doff);
@@ -1457,17 +1446,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
                                continue;
                        }
 
-#ifdef BCMDBG
-                       if (BRCMF_GLOM_ON()) {
-                               brcmf_dbg(GLOM, "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n",
-                                         bus->glom.qlen, pfirst, pfirst->data,
-                                         pfirst->len, pfirst->next,
-                                         pfirst->prev);
-                               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                                               pfirst->data,
-                                               min_t(int, pfirst->len, 32));
-                       }
-#endif                         /* BCMDBG */
+                       brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
+                                          pfirst->data,
+                                          min_t(int, pfirst->len, 32),
+                                          "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n",
+                                          bus->glom.qlen, pfirst, pfirst->data,
+                                          pfirst->len, pfirst->next,
+                                          pfirst->prev);
                }
                /* sent any remaining packets up */
                if (bus->glom.qlen) {
@@ -1584,12 +1569,8 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
 
 gotpkt:
 
-#ifdef BCMDBG
-       if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) {
-               printk(KERN_DEBUG "RxCtrl:\n");
-               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len);
-       }
-#endif
+       brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
+                          bus->rxctl, len, "RxCtrl:\n");
 
        /* Point to valid data and indicate its length */
        bus->rxctl += doff;
@@ -1818,17 +1799,13 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
                        }
                        bus->tx_max = txmax;
 
-#ifdef BCMDBG
-                       if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
-                               printk(KERN_DEBUG "Rx Data:\n");
-                               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                                                    rxbuf, len);
-                       } else if (BRCMF_HDRS_ON()) {
-                               printk(KERN_DEBUG "RxHdr:\n");
-                               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                                                    bus->rxhdr, SDPCM_HDRLEN);
-                       }
-#endif
+                       brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
+                                          rxbuf, len, "Rx Data:\n");
+                       brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
+                                            BRCMF_DATA_ON()) &&
+                                          BRCMF_HDRS_ON(),
+                                          bus->rxhdr, SDPCM_HDRLEN,
+                                          "RxHdr:\n");
 
                        if (chan == SDPCM_CONTROL_CHANNEL) {
                                brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n",
@@ -1865,13 +1842,9 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
                        brcmf_sdbrcm_rxfail(bus, true, true);
                        continue;
                }
-#ifdef BCMDBG
-               if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) {
-                       printk(KERN_DEBUG "RxHdr:\n");
-                       print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                                            bus->rxhdr, SDPCM_HDRLEN);
-               }
-#endif
+               brcmf_dbg_hex_dump(BRCMF_BYTES_ON() || BRCMF_HDRS_ON(),
+                                  bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n");
+
 
                /* Extract hardware header fields */
                len = get_unaligned_le16(bus->rxhdr);
@@ -2024,13 +1997,8 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
                skb_push(pkt, BRCMF_FIRSTREAD);
                memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD);
 
-#ifdef BCMDBG
-               if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
-                       printk(KERN_DEBUG "Rx Data:\n");
-                       print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                                            pkt->data, len);
-               }
-#endif
+               brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
+                                  pkt->data, len, "Rx Data:\n");
 
 deliver:
                /* Save superframe descriptor and allocate packet frame */
@@ -2038,14 +2006,9 @@ deliver:
                        if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
                                brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n",
                                          len);
-#ifdef BCMDBG
-                               if (BRCMF_GLOM_ON()) {
-                                       printk(KERN_DEBUG "Glom Data:\n");
-                                       print_hex_dump_bytes("",
-                                                            DUMP_PREFIX_OFFSET,
-                                                            pkt->data, len);
-                               }
-#endif
+                               brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
+                                                  pkt->data, len,
+                                                  "Glom Data:\n");
                                __skb_trim(pkt, len);
                                skb_pull(pkt, SDPCM_HDRLEN);
                                bus->glomd = pkt;
@@ -2078,13 +2041,11 @@ deliver:
                down(&bus->sdsem);
        }
        rxcount = maxframes - rxleft;
-#ifdef BCMDBG
        /* Message if we hit the limit */
        if (!rxleft)
                brcmf_dbg(DATA, "hit rx limit of %d frames\n",
                          maxframes);
        else
-#endif                         /* BCMDBG */
                brcmf_dbg(DATA, "processed %d frames\n", rxcount);
        /* Back off rxseq if awaiting rtx, update rx_seq */
        if (bus->rxskip)
@@ -2176,20 +2137,22 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
        put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
        put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
 
-#ifdef BCMDBG
+#ifdef DEBUG
        tx_packets[pkt->priority]++;
-       if (BRCMF_BYTES_ON() &&
-           (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
-             (BRCMF_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
-               printk(KERN_DEBUG "Tx Frame:\n");
-               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len);
-       } else if (BRCMF_HDRS_ON()) {
-               printk(KERN_DEBUG "TxHdr:\n");
-               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                                    frame, min_t(u16, len, 16));
-       }
 #endif
 
+       brcmf_dbg_hex_dump(BRCMF_BYTES_ON() &&
+                          ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
+                           (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)),
+                          frame, len, "Tx Frame:\n");
+       brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
+                            ((BRCMF_CTL_ON() &&
+                              chan == SDPCM_CONTROL_CHANNEL) ||
+                             (BRCMF_DATA_ON() &&
+                              chan != SDPCM_CONTROL_CHANNEL))) &&
+                          BRCMF_HDRS_ON(),
+                          frame, min_t(u16, len, 16), "TxHdr:\n");
+
        /* Raise len to next SDIO block to eliminate tail command */
        if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
                u16 pad = bus->blocksize - (len % bus->blocksize);
@@ -2314,7 +2277,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
        uint retries;
        int err;
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv;
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
        struct brcmf_sdio *bus = sdiodev->bus;
 
        brcmf_dbg(TRACE, "Enter\n");
@@ -2410,7 +2373,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
                int err;
                u8 clkctl, devctl = 0;
 
-#ifdef BCMDBG
+#ifdef DEBUG
                /* Check for inconsistent device control */
                devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
                                               SBSDIO_DEVICE_CTL, &err);
@@ -2418,7 +2381,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
                        brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err);
                        bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
                }
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
                /* Read CSR, if clock on switch to AVAIL, else ignore */
                clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
@@ -2664,7 +2627,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
        int ret = -EBADE;
        uint datalen, prec;
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv;
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
        struct brcmf_sdio *bus = sdiodev->bus;
 
        brcmf_dbg(TRACE, "Enter\n");
@@ -2701,7 +2664,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
                brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON);
        }
 
-#ifdef BCMDBG
+#ifdef DEBUG
        if (pktq_plen(&bus->txq, prec) > qcount[prec])
                qcount[prec] = pktq_plen(&bus->txq, prec);
 #endif
@@ -2774,7 +2737,7 @@ xfer_done:
        return bcmerror;
 }
 
-#ifdef BCMDBG
+#ifdef DEBUG
 #define CONSOLE_LINE_MAX       192
 
 static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
@@ -2845,14 +2808,14 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
                        if (line[n - 1] == '\r')
                                n--;
                        line[n] = 0;
-                       printk(KERN_DEBUG "CONSOLE: %s\n", line);
+                       pr_debug("CONSOLE: %s\n", line);
                }
        }
 break2:
 
        return 0;
 }
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
 static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
 {
@@ -2906,7 +2869,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
        u8 doff = 0;
        int ret = -1;
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv;
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
        struct brcmf_sdio *bus = sdiodev->bus;
 
        brcmf_dbg(TRACE, "Enter\n");
@@ -2982,17 +2945,11 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
        }
 
        if (ret == -1) {
-#ifdef BCMDBG
-               if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) {
-                       printk(KERN_DEBUG "Tx Frame:\n");
-                       print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                                            frame, len);
-               } else if (BRCMF_HDRS_ON()) {
-                       printk(KERN_DEBUG "TxHdr:\n");
-                       print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                                            frame, min_t(u16, len, 16));
-               }
-#endif
+               brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
+                                  frame, len, "Tx Frame:\n");
+               brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
+                                  BRCMF_HDRS_ON(),
+                                  frame, min_t(u16, len, 16), "TxHdr:\n");
 
                do {
                        ret = brcmf_tx_frame(bus, frame, len);
@@ -3021,7 +2978,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
        uint rxlen = 0;
        bool pending;
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv;
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
        struct brcmf_sdio *bus = sdiodev->bus;
 
        brcmf_dbg(TRACE, "Enter\n");
@@ -3096,9 +3053,9 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
        u8 *vbuffer;
        u32 varsizew;
        __le32 varsizew_le;
-#ifdef BCMDBG
+#ifdef DEBUG
        char *nvram_ularray;
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
        /* Even if there are no vars are to be written, we still
                 need to set the ramsize. */
@@ -3115,7 +3072,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
                /* Write the vars list */
                bcmerror =
                    brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
-#ifdef BCMDBG
+#ifdef DEBUG
                /* Verify NVRAM bytes */
                brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
                nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
@@ -3142,7 +3099,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
                        brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
 
                kfree(nvram_ularray);
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
                kfree(vbuffer);
        }
@@ -3245,7 +3202,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
 
        brcmf_dbg(INFO, "Enter\n");
 
-       ret = request_firmware(&bus->firmware, BRCMFMAC_FW_NAME,
+       ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME,
                               &bus->sdiodev->func[2]->dev);
        if (ret) {
                brcmf_dbg(ERROR, "Fail to request firmware %d\n", ret);
@@ -3342,7 +3299,7 @@ static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
        char *bufp;
        int ret;
 
-       ret = request_firmware(&bus->firmware, BRCMFMAC_NV_NAME,
+       ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
                               &bus->sdiodev->func[2]->dev);
        if (ret) {
                brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
@@ -3432,7 +3389,7 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
 static int brcmf_sdbrcm_bus_init(struct device *dev)
 {
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv;
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
        struct brcmf_sdio *bus = sdiodev->bus;
        unsigned long timeout;
        uint retries = 0;
@@ -3507,16 +3464,12 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
 
                brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
                                       SBSDIO_WATERMARK, 8, &err);
-
-               /* Set bus state according to enable result */
-               bus_if->state = BRCMF_BUS_DATA;
-       }
-
-       else {
+       } else {
                /* Disable F2 again */
                enable = SDIO_FUNC_ENABLE_1;
                brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0,
                                       SDIO_CCCR_IOEx, enable, NULL);
+               ret = -ENODEV;
        }
 
        /* Restore previous clock setting */
@@ -3524,7 +3477,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
                               SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
 
        /* If we didn't come up, turn off backplane clock */
-       if (bus_if->state != BRCMF_BUS_DATA)
+       if (!ret)
                brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
 
 exit:
@@ -3569,9 +3522,9 @@ void brcmf_sdbrcm_isr(void *arg)
 
 static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
 {
-#ifdef BCMDBG
+#ifdef DEBUG
        struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev);
-#endif /* BCMDBG */
+#endif /* DEBUG */
 
        brcmf_dbg(TIMER, "Enter\n");
 
@@ -3616,7 +3569,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
                /* Update interrupt tracking */
                bus->lastintrs = bus->intrcount;
        }
-#ifdef BCMDBG
+#ifdef DEBUG
        /* Poll for console output periodically */
        if (bus_if->state == BRCMF_BUS_DATA &&
            bus->console_interval != 0) {
@@ -3630,7 +3583,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
                                bus->console_interval = 0;
                }
        }
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
        /* On idle timeout clear activity flag and/or turn off clock */
        if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
@@ -3721,11 +3674,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
        if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE))
                brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n");
 
-#ifdef BCMDBG
-       printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n",
-              brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4));
-
-#endif                         /* BCMDBG */
+       pr_debug("F1 signature read @0x18000000=0x%4x\n",
+                brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4));
 
        /*
         * Force PLL off until brcmf_sdio_chip_attach()
@@ -3944,8 +3894,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
        bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,
                                        bus, "brcmf_watchdog");
        if (IS_ERR(bus->watchdog_tsk)) {
-               printk(KERN_WARNING
-                      "brcmf_watchdog thread failed to start\n");
+               pr_warn("brcmf_watchdog thread failed to start\n");
                bus->watchdog_tsk = NULL;
        }
        /* Initialize DPC thread */
@@ -3953,8 +3902,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
        bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
                                   bus, "brcmf_dpc");
        if (IS_ERR(bus->dpc_tsk)) {
-               printk(KERN_WARNING
-                      "brcmf_dpc thread failed to start\n");
+               pr_warn("brcmf_dpc thread failed to start\n");
                bus->dpc_tsk = NULL;
        }
 
index 11b2d7c97ba22072e8231fd02f2758e7d0bf5945..1534efc21631482e5b7902e88511b48964a15568 100644 (file)
@@ -15,6 +15,8 @@
  */
 /* ***** SDIO interface chip backplane handle functions ***** */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/mmc/card.h>
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
new file mode 100644 (file)
index 0000000..8236422
--- /dev/null
@@ -0,0 +1,1621 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/firmware.h>
+#include <linux/usb.h>
+#include <net/cfg80211.h>
+
+#include <defs.h>
+#include <brcmu_utils.h>
+#include <brcmu_wifi.h>
+#include <dhd_bus.h>
+#include <dhd_dbg.h>
+
+#include "usb_rdl.h"
+#include "usb.h"
+
+#define IOCTL_RESP_TIMEOUT  2000
+
+#define BRCMF_USB_SYNC_TIMEOUT         300     /* ms */
+#define BRCMF_USB_DLIMAGE_SPINWAIT     100     /* in unit of ms */
+#define BRCMF_USB_DLIMAGE_LIMIT                500     /* spinwait limit (ms) */
+
+#define BRCMF_POSTBOOT_ID              0xA123  /* ID to detect if dongle
+                                                  has boot up */
+#define BRCMF_USB_RESETCFG_SPINWAIT    1       /* wait after resetcfg (ms) */
+
+#define BRCMF_USB_NRXQ 50
+#define BRCMF_USB_NTXQ 50
+
+#define CONFIGDESC(usb)         (&((usb)->actconfig)->desc)
+#define IFPTR(usb, idx)         ((usb)->actconfig->interface[(idx)])
+#define IFALTS(usb, idx)        (IFPTR((usb), (idx))->altsetting[0])
+#define IFDESC(usb, idx)        IFALTS((usb), (idx)).desc
+#define IFEPDESC(usb, idx, ep)  (IFALTS((usb), (idx)).endpoint[(ep)]).desc
+
+#define CONTROL_IF              0
+#define BULK_IF                 0
+
+#define BRCMF_USB_CBCTL_WRITE  0
+#define BRCMF_USB_CBCTL_READ   1
+#define BRCMF_USB_MAX_PKT_SIZE 1600
+
+#define BRCMF_USB_43236_FW_NAME        "brcm/brcmfmac43236b.bin"
+
+enum usbdev_suspend_state {
+       USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow
+                                                 suspend */
+       USBOS_SUSPEND_STATE_SUSPEND_PENDING,    /* Device is idle, can be
+                                                * suspended. Wating PM to
+                                                * suspend the device
+                                                */
+       USBOS_SUSPEND_STATE_SUSPENDED   /* Device suspended */
+};
+
+struct brcmf_usb_probe_info {
+       void *usbdev_info;
+       struct usb_device *usb; /* USB device pointer from OS */
+       uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
+       int intr_size; /* Size of interrupt message */
+       int interval;  /* Interrupt polling interval */
+       int vid;
+       int pid;
+       enum usb_device_speed device_speed;
+       enum usbdev_suspend_state suspend_state;
+       struct usb_interface *intf;
+};
+static struct brcmf_usb_probe_info usbdev_probe_info;
+
+struct brcmf_usb_image {
+       void *data;
+       u32 len;
+};
+static struct brcmf_usb_image g_image = { NULL, 0 };
+
+struct intr_transfer_buf {
+       u32 notification;
+       u32 reserved;
+};
+
+struct brcmf_usbdev_info {
+       struct brcmf_usbdev bus_pub; /* MUST BE FIRST */
+       spinlock_t qlock;
+       struct list_head rx_freeq;
+       struct list_head rx_postq;
+       struct list_head tx_freeq;
+       struct list_head tx_postq;
+       enum usbdev_suspend_state suspend_state;
+       uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
+
+       bool activity;
+       int rx_low_watermark;
+       int tx_low_watermark;
+       int tx_high_watermark;
+       bool txoff;
+       bool rxoff;
+       bool txoverride;
+
+       struct brcmf_usbreq *tx_reqs;
+       struct brcmf_usbreq *rx_reqs;
+
+       u8 *image;      /* buffer for combine fw and nvram */
+       int image_len;
+
+       wait_queue_head_t wait;
+       bool waitdone;
+       int sync_urb_status;
+
+       struct usb_device *usbdev;
+       struct device *dev;
+       enum usb_device_speed  device_speed;
+
+       int ctl_in_pipe, ctl_out_pipe;
+       struct urb *ctl_urb; /* URB for control endpoint */
+       struct usb_ctrlrequest ctl_write;
+       struct usb_ctrlrequest ctl_read;
+       u32 ctl_urb_actual_length;
+       int ctl_urb_status;
+       int ctl_completed;
+       wait_queue_head_t ioctl_resp_wait;
+       wait_queue_head_t ctrl_wait;
+       ulong ctl_op;
+
+       bool rxctl_deferrespok;
+
+       struct urb *bulk_urb; /* used for FW download */
+       struct urb *intr_urb; /* URB for interrupt endpoint */
+       int intr_size;          /* Size of interrupt message */
+       int interval;           /* Interrupt polling interval */
+       struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
+
+       struct brcmf_usb_probe_info probe_info;
+
+};
+
+static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
+                               struct brcmf_usbreq  *req);
+
+MODULE_AUTHOR("Broadcom Corporation");
+MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac usb driver.");
+MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac usb cards");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static struct brcmf_usbdev *brcmf_usb_get_buspub(struct device *dev)
+{
+       struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+       return bus_if->bus_priv.usb;
+}
+
+static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
+{
+       return brcmf_usb_get_buspub(dev)->devinfo;
+}
+
+#if 0
+static void
+brcmf_usb_txflowcontrol(struct brcmf_usbdev_info *devinfo, bool onoff)
+{
+       dhd_txflowcontrol(devinfo->bus_pub.netdev, 0, onoff);
+}
+#endif
+
+static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo,
+        uint *condition, bool *pending)
+{
+       DECLARE_WAITQUEUE(wait, current);
+       int timeout = IOCTL_RESP_TIMEOUT;
+
+       /* Convert timeout in millsecond to jiffies */
+       timeout = msecs_to_jiffies(timeout);
+       /* Wait until control frame is available */
+       add_wait_queue(&devinfo->ioctl_resp_wait, &wait);
+       set_current_state(TASK_INTERRUPTIBLE);
+
+       smp_mb();
+       while (!(*condition) && (!signal_pending(current) && timeout)) {
+               timeout = schedule_timeout(timeout);
+               /* Wait until control frame is available */
+               smp_mb();
+       }
+
+       if (signal_pending(current))
+               *pending = true;
+
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(&devinfo->ioctl_resp_wait, &wait);
+
+       return timeout;
+}
+
+static int brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
+{
+       if (waitqueue_active(&devinfo->ioctl_resp_wait))
+               wake_up_interruptible(&devinfo->ioctl_resp_wait);
+
+       return 0;
+}
+
+static void
+brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status)
+{
+
+       if (unlikely(devinfo == NULL))
+               return;
+
+       if (type == BRCMF_USB_CBCTL_READ) {
+               if (status == 0)
+                       devinfo->bus_pub.stats.rx_ctlpkts++;
+               else
+                       devinfo->bus_pub.stats.rx_ctlerrs++;
+       } else if (type == BRCMF_USB_CBCTL_WRITE) {
+               if (status == 0)
+                       devinfo->bus_pub.stats.tx_ctlpkts++;
+               else
+                       devinfo->bus_pub.stats.tx_ctlerrs++;
+       }
+
+       devinfo->ctl_urb_status = status;
+       devinfo->ctl_completed = true;
+       brcmf_usb_ioctl_resp_wake(devinfo);
+}
+
+static void
+brcmf_usb_ctlread_complete(struct urb *urb)
+{
+       struct brcmf_usbdev_info *devinfo =
+               (struct brcmf_usbdev_info *)urb->context;
+
+       devinfo->ctl_urb_actual_length = urb->actual_length;
+       brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ,
+               urb->status);
+}
+
+static void
+brcmf_usb_ctlwrite_complete(struct urb *urb)
+{
+       struct brcmf_usbdev_info *devinfo =
+               (struct brcmf_usbdev_info *)urb->context;
+
+       brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE,
+               urb->status);
+}
+
+static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state)
+{
+       return 0;
+}
+
+static int
+brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
+{
+       int ret;
+       u16 size;
+
+       if (devinfo == NULL || buf == NULL ||
+           len == 0 || devinfo->ctl_urb == NULL)
+               return -EINVAL;
+
+       /* If the USB/HSIC bus in sleep state, wake it up */
+       if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED)
+               if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
+                       brcmf_dbg(ERROR, "Could not Resume the bus!\n");
+                       return -EIO;
+               }
+
+       devinfo->activity = true;
+       size = len;
+       devinfo->ctl_write.wLength = cpu_to_le16p(&size);
+       devinfo->ctl_urb->transfer_buffer_length = size;
+       devinfo->ctl_urb_status = 0;
+       devinfo->ctl_urb_actual_length = 0;
+
+       usb_fill_control_urb(devinfo->ctl_urb,
+               devinfo->usbdev,
+               devinfo->ctl_out_pipe,
+               (unsigned char *) &devinfo->ctl_write,
+               buf, size,
+               (usb_complete_t)brcmf_usb_ctlwrite_complete,
+               devinfo);
+
+       ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
+       if (ret < 0)
+               brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
+
+       return ret;
+}
+
+static int
+brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
+{
+       int ret;
+       u16 size;
+
+       if ((devinfo == NULL) || (buf == NULL) || (len == 0)
+               || (devinfo->ctl_urb == NULL))
+               return -EINVAL;
+
+       size = len;
+       devinfo->ctl_read.wLength = cpu_to_le16p(&size);
+       devinfo->ctl_urb->transfer_buffer_length = size;
+
+       if (devinfo->rxctl_deferrespok) {
+               /* BMAC model */
+               devinfo->ctl_read.bRequestType = USB_DIR_IN
+                       | USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
+               devinfo->ctl_read.bRequest = DL_DEFER_RESP_OK;
+       } else {
+               /* full dongle model */
+               devinfo->ctl_read.bRequestType = USB_DIR_IN
+                       | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+               devinfo->ctl_read.bRequest = 1;
+       }
+
+       usb_fill_control_urb(devinfo->ctl_urb,
+               devinfo->usbdev,
+               devinfo->ctl_in_pipe,
+               (unsigned char *) &devinfo->ctl_read,
+               buf, size,
+               (usb_complete_t)brcmf_usb_ctlread_complete,
+               devinfo);
+
+       ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
+       if (ret < 0)
+               brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
+
+       return ret;
+}
+
+static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
+{
+       int err = 0;
+       int timeout = 0;
+       bool pending;
+       struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
+
+       if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
+               /* TODO: handle suspend/resume */
+               return -EIO;
+       }
+
+       if (test_and_set_bit(0, &devinfo->ctl_op))
+               return -EIO;
+
+       err = brcmf_usb_send_ctl(devinfo, buf, len);
+       if (err) {
+               brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
+               return err;
+       }
+
+       devinfo->ctl_completed = false;
+       timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
+                                           &pending);
+       clear_bit(0, &devinfo->ctl_op);
+       if (!timeout) {
+               brcmf_dbg(ERROR, "Txctl wait timed out\n");
+               err = -EIO;
+       }
+       return err;
+}
+
+static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
+{
+       int err = 0;
+       int timeout = 0;
+       bool pending;
+       struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
+
+       if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
+               /* TODO: handle suspend/resume */
+               return -EIO;
+       }
+       if (test_and_set_bit(0, &devinfo->ctl_op))
+               return -EIO;
+
+       err = brcmf_usb_recv_ctl(devinfo, buf, len);
+       if (err) {
+               brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
+               return err;
+       }
+       devinfo->ctl_completed = false;
+       timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
+                                           &pending);
+       err = devinfo->ctl_urb_status;
+       clear_bit(0, &devinfo->ctl_op);
+       if (!timeout) {
+               brcmf_dbg(ERROR, "rxctl wait timed out\n");
+               err = -EIO;
+       }
+       if (!err)
+               return devinfo->ctl_urb_actual_length;
+       else
+               return err;
+}
+
+static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo,
+                                         struct list_head *q)
+{
+       unsigned long flags;
+       struct brcmf_usbreq  *req;
+       spin_lock_irqsave(&devinfo->qlock, flags);
+       if (list_empty(q)) {
+               spin_unlock_irqrestore(&devinfo->qlock, flags);
+               return NULL;
+       }
+       req = list_entry(q->next, struct brcmf_usbreq, list);
+       list_del_init(q->next);
+       spin_unlock_irqrestore(&devinfo->qlock, flags);
+       return req;
+
+}
+
+static void brcmf_usb_enq(struct brcmf_usbdev_info *devinfo,
+                         struct list_head *q, struct brcmf_usbreq *req)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&devinfo->qlock, flags);
+       list_add_tail(&req->list, q);
+       spin_unlock_irqrestore(&devinfo->qlock, flags);
+}
+
+static struct brcmf_usbreq *
+brcmf_usbdev_qinit(struct list_head *q, int qsize)
+{
+       int i;
+       struct brcmf_usbreq *req, *reqs;
+
+       reqs = kzalloc(sizeof(struct brcmf_usbreq) * qsize, GFP_ATOMIC);
+       if (reqs == NULL) {
+               brcmf_dbg(ERROR, "fail to allocate memory!\n");
+               return NULL;
+       }
+       req = reqs;
+
+       for (i = 0; i < qsize; i++) {
+               req->urb = usb_alloc_urb(0, GFP_ATOMIC);
+               if (!req->urb)
+                       goto fail;
+
+               INIT_LIST_HEAD(&req->list);
+               list_add_tail(&req->list, q);
+               req++;
+       }
+       return reqs;
+fail:
+       brcmf_dbg(ERROR, "fail!\n");
+       while (!list_empty(q)) {
+               req = list_entry(q->next, struct brcmf_usbreq, list);
+               if (req && req->urb)
+                       usb_free_urb(req->urb);
+               list_del(q->next);
+       }
+       return NULL;
+
+}
+
+static void brcmf_usb_free_q(struct list_head *q, bool pending)
+{
+       struct brcmf_usbreq *req, *next;
+       int i = 0;
+       list_for_each_entry_safe(req, next, q, list) {
+               if (!req->urb) {
+                       brcmf_dbg(ERROR, "bad req\n");
+                       break;
+               }
+               i++;
+               if (pending) {
+                       usb_kill_urb(req->urb);
+               } else {
+                       usb_free_urb(req->urb);
+                       list_del_init(&req->list);
+               }
+       }
+}
+
+static void brcmf_usb_del_fromq(struct brcmf_usbdev_info *devinfo,
+                               struct brcmf_usbreq *req)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&devinfo->qlock, flags);
+       list_del_init(&req->list);
+       spin_unlock_irqrestore(&devinfo->qlock, flags);
+}
+
+
+static void brcmf_usb_tx_complete(struct urb *urb)
+{
+       struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
+       struct brcmf_usbdev_info *devinfo = req->devinfo;
+
+       brcmf_usb_del_fromq(devinfo, req);
+       if (urb->status == 0)
+               devinfo->bus_pub.bus->dstats.tx_packets++;
+       else
+               devinfo->bus_pub.bus->dstats.tx_errors++;
+
+       dev_kfree_skb(req->skb);
+       req->skb = NULL;
+       brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
+
+}
+
+static void brcmf_usb_rx_complete(struct urb *urb)
+{
+       struct brcmf_usbreq  *req = (struct brcmf_usbreq *)urb->context;
+       struct brcmf_usbdev_info *devinfo = req->devinfo;
+       struct sk_buff *skb;
+       int ifidx = 0;
+
+       brcmf_usb_del_fromq(devinfo, req);
+       skb = req->skb;
+       req->skb = NULL;
+
+       if (urb->status == 0) {
+               devinfo->bus_pub.bus->dstats.rx_packets++;
+       } else {
+               devinfo->bus_pub.bus->dstats.rx_errors++;
+               dev_kfree_skb(skb);
+               brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
+               return;
+       }
+
+       if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) {
+               skb_put(skb, urb->actual_length);
+               if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
+                       brcmf_dbg(ERROR, "rx protocol error\n");
+                       brcmu_pkt_buf_free_skb(skb);
+                       devinfo->bus_pub.bus->dstats.rx_errors++;
+               } else {
+                       brcmf_rx_packet(devinfo->dev, ifidx, skb);
+                       brcmf_usb_rx_refill(devinfo, req);
+               }
+       } else {
+               dev_kfree_skb(skb);
+       }
+       return;
+
+}
+
+static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
+                               struct brcmf_usbreq  *req)
+{
+       struct sk_buff *skb;
+       int ret;
+
+       if (!req || !devinfo)
+               return;
+
+       skb = dev_alloc_skb(devinfo->bus_pub.bus_mtu);
+       if (!skb) {
+               brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
+               return;
+       }
+       req->skb = skb;
+
+       usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe,
+                         skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,
+                         req);
+       req->urb->transfer_flags |= URB_ZERO_PACKET;
+       req->devinfo = devinfo;
+
+       ret = usb_submit_urb(req->urb, GFP_ATOMIC);
+       if (ret == 0) {
+               brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);
+       } else {
+               dev_kfree_skb(req->skb);
+               req->skb = NULL;
+               brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
+       }
+       return;
+}
+
+static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo)
+{
+       struct brcmf_usbreq *req;
+
+       if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
+               brcmf_dbg(ERROR, "bus is not up\n");
+               return;
+       }
+       while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq)) != NULL)
+               brcmf_usb_rx_refill(devinfo, req);
+}
+
+static void
+brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
+{
+       struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus;
+       int old_state;
+
+
+       if (devinfo->bus_pub.state == state)
+               return;
+
+       old_state = devinfo->bus_pub.state;
+       brcmf_dbg(TRACE, "dbus state change from %d to to %d\n",
+                 old_state, state);
+
+       /* Don't update state if it's PnP firmware re-download */
+       if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */
+               devinfo->bus_pub.state = state;
+
+       if ((old_state  == BCMFMAC_USB_STATE_SLEEP)
+               && (state == BCMFMAC_USB_STATE_UP)) {
+               brcmf_usb_rx_fill_all(devinfo);
+       }
+
+       /* update state of upper layer */
+       if (state == BCMFMAC_USB_STATE_DOWN) {
+               brcmf_dbg(INFO, "DBUS is down\n");
+               bcmf_bus->state = BRCMF_BUS_DOWN;
+       } else {
+               brcmf_dbg(INFO, "DBUS current state=%d\n", state);
+       }
+}
+
+static void
+brcmf_usb_intr_complete(struct urb *urb)
+{
+       struct brcmf_usbdev_info *devinfo =
+                       (struct brcmf_usbdev_info *)urb->context;
+       bool killed;
+
+       if (devinfo == NULL)
+               return;
+
+       if (unlikely(urb->status)) {
+               if (devinfo->suspend_state ==
+                       USBOS_SUSPEND_STATE_SUSPEND_PENDING)
+                       killed = true;
+
+               if ((urb->status == -ENOENT && (!killed))
+                       || urb->status == -ESHUTDOWN ||
+                       urb->status == -ENODEV) {
+                       brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN);
+               }
+       }
+
+       if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) {
+               brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n");
+               return;
+       }
+
+       if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
+               usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
+}
+
+static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
+{
+       struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
+       struct brcmf_usbreq  *req;
+       int ret;
+
+       if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
+               /* TODO: handle suspend/resume */
+               return -EIO;
+       }
+
+       req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);
+       if (!req) {
+               brcmf_dbg(ERROR, "no req to send\n");
+               return -ENOMEM;
+       }
+       if (!req->urb) {
+               brcmf_dbg(ERROR, "no urb for req %p\n", req);
+               return -ENOBUFS;
+       }
+
+       req->skb = skb;
+       req->devinfo = devinfo;
+       usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
+                         skb->data, skb->len, brcmf_usb_tx_complete, req);
+       req->urb->transfer_flags |= URB_ZERO_PACKET;
+       ret = usb_submit_urb(req->urb, GFP_ATOMIC);
+       if (!ret) {
+               brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
+       } else {
+               req->skb = NULL;
+               brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
+       }
+
+       return ret;
+}
+
+
+static int brcmf_usb_up(struct device *dev)
+{
+       struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
+       u16 ifnum;
+
+       if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
+               return 0;
+
+       /* If the USB/HSIC bus in sleep state, wake it up */
+       if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) {
+               if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
+                       brcmf_dbg(ERROR, "Could not Resume the bus!\n");
+                       return -EIO;
+               }
+       }
+       devinfo->activity = true;
+
+       /* Success, indicate devinfo is fully up */
+       brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP);
+
+       if (devinfo->intr_urb) {
+               int ret;
+
+               usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev,
+                       devinfo->intr_pipe,
+                       &devinfo->intr,
+                       devinfo->intr_size,
+                       (usb_complete_t)brcmf_usb_intr_complete,
+                       devinfo,
+                       devinfo->interval);
+
+               ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
+               if (ret) {
+                       brcmf_dbg(ERROR, "USB_SUBMIT_URB failed with status %d\n",
+                                 ret);
+                       return -EINVAL;
+               }
+       }
+
+       if (devinfo->ctl_urb) {
+               devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
+               devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);
+
+               ifnum = IFDESC(devinfo->usbdev, CONTROL_IF).bInterfaceNumber;
+
+               /* CTL Write */
+               devinfo->ctl_write.bRequestType =
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+               devinfo->ctl_write.bRequest = 0;
+               devinfo->ctl_write.wValue = cpu_to_le16(0);
+               devinfo->ctl_write.wIndex = cpu_to_le16p(&ifnum);
+
+               /* CTL Read */
+               devinfo->ctl_read.bRequestType =
+                       USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+               devinfo->ctl_read.bRequest = 1;
+               devinfo->ctl_read.wValue = cpu_to_le16(0);
+               devinfo->ctl_read.wIndex = cpu_to_le16p(&ifnum);
+       }
+       brcmf_usb_rx_fill_all(devinfo);
+       return 0;
+}
+
+static void brcmf_usb_down(struct device *dev)
+{
+       struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
+
+       if (devinfo == NULL)
+               return;
+
+       brcmf_dbg(TRACE, "enter\n");
+       if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN)
+               return;
+
+       brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN);
+       if (devinfo->intr_urb)
+               usb_kill_urb(devinfo->intr_urb);
+
+       if (devinfo->ctl_urb)
+               usb_kill_urb(devinfo->ctl_urb);
+
+       if (devinfo->bulk_urb)
+               usb_kill_urb(devinfo->bulk_urb);
+       brcmf_usb_free_q(&devinfo->tx_postq, true);
+
+       brcmf_usb_free_q(&devinfo->rx_postq, true);
+}
+
+static int
+brcmf_usb_sync_wait(struct brcmf_usbdev_info *devinfo, u16 time)
+{
+       int ret;
+       int err = 0;
+       int ms = time;
+
+       ret = wait_event_interruptible_timeout(devinfo->wait,
+               devinfo->waitdone == true, (ms * HZ / 1000));
+
+       if ((devinfo->waitdone == false) || (devinfo->sync_urb_status)) {
+               brcmf_dbg(ERROR, "timeout(%d) or urb err=%d\n",
+                         ret, devinfo->sync_urb_status);
+               err = -EINVAL;
+       }
+       devinfo->waitdone = false;
+       return err;
+}
+
+static void
+brcmf_usb_sync_complete(struct urb *urb)
+{
+       struct brcmf_usbdev_info *devinfo =
+                       (struct brcmf_usbdev_info *)urb->context;
+
+       devinfo->waitdone = true;
+       wake_up_interruptible(&devinfo->wait);
+       devinfo->sync_urb_status = urb->status;
+}
+
+static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
+                            void *buffer, int buflen)
+{
+       int ret = 0;
+       char *tmpbuf;
+       u16 size;
+
+       if ((!devinfo) || (devinfo->ctl_urb == NULL))
+               return false;
+
+       tmpbuf = kmalloc(buflen, GFP_ATOMIC);
+       if (!tmpbuf)
+               return false;
+
+       size = buflen;
+       devinfo->ctl_urb->transfer_buffer_length = size;
+
+       devinfo->ctl_read.wLength = cpu_to_le16p(&size);
+       devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR |
+               USB_RECIP_INTERFACE;
+       devinfo->ctl_read.bRequest = cmd;
+
+       usb_fill_control_urb(devinfo->ctl_urb,
+               devinfo->usbdev,
+               usb_rcvctrlpipe(devinfo->usbdev, 0),
+               (unsigned char *) &devinfo->ctl_read,
+               (void *) tmpbuf, size,
+               (usb_complete_t)brcmf_usb_sync_complete, devinfo);
+
+       ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
+       if (ret < 0) {
+               brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
+               kfree(tmpbuf);
+               return false;
+       }
+
+       ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT);
+       memcpy(buffer, tmpbuf, buflen);
+       kfree(tmpbuf);
+
+       return (ret == 0);
+}
+
+static bool
+brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo)
+{
+       struct bootrom_id_le id;
+       u32 chipid, chiprev;
+
+       brcmf_dbg(TRACE, "enter\n");
+
+       if (devinfo == NULL)
+               return false;
+
+       /* Check if firmware downloaded already by querying runtime ID */
+       id.chip = cpu_to_le32(0xDEAD);
+       brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id,
+               sizeof(struct bootrom_id_le));
+
+       chipid = le32_to_cpu(id.chip);
+       chiprev = le32_to_cpu(id.chiprev);
+
+       if ((chipid & 0x4300) == 0x4300)
+               brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev);
+       else
+               brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev);
+       if (chipid == BRCMF_POSTBOOT_ID) {
+               brcmf_dbg(INFO, "firmware already downloaded\n");
+               brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
+                       sizeof(struct bootrom_id_le));
+               return false;
+       } else {
+               devinfo->bus_pub.devid = chipid;
+               devinfo->bus_pub.chiprev = chiprev;
+       }
+       return true;
+}
+
+static int
+brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
+{
+       struct bootrom_id_le id;
+       u16 wait = 0, wait_time;
+
+       brcmf_dbg(TRACE, "enter\n");
+
+       if (devinfo == NULL)
+               return -EINVAL;
+
+       /* Give dongle chance to boot */
+       wait_time = BRCMF_USB_DLIMAGE_SPINWAIT;
+       while (wait < BRCMF_USB_DLIMAGE_LIMIT) {
+               mdelay(wait_time);
+               wait += wait_time;
+               id.chip = cpu_to_le32(0xDEAD);       /* Get the ID */
+               brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id,
+                       sizeof(struct bootrom_id_le));
+               if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID))
+                       break;
+       }
+
+       if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) {
+               brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n",
+                         wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev));
+
+               brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
+                       sizeof(struct bootrom_id_le));
+
+               /* XXX this wait may not be necessary */
+               mdelay(BRCMF_USB_RESETCFG_SPINWAIT);
+               return 0;
+       } else {
+               brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n",
+                         wait);
+               return -EINVAL;
+       }
+}
+
+
+static int
+brcmf_usb_dl_send_bulk(struct brcmf_usbdev_info *devinfo, void *buffer, int len)
+{
+       int ret;
+
+       if ((devinfo == NULL) || (devinfo->bulk_urb == NULL))
+               return -EINVAL;
+
+       /* Prepare the URB */
+       usb_fill_bulk_urb(devinfo->bulk_urb, devinfo->usbdev,
+                         devinfo->tx_pipe, buffer, len,
+                         (usb_complete_t)brcmf_usb_sync_complete, devinfo);
+
+       devinfo->bulk_urb->transfer_flags |= URB_ZERO_PACKET;
+
+       ret = usb_submit_urb(devinfo->bulk_urb, GFP_ATOMIC);
+       if (ret) {
+               brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
+               return ret;
+       }
+       ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT);
+       return ret;
+}
+
+static int
+brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
+{
+       unsigned int sendlen, sent, dllen;
+       char *bulkchunk = NULL, *dlpos;
+       struct rdl_state_le state;
+       u32 rdlstate, rdlbytes;
+       int err = 0;
+       brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen);
+
+       bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC);
+       if (bulkchunk == NULL) {
+               err = -ENOMEM;
+               goto fail;
+       }
+
+       /* 1) Prepare USB boot loader for runtime image */
+       brcmf_usb_dl_cmd(devinfo, DL_START, &state,
+                        sizeof(struct rdl_state_le));
+
+       rdlstate = le32_to_cpu(state.state);
+       rdlbytes = le32_to_cpu(state.bytes);
+
+       /* 2) Check we are in the Waiting state */
+       if (rdlstate != DL_WAITING) {
+               brcmf_dbg(ERROR, "Failed to DL_START\n");
+               err = -EINVAL;
+               goto fail;
+       }
+       sent = 0;
+       dlpos = fw;
+       dllen = fwlen;
+
+       /* Get chip id and rev */
+       while (rdlbytes != dllen) {
+               /* Wait until the usb device reports it received all
+                * the bytes we sent */
+               if ((rdlbytes == sent) && (rdlbytes != dllen)) {
+                       if ((dllen-sent) < RDL_CHUNK)
+                               sendlen = dllen-sent;
+                       else
+                               sendlen = RDL_CHUNK;
+
+                       /* simply avoid having to send a ZLP by ensuring we
+                        * never have an even
+                        * multiple of 64
+                        */
+                       if (!(sendlen % 64))
+                               sendlen -= 4;
+
+                       /* send data */
+                       memcpy(bulkchunk, dlpos, sendlen);
+                       if (brcmf_usb_dl_send_bulk(devinfo, bulkchunk,
+                                                  sendlen)) {
+                               brcmf_dbg(ERROR, "send_bulk failed\n");
+                               err = -EINVAL;
+                               goto fail;
+                       }
+
+                       dlpos += sendlen;
+                       sent += sendlen;
+               }
+               if (!brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
+                                     sizeof(struct rdl_state_le))) {
+                       brcmf_dbg(ERROR, "DL_GETSTATE Failed xxxx\n");
+                       err = -EINVAL;
+                       goto fail;
+               }
+
+               rdlstate = le32_to_cpu(state.state);
+               rdlbytes = le32_to_cpu(state.bytes);
+
+               /* restart if an error is reported */
+               if (rdlstate == DL_BAD_HDR || rdlstate == DL_BAD_CRC) {
+                       brcmf_dbg(ERROR, "Bad Hdr or Bad CRC state %d\n",
+                                 rdlstate);
+                       err = -EINVAL;
+                       goto fail;
+               }
+       }
+
+fail:
+       kfree(bulkchunk);
+       brcmf_dbg(TRACE, "err=%d\n", err);
+       return err;
+}
+
+static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len)
+{
+       int err;
+
+       brcmf_dbg(TRACE, "enter\n");
+
+       if (devinfo == NULL)
+               return -EINVAL;
+
+       if (devinfo->bus_pub.devid == 0xDEAD)
+               return -EINVAL;
+
+       err = brcmf_usb_dl_writeimage(devinfo, fw, len);
+       if (err == 0)
+               devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE;
+       else
+               devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING;
+       brcmf_dbg(TRACE, "exit: err=%d\n", err);
+
+       return err;
+}
+
+static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
+{
+       struct rdl_state_le state;
+
+       brcmf_dbg(TRACE, "enter\n");
+       if (!devinfo)
+               return -EINVAL;
+
+       if (devinfo->bus_pub.devid == 0xDEAD)
+               return -EINVAL;
+
+       /* Check we are runnable */
+       brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
+               sizeof(struct rdl_state_le));
+
+       /* Start the image */
+       if (state.state == cpu_to_le32(DL_RUNNABLE)) {
+               if (!brcmf_usb_dl_cmd(devinfo, DL_GO, &state,
+                       sizeof(struct rdl_state_le)))
+                       return -ENODEV;
+               if (brcmf_usb_resetcfg(devinfo))
+                       return -ENODEV;
+               /* The Dongle may go for re-enumeration. */
+       } else {
+               brcmf_dbg(ERROR, "Dongle not runnable\n");
+               return -EINVAL;
+       }
+       brcmf_dbg(TRACE, "exit\n");
+       return 0;
+}
+
+static bool brcmf_usb_chip_support(int chipid, int chiprev)
+{
+       switch(chipid) {
+       case 43235:
+       case 43236:
+       case 43238:
+               return (chiprev == 3);
+       default:
+               break;
+       }
+       return false;
+}
+
+static int
+brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
+{
+       int devid, chiprev;
+       int err;
+
+       brcmf_dbg(TRACE, "enter\n");
+       if (devinfo == NULL)
+               return -ENODEV;
+
+       devid = devinfo->bus_pub.devid;
+       chiprev = devinfo->bus_pub.chiprev;
+
+       if (!brcmf_usb_chip_support(devid, chiprev)) {
+               brcmf_dbg(ERROR, "unsupported chip %d rev %d\n",
+                         devid, chiprev);
+               return -EINVAL;
+       }
+
+       if (!devinfo->image) {
+               brcmf_dbg(ERROR, "No firmware!\n");
+               return -ENOENT;
+       }
+
+       err = brcmf_usb_dlstart(devinfo,
+               devinfo->image, devinfo->image_len);
+       if (err == 0)
+               err = brcmf_usb_dlrun(devinfo);
+       return err;
+}
+
+
+static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub)
+{
+       struct brcmf_usbdev_info *devinfo =
+               (struct brcmf_usbdev_info *)bus_pub;
+
+       brcmf_dbg(TRACE, "devinfo %p\n", devinfo);
+
+       /* store the image globally */
+       g_image.data = devinfo->image;
+       g_image.len = devinfo->image_len;
+
+       /* free the URBS */
+       brcmf_usb_free_q(&devinfo->rx_freeq, false);
+       brcmf_usb_free_q(&devinfo->tx_freeq, false);
+
+       usb_free_urb(devinfo->intr_urb);
+       usb_free_urb(devinfo->ctl_urb);
+       usb_free_urb(devinfo->bulk_urb);
+
+       kfree(devinfo->tx_reqs);
+       kfree(devinfo->rx_reqs);
+       kfree(devinfo);
+}
+
+#define TRX_MAGIC       0x30524448      /* "HDR0" */
+#define TRX_VERSION     1               /* Version 1 */
+#define TRX_MAX_LEN     0x3B0000        /* Max length */
+#define TRX_NO_HEADER   1               /* Do not write TRX header */
+#define TRX_MAX_OFFSET  3               /* Max number of individual files */
+#define TRX_UNCOMP_IMAGE        0x20    /* Trx contains uncompressed image */
+
+struct trx_header_le {
+       __le32 magic;           /* "HDR0" */
+       __le32 len;             /* Length of file including header */
+       __le32 crc32;           /* CRC from flag_version to end of file */
+       __le32 flag_version;    /* 0:15 flags, 16:31 version */
+       __le32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of
+                                        * header */
+};
+
+static int check_file(const u8 *headers)
+{
+       struct trx_header_le *trx;
+       int actual_len = -1;
+
+       /* Extract trx header */
+       trx = (struct trx_header_le *) headers;
+       if (trx->magic != cpu_to_le32(TRX_MAGIC))
+               return -1;
+
+       headers += sizeof(struct trx_header_le);
+
+       if (le32_to_cpu(trx->flag_version) & TRX_UNCOMP_IMAGE) {
+               actual_len = le32_to_cpu(trx->offsets[TRX_OFFSETS_DLFWLEN_IDX]);
+               return actual_len + sizeof(struct trx_header_le);
+       }
+       return -1;
+}
+
+static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
+{
+       s8 *fwname;
+       const struct firmware *fw;
+       int err;
+
+       devinfo->image = g_image.data;
+       devinfo->image_len = g_image.len;
+
+       /*
+        * if we have an image we can leave here.
+        */
+       if (devinfo->image)
+               return 0;
+
+       fwname = BRCMF_USB_43236_FW_NAME;
+
+       err = request_firmware(&fw, fwname, devinfo->dev);
+       if (!fw) {
+               brcmf_dbg(ERROR, "fail to request firmware %s\n", fwname);
+               return err;
+       }
+       if (check_file(fw->data) < 0) {
+               brcmf_dbg(ERROR, "invalid firmware %s\n", fwname);
+               return -EINVAL;
+       }
+
+       devinfo->image = kmalloc(fw->size, GFP_ATOMIC); /* plus nvram */
+       if (!devinfo->image)
+               return -ENOMEM;
+
+       memcpy(devinfo->image, fw->data, fw->size);
+       devinfo->image_len = fw->size;
+
+       release_firmware(fw);
+       return 0;
+}
+
+
+static
+struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
+{
+       struct brcmf_usbdev_info *devinfo;
+
+       devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC);
+       if (devinfo == NULL)
+               return NULL;
+
+       devinfo->bus_pub.nrxq = nrxq;
+       devinfo->rx_low_watermark = nrxq / 2;
+       devinfo->bus_pub.devinfo = devinfo;
+       devinfo->bus_pub.ntxq = ntxq;
+
+       /* flow control when too many tx urbs posted */
+       devinfo->tx_low_watermark = ntxq / 4;
+       devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3;
+       devinfo->dev = dev;
+       devinfo->usbdev = usbdev_probe_info.usb;
+       devinfo->tx_pipe = usbdev_probe_info.tx_pipe;
+       devinfo->rx_pipe = usbdev_probe_info.rx_pipe;
+       devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2;
+       devinfo->intr_pipe = usbdev_probe_info.intr_pipe;
+
+       devinfo->interval = usbdev_probe_info.interval;
+       devinfo->intr_size = usbdev_probe_info.intr_size;
+
+       memcpy(&devinfo->probe_info, &usbdev_probe_info,
+               sizeof(struct brcmf_usb_probe_info));
+       devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE;
+
+       /* Initialize other structure content */
+       init_waitqueue_head(&devinfo->ioctl_resp_wait);
+
+       /* Initialize the spinlocks */
+       spin_lock_init(&devinfo->qlock);
+
+       INIT_LIST_HEAD(&devinfo->rx_freeq);
+       INIT_LIST_HEAD(&devinfo->rx_postq);
+
+       INIT_LIST_HEAD(&devinfo->tx_freeq);
+       INIT_LIST_HEAD(&devinfo->tx_postq);
+
+       devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq);
+       if (!devinfo->rx_reqs)
+               goto error;
+
+       devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq);
+       if (!devinfo->tx_reqs)
+               goto error;
+
+       devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!devinfo->intr_urb) {
+               brcmf_dbg(ERROR, "usb_alloc_urb (intr) failed\n");
+               goto error;
+       }
+       devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!devinfo->ctl_urb) {
+               brcmf_dbg(ERROR, "usb_alloc_urb (ctl) failed\n");
+               goto error;
+       }
+       devinfo->rxctl_deferrespok = 0;
+
+       devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!devinfo->bulk_urb) {
+               brcmf_dbg(ERROR, "usb_alloc_urb (bulk) failed\n");
+               goto error;
+       }
+
+       init_waitqueue_head(&devinfo->wait);
+       if (!brcmf_usb_dlneeded(devinfo))
+               return &devinfo->bus_pub;
+
+       brcmf_dbg(TRACE, "start fw downloading\n");
+       if (brcmf_usb_get_fw(devinfo))
+               goto error;
+
+       if (brcmf_usb_fw_download(devinfo))
+               goto error;
+
+       return &devinfo->bus_pub;
+
+error:
+       brcmf_dbg(ERROR, "failed!\n");
+       brcmf_usb_detach(&devinfo->bus_pub);
+       return NULL;
+}
+
+static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
+                               u32 bustype, u32 hdrlen)
+{
+       struct brcmf_bus *bus = NULL;
+       struct brcmf_usbdev *bus_pub = NULL;
+       int ret;
+
+
+       bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev);
+       if (!bus_pub) {
+               ret = -ENODEV;
+               goto fail;
+       }
+
+       bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
+       if (!bus) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       bus_pub->bus = bus;
+       bus->brcmf_bus_txdata = brcmf_usb_tx;
+       bus->brcmf_bus_init = brcmf_usb_up;
+       bus->brcmf_bus_stop = brcmf_usb_down;
+       bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt;
+       bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt;
+       bus->type = bustype;
+       bus->bus_priv.usb = bus_pub;
+       dev_set_drvdata(dev, bus);
+
+       /* Attach to the common driver interface */
+       ret = brcmf_attach(hdrlen, dev);
+       if (ret) {
+               brcmf_dbg(ERROR, "dhd_attach failed\n");
+               goto fail;
+       }
+
+       ret = brcmf_bus_start(dev);
+       if (ret == -ENOLINK) {
+               brcmf_dbg(ERROR, "dongle is not responding\n");
+               brcmf_detach(dev);
+               goto fail;
+       }
+
+       /* add interface and open for business */
+       ret = brcmf_add_if(dev, 0, "wlan%d", NULL);
+       if (ret) {
+               brcmf_dbg(ERROR, "Add primary net device interface failed!!\n");
+               brcmf_detach(dev);
+               goto fail;
+       }
+
+       return 0;
+fail:
+       /* Release resources in reverse order */
+       if (bus_pub)
+               brcmf_usb_detach(bus_pub);
+       kfree(bus);
+       return ret;
+}
+
+static void
+brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub)
+{
+       if (!bus_pub)
+               return;
+       brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub);
+
+       brcmf_detach(bus_pub->devinfo->dev);
+       kfree(bus_pub->bus);
+       brcmf_usb_detach(bus_pub);
+
+}
+
+static int
+brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+       int ep;
+       struct usb_endpoint_descriptor *endpoint;
+       int ret = 0;
+       struct usb_device *usb = interface_to_usbdev(intf);
+       int num_of_eps;
+       u8 endpoint_num;
+
+       brcmf_dbg(TRACE, "enter\n");
+
+       usbdev_probe_info.usb = usb;
+       usbdev_probe_info.intf = intf;
+
+       if (id != NULL) {
+               usbdev_probe_info.vid = id->idVendor;
+               usbdev_probe_info.pid = id->idProduct;
+       }
+
+       usb_set_intfdata(intf, &usbdev_probe_info);
+
+       /* Check that the device supports only one configuration */
+       if (usb->descriptor.bNumConfigurations != 1) {
+               ret = -1;
+               goto fail;
+       }
+
+       if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
+               ret = -1;
+               goto fail;
+       }
+
+       /*
+        * Only the BDC interface configuration is supported:
+        *      Device class: USB_CLASS_VENDOR_SPEC
+        *      if0 class: USB_CLASS_VENDOR_SPEC
+        *      if0/ep0: control
+        *      if0/ep1: bulk in
+        *      if0/ep2: bulk out (ok if swapped with bulk in)
+        */
+       if (CONFIGDESC(usb)->bNumInterfaces != 1) {
+               ret = -1;
+               goto fail;
+       }
+
+       /* Check interface */
+       if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
+           IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 ||
+           IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff) {
+               brcmf_dbg(ERROR, "invalid control interface: class %d, subclass %d, proto %d\n",
+                         IFDESC(usb, CONTROL_IF).bInterfaceClass,
+                         IFDESC(usb, CONTROL_IF).bInterfaceSubClass,
+                         IFDESC(usb, CONTROL_IF).bInterfaceProtocol);
+               ret = -1;
+               goto fail;
+       }
+
+       /* Check control endpoint */
+       endpoint = &IFEPDESC(usb, CONTROL_IF, 0);
+       if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+               != USB_ENDPOINT_XFER_INT) {
+               brcmf_dbg(ERROR, "invalid control endpoint %d\n",
+                         endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+               ret = -1;
+               goto fail;
+       }
+
+       endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+       usbdev_probe_info.intr_pipe = usb_rcvintpipe(usb, endpoint_num);
+
+       usbdev_probe_info.rx_pipe = 0;
+       usbdev_probe_info.rx_pipe2 = 0;
+       usbdev_probe_info.tx_pipe = 0;
+       num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
+
+       /* Check data endpoints and get pipes */
+       for (ep = 1; ep <= num_of_eps; ep++) {
+               endpoint = &IFEPDESC(usb, BULK_IF, ep);
+               if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
+                   USB_ENDPOINT_XFER_BULK) {
+                       brcmf_dbg(ERROR, "invalid data endpoint %d\n", ep);
+                       ret = -1;
+                       goto fail;
+               }
+
+               endpoint_num = endpoint->bEndpointAddress &
+                              USB_ENDPOINT_NUMBER_MASK;
+               if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+                       == USB_DIR_IN) {
+                       if (!usbdev_probe_info.rx_pipe) {
+                               usbdev_probe_info.rx_pipe =
+                                       usb_rcvbulkpipe(usb, endpoint_num);
+                       } else {
+                               usbdev_probe_info.rx_pipe2 =
+                                       usb_rcvbulkpipe(usb, endpoint_num);
+                       }
+               } else {
+                       usbdev_probe_info.tx_pipe =
+                                       usb_sndbulkpipe(usb, endpoint_num);
+               }
+       }
+
+       /* Allocate interrupt URB and data buffer */
+       /* RNDIS says 8-byte intr, our old drivers used 4-byte */
+       if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
+               usbdev_probe_info.intr_size = 8;
+       else
+               usbdev_probe_info.intr_size = 4;
+
+       usbdev_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
+
+       usbdev_probe_info.device_speed = usb->speed;
+       if (usb->speed == USB_SPEED_HIGH)
+               brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n");
+       else
+               brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n");
+
+       ret = brcmf_usb_probe_cb(&usb->dev, "", USB_BUS, 0);
+       if (ret)
+               goto fail;
+
+       /* Success */
+       return 0;
+
+fail:
+       brcmf_dbg(ERROR, "failed with errno %d\n", ret);
+       usb_set_intfdata(intf, NULL);
+       return ret;
+
+}
+
+static void
+brcmf_usb_disconnect(struct usb_interface *intf)
+{
+       struct usb_device *usb = interface_to_usbdev(intf);
+
+       brcmf_dbg(TRACE, "enter\n");
+       brcmf_usb_disconnect_cb(brcmf_usb_get_buspub(&usb->dev));
+       usb_set_intfdata(intf, NULL);
+}
+
+/*
+ *     only need to signal the bus being down and update the suspend state.
+ */
+static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
+{
+       struct usb_device *usb = interface_to_usbdev(intf);
+       struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
+
+       brcmf_dbg(TRACE, "enter\n");
+       devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN;
+       devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED;
+       return 0;
+}
+
+/*
+ *     mark suspend state active and crank up the bus.
+ */
+static int brcmf_usb_resume(struct usb_interface *intf)
+{
+       struct usb_device *usb = interface_to_usbdev(intf);
+       struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
+
+       brcmf_dbg(TRACE, "enter\n");
+       devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
+       brcmf_bus_start(&usb->dev);
+       return 0;
+}
+
+#define BRCMF_USB_VENDOR_ID_BROADCOM   0x0a5c
+#define BRCMF_USB_DEVICE_ID_43236      0xbd17
+#define BRCMF_USB_DEVICE_ID_BCMFW      0x0bdc
+
+static struct usb_device_id brcmf_usb_devid_table[] = {
+       { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) },
+       /* special entry for device with firmware loaded and running */
+       { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
+MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
+
+/* TODO: suspend and resume entries */
+static struct usb_driver brcmf_usbdrvr = {
+       .name = KBUILD_MODNAME,
+       .probe = brcmf_usb_probe,
+       .disconnect = brcmf_usb_disconnect,
+       .id_table = brcmf_usb_devid_table,
+       .suspend = brcmf_usb_suspend,
+       .resume = brcmf_usb_resume,
+       .supports_autosuspend = 1
+};
+
+void brcmf_usb_exit(void)
+{
+       usb_deregister(&brcmf_usbdrvr);
+       kfree(g_image.data);
+       g_image.data = NULL;
+       g_image.len = 0;
+}
+
+void brcmf_usb_init(void)
+{
+       usb_register(&brcmf_usbdrvr);
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h
new file mode 100644 (file)
index 0000000..acfa5e8
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef BRCMFMAC_USB_H
+#define BRCMFMAC_USB_H
+
+enum brcmf_usb_state {
+       BCMFMAC_USB_STATE_DL_PENDING,
+       BCMFMAC_USB_STATE_DL_DONE,
+       BCMFMAC_USB_STATE_UP,
+       BCMFMAC_USB_STATE_DOWN,
+       BCMFMAC_USB_STATE_PNP_FWDL,
+       BCMFMAC_USB_STATE_DISCONNECT,
+       BCMFMAC_USB_STATE_SLEEP
+};
+
+enum brcmf_usb_pnp_state {
+       BCMFMAC_USB_PNP_DISCONNECT,
+       BCMFMAC_USB_PNP_SLEEP,
+       BCMFMAC_USB_PNP_RESUME,
+};
+
+struct brcmf_stats {
+       u32 tx_ctlpkts;
+       u32 tx_ctlerrs;
+       u32 rx_ctlpkts;
+       u32 rx_ctlerrs;
+};
+
+struct brcmf_usbdev {
+       struct brcmf_bus *bus;
+       struct brcmf_usbdev_info *devinfo;
+       enum brcmf_usb_state state;
+       struct brcmf_stats stats;
+       int ntxq, nrxq, rxsize;
+       u32 bus_mtu;
+       int devid;
+       int chiprev; /* chip revsion number */
+};
+
+/* IO Request Block (IRB) */
+struct brcmf_usbreq {
+       struct list_head list;
+       struct brcmf_usbdev_info *devinfo;
+       struct urb *urb;
+       struct sk_buff  *skb;
+};
+
+#endif /* BRCMFMAC_USB_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
new file mode 100644 (file)
index 0000000..0a35c51
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _USB_RDL_H
+#define _USB_RDL_H
+
+/* Control messages: bRequest values */
+#define DL_GETSTATE    0       /* returns the rdl_state_t struct */
+#define DL_CHECK_CRC   1       /* currently unused */
+#define DL_GO          2       /* execute downloaded image */
+#define DL_START       3       /* initialize dl state */
+#define DL_REBOOT      4       /* reboot the device in 2 seconds */
+#define DL_GETVER      5       /* returns the bootrom_id_t struct */
+#define DL_GO_PROTECTED        6       /* execute the downloaded code and set reset
+                                * event to occur in 2 seconds.  It is the
+                                * responsibility of the downloaded code to
+                                * clear this event
+                                */
+#define DL_EXEC                7       /* jump to a supplied address */
+#define DL_RESETCFG    8       /* To support single enum on dongle
+                                * - Not used by bootloader
+                                */
+#define DL_DEFER_RESP_OK 9     /* Potentially defer the response to setup
+                                * if resp unavailable
+                                */
+
+/* states */
+#define DL_WAITING     0       /* waiting to rx first pkt */
+#define DL_READY       1       /* hdr was good, waiting for more of the
+                                * compressed image */
+#define DL_BAD_HDR     2       /* hdr was corrupted */
+#define DL_BAD_CRC     3       /* compressed image was corrupted */
+#define DL_RUNNABLE    4       /* download was successful,waiting for go cmd */
+#define DL_START_FAIL  5       /* failed to initialize correctly */
+#define DL_NVRAM_TOOBIG        6       /* host specified nvram data exceeds DL_NVRAM
+                                * value */
+#define DL_IMAGE_TOOBIG        7       /* download image too big (exceeds DATA_START
+                                *  for rdl) */
+
+struct rdl_state_le {
+       __le32 state;
+       __le32 bytes;
+};
+
+struct bootrom_id_le {
+       __le32 chip;    /* Chip id */
+       __le32 chiprev; /* Chip rev */
+       __le32 ramsize; /* Size of  RAM */
+       __le32 remapbase;       /* Current remap base address */
+       __le32 boardtype;       /* Type of board */
+       __le32 boardrev;        /* Board revision */
+};
+
+#define RDL_CHUNK      1500  /* size of each dl transfer */
+
+#define TRX_OFFSETS_DLFWLEN_IDX        0
+#define TRX_OFFSETS_JUMPTO_IDX 1
+#define TRX_OFFSETS_NVM_LEN_IDX        2
+
+#define TRX_OFFSETS_DLBASE_IDX  0
+
+#endif  /* _USB_RDL_H */
index bf11850a20f11b1201179c7c7659a16397f2d4cc..15d7f00513be9e052f8b915782542c7b9f574ef9 100644 (file)
@@ -16,6 +16,8 @@
 
 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
 #include <linux/sched.h>
@@ -1374,7 +1376,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
        memset(&join_params, 0, sizeof(join_params));
        join_params_size = sizeof(join_params.ssid_le);
 
-       ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), sme->ssid_len);
+       ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
        memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
        memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
        join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
@@ -2783,7 +2785,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
            wiphy_new(&wl_cfg80211_ops,
                      sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
        if (!wdev->wiphy) {
-               WL_ERR("Couldn not allocate wiphy device\n");
+               WL_ERR("Could not allocate wiphy device\n");
                err = -ENOMEM;
                goto wiphy_new_out;
        }
@@ -2809,7 +2811,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
                                                                 */
        err = wiphy_register(wdev->wiphy);
        if (err < 0) {
-               WL_ERR("Couldn not register wiphy device (%d)\n", err);
+               WL_ERR("Could not register wiphy device (%d)\n", err);
                goto wiphy_register_out;
        }
        return wdev;
@@ -3295,7 +3297,9 @@ static struct brcmf_cfg80211_event_q *brcmf_deq_event(
 }
 
 /*
-** push event to tail of the queue
+*      push event to tail of the queue
+*
+*      remark: this function may not sleep as it is called in atomic context.
 */
 
 static s32
@@ -3304,17 +3308,18 @@ brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
 {
        struct brcmf_cfg80211_event_q *e;
        s32 err = 0;
+       ulong flags;
 
-       e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
+       e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
        if (!e)
                return -ENOMEM;
 
        e->etype = event;
        memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
 
-       spin_lock_irq(&cfg_priv->evt_q_lock);
+       spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
        list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
-       spin_unlock_irq(&cfg_priv->evt_q_lock);
+       spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
 
        return err;
 }
index a613b49cb13f543e66363f5749ac09473a64b4b5..b5d9b36df3d0556bb54a34efbeabc5512b10057b 100644 (file)
@@ -32,63 +32,63 @@ struct brcmf_cfg80211_ibss;
 #define WL_DBG_MASK            ((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
                                (WL_DBG_SCAN) | (WL_DBG_CONN))
 
-#define        WL_ERR(fmt, args...)                                    \
+#define        WL_ERR(fmt, ...)                                        \
 do {                                                           \
        if (brcmf_dbg_level & WL_DBG_ERR) {                     \
                if (net_ratelimit()) {                          \
-                       printk(KERN_ERR "ERROR @%s : " fmt,     \
-                               __func__, ##args);              \
+                       pr_err("ERROR @%s : " fmt,              \
+                              __func__, ##__VA_ARGS__);        \
                }                                               \
        }                                                       \
 } while (0)
 
-#if (defined BCMDBG)
-#define        WL_INFO(fmt, args...)                                   \
+#if (defined DEBUG)
+#define        WL_INFO(fmt, ...)                                       \
 do {                                                           \
        if (brcmf_dbg_level & WL_DBG_INFO) {                    \
                if (net_ratelimit()) {                          \
-                       printk(KERN_ERR "INFO @%s : " fmt,      \
-                               __func__, ##args);              \
+                       pr_err("INFO @%s : " fmt,               \
+                              __func__, ##__VA_ARGS__);        \
                }                                               \
        }                                                       \
 } while (0)
 
-#define        WL_TRACE(fmt, args...)                                  \
+#define        WL_TRACE(fmt, ...)                                      \
 do {                                                           \
        if (brcmf_dbg_level & WL_DBG_TRACE) {                   \
                if (net_ratelimit()) {                          \
-                       printk(KERN_ERR "TRACE @%s : " fmt,     \
-                               __func__, ##args);              \
+                       pr_err("TRACE @%s : " fmt,              \
+                              __func__, ##__VA_ARGS__);        \
                }                                               \
        }                                                       \
 } while (0)
 
-#define        WL_SCAN(fmt, args...)                                   \
+#define        WL_SCAN(fmt, ...)                                       \
 do {                                                           \
        if (brcmf_dbg_level & WL_DBG_SCAN) {                    \
                if (net_ratelimit()) {                          \
-                       printk(KERN_ERR "SCAN @%s : " fmt,      \
-                               __func__, ##args);              \
+                       pr_err("SCAN @%s : " fmt,               \
+                              __func__, ##__VA_ARGS__);        \
                }                                               \
        }                                                       \
 } while (0)
 
-#define        WL_CONN(fmt, args...)                                   \
+#define        WL_CONN(fmt, ...)                                       \
 do {                                                           \
        if (brcmf_dbg_level & WL_DBG_CONN) {                    \
                if (net_ratelimit()) {                          \
-                       printk(KERN_ERR "CONN @%s : " fmt,      \
-                               __func__, ##args);              \
+                       pr_err("CONN @%s : " fmt,               \
+                              __func__, ##__VA_ARGS__);        \
                }                                               \
        }                                                       \
 } while (0)
 
-#else /* (defined BCMDBG) */
+#else /* (defined DEBUG) */
 #define        WL_INFO(fmt, args...)
 #define        WL_TRACE(fmt, args...)
 #define        WL_SCAN(fmt, args...)
 #define        WL_CONN(fmt, args...)
-#endif /* (defined BCMDBG) */
+#endif /* (defined DEBUG) */
 
 #define WL_NUM_SCAN_MAX                1
 #define WL_NUM_PMKIDS_MAX      MAXPMKID        /* will be used
index ab9bb11abfbb2b26f0bf3a440030a26734099887..c93ea35bceecc2e19157a81981ba183ad5b59b6d 100644 (file)
 
 #define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID))
 
-#ifdef BCMDBG
+#ifdef DEBUG
 #define        SI_MSG(fmt, ...)        pr_debug(fmt, ##__VA_ARGS__)
 #else
 #define        SI_MSG(fmt, ...)        no_printk(fmt, ##__VA_ARGS__)
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
 #define        GOODCOREADDR(x, b) \
        (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
index 90911eec0cf55948fddecffb225eb1543412cc6a..95b5902bc4b3a3241f68cde20434b8592ba71ebc 100644 (file)
@@ -915,7 +915,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
        struct wiphy *wiphy = wlc->wiphy;
 
-#ifdef BCMDBG
+#ifdef DEBUG
        u8 hole[AMPDU_MAX_MPDU];
        memset(hole, 0, sizeof(hole));
 #endif
@@ -959,14 +959,13 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
                if (supr_status) {
                        update_rate = false;
                        if (supr_status == TX_STATUS_SUPR_BADCH) {
-                               wiphy_err(wiphy, "%s: Pkt tx suppressed, "
-                                         "illegal channel possibly %d\n",
+                               wiphy_err(wiphy,
+                                         "%s: Pkt tx suppressed, illegal channel possibly %d\n",
                                          __func__, CHSPEC_CHANNEL(
                                          wlc->default_bss->chanspec));
                        } else {
                                if (supr_status != TX_STATUS_SUPR_FRAG)
-                                       wiphy_err(wiphy, "%s:"
-                                                 "supr_status 0x%x\n",
+                                       wiphy_err(wiphy, "%s: supr_status 0x%x\n",
                                                  __func__, supr_status);
                        }
                        /* no need to retry for badch; will fail again */
@@ -988,9 +987,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
                        }
                } else if (txs->phyerr) {
                        update_rate = false;
-                       wiphy_err(wiphy, "wl%d: ampdu tx phy "
-                                 "error (0x%x)\n", wlc->pub->unit,
-                                 txs->phyerr);
+                       wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
+                                 __func__, txs->phyerr);
 
                        if (brcm_msg_level & LOG_ERROR_VAL) {
                                brcmu_prpkt("txpkt (AMPDU)", p);
@@ -1018,10 +1016,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
                ack_recd = false;
                if (ba_recd) {
                        bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
-                       BCMMSG(wlc->wiphy, "tid %d seq %d,"
-                               " start_seq %d, bindex %d set %d, index %d\n",
-                               tid, seq, start_seq, bindex,
-                               isset(bitmap, bindex), index);
+                       BCMMSG(wiphy,
+                              "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
+                              tid, seq, start_seq, bindex,
+                              isset(bitmap, bindex), index);
                        /* if acked then clear bit and free packet */
                        if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
                            && isset(bitmap, bindex)) {
@@ -1051,17 +1049,13 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
                }
                /* either retransmit or send bar if ack not recd */
                if (!ack_recd) {
-                       struct ieee80211_tx_rate *txrate =
-                           tx_info->status.rates;
-                       if (retry && (txrate[0].count < (int)retry_limit)) {
+                       if (retry && (ini->txretry[index] < (int)retry_limit)) {
                                ini->txretry[index]++;
                                ini->tx_in_transit--;
                                /*
                                 * Use high prededence for retransmit to
                                 * give some punch
                                 */
-                               /* brcms_c_txq_enq(wlc, scb, p,
-                                * BRCMS_PRIO_TO_PREC(tid)); */
                                brcms_c_txq_enq(wlc, scb, p,
                                                BRCMS_PRIO_TO_HI_PREC(tid));
                        } else {
@@ -1074,9 +1068,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
                                    IEEE80211_TX_STAT_AMPDU_NO_BACK;
                                skb_pull(p, D11_PHY_HDR_LEN);
                                skb_pull(p, D11_TXH_LEN);
-                               wiphy_err(wiphy, "%s: BA Timeout, seq %d, in_"
-                                       "transit %d\n", "AMPDU status", seq,
-                                       ini->tx_in_transit);
+                               BCMMSG(wiphy,
+                                      "BA Timeout, seq %d, in_transit %d\n",
+                                      seq, ini->tx_in_transit);
                                ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
                                                            p);
                        }
index 2e90a9a16ed6885e4792c56953efb701c8b8ee8e..11054ae9d4f6e6993ab5483140a1c367f8c670e2 100644 (file)
 #define BCMEXTRAHDROOM 172
 
 /* debug/trace */
-#ifdef BCMDBG
+#ifdef DEBUG
 #define        DMA_ERROR(fmt, ...)                                     \
 do {                                                           \
        if (*di->msg_level & 1)                                 \
@@ -193,7 +193,7 @@ do {                                                                \
        no_printk(fmt, ##__VA_ARGS__)
 #define        DMA_TRACE(fmt, ...)                     \
        no_printk(fmt, ##__VA_ARGS__)
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
 #define        DMA_NONE(fmt, ...)                      \
        no_printk(fmt, ##__VA_ARGS__)
@@ -968,7 +968,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
                        pktcnt++;
                }
 
-#ifdef BCMDBG
+#ifdef DEBUG
                if (resid > 0) {
                        uint cur;
                        cur =
@@ -979,7 +979,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
                        DMA_ERROR("rxin %d rxout %d, hw_curr %d\n",
                                   di->rxin, di->rxout, cur);
                }
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
                if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
                        DMA_ERROR("%s: bad frame length (%d)\n",
index 448ab9c4eb47b00db5ff558db6a4ab978a4f4f77..569ab8abd2a1c2d132eb1fbe273d09f077d68c3e 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #define __UNDEF_NO_VERSION__
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
@@ -96,10 +97,10 @@ static struct bcma_device_id brcms_coreid_table[] = {
 };
 MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
 
-#ifdef BCMDBG
+#ifdef DEBUG
 static int msglevel = 0xdeadbeef;
 module_param(msglevel, int, 0);
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
 static struct ieee80211_channel brcms_2ghz_chantable[] = {
        CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
@@ -857,7 +858,7 @@ static void brcms_free(struct brcms_info *wl)
        /* free timers */
        for (t = wl->timers; t; t = next) {
                next = t->next;
-#ifdef BCMDBG
+#ifdef DEBUG
                kfree(t->name);
 #endif
                kfree(t);
@@ -1121,8 +1122,7 @@ static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
 
        wl = brcms_attach(pdev);
        if (!wl) {
-               pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME,
-                      __func__);
+               pr_err("%s: brcms_attach failed!\n", __func__);
                return -ENODEV;
        }
        return 0;
@@ -1136,8 +1136,8 @@ static int brcms_suspend(struct bcma_device *pdev)
        hw = bcma_get_drvdata(pdev);
        wl = hw->priv;
        if (!wl) {
-               wiphy_err(wl->wiphy,
-                         "brcms_suspend: bcma_get_drvdata failed\n");
+               pr_err("%s: %s: no driver private struct!\n", KBUILD_MODNAME,
+                      __func__);
                return -ENODEV;
        }
 
@@ -1169,25 +1169,31 @@ static struct bcma_driver brcms_bcma_driver = {
 /**
  * This is the main entry point for the brcmsmac driver.
  *
- * This function determines if a device pointed to by pdev is a WL device,
- * and if so, performs a brcms_attach() on it.
- *
+ * This function is scheduled upon module initialization and
+ * does the driver registration, which result in brcms_bcma_probe()
+ * call resulting in the driver bringup.
  */
-static int __init brcms_module_init(void)
+static void brcms_driver_init(struct work_struct *work)
 {
-       int error = -ENODEV;
+       int error;
+
+       error = bcma_driver_register(&brcms_bcma_driver);
+       if (error)
+               pr_err("%s: register returned %d\n", __func__, error);
+}
 
-#ifdef BCMDBG
+static DECLARE_WORK(brcms_driver_work, brcms_driver_init);
+
+static int __init brcms_module_init(void)
+{
+#ifdef DEBUG
        if (msglevel != 0xdeadbeef)
                brcm_msg_level = msglevel;
-#endif                         /* BCMDBG */
-
-       error = bcma_driver_register(&brcms_bcma_driver);
-       printk(KERN_ERR "%s: register returned %d\n", __func__, error);
-       if (!error)
-               return 0;
+#endif
+       if (!schedule_work(&brcms_driver_work))
+               return -EBUSY;
 
-       return error;
+       return 0;
 }
 
 /**
@@ -1199,6 +1205,7 @@ static int __init brcms_module_init(void)
  */
 static void __exit brcms_module_exit(void)
 {
+       cancel_work_sync(&brcms_driver_work);
        bcma_driver_unregister(&brcms_bcma_driver);
 }
 
@@ -1367,7 +1374,7 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
        t->next = wl->timers;
        wl->timers = t;
 
-#ifdef BCMDBG
+#ifdef DEBUG
        t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
        if (t->name)
                strcpy(t->name, name);
@@ -1386,7 +1393,7 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
 {
        struct ieee80211_hw *hw = t->wl->pub->ieee_hw;
 
-#ifdef BCMDBG
+#ifdef DEBUG
        if (t->set)
                wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
                          __func__, t->name, periodic);
@@ -1431,7 +1438,7 @@ void brcms_free_timer(struct brcms_timer *t)
 
        if (wl->timers == t) {
                wl->timers = wl->timers->next;
-#ifdef BCMDBG
+#ifdef DEBUG
                kfree(t->name);
 #endif
                kfree(t);
@@ -1443,7 +1450,7 @@ void brcms_free_timer(struct brcms_timer *t)
        while (tmp) {
                if (tmp->next == t) {
                        tmp->next = t->next;
-#ifdef BCMDBG
+#ifdef DEBUG
                        kfree(t->name);
 #endif
                        kfree(t);
index 8f60419c37bf1e0d5d0c15062c8a1103b8248b61..9358bd5ebd35d016058d1238d11aca6880fdae19 100644 (file)
@@ -40,7 +40,7 @@ struct brcms_timer {
        bool periodic;
        bool set;               /* indicates if timer is active */
        struct brcms_timer *next;       /* for freeing on unload */
-#ifdef BCMDBG
+#ifdef DEBUG
        char *name;             /* Description of the timer */
 #endif
 };
index f6affc6fd12a511831d07d7333ea0b45f0bb8d5f..86186fa82946d31c7b559256e28402c52a9e6ddc 100644 (file)
@@ -14,6 +14,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci_ids.h>
 #include <linux/if_ether.h>
 #include <net/mac80211.h>
@@ -293,11 +295,11 @@ const u8 prio2fifo[NUMPRIO] = {
 
 /* debug/trace */
 uint brcm_msg_level =
-#if defined(BCMDBG)
+#if defined(DEBUG)
        LOG_ERROR_VAL;
 #else
        0;
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
 /* TX FIFO number to WME/802.1E Access Category */
 static const u8 wme_fifo2ac[] = {
@@ -342,14 +344,14 @@ static const u16 xmtfifo_sz[][NFIFO] = {
        {9, 58, 22, 14, 14, 5},
 };
 
-#ifdef BCMDBG
+#ifdef DEBUG
 static const char * const fifo_names[] = {
        "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
 #else
 static const char fifo_names[6][0];
 #endif
 
-#ifdef BCMDBG
+#ifdef DEBUG
 /* pointer to most recently allocated wl/wlc */
 static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
 #endif
@@ -2899,7 +2901,6 @@ brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
                objoff += 2;
 
        return bcma_read16(core, objoff);
-;
 }
 
 static void
@@ -3075,30 +3076,30 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc)
 {
        int i;
        struct macstat macstats;
-#ifdef BCMDBG
+#ifdef DEBUG
        u16 delta;
        u16 rxf0ovfl;
        u16 txfunfl[NFIFO];
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
        /* if driver down, make no sense to update stats */
        if (!wlc->pub->up)
                return;
 
-#ifdef BCMDBG
+#ifdef DEBUG
        /* save last rx fifo 0 overflow count */
        rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
 
        /* save last tx fifo  underflow count */
        for (i = 0; i < NFIFO; i++)
                txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
        /* Read mac stats from contiguous shared memory */
        brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats,
                                sizeof(struct macstat), OBJADDR_SHM_SEL);
 
-#ifdef BCMDBG
+#ifdef DEBUG
        /* check for rx fifo 0 overflow */
        delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
        if (delta)
@@ -3114,7 +3115,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc)
                        wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
                                  "\n", wlc->pub->unit, delta, i);
        }
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
 
        /* merge counters from dma module */
        for (i = 0; i < NFIFO; i++) {
@@ -5765,62 +5766,49 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
        return -ENODATA;
 }
 
-#ifdef BCMDBG
-static const char * const supr_reason[] = {
-       "None", "PMQ Entry", "Flush request",
-       "Previous frag failure", "Channel mismatch",
-       "Lifetime Expiry", "Underflow"
-};
-
-static void brcms_c_print_txs_status(u16 s)
-{
-       printk(KERN_DEBUG "[15:12]  %d  frame attempts\n",
-              (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT);
-       printk(KERN_DEBUG " [11:8]  %d  rts attempts\n",
-              (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT);
-       printk(KERN_DEBUG "    [7]  %d  PM mode indicated\n",
-              ((s & TX_STATUS_PMINDCTD) ? 1 : 0));
-       printk(KERN_DEBUG "    [6]  %d  intermediate status\n",
-              ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0));
-       printk(KERN_DEBUG "    [5]  %d  AMPDU\n",
-              (s & TX_STATUS_AMPDU) ? 1 : 0);
-       printk(KERN_DEBUG "  [4:2]  %d  Frame Suppressed Reason (%s)\n",
-              ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT),
-              supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]);
-       printk(KERN_DEBUG "    [1]  %d  acked\n",
-              ((s & TX_STATUS_ACK_RCV) ? 1 : 0));
-}
-#endif                         /* BCMDBG */
-
 void brcms_c_print_txstatus(struct tx_status *txs)
 {
-#if defined(BCMDBG)
-       u16 s = txs->status;
-       u16 ackphyrxsh = txs->ackphyrxsh;
-
-       printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n");
-
-       printk(KERN_DEBUG "FrameID: %04x   ", txs->frameid);
-       printk(KERN_DEBUG "TxStatus: %04x", s);
-       printk(KERN_DEBUG "\n");
-
-       brcms_c_print_txs_status(s);
-
-       printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime);
-       printk(KERN_DEBUG "Seq: %04x ", txs->sequence);
-       printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr);
-       printk(KERN_DEBUG "RxAckRSSI: %04x ",
-              (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT);
-       printk(KERN_DEBUG "RxAckSQ: %04x",
-              (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
-       printk(KERN_DEBUG "\n");
-#endif                         /* defined(BCMDBG) */
+       pr_debug("\ntxpkt (MPDU) Complete\n");
+
+       pr_debug("FrameID: %04x   TxStatus: %04x\n", txs->frameid, txs->status);
+
+       pr_debug("[15:12]  %d  frame attempts\n",
+                 (txs->status & TX_STATUS_FRM_RTX_MASK) >>
+                TX_STATUS_FRM_RTX_SHIFT);
+       pr_debug(" [11:8]  %d  rts attempts\n",
+                (txs->status & TX_STATUS_RTS_RTX_MASK) >>
+                TX_STATUS_RTS_RTX_SHIFT);
+       pr_debug("    [7]  %d  PM mode indicated\n",
+                txs->status & TX_STATUS_PMINDCTD ? 1 : 0);
+       pr_debug("    [6]  %d  intermediate status\n",
+                txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0);
+       pr_debug("    [5]  %d  AMPDU\n",
+                txs->status & TX_STATUS_AMPDU ? 1 : 0);
+       pr_debug("  [4:2]  %d  Frame Suppressed Reason (%s)\n",
+                (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT,
+                (const char *[]) {
+                       "None",
+                       "PMQ Entry",
+                       "Flush request",
+                       "Previous frag failure",
+                       "Channel mismatch",
+                       "Lifetime Expiry",
+                       "Underflow"
+                } [(txs->status & TX_STATUS_SUPR_MASK) >>
+                   TX_STATUS_SUPR_SHIFT]);
+       pr_debug("    [1]  %d  acked\n",
+                txs->status & TX_STATUS_ACK_RCV ? 1 : 0);
+
+       pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n",
+                txs->lasttxtime, txs->sequence, txs->phyerr,
+                (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT,
+                (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
 }
 
 bool brcms_c_chipmatch(u16 vendor, u16 device)
 {
        if (vendor != PCI_VENDOR_ID_BROADCOM) {
-               pr_err("chipmatch: unknown vendor id %04x\n", vendor);
+               pr_err("unknown vendor id %04x\n", vendor);
                return false;
        }
 
@@ -5833,11 +5821,11 @@ bool brcms_c_chipmatch(u16 vendor, u16 device)
        if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
                return true;
 
-       pr_err("chipmatch: unknown device id %04x\n", device);
+       pr_err("unknown device id %04x\n", device);
        return false;
 }
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 void brcms_c_print_txdesc(struct d11txh *txh)
 {
        u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
@@ -5871,57 +5859,56 @@ void brcms_c_print_txdesc(struct d11txh *txh)
        struct ieee80211_rts rts = txh->rts_frame;
 
        /* add plcp header along with txh descriptor */
-       printk(KERN_DEBUG "Raw TxDesc + plcp header:\n");
-       print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-                            txh, sizeof(struct d11txh) + 48);
-
-       printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl);
-       printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch);
-       printk(KERN_DEBUG "FC: %04x ", mfc);
-       printk(KERN_DEBUG "FES Time: %04x\n", tfest);
-       printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw,
+       brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48,
+                          "Raw TxDesc + plcp header:\n");
+
+       pr_debug("TxCtlLow: %04x ", mtcl);
+       pr_debug("TxCtlHigh: %04x ", mtch);
+       pr_debug("FC: %04x ", mfc);
+       pr_debug("FES Time: %04x\n", tfest);
+       pr_debug("PhyCtl: %04x%s ", ptcw,
               (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
-       printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1);
-       printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
-       printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
-       printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
-       printk(KERN_DEBUG "MainRates: %04x ", mainrates);
-       printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft);
-       printk(KERN_DEBUG "\n");
+       pr_debug("PhyCtl_1: %04x ", ptcw_1);
+       pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
+       pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
+       pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
+       pr_debug("MainRates: %04x ", mainrates);
+       pr_debug("XtraFrameTypes: %04x ", xtraft);
+       pr_debug("\n");
 
        print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV));
        print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET,
                             ra, sizeof(txh->TxFrameRA));
 
-       printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb);
+       pr_debug("Fb FES Time: %04x ", tfestfb);
        print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET,
                             rtspfb, sizeof(txh->RTSPLCPFallback));
-       printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb);
+       pr_debug("RTS DUR: %04x ", rtsdfb);
        print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET,
                             fragpfb, sizeof(txh->FragPLCPFallback));
-       printk(KERN_DEBUG "DUR: %04x", fragdfb);
-       printk(KERN_DEBUG "\n");
+       pr_debug("DUR: %04x", fragdfb);
+       pr_debug("\n");
 
-       printk(KERN_DEBUG "MModeLen: %04x ", mmodelen);
-       printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen);
+       pr_debug("MModeLen: %04x ", mmodelen);
+       pr_debug("MModeFbrLen: %04x\n", mmodefbrlen);
 
-       printk(KERN_DEBUG "FrameID:     %04x\n", tfid);
-       printk(KERN_DEBUG "TxStatus:    %04x\n", txs);
+       pr_debug("FrameID:     %04x\n", tfid);
+       pr_debug("TxStatus:    %04x\n", txs);
 
-       printk(KERN_DEBUG "MaxNumMpdu:  %04x\n", mnmpdu);
-       printk(KERN_DEBUG "MaxAggbyte:  %04x\n", mabyte);
-       printk(KERN_DEBUG "MaxAggbyte_fb:  %04x\n", mabyte_f);
-       printk(KERN_DEBUG "MinByte:     %04x\n", mmbyte);
+       pr_debug("MaxNumMpdu:  %04x\n", mnmpdu);
+       pr_debug("MaxAggbyte:  %04x\n", mabyte);
+       pr_debug("MaxAggbyte_fb:  %04x\n", mabyte_f);
+       pr_debug("MinByte:     %04x\n", mmbyte);
 
        print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET,
                             rtsph, sizeof(txh->RTSPhyHeader));
        print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET,
                             (u8 *)&rts, sizeof(txh->rts_frame));
-       printk(KERN_DEBUG "\n");
+       pr_debug("\n");
 }
-#endif                         /* defined(BCMDBG) */
+#endif                         /* defined(DEBUG) */
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 static int
 brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
                     int len)
@@ -5975,9 +5962,9 @@ brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
 
        return (int)(p - buf);
 }
-#endif                         /* defined(BCMDBG) */
+#endif                         /* defined(DEBUG) */
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 void brcms_c_print_rxh(struct d11rxhdr *rxh)
 {
        u16 len = rxh->RxFrameSize;
@@ -5999,24 +5986,22 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh)
                {0, NULL}
        };
 
-       printk(KERN_DEBUG "Raw RxDesc:\n");
-       print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh,
-                            sizeof(struct d11rxhdr));
+       brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n");
 
        brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64);
 
        snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
 
-       printk(KERN_DEBUG "RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
+       pr_debug("RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
               (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
-       printk(KERN_DEBUG "RxPHYStatus:     %04x %04x %04x %04x\n",
+       pr_debug("RxPHYStatus:     %04x %04x %04x %04x\n",
               phystatus_0, phystatus_1, phystatus_2, phystatus_3);
-       printk(KERN_DEBUG "RxMACStatus:     %x %s\n", macstatus1, flagstr);
-       printk(KERN_DEBUG "RXMACaggtype:    %x\n",
+       pr_debug("RxMACStatus:     %x %s\n", macstatus1, flagstr);
+       pr_debug("RXMACaggtype:    %x\n",
               (macstatus2 & RXS_AGGTYPE_MASK));
-       printk(KERN_DEBUG "RxTSFTime:       %04x\n", rxh->RxTSFTime);
+       pr_debug("RxTSFTime:       %04x\n", rxh->RxTSFTime);
 }
-#endif                         /* defined(BCMDBG) */
+#endif                         /* defined(DEBUG) */
 
 u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
 {
@@ -8354,7 +8339,7 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
        wlc->wiphy = wl->wiphy;
        pub = wlc->pub;
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
        wlc_info_dbg = wlc;
 #endif
 
index adb136ec1f04b0db413bac1f02f915c0222db36a..8debc74c54e1a63b5d9be1eae54e3c52d33375ba 100644 (file)
@@ -648,10 +648,12 @@ extern void brcms_c_print_txstatus(struct tx_status *txs);
 extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
                   uint *blocks);
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 extern void brcms_c_print_txdesc(struct d11txh *txh);
 #else
-#define brcms_c_print_txdesc(a)
+static inline void brcms_c_print_txdesc(struct d11txh *txh)
+{
+}
 #endif
 
 extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
index a16f1ab292fdb2c87e1d3c5c1a1ada25df897769..9595ecd38c1f1d4d14807f03a0dbf0e5a4fab39e 100644 (file)
@@ -14,6 +14,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/cordic.h>
@@ -17822,8 +17824,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
        if (pi->sh->sromrev < 4) {
                idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
                idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
-               target_pwr_qtrdbm[0] = 13 * 4;
-               target_pwr_qtrdbm[1] = 13 * 4;
                a1[0] = -424;
                a1[1] = -424;
                b0[0] = 5612;
@@ -17837,10 +17837,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
                case WL_CHAN_FREQ_RANGE_2G:
                        idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
                        idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
-                       target_pwr_qtrdbm[0] =
-                               pi->nphy_pwrctrl_info[0].max_pwr_2g;
-                       target_pwr_qtrdbm[1] =
-                               pi->nphy_pwrctrl_info[1].max_pwr_2g;
                        a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1;
                        a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
                        b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0;
@@ -17851,10 +17847,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
                case WL_CHAN_FREQ_RANGE_5GL:
                        idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
                        idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
-                       target_pwr_qtrdbm[0] =
-                               pi->nphy_pwrctrl_info[0].max_pwr_5gl;
-                       target_pwr_qtrdbm[1] =
-                               pi->nphy_pwrctrl_info[1].max_pwr_5gl;
                        a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1;
                        a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
                        b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0;
@@ -17865,10 +17857,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
                case WL_CHAN_FREQ_RANGE_5GM:
                        idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
                        idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
-                       target_pwr_qtrdbm[0] =
-                               pi->nphy_pwrctrl_info[0].max_pwr_5gm;
-                       target_pwr_qtrdbm[1] =
-                               pi->nphy_pwrctrl_info[1].max_pwr_5gm;
                        a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1;
                        a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
                        b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0;
@@ -17879,10 +17867,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
                case WL_CHAN_FREQ_RANGE_5GH:
                        idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
                        idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
-                       target_pwr_qtrdbm[0] =
-                               pi->nphy_pwrctrl_info[0].max_pwr_5gh;
-                       target_pwr_qtrdbm[1] =
-                               pi->nphy_pwrctrl_info[1].max_pwr_5gh;
                        a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1;
                        a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
                        b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0;
@@ -17893,8 +17877,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
                default:
                        idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
                        idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
-                       target_pwr_qtrdbm[0] = 13 * 4;
-                       target_pwr_qtrdbm[1] = 13 * 4;
                        a1[0] = -424;
                        a1[1] = -424;
                        b0[0] = 5612;
@@ -17905,6 +17887,7 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
                }
        }
 
+       /* use the provided transmit power */
        target_pwr_qtrdbm[0] = (s8) pi->tx_power_max;
        target_pwr_qtrdbm[1] = (s8) pi->tx_power_max;
 
@@ -19987,12 +19970,11 @@ static void wlc_phy_radio_init_2057(struct brcms_phy *pi)
                switch (pi->pubpi.radiorev) {
                case 5:
 
-                       if (pi->pubpi.radiover == 0x0)
+                       if (NREV_IS(pi->pubpi.phy_rev, 8))
                                regs_2057_ptr = regs_2057_rev5;
-                       else if (pi->pubpi.radiover == 0x1)
+                       else if (NREV_IS(pi->pubpi.phy_rev, 9))
                                regs_2057_ptr = regs_2057_rev5v1;
-                       else
-                               break;
+                       break;
 
                case 7:
 
@@ -26434,8 +26416,7 @@ cal_try:
        }
 
        if (bcmerror != 0) {
-               printk(KERN_DEBUG "%s: Failed, cnt = %d\n", __func__,
-                      cal_retry);
+               pr_debug("%s: Failed, cnt = %d\n", __func__, cal_retry);
 
                if (cal_retry < CAL_RETRY_CNT) {
                        cal_retry++;
index 5637436430381a12d6322fbac9e9be1ec27de276..b96f4b9d74bdb2af5bab3403323fab243a8db0d7 100644 (file)
@@ -621,7 +621,7 @@ static inline void cpu_to_le16_buf(u16 *buf, uint nwords)
 /*
  * convert binary srom data into linked list of srom variable items.
  */
-static void
+static int
 _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
 {
        struct brcms_srom_list_head *entry;
@@ -638,6 +638,9 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
 
        /* first store the srom revision */
        entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL);
+       if (!entry)
+               return -ENOMEM;
+
        entry->varid = BRCMS_SROM_REV;
        entry->var_type = BRCMS_SROM_UNUMBER;
        entry->uval = sromrev;
@@ -715,6 +718,8 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
 
                entry = kzalloc(sizeof(struct brcms_srom_list_head) +
                                extra_space, GFP_KERNEL);
+               if (!entry)
+                       return -ENOMEM;
                entry->varid = id;
                entry->var_type = type;
                if (flags & SRFL_ETHADDR) {
@@ -754,6 +759,8 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
                        entry =
                            kzalloc(sizeof(struct brcms_srom_list_head),
                                    GFP_KERNEL);
+                       if (!entry)
+                               return -ENOMEM;
                        entry->varid = srv->varid+p;
                        entry->var_type = BRCMS_SROM_UNUMBER;
                        entry->uval = val;
@@ -761,6 +768,7 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
                }
                pb += psz;
        }
+       return 0;
 }
 
 /*
@@ -906,7 +914,9 @@ int srom_var_init(struct si_pub *sih)
                INIT_LIST_HEAD(&sii->var_list);
 
                /* parse SROM into name=value pairs. */
-               _initvars_srom_pci(sromrev, srom, &sii->var_list);
+               err = _initvars_srom_pci(sromrev, srom, &sii->var_list);
+               if (err)
+                       srom_free_vars(sih);
        }
 
 errout:
index b7537f70a79538fab66fd48183179c4b78a2f78a..b45ab34cdfdc0693676fae614359b2bafaa5c526 100644 (file)
@@ -14,6 +14,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/netdevice.h>
 #include <linux/module.h>
 
@@ -240,17 +242,35 @@ struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
 }
 EXPORT_SYMBOL(brcmu_pktq_mdeq);
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 /* pretty hex print a pkt buffer chain */
 void brcmu_prpkt(const char *msg, struct sk_buff *p0)
 {
        struct sk_buff *p;
 
        if (msg && (msg[0] != '\0'))
-               printk(KERN_DEBUG "%s:\n", msg);
+               pr_debug("%s:\n", msg);
 
        for (p = p0; p; p = p->next)
                print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
 }
 EXPORT_SYMBOL(brcmu_prpkt);
-#endif                         /* defined(BCMDBG) */
+
+void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
+{
+       struct va_format vaf;
+       va_list args;
+
+       va_start(args, fmt);
+
+       vaf.fmt = fmt;
+       vaf.va = &args;
+
+       pr_debug("%pV", &vaf);
+
+       va_end(args);
+
+       print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, size);
+}
+EXPORT_SYMBOL(brcmu_dbg_hex_dump);
+#endif                         /* defined(DEBUG) */
index ad249a0b4730ebea6eec5cd2f2bdfbb355fe232a..477b92ad3d62c37b9ec99b3e7b48b0b60f388311 100644 (file)
@@ -176,10 +176,21 @@ struct ipv4_addr;
 
 /* externs */
 /* format/print */
-#ifdef BCMDBG
+#ifdef DEBUG
 extern void brcmu_prpkt(const char *msg, struct sk_buff *p0);
 #else
 #define brcmu_prpkt(a, b)
-#endif                         /* BCMDBG */
+#endif                         /* DEBUG */
+
+#ifdef DEBUG
+extern __printf(3, 4)
+void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...);
+#else
+__printf(3, 4)
+static inline
+void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
+{
+}
+#endif
 
 #endif                         /* _BRCMU_UTILS_H_ */
index a0e5c21d36576c74c1c402984a7392869926bdea..ddf340f914da3b4a61118d60ee0f7c3519bd99af 100644 (file)
@@ -298,8 +298,6 @@ static const char *command_types[] = {
 };
 #endif
 
-#define WEXT_USECHANNELS 1
-
 static const long ipw2100_frequencies[] = {
        2412, 2417, 2422, 2427,
        2432, 2437, 2442, 2447,
@@ -309,13 +307,6 @@ static const long ipw2100_frequencies[] = {
 
 #define FREQ_COUNT     ARRAY_SIZE(ipw2100_frequencies)
 
-static const long ipw2100_rates_11b[] = {
-       1000000,
-       2000000,
-       5500000,
-       11000000
-};
-
 static struct ieee80211_rate ipw2100_bg_rates[] = {
        { .bitrate = 10 },
        { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
@@ -323,7 +314,7 @@ static struct ieee80211_rate ipw2100_bg_rates[] = {
        { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 };
 
-#define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b)
+#define RATE_COUNT ARRAY_SIZE(ipw2100_bg_rates)
 
 /* Pre-decl until we get the code solid and then we can clean it up */
 static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
@@ -6896,7 +6887,7 @@ static int ipw2100_wx_get_range(struct net_device *dev,
        range->num_bitrates = RATE_COUNT;
 
        for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
-               range->bitrate[i] = ipw2100_rates_11b[i];
+               range->bitrate[i] = ipw2100_bg_rates[i].bitrate * 100 * 1000;
        }
 
        range->min_rts = MIN_RTS_THRESHOLD;
@@ -8108,61 +8099,41 @@ static int ipw2100_wx_get_crc_check(struct net_device *dev,
 #endif                         /* CONFIG_IPW2100_MONITOR */
 
 static iw_handler ipw2100_wx_handlers[] = {
-       NULL,                   /* SIOCSIWCOMMIT */
-       ipw2100_wx_get_name,    /* SIOCGIWNAME */
-       NULL,                   /* SIOCSIWNWID */
-       NULL,                   /* SIOCGIWNWID */
-       ipw2100_wx_set_freq,    /* SIOCSIWFREQ */
-       ipw2100_wx_get_freq,    /* SIOCGIWFREQ */
-       ipw2100_wx_set_mode,    /* SIOCSIWMODE */
-       ipw2100_wx_get_mode,    /* SIOCGIWMODE */
-       NULL,                   /* SIOCSIWSENS */
-       NULL,                   /* SIOCGIWSENS */
-       NULL,                   /* SIOCSIWRANGE */
-       ipw2100_wx_get_range,   /* SIOCGIWRANGE */
-       NULL,                   /* SIOCSIWPRIV */
-       NULL,                   /* SIOCGIWPRIV */
-       NULL,                   /* SIOCSIWSTATS */
-       NULL,                   /* SIOCGIWSTATS */
-       NULL,                   /* SIOCSIWSPY */
-       NULL,                   /* SIOCGIWSPY */
-       NULL,                   /* SIOCGIWTHRSPY */
-       NULL,                   /* SIOCWIWTHRSPY */
-       ipw2100_wx_set_wap,     /* SIOCSIWAP */
-       ipw2100_wx_get_wap,     /* SIOCGIWAP */
-       ipw2100_wx_set_mlme,    /* SIOCSIWMLME */
-       NULL,                   /* SIOCGIWAPLIST -- deprecated */
-       ipw2100_wx_set_scan,    /* SIOCSIWSCAN */
-       ipw2100_wx_get_scan,    /* SIOCGIWSCAN */
-       ipw2100_wx_set_essid,   /* SIOCSIWESSID */
-       ipw2100_wx_get_essid,   /* SIOCGIWESSID */
-       ipw2100_wx_set_nick,    /* SIOCSIWNICKN */
-       ipw2100_wx_get_nick,    /* SIOCGIWNICKN */
-       NULL,                   /* -- hole -- */
-       NULL,                   /* -- hole -- */
-       ipw2100_wx_set_rate,    /* SIOCSIWRATE */
-       ipw2100_wx_get_rate,    /* SIOCGIWRATE */
-       ipw2100_wx_set_rts,     /* SIOCSIWRTS */
-       ipw2100_wx_get_rts,     /* SIOCGIWRTS */
-       ipw2100_wx_set_frag,    /* SIOCSIWFRAG */
-       ipw2100_wx_get_frag,    /* SIOCGIWFRAG */
-       ipw2100_wx_set_txpow,   /* SIOCSIWTXPOW */
-       ipw2100_wx_get_txpow,   /* SIOCGIWTXPOW */
-       ipw2100_wx_set_retry,   /* SIOCSIWRETRY */
-       ipw2100_wx_get_retry,   /* SIOCGIWRETRY */
-       ipw2100_wx_set_encode,  /* SIOCSIWENCODE */
-       ipw2100_wx_get_encode,  /* SIOCGIWENCODE */
-       ipw2100_wx_set_power,   /* SIOCSIWPOWER */
-       ipw2100_wx_get_power,   /* SIOCGIWPOWER */
-       NULL,                   /* -- hole -- */
-       NULL,                   /* -- hole -- */
-       ipw2100_wx_set_genie,   /* SIOCSIWGENIE */
-       ipw2100_wx_get_genie,   /* SIOCGIWGENIE */
-       ipw2100_wx_set_auth,    /* SIOCSIWAUTH */
-       ipw2100_wx_get_auth,    /* SIOCGIWAUTH */
-       ipw2100_wx_set_encodeext,       /* SIOCSIWENCODEEXT */
-       ipw2100_wx_get_encodeext,       /* SIOCGIWENCODEEXT */
-       NULL,                   /* SIOCSIWPMKSA */
+       IW_HANDLER(SIOCGIWNAME, ipw2100_wx_get_name),
+       IW_HANDLER(SIOCSIWFREQ, ipw2100_wx_set_freq),
+       IW_HANDLER(SIOCGIWFREQ, ipw2100_wx_get_freq),
+       IW_HANDLER(SIOCSIWMODE, ipw2100_wx_set_mode),
+       IW_HANDLER(SIOCGIWMODE, ipw2100_wx_get_mode),
+       IW_HANDLER(SIOCGIWRANGE, ipw2100_wx_get_range),
+       IW_HANDLER(SIOCSIWAP, ipw2100_wx_set_wap),
+       IW_HANDLER(SIOCGIWAP, ipw2100_wx_get_wap),
+       IW_HANDLER(SIOCSIWMLME, ipw2100_wx_set_mlme),
+       IW_HANDLER(SIOCSIWSCAN, ipw2100_wx_set_scan),
+       IW_HANDLER(SIOCGIWSCAN, ipw2100_wx_get_scan),
+       IW_HANDLER(SIOCSIWESSID, ipw2100_wx_set_essid),
+       IW_HANDLER(SIOCGIWESSID, ipw2100_wx_get_essid),
+       IW_HANDLER(SIOCSIWNICKN, ipw2100_wx_set_nick),
+       IW_HANDLER(SIOCGIWNICKN, ipw2100_wx_get_nick),
+       IW_HANDLER(SIOCSIWRATE, ipw2100_wx_set_rate),
+       IW_HANDLER(SIOCGIWRATE, ipw2100_wx_get_rate),
+       IW_HANDLER(SIOCSIWRTS, ipw2100_wx_set_rts),
+       IW_HANDLER(SIOCGIWRTS, ipw2100_wx_get_rts),
+       IW_HANDLER(SIOCSIWFRAG, ipw2100_wx_set_frag),
+       IW_HANDLER(SIOCGIWFRAG, ipw2100_wx_get_frag),
+       IW_HANDLER(SIOCSIWTXPOW, ipw2100_wx_set_txpow),
+       IW_HANDLER(SIOCGIWTXPOW, ipw2100_wx_get_txpow),
+       IW_HANDLER(SIOCSIWRETRY, ipw2100_wx_set_retry),
+       IW_HANDLER(SIOCGIWRETRY, ipw2100_wx_get_retry),
+       IW_HANDLER(SIOCSIWENCODE, ipw2100_wx_set_encode),
+       IW_HANDLER(SIOCGIWENCODE, ipw2100_wx_get_encode),
+       IW_HANDLER(SIOCSIWPOWER, ipw2100_wx_set_power),
+       IW_HANDLER(SIOCGIWPOWER, ipw2100_wx_get_power),
+       IW_HANDLER(SIOCSIWGENIE, ipw2100_wx_set_genie),
+       IW_HANDLER(SIOCGIWGENIE, ipw2100_wx_get_genie),
+       IW_HANDLER(SIOCSIWAUTH, ipw2100_wx_set_auth),
+       IW_HANDLER(SIOCGIWAUTH, ipw2100_wx_get_auth),
+       IW_HANDLER(SIOCSIWENCODEEXT, ipw2100_wx_set_encodeext),
+       IW_HANDLER(SIOCGIWENCODEEXT, ipw2100_wx_get_encodeext),
 };
 
 #define IPW2100_PRIV_SET_MONITOR       SIOCIWFIRSTPRIV
index ecb561d7a7a07016e8de302f8e21b0b800f573dd..66e84ec0eb55445ee16ff20dfe58038629343569 100644 (file)
@@ -27,8 +27,6 @@
 #ifndef __ipw2200_h__
 #define __ipw2200_h__
 
-#define WEXT_USECHANNELS 1
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
index 32a9966c3bf6ca05e182e3138f94b61e12388d5b..c4955d25a19a7a27602427c7d2b73a16639a903c 100644 (file)
@@ -172,7 +172,7 @@ libipw_rx_frame_mgmt(struct libipw_device *ieee, struct sk_buff *skb,
                        u16 stype)
 {
        if (ieee->iw_mode == IW_MODE_MASTER) {
-               printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
+               printk(KERN_DEBUG "%s: Master mode not yet supported.\n",
                       ieee->dev->name);
                return 0;
 /*
index 5e1a19fd354dcd4ffcb3629642996556d2d0c346..f767dd106b09e53d4de130e38b22d0e5490a84a8 100644 (file)
@@ -503,3 +503,9 @@ il3945_ucode_general_stats_read(struct file *file, char __user *user_buf,
        kfree(buf);
        return ret;
 }
+
+const struct il_debugfs_ops il3945_debugfs_ops = {
+       .rx_stats_read = il3945_ucode_rx_stats_read,
+       .tx_stats_read = il3945_ucode_tx_stats_read,
+       .general_stats_read = il3945_ucode_general_stats_read,
+};
index 54b2d391e91a942bbbbbe08e5ff65347a22328ac..0ccc934a35bb2846822f0ef6e9ce30e3962d1420 100644 (file)
@@ -140,7 +140,7 @@ il3945_set_ccmp_dynamic_key_info(struct il_priv *il,
        key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
        key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
 
-       if (sta_id == il->ctx.bcast_sta_id)
+       if (sta_id == il->hw_params.bcast_id)
                key_flags |= STA_KEY_MULTICAST_MSK;
 
        keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -341,7 +341,7 @@ il3945_send_beacon_cmd(struct il_priv *il)
                return -ENOMEM;
        }
 
-       rate = il_get_lowest_plcp(il, &il->ctx);
+       rate = il_get_lowest_plcp(il);
 
        frame_size = il3945_hw_get_beacon_cmd(il, frame, rate);
 
@@ -512,7 +512,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
        hdr_len = ieee80211_hdrlen(fc);
 
        /* Find idx into station table for destination station */
-       sta_id = il_sta_id_or_broadcast(il, &il->ctx, info->control.sta);
+       sta_id = il_sta_id_or_broadcast(il, info->control.sta);
        if (sta_id == IL_INVALID_STATION) {
                D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1);
                goto drop;
@@ -538,10 +538,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
        idx = il_get_cmd_idx(q, q->write_ptr, 0);
 
-       /* Set up driver data for this TFD */
-       memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info));
-       txq->txb[q->write_ptr].skb = skb;
-       txq->txb[q->write_ptr].ctx = &il->ctx;
+       txq->skbs[q->write_ptr] = skb;
 
        /* Init first empty entry in queue's array of Tx/cmd buffers */
        out_cmd = txq->cmd[idx];
@@ -576,7 +573,6 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
        len = (u16) skb->len;
        tx_cmd->len = cpu_to_le16(len);
 
-       il_dbg_log_tx_data_frame(il, len, hdr);
        il_update_stats(il, true, fc, len);
        tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
        tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
@@ -619,8 +615,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
        /* Add buffer containing Tx command and MAC(!) header to TFD's
         * first entry */
-       il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1,
-                                                0);
+       il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0);
 
        /* Set up TFD's 2nd entry to point directly to remainder of skb,
         * if any (802.11 null frames have no payload). */
@@ -629,8 +624,8 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
                phys_addr =
                    pci_map_single(il->pci_dev, skb->data + hdr_len, len,
                                   PCI_DMA_TODEVICE);
-               il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr,
-                                                        len, 0, U32_PAD(len));
+               il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0,
+                                              U32_PAD(len));
        }
 
        /* Tell device the write idx *just past* this latest filled TFD */
@@ -672,15 +667,13 @@ il3945_get_measurement(struct il_priv *il,
        int rc;
        int spectrum_resp_status;
        int duration = le16_to_cpu(params->duration);
-       struct il_rxon_context *ctx = &il->ctx;
 
        if (il_is_associated(il))
                add_time =
                    il_usecs_to_beacons(il,
                                        le64_to_cpu(params->start_time) -
                                        il->_3945.last_tsf,
-                                       le16_to_cpu(ctx->timing.
-                                                   beacon_interval));
+                                       le16_to_cpu(il->timing.beacon_interval));
 
        memset(&spectrum, 0, sizeof(spectrum));
 
@@ -694,15 +687,14 @@ il3945_get_measurement(struct il_priv *il,
        if (il_is_associated(il))
                spectrum.start_time =
                    il_add_beacon_time(il, il->_3945.last_beacon_time, add_time,
-                                      le16_to_cpu(ctx->timing.
-                                                  beacon_interval));
+                                      le16_to_cpu(il->timing.beacon_interval));
        else
                spectrum.start_time = 0;
 
        spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
        spectrum.channels[0].channel = params->channel;
        spectrum.channels[0].type = type;
-       if (ctx->active.flags & RXON_FLG_BAND_24G_MSK)
+       if (il->active.flags & RXON_FLG_BAND_24G_MSK)
                spectrum.flags |=
                    RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
                    RXON_FLG_TGG_PROTECT_MSK;
@@ -817,16 +809,16 @@ il3945_hdl_card_state(struct il_priv *il, struct il_rx_buf *rxb)
        _il_wr(il, CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
        if (flags & HW_CARD_DISABLED)
-               set_bit(S_RF_KILL_HW, &il->status);
+               set_bit(S_RFKILL, &il->status);
        else
-               clear_bit(S_RF_KILL_HW, &il->status);
+               clear_bit(S_RFKILL, &il->status);
 
        il_scan_cancel(il);
 
-       if ((test_bit(S_RF_KILL_HW, &status) !=
-            test_bit(S_RF_KILL_HW, &il->status)))
+       if ((test_bit(S_RFKILL, &status) !=
+            test_bit(S_RFKILL, &il->status)))
                wiphy_rfkill_set_hw_state(il->hw->wiphy,
-                                         test_bit(S_RF_KILL_HW, &il->status));
+                                         test_bit(S_RFKILL, &il->status));
        else
                wake_up(&il->wait_command_queue);
 }
@@ -2150,7 +2142,6 @@ il3945_alive_start(struct il_priv *il)
 {
        int thermal_spin = 0;
        u32 rfkill;
-       struct il_rxon_context *ctx = &il->ctx;
 
        D_INFO("Runtime Alive received.\n");
 
@@ -2175,7 +2166,7 @@ il3945_alive_start(struct il_priv *il)
        D_INFO("RFKILL status: 0x%x\n", rfkill);
 
        if (rfkill & 0x1) {
-               clear_bit(S_RF_KILL_HW, &il->status);
+               clear_bit(S_RFKILL, &il->status);
                /* if RFKILL is not on, then wait for thermal
                 * sensor in adapter to kick in */
                while (il3945_hw_get_temperature(il) == 0) {
@@ -2187,7 +2178,7 @@ il3945_alive_start(struct il_priv *il)
                        D_INFO("Thermal calibration took %dus\n",
                               thermal_spin * 10);
        } else
-               set_bit(S_RF_KILL_HW, &il->status);
+               set_bit(S_RFKILL, &il->status);
 
        /* After the ALIVE response, we can send commands to 3945 uCode */
        set_bit(S_ALIVE, &il->status);
@@ -2206,13 +2197,13 @@ il3945_alive_start(struct il_priv *il)
 
        if (il_is_associated(il)) {
                struct il3945_rxon_cmd *active_rxon =
-                   (struct il3945_rxon_cmd *)(&ctx->active);
+                   (struct il3945_rxon_cmd *)(&il->active);
 
-               ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+               il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        } else {
                /* Initialize our rx_config data */
-               il_connection_init_rx_config(il, ctx);
+               il_connection_init_rx_config(il);
        }
 
        /* Configure Bluetooth device coexistence support */
@@ -2221,7 +2212,7 @@ il3945_alive_start(struct il_priv *il)
        set_bit(S_READY, &il->status);
 
        /* Configure the adapter for unassociated operation */
-       il3945_commit_rxon(il, ctx);
+       il3945_commit_rxon(il);
 
        il3945_reg_txpower_periodic(il);
 
@@ -2253,7 +2244,7 @@ __il3945_down(struct il_priv *il)
        del_timer_sync(&il->watchdog);
 
        /* Station information will now be cleared in device */
-       il_clear_ucode_stations(il, NULL);
+       il_clear_ucode_stations(il);
        il_dealloc_bcast_stations(il);
        il_clear_driver_stations(il);
 
@@ -2281,12 +2272,8 @@ __il3945_down(struct il_priv *il)
         * clear all bits but the RF Kill bits and return */
        if (!il_is_init(il)) {
                il->status =
-                   test_bit(S_RF_KILL_HW,
-                            &il->
-                            status) << S_RF_KILL_HW |
-                   test_bit(S_GEO_CONFIGURED,
-                            &il->
-                            status) << S_GEO_CONFIGURED |
+                   test_bit(S_RFKILL, &il->status) << S_RFKILL |
+                   test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
                    test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
                goto exit;
        }
@@ -2294,25 +2281,30 @@ __il3945_down(struct il_priv *il)
        /* ...otherwise clear out all the status bits but the RF Kill
         * bit and continue taking the NIC down. */
        il->status &=
-           test_bit(S_RF_KILL_HW,
-                    &il->status) << S_RF_KILL_HW | test_bit(S_GEO_CONFIGURED,
-                                                            &il->
-                                                            status) <<
-           S_GEO_CONFIGURED | test_bit(S_FW_ERROR,
-                                       &il->
-                                       status) << S_FW_ERROR |
+           test_bit(S_RFKILL, &il->status) << S_RFKILL |
+           test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
+           test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
            test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
 
+       /*
+        * We disabled and synchronized interrupt, and priv->mutex is taken, so
+        * here is the only thread which will program device registers, but
+        * still have lockdep assertions, so we are taking reg_lock.
+        */
+       spin_lock_irq(&il->reg_lock);
+       /* FIXME: il_grab_nic_access if rfkill is off ? */
+
        il3945_hw_txq_ctx_stop(il);
        il3945_hw_rxq_stop(il);
-
        /* Power-down device's busmaster DMA clocks */
-       il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+       _il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
        udelay(5);
-
        /* Stop the device, and put it in low power state */
-       il_apm_stop(il);
+       _il_apm_stop(il);
+
+       spin_unlock_irq(&il->reg_lock);
 
+       il3945_hw_txq_ctx_free(il);
 exit:
        memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
 
@@ -2339,12 +2331,11 @@ il3945_down(struct il_priv *il)
 static int
 il3945_alloc_bcast_station(struct il_priv *il)
 {
-       struct il_rxon_context *ctx = &il->ctx;
        unsigned long flags;
        u8 sta_id;
 
        spin_lock_irqsave(&il->sta_lock, flags);
-       sta_id = il_prep_station(il, ctx, il_bcast_addr, false, NULL);
+       sta_id = il_prep_station(il, il_bcast_addr, false, NULL);
        if (sta_id == IL_INVALID_STATION) {
                IL_ERR("Unable to prepare broadcast station\n");
                spin_unlock_irqrestore(&il->sta_lock, flags);
@@ -2380,9 +2371,9 @@ __il3945_up(struct il_priv *il)
 
        /* If platform's RF_KILL switch is NOT set to KILL */
        if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-               clear_bit(S_RF_KILL_HW, &il->status);
+               clear_bit(S_RFKILL, &il->status);
        else {
-               set_bit(S_RF_KILL_HW, &il->status);
+               set_bit(S_RFKILL, &il->status);
                IL_WARN("Radio disabled by HW RF Kill switch\n");
                return -ENODEV;
        }
@@ -2414,7 +2405,7 @@ __il3945_up(struct il_priv *il)
               il->ucode_data.len);
 
        /* We return success when we resume from suspend and rf_kill is on. */
-       if (test_bit(S_RF_KILL_HW, &il->status))
+       if (test_bit(S_RFKILL, &il->status))
                return 0;
 
        for (i = 0; i < MAX_HW_RESTARTS; i++) {
@@ -2422,7 +2413,7 @@ __il3945_up(struct il_priv *il)
                /* load bootstrap state machine,
                 * load bootstrap program into processor's memory,
                 * prepare to load the "initialize" uCode */
-               rc = il->cfg->ops->lib->load_ucode(il);
+               rc = il->ops->load_ucode(il);
 
                if (rc) {
                        IL_ERR("Unable to set up bootstrap uCode: %d\n", rc);
@@ -2494,15 +2485,15 @@ il3945_rfkill_poll(struct work_struct *data)
 {
        struct il_priv *il =
            container_of(data, struct il_priv, _3945.rfkill_poll.work);
-       bool old_rfkill = test_bit(S_RF_KILL_HW, &il->status);
+       bool old_rfkill = test_bit(S_RFKILL, &il->status);
        bool new_rfkill =
            !(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
 
        if (new_rfkill != old_rfkill) {
                if (new_rfkill)
-                       set_bit(S_RF_KILL_HW, &il->status);
+                       set_bit(S_RFKILL, &il->status);
                else
-                       clear_bit(S_RF_KILL_HW, &il->status);
+                       clear_bit(S_RFKILL, &il->status);
 
                wiphy_rfkill_set_hw_state(il->hw->wiphy, new_rfkill);
 
@@ -2602,7 +2593,7 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
        /* We don't build a direct scan probe request; the uCode will do
         * that based on the direct_mask added to each channel entry */
        scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
-       scan->tx_cmd.sta_id = il->ctx.bcast_sta_id;
+       scan->tx_cmd.sta_id = il->hw_params.bcast_id;
        scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
        /* flags + rate selection */
@@ -2664,14 +2655,12 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
 void
 il3945_post_scan(struct il_priv *il)
 {
-       struct il_rxon_context *ctx = &il->ctx;
-
        /*
         * Since setting the RXON may have been deferred while
         * performing the scan, fire one off if needed
         */
-       if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
-               il3945_commit_rxon(il, ctx);
+       if (memcmp(&il->staging, &il->active, sizeof(il->staging)))
+               il3945_commit_rxon(il);
 }
 
 static void
@@ -2684,7 +2673,8 @@ il3945_bg_restart(struct work_struct *data)
 
        if (test_and_clear_bit(S_FW_ERROR, &il->status)) {
                mutex_lock(&il->mutex);
-               il->ctx.vif = NULL;
+               /* FIXME: vif can be dereferenced */
+               il->vif = NULL;
                il->is_open = 0;
                mutex_unlock(&il->mutex);
                il3945_down(il);
@@ -2722,13 +2712,12 @@ il3945_post_associate(struct il_priv *il)
 {
        int rc = 0;
        struct ieee80211_conf *conf = NULL;
-       struct il_rxon_context *ctx = &il->ctx;
 
-       if (!ctx->vif || !il->is_open)
+       if (!il->vif || !il->is_open)
                return;
 
-       D_ASSOC("Associated as %d to: %pM\n", ctx->vif->bss_conf.aid,
-               ctx->active.bssid_addr);
+       D_ASSOC("Associated as %d to: %pM\n", il->vif->bss_conf.aid,
+               il->active.bssid_addr);
 
        if (test_bit(S_EXIT_PENDING, &il->status))
                return;
@@ -2737,35 +2726,35 @@ il3945_post_associate(struct il_priv *il)
 
        conf = &il->hw->conf;
 
-       ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       il3945_commit_rxon(il, ctx);
+       il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+       il3945_commit_rxon(il);
 
-       rc = il_send_rxon_timing(il, ctx);
+       rc = il_send_rxon_timing(il);
        if (rc)
                IL_WARN("C_RXON_TIMING failed - " "Attempting to continue.\n");
 
-       ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+       il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
 
-       ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid);
+       il->staging.assoc_id = cpu_to_le16(il->vif->bss_conf.aid);
 
-       D_ASSOC("assoc id %d beacon interval %d\n", ctx->vif->bss_conf.aid,
-               ctx->vif->bss_conf.beacon_int);
+       D_ASSOC("assoc id %d beacon interval %d\n", il->vif->bss_conf.aid,
+               il->vif->bss_conf.beacon_int);
 
-       if (ctx->vif->bss_conf.use_short_preamble)
-               ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+       if (il->vif->bss_conf.use_short_preamble)
+               il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
        else
-               ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+               il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
 
-       if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
-               if (ctx->vif->bss_conf.use_short_slot)
-                       ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+       if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
+               if (il->vif->bss_conf.use_short_slot)
+                       il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
                else
-                       ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+                       il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
        }
 
-       il3945_commit_rxon(il, ctx);
+       il3945_commit_rxon(il);
 
-       switch (ctx->vif->type) {
+       switch (il->vif->type) {
        case NL80211_IFTYPE_STATION:
                il3945_rate_scale_init(il->hw, IL_AP_ID);
                break;
@@ -2774,7 +2763,7 @@ il3945_post_associate(struct il_priv *il)
                break;
        default:
                IL_ERR("%s Should not be called in %d mode\n", __func__,
-                      ctx->vif->type);
+                     il->vif->type);
                break;
        }
 }
@@ -2793,10 +2782,9 @@ il3945_mac_start(struct ieee80211_hw *hw)
        struct il_priv *il = hw->priv;
        int ret;
 
-       D_MAC80211("enter\n");
-
        /* we should be verifying the device is ready to be opened */
        mutex_lock(&il->mutex);
+       D_MAC80211("enter\n");
 
        /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
         * ucode filename and max sizes are card-specific. */
@@ -2891,8 +2879,7 @@ il3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 void
 il3945_config_ap(struct il_priv *il)
 {
-       struct il_rxon_context *ctx = &il->ctx;
-       struct ieee80211_vif *vif = ctx->vif;
+       struct ieee80211_vif *vif = il->vif;
        int rc = 0;
 
        if (test_bit(S_EXIT_PENDING, &il->status))
@@ -2902,31 +2889,31 @@ il3945_config_ap(struct il_priv *il)
        if (!(il_is_associated(il))) {
 
                /* RXON - unassoc (to set timing command) */
-               ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               il3945_commit_rxon(il, ctx);
+               il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+               il3945_commit_rxon(il);
 
                /* RXON Timing */
-               rc = il_send_rxon_timing(il, ctx);
+               rc = il_send_rxon_timing(il);
                if (rc)
                        IL_WARN("C_RXON_TIMING failed - "
                                "Attempting to continue.\n");
 
-               ctx->staging.assoc_id = 0;
+               il->staging.assoc_id = 0;
 
                if (vif->bss_conf.use_short_preamble)
-                       ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+                       il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
                else
-                       ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+                       il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
 
-               if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+               if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
                        if (vif->bss_conf.use_short_slot)
-                               ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+                               il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
                        else
-                               ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+                               il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
                }
                /* restore RXON assoc */
-               ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
-               il3945_commit_rxon(il, ctx);
+               il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+               il3945_commit_rxon(il);
        }
        il3945_send_beacon_cmd(il);
 }
@@ -2953,15 +2940,19 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
         * hardware will then not attempt to decrypt the frames.
         */
        if (vif->type == NL80211_IFTYPE_ADHOC &&
-           !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+           !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+               D_MAC80211("leave - IBSS RSN\n");
                return -EOPNOTSUPP;
+       }
 
        static_key = !il_is_associated(il);
 
        if (!static_key) {
-               sta_id = il_sta_id_or_broadcast(il, &il->ctx, sta);
-               if (sta_id == IL_INVALID_STATION)
+               sta_id = il_sta_id_or_broadcast(il, sta);
+               if (sta_id == IL_INVALID_STATION) {
+                       D_MAC80211("leave - station not found\n");
                        return -EINVAL;
+               }
        }
 
        mutex_lock(&il->mutex);
@@ -2986,8 +2977,8 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                ret = -EINVAL;
        }
 
+       D_MAC80211("leave ret %d\n", ret);
        mutex_unlock(&il->mutex);
-       D_MAC80211("leave\n");
 
        return ret;
 }
@@ -3002,13 +2993,11 @@ il3945_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        bool is_ap = vif->type == NL80211_IFTYPE_STATION;
        u8 sta_id;
 
-       D_INFO("received request to add station %pM\n", sta->addr);
        mutex_lock(&il->mutex);
-       D_INFO("proceeding to add station %pM\n", sta->addr);
+       D_INFO("station %pM\n", sta->addr);
        sta_priv->common.sta_id = IL_INVALID_STATION;
 
-       ret =
-           il_add_station_common(il, &il->ctx, sta->addr, is_ap, sta, &sta_id);
+       ret = il_add_station_common(il, sta->addr, is_ap, sta, &sta_id);
        if (ret) {
                IL_ERR("Unable to add station %pM (%d)\n", sta->addr, ret);
                /* Should we return success if return code is EEXIST ? */
@@ -3032,7 +3021,6 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 {
        struct il_priv *il = hw->priv;
        __le32 filter_or = 0, filter_nand = 0;
-       struct il_rxon_context *ctx = &il->ctx;
 
 #define CHK(test, flag)        do { \
        if (*total_flags & (test))              \
@@ -3052,8 +3040,8 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 
        mutex_lock(&il->mutex);
 
-       ctx->staging.filter_flags &= ~filter_nand;
-       ctx->staging.filter_flags |= filter_or;
+       il->staging.filter_flags &= ~filter_nand;
+       il->staging.filter_flags |= filter_or;
 
        /*
         * Not committing directly because hardware can perform a scan,
@@ -3112,11 +3100,9 @@ il3945_store_debug_level(struct device *d, struct device_attribute *attr,
        ret = strict_strtoul(buf, 0, &val);
        if (ret)
                IL_INFO("%s is not in hex or decimal form.\n", buf);
-       else {
+       else
                il->debug_level = val;
-               if (il_alloc_traffic_mem(il))
-                       IL_ERR("Not enough memory to generate traffic log\n");
-       }
+
        return strnlen(buf, count);
 }
 
@@ -3170,9 +3156,8 @@ static ssize_t
 il3945_show_flags(struct device *d, struct device_attribute *attr, char *buf)
 {
        struct il_priv *il = dev_get_drvdata(d);
-       struct il_rxon_context *ctx = &il->ctx;
 
-       return sprintf(buf, "0x%04X\n", ctx->active.flags);
+       return sprintf(buf, "0x%04X\n", il->active.flags);
 }
 
 static ssize_t
@@ -3181,17 +3166,16 @@ il3945_store_flags(struct device *d, struct device_attribute *attr,
 {
        struct il_priv *il = dev_get_drvdata(d);
        u32 flags = simple_strtoul(buf, NULL, 0);
-       struct il_rxon_context *ctx = &il->ctx;
 
        mutex_lock(&il->mutex);
-       if (le32_to_cpu(ctx->staging.flags) != flags) {
+       if (le32_to_cpu(il->staging.flags) != flags) {
                /* Cancel any currently running scans... */
                if (il_scan_cancel_timeout(il, 100))
                        IL_WARN("Could not cancel scan.\n");
                else {
                        D_INFO("Committing rxon.flags = 0x%04X\n", flags);
-                       ctx->staging.flags = cpu_to_le32(flags);
-                       il3945_commit_rxon(il, ctx);
+                       il->staging.flags = cpu_to_le32(flags);
+                       il3945_commit_rxon(il);
                }
        }
        mutex_unlock(&il->mutex);
@@ -3207,9 +3191,8 @@ il3945_show_filter_flags(struct device *d, struct device_attribute *attr,
                         char *buf)
 {
        struct il_priv *il = dev_get_drvdata(d);
-       struct il_rxon_context *ctx = &il->ctx;
 
-       return sprintf(buf, "0x%04X\n", le32_to_cpu(ctx->active.filter_flags));
+       return sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags));
 }
 
 static ssize_t
@@ -3217,19 +3200,18 @@ il3945_store_filter_flags(struct device *d, struct device_attribute *attr,
                          const char *buf, size_t count)
 {
        struct il_priv *il = dev_get_drvdata(d);
-       struct il_rxon_context *ctx = &il->ctx;
        u32 filter_flags = simple_strtoul(buf, NULL, 0);
 
        mutex_lock(&il->mutex);
-       if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) {
+       if (le32_to_cpu(il->staging.filter_flags) != filter_flags) {
                /* Cancel any currently running scans... */
                if (il_scan_cancel_timeout(il, 100))
                        IL_WARN("Could not cancel scan.\n");
                else {
                        D_INFO("Committing rxon.filter_flags = " "0x%04X\n",
                               filter_flags);
-                       ctx->staging.filter_flags = cpu_to_le32(filter_flags);
-                       il3945_commit_rxon(il, ctx);
+                       il->staging.filter_flags = cpu_to_le32(filter_flags);
+                       il3945_commit_rxon(il);
                }
        }
        mutex_unlock(&il->mutex);
@@ -3278,9 +3260,8 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr,
                         const char *buf, size_t count)
 {
        struct il_priv *il = dev_get_drvdata(d);
-       struct il_rxon_context *ctx = &il->ctx;
        struct ieee80211_measurement_params params = {
-               .channel = le16_to_cpu(ctx->active.channel),
+               .channel = le16_to_cpu(il->active.channel),
                .start_time = cpu_to_le64(il->_3945.last_tsf),
                .duration = cpu_to_le16(1),
        };
@@ -3474,7 +3455,7 @@ static struct attribute_group il3945_attribute_group = {
        .attrs = il3945_sysfs_entries,
 };
 
-struct ieee80211_ops il3945_hw_ops = {
+struct ieee80211_ops il3945_mac_ops = {
        .tx = il3945_mac_tx,
        .start = il3945_mac_start,
        .stop = il3945_mac_stop,
@@ -3567,7 +3548,8 @@ il3945_setup_mac(struct il_priv *il)
        /* Tell mac80211 our characteristics */
        hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT;
 
-       hw->wiphy->interface_modes = il->ctx.interface_modes;
+       hw->wiphy->interface_modes =
+           BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
 
        hw->wiphy->flags |=
            WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS |
@@ -3614,50 +3596,35 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * 1. Allocating HW data
         * ********************/
 
-       /* mac80211 allocates memory for this device instance, including
-        *   space for this driver's ilate structure */
-       hw = il_alloc_all(cfg);
-       if (hw == NULL) {
-               pr_err("Can not allocate network device\n");
+       hw = ieee80211_alloc_hw(sizeof(struct il_priv), &il3945_mac_ops);
+       if (!hw) {
                err = -ENOMEM;
                goto out;
        }
        il = hw->priv;
+       il->hw = hw;
        SET_IEEE80211_DEV(hw, &pdev->dev);
 
        il->cmd_queue = IL39_CMD_QUEUE_NUM;
 
-       il->ctx.ctxid = 0;
-
-       il->ctx.rxon_cmd = C_RXON;
-       il->ctx.rxon_timing_cmd = C_RXON_TIMING;
-       il->ctx.rxon_assoc_cmd = C_RXON_ASSOC;
-       il->ctx.qos_cmd = C_QOS_PARAM;
-       il->ctx.ap_sta_id = IL_AP_ID;
-       il->ctx.wep_key_cmd = C_WEPKEY;
-       il->ctx.interface_modes =
-           BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
-       il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS;
-       il->ctx.station_devtype = RXON_DEV_TYPE_ESS;
-       il->ctx.unused_devtype = RXON_DEV_TYPE_ESS;
-
        /*
         * Disabling hardware scan means that mac80211 will perform scans
         * "the hard way", rather than using device's scan.
         */
        if (il3945_mod_params.disable_hw_scan) {
                D_INFO("Disabling hw_scan\n");
-               il3945_hw_ops.hw_scan = NULL;
+               il3945_mac_ops.hw_scan = NULL;
        }
 
        D_INFO("*** LOAD DRIVER ***\n");
        il->cfg = cfg;
+       il->ops = &il3945_ops;
+#ifdef CONFIG_IWLEGACY_DEBUGFS
+       il->debugfs_ops = &il3945_debugfs_ops;
+#endif
        il->pci_dev = pdev;
        il->inta_mask = CSR_INI_SET_MASK;
 
-       if (il_alloc_traffic_mem(il))
-               IL_ERR("Not enough memory to generate traffic log\n");
-
        /***************************
         * 2. Initializing PCI bus
         * *************************/
@@ -3688,7 +3655,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        /***********************
         * 3. Read REV Register
         * ********************/
-       il->hw_base = pci_iomap(pdev, 0, 0);
+       il->hw_base = pci_ioremap_bar(pdev, 0);
        if (!il->hw_base) {
                err = -ENODEV;
                goto out_pci_release_regions;
@@ -3702,7 +3669,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * PCI Tx retries from interfering with C3 CPU state */
        pci_write_config_byte(pdev, 0x41, 0x00);
 
-       /* these spin locks will be used in apm_ops.init and EEPROM access
+       /* these spin locks will be used in apm_init and EEPROM access
         * we should init now
         */
        spin_lock_init(&il->reg_lock);
@@ -3773,8 +3740,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto out_release_irq;
        }
 
-       il_set_rxon_channel(il, &il->bands[IEEE80211_BAND_2GHZ].channels[5],
-                           &il->ctx);
+       il_set_rxon_channel(il, &il->bands[IEEE80211_BAND_2GHZ].channels[5]);
        il3945_setup_deferred_work(il);
        il3945_setup_handlers(il);
        il_power_initialize(il);
@@ -3814,14 +3780,13 @@ out_unset_hw_params:
 out_eeprom_free:
        il_eeprom_free(il);
 out_iounmap:
-       pci_iounmap(pdev, il->hw_base);
+       iounmap(il->hw_base);
 out_pci_release_regions:
        pci_release_regions(pdev);
 out_pci_disable_device:
        pci_set_drvdata(pdev, NULL);
        pci_disable_device(pdev);
 out_ieee80211_free_hw:
-       il_free_traffic_mem(il);
        ieee80211_free_hw(il->hw);
 out:
        return err;
@@ -3889,12 +3854,11 @@ il3945_pci_remove(struct pci_dev *pdev)
         * until now... */
        destroy_workqueue(il->workqueue);
        il->workqueue = NULL;
-       il_free_traffic_mem(il);
 
        free_irq(pdev->irq, il);
        pci_disable_msi(pdev);
 
-       pci_iounmap(pdev, il->hw_base);
+       iounmap(il->hw_base);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
index d7a83f229190b579aa5331809a4cd15505094915..70bee1a4d87679e57cafdb01fa22968ec823f20e 100644 (file)
@@ -342,7 +342,7 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)
        int i;
 
        D_INFO("enter\n");
-       if (sta_id == il->ctx.bcast_sta_id)
+       if (sta_id == il->hw_params.bcast_id)
                goto out;
 
        psta = (struct il3945_sta_priv *)sta->drv_priv;
@@ -927,8 +927,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 
        rcu_read_lock();
 
-       sta =
-           ieee80211_find_sta(il->ctx.vif, il->stations[sta_id].sta.sta.addr);
+       sta = ieee80211_find_sta(il->vif, il->stations[sta_id].sta.sta.addr);
        if (!sta) {
                D_RATE("Unable to find station to initialize rate scaling.\n");
                rcu_read_unlock();
@@ -944,7 +943,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
        switch (il->band) {
        case IEEE80211_BAND_2GHZ:
                /* TODO: this always does G, not a regression */
-               if (il->ctx.active.flags & RXON_FLG_TGG_PROTECT_MSK) {
+               if (il->active.flags & RXON_FLG_TGG_PROTECT_MSK) {
                        rs_sta->tgg = 1;
                        rs_sta->expected_tpt = il3945_expected_tpt_g_prot;
                } else
index 1489b1573a6a3d62384a0e1b9f7fdbb490d71126..456f32da6b26e2a1f5d60241e20739c7f423b825 100644 (file)
@@ -57,10 +57,6 @@ il3945_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd)
        return il_send_cmd(il, &cmd);
 }
 
-const struct il_led_ops il3945_led_ops = {
-       .cmd = il3945_send_led_cmd,
-};
-
 #define IL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np)    \
        [RATE_##r##M_IDX] = { RATE_##r##M_PLCP,   \
                                    RATE_##r##M_IEEE,   \
@@ -293,17 +289,17 @@ il3945_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
 {
        struct il_tx_queue *txq = &il->txq[txq_id];
        struct il_queue *q = &txq->q;
-       struct il_tx_info *tx_info;
+       struct sk_buff *skb;
 
        BUG_ON(txq_id == IL39_CMD_QUEUE_NUM);
 
        for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
             q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
-               tx_info = &txq->txb[txq->q.read_ptr];
-               ieee80211_tx_status_irqsafe(il->hw, tx_info->skb);
-               tx_info->skb = NULL;
-               il->cfg->ops->lib->txq_free_tfd(il, txq);
+               skb = txq->skbs[txq->q.read_ptr];
+               ieee80211_tx_status_irqsafe(il->hw, skb);
+               txq->skbs[txq->q.read_ptr] = NULL;
+               il->ops->txq_free_tfd(il, txq);
        }
 
        if (il_queue_space(q) > q->low_mark && txq_id >= 0 &&
@@ -336,7 +332,7 @@ il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
        }
 
        txq->time_stamp = jiffies;
-       info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
+       info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]);
        ieee80211_tx_info_clear_status(info);
 
        /* Fill the MRR chain with some info about on-chip retransmissions */
@@ -577,8 +573,6 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
                network_packet ? '*' : ' ', le16_to_cpu(rx_hdr->channel),
                rx_status.signal, rx_status.signal, rx_status.rate_idx);
 
-       il_dbg_log_rx_data_frame(il, le16_to_cpu(rx_hdr->len), header);
-
        if (network_packet) {
                il->_3945.last_beacon_time =
                    le32_to_cpu(rx_end->beacon_timestamp);
@@ -660,15 +654,13 @@ il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)
                                 PCI_DMA_TODEVICE);
 
        /* free SKB */
-       if (txq->txb) {
-               struct sk_buff *skb;
-
-               skb = txq->txb[txq->q.read_ptr].skb;
+       if (txq->skbs) {
+               struct sk_buff *skb = txq->skbs[txq->q.read_ptr];
 
                /* can be called from irqs-disabled context */
                if (skb) {
                        dev_kfree_skb_any(skb);
-                       txq->txb[txq->q.read_ptr].skb = NULL;
+                       txq->skbs[txq->q.read_ptr] = NULL;
                }
        }
 }
@@ -798,7 +790,6 @@ il3945_rx_init(struct il_priv *il, struct il_rx_queue *rxq)
 static int
 il3945_tx_reset(struct il_priv *il)
 {
-
        /* bypass mode */
        il_wr_prph(il, ALM_SCD_MODE_REG, 0x2);
 
@@ -835,8 +826,7 @@ il3945_tx_reset(struct il_priv *il)
 static int
 il3945_txq_ctx_reset(struct il_priv *il)
 {
-       int rc;
-       int txq_id, slots_num;
+       int rc, txq_id;
 
        il3945_hw_txq_ctx_free(il);
 
@@ -852,10 +842,7 @@ il3945_txq_ctx_reset(struct il_priv *il)
 
        /* Tx queue(s) */
        for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
-               slots_num =
-                   (txq_id ==
-                    IL39_CMD_QUEUE_NUM) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
-               rc = il_tx_queue_init(il, &il->txq[txq_id], slots_num, txq_id);
+               rc = il_tx_queue_init(il, txq_id);
                if (rc) {
                        IL_ERR("Tx %d queue init failed\n", txq_id);
                        goto error;
@@ -960,12 +947,11 @@ il3945_hw_nic_init(struct il_priv *il)
        struct il_rx_queue *rxq = &il->rxq;
 
        spin_lock_irqsave(&il->lock, flags);
-       il->cfg->ops->lib->apm_ops.init(il);
+       il3945_apm_init(il);
        spin_unlock_irqrestore(&il->lock, flags);
 
        il3945_set_pwr_vmain(il);
-
-       il->cfg->ops->lib->apm_ops.config(il);
+       il3945_nic_config(il);
 
        /* Allocate the RX queue, or reset if it is already allocated */
        if (!rxq->bd) {
@@ -1016,7 +1002,7 @@ il3945_hw_txq_ctx_free(struct il_priv *il)
                                il_tx_queue_free(il, txq_id);
 
        /* free tx queue structure */
-       il_txq_mem(il);
+       il_free_txq_mem(il);
 }
 
 void
@@ -1025,18 +1011,17 @@ il3945_hw_txq_ctx_stop(struct il_priv *il)
        int txq_id;
 
        /* stop SCD */
-       il_wr_prph(il, ALM_SCD_MODE_REG, 0);
-       il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);
+       _il_wr_prph(il, ALM_SCD_MODE_REG, 0);
+       _il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);
 
        /* reset TFD queues */
        for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
-               il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);
-               il_poll_bit(il, FH39_TSSR_TX_STATUS,
-                           FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
-                           1000);
+               _il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);
+               _il_poll_bit(il, FH39_TSSR_TX_STATUS,
+                            FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
+                            FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
+                            1000);
        }
-
-       il3945_hw_txq_ctx_free(il);
 }
 
 /**
@@ -1388,7 +1373,7 @@ il3945_send_tx_power(struct il_priv *il)
        int rate_idx, i;
        const struct il_channel_info *ch_info = NULL;
        struct il3945_txpowertable_cmd txpower = {
-               .channel = il->ctx.active.channel,
+               .channel = il->active.channel,
        };
        u16 chan;
 
@@ -1397,7 +1382,7 @@ il3945_send_tx_power(struct il_priv *il)
             "TX Power requested while scanning!\n"))
                return -EAGAIN;
 
-       chan = le16_to_cpu(il->ctx.active.channel);
+       chan = le16_to_cpu(il->active.channel);
 
        txpower.band = (il->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
        ch_info = il_get_channel_info(il, il->band, chan);
@@ -1615,7 +1600,7 @@ il3945_hw_reg_comp_txpower_temp(struct il_priv *il)
        }
 
        /* send Txpower command for current channel to ucode */
-       return il->cfg->ops->lib->send_tx_power(il);
+       return il->ops->send_tx_power(il);
 }
 
 int
@@ -1662,7 +1647,7 @@ il3945_hw_reg_set_txpower(struct il_priv *il, s8 power)
 }
 
 static int
-il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
+il3945_send_rxon_assoc(struct il_priv *il)
 {
        int rc = 0;
        struct il_rx_pkt *pkt;
@@ -1673,8 +1658,8 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
                .flags = CMD_WANT_SKB,
                .data = &rxon_assoc,
        };
-       const struct il_rxon_cmd *rxon1 = &ctx->staging;
-       const struct il_rxon_cmd *rxon2 = &ctx->active;
+       const struct il_rxon_cmd *rxon1 = &il->staging;
+       const struct il_rxon_cmd *rxon2 = &il->active;
 
        if (rxon1->flags == rxon2->flags &&
            rxon1->filter_flags == rxon2->filter_flags &&
@@ -1684,10 +1669,10 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
                return 0;
        }
 
-       rxon_assoc.flags = ctx->staging.flags;
-       rxon_assoc.filter_flags = ctx->staging.filter_flags;
-       rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
-       rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+       rxon_assoc.flags = il->staging.flags;
+       rxon_assoc.filter_flags = il->staging.filter_flags;
+       rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates;
+       rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates;
        rxon_assoc.reserved = 0;
 
        rc = il_send_cmd_sync(il, &cmd);
@@ -1714,11 +1699,11 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
  * a HW tune is required based on the RXON structure changes.
  */
 int
-il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
+il3945_commit_rxon(struct il_priv *il)
 {
        /* cast away the const for active_rxon in this function */
-       struct il3945_rxon_cmd *active_rxon = (void *)&ctx->active;
-       struct il3945_rxon_cmd *staging_rxon = (void *)&ctx->staging;
+       struct il3945_rxon_cmd *active_rxon = (void *)&il->active;
+       struct il3945_rxon_cmd *staging_rxon = (void *)&il->staging;
        int rc = 0;
        bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK);
 
@@ -1735,7 +1720,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
        staging_rxon->flags &= ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
        staging_rxon->flags |= il3945_get_antenna_flags(il);
 
-       rc = il_check_rxon_cmd(il, ctx);
+       rc = il_check_rxon_cmd(il);
        if (rc) {
                IL_ERR("Invalid RXON configuration.  Not committing.\n");
                return -EINVAL;
@@ -1744,8 +1729,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
        /* If we don't need to send a full RXON, we can use
         * il3945_rxon_assoc_cmd which is used to reconfigure filter
         * and other flags for the current radio configuration. */
-       if (!il_full_rxon_required(il, &il->ctx)) {
-               rc = il_send_rxon_assoc(il, &il->ctx);
+       if (!il_full_rxon_required(il)) {
+               rc = il_send_rxon_assoc(il);
                if (rc) {
                        IL_ERR("Error setting RXON_ASSOC "
                               "configuration (%d).\n", rc);
@@ -1776,7 +1761,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
                active_rxon->reserved4 = 0;
                active_rxon->reserved5 = 0;
                rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd),
-                                    &il->ctx.active);
+                                    &il->active);
 
                /* If the mask clearing failed then we set
                 * active_rxon back to what it was previously */
@@ -1786,8 +1771,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
                               "configuration (%d).\n", rc);
                        return rc;
                }
-               il_clear_ucode_stations(il, &il->ctx);
-               il_restore_stations(il, &il->ctx);
+               il_clear_ucode_stations(il);
+               il_restore_stations(il);
        }
 
        D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n"
@@ -1801,7 +1786,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
        staging_rxon->reserved4 = 0;
        staging_rxon->reserved5 = 0;
 
-       il_set_rxon_hwcrypto(il, ctx, !il3945_mod_params.sw_crypto);
+       il_set_rxon_hwcrypto(il, !il3945_mod_params.sw_crypto);
 
        /* Apply the new configuration */
        rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd),
@@ -1814,8 +1799,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
        memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
 
        if (!new_assoc) {
-               il_clear_ucode_stations(il, &il->ctx);
-               il_restore_stations(il, &il->ctx);
+               il_clear_ucode_stations(il);
+               il_restore_stations(il);
        }
 
        /* If we issue a new RXON command which required a tune then we must
@@ -2185,12 +2170,14 @@ il3945_txpower_set_from_eeprom(struct il_priv *il)
 int
 il3945_hw_rxq_stop(struct il_priv *il)
 {
-       int rc;
+       int ret;
 
-       il_wr(il, FH39_RCSR_CONFIG(0), 0);
-       rc = il_poll_bit(il, FH39_RSSR_STATUS,
-                        FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
-       if (rc < 0)
+       _il_wr(il, FH39_RCSR_CONFIG(0), 0);
+       ret = _il_poll_bit(il, FH39_RSSR_STATUS,
+                          FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
+                          FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
+                          1000);
+       if (ret < 0)
                IL_ERR("Can't stop Rx DMA.\n");
 
        return 0;
@@ -2258,7 +2245,6 @@ il3945_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data)
 static int
 il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r)
 {
-       struct il_rxon_context *ctx = &il->ctx;
        int ret;
        u8 sta_id;
        unsigned long flags;
@@ -2266,7 +2252,7 @@ il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r)
        if (sta_id_r)
                *sta_id_r = IL_INVALID_STATION;
 
-       ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id);
+       ret = il_add_station_common(il, addr, 0, NULL, &sta_id);
        if (ret) {
                IL_ERR("Unable to add station %pM\n", addr);
                return ret;
@@ -2396,15 +2382,16 @@ il3945_hw_set_hw_params(struct il_priv *il)
                return -ENOMEM;
        }
 
+       il->hw_params.bcast_id = IL3945_BROADCAST_ID;
+
        /* Assign number of Usable TX queues */
-       il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues;
+       il->hw_params.max_txq_num = il->cfg->num_of_queues;
 
        il->hw_params.tfd_size = sizeof(struct il3945_tfd);
        il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_3K);
        il->hw_params.max_rxq_size = RX_QUEUE_SIZE;
        il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
        il->hw_params.max_stations = IL3945_STATION_COUNT;
-       il->ctx.bcast_sta_id = IL3945_BROADCAST_ID;
 
        il->sta_key_max_num = STA_KEY_MAX_NUM;
 
@@ -2425,7 +2412,7 @@ il3945_hw_get_beacon_cmd(struct il_priv *il, struct il3945_frame *frame,
        tx_beacon_cmd = (struct il3945_tx_beacon_cmd *)&frame->u;
        memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
 
-       tx_beacon_cmd->tx.sta_id = il->ctx.bcast_sta_id;
+       tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id;
        tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
        frame_size =
@@ -2632,76 +2619,31 @@ il3945_load_bsm(struct il_priv *il)
        return 0;
 }
 
-static struct il_hcmd_ops il3945_hcmd = {
-       .rxon_assoc = il3945_send_rxon_assoc,
-       .commit_rxon = il3945_commit_rxon,
-};
-
-static struct il_lib_ops il3945_lib = {
+const struct il_ops il3945_ops = {
        .txq_attach_buf_to_tfd = il3945_hw_txq_attach_buf_to_tfd,
        .txq_free_tfd = il3945_hw_txq_free_tfd,
        .txq_init = il3945_hw_tx_queue_init,
        .load_ucode = il3945_load_bsm,
        .dump_nic_error_log = il3945_dump_nic_error_log,
-       .apm_ops = {
-                   .init = il3945_apm_init,
-                   .config = il3945_nic_config,
-                   },
-       .eeprom_ops = {
-                      .regulatory_bands = {
-                                           EEPROM_REGULATORY_BAND_1_CHANNELS,
-                                           EEPROM_REGULATORY_BAND_2_CHANNELS,
-                                           EEPROM_REGULATORY_BAND_3_CHANNELS,
-                                           EEPROM_REGULATORY_BAND_4_CHANNELS,
-                                           EEPROM_REGULATORY_BAND_5_CHANNELS,
-                                           EEPROM_REGULATORY_BAND_NO_HT40,
-                                           EEPROM_REGULATORY_BAND_NO_HT40,
-                                           },
-                      .acquire_semaphore = il3945_eeprom_acquire_semaphore,
-                      .release_semaphore = il3945_eeprom_release_semaphore,
-                      },
+       .apm_init = il3945_apm_init,
        .send_tx_power = il3945_send_tx_power,
        .is_valid_rtc_data_addr = il3945_hw_valid_rtc_data_addr,
+       .eeprom_acquire_semaphore = il3945_eeprom_acquire_semaphore,
+       .eeprom_release_semaphore = il3945_eeprom_release_semaphore,
 
-#ifdef CONFIG_IWLEGACY_DEBUGFS
-       .debugfs_ops = {
-                       .rx_stats_read = il3945_ucode_rx_stats_read,
-                       .tx_stats_read = il3945_ucode_tx_stats_read,
-                       .general_stats_read = il3945_ucode_general_stats_read,
-                       },
-#endif
-};
-
-static const struct il_legacy_ops il3945_legacy_ops = {
-       .post_associate = il3945_post_associate,
-       .config_ap = il3945_config_ap,
-       .manage_ibss_station = il3945_manage_ibss_station,
-};
+       .rxon_assoc = il3945_send_rxon_assoc,
+       .commit_rxon = il3945_commit_rxon,
 
-static struct il_hcmd_utils_ops il3945_hcmd_utils = {
        .get_hcmd_size = il3945_get_hcmd_size,
        .build_addsta_hcmd = il3945_build_addsta_hcmd,
        .request_scan = il3945_request_scan,
        .post_scan = il3945_post_scan,
-};
 
-static const struct il_ops il3945_ops = {
-       .lib = &il3945_lib,
-       .hcmd = &il3945_hcmd,
-       .utils = &il3945_hcmd_utils,
-       .led = &il3945_led_ops,
-       .legacy = &il3945_legacy_ops,
-       .ieee80211_ops = &il3945_hw_ops,
-};
+       .post_associate = il3945_post_associate,
+       .config_ap = il3945_config_ap,
+       .manage_ibss_station = il3945_manage_ibss_station,
 
-static struct il_base_params il3945_base_params = {
-       .eeprom_size = IL3945_EEPROM_IMG_SIZE,
-       .num_of_queues = IL39_NUM_QUEUES,
-       .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
-       .set_l0s = false,
-       .use_bsm = true,
-       .led_compensation = 64,
-       .wd_timeout = IL_DEF_WD_TIMEOUT,
+       .send_led_cmd = il3945_send_led_cmd,
 };
 
 static struct il_cfg il3945_bg_cfg = {
@@ -2711,10 +2653,26 @@ static struct il_cfg il3945_bg_cfg = {
        .ucode_api_min = IL3945_UCODE_API_MIN,
        .sku = IL_SKU_G,
        .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
-       .ops = &il3945_ops,
        .mod_params = &il3945_mod_params,
-       .base_params = &il3945_base_params,
        .led_mode = IL_LED_BLINK,
+
+       .eeprom_size = IL3945_EEPROM_IMG_SIZE,
+       .num_of_queues = IL39_NUM_QUEUES,
+       .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
+       .set_l0s = false,
+       .use_bsm = true,
+       .led_compensation = 64,
+       .wd_timeout = IL_DEF_WD_TIMEOUT,
+
+       .regulatory_bands = {
+               EEPROM_REGULATORY_BAND_1_CHANNELS,
+               EEPROM_REGULATORY_BAND_2_CHANNELS,
+               EEPROM_REGULATORY_BAND_3_CHANNELS,
+               EEPROM_REGULATORY_BAND_4_CHANNELS,
+               EEPROM_REGULATORY_BAND_5_CHANNELS,
+               EEPROM_REGULATORY_BAND_NO_HT40,
+               EEPROM_REGULATORY_BAND_NO_HT40,
+       },
 };
 
 static struct il_cfg il3945_abg_cfg = {
@@ -2724,10 +2682,26 @@ static struct il_cfg il3945_abg_cfg = {
        .ucode_api_min = IL3945_UCODE_API_MIN,
        .sku = IL_SKU_A | IL_SKU_G,
        .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
-       .ops = &il3945_ops,
        .mod_params = &il3945_mod_params,
-       .base_params = &il3945_base_params,
        .led_mode = IL_LED_BLINK,
+
+       .eeprom_size = IL3945_EEPROM_IMG_SIZE,
+       .num_of_queues = IL39_NUM_QUEUES,
+       .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
+       .set_l0s = false,
+       .use_bsm = true,
+       .led_compensation = 64,
+       .wd_timeout = IL_DEF_WD_TIMEOUT,
+
+       .regulatory_bands = {
+               EEPROM_REGULATORY_BAND_1_CHANNELS,
+               EEPROM_REGULATORY_BAND_2_CHANNELS,
+               EEPROM_REGULATORY_BAND_3_CHANNELS,
+               EEPROM_REGULATORY_BAND_4_CHANNELS,
+               EEPROM_REGULATORY_BAND_5_CHANNELS,
+               EEPROM_REGULATORY_BAND_NO_HT40,
+               EEPROM_REGULATORY_BAND_NO_HT40,
+       },
 };
 
 DEFINE_PCI_DEVICE_TABLE(il3945_hw_card_ids) = {
index 9f42f79f87784127f46e5b06753abdefb9e5490f..1d45075e0d5b51a21e234b44c4603bb0c0481ce6 100644 (file)
@@ -36,6 +36,8 @@ extern const struct pci_device_id il3945_hw_card_ids[];
 
 #include "common.h"
 
+extern const struct il_ops il3945_ops;
+
 /* Highest firmware API version supported */
 #define IL3945_UCODE_API_MAX 2
 
@@ -249,7 +251,7 @@ extern int il4965_get_temperature(const struct il_priv *il);
 extern void il3945_post_associate(struct il_priv *il);
 extern void il3945_config_ap(struct il_priv *il);
 
-extern int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx);
+extern int il3945_commit_rxon(struct il_priv *il);
 
 /**
  * il3945_hw_find_station - Find station id for a given BSSID
@@ -261,8 +263,6 @@ extern int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx);
  */
 extern u8 il3945_hw_find_station(struct il_priv *il, const u8 * bssid);
 
-extern struct ieee80211_ops il3945_hw_ops;
-
 extern __le32 il3945_get_antenna_flags(const struct il_priv *il);
 extern int il3945_init_hw_rate_table(struct il_priv *il);
 extern void il3945_reg_txpower_periodic(struct il_priv *il);
@@ -595,13 +595,7 @@ struct il3945_tfd {
 } __packed;
 
 #ifdef CONFIG_IWLEGACY_DEBUGFS
-ssize_t il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
-                                  size_t count, loff_t *ppos);
-ssize_t il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
-                                  size_t count, loff_t *ppos);
-ssize_t il3945_ucode_general_stats_read(struct file *file,
-                                       char __user *user_buf, size_t count,
-                                       loff_t *ppos);
+extern const struct il_debugfs_ops il3945_debugfs_ops;
 #endif
 
 #endif
index d3248e3ef23bb6c917e709f56c90c11c93ca1482..e78bdefb8952ca605ae8eb1d3243274b80bdd63f 100644 (file)
@@ -79,18 +79,6 @@ struct stats_general_data {
        u32 beacon_energy_c;
 };
 
-void
-il4965_calib_free_results(struct il_priv *il)
-{
-       int i;
-
-       for (i = 0; i < IL_CALIB_MAX; i++) {
-               kfree(il->calib_results[i].buf);
-               il->calib_results[i].buf = NULL;
-               il->calib_results[i].buf_len = 0;
-       }
-}
-
 /*****************************************************************************
  * RUNTIME calibrations framework
  *****************************************************************************/
@@ -627,13 +615,13 @@ il4965_find_disconn_antenna(struct il_priv *il, u32 * average_sig,
 
        average_sig[0] =
            data->chain_signal_a /
-           il->cfg->base_params->chain_noise_num_beacons;
+           il->cfg->chain_noise_num_beacons;
        average_sig[1] =
            data->chain_signal_b /
-           il->cfg->base_params->chain_noise_num_beacons;
+           il->cfg->chain_noise_num_beacons;
        average_sig[2] =
            data->chain_signal_c /
-           il->cfg->base_params->chain_noise_num_beacons;
+           il->cfg->chain_noise_num_beacons;
 
        if (average_sig[0] >= average_sig[1]) {
                max_average_sig = average_sig[0];
@@ -806,8 +794,6 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
        unsigned long flags;
        struct stats_rx_non_phy *rx_info;
 
-       struct il_rxon_context *ctx = &il->ctx;
-
        if (il->disable_chain_noise_cal)
                return;
 
@@ -833,8 +819,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
                return;
        }
 
-       rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
-       rxon_chnum = le16_to_cpu(ctx->staging.channel);
+       rxon_band24 = !!(il->staging.flags & RXON_FLG_BAND_24G_MSK);
+       rxon_chnum = le16_to_cpu(il->staging.channel);
 
        stat_band24 =
            !!(((struct il_notif_stats *)stat_resp)->
@@ -888,7 +874,7 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
        /* If this is the "chain_noise_num_beacons", determine:
         * 1)  Disconnected antennas (using signal strengths)
         * 2)  Differential gain (using silence noise) to balance receivers */
-       if (data->beacon_count != il->cfg->base_params->chain_noise_num_beacons)
+       if (data->beacon_count != il->cfg->chain_noise_num_beacons)
                return;
 
        /* Analyze signal for disconnected antenna */
@@ -896,11 +882,11 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
 
        /* Analyze noise for rx balance */
        average_noise[0] =
-           data->chain_noise_a / il->cfg->base_params->chain_noise_num_beacons;
+           data->chain_noise_a / il->cfg->chain_noise_num_beacons;
        average_noise[1] =
-           data->chain_noise_b / il->cfg->base_params->chain_noise_num_beacons;
+           data->chain_noise_b / il->cfg->chain_noise_num_beacons;
        average_noise[2] =
-           data->chain_noise_c / il->cfg->base_params->chain_noise_num_beacons;
+           data->chain_noise_c / il->cfg->chain_noise_num_beacons;
 
        for (i = 0; i < NUM_RX_CHAINS; i++) {
                if (!data->disconn_array[i] &&
@@ -925,8 +911,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
        /* Some power changes may have been made during the calibration.
         * Update and commit the RXON
         */
-       if (il->cfg->ops->lib->update_chain_flags)
-               il->cfg->ops->lib->update_chain_flags(il);
+       if (il->ops->update_chain_flags)
+               il->ops->update_chain_flags(il);
 
        data->state = IL_CHAIN_NOISE_DONE;
        il_power_update_mode(il, false);
index 98ec39f56ba34c107f5a6fd8498e8d9166afaea8..c8153fc64f7465b8bfb87ac8700840cb08e3ebc4 100644 (file)
@@ -744,3 +744,9 @@ il4965_ucode_general_stats_read(struct file *file, char __user *user_buf,
        kfree(buf);
        return ret;
 }
+
+const struct il_debugfs_ops il4965_debugfs_ops = {
+       .rx_stats_read = il4965_ucode_rx_stats_read,
+       .tx_stats_read = il4965_ucode_tx_stats_read,
+       .general_stats_read = il4965_ucode_general_stats_read,
+};
index 1667232af647784e03d8bc15c9f63e44e9678990..7b54dbb338be6127bec123f8414cd3231eaabb00 100644 (file)
@@ -199,18 +199,14 @@ il4965_hw_nic_init(struct il_priv *il)
        struct il_rx_queue *rxq = &il->rxq;
        int ret;
 
-       /* nic_init */
        spin_lock_irqsave(&il->lock, flags);
-       il->cfg->ops->lib->apm_ops.init(il);
-
+       il_apm_init(il);
        /* Set interrupt coalescing calibration timer to default (512 usecs) */
        il_write8(il, CSR_INT_COALESCING, IL_HOST_INT_CALIB_TIMEOUT_DEF);
-
        spin_unlock_irqrestore(&il->lock, flags);
 
        il4965_set_pwr_vmain(il);
-
-       il->cfg->ops->lib->apm_ops.config(il);
+       il4965_nic_config(il);
 
        /* Allocate the RX queue, or reset if it is already allocated */
        if (!rxq->bd) {
@@ -445,11 +441,15 @@ il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq)
 int
 il4965_rxq_stop(struct il_priv *il)
 {
+       int ret;
 
-       /* stop Rx DMA */
-       il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0);
-       il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG,
-                   FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
+       _il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+       ret = _il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG,
+                          FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
+                          FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
+                          1000);
+       if (ret < 0)
+               IL_ERR("Can't stop Rx DMA.\n");
 
        return 0;
 }
@@ -692,7 +692,6 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
        /* Find max signal strength (dBm) among 3 antenna/receiver chains */
        rx_status.signal = il4965_calc_rssi(il, phy_res);
 
-       il_dbg_log_rx_data_frame(il, len, header);
        D_STATS("Rssi %d, TSF %llu\n", rx_status.signal,
                (unsigned long long)rx_status.mactime);
 
@@ -843,7 +842,6 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
                .flags = CMD_SIZE_HUGE,
        };
        struct il_scan_cmd *scan;
-       struct il_rxon_context *ctx = &il->ctx;
        u32 rate_flags = 0;
        u16 cmd_len;
        u16 rx_chain = 0;
@@ -859,8 +857,6 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
 
        lockdep_assert_held(&il->mutex);
 
-       ctx = il_rxon_ctx_from_vif(vif);
-
        if (!il->scan_cmd) {
                il->scan_cmd =
                    kmalloc(sizeof(struct il_scan_cmd) + IL_MAX_SCAN_SIZE,
@@ -919,15 +915,14 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
                D_SCAN("Start passive scan.\n");
 
        scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
-       scan->tx_cmd.sta_id = ctx->bcast_sta_id;
+       scan->tx_cmd.sta_id = il->hw_params.bcast_id;
        scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
        switch (il->scan_band) {
        case IEEE80211_BAND_2GHZ:
                scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
                chan_mod =
-                   le32_to_cpu(il->ctx.active.
-                               flags & RXON_FLG_CHANNEL_MODE_MSK) >>
+                   le32_to_cpu(il->active.flags & RXON_FLG_CHANNEL_MODE_MSK) >>
                    RXON_FLG_CHANNEL_MODE_POS;
                if (chan_mod == CHANNEL_MODE_PURE_40) {
                        rate = RATE_6M_PLCP;
@@ -1034,8 +1029,7 @@ il4965_manage_ibss_station(struct il_priv *il, struct ieee80211_vif *vif,
        struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
 
        if (add)
-               return il4965_add_bssid_station(il, vif_priv->ctx,
-                                               vif->bss_conf.bssid,
+               return il4965_add_bssid_station(il, vif->bss_conf.bssid,
                                                &vif_priv->ibss_bssid_sta_id);
        return il_remove_station(il, vif_priv->ibss_bssid_sta_id,
                                 vif->bss_conf.bssid);
@@ -1128,7 +1122,7 @@ il4965_count_chain_bitmap(u32 chain_bitmap)
  * This should not be used for scan command ... it puts data in wrong place.
  */
 void
-il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_set_rxon_chain(struct il_priv *il)
 {
        bool is_single = il4965_is_single_rx_stream(il);
        bool is_cam = !test_bit(S_POWER_PMI, &il->status);
@@ -1164,14 +1158,14 @@ il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx)
        rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
        rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
 
-       ctx->staging.rx_chain = cpu_to_le16(rx_chain);
+       il->staging.rx_chain = cpu_to_le16(rx_chain);
 
        if (!is_single && active_rx_cnt >= IL_NUM_RX_CHAINS_SINGLE && is_cam)
-               ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
+               il->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
        else
-               ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
+               il->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
 
-       D_ASSOC("rx_chain=0x%X active=%d idle=%d\n", ctx->staging.rx_chain,
+       D_ASSOC("rx_chain=0x%X active=%d idle=%d\n", il->staging.rx_chain,
                active_rx_cnt, idle_rx_cnt);
 
        WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
@@ -1348,12 +1342,11 @@ il4965_accumulative_stats(struct il_priv *il, __le32 * stats)
 }
 #endif
 
-#define REG_RECALIB_PERIOD (60)
-
 void
 il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
 {
-       int change;
+       const int recalib_seconds = 60;
+       bool change;
        struct il_rx_pkt *pkt = rxb_addr(rxb);
 
        D_RX("Statistics notification received (%d vs %d).\n",
@@ -1374,20 +1367,21 @@ il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
 
        set_bit(S_STATS, &il->status);
 
-       /* Reschedule the stats timer to occur in
-        * REG_RECALIB_PERIOD seconds to ensure we get a
-        * thermal update even if the uCode doesn't give
-        * us one */
+       /*
+        * Reschedule the stats timer to occur in recalib_seconds to ensure
+        * we get a thermal update even if the uCode doesn't give us one
+        */
        mod_timer(&il->stats_periodic,
-                 jiffies + msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
+                 jiffies + msecs_to_jiffies(recalib_seconds * 1000));
 
        if (unlikely(!test_bit(S_SCANNING, &il->status)) &&
            (pkt->hdr.cmd == N_STATS)) {
                il4965_rx_calc_noise(il);
                queue_work(il->workqueue, &il->run_time_calib_work);
        }
-       if (il->cfg->ops->lib->temp_ops.temperature && change)
-               il->cfg->ops->lib->temp_ops.temperature(il);
+
+       if (change)
+               il4965_temperature_calib(il);
 }
 
 void
@@ -1457,10 +1451,17 @@ il4965_get_ac_from_tid(u16 tid)
 }
 
 static inline int
-il4965_get_fifo_from_tid(struct il_rxon_context *ctx, u16 tid)
+il4965_get_fifo_from_tid(u16 tid)
 {
+       const u8 ac_to_fifo[] = {
+               IL_TX_FIFO_VO,
+               IL_TX_FIFO_VI,
+               IL_TX_FIFO_BE,
+               IL_TX_FIFO_BK,
+       };
+
        if (likely(tid < ARRAY_SIZE(tid_to_ac)))
-               return ctx->ac_to_fifo[tid_to_ac[tid]];
+               return ac_to_fifo[tid_to_ac[tid]];
 
        /* no support for TIDs 8-15 yet */
        return -EINVAL;
@@ -1639,7 +1640,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
        struct il_device_cmd *out_cmd;
        struct il_cmd_meta *out_meta;
        struct il_tx_cmd *tx_cmd;
-       struct il_rxon_context *ctx = &il->ctx;
        int txq_id;
        dma_addr_t phys_addr;
        dma_addr_t txcmd_phys;
@@ -1655,9 +1655,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
        unsigned long flags;
        bool is_agg = false;
 
-       if (info->control.vif)
-               ctx = il_rxon_ctx_from_vif(info->control.vif);
-
        spin_lock_irqsave(&il->lock, flags);
        if (il_is_rfkill(il)) {
                D_DROP("Dropping - RF KILL\n");
@@ -1679,10 +1676,10 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
        /* For management frames use broadcast id to do not break aggregation */
        if (!ieee80211_is_data(fc))
-               sta_id = ctx->bcast_sta_id;
+               sta_id = il->hw_params.bcast_id;
        else {
                /* Find idx into station table for destination station */
-               sta_id = il_sta_id_or_broadcast(il, ctx, info->control.sta);
+               sta_id = il_sta_id_or_broadcast(il, info->control.sta);
 
                if (sta_id == IL_INVALID_STATION) {
                        D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1);
@@ -1696,7 +1693,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
                sta_priv = (void *)sta->drv_priv;
 
        if (sta_priv && sta_priv->asleep &&
-           (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) {
+           (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) {
                /*
                 * This sends an asynchronous command to the device,
                 * but we can rely on it being processed before the
@@ -1709,19 +1706,11 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
                il4965_sta_modify_sleep_tx_count(il, sta_id, 1);
        }
 
-       /*
-        * Send this frame after DTIM -- there's a special queue
-        * reserved for this for contexts that support AP mode.
-        */
-       if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
-               txq_id = ctx->mcast_queue;
-               /*
-                * The microcode will clear the more data
-                * bit in the last frame it transmits.
-                */
-               hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
-       } else
-               txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
+       /* FIXME: remove me ? */
+       WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM);
+
+       /* Access category (AC) is also the queue number */
+       txq_id = skb_get_queue_mapping(skb);
 
        /* irqs already disabled/saved above when locking il->lock */
        spin_lock(&il->sta_lock);
@@ -1763,10 +1752,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
        spin_unlock(&il->sta_lock);
 
-       /* Set up driver data for this TFD */
-       memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info));
-       txq->txb[q->write_ptr].skb = skb;
-       txq->txb[q->write_ptr].ctx = ctx;
+       txq->skbs[q->write_ptr] = skb;
 
        /* Set up first empty entry in queue's array of Tx/cmd buffers */
        out_cmd = txq->cmd[q->write_ptr];
@@ -1798,7 +1784,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
        /* TODO need this for burst mode later on */
        il4965_tx_cmd_build_basic(il, skb, tx_cmd, info, hdr, sta_id);
-       il_dbg_log_tx_data_frame(il, len, hdr);
 
        il4965_tx_cmd_build_rate(il, tx_cmd, info, fc);
 
@@ -1828,8 +1813,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
        dma_unmap_len_set(out_meta, len, firstlen);
        /* Add buffer containing Tx command and MAC(!) header to TFD's
         * first entry */
-       il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen,
-                                                1, 0);
+       il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0);
 
        if (!ieee80211_has_morefrags(hdr->frame_control)) {
                txq->need_update = 1;
@@ -1845,8 +1829,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
                phys_addr =
                    pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen,
                                   PCI_DMA_TODEVICE);
-               il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr,
-                                                        secondlen, 0, 0);
+               il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen,
+                                              0, 0);
        }
 
        scratch_phys =
@@ -1866,9 +1850,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
        /* Set up entry for this TFD in Tx byte-count array */
        if (info->flags & IEEE80211_TX_CTL_AMPDU)
-               il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq,
-                                                          le16_to_cpu(tx_cmd->
-                                                                      len));
+               il->ops->txq_update_byte_cnt_tbl(il, txq, le16_to_cpu(tx_cmd->len));
 
        pci_dma_sync_single_for_device(il->pci_dev, txcmd_phys, firstlen,
                                       PCI_DMA_BIDIRECTIONAL);
@@ -1957,7 +1939,7 @@ il4965_hw_txq_ctx_free(struct il_priv *il)
        il4965_free_dma_ptr(il, &il->scd_bc_tbls);
 
        /* free tx queue structure */
-       il_txq_mem(il);
+       il_free_txq_mem(il);
 }
 
 /**
@@ -1970,8 +1952,7 @@ il4965_hw_txq_ctx_free(struct il_priv *il)
 int
 il4965_txq_ctx_alloc(struct il_priv *il)
 {
-       int ret;
-       int txq_id, slots_num;
+       int ret, txq_id;
        unsigned long flags;
 
        /* Free all tx/cmd queues and keep-warm buffer */
@@ -2008,10 +1989,7 @@ il4965_txq_ctx_alloc(struct il_priv *il)
 
        /* Alloc and init all Tx queues, including the command queue (#4/#9) */
        for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
-               slots_num =
-                   (txq_id ==
-                    il->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
-               ret = il_tx_queue_init(il, &il->txq[txq_id], slots_num, txq_id);
+               ret = il_tx_queue_init(il, txq_id);
                if (ret) {
                        IL_ERR("Tx %d queue init failed\n", txq_id);
                        goto error;
@@ -2032,52 +2010,27 @@ error_bc_tbls:
 void
 il4965_txq_ctx_reset(struct il_priv *il)
 {
-       int txq_id, slots_num;
+       int txq_id;
        unsigned long flags;
 
        spin_lock_irqsave(&il->lock, flags);
 
        /* Turn off all Tx DMA fifos */
        il4965_txq_set_sched(il, 0);
-
        /* Tell NIC where to find the "keep warm" buffer */
        il_wr(il, FH49_KW_MEM_ADDR_REG, il->kw.dma >> 4);
 
        spin_unlock_irqrestore(&il->lock, flags);
 
        /* Alloc and init all Tx queues, including the command queue (#4) */
-       for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
-               slots_num =
-                   txq_id == il->cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
-               il_tx_queue_reset(il, &il->txq[txq_id], slots_num, txq_id);
-       }
+       for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
+               il_tx_queue_reset(il, txq_id);
 }
 
-/**
- * il4965_txq_ctx_stop - Stop all Tx DMA channels
- */
 void
-il4965_txq_ctx_stop(struct il_priv *il)
+il4965_txq_ctx_unmap(struct il_priv *il)
 {
-       int ch, txq_id;
-       unsigned long flags;
-
-       /* Turn off all Tx DMA fifos */
-       spin_lock_irqsave(&il->lock, flags);
-
-       il4965_txq_set_sched(il, 0);
-
-       /* Stop each Tx DMA channel, and wait for it to be idle */
-       for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
-               il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
-               if (il_poll_bit
-                   (il, FH49_TSSR_TX_STATUS_REG,
-                    FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000))
-                       IL_ERR("Failing on timeout while stopping"
-                              " DMA channel %d [0x%08x]", ch,
-                              il_rd(il, FH49_TSSR_TX_STATUS_REG));
-       }
-       spin_unlock_irqrestore(&il->lock, flags);
+       int txq_id;
 
        if (!il->txq)
                return;
@@ -2090,6 +2043,30 @@ il4965_txq_ctx_stop(struct il_priv *il)
                        il_tx_queue_unmap(il, txq_id);
 }
 
+/**
+ * il4965_txq_ctx_stop - Stop all Tx DMA channels
+ */
+void
+il4965_txq_ctx_stop(struct il_priv *il)
+{
+       int ch, ret;
+
+       _il_wr_prph(il, IL49_SCD_TXFACT, 0);
+
+       /* Stop each Tx DMA channel, and wait for it to be idle */
+       for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
+               _il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
+               ret =
+                   _il_poll_bit(il, FH49_TSSR_TX_STATUS_REG,
+                                FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
+                                FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
+                                1000);
+               if (ret < 0)
+                       IL_ERR("Timeout stopping DMA channel %d [0x%08x]",
+                              ch, _il_rd(il, FH49_TSSR_TX_STATUS_REG));
+       }
+}
+
 /*
  * Find first available (lowest unused) Tx Queue, mark it "active".
  * Called only when finding queue for aggregation.
@@ -2163,11 +2140,11 @@ il4965_txq_agg_enable(struct il_priv *il, int txq_id, int tx_fifo, int sta_id,
 
        if ((IL49_FIRST_AMPDU_QUEUE > txq_id) ||
            (IL49_FIRST_AMPDU_QUEUE +
-            il->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
+            il->cfg->num_of_ampdu_queues <= txq_id)) {
                IL_WARN("queue number out of range: %d, must be %d to %d\n",
                        txq_id, IL49_FIRST_AMPDU_QUEUE,
                        IL49_FIRST_AMPDU_QUEUE +
-                       il->cfg->base_params->num_of_ampdu_queues - 1);
+                       il->cfg->num_of_ampdu_queues - 1);
                return -EINVAL;
        }
 
@@ -2230,7 +2207,8 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
        unsigned long flags;
        struct il_tid_data *tid_data;
 
-       tx_fifo = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid);
+       /* FIXME: warning if tx fifo not found ? */
+       tx_fifo = il4965_get_fifo_from_tid(tid);
        if (unlikely(tx_fifo < 0))
                return tx_fifo;
 
@@ -2290,11 +2268,11 @@ il4965_txq_agg_disable(struct il_priv *il, u16 txq_id, u16 ssn_idx, u8 tx_fifo)
 {
        if ((IL49_FIRST_AMPDU_QUEUE > txq_id) ||
            (IL49_FIRST_AMPDU_QUEUE +
-            il->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
+            il->cfg->num_of_ampdu_queues <= txq_id)) {
                IL_WARN("queue number out of range: %d, must be %d to %d\n",
                        txq_id, IL49_FIRST_AMPDU_QUEUE,
                        IL49_FIRST_AMPDU_QUEUE +
-                       il->cfg->base_params->num_of_ampdu_queues - 1);
+                       il->cfg->num_of_ampdu_queues - 1);
                return -EINVAL;
        }
 
@@ -2323,7 +2301,8 @@ il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif,
        int write_ptr, read_ptr;
        unsigned long flags;
 
-       tx_fifo_id = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid);
+       /* FIXME: warning if tx_fifo_id not found ? */
+       tx_fifo_id = il4965_get_fifo_from_tid(tid);
        if (unlikely(tx_fifo_id < 0))
                return tx_fifo_id;
 
@@ -2397,9 +2376,6 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
        struct il_queue *q = &il->txq[txq_id].q;
        u8 *addr = il->stations[sta_id].sta.sta.addr;
        struct il_tid_data *tid_data = &il->stations[sta_id].tid[tid];
-       struct il_rxon_context *ctx;
-
-       ctx = &il->ctx;
 
        lockdep_assert_held(&il->sta_lock);
 
@@ -2410,11 +2386,11 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
                if (txq_id == tid_data->agg.txq_id &&
                    q->read_ptr == q->write_ptr) {
                        u16 ssn = SEQ_TO_SN(tid_data->seq_number);
-                       int tx_fifo = il4965_get_fifo_from_tid(ctx, tid);
+                       int tx_fifo = il4965_get_fifo_from_tid(tid);
                        D_HT("HW queue empty: continue DELBA flow\n");
                        il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo);
                        tid_data->agg.state = IL_AGG_OFF;
-                       ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
+                       ieee80211_stop_tx_ba_cb_irqsafe(il->vif, addr, tid);
                }
                break;
        case IL_EMPTYING_HW_QUEUE_ADDBA:
@@ -2422,7 +2398,7 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
                if (tid_data->tfds_in_queue == 0) {
                        D_HT("HW queue empty: continue ADDBA flow\n");
                        tid_data->agg.state = IL_AGG_ON;
-                       ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
+                       ieee80211_start_tx_ba_cb_irqsafe(il->vif, addr, tid);
                }
                break;
        }
@@ -2431,14 +2407,13 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
 }
 
 static void
-il4965_non_agg_tx_status(struct il_priv *il, struct il_rxon_context *ctx,
-                        const u8 *addr1)
+il4965_non_agg_tx_status(struct il_priv *il, const u8 *addr1)
 {
        struct ieee80211_sta *sta;
        struct il_station_priv *sta_priv;
 
        rcu_read_lock();
-       sta = ieee80211_find_sta(ctx->vif, addr1);
+       sta = ieee80211_find_sta(il->vif, addr1);
        if (sta) {
                sta_priv = (void *)sta->drv_priv;
                /* avoid atomic ops if this isn't a client */
@@ -2450,14 +2425,14 @@ il4965_non_agg_tx_status(struct il_priv *il, struct il_rxon_context *ctx,
 }
 
 static void
-il4965_tx_status(struct il_priv *il, struct il_tx_info *tx_info, bool is_agg)
+il4965_tx_status(struct il_priv *il, struct sk_buff *skb, bool is_agg)
 {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
        if (!is_agg)
-               il4965_non_agg_tx_status(il, tx_info->ctx, hdr->addr1);
+               il4965_non_agg_tx_status(il, hdr->addr1);
 
-       ieee80211_tx_status_irqsafe(il->hw, tx_info->skb);
+       ieee80211_tx_status_irqsafe(il->hw, skb);
 }
 
 int
@@ -2465,9 +2440,9 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
 {
        struct il_tx_queue *txq = &il->txq[txq_id];
        struct il_queue *q = &txq->q;
-       struct il_tx_info *tx_info;
        int nfreed = 0;
        struct ieee80211_hdr *hdr;
+       struct sk_buff *skb;
 
        if (idx >= q->n_bd || il_queue_used(q, idx) == 0) {
                IL_ERR("Read idx for DMA queue txq id (%d), idx %d, "
@@ -2479,20 +2454,19 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
        for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
             q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
-               tx_info = &txq->txb[txq->q.read_ptr];
+               skb = txq->skbs[txq->q.read_ptr];
 
-               if (WARN_ON_ONCE(tx_info->skb == NULL))
+               if (WARN_ON_ONCE(skb == NULL))
                        continue;
 
-               hdr = (struct ieee80211_hdr *)tx_info->skb->data;
+               hdr = (struct ieee80211_hdr *) skb->data;
                if (ieee80211_is_data_qos(hdr->frame_control))
                        nfreed++;
 
-               il4965_tx_status(il, tx_info,
-                                txq_id >= IL4965_FIRST_AMPDU_QUEUE);
-               tx_info->skb = NULL;
+               il4965_tx_status(il, skb, txq_id >= IL4965_FIRST_AMPDU_QUEUE);
 
-               il->cfg->ops->lib->txq_free_tfd(il, txq);
+               txq->skbs[txq->q.read_ptr] = NULL;
+               il->ops->txq_free_tfd(il, txq);
        }
        return nfreed;
 }
@@ -2555,7 +2529,7 @@ il4965_tx_status_reply_compressed_ba(struct il_priv *il, struct il_ht_agg *agg,
 
        D_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
 
-       info = IEEE80211_SKB_CB(il->txq[scd_flow].txb[agg->start_idx].skb);
+       info = IEEE80211_SKB_CB(il->txq[scd_flow].skbs[agg->start_idx]);
        memset(&info->status, 0, sizeof(info->status));
        info->flags |= IEEE80211_TX_STAT_ACK;
        info->flags |= IEEE80211_TX_STAT_AMPDU;
@@ -2566,6 +2540,308 @@ il4965_tx_status_reply_compressed_ba(struct il_priv *il, struct il_ht_agg *agg,
        return 0;
 }
 
+static inline bool
+il4965_is_tx_success(u32 status)
+{
+       status &= TX_STATUS_MSK;
+       return (status == TX_STATUS_SUCCESS || status == TX_STATUS_DIRECT_DONE);
+}
+
+static u8
+il4965_find_station(struct il_priv *il, const u8 *addr)
+{
+       int i;
+       int start = 0;
+       int ret = IL_INVALID_STATION;
+       unsigned long flags;
+
+       if (il->iw_mode == NL80211_IFTYPE_ADHOC)
+               start = IL_STA_ID;
+
+       if (is_broadcast_ether_addr(addr))
+               return il->hw_params.bcast_id;
+
+       spin_lock_irqsave(&il->sta_lock, flags);
+       for (i = start; i < il->hw_params.max_stations; i++)
+               if (il->stations[i].used &&
+                   (!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) {
+                       ret = i;
+                       goto out;
+               }
+
+       D_ASSOC("can not find STA %pM total %d\n", addr, il->num_stations);
+
+out:
+       /*
+        * It may be possible that more commands interacting with stations
+        * arrive before we completed processing the adding of
+        * station
+        */
+       if (ret != IL_INVALID_STATION &&
+           (!(il->stations[ret].used & IL_STA_UCODE_ACTIVE) ||
+            ((il->stations[ret].used & IL_STA_UCODE_ACTIVE) &&
+             (il->stations[ret].used & IL_STA_UCODE_INPROGRESS)))) {
+               IL_ERR("Requested station info for sta %d before ready.\n",
+                      ret);
+               ret = IL_INVALID_STATION;
+       }
+       spin_unlock_irqrestore(&il->sta_lock, flags);
+       return ret;
+}
+
+static int
+il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr)
+{
+       if (il->iw_mode == NL80211_IFTYPE_STATION)
+               return IL_AP_ID;
+       else {
+               u8 *da = ieee80211_get_DA(hdr);
+
+               return il4965_find_station(il, da);
+       }
+}
+
+static inline u32
+il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp)
+{
+       return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
+}
+
+static inline u32
+il4965_tx_status_to_mac80211(u32 status)
+{
+       status &= TX_STATUS_MSK;
+
+       switch (status) {
+       case TX_STATUS_SUCCESS:
+       case TX_STATUS_DIRECT_DONE:
+               return IEEE80211_TX_STAT_ACK;
+       case TX_STATUS_FAIL_DEST_PS:
+               return IEEE80211_TX_STAT_TX_FILTERED;
+       default:
+               return 0;
+       }
+}
+
+/**
+ * il4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue
+ */
+static int
+il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
+                         struct il4965_tx_resp *tx_resp, int txq_id,
+                         u16 start_idx)
+{
+       u16 status;
+       struct agg_tx_status *frame_status = tx_resp->u.agg_status;
+       struct ieee80211_tx_info *info = NULL;
+       struct ieee80211_hdr *hdr = NULL;
+       u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
+       int i, sh, idx;
+       u16 seq;
+       if (agg->wait_for_ba)
+               D_TX_REPLY("got tx response w/o block-ack\n");
+
+       agg->frame_count = tx_resp->frame_count;
+       agg->start_idx = start_idx;
+       agg->rate_n_flags = rate_n_flags;
+       agg->bitmap = 0;
+
+       /* num frames attempted by Tx command */
+       if (agg->frame_count == 1) {
+               /* Only one frame was attempted; no block-ack will arrive */
+               status = le16_to_cpu(frame_status[0].status);
+               idx = start_idx;
+
+               D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+                          agg->frame_count, agg->start_idx, idx);
+
+               info = IEEE80211_SKB_CB(il->txq[txq_id].skbs[idx]);
+               info->status.rates[0].count = tx_resp->failure_frame + 1;
+               info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+               info->flags |= il4965_tx_status_to_mac80211(status);
+               il4965_hwrate_to_tx_control(il, rate_n_flags, info);
+
+               D_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff,
+                          tx_resp->failure_frame);
+               D_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
+
+               agg->wait_for_ba = 0;
+       } else {
+               /* Two or more frames were attempted; expect block-ack */
+               u64 bitmap = 0;
+               int start = agg->start_idx;
+               struct sk_buff *skb;
+
+               /* Construct bit-map of pending frames within Tx win */
+               for (i = 0; i < agg->frame_count; i++) {
+                       u16 sc;
+                       status = le16_to_cpu(frame_status[i].status);
+                       seq = le16_to_cpu(frame_status[i].sequence);
+                       idx = SEQ_TO_IDX(seq);
+                       txq_id = SEQ_TO_QUEUE(seq);
+
+                       if (status &
+                           (AGG_TX_STATE_FEW_BYTES_MSK |
+                            AGG_TX_STATE_ABORT_MSK))
+                               continue;
+
+                       D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
+                                  agg->frame_count, txq_id, idx);
+
+                       skb = il->txq[txq_id].skbs[idx];
+                       if (WARN_ON_ONCE(skb == NULL))
+                               return -1;
+                       hdr = (struct ieee80211_hdr *) skb->data;
+
+                       sc = le16_to_cpu(hdr->seq_ctrl);
+                       if (idx != (SEQ_TO_SN(sc) & 0xff)) {
+                               IL_ERR("BUG_ON idx doesn't match seq control"
+                                      " idx=%d, seq_idx=%d, seq=%d\n", idx,
+                                      SEQ_TO_SN(sc), hdr->seq_ctrl);
+                               return -1;
+                       }
+
+                       D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx,
+                                  SEQ_TO_SN(sc));
+
+                       sh = idx - start;
+                       if (sh > 64) {
+                               sh = (start - idx) + 0xff;
+                               bitmap = bitmap << sh;
+                               sh = 0;
+                               start = idx;
+                       } else if (sh < -64)
+                               sh = 0xff - (start - idx);
+                       else if (sh < 0) {
+                               sh = start - idx;
+                               start = idx;
+                               bitmap = bitmap << sh;
+                               sh = 0;
+                       }
+                       bitmap |= 1ULL << sh;
+                       D_TX_REPLY("start=%d bitmap=0x%llx\n", start,
+                                  (unsigned long long)bitmap);
+               }
+
+               agg->bitmap = bitmap;
+               agg->start_idx = start;
+               D_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
+                          agg->frame_count, agg->start_idx,
+                          (unsigned long long)agg->bitmap);
+
+               if (bitmap)
+                       agg->wait_for_ba = 1;
+       }
+       return 0;
+}
+
+/**
+ * il4965_hdl_tx - Handle standard (non-aggregation) Tx response
+ */
+static void
+il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
+{
+       struct il_rx_pkt *pkt = rxb_addr(rxb);
+       u16 sequence = le16_to_cpu(pkt->hdr.sequence);
+       int txq_id = SEQ_TO_QUEUE(sequence);
+       int idx = SEQ_TO_IDX(sequence);
+       struct il_tx_queue *txq = &il->txq[txq_id];
+       struct sk_buff *skb;
+       struct ieee80211_hdr *hdr;
+       struct ieee80211_tx_info *info;
+       struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+       u32 status = le32_to_cpu(tx_resp->u.status);
+       int uninitialized_var(tid);
+       int sta_id;
+       int freed;
+       u8 *qc = NULL;
+       unsigned long flags;
+
+       if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) {
+               IL_ERR("Read idx for DMA queue txq_id (%d) idx %d "
+                      "is out of range [0-%d] %d %d\n", txq_id, idx,
+                      txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr);
+               return;
+       }
+
+       txq->time_stamp = jiffies;
+
+       skb = txq->skbs[txq->q.read_ptr];
+       info = IEEE80211_SKB_CB(skb);
+       memset(&info->status, 0, sizeof(info->status));
+
+       hdr = (struct ieee80211_hdr *) skb->data;
+       if (ieee80211_is_data_qos(hdr->frame_control)) {
+               qc = ieee80211_get_qos_ctl(hdr);
+               tid = qc[0] & 0xf;
+       }
+
+       sta_id = il4965_get_ra_sta_id(il, hdr);
+       if (txq->sched_retry && unlikely(sta_id == IL_INVALID_STATION)) {
+               IL_ERR("Station not known\n");
+               return;
+       }
+
+       spin_lock_irqsave(&il->sta_lock, flags);
+       if (txq->sched_retry) {
+               const u32 scd_ssn = il4965_get_scd_ssn(tx_resp);
+               struct il_ht_agg *agg = NULL;
+               WARN_ON(!qc);
+
+               agg = &il->stations[sta_id].tid[tid].agg;
+
+               il4965_tx_status_reply_tx(il, agg, tx_resp, txq_id, idx);
+
+               /* check if BAR is needed */
+               if (tx_resp->frame_count == 1 &&
+                   !il4965_is_tx_success(status))
+                       info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
+
+               if (txq->q.read_ptr != (scd_ssn & 0xff)) {
+                       idx = il_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
+                       D_TX_REPLY("Retry scheduler reclaim scd_ssn "
+                                  "%d idx %d\n", scd_ssn, idx);
+                       freed = il4965_tx_queue_reclaim(il, txq_id, idx);
+                       if (qc)
+                               il4965_free_tfds_in_queue(il, sta_id, tid,
+                                                         freed);
+
+                       if (il->mac80211_registered &&
+                           il_queue_space(&txq->q) > txq->q.low_mark &&
+                           agg->state != IL_EMPTYING_HW_QUEUE_DELBA)
+                               il_wake_queue(il, txq);
+               }
+       } else {
+               info->status.rates[0].count = tx_resp->failure_frame + 1;
+               info->flags |= il4965_tx_status_to_mac80211(status);
+               il4965_hwrate_to_tx_control(il,
+                                           le32_to_cpu(tx_resp->rate_n_flags),
+                                           info);
+
+               D_TX_REPLY("TXQ %d status %s (0x%08x) "
+                          "rate_n_flags 0x%x retries %d\n", txq_id,
+                          il4965_get_tx_fail_reason(status), status,
+                          le32_to_cpu(tx_resp->rate_n_flags),
+                          tx_resp->failure_frame);
+
+               freed = il4965_tx_queue_reclaim(il, txq_id, idx);
+               if (qc && likely(sta_id != IL_INVALID_STATION))
+                       il4965_free_tfds_in_queue(il, sta_id, tid, freed);
+               else if (sta_id == IL_INVALID_STATION)
+                       D_TX_REPLY("Station not known\n");
+
+               if (il->mac80211_registered &&
+                   il_queue_space(&txq->q) > txq->q.low_mark)
+                       il_wake_queue(il, txq);
+       }
+       if (qc && likely(sta_id != IL_INVALID_STATION))
+               il4965_txq_check_empty(il, sta_id, tid, txq_id);
+
+       il4965_check_abort_status(il, tx_resp->frame_count, status);
+
+       spin_unlock_irqrestore(&il->sta_lock, flags);
+}
+
 /**
  * translate ucode response to mac80211 tx status control values
  */
@@ -2771,8 +3047,7 @@ il4965_sta_alloc_lq(struct il_priv *il, u8 sta_id)
  * Function sleeps.
  */
 int
-il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
-                        const u8 *addr, u8 *sta_id_r)
+il4965_add_bssid_station(struct il_priv *il, const u8 *addr, u8 *sta_id_r)
 {
        int ret;
        u8 sta_id;
@@ -2782,7 +3057,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
        if (sta_id_r)
                *sta_id_r = IL_INVALID_STATION;
 
-       ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id);
+       ret = il_add_station_common(il, addr, 0, NULL, &sta_id);
        if (ret) {
                IL_ERR("Unable to add station %pM\n", addr);
                return ret;
@@ -2803,7 +3078,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
                return -ENOMEM;
        }
 
-       ret = il_send_lq_cmd(il, ctx, link_cmd, CMD_SYNC, true);
+       ret = il_send_lq_cmd(il, link_cmd, CMD_SYNC, true);
        if (ret)
                IL_ERR("Link quality command failed (%d)\n", ret);
 
@@ -2815,19 +3090,19 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
 }
 
 static int
-il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx,
-                        bool send_if_empty)
+il4965_static_wepkey_cmd(struct il_priv *il, bool send_if_empty)
 {
-       int i, not_empty = 0;
+       int i;
        u8 buff[sizeof(struct il_wep_cmd) +
                sizeof(struct il_wep_key) * WEP_KEYS_MAX];
        struct il_wep_cmd *wep_cmd = (struct il_wep_cmd *)buff;
        size_t cmd_size = sizeof(struct il_wep_cmd);
        struct il_host_cmd cmd = {
-               .id = ctx->wep_key_cmd,
+               .id = C_WEPKEY,
                .data = wep_cmd,
                .flags = CMD_SYNC,
        };
+       bool not_empty = false;
 
        might_sleep();
 
@@ -2835,24 +3110,23 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx,
               cmd_size + (sizeof(struct il_wep_key) * WEP_KEYS_MAX));
 
        for (i = 0; i < WEP_KEYS_MAX; i++) {
+               u8 key_size = il->_4965.wep_keys[i].key_size;
+
                wep_cmd->key[i].key_idx = i;
-               if (ctx->wep_keys[i].key_size) {
+               if (key_size) {
                        wep_cmd->key[i].key_offset = i;
-                       not_empty = 1;
-               } else {
+                       not_empty = true;
+               } else
                        wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
-               }
 
-               wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
-               memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
-                      ctx->wep_keys[i].key_size);
+               wep_cmd->key[i].key_size = key_size;
+               memcpy(&wep_cmd->key[i].key[3], il->_4965.wep_keys[i].key, key_size);
        }
 
        wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
        wep_cmd->num_keys = WEP_KEYS_MAX;
 
        cmd_size += sizeof(struct il_wep_key) * WEP_KEYS_MAX;
-
        cmd.len = cmd_size;
 
        if (not_empty || send_if_empty)
@@ -2862,66 +3136,66 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx,
 }
 
 int
-il4965_restore_default_wep_keys(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_restore_default_wep_keys(struct il_priv *il)
 {
        lockdep_assert_held(&il->mutex);
 
-       return il4965_static_wepkey_cmd(il, ctx, false);
+       return il4965_static_wepkey_cmd(il, false);
 }
 
 int
-il4965_remove_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_remove_default_wep_key(struct il_priv *il,
                              struct ieee80211_key_conf *keyconf)
 {
        int ret;
+       int idx = keyconf->keyidx;
 
        lockdep_assert_held(&il->mutex);
 
-       D_WEP("Removing default WEP key: idx=%d\n", keyconf->keyidx);
+       D_WEP("Removing default WEP key: idx=%d\n", idx);
 
-       memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
+       memset(&il->_4965.wep_keys[idx], 0, sizeof(struct il_wep_key));
        if (il_is_rfkill(il)) {
                D_WEP("Not sending C_WEPKEY command due to RFKILL.\n");
                /* but keys in device are clear anyway so return success */
                return 0;
        }
-       ret = il4965_static_wepkey_cmd(il, ctx, 1);
-       D_WEP("Remove default WEP key: idx=%d ret=%d\n", keyconf->keyidx, ret);
+       ret = il4965_static_wepkey_cmd(il, 1);
+       D_WEP("Remove default WEP key: idx=%d ret=%d\n", idx, ret);
 
        return ret;
 }
 
 int
-il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_set_default_wep_key(struct il_priv *il,
                           struct ieee80211_key_conf *keyconf)
 {
        int ret;
+       int len = keyconf->keylen;
+       int idx = keyconf->keyidx;
 
        lockdep_assert_held(&il->mutex);
 
-       if (keyconf->keylen != WEP_KEY_LEN_128 &&
-           keyconf->keylen != WEP_KEY_LEN_64) {
+       if (len != WEP_KEY_LEN_128 && len != WEP_KEY_LEN_64) {
                D_WEP("Bad WEP key length %d\n", keyconf->keylen);
                return -EINVAL;
        }
 
        keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
        keyconf->hw_key_idx = HW_KEY_DEFAULT;
-       il->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
+       il->stations[IL_AP_ID].keyinfo.cipher = keyconf->cipher;
 
-       ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
-       memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
-              keyconf->keylen);
+       il->_4965.wep_keys[idx].key_size = len;
+       memcpy(&il->_4965.wep_keys[idx].key, &keyconf->key, len);
 
-       ret = il4965_static_wepkey_cmd(il, ctx, false);
-       D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", keyconf->keylen,
-             keyconf->keyidx, ret);
+       ret = il4965_static_wepkey_cmd(il, false);
 
+       D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", len, idx, ret);
        return ret;
 }
 
 static int
-il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_set_wep_dynamic_key_info(struct il_priv *il,
                                struct ieee80211_key_conf *keyconf, u8 sta_id)
 {
        unsigned long flags;
@@ -2939,7 +3213,7 @@ il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx,
        if (keyconf->keylen == WEP_KEY_LEN_128)
                key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
 
-       if (sta_id == ctx->bcast_sta_id)
+       if (sta_id == il->hw_params.bcast_id)
                key_flags |= STA_KEY_MULTICAST_MSK;
 
        spin_lock_irqsave(&il->sta_lock, flags);
@@ -2976,7 +3250,6 @@ il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx,
 
 static int
 il4965_set_ccmp_dynamic_key_info(struct il_priv *il,
-                                struct il_rxon_context *ctx,
                                 struct ieee80211_key_conf *keyconf, u8 sta_id)
 {
        unsigned long flags;
@@ -2989,7 +3262,7 @@ il4965_set_ccmp_dynamic_key_info(struct il_priv *il,
        key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
        key_flags &= ~STA_KEY_FLG_INVALID;
 
-       if (sta_id == ctx->bcast_sta_id)
+       if (sta_id == il->hw_params.bcast_id)
                key_flags |= STA_KEY_MULTICAST_MSK;
 
        keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -3025,7 +3298,6 @@ il4965_set_ccmp_dynamic_key_info(struct il_priv *il,
 
 static int
 il4965_set_tkip_dynamic_key_info(struct il_priv *il,
-                                struct il_rxon_context *ctx,
                                 struct ieee80211_key_conf *keyconf, u8 sta_id)
 {
        unsigned long flags;
@@ -3036,7 +3308,7 @@ il4965_set_tkip_dynamic_key_info(struct il_priv *il,
        key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
        key_flags &= ~STA_KEY_FLG_INVALID;
 
-       if (sta_id == ctx->bcast_sta_id)
+       if (sta_id == il->hw_params.bcast_id)
                key_flags |= STA_KEY_MULTICAST_MSK;
 
        keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -3070,9 +3342,8 @@ il4965_set_tkip_dynamic_key_info(struct il_priv *il,
 }
 
 void
-il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
-                      struct ieee80211_key_conf *keyconf,
-                      struct ieee80211_sta *sta, u32 iv32, u16 * phase1key)
+il4965_update_tkip_key(struct il_priv *il, struct ieee80211_key_conf *keyconf,
+                      struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
 {
        u8 sta_id;
        unsigned long flags;
@@ -3084,7 +3355,7 @@ il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
                return;
        }
 
-       sta_id = il_sta_id_or_broadcast(il, ctx, sta);
+       sta_id = il_sta_id_or_broadcast(il, sta);
        if (sta_id == IL_INVALID_STATION)
                return;
 
@@ -3102,11 +3373,10 @@ il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
        il_send_add_sta(il, &il->stations[sta_id].sta, CMD_ASYNC);
 
        spin_unlock_irqrestore(&il->sta_lock, flags);
-
 }
 
 int
-il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_remove_dynamic_key(struct il_priv *il,
                          struct ieee80211_key_conf *keyconf, u8 sta_id)
 {
        unsigned long flags;
@@ -3116,7 +3386,7 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
 
        lockdep_assert_held(&il->mutex);
 
-       ctx->key_mapping_keys--;
+       il->_4965.key_mapping_keys--;
 
        spin_lock_irqsave(&il->sta_lock, flags);
        key_flags = le16_to_cpu(il->stations[sta_id].sta.key.key_flags);
@@ -3167,28 +3437,28 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
 }
 
 int
-il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
-                      struct ieee80211_key_conf *keyconf, u8 sta_id)
+il4965_set_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *keyconf,
+                      u8 sta_id)
 {
        int ret;
 
        lockdep_assert_held(&il->mutex);
 
-       ctx->key_mapping_keys++;
+       il->_4965.key_mapping_keys++;
        keyconf->hw_key_idx = HW_KEY_DYNAMIC;
 
        switch (keyconf->cipher) {
        case WLAN_CIPHER_SUITE_CCMP:
                ret =
-                   il4965_set_ccmp_dynamic_key_info(il, ctx, keyconf, sta_id);
+                   il4965_set_ccmp_dynamic_key_info(il, keyconf, sta_id);
                break;
        case WLAN_CIPHER_SUITE_TKIP:
                ret =
-                   il4965_set_tkip_dynamic_key_info(il, ctx, keyconf, sta_id);
+                   il4965_set_tkip_dynamic_key_info(il, keyconf, sta_id);
                break;
        case WLAN_CIPHER_SUITE_WEP40:
        case WLAN_CIPHER_SUITE_WEP104:
-               ret = il4965_set_wep_dynamic_key_info(il, ctx, keyconf, sta_id);
+               ret = il4965_set_wep_dynamic_key_info(il, keyconf, sta_id);
                break;
        default:
                IL_ERR("Unknown alg: %s cipher = %x\n", __func__,
@@ -3210,14 +3480,14 @@ il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
  * device at the next best time.
  */
 int
-il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_alloc_bcast_station(struct il_priv *il)
 {
        struct il_link_quality_cmd *link_cmd;
        unsigned long flags;
        u8 sta_id;
 
        spin_lock_irqsave(&il->sta_lock, flags);
-       sta_id = il_prep_station(il, ctx, il_bcast_addr, false, NULL);
+       sta_id = il_prep_station(il, il_bcast_addr, false, NULL);
        if (sta_id == IL_INVALID_STATION) {
                IL_ERR("Unable to prepare broadcast station\n");
                spin_unlock_irqrestore(&il->sta_lock, flags);
@@ -3250,11 +3520,11 @@ il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
  * code together.
  */
 static int
-il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_update_bcast_station(struct il_priv *il)
 {
        unsigned long flags;
        struct il_link_quality_cmd *link_cmd;
-       u8 sta_id = ctx->bcast_sta_id;
+       u8 sta_id = il->hw_params.bcast_id;
 
        link_cmd = il4965_sta_alloc_lq(il, sta_id);
        if (!link_cmd) {
@@ -3276,7 +3546,7 @@ il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
 int
 il4965_update_bcast_stations(struct il_priv *il)
 {
-       return il4965_update_bcast_station(il, &il->ctx);
+       return il4965_update_bcast_station(il);
 }
 
 /**
@@ -3376,10 +3646,10 @@ il4965_sta_modify_sleep_tx_count(struct il_priv *il, int sta_id, int cnt)
 void
 il4965_update_chain_flags(struct il_priv *il)
 {
-       if (il->cfg->ops->hcmd->set_rxon_chain) {
-               il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
-               if (il->ctx.active.rx_chain != il->ctx.staging.rx_chain)
-                       il_commit_rxon(il, &il->ctx);
+       if (il->ops->set_rxon_chain) {
+               il->ops->set_rxon_chain(il);
+               if (il->active.rx_chain != il->staging.rx_chain)
+                       il_commit_rxon(il);
        }
 }
 
@@ -3491,8 +3761,8 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame)
 
        lockdep_assert_held(&il->mutex);
 
-       if (!il->beacon_ctx) {
-               IL_ERR("trying to build beacon w/o beacon context!\n");
+       if (!il->beacon_enabled) {
+               IL_ERR("Trying to build beacon without beaconing enabled\n");
                return 0;
        }
 
@@ -3511,7 +3781,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame)
 
        /* Set up TX command fields */
        tx_beacon_cmd->tx.len = cpu_to_le16((u16) frame_size);
-       tx_beacon_cmd->tx.sta_id = il->beacon_ctx->bcast_sta_id;
+       tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id;
        tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
        tx_beacon_cmd->tx.tx_flags =
            TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK |
@@ -3522,7 +3792,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame)
                              frame_size);
 
        /* Set up packet rate and flags */
-       rate = il_get_lowest_plcp(il, il->beacon_ctx);
+       rate = il_get_lowest_plcp(il);
        il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant);
        rate_flags = BIT(il->mgmt_tx_ant) << RATE_MCS_ANT_POS;
        if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE))
@@ -3645,15 +3915,13 @@ il4965_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)
                                 PCI_DMA_TODEVICE);
 
        /* free SKB */
-       if (txq->txb) {
-               struct sk_buff *skb;
-
-               skb = txq->txb[txq->q.read_ptr].skb;
+       if (txq->skbs) {
+               struct sk_buff *skb = txq->skbs[txq->q.read_ptr];
 
                /* can be called from irqs-disabled context */
                if (skb) {
                        dev_kfree_skb_any(skb);
-                       txq->txb[txq->q.read_ptr].skb = NULL;
+                       txq->skbs[txq->q.read_ptr] = NULL;
                }
        }
 }
@@ -3752,9 +4020,9 @@ il4965_hdl_alive(struct il_priv *il, struct il_rx_buf *rxb)
  * This callback is provided in order to send a stats request.
  *
  * This timer function is continually reset to execute within
- * REG_RECALIB_PERIOD seconds since the last N_STATS
- * was received.  We need to ensure we receive the stats in order
- * to update the temperature used for calibrating the TXPOWER.
+ * 60 seconds since the last N_STATS was received.  We need to
+ * ensure we receive the stats in order to update the temperature
+ * used for calibrating the TXPOWER.
  */
 static void
 il4965_bg_stats_periodic(unsigned long data)
@@ -3804,7 +4072,7 @@ il4965_perform_ct_kill_task(struct il_priv *il)
        _il_rd(il, CSR_UCODE_DRV_GP1);
 
        spin_lock_irqsave(&il->reg_lock, flags);
-       if (!_il_grab_nic_access(il))
+       if (likely(_il_grab_nic_access(il)))
                _il_release_nic_access(il);
        spin_unlock_irqrestore(&il->reg_lock, flags);
 }
@@ -3842,17 +4110,17 @@ il4965_hdl_card_state(struct il_priv *il, struct il_rx_buf *rxb)
                il4965_perform_ct_kill_task(il);
 
        if (flags & HW_CARD_DISABLED)
-               set_bit(S_RF_KILL_HW, &il->status);
+               set_bit(S_RFKILL, &il->status);
        else
-               clear_bit(S_RF_KILL_HW, &il->status);
+               clear_bit(S_RFKILL, &il->status);
 
        if (!(flags & RXON_CARD_DISABLED))
                il_scan_cancel(il);
 
-       if ((test_bit(S_RF_KILL_HW, &status) !=
-            test_bit(S_RF_KILL_HW, &il->status)))
+       if ((test_bit(S_RFKILL, &status) !=
+            test_bit(S_RFKILL, &il->status)))
                wiphy_rfkill_set_hw_state(il->hw->wiphy,
-                                         test_bit(S_RF_KILL_HW, &il->status));
+                                         test_bit(S_RFKILL, &il->status));
        else
                wake_up(&il->wait_command_queue);
 }
@@ -3894,10 +4162,11 @@ il4965_setup_handlers(struct il_priv *il)
        /* Rx handlers */
        il->handlers[N_RX_PHY] = il4965_hdl_rx_phy;
        il->handlers[N_RX_MPDU] = il4965_hdl_rx;
+       il->handlers[N_RX] = il4965_hdl_rx;
        /* block ack */
        il->handlers[N_COMPRESSED_BA] = il4965_hdl_compressed_ba;
-       /* Set up hardware specific Rx handlers */
-       il->cfg->ops->lib->handler_setup(il);
+       /* Tx response */
+       il->handlers[C_TX] = il4965_hdl_tx;
 }
 
 /**
@@ -4127,9 +4396,8 @@ il4965_irq_tasklet(struct il_priv *il)
        /* HW RF KILL switch toggled */
        if (inta & CSR_INT_BIT_RF_KILL) {
                int hw_rf_kill = 0;
-               if (!
-                   (_il_rd(il, CSR_GP_CNTRL) &
-                    CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
+
+               if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
                        hw_rf_kill = 1;
 
                IL_WARN("RF_KILL bit toggled to %s.\n",
@@ -4144,9 +4412,9 @@ il4965_irq_tasklet(struct il_priv *il)
                 */
                if (!test_bit(S_ALIVE, &il->status)) {
                        if (hw_rf_kill)
-                               set_bit(S_RF_KILL_HW, &il->status);
+                               set_bit(S_RFKILL, &il->status);
                        else
-                               clear_bit(S_RF_KILL_HW, &il->status);
+                               clear_bit(S_RFKILL, &il->status);
                        wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
                }
 
@@ -4270,11 +4538,9 @@ il4965_store_debug_level(struct device *d, struct device_attribute *attr,
        ret = strict_strtoul(buf, 0, &val);
        if (ret)
                IL_ERR("%s is not in hex or decimal form.\n", buf);
-       else {
+       else
                il->debug_level = val;
-               if (il_alloc_traffic_mem(il))
-                       IL_ERR("Not enough memory to generate traffic log\n");
-       }
+
        return strnlen(buf, count);
 }
 
@@ -4799,7 +5065,7 @@ il4965_dump_nic_error_log(struct il_priv *il)
        else
                base = le32_to_cpu(il->card_alive.error_event_table_ptr);
 
-       if (!il->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+       if (!il->ops->is_valid_rtc_data_addr(base)) {
                IL_ERR("Not valid error log pointer 0x%08X for %s uCode\n",
                       base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT");
                return;
@@ -4979,7 +5245,6 @@ static void
 il4965_alive_start(struct il_priv *il)
 {
        int ret = 0;
-       struct il_rxon_context *ctx = &il->ctx;
 
        D_INFO("Runtime Alive received.\n");
 
@@ -5019,18 +5284,18 @@ il4965_alive_start(struct il_priv *il)
 
        il->active_rate = RATES_MASK;
 
-       if (il_is_associated_ctx(ctx)) {
+       if (il_is_associated(il)) {
                struct il_rxon_cmd *active_rxon =
-                   (struct il_rxon_cmd *)&ctx->active;
+                   (struct il_rxon_cmd *)&il->active;
                /* apply any changes in staging */
-               ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+               il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        } else {
                /* Initialize our rx_config data */
-               il_connection_init_rx_config(il, &il->ctx);
+               il_connection_init_rx_config(il);
 
-               if (il->cfg->ops->hcmd->set_rxon_chain)
-                       il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+               if (il->ops->set_rxon_chain)
+                       il->ops->set_rxon_chain(il);
        }
 
        /* Configure bluetooth coexistence if enabled */
@@ -5041,7 +5306,7 @@ il4965_alive_start(struct il_priv *il)
        set_bit(S_READY, &il->status);
 
        /* Configure the adapter for unassociated operation */
-       il_commit_rxon(il, ctx);
+       il_commit_rxon(il);
 
        /* At this point, the NIC is initialized and operational */
        il4965_rf_kill_ct_config(il);
@@ -5076,7 +5341,21 @@ __il4965_down(struct il_priv *il)
         * to prevent rearm timer */
        del_timer_sync(&il->watchdog);
 
-       il_clear_ucode_stations(il, NULL);
+       il_clear_ucode_stations(il);
+
+       /* FIXME: race conditions ? */
+       spin_lock_irq(&il->sta_lock);
+       /*
+        * Remove all key information that is not stored as part
+        * of station information since mac80211 may not have had
+        * a chance to remove all the keys. When device is
+        * reconfigured by mac80211 after an error all keys will
+        * be reconfigured.
+        */
+       memset(il->_4965.wep_keys, 0, sizeof(il->_4965.wep_keys));
+       il->_4965.key_mapping_keys = 0;
+       spin_unlock_irq(&il->sta_lock);
+
        il_dealloc_bcast_stations(il);
        il_clear_driver_stations(il);
 
@@ -5104,12 +5383,8 @@ __il4965_down(struct il_priv *il)
         * clear all bits but the RF Kill bit and return */
        if (!il_is_init(il)) {
                il->status =
-                   test_bit(S_RF_KILL_HW,
-                            &il->
-                            status) << S_RF_KILL_HW |
-                   test_bit(S_GEO_CONFIGURED,
-                            &il->
-                            status) << S_GEO_CONFIGURED |
+                   test_bit(S_RFKILL, &il->status) << S_RFKILL |
+                   test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
                    test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
                goto exit;
        }
@@ -5117,28 +5392,32 @@ __il4965_down(struct il_priv *il)
        /* ...otherwise clear out all the status bits but the RF Kill
         * bit and continue taking the NIC down. */
        il->status &=
-           test_bit(S_RF_KILL_HW,
-                    &il->status) << S_RF_KILL_HW | test_bit(S_GEO_CONFIGURED,
-                                                            &il->
-                                                            status) <<
-           S_GEO_CONFIGURED | test_bit(S_FW_ERROR,
-                                       &il->
-                                       status) << S_FW_ERROR |
+           test_bit(S_RFKILL, &il->status) << S_RFKILL |
+           test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
+           test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
            test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
 
+       /*
+        * We disabled and synchronized interrupt, and priv->mutex is taken, so
+        * here is the only thread which will program device registers, but
+        * still have lockdep assertions, so we are taking reg_lock.
+        */
+       spin_lock_irq(&il->reg_lock);
+       /* FIXME: il_grab_nic_access if rfkill is off ? */
+
        il4965_txq_ctx_stop(il);
        il4965_rxq_stop(il);
-
        /* Power-down device's busmaster DMA clocks */
-       il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+       _il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
        udelay(5);
-
        /* Make sure (redundant) we've released our request to stay awake */
-       il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
+       _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
        /* Stop the device, and put it in low power state */
-       il_apm_stop(il);
+       _il_apm_stop(il);
+
+       spin_unlock_irq(&il->reg_lock);
 
+       il4965_txq_ctx_unmap(il);
 exit:
        memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
 
@@ -5159,40 +5438,36 @@ il4965_down(struct il_priv *il)
        il4965_cancel_deferred_work(il);
 }
 
-#define HW_READY_TIMEOUT (50)
 
-static int
+static void
 il4965_set_hw_ready(struct il_priv *il)
 {
-       int ret = 0;
+       int ret;
 
        il_set_bit(il, CSR_HW_IF_CONFIG_REG,
                   CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
 
        /* See if we got it */
-       ret =
-           _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
-                        CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
-                        CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, HW_READY_TIMEOUT);
-       if (ret != -ETIMEDOUT)
+       ret = _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
+                          CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+                          CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+                          100);
+       if (ret >= 0)
                il->hw_ready = true;
-       else
-               il->hw_ready = false;
 
-       D_INFO("hardware %s\n", (il->hw_ready == 1) ? "ready" : "not ready");
-       return ret;
+       D_INFO("hardware %s ready\n", (il->hw_ready) ? "" : "not");
 }
 
-static int
+static void
 il4965_prepare_card_hw(struct il_priv *il)
 {
-       int ret = 0;
+       int ret;
 
-       D_INFO("il4965_prepare_card_hw enter\n");
+       il->hw_ready = false;
 
-       ret = il4965_set_hw_ready(il);
+       il4965_set_hw_ready(il);
        if (il->hw_ready)
-               return ret;
+               return;
 
        /* If HW is not ready, prepare the conditions to check again */
        il_set_bit(il, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE);
@@ -5205,8 +5480,6 @@ il4965_prepare_card_hw(struct il_priv *il)
        /* HW should be ready by now, check again. */
        if (ret != -ETIMEDOUT)
                il4965_set_hw_ready(il);
-
-       return ret;
 }
 
 #define MAX_HW_RESTARTS 5
@@ -5227,29 +5500,26 @@ __il4965_up(struct il_priv *il)
                return -EIO;
        }
 
-       ret = il4965_alloc_bcast_station(il, &il->ctx);
+       ret = il4965_alloc_bcast_station(il);
        if (ret) {
                il_dealloc_bcast_stations(il);
                return ret;
        }
 
        il4965_prepare_card_hw(il);
-
        if (!il->hw_ready) {
-               IL_WARN("Exit HW not ready\n");
+               IL_ERR("HW not ready\n");
                return -EIO;
        }
 
        /* If platform's RF_KILL switch is NOT set to KILL */
        if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-               clear_bit(S_RF_KILL_HW, &il->status);
-       else
-               set_bit(S_RF_KILL_HW, &il->status);
-
-       if (il_is_rfkill(il)) {
+               clear_bit(S_RFKILL, &il->status);
+       else {
+               set_bit(S_RFKILL, &il->status);
                wiphy_rfkill_set_hw_state(il->hw->wiphy, true);
 
-               il_enable_interrupts(il);
+               il_enable_rfkill_int(il);
                IL_WARN("Radio disabled by HW RF Kill switch\n");
                return 0;
        }
@@ -5288,7 +5558,7 @@ __il4965_up(struct il_priv *il)
                /* load bootstrap state machine,
                 * load bootstrap program into processor's memory,
                 * prepare to load the "initialize" uCode */
-               ret = il->cfg->ops->lib->load_ucode(il);
+               ret = il->ops->load_ucode(il);
 
                if (ret) {
                        IL_ERR("Unable to set up bootstrap uCode: %d\n", ret);
@@ -5329,7 +5599,7 @@ il4965_bg_init_alive_start(struct work_struct *data)
        if (test_bit(S_EXIT_PENDING, &il->status))
                goto out;
 
-       il->cfg->ops->lib->init_alive_start(il);
+       il->ops->init_alive_start(il);
 out:
        mutex_unlock(&il->mutex);
 }
@@ -5381,7 +5651,8 @@ il4965_bg_restart(struct work_struct *data)
 
        if (test_and_clear_bit(S_FW_ERROR, &il->status)) {
                mutex_lock(&il->mutex);
-               il->ctx.vif = NULL;
+               /* FIXME: do we dereference vif without mutex locked ? */
+               il->vif = NULL;
                il->is_open = 0;
 
                __il4965_down(il);
@@ -5450,8 +5721,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
        hw->sta_data_size = sizeof(struct il_station_priv);
        hw->vif_data_size = sizeof(struct il_vif_priv);
 
-       hw->wiphy->interface_modes |= il->ctx.interface_modes;
-       hw->wiphy->interface_modes |= il->ctx.exclusive_interface_modes;
+       hw->wiphy->interface_modes =
+           BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
 
        hw->wiphy->flags |=
            WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS;
@@ -5578,12 +5849,10 @@ il4965_mac_update_tkip_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                           struct ieee80211_sta *sta, u32 iv32, u16 * phase1key)
 {
        struct il_priv *il = hw->priv;
-       struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
 
        D_MAC80211("enter\n");
 
-       il4965_update_tkip_key(il, vif_priv->ctx, keyconf, sta, iv32,
-                              phase1key);
+       il4965_update_tkip_key(il, keyconf, sta, iv32, phase1key);
 
        D_MAC80211("leave\n");
 }
@@ -5594,8 +5863,6 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                   struct ieee80211_key_conf *key)
 {
        struct il_priv *il = hw->priv;
-       struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
-       struct il_rxon_context *ctx = vif_priv->ctx;
        int ret;
        u8 sta_id;
        bool is_default_wep_key = false;
@@ -5607,7 +5874,7 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                return -EOPNOTSUPP;
        }
 
-       sta_id = il_sta_id_or_broadcast(il, vif_priv->ctx, sta);
+       sta_id = il_sta_id_or_broadcast(il, sta);
        if (sta_id == IL_INVALID_STATION)
                return -EINVAL;
 
@@ -5623,7 +5890,7 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
             key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) {
                if (cmd == SET_KEY)
-                       is_default_wep_key = !ctx->key_mapping_keys;
+                       is_default_wep_key = !il->_4965.key_mapping_keys;
                else
                        is_default_wep_key =
                            (key->hw_key_idx == HW_KEY_DEFAULT);
@@ -5632,20 +5899,17 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        switch (cmd) {
        case SET_KEY:
                if (is_default_wep_key)
-                       ret =
-                           il4965_set_default_wep_key(il, vif_priv->ctx, key);
+                       ret = il4965_set_default_wep_key(il, key);
                else
-                       ret =
-                           il4965_set_dynamic_key(il, vif_priv->ctx, key,
-                                                  sta_id);
+                       ret = il4965_set_dynamic_key(il, key, sta_id);
 
                D_MAC80211("enable hwcrypto key\n");
                break;
        case DISABLE_KEY:
                if (is_default_wep_key)
-                       ret = il4965_remove_default_wep_key(il, ctx, key);
+                       ret = il4965_remove_default_wep_key(il, key);
                else
-                       ret = il4965_remove_dynamic_key(il, ctx, key, sta_id);
+                       ret = il4965_remove_dynamic_key(il, key, sta_id);
 
                D_MAC80211("disable hwcrypto key\n");
                break;
@@ -5711,7 +5975,6 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 {
        struct il_priv *il = hw->priv;
        struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
        bool is_ap = vif->type == NL80211_IFTYPE_STATION;
        int ret;
        u8 sta_id;
@@ -5724,8 +5987,7 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        atomic_set(&sta_priv->pending_frames, 0);
 
        ret =
-           il_add_station_common(il, vif_priv->ctx, sta->addr, is_ap, sta,
-                                 &sta_id);
+           il_add_station_common(il, sta->addr, is_ap, sta, &sta_id);
        if (ret) {
                IL_ERR("Unable to add station %pM (%d)\n", sta->addr, ret);
                /* Should we return success if return code is EEXIST ? */
@@ -5752,8 +6014,6 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
        struct ieee80211_conf *conf = &hw->conf;
        struct ieee80211_channel *channel = ch_switch->channel;
        struct il_ht_config *ht_conf = &il->current_ht_config;
-
-       struct il_rxon_context *ctx = &il->ctx;
        u16 ch;
 
        D_MAC80211("enter\n");
@@ -5768,14 +6028,14 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
            test_bit(S_CHANNEL_SWITCH_PENDING, &il->status))
                goto out;
 
-       if (!il_is_associated_ctx(ctx))
+       if (!il_is_associated(il))
                goto out;
 
-       if (!il->cfg->ops->lib->set_channel_switch)
+       if (!il->ops->set_channel_switch)
                goto out;
 
        ch = channel->hw_value;
-       if (le16_to_cpu(ctx->active.channel) == ch)
+       if (le16_to_cpu(il->active.channel) == ch)
                goto out;
 
        ch_info = il_get_channel_info(il, channel->band, ch);
@@ -5789,30 +6049,30 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
        il->current_ht_config.smps = conf->smps_mode;
 
        /* Configure HT40 channels */
-       ctx->ht.enabled = conf_is_ht(conf);
-       if (ctx->ht.enabled) {
+       il->ht.enabled = conf_is_ht(conf);
+       if (il->ht.enabled) {
                if (conf_is_ht40_minus(conf)) {
-                       ctx->ht.extension_chan_offset =
+                       il->ht.extension_chan_offset =
                            IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-                       ctx->ht.is_40mhz = true;
+                       il->ht.is_40mhz = true;
                } else if (conf_is_ht40_plus(conf)) {
-                       ctx->ht.extension_chan_offset =
+                       il->ht.extension_chan_offset =
                            IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-                       ctx->ht.is_40mhz = true;
+                       il->ht.is_40mhz = true;
                } else {
-                       ctx->ht.extension_chan_offset =
+                       il->ht.extension_chan_offset =
                            IEEE80211_HT_PARAM_CHA_SEC_NONE;
-                       ctx->ht.is_40mhz = false;
+                       il->ht.is_40mhz = false;
                }
        } else
-               ctx->ht.is_40mhz = false;
+               il->ht.is_40mhz = false;
 
-       if ((le16_to_cpu(ctx->staging.channel) != ch))
-               ctx->staging.flags = 0;
+       if ((le16_to_cpu(il->staging.channel) != ch))
+               il->staging.flags = 0;
 
-       il_set_rxon_channel(il, channel, ctx);
+       il_set_rxon_channel(il, channel);
        il_set_rxon_ht(il, ht_conf);
-       il_set_flags_for_band(il, ctx, channel->band, ctx->vif);
+       il_set_flags_for_band(il, channel->band, il->vif);
 
        spin_unlock_irq(&il->lock);
 
@@ -5823,10 +6083,10 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
         */
        set_bit(S_CHANNEL_SWITCH_PENDING, &il->status);
        il->switch_channel = cpu_to_le16(ch);
-       if (il->cfg->ops->lib->set_channel_switch(il, ch_switch)) {
+       if (il->ops->set_channel_switch(il, ch_switch)) {
                clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status);
                il->switch_channel = 0;
-               ieee80211_chswitch_done(ctx->vif, false);
+               ieee80211_chswitch_done(il->vif, false);
        }
 
 out:
@@ -5860,8 +6120,8 @@ il4965_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 
        mutex_lock(&il->mutex);
 
-       il->ctx.staging.filter_flags &= ~filter_nand;
-       il->ctx.staging.filter_flags |= filter_or;
+       il->staging.filter_flags &= ~filter_nand;
+       il->staging.filter_flags |= filter_or;
 
        /*
         * Not committing directly because hardware can perform a scan,
@@ -5906,7 +6166,7 @@ il4965_bg_txpower_work(struct work_struct *work)
        /* Regardless of if we are associated, we must reconfigure the
         * TX power since frames can be sent on non-radar channels while
         * not associated */
-       il->cfg->ops->lib->send_tx_power(il);
+       il->ops->send_tx_power(il);
 
        /* Update last_temperature to keep is_calib_needed from running
         * when it isn't needed... */
@@ -6012,6 +6272,28 @@ il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq,
               scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
 }
 
+const struct ieee80211_ops il4965_mac_ops = {
+       .tx = il4965_mac_tx,
+       .start = il4965_mac_start,
+       .stop = il4965_mac_stop,
+       .add_interface = il_mac_add_interface,
+       .remove_interface = il_mac_remove_interface,
+       .change_interface = il_mac_change_interface,
+       .config = il_mac_config,
+       .configure_filter = il4965_configure_filter,
+       .set_key = il4965_mac_set_key,
+       .update_tkip_key = il4965_mac_update_tkip_key,
+       .conf_tx = il_mac_conf_tx,
+       .reset_tsf = il_mac_reset_tsf,
+       .bss_info_changed = il_mac_bss_info_changed,
+       .ampdu_action = il4965_mac_ampdu_action,
+       .hw_scan = il_mac_hw_scan,
+       .sta_add = il4965_mac_sta_add,
+       .sta_remove = il_mac_sta_remove,
+       .channel_switch = il4965_mac_channel_switch,
+       .tx_last_beacon = il_mac_tx_last_beacon,
+};
+
 static int
 il4965_init_drv(struct il_priv *il)
 {
@@ -6036,8 +6318,8 @@ il4965_init_drv(struct il_priv *il)
        il->force_reset.reset_duration = IL_DELAY_NEXT_FORCE_FW_RELOAD;
 
        /* Choose which receivers/antennas to use */
-       if (il->cfg->ops->hcmd->set_rxon_chain)
-               il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
+       if (il->ops->set_rxon_chain)
+               il->ops->set_rxon_chain(il);
 
        il_init_scan_params(il);
 
@@ -6065,7 +6347,6 @@ err:
 static void
 il4965_uninit_drv(struct il_priv *il)
 {
-       il4965_calib_free_results(il);
        il_free_geos(il);
        il_free_channel_map(il);
        kfree(il->scan_cmd);
@@ -6080,9 +6361,37 @@ il4965_hw_detect(struct il_priv *il)
        D_INFO("HW Revision ID = 0x%X\n", il->rev_id);
 }
 
-static int
+static struct il_sensitivity_ranges il4965_sensitivity = {
+       .min_nrg_cck = 97,
+       .max_nrg_cck = 0,       /* not used, set to 0 */
+
+       .auto_corr_min_ofdm = 85,
+       .auto_corr_min_ofdm_mrc = 170,
+       .auto_corr_min_ofdm_x1 = 105,
+       .auto_corr_min_ofdm_mrc_x1 = 220,
+
+       .auto_corr_max_ofdm = 120,
+       .auto_corr_max_ofdm_mrc = 210,
+       .auto_corr_max_ofdm_x1 = 140,
+       .auto_corr_max_ofdm_mrc_x1 = 270,
+
+       .auto_corr_min_cck = 125,
+       .auto_corr_max_cck = 200,
+       .auto_corr_min_cck_mrc = 200,
+       .auto_corr_max_cck_mrc = 400,
+
+       .nrg_th_cck = 100,
+       .nrg_th_ofdm = 100,
+
+       .barker_corr_th_min = 190,
+       .barker_corr_th_min_mrc = 390,
+       .nrg_th_cca = 62,
+};
+
+static void
 il4965_set_hw_params(struct il_priv *il)
 {
+       il->hw_params.bcast_id = IL4965_BROADCAST_ID;
        il->hw_params.max_rxq_size = RX_QUEUE_SIZE;
        il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
        if (il->cfg->mod_params->amsdu_size_8K)
@@ -6095,20 +6404,37 @@ il4965_set_hw_params(struct il_priv *il)
        if (il->cfg->mod_params->disable_11n)
                il->cfg->sku &= ~IL_SKU_N;
 
-       /* Device-specific setup */
-       return il->cfg->ops->lib->set_hw_params(il);
-}
+       if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES &&
+           il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES)
+               il->cfg->num_of_queues =
+                   il->cfg->mod_params->num_of_queues;
 
-static const u8 il4965_bss_ac_to_fifo[] = {
-       IL_TX_FIFO_VO,
-       IL_TX_FIFO_VI,
-       IL_TX_FIFO_BE,
-       IL_TX_FIFO_BK,
-};
+       il->hw_params.max_txq_num = il->cfg->num_of_queues;
+       il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
+       il->hw_params.scd_bc_tbls_size =
+           il->cfg->num_of_queues *
+           sizeof(struct il4965_scd_bc_tbl);
 
-static const u8 il4965_bss_ac_to_queue[] = {
-       0, 1, 2, 3,
-};
+       il->hw_params.tfd_size = sizeof(struct il_tfd);
+       il->hw_params.max_stations = IL4965_STATION_COUNT;
+       il->hw_params.max_data_size = IL49_RTC_DATA_SIZE;
+       il->hw_params.max_inst_size = IL49_RTC_INST_SIZE;
+       il->hw_params.max_bsm_size = BSM_SRAM_SIZE;
+       il->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ);
+
+       il->hw_params.rx_wrt_ptr_reg = FH49_RSCSR_CHNL0_WPTR;
+
+       il->hw_params.tx_chains_num = il4965_num_of_ant(il->cfg->valid_tx_ant);
+       il->hw_params.rx_chains_num = il4965_num_of_ant(il->cfg->valid_rx_ant);
+       il->hw_params.valid_tx_ant = il->cfg->valid_tx_ant;
+       il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant;
+
+       il->hw_params.ct_kill_threshold =
+          CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY);
+
+       il->hw_params.sens = &il4965_sensitivity;
+       il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS;
+}
 
 static int
 il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -6124,43 +6450,24 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * 1. Allocating HW data
         ************************/
 
-       hw = il_alloc_all(cfg);
+       hw = ieee80211_alloc_hw(sizeof(struct il_priv), &il4965_mac_ops);
        if (!hw) {
                err = -ENOMEM;
                goto out;
        }
        il = hw->priv;
-       /* At this point both hw and il are allocated. */
-
-       il->ctx.ctxid = 0;
-
-       il->ctx.always_active = true;
-       il->ctx.is_active = true;
-       il->ctx.rxon_cmd = C_RXON;
-       il->ctx.rxon_timing_cmd = C_RXON_TIMING;
-       il->ctx.rxon_assoc_cmd = C_RXON_ASSOC;
-       il->ctx.qos_cmd = C_QOS_PARAM;
-       il->ctx.ap_sta_id = IL_AP_ID;
-       il->ctx.wep_key_cmd = C_WEPKEY;
-       il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo;
-       il->ctx.ac_to_queue = il4965_bss_ac_to_queue;
-       il->ctx.exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC);
-       il->ctx.interface_modes = BIT(NL80211_IFTYPE_STATION);
-       il->ctx.ap_devtype = RXON_DEV_TYPE_AP;
-       il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS;
-       il->ctx.station_devtype = RXON_DEV_TYPE_ESS;
-       il->ctx.unused_devtype = RXON_DEV_TYPE_ESS;
-
+       il->hw = hw;
        SET_IEEE80211_DEV(hw, &pdev->dev);
 
        D_INFO("*** LOAD DRIVER ***\n");
        il->cfg = cfg;
+       il->ops = &il4965_ops;
+#ifdef CONFIG_IWLEGACY_DEBUGFS
+       il->debugfs_ops = &il4965_debugfs_ops;
+#endif
        il->pci_dev = pdev;
        il->inta_mask = CSR_INI_SET_MASK;
 
-       if (il_alloc_traffic_mem(il))
-               IL_ERR("Not enough memory to generate traffic log\n");
-
        /**************************
         * 2. Initializing PCI bus
         **************************/
@@ -6199,7 +6506,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        /***********************
         * 3. Read REV register
         ***********************/
-       il->hw_base = pci_iomap(pdev, 0, 0);
+       il->hw_base = pci_ioremap_bar(pdev, 0);
        if (!il->hw_base) {
                err = -ENODEV;
                goto out_pci_release_regions;
@@ -6260,10 +6567,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        /************************
         * 5. Setup HW constants
         ************************/
-       if (il4965_set_hw_params(il)) {
-               IL_ERR("failed to set hw parameters\n");
-               goto out_free_eeprom;
-       }
+       il4965_set_hw_params(il);
 
        /*******************
         * 6. Setup il
@@ -6307,12 +6611,12 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* If platform's RF_KILL switch is NOT set to KILL */
        if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-               clear_bit(S_RF_KILL_HW, &il->status);
+               clear_bit(S_RFKILL, &il->status);
        else
-               set_bit(S_RF_KILL_HW, &il->status);
+               set_bit(S_RFKILL, &il->status);
 
        wiphy_rfkill_set_hw_state(il->hw->wiphy,
-                                 test_bit(S_RF_KILL_HW, &il->status));
+                                 test_bit(S_RFKILL, &il->status));
 
        il_power_initialize(il);
 
@@ -6334,14 +6638,13 @@ out_disable_msi:
 out_free_eeprom:
        il_eeprom_free(il);
 out_iounmap:
-       pci_iounmap(pdev, il->hw_base);
+       iounmap(il->hw_base);
 out_pci_release_regions:
        pci_set_drvdata(pdev, NULL);
        pci_release_regions(pdev);
 out_pci_disable_device:
        pci_disable_device(pdev);
 out_ieee80211_free_hw:
-       il_free_traffic_mem(il);
        ieee80211_free_hw(il->hw);
 out:
        return err;
@@ -6412,11 +6715,10 @@ il4965_pci_remove(struct pci_dev *pdev)
         * until now... */
        destroy_workqueue(il->workqueue);
        il->workqueue = NULL;
-       il_free_traffic_mem(il);
 
        free_irq(il->pci_dev->irq, il);
        pci_disable_msi(il->pci_dev);
-       pci_iounmap(pdev, il->hw_base);
+       iounmap(il->hw_base);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
index 467d0cb14ecdf56213839126ac08ac8c03668834..d7e2856e41d3b0e90929d605096e9e40932f95ee 100644 (file)
@@ -641,13 +641,10 @@ il4965_rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
  * there are no non-GF stations present in the BSS.
  */
 static bool
-il4965_rs_use_green(struct ieee80211_sta *sta)
+il4965_rs_use_green(struct il_priv *il, struct ieee80211_sta *sta)
 {
-       struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct il_rxon_context *ctx = sta_priv->common.ctx;
-
        return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
-           !(ctx->ht.non_gf_sta_present);
+              !il->ht.non_gf_sta_present;
 }
 
 /**
@@ -823,8 +820,6 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband,
        u32 tx_rate;
        struct il_scale_tbl_info tbl_type;
        struct il_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
-       struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct il_rxon_context *ctx = sta_priv->common.ctx;
 
        D_RATE("get frame ack response, update rate scale win\n");
 
@@ -892,7 +887,7 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband,
                lq_sta->missed_rate_counter++;
                if (lq_sta->missed_rate_counter > IL_MISSED_RATE_MAX) {
                        lq_sta->missed_rate_counter = 0;
-                       il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false);
+                       il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false);
                }
                /* Regardless, ignore this status info for outdated rate */
                return;
@@ -1184,8 +1179,6 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta,
        u16 rate_mask;
        s32 rate;
        s8 is_green = lq_sta->is_green;
-       struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct il_rxon_context *ctx = sta_priv->common.ctx;
 
        if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
                return -1;
@@ -1206,7 +1199,7 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta,
        tbl->max_search = IL_MAX_SEARCH;
        rate_mask = lq_sta->active_mimo2_rate;
 
-       if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))
+       if (il_is_ht40_tx_allowed(il, &sta->ht_cap))
                tbl->is_ht40 = 1;
        else
                tbl->is_ht40 = 0;
@@ -1240,8 +1233,6 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta,
        u16 rate_mask;
        u8 is_green = lq_sta->is_green;
        s32 rate;
-       struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct il_rxon_context *ctx = sta_priv->common.ctx;
 
        if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
                return -1;
@@ -1254,7 +1245,7 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta,
        tbl->max_search = IL_MAX_SEARCH;
        rate_mask = lq_sta->active_siso_rate;
 
-       if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))
+       if (il_is_ht40_tx_allowed(il, &sta->ht_cap))
                tbl->is_ht40 = 1;
        else
                tbl->is_ht40 = 0;
@@ -1733,8 +1724,7 @@ il4965_rs_stay_in_table(struct il_lq_sta *lq_sta, bool force_search)
  * setup rate table in uCode
  */
 static void
-il4965_rs_update_rate_tbl(struct il_priv *il, struct il_rxon_context *ctx,
-                         struct il_lq_sta *lq_sta,
+il4965_rs_update_rate_tbl(struct il_priv *il, struct il_lq_sta *lq_sta,
                          struct il_scale_tbl_info *tbl, int idx, u8 is_green)
 {
        u32 rate;
@@ -1742,7 +1732,7 @@ il4965_rs_update_rate_tbl(struct il_priv *il, struct il_rxon_context *ctx,
        /* Update uCode's rate table. */
        rate = il4965_rate_n_flags_from_tbl(il, tbl, idx, is_green);
        il4965_rs_fill_link_cmd(il, lq_sta, rate);
-       il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false);
+       il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false);
 }
 
 /*
@@ -1778,8 +1768,6 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
        s32 sr;
        u8 tid = MAX_TID_COUNT;
        struct il_tid_data *tid_data;
-       struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct il_rxon_context *ctx = sta_priv->common.ctx;
 
        D_RATE("rate scale calculate new rate for skb\n");
 
@@ -1815,7 +1803,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
        if (is_legacy(tbl->lq_type))
                lq_sta->is_green = 0;
        else
-               lq_sta->is_green = il4965_rs_use_green(sta);
+               lq_sta->is_green = il4965_rs_use_green(il, sta);
        is_green = lq_sta->is_green;
 
        /* current tx rate */
@@ -1854,7 +1842,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
                        tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
                        /* get "active" rate info */
                        idx = il4965_hwrate_to_plcp_idx(tbl->current_rate);
-                       il4965_rs_update_rate_tbl(il, ctx, lq_sta, tbl, idx,
+                       il4965_rs_update_rate_tbl(il, lq_sta, tbl, idx,
                                                      is_green);
                }
                return;
@@ -2057,8 +2045,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
 lq_update:
        /* Replace uCode's rate table for the destination station. */
        if (update_lq)
-               il4965_rs_update_rate_tbl(il, ctx, lq_sta, tbl, idx,
-                                             is_green);
+               il4965_rs_update_rate_tbl(il, lq_sta, tbl, idx, is_green);
 
        /* Should we stay with this modulation mode,
         * or search for a new one? */
@@ -2098,7 +2085,7 @@ lq_update:
                        D_RATE("Switch current  mcs: %X idx: %d\n",
                               tbl->current_rate, idx);
                        il4965_rs_fill_link_cmd(il, lq_sta, tbl->current_rate);
-                       il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false);
+                       il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false);
                } else
                        done_search = 1;
        }
@@ -2166,17 +2153,15 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf,
        int rate_idx;
        int i;
        u32 rate;
-       u8 use_green = il4965_rs_use_green(sta);
+       u8 use_green = il4965_rs_use_green(il, sta);
        u8 active_tbl = 0;
        u8 valid_tx_ant;
        struct il_station_priv *sta_priv;
-       struct il_rxon_context *ctx;
 
        if (!sta || !lq_sta)
                return;
 
        sta_priv = (void *)sta->drv_priv;
-       ctx = sta_priv->common.ctx;
 
        i = lq_sta->last_txrate_idx;
 
@@ -2208,7 +2193,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf,
        il4965_rs_set_expected_tpt_table(lq_sta, tbl);
        il4965_rs_fill_link_cmd(NULL, lq_sta, rate);
        il->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;
-       il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_SYNC, true);
+       il_send_lq_cmd(il, &lq_sta->lq, CMD_SYNC, true);
 }
 
 static void
@@ -2341,7 +2326,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)
        lq_sta->is_dup = 0;
        lq_sta->max_rate_idx = -1;
        lq_sta->missed_rate_counter = IL_MISSED_RATE_MAX;
-       lq_sta->is_green = il4965_rs_use_green(sta);
+       lq_sta->is_green = il4965_rs_use_green(il, sta);
        lq_sta->active_legacy_rate = il->active_rate & ~(0x1000);
        lq_sta->band = il->band;
        /*
@@ -2579,9 +2564,6 @@ il4965_rs_sta_dbgfs_scale_table_write(struct file *file,
        char buf[64];
        size_t buf_size;
        u32 parsed_rate;
-       struct il_station_priv *sta_priv =
-           container_of(lq_sta, struct il_station_priv, lq_sta);
-       struct il_rxon_context *ctx = sta_priv->common.ctx;
 
        il = lq_sta->drv;
        memset(buf, 0, sizeof(buf));
@@ -2603,7 +2585,7 @@ il4965_rs_sta_dbgfs_scale_table_write(struct file *file,
 
        if (lq_sta->dbg_fixed_rate) {
                il4965_rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
-               il_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, false);
+               il_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
        }
 
        return count;
index cacbc03880b0fc07846bdbea1694af40504ad75d..5db11714e04705cd9f68c061c59dfdab6abecfc6 100644 (file)
@@ -264,10 +264,6 @@ il4965_led_enable(struct il_priv *il)
        _il_wr(il, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
 }
 
-const struct il_led_ops il4965_led_ops = {
-       .cmd = il4965_send_led_cmd,
-};
-
 static int il4965_send_tx_power(struct il_priv *il);
 static int il4965_hw_get_temperature(struct il_priv *il);
 
@@ -508,7 +504,7 @@ iw4965_is_ht40_channel(__le32 rxon_flags)
                chan_mod == CHANNEL_MODE_MIXED);
 }
 
-static void
+void
 il4965_nic_config(struct il_priv *il)
 {
        unsigned long flags;
@@ -569,82 +565,6 @@ il4965_chain_noise_reset(struct il_priv *il)
        }
 }
 
-static struct il_sensitivity_ranges il4965_sensitivity = {
-       .min_nrg_cck = 97,
-       .max_nrg_cck = 0,       /* not used, set to 0 */
-
-       .auto_corr_min_ofdm = 85,
-       .auto_corr_min_ofdm_mrc = 170,
-       .auto_corr_min_ofdm_x1 = 105,
-       .auto_corr_min_ofdm_mrc_x1 = 220,
-
-       .auto_corr_max_ofdm = 120,
-       .auto_corr_max_ofdm_mrc = 210,
-       .auto_corr_max_ofdm_x1 = 140,
-       .auto_corr_max_ofdm_mrc_x1 = 270,
-
-       .auto_corr_min_cck = 125,
-       .auto_corr_max_cck = 200,
-       .auto_corr_min_cck_mrc = 200,
-       .auto_corr_max_cck_mrc = 400,
-
-       .nrg_th_cck = 100,
-       .nrg_th_ofdm = 100,
-
-       .barker_corr_th_min = 190,
-       .barker_corr_th_min_mrc = 390,
-       .nrg_th_cca = 62,
-};
-
-static void
-il4965_set_ct_threshold(struct il_priv *il)
-{
-       /* want Kelvin */
-       il->hw_params.ct_kill_threshold =
-           CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY);
-}
-
-/**
- * il4965_hw_set_hw_params
- *
- * Called when initializing driver
- */
-static int
-il4965_hw_set_hw_params(struct il_priv *il)
-{
-       if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES &&
-           il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES)
-               il->cfg->base_params->num_of_queues =
-                   il->cfg->mod_params->num_of_queues;
-
-       il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues;
-       il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
-       il->hw_params.scd_bc_tbls_size =
-           il->cfg->base_params->num_of_queues *
-           sizeof(struct il4965_scd_bc_tbl);
-       il->hw_params.tfd_size = sizeof(struct il_tfd);
-       il->hw_params.max_stations = IL4965_STATION_COUNT;
-       il->ctx.bcast_sta_id = IL4965_BROADCAST_ID;
-       il->hw_params.max_data_size = IL49_RTC_DATA_SIZE;
-       il->hw_params.max_inst_size = IL49_RTC_INST_SIZE;
-       il->hw_params.max_bsm_size = BSM_SRAM_SIZE;
-       il->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ);
-
-       il->hw_params.rx_wrt_ptr_reg = FH49_RSCSR_CHNL0_WPTR;
-
-       il->hw_params.tx_chains_num = il4965_num_of_ant(il->cfg->valid_tx_ant);
-       il->hw_params.rx_chains_num = il4965_num_of_ant(il->cfg->valid_rx_ant);
-       il->hw_params.valid_tx_ant = il->cfg->valid_tx_ant;
-       il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant;
-
-       il4965_set_ct_threshold(il);
-
-       il->hw_params.sens = &il4965_sensitivity;
-       il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS;
-
-       return 0;
-}
-
 static s32
 il4965_math_div_round(s32 num, s32 denom, s32 * res)
 {
@@ -1342,7 +1262,6 @@ il4965_send_tx_power(struct il_priv *il)
        u8 band = 0;
        bool is_ht40 = false;
        u8 ctrl_chan_high = 0;
-       struct il_rxon_context *ctx = &il->ctx;
 
        if (WARN_ONCE
            (test_bit(S_SCAN_HW, &il->status),
@@ -1351,16 +1270,16 @@ il4965_send_tx_power(struct il_priv *il)
 
        band = il->band == IEEE80211_BAND_2GHZ;
 
-       is_ht40 = iw4965_is_ht40_channel(ctx->active.flags);
+       is_ht40 = iw4965_is_ht40_channel(il->active.flags);
 
-       if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+       if (is_ht40 && (il->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
                ctrl_chan_high = 1;
 
        cmd.band = band;
-       cmd.channel = ctx->active.channel;
+       cmd.channel = il->active.channel;
 
        ret =
-           il4965_fill_txpower_tbl(il, band, le16_to_cpu(ctx->active.channel),
+           il4965_fill_txpower_tbl(il, band, le16_to_cpu(il->active.channel),
                                    is_ht40, ctrl_chan_high, &cmd.tx_power);
        if (ret)
                goto out;
@@ -1372,12 +1291,12 @@ out:
 }
 
 static int
-il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_send_rxon_assoc(struct il_priv *il)
 {
        int ret = 0;
        struct il4965_rxon_assoc_cmd rxon_assoc;
-       const struct il_rxon_cmd *rxon1 = &ctx->staging;
-       const struct il_rxon_cmd *rxon2 = &ctx->active;
+       const struct il_rxon_cmd *rxon1 = &il->staging;
+       const struct il_rxon_cmd *rxon2 = &il->active;
 
        if (rxon1->flags == rxon2->flags &&
            rxon1->filter_flags == rxon2->filter_flags &&
@@ -1392,16 +1311,16 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
                return 0;
        }
 
-       rxon_assoc.flags = ctx->staging.flags;
-       rxon_assoc.filter_flags = ctx->staging.filter_flags;
-       rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
-       rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+       rxon_assoc.flags = il->staging.flags;
+       rxon_assoc.filter_flags = il->staging.filter_flags;
+       rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates;
+       rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates;
        rxon_assoc.reserved = 0;
        rxon_assoc.ofdm_ht_single_stream_basic_rates =
-           ctx->staging.ofdm_ht_single_stream_basic_rates;
+           il->staging.ofdm_ht_single_stream_basic_rates;
        rxon_assoc.ofdm_ht_dual_stream_basic_rates =
-           ctx->staging.ofdm_ht_dual_stream_basic_rates;
-       rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
+           il->staging.ofdm_ht_dual_stream_basic_rates;
+       rxon_assoc.rx_chain_select_flags = il->staging.rx_chain;
 
        ret =
            il_send_cmd_pdu_async(il, C_RXON_ASSOC, sizeof(rxon_assoc),
@@ -1411,23 +1330,20 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
 }
 
 static int
-il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_commit_rxon(struct il_priv *il)
 {
        /* cast away the const for active_rxon in this function */
-       struct il_rxon_cmd *active_rxon = (void *)&ctx->active;
+       struct il_rxon_cmd *active_rxon = (void *)&il->active;
        int ret;
-       bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
+       bool new_assoc = !!(il->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
 
        if (!il_is_alive(il))
                return -EBUSY;
 
-       if (!ctx->is_active)
-               return 0;
-
        /* always get timestamp with Rx frame */
-       ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
+       il->staging.flags |= RXON_FLG_TSF2HOST_MSK;
 
-       ret = il_check_rxon_cmd(il, ctx);
+       ret = il_check_rxon_cmd(il);
        if (ret) {
                IL_ERR("Invalid RXON configuration.  Not committing.\n");
                return -EINVAL;
@@ -1438,7 +1354,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
         * abort any previous channel switch if still in process
         */
        if (test_bit(S_CHANNEL_SWITCH_PENDING, &il->status) &&
-           il->switch_channel != ctx->staging.channel) {
+           il->switch_channel != il->staging.channel) {
                D_11H("abort channel switch on %d\n",
                      le16_to_cpu(il->switch_channel));
                il_chswitch_done(il, false);
@@ -1447,15 +1363,15 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
        /* If we don't need to send a full RXON, we can use
         * il_rxon_assoc_cmd which is used to reconfigure filter
         * and other flags for the current radio configuration. */
-       if (!il_full_rxon_required(il, ctx)) {
-               ret = il_send_rxon_assoc(il, ctx);
+       if (!il_full_rxon_required(il)) {
+               ret = il_send_rxon_assoc(il);
                if (ret) {
                        IL_ERR("Error setting RXON_ASSOC (%d)\n", ret);
                        return ret;
                }
 
-               memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
-               il_print_rx_config_cmd(il, ctx);
+               memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
+               il_print_rx_config_cmd(il);
                /*
                 * We do not commit tx power settings while channel changing,
                 * do it now if tx power changed.
@@ -1468,12 +1384,12 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
         * an RXON_ASSOC and the new config wants the associated mask enabled,
         * we must clear the associated from the active configuration
         * before we apply the new config */
-       if (il_is_associated_ctx(ctx) && new_assoc) {
+       if (il_is_associated(il) && new_assoc) {
                D_INFO("Toggling associated bit on current RXON\n");
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 
                ret =
-                   il_send_cmd_pdu(il, ctx->rxon_cmd,
+                   il_send_cmd_pdu(il, C_RXON,
                                    sizeof(struct il_rxon_cmd), active_rxon);
 
                /* If the mask clearing failed then we set
@@ -1483,9 +1399,9 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
                        IL_ERR("Error clearing ASSOC_MSK (%d)\n", ret);
                        return ret;
                }
-               il_clear_ucode_stations(il, ctx);
-               il_restore_stations(il, ctx);
-               ret = il4965_restore_default_wep_keys(il, ctx);
+               il_clear_ucode_stations(il);
+               il_restore_stations(il);
+               ret = il4965_restore_default_wep_keys(il);
                if (ret) {
                        IL_ERR("Failed to restore WEP keys (%d)\n", ret);
                        return ret;
@@ -1494,9 +1410,9 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 
        D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n"
               "* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"),
-              le16_to_cpu(ctx->staging.channel), ctx->staging.bssid_addr);
+              le16_to_cpu(il->staging.channel), il->staging.bssid_addr);
 
-       il_set_rxon_hwcrypto(il, ctx, !il->cfg->mod_params->sw_crypto);
+       il_set_rxon_hwcrypto(il, !il->cfg->mod_params->sw_crypto);
 
        /* Apply the new configuration
         * RXON unassoc clears the station table in uCode so restoration of
@@ -1504,17 +1420,17 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
         */
        if (!new_assoc) {
                ret =
-                   il_send_cmd_pdu(il, ctx->rxon_cmd,
-                                   sizeof(struct il_rxon_cmd), &ctx->staging);
+                   il_send_cmd_pdu(il, C_RXON,
+                                   sizeof(struct il_rxon_cmd), &il->staging);
                if (ret) {
                        IL_ERR("Error setting new RXON (%d)\n", ret);
                        return ret;
                }
                D_INFO("Return from !new_assoc RXON.\n");
-               memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
-               il_clear_ucode_stations(il, ctx);
-               il_restore_stations(il, ctx);
-               ret = il4965_restore_default_wep_keys(il, ctx);
+               memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
+               il_clear_ucode_stations(il);
+               il_restore_stations(il);
+               ret = il4965_restore_default_wep_keys(il);
                if (ret) {
                        IL_ERR("Failed to restore WEP keys (%d)\n", ret);
                        return ret;
@@ -1526,15 +1442,15 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
                 * RXON assoc doesn't clear the station table in uCode,
                 */
                ret =
-                   il_send_cmd_pdu(il, ctx->rxon_cmd,
-                                   sizeof(struct il_rxon_cmd), &ctx->staging);
+                   il_send_cmd_pdu(il, C_RXON,
+                                   sizeof(struct il_rxon_cmd), &il->staging);
                if (ret) {
                        IL_ERR("Error setting new RXON (%d)\n", ret);
                        return ret;
                }
-               memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+               memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
        }
-       il_print_rx_config_cmd(il, ctx);
+       il_print_rx_config_cmd(il);
 
        il4965_init_sensitivity(il);
 
@@ -1553,7 +1469,6 @@ static int
 il4965_hw_channel_switch(struct il_priv *il,
                         struct ieee80211_channel_switch *ch_switch)
 {
-       struct il_rxon_context *ctx = &il->ctx;
        int rc;
        u8 band = 0;
        bool is_ht40 = false;
@@ -1564,21 +1479,24 @@ il4965_hw_channel_switch(struct il_priv *il,
        u16 ch;
        u32 tsf_low;
        u8 switch_count;
-       u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
-       struct ieee80211_vif *vif = ctx->vif;
-       band = il->band == IEEE80211_BAND_2GHZ;
+       u16 beacon_interval = le16_to_cpu(il->timing.beacon_interval);
+       struct ieee80211_vif *vif = il->vif;
+       band = (il->band == IEEE80211_BAND_2GHZ);
+
+       if (WARN_ON_ONCE(vif == NULL))
+               return -EIO;
 
-       is_ht40 = iw4965_is_ht40_channel(ctx->staging.flags);
+       is_ht40 = iw4965_is_ht40_channel(il->staging.flags);
 
-       if (is_ht40 && (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+       if (is_ht40 && (il->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
                ctrl_chan_high = 1;
 
        cmd.band = band;
        cmd.expect_beacon = 0;
        ch = ch_switch->channel->hw_value;
        cmd.channel = cpu_to_le16(ch);
-       cmd.rxon_flags = ctx->staging.flags;
-       cmd.rxon_filter_flags = ctx->staging.filter_flags;
+       cmd.rxon_flags = il->staging.flags;
+       cmd.rxon_filter_flags = il->staging.filter_flags;
        switch_count = ch_switch->count;
        tsf_low = ch_switch->timestamp & 0x0ffffffff;
        /*
@@ -1611,7 +1529,7 @@ il4965_hw_channel_switch(struct il_priv *il,
                cmd.expect_beacon = il_is_channel_radar(ch_info);
        else {
                IL_ERR("invalid channel switch from %u to %u\n",
-                      ctx->active.channel, ch);
+                      il->active.channel, ch);
                return -EFAULT;
        }
 
@@ -1756,7 +1674,7 @@ il4965_is_temp_calib_needed(struct il_priv *il)
        return 1;
 }
 
-static void
+void
 il4965_temperature_calib(struct il_priv *il)
 {
        s32 temp;
@@ -1815,339 +1733,21 @@ il4965_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data)
        return (u16) sizeof(struct il4965_addsta_cmd);
 }
 
-static inline u32
-il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp)
-{
-       return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
-}
-
-static inline u32
-il4965_tx_status_to_mac80211(u32 status)
-{
-       status &= TX_STATUS_MSK;
-
-       switch (status) {
-       case TX_STATUS_SUCCESS:
-       case TX_STATUS_DIRECT_DONE:
-               return IEEE80211_TX_STAT_ACK;
-       case TX_STATUS_FAIL_DEST_PS:
-               return IEEE80211_TX_STAT_TX_FILTERED;
-       default:
-               return 0;
-       }
-}
-
-static inline bool
-il4965_is_tx_success(u32 status)
-{
-       status &= TX_STATUS_MSK;
-       return (status == TX_STATUS_SUCCESS || status == TX_STATUS_DIRECT_DONE);
-}
-
-/**
- * il4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue
- */
-static int
-il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
-                         struct il4965_tx_resp *tx_resp, int txq_id,
-                         u16 start_idx)
-{
-       u16 status;
-       struct agg_tx_status *frame_status = tx_resp->u.agg_status;
-       struct ieee80211_tx_info *info = NULL;
-       struct ieee80211_hdr *hdr = NULL;
-       u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
-       int i, sh, idx;
-       u16 seq;
-       if (agg->wait_for_ba)
-               D_TX_REPLY("got tx response w/o block-ack\n");
-
-       agg->frame_count = tx_resp->frame_count;
-       agg->start_idx = start_idx;
-       agg->rate_n_flags = rate_n_flags;
-       agg->bitmap = 0;
-
-       /* num frames attempted by Tx command */
-       if (agg->frame_count == 1) {
-               /* Only one frame was attempted; no block-ack will arrive */
-               status = le16_to_cpu(frame_status[0].status);
-               idx = start_idx;
-
-               D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
-                          agg->frame_count, agg->start_idx, idx);
-
-               info = IEEE80211_SKB_CB(il->txq[txq_id].txb[idx].skb);
-               info->status.rates[0].count = tx_resp->failure_frame + 1;
-               info->flags &= ~IEEE80211_TX_CTL_AMPDU;
-               info->flags |= il4965_tx_status_to_mac80211(status);
-               il4965_hwrate_to_tx_control(il, rate_n_flags, info);
-
-               D_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff,
-                          tx_resp->failure_frame);
-               D_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
-
-               agg->wait_for_ba = 0;
-       } else {
-               /* Two or more frames were attempted; expect block-ack */
-               u64 bitmap = 0;
-               int start = agg->start_idx;
-
-               /* Construct bit-map of pending frames within Tx win */
-               for (i = 0; i < agg->frame_count; i++) {
-                       u16 sc;
-                       status = le16_to_cpu(frame_status[i].status);
-                       seq = le16_to_cpu(frame_status[i].sequence);
-                       idx = SEQ_TO_IDX(seq);
-                       txq_id = SEQ_TO_QUEUE(seq);
-
-                       if (status &
-                           (AGG_TX_STATE_FEW_BYTES_MSK |
-                            AGG_TX_STATE_ABORT_MSK))
-                               continue;
-
-                       D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
-                                  agg->frame_count, txq_id, idx);
-
-                       hdr = il_tx_queue_get_hdr(il, txq_id, idx);
-                       if (!hdr) {
-                               IL_ERR("BUG_ON idx doesn't point to valid skb"
-                                      " idx=%d, txq_id=%d\n", idx, txq_id);
-                               return -1;
-                       }
-
-                       sc = le16_to_cpu(hdr->seq_ctrl);
-                       if (idx != (SEQ_TO_SN(sc) & 0xff)) {
-                               IL_ERR("BUG_ON idx doesn't match seq control"
-                                      " idx=%d, seq_idx=%d, seq=%d\n", idx,
-                                      SEQ_TO_SN(sc), hdr->seq_ctrl);
-                               return -1;
-                       }
-
-                       D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx,
-                                  SEQ_TO_SN(sc));
-
-                       sh = idx - start;
-                       if (sh > 64) {
-                               sh = (start - idx) + 0xff;
-                               bitmap = bitmap << sh;
-                               sh = 0;
-                               start = idx;
-                       } else if (sh < -64)
-                               sh = 0xff - (start - idx);
-                       else if (sh < 0) {
-                               sh = start - idx;
-                               start = idx;
-                               bitmap = bitmap << sh;
-                               sh = 0;
-                       }
-                       bitmap |= 1ULL << sh;
-                       D_TX_REPLY("start=%d bitmap=0x%llx\n", start,
-                                  (unsigned long long)bitmap);
-               }
-
-               agg->bitmap = bitmap;
-               agg->start_idx = start;
-               D_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
-                          agg->frame_count, agg->start_idx,
-                          (unsigned long long)agg->bitmap);
-
-               if (bitmap)
-                       agg->wait_for_ba = 1;
-       }
-       return 0;
-}
-
-static u8
-il4965_find_station(struct il_priv *il, const u8 * addr)
-{
-       int i;
-       int start = 0;
-       int ret = IL_INVALID_STATION;
-       unsigned long flags;
-
-       if ((il->iw_mode == NL80211_IFTYPE_ADHOC))
-               start = IL_STA_ID;
-
-       if (is_broadcast_ether_addr(addr))
-               return il->ctx.bcast_sta_id;
-
-       spin_lock_irqsave(&il->sta_lock, flags);
-       for (i = start; i < il->hw_params.max_stations; i++)
-               if (il->stations[i].used &&
-                   (!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) {
-                       ret = i;
-                       goto out;
-               }
-
-       D_ASSOC("can not find STA %pM total %d\n", addr, il->num_stations);
-
-out:
-       /*
-        * It may be possible that more commands interacting with stations
-        * arrive before we completed processing the adding of
-        * station
-        */
-       if (ret != IL_INVALID_STATION &&
-           (!(il->stations[ret].used & IL_STA_UCODE_ACTIVE) ||
-            ((il->stations[ret].used & IL_STA_UCODE_ACTIVE) &&
-             (il->stations[ret].used & IL_STA_UCODE_INPROGRESS)))) {
-               IL_ERR("Requested station info for sta %d before ready.\n",
-                      ret);
-               ret = IL_INVALID_STATION;
-       }
-       spin_unlock_irqrestore(&il->sta_lock, flags);
-       return ret;
-}
-
-static int
-il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr)
-{
-       if (il->iw_mode == NL80211_IFTYPE_STATION) {
-               return IL_AP_ID;
-       } else {
-               u8 *da = ieee80211_get_DA(hdr);
-               return il4965_find_station(il, da);
-       }
-}
-
-/**
- * il4965_hdl_tx - Handle standard (non-aggregation) Tx response
- */
-static void
-il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
-{
-       struct il_rx_pkt *pkt = rxb_addr(rxb);
-       u16 sequence = le16_to_cpu(pkt->hdr.sequence);
-       int txq_id = SEQ_TO_QUEUE(sequence);
-       int idx = SEQ_TO_IDX(sequence);
-       struct il_tx_queue *txq = &il->txq[txq_id];
-       struct ieee80211_hdr *hdr;
-       struct ieee80211_tx_info *info;
-       struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
-       u32 status = le32_to_cpu(tx_resp->u.status);
-       int uninitialized_var(tid);
-       int sta_id;
-       int freed;
-       u8 *qc = NULL;
-       unsigned long flags;
-
-       if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) {
-               IL_ERR("Read idx for DMA queue txq_id (%d) idx %d "
-                      "is out of range [0-%d] %d %d\n", txq_id, idx,
-                      txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr);
-               return;
-       }
-
-       txq->time_stamp = jiffies;
-       info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
-       memset(&info->status, 0, sizeof(info->status));
-
-       hdr = il_tx_queue_get_hdr(il, txq_id, idx);
-       if (ieee80211_is_data_qos(hdr->frame_control)) {
-               qc = ieee80211_get_qos_ctl(hdr);
-               tid = qc[0] & 0xf;
-       }
-
-       sta_id = il4965_get_ra_sta_id(il, hdr);
-       if (txq->sched_retry && unlikely(sta_id == IL_INVALID_STATION)) {
-               IL_ERR("Station not known\n");
-               return;
-       }
-
-       spin_lock_irqsave(&il->sta_lock, flags);
-       if (txq->sched_retry) {
-               const u32 scd_ssn = il4965_get_scd_ssn(tx_resp);
-               struct il_ht_agg *agg = NULL;
-               WARN_ON(!qc);
-
-               agg = &il->stations[sta_id].tid[tid].agg;
-
-               il4965_tx_status_reply_tx(il, agg, tx_resp, txq_id, idx);
-
-               /* check if BAR is needed */
-               if ((tx_resp->frame_count == 1) &&
-                   !il4965_is_tx_success(status))
-                       info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
-
-               if (txq->q.read_ptr != (scd_ssn & 0xff)) {
-                       idx = il_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
-                       D_TX_REPLY("Retry scheduler reclaim scd_ssn "
-                                  "%d idx %d\n", scd_ssn, idx);
-                       freed = il4965_tx_queue_reclaim(il, txq_id, idx);
-                       if (qc)
-                               il4965_free_tfds_in_queue(il, sta_id, tid,
-                                                         freed);
-
-                       if (il->mac80211_registered &&
-                           il_queue_space(&txq->q) > txq->q.low_mark &&
-                           agg->state != IL_EMPTYING_HW_QUEUE_DELBA)
-                               il_wake_queue(il, txq);
-               }
-       } else {
-               info->status.rates[0].count = tx_resp->failure_frame + 1;
-               info->flags |= il4965_tx_status_to_mac80211(status);
-               il4965_hwrate_to_tx_control(il,
-                                           le32_to_cpu(tx_resp->rate_n_flags),
-                                           info);
-
-               D_TX_REPLY("TXQ %d status %s (0x%08x) "
-                          "rate_n_flags 0x%x retries %d\n", txq_id,
-                          il4965_get_tx_fail_reason(status), status,
-                          le32_to_cpu(tx_resp->rate_n_flags),
-                          tx_resp->failure_frame);
-
-               freed = il4965_tx_queue_reclaim(il, txq_id, idx);
-               if (qc && likely(sta_id != IL_INVALID_STATION))
-                       il4965_free_tfds_in_queue(il, sta_id, tid, freed);
-               else if (sta_id == IL_INVALID_STATION)
-                       D_TX_REPLY("Station not known\n");
-
-               if (il->mac80211_registered &&
-                   il_queue_space(&txq->q) > txq->q.low_mark)
-                       il_wake_queue(il, txq);
-       }
-       if (qc && likely(sta_id != IL_INVALID_STATION))
-               il4965_txq_check_empty(il, sta_id, tid, txq_id);
-
-       il4965_check_abort_status(il, tx_resp->frame_count, status);
-
-       spin_unlock_irqrestore(&il->sta_lock, flags);
-}
-
-/* Set up 4965-specific Rx frame reply handlers */
-static void
-il4965_handler_setup(struct il_priv *il)
-{
-       /* Legacy Rx frames */
-       il->handlers[N_RX] = il4965_hdl_rx;
-       /* Tx response */
-       il->handlers[C_TX] = il4965_hdl_tx;
-}
-
-static struct il_hcmd_ops il4965_hcmd = {
-       .rxon_assoc = il4965_send_rxon_assoc,
-       .commit_rxon = il4965_commit_rxon,
-       .set_rxon_chain = il4965_set_rxon_chain,
-};
-
 static void
 il4965_post_scan(struct il_priv *il)
 {
-       struct il_rxon_context *ctx = &il->ctx;
-
        /*
         * Since setting the RXON may have been deferred while
         * performing the scan, fire one off if needed
         */
-       if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
-               il_commit_rxon(il, ctx);
+       if (memcmp(&il->staging, &il->active, sizeof(il->staging)))
+               il_commit_rxon(il);
 }
 
 static void
 il4965_post_associate(struct il_priv *il)
 {
-       struct il_rxon_context *ctx = &il->ctx;
-       struct ieee80211_vif *vif = ctx->vif;
+       struct ieee80211_vif *vif = il->vif;
        struct ieee80211_conf *conf = NULL;
        int ret = 0;
 
@@ -2161,41 +1761,41 @@ il4965_post_associate(struct il_priv *il)
 
        conf = &il->hw->conf;
 
-       ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       il_commit_rxon(il, ctx);
+       il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+       il_commit_rxon(il);
 
-       ret = il_send_rxon_timing(il, ctx);
+       ret = il_send_rxon_timing(il);
        if (ret)
                IL_WARN("RXON timing - " "Attempting to continue.\n");
 
-       ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+       il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
 
        il_set_rxon_ht(il, &il->current_ht_config);
 
-       if (il->cfg->ops->hcmd->set_rxon_chain)
-               il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+       if (il->ops->set_rxon_chain)
+               il->ops->set_rxon_chain(il);
 
-       ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+       il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
 
        D_ASSOC("assoc id %d beacon interval %d\n", vif->bss_conf.aid,
                vif->bss_conf.beacon_int);
 
        if (vif->bss_conf.use_short_preamble)
-               ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+               il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
        else
-               ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+               il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
 
-       if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+       if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
                if (vif->bss_conf.use_short_slot)
-                       ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+                       il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
                else
-                       ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+                       il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
        }
 
-       il_commit_rxon(il, ctx);
+       il_commit_rxon(il);
 
        D_ASSOC("Associated as %d to: %pM\n", vif->bss_conf.aid,
-               ctx->active.bssid_addr);
+               il->active.bssid_addr);
 
        switch (vif->type) {
        case NL80211_IFTYPE_STATION:
@@ -2223,8 +1823,7 @@ il4965_post_associate(struct il_priv *il)
 static void
 il4965_config_ap(struct il_priv *il)
 {
-       struct il_rxon_context *ctx = &il->ctx;
-       struct ieee80211_vif *vif = ctx->vif;
+       struct ieee80211_vif *vif = il->vif;
        int ret = 0;
 
        lockdep_assert_held(&il->mutex);
@@ -2233,14 +1832,14 @@ il4965_config_ap(struct il_priv *il)
                return;
 
        /* The following should be done only at AP bring up */
-       if (!il_is_associated_ctx(ctx)) {
+       if (!il_is_associated(il)) {
 
                /* RXON - unassoc (to set timing command) */
-               ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               il_commit_rxon(il, ctx);
+               il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+               il_commit_rxon(il);
 
                /* RXON Timing */
-               ret = il_send_rxon_timing(il, ctx);
+               ret = il_send_rxon_timing(il);
                if (ret)
                        IL_WARN("RXON timing failed - "
                                "Attempting to continue.\n");
@@ -2248,133 +1847,63 @@ il4965_config_ap(struct il_priv *il)
                /* AP has all antennas */
                il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant;
                il_set_rxon_ht(il, &il->current_ht_config);
-               if (il->cfg->ops->hcmd->set_rxon_chain)
-                       il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+               if (il->ops->set_rxon_chain)
+                       il->ops->set_rxon_chain(il);
 
-               ctx->staging.assoc_id = 0;
+               il->staging.assoc_id = 0;
 
                if (vif->bss_conf.use_short_preamble)
-                       ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+                       il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
                else
-                       ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+                       il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
 
-               if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+               if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
                        if (vif->bss_conf.use_short_slot)
-                               ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+                               il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
                        else
-                               ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+                               il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
                }
                /* need to send beacon cmd before committing assoc RXON! */
                il4965_send_beacon_cmd(il);
                /* restore RXON assoc */
-               ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
-               il_commit_rxon(il, ctx);
+               il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+               il_commit_rxon(il);
        }
        il4965_send_beacon_cmd(il);
 }
 
-static struct il_hcmd_utils_ops il4965_hcmd_utils = {
-       .get_hcmd_size = il4965_get_hcmd_size,
-       .build_addsta_hcmd = il4965_build_addsta_hcmd,
-       .request_scan = il4965_request_scan,
-       .post_scan = il4965_post_scan,
-};
-
-static struct il_lib_ops il4965_lib = {
-       .set_hw_params = il4965_hw_set_hw_params,
+const struct il_ops il4965_ops = {
        .txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl,
        .txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd,
        .txq_free_tfd = il4965_hw_txq_free_tfd,
        .txq_init = il4965_hw_tx_queue_init,
-       .handler_setup = il4965_handler_setup,
        .is_valid_rtc_data_addr = il4965_hw_valid_rtc_data_addr,
        .init_alive_start = il4965_init_alive_start,
        .load_ucode = il4965_load_bsm,
        .dump_nic_error_log = il4965_dump_nic_error_log,
        .dump_fh = il4965_dump_fh,
        .set_channel_switch = il4965_hw_channel_switch,
-       .apm_ops = {
-                   .init = il_apm_init,
-                   .config = il4965_nic_config,
-                   },
-       .eeprom_ops = {
-                      .regulatory_bands = {
-                                           EEPROM_REGULATORY_BAND_1_CHANNELS,
-                                           EEPROM_REGULATORY_BAND_2_CHANNELS,
-                                           EEPROM_REGULATORY_BAND_3_CHANNELS,
-                                           EEPROM_REGULATORY_BAND_4_CHANNELS,
-                                           EEPROM_REGULATORY_BAND_5_CHANNELS,
-                                           EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
-                                           EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS},
-                      .acquire_semaphore = il4965_eeprom_acquire_semaphore,
-                      .release_semaphore = il4965_eeprom_release_semaphore,
-                      },
+       .apm_init = il_apm_init,
        .send_tx_power = il4965_send_tx_power,
        .update_chain_flags = il4965_update_chain_flags,
-       .temp_ops = {
-                    .temperature = il4965_temperature_calib,
-                    },
-#ifdef CONFIG_IWLEGACY_DEBUGFS
-       .debugfs_ops = {
-                       .rx_stats_read = il4965_ucode_rx_stats_read,
-                       .tx_stats_read = il4965_ucode_tx_stats_read,
-                       .general_stats_read = il4965_ucode_general_stats_read,
-                       },
-#endif
-};
+       .eeprom_acquire_semaphore = il4965_eeprom_acquire_semaphore,
+       .eeprom_release_semaphore = il4965_eeprom_release_semaphore,
+
+       .rxon_assoc = il4965_send_rxon_assoc,
+       .commit_rxon = il4965_commit_rxon,
+       .set_rxon_chain = il4965_set_rxon_chain,
+
+       .get_hcmd_size = il4965_get_hcmd_size,
+       .build_addsta_hcmd = il4965_build_addsta_hcmd,
+       .request_scan = il4965_request_scan,
+       .post_scan = il4965_post_scan,
 
-static const struct il_legacy_ops il4965_legacy_ops = {
        .post_associate = il4965_post_associate,
        .config_ap = il4965_config_ap,
        .manage_ibss_station = il4965_manage_ibss_station,
        .update_bcast_stations = il4965_update_bcast_stations,
-};
 
-struct ieee80211_ops il4965_hw_ops = {
-       .tx = il4965_mac_tx,
-       .start = il4965_mac_start,
-       .stop = il4965_mac_stop,
-       .add_interface = il_mac_add_interface,
-       .remove_interface = il_mac_remove_interface,
-       .change_interface = il_mac_change_interface,
-       .config = il_mac_config,
-       .configure_filter = il4965_configure_filter,
-       .set_key = il4965_mac_set_key,
-       .update_tkip_key = il4965_mac_update_tkip_key,
-       .conf_tx = il_mac_conf_tx,
-       .reset_tsf = il_mac_reset_tsf,
-       .bss_info_changed = il_mac_bss_info_changed,
-       .ampdu_action = il4965_mac_ampdu_action,
-       .hw_scan = il_mac_hw_scan,
-       .sta_add = il4965_mac_sta_add,
-       .sta_remove = il_mac_sta_remove,
-       .channel_switch = il4965_mac_channel_switch,
-       .tx_last_beacon = il_mac_tx_last_beacon,
-};
-
-static const struct il_ops il4965_ops = {
-       .lib = &il4965_lib,
-       .hcmd = &il4965_hcmd,
-       .utils = &il4965_hcmd_utils,
-       .led = &il4965_led_ops,
-       .legacy = &il4965_legacy_ops,
-       .ieee80211_ops = &il4965_hw_ops,
-};
-
-static struct il_base_params il4965_base_params = {
-       .eeprom_size = IL4965_EEPROM_IMG_SIZE,
-       .num_of_queues = IL49_NUM_QUEUES,
-       .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES,
-       .pll_cfg_val = 0,
-       .set_l0s = true,
-       .use_bsm = true,
-       .led_compensation = 61,
-       .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS,
-       .wd_timeout = IL_DEF_WD_TIMEOUT,
-       .temperature_kelvin = true,
-       .ucode_tracing = true,
-       .sensitivity_calib_by_driver = true,
-       .chain_noise_calib_by_driver = true,
+       .send_led_cmd = il4965_send_led_cmd,
 };
 
 struct il_cfg il4965_cfg = {
@@ -2387,15 +1916,38 @@ struct il_cfg il4965_cfg = {
        .valid_rx_ant = ANT_ABC,
        .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
-       .ops = &il4965_ops,
        .mod_params = &il4965_mod_params,
-       .base_params = &il4965_base_params,
        .led_mode = IL_LED_BLINK,
        /*
         * Force use of chains B and C for scan RX on 5 GHz band
         * because the device has off-channel reception on chain A.
         */
        .scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC,
+
+       .eeprom_size = IL4965_EEPROM_IMG_SIZE,
+       .num_of_queues = IL49_NUM_QUEUES,
+       .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES,
+       .pll_cfg_val = 0,
+       .set_l0s = true,
+       .use_bsm = true,
+       .led_compensation = 61,
+       .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS,
+       .wd_timeout = IL_DEF_WD_TIMEOUT,
+       .temperature_kelvin = true,
+       .ucode_tracing = true,
+       .sensitivity_calib_by_driver = true,
+       .chain_noise_calib_by_driver = true,
+
+       .regulatory_bands = {
+               EEPROM_REGULATORY_BAND_1_CHANNELS,
+               EEPROM_REGULATORY_BAND_2_CHANNELS,
+               EEPROM_REGULATORY_BAND_3_CHANNELS,
+               EEPROM_REGULATORY_BAND_4_CHANNELS,
+               EEPROM_REGULATORY_BAND_5_CHANNELS,
+               EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
+               EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
+       },
+
 };
 
 /* Module firmware */
index f280e0161b1716989fa30af9cd25bc7358bd3128..1db677689cfe36b18940c406e302519c51591bef 100644 (file)
@@ -38,17 +38,16 @@ struct il_rxon_context;
 
 /* configuration for the _4965 devices */
 extern struct il_cfg il4965_cfg;
+extern const struct il_ops il4965_ops;
 
 extern struct il_mod_params il4965_mod_params;
 
-extern struct ieee80211_ops il4965_hw_ops;
-
 /* tx queue */
 void il4965_free_tfds_in_queue(struct il_priv *il, int sta_id, int tid,
                               int freed);
 
 /* RXON */
-void il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx);
+void il4965_set_rxon_chain(struct il_priv *il);
 
 /* uCode */
 int il4965_verify_ucode(struct il_priv *il);
@@ -61,6 +60,8 @@ int il4965_rx_init(struct il_priv *il, struct il_rx_queue *rxq);
 int il4965_hw_nic_init(struct il_priv *il);
 int il4965_dump_fh(struct il_priv *il, char **buf, bool display);
 
+void il4965_nic_config(struct il_priv *il);
+
 /* rx */
 void il4965_rx_queue_restock(struct il_priv *il);
 void il4965_rx_replenish(struct il_priv *il);
@@ -68,8 +69,6 @@ void il4965_rx_replenish_now(struct il_priv *il);
 void il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq);
 int il4965_rxq_stop(struct il_priv *il);
 int il4965_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
-void il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb);
-void il4965_hdl_rx_phy(struct il_priv *il, struct il_rx_buf *rxb);
 void il4965_rx_handle(struct il_priv *il);
 
 /* tx */
@@ -85,7 +84,6 @@ int il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
 int il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif,
                       struct ieee80211_sta *sta, u16 tid);
 int il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id);
-void il4965_hdl_compressed_ba(struct il_priv *il, struct il_rx_buf *rxb);
 int il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx);
 void il4965_hw_txq_ctx_free(struct il_priv *il);
 int il4965_txq_ctx_alloc(struct il_priv *il);
@@ -107,12 +105,6 @@ void il4965_set_wr_ptrs(struct il_priv *il, int txq_id, u32 idx);
 void il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq,
                                int tx_fifo_id, int scd_retry);
 
-/* rx */
-void il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb);
-bool il4965_good_plcp_health(struct il_priv *il, struct il_rx_pkt *pkt);
-void il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb);
-void il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb);
-
 /* scan */
 int il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif);
 
@@ -134,21 +126,18 @@ il4965_get_tx_fail_reason(u32 status)
 #endif
 
 /* station management */
-int il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx);
-int il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
-                            const u8 *addr, u8 *sta_id_r);
+int il4965_alloc_bcast_station(struct il_priv *il);
+int il4965_add_bssid_station(struct il_priv *il, const u8 *addr, u8 *sta_id_r);
 int il4965_remove_default_wep_key(struct il_priv *il,
-                                 struct il_rxon_context *ctx,
                                  struct ieee80211_key_conf *key);
-int il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx,
+int il4965_set_default_wep_key(struct il_priv *il,
                               struct ieee80211_key_conf *key);
-int il4965_restore_default_wep_keys(struct il_priv *il,
-                                   struct il_rxon_context *ctx);
-int il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
+int il4965_restore_default_wep_keys(struct il_priv *il);
+int il4965_set_dynamic_key(struct il_priv *il,
                           struct ieee80211_key_conf *key, u8 sta_id);
-int il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
+int il4965_remove_dynamic_key(struct il_priv *il,
                              struct ieee80211_key_conf *key, u8 sta_id);
-void il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
+void il4965_update_tkip_key(struct il_priv *il,
                            struct ieee80211_key_conf *keyconf,
                            struct ieee80211_sta *sta, u32 iv32,
                            u16 *phase1key);
@@ -279,6 +268,7 @@ il4965_hw_valid_rtc_data_addr(u32 addr)
        ((t) < IL_TX_POWER_TEMPERATURE_MIN || \
         (t) > IL_TX_POWER_TEMPERATURE_MAX)
 
+extern void il4965_temperature_calib(struct il_priv *il);
 /********************* END TEMPERATURE ***************************************/
 
 /********************* START TXPOWER *****************************************/
@@ -937,17 +927,10 @@ void il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp);
 void il4965_sensitivity_calibration(struct il_priv *il, void *resp);
 void il4965_init_sensitivity(struct il_priv *il);
 void il4965_reset_run_time_calib(struct il_priv *il);
-void il4965_calib_free_results(struct il_priv *il);
 
 /* Debug */
 #ifdef CONFIG_IWLEGACY_DEBUGFS
-ssize_t il4965_ucode_rx_stats_read(struct file *file, char __user *user_buf,
-                                  size_t count, loff_t *ppos);
-ssize_t il4965_ucode_tx_stats_read(struct file *file, char __user *user_buf,
-                                  size_t count, loff_t *ppos);
-ssize_t il4965_ucode_general_stats_read(struct file *file,
-                                       char __user *user_buf, size_t count,
-                                       loff_t *ppos);
+extern const struct il_debugfs_ops il4965_debugfs_ops;
 #endif
 
 /****************************/
index 05bd375cb845b73fbf94401ba57bfc50c59d448d..fb919727b8bb520bc32f2c151997e1d33c721eab 100644 (file)
@@ -6,45 +6,6 @@ config IWLEGACY
        select LEDS_TRIGGERS
        select MAC80211_LEDS
 
-menu "Debugging Options"
-       depends on IWLEGACY
-
-config IWLEGACY_DEBUG
-       bool "Enable full debugging output in iwlegacy (iwl 3945/4965) drivers"
-       depends on IWLEGACY
-       ---help---
-         This option will enable debug tracing output for the iwlegacy
-         drivers.
-
-         This will result in the kernel module being ~100k larger.  You can
-         control which debug output is sent to the kernel log by setting the
-         value in
-
-               /sys/class/net/wlan0/device/debug_level
-
-         This entry will only exist if this option is enabled.
-
-         To set a value, simply echo an 8-byte hex value to the same file:
-
-                 % echo 0x43fff > /sys/class/net/wlan0/device/debug_level
-
-         You can find the list of debug mask values in:
-                 drivers/net/wireless/iwlegacy/common.h
-
-         If this is your first time using this driver, you should say Y here
-         as the debug information can assist others in helping you resolve
-         any problems you may encounter.
-
-config IWLEGACY_DEBUGFS
-        bool "iwlegacy (iwl 3945/4965) debugfs support"
-        depends on IWLEGACY && MAC80211_DEBUGFS
-        ---help---
-         Enable creation of debugfs files for the iwlegacy drivers. This
-         is a low-impact option that allows getting insight into the
-         driver's state at runtime.
-
-endmenu
-
 config IWL4965
        tristate "Intel Wireless WiFi 4965AGN (iwl4965)"
        depends on PCI && MAC80211
@@ -98,3 +59,42 @@ config IWL3945
          inserted in and removed from the running kernel whenever you want),
          say M here and read <file:Documentation/kbuild/modules.txt>.  The
          module will be called iwl3945.
+
+menu "iwl3945 / iwl4965 Debugging Options"
+       depends on IWLEGACY
+
+config IWLEGACY_DEBUG
+       bool "Enable full debugging output in iwlegacy (iwl 3945/4965) drivers"
+       depends on IWLEGACY
+       ---help---
+         This option will enable debug tracing output for the iwlegacy
+         drivers.
+
+         This will result in the kernel module being ~100k larger.  You can
+         control which debug output is sent to the kernel log by setting the
+         value in
+
+               /sys/class/net/wlan0/device/debug_level
+
+         This entry will only exist if this option is enabled.
+
+         To set a value, simply echo an 8-byte hex value to the same file:
+
+                 % echo 0x43fff > /sys/class/net/wlan0/device/debug_level
+
+         You can find the list of debug mask values in:
+                 drivers/net/wireless/iwlegacy/common.h
+
+         If this is your first time using this driver, you should say Y here
+         as the debug information can assist others in helping you resolve
+         any problems you may encounter.
+
+config IWLEGACY_DEBUGFS
+        bool "iwlegacy (iwl 3945/4965) debugfs support"
+        depends on IWLEGACY && MAC80211_DEBUGFS
+        ---help---
+         Enable creation of debugfs files for the iwlegacy drivers. This
+         is a low-impact option that allows getting insight into the
+         driver's state at runtime.
+
+endmenu
index 36454d0bbeedf7917b04e8d07f729e8b791f8a07..b42052b47d8e290ebede79489c70aa094cd3f3bf 100644 (file)
@@ -81,7 +81,7 @@ il_clear_bit(struct il_priv *p, u32 r, u32 m)
 }
 EXPORT_SYMBOL(il_clear_bit);
 
-int
+bool
 _il_grab_nic_access(struct il_priv *il)
 {
        int ret;
@@ -111,14 +111,15 @@ _il_grab_nic_access(struct il_priv *il)
            _il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
                         (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
                          CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
-       if (ret < 0) {
+       if (unlikely(ret < 0)) {
                val = _il_rd(il, CSR_GP_CNTRL);
-               IL_ERR("MAC is in deep sleep!.  CSR_GP_CNTRL = 0x%08X\n", val);
+               WARN_ONCE(1, "Timeout waiting for ucode processor access "
+                            "(CSR_GP_CNTRL 0x%08x)\n", val);
                _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
-               return -EIO;
+               return false;
        }
 
-       return 0;
+       return true;
 }
 EXPORT_SYMBOL_GPL(_il_grab_nic_access);
 
@@ -160,7 +161,7 @@ il_wr_prph(struct il_priv *il, u32 addr, u32 val)
        unsigned long reg_flags;
 
        spin_lock_irqsave(&il->reg_lock, reg_flags);
-       if (!_il_grab_nic_access(il)) {
+       if (likely(_il_grab_nic_access(il))) {
                _il_wr_prph(il, addr, val);
                _il_release_nic_access(il);
        }
@@ -178,7 +179,6 @@ il_read_targ_mem(struct il_priv *il, u32 addr)
        _il_grab_nic_access(il);
 
        _il_wr(il, HBUS_TARG_MEM_RADDR, addr);
-       rmb();
        value = _il_rd(il, HBUS_TARG_MEM_RDAT);
 
        _il_release_nic_access(il);
@@ -193,9 +193,8 @@ il_write_targ_mem(struct il_priv *il, u32 addr, u32 val)
        unsigned long reg_flags;
 
        spin_lock_irqsave(&il->reg_lock, reg_flags);
-       if (!_il_grab_nic_access(il)) {
+       if (likely(_il_grab_nic_access(il))) {
                _il_wr(il, HBUS_TARG_MEM_WADDR, addr);
-               wmb();
                _il_wr(il, HBUS_TARG_MEM_WDAT, val);
                _il_release_nic_access(il);
        }
@@ -351,7 +350,7 @@ il_send_cmd_sync(struct il_priv *il, struct il_host_cmd *cmd)
                }
        }
 
-       if (test_bit(S_RF_KILL_HW, &il->status)) {
+       if (test_bit(S_RFKILL, &il->status)) {
                IL_ERR("Command %s aborted: RF KILL Switch\n",
                       il_get_cmd_string(cmd->id));
                ret = -ECANCELED;
@@ -512,15 +511,15 @@ il_led_cmd(struct il_priv *il, unsigned long on, unsigned long off)
        }
 
        D_LED("Led blink time compensation=%u\n",
-             il->cfg->base_params->led_compensation);
+             il->cfg->led_compensation);
        led_cmd.on =
            il_blink_compensation(il, on,
-                                 il->cfg->base_params->led_compensation);
+                                 il->cfg->led_compensation);
        led_cmd.off =
            il_blink_compensation(il, off,
-                                 il->cfg->base_params->led_compensation);
+                                 il->cfg->led_compensation);
 
-       ret = il->cfg->ops->led->cmd(il, &led_cmd);
+       ret = il->ops->send_led_cmd(il, &led_cmd);
        if (!ret) {
                il->blink_on = on;
                il->blink_off = off;
@@ -691,7 +690,7 @@ il_eeprom_verify_signature(struct il_priv *il)
 const u8 *
 il_eeprom_query_addr(const struct il_priv *il, size_t offset)
 {
-       BUG_ON(offset >= il->cfg->base_params->eeprom_size);
+       BUG_ON(offset >= il->cfg->eeprom_size);
        return &il->eeprom[offset];
 }
 EXPORT_SYMBOL(il_eeprom_query_addr);
@@ -722,7 +721,7 @@ il_eeprom_init(struct il_priv *il)
        u16 addr;
 
        /* allocate eeprom */
-       sz = il->cfg->base_params->eeprom_size;
+       sz = il->cfg->eeprom_size;
        D_EEPROM("NVM size = %d\n", sz);
        il->eeprom = kzalloc(sz, GFP_KERNEL);
        if (!il->eeprom) {
@@ -731,7 +730,7 @@ il_eeprom_init(struct il_priv *il)
        }
        e = (__le16 *) il->eeprom;
 
-       il->cfg->ops->lib->apm_ops.init(il);
+       il->ops->apm_init(il);
 
        ret = il_eeprom_verify_signature(il);
        if (ret < 0) {
@@ -741,7 +740,7 @@ il_eeprom_init(struct il_priv *il)
        }
 
        /* Make sure driver (instead of uCode) is allowed to read EEPROM */
-       ret = il->cfg->ops->lib->eeprom_ops.acquire_semaphore(il);
+       ret = il->ops->eeprom_acquire_semaphore(il);
        if (ret < 0) {
                IL_ERR("Failed to acquire EEPROM semaphore.\n");
                ret = -ENOENT;
@@ -773,7 +772,7 @@ il_eeprom_init(struct il_priv *il)
 
        ret = 0;
 done:
-       il->cfg->ops->lib->eeprom_ops.release_semaphore(il);
+       il->ops->eeprom_release_semaphore(il);
 
 err:
        if (ret)
@@ -799,8 +798,8 @@ il_init_band_reference(const struct il_priv *il, int eep_band,
                       const struct il_eeprom_channel **eeprom_ch_info,
                       const u8 **eeprom_ch_idx)
 {
-       u32 offset =
-           il->cfg->ops->lib->eeprom_ops.regulatory_bands[eep_band - 1];
+       u32 offset = il->cfg->regulatory_bands[eep_band - 1];
+
        switch (eep_band) {
        case 1:         /* 2.4GHz band */
                *eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_1);
@@ -1001,10 +1000,8 @@ il_init_channel_map(struct il_priv *il)
        }
 
        /* Check if we do have HT40 channels */
-       if (il->cfg->ops->lib->eeprom_ops.regulatory_bands[5] ==
-           EEPROM_REGULATORY_BAND_NO_HT40 &&
-           il->cfg->ops->lib->eeprom_ops.regulatory_bands[6] ==
-           EEPROM_REGULATORY_BAND_NO_HT40)
+       if (il->cfg->regulatory_bands[5] == EEPROM_REGULATORY_BAND_NO_HT40 &&
+           il->cfg->regulatory_bands[6] == EEPROM_REGULATORY_BAND_NO_HT40)
                return 0;
 
        /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */
@@ -1158,9 +1155,9 @@ il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force)
                if (!(cmd->flags & IL_POWER_DRIVER_ALLOW_SLEEP_MSK))
                        clear_bit(S_POWER_PMI, &il->status);
 
-               if (il->cfg->ops->lib->update_chain_flags && update_chains)
-                       il->cfg->ops->lib->update_chain_flags(il);
-               else if (il->cfg->ops->lib->update_chain_flags)
+               if (il->ops->update_chain_flags && update_chains)
+                       il->ops->update_chain_flags(il);
+               else if (il->ops->update_chain_flags)
                        D_POWER("Cannot update the power, chain noise "
                                "calibration running: %d\n",
                                il->chain_noise_data.state);
@@ -1442,7 +1439,6 @@ u16
 il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band,
                          struct ieee80211_vif *vif)
 {
-       struct il_rxon_context *ctx = &il->ctx;
        u16 value;
 
        u16 passive =
@@ -1457,7 +1453,7 @@ il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band,
                 * dwell time to be 98% of the smallest beacon interval
                 * (minus 2 * channel tune time)
                 */
-               value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0;
+               value = il->vif ? il->vif->bss_conf.beacon_int : 0;
                if (value > IL_PASSIVE_DWELL_BASE || !value)
                        value = IL_PASSIVE_DWELL_BASE;
                value = (value * 98) / 100 - IL_CHANNEL_TUNE_TIME * 2;
@@ -1486,9 +1482,6 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif)
 
        lockdep_assert_held(&il->mutex);
 
-       if (WARN_ON(!il->cfg->ops->utils->request_scan))
-               return -EOPNOTSUPP;
-
        cancel_delayed_work(&il->scan_check);
 
        if (!il_is_ready_rf(il)) {
@@ -1511,7 +1504,7 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif)
        set_bit(S_SCANNING, &il->status);
        il->scan_start = jiffies;
 
-       ret = il->cfg->ops->utils->request_scan(il, vif);
+       ret = il->ops->request_scan(il, vif);
        if (ret) {
                clear_bit(S_SCANNING, &il->status);
                return ret;
@@ -1530,12 +1523,13 @@ il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        struct il_priv *il = hw->priv;
        int ret;
 
-       D_MAC80211("enter\n");
-
-       if (req->n_channels == 0)
+       if (req->n_channels == 0) {
+               IL_ERR("Can not scan on no channels.\n");
                return -EINVAL;
+       }
 
        mutex_lock(&il->mutex);
+       D_MAC80211("enter\n");
 
        if (test_bit(S_SCANNING, &il->status)) {
                D_SCAN("Scan already in progress.\n");
@@ -1550,9 +1544,8 @@ il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        ret = il_scan_initiate(il, vif);
 
-       D_MAC80211("leave\n");
-
 out_unlock:
+       D_MAC80211("leave ret %d\n", ret);
        mutex_unlock(&il->mutex);
 
        return ret;
@@ -1673,7 +1666,7 @@ out_settings:
        il_power_set_mode(il, &il->power_data.sleep_cmd_next, false);
        il_set_tx_power(il, il->tx_power_next, false);
 
-       il->cfg->ops->utils->post_scan(il);
+       il->ops->post_scan(il);
 
 out:
        mutex_unlock(&il->mutex);
@@ -1815,7 +1808,7 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags)
                might_sleep();
        }
 
-       cmd.len = il->cfg->ops->utils->build_addsta_hcmd(sta, data);
+       cmd.len = il->ops->build_addsta_hcmd(sta, data);
        ret = il_send_cmd(il, &cmd);
 
        if (ret || (flags & CMD_ASYNC))
@@ -1832,8 +1825,7 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags)
 EXPORT_SYMBOL(il_send_add_sta);
 
 static void
-il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta,
-                     struct il_rxon_context *ctx)
+il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta)
 {
        struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
        __le32 sta_flags;
@@ -1874,7 +1866,7 @@ il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta,
            cpu_to_le32((u32) sta_ht_inf->
                        ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
 
-       if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))
+       if (il_is_ht40_tx_allowed(il, &sta->ht_cap))
                sta_flags |= STA_FLG_HT40_EN_MSK;
        else
                sta_flags &= ~STA_FLG_HT40_EN_MSK;
@@ -1890,8 +1882,8 @@ done:
  * should be called with sta_lock held
  */
 u8
-il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
-               const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
+il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap,
+               struct ieee80211_sta *sta)
 {
        struct il_station_entry *station;
        int i;
@@ -1899,9 +1891,9 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
        u16 rate;
 
        if (is_ap)
-               sta_id = ctx->ap_sta_id;
+               sta_id = IL_AP_ID;
        else if (is_broadcast_ether_addr(addr))
-               sta_id = ctx->bcast_sta_id;
+               sta_id = il->hw_params.bcast_id;
        else
                for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) {
                        if (!compare_ether_addr
@@ -1950,22 +1942,14 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
        memcpy(station->sta.sta.addr, addr, ETH_ALEN);
        station->sta.mode = 0;
        station->sta.sta.sta_id = sta_id;
-       station->sta.station_flags = ctx->station_flags;
-       station->ctxid = ctx->ctxid;
-
-       if (sta) {
-               struct il_station_priv_common *sta_priv;
-
-               sta_priv = (void *)sta->drv_priv;
-               sta_priv->ctx = ctx;
-       }
+       station->sta.station_flags = 0;
 
        /*
         * OK to call unconditionally, since local stations (IBSS BSSID
         * STA and broadcast STA) pass in a NULL sta, and mac80211
         * doesn't allow HT IBSS.
         */
-       il_set_ht_add_station(il, sta_id, sta, ctx);
+       il_set_ht_add_station(il, sta_id, sta);
 
        /* 3945 only */
        rate = (il->band == IEEE80211_BAND_5GHZ) ? RATE_6M_PLCP : RATE_1M_PLCP;
@@ -1983,9 +1967,8 @@ EXPORT_SYMBOL_GPL(il_prep_station);
  * il_add_station_common -
  */
 int
-il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx,
-                     const u8 *addr, bool is_ap, struct ieee80211_sta *sta,
-                     u8 *sta_id_r)
+il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap,
+                     struct ieee80211_sta *sta, u8 *sta_id_r)
 {
        unsigned long flags_spin;
        int ret = 0;
@@ -1994,7 +1977,7 @@ il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx,
 
        *sta_id_r = 0;
        spin_lock_irqsave(&il->sta_lock, flags_spin);
-       sta_id = il_prep_station(il, ctx, addr, is_ap, sta);
+       sta_id = il_prep_station(il, addr, is_ap, sta);
        if (sta_id == IL_INVALID_STATION) {
                IL_ERR("Unable to prepare station %pM for addition\n", addr);
                spin_unlock_irqrestore(&il->sta_lock, flags_spin);
@@ -2181,7 +2164,7 @@ EXPORT_SYMBOL_GPL(il_remove_station);
  * the ucode, e.g. unassociated RXON.
  */
 void
-il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx)
+il_clear_ucode_stations(struct il_priv *il)
 {
        int i;
        unsigned long flags_spin;
@@ -2191,9 +2174,6 @@ il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx)
 
        spin_lock_irqsave(&il->sta_lock, flags_spin);
        for (i = 0; i < il->hw_params.max_stations; i++) {
-               if (ctx && ctx->ctxid != il->stations[i].ctxid)
-                       continue;
-
                if (il->stations[i].used & IL_STA_UCODE_ACTIVE) {
                        D_INFO("Clearing ucode active for station %d\n", i);
                        il->stations[i].used &= ~IL_STA_UCODE_ACTIVE;
@@ -2216,7 +2196,7 @@ EXPORT_SYMBOL(il_clear_ucode_stations);
  * Function sleeps.
  */
 void
-il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)
+il_restore_stations(struct il_priv *il)
 {
        struct il_addsta_cmd sta_cmd;
        struct il_link_quality_cmd lq;
@@ -2234,8 +2214,6 @@ il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)
        D_ASSOC("Restoring all known stations ... start.\n");
        spin_lock_irqsave(&il->sta_lock, flags_spin);
        for (i = 0; i < il->hw_params.max_stations; i++) {
-               if (ctx->ctxid != il->stations[i].ctxid)
-                       continue;
                if ((il->stations[i].used & IL_STA_DRIVER_ACTIVE) &&
                    !(il->stations[i].used & IL_STA_UCODE_ACTIVE)) {
                        D_ASSOC("Restoring sta %pM\n",
@@ -2273,7 +2251,7 @@ il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)
                         * current LQ command
                         */
                        if (send_lq)
-                               il_send_lq_cmd(il, ctx, &lq, CMD_SYNC, true);
+                               il_send_lq_cmd(il, &lq, CMD_SYNC, true);
                        spin_lock_irqsave(&il->sta_lock, flags_spin);
                        il->stations[i].used &= ~IL_STA_UCODE_INPROGRESS;
                }
@@ -2353,15 +2331,14 @@ il_dump_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq)
  * RXON flags are updated and when LQ command is updated.
  */
 static bool
-il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx,
-                    struct il_link_quality_cmd *lq)
+il_is_lq_table_valid(struct il_priv *il, struct il_link_quality_cmd *lq)
 {
        int i;
 
-       if (ctx->ht.enabled)
+       if (il->ht.enabled)
                return true;
 
-       D_INFO("Channel %u is not an HT channel\n", ctx->active.channel);
+       D_INFO("Channel %u is not an HT channel\n", il->active.channel);
        for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
                if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
                        D_INFO("idx %d of LQ expects HT channel\n", i);
@@ -2382,8 +2359,8 @@ il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx,
  * progress.
  */
 int
-il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,
-              struct il_link_quality_cmd *lq, u8 flags, bool init)
+il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq,
+              u8 flags, bool init)
 {
        int ret = 0;
        unsigned long flags_spin;
@@ -2408,7 +2385,7 @@ il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,
        il_dump_lq_cmd(il, lq);
        BUG_ON(init && (cmd.flags & CMD_ASYNC));
 
-       if (il_is_lq_table_valid(il, ctx, lq))
+       if (il_is_lq_table_valid(il, lq))
                ret = il_send_cmd(il, &cmd);
        else
                ret = -EINVAL;
@@ -2436,13 +2413,16 @@ il_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        struct il_station_priv_common *sta_common = (void *)sta->drv_priv;
        int ret;
 
-       D_INFO("received request to remove station %pM\n", sta->addr);
        mutex_lock(&il->mutex);
-       D_INFO("proceeding to remove station %pM\n", sta->addr);
+       D_MAC80211("enter station %pM\n", sta->addr);
+
        ret = il_remove_station(il, sta_common->sta_id, sta->addr);
        if (ret)
                IL_ERR("Error removing station %pM\n", sta->addr);
+
+       D_MAC80211("leave ret %d\n", ret);
        mutex_unlock(&il->mutex);
+
        return ret;
 }
 EXPORT_SYMBOL(il_mac_sta_remove);
@@ -2648,7 +2628,7 @@ il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr,
         * All contexts have the same setting here due to it being
         * a module parameter, so OK to check any context.
         */
-       if (il->ctx.active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
+       if (il->active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
                return 0;
 
        if (!(fc & IEEE80211_FCTL_PROTECTED))
@@ -2739,7 +2719,7 @@ il_tx_queue_unmap(struct il_priv *il, int txq_id)
                return;
 
        while (q->write_ptr != q->read_ptr) {
-               il->cfg->ops->lib->txq_free_tfd(il, txq);
+               il->ops->txq_free_tfd(il, txq);
                q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd);
        }
 }
@@ -2772,8 +2752,8 @@ il_tx_queue_free(struct il_priv *il, int txq_id)
                                  txq->tfds, txq->q.dma_addr);
 
        /* De-alloc array of per-TFD driver data */
-       kfree(txq->txb);
-       txq->txb = NULL;
+       kfree(txq->skbs);
+       txq->skbs = NULL;
 
        /* deallocate arrays */
        kfree(txq->cmd);
@@ -2907,20 +2887,22 @@ EXPORT_SYMBOL(il_queue_space);
  * il_queue_init - Initialize queue's high/low-water and read/write idxes
  */
 static int
-il_queue_init(struct il_priv *il, struct il_queue *q, int count, int slots_num,
-             u32 id)
+il_queue_init(struct il_priv *il, struct il_queue *q, int slots, u32 id)
 {
-       q->n_bd = count;
-       q->n_win = slots_num;
-       q->id = id;
+       /*
+        * TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
+        * il_queue_inc_wrap and il_queue_dec_wrap are broken.
+        */
+       BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
+       /* FIXME: remove q->n_bd */
+       q->n_bd = TFD_QUEUE_SIZE_MAX;
 
-       /* count must be power-of-two size, otherwise il_queue_inc_wrap
-        * and il_queue_dec_wrap are broken. */
-       BUG_ON(!is_power_of_2(count));
+       q->n_win = slots;
+       q->id = id;
 
-       /* slots_num must be power-of-two size, otherwise
+       /* slots_must be power-of-two size, otherwise
         * il_get_cmd_idx is broken. */
-       BUG_ON(!is_power_of_2(slots_num));
+       BUG_ON(!is_power_of_2(slots));
 
        q->low_mark = q->n_win / 4;
        if (q->low_mark < 4)
@@ -2947,23 +2929,21 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id)
        /* Driver ilate data, only for Tx (not command) queues,
         * not shared with device. */
        if (id != il->cmd_queue) {
-               txq->txb = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->txb[0]),
-                                  GFP_KERNEL);
-               if (!txq->txb) {
-                       IL_ERR("kmalloc for auxiliary BD "
-                              "structures failed\n");
+               txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(struct skb *),
+                                   GFP_KERNEL);
+               if (!txq->skbs) {
+                       IL_ERR("Fail to alloc skbs\n");
                        goto error;
                }
-       } else {
-               txq->txb = NULL;
-       }
+       } else
+               txq->skbs = NULL;
 
        /* Circular buffer of transmit frame descriptors (TFDs),
         * shared with device */
        txq->tfds =
            dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL);
        if (!txq->tfds) {
-               IL_ERR("pci_alloc_consistent(%zd) failed\n", tfd_sz);
+               IL_ERR("Fail to alloc TFDs\n");
                goto error;
        }
        txq->q.id = id;
@@ -2971,8 +2951,8 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id)
        return 0;
 
 error:
-       kfree(txq->txb);
-       txq->txb = NULL;
+       kfree(txq->skbs);
+       txq->skbs = NULL;
 
        return -ENOMEM;
 }
@@ -2981,12 +2961,11 @@ error:
  * il_tx_queue_init - Allocate and initialize one tx/cmd queue
  */
 int
-il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
-                u32 txq_id)
+il_tx_queue_init(struct il_priv *il, u32 txq_id)
 {
-       int i, len;
-       int ret;
-       int actual_slots = slots_num;
+       int i, len, ret;
+       int slots, actual_slots;
+       struct il_tx_queue *txq = &il->txq[txq_id];
 
        /*
         * Alloc buffer array for commands (Tx or other types of commands).
@@ -2996,8 +2975,13 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
         * For normal Tx queues (all other queues), no super-size command
         * space is needed.
         */
-       if (txq_id == il->cmd_queue)
-               actual_slots++;
+       if (txq_id == il->cmd_queue) {
+               slots = TFD_CMD_SLOTS;
+               actual_slots = slots + 1;
+       } else {
+               slots = TFD_TX_CMD_SLOTS;
+               actual_slots = slots;
+       }
 
        txq->meta =
            kzalloc(sizeof(struct il_cmd_meta) * actual_slots, GFP_KERNEL);
@@ -3010,7 +2994,7 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
        len = sizeof(struct il_device_cmd);
        for (i = 0; i < actual_slots; i++) {
                /* only happens for cmd queue */
-               if (i == slots_num)
+               if (i == slots)
                        len = IL_MAX_CMD_SIZE;
 
                txq->cmd[i] = kmalloc(len, GFP_KERNEL);
@@ -3033,15 +3017,11 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
        if (txq_id < 4)
                il_set_swq_id(txq, txq_id, txq_id);
 
-       /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
-        * il_queue_inc_wrap and il_queue_dec_wrap are broken. */
-       BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-
        /* Initialize queue's high/low-water marks, and head/tail idxes */
-       il_queue_init(il, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+       il_queue_init(il, &txq->q, slots, txq_id);
 
        /* Tell device where to find queue */
-       il->cfg->ops->lib->txq_init(il, txq);
+       il->ops->txq_init(il, txq);
 
        return 0;
 err:
@@ -3056,23 +3036,27 @@ out_free_arrays:
 EXPORT_SYMBOL(il_tx_queue_init);
 
 void
-il_tx_queue_reset(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
-                 u32 txq_id)
+il_tx_queue_reset(struct il_priv *il, u32 txq_id)
 {
-       int actual_slots = slots_num;
+       int slots, actual_slots;
+       struct il_tx_queue *txq = &il->txq[txq_id];
 
-       if (txq_id == il->cmd_queue)
-               actual_slots++;
+       if (txq_id == il->cmd_queue) {
+               slots = TFD_CMD_SLOTS;
+               actual_slots = TFD_CMD_SLOTS + 1;
+       } else {
+               slots = TFD_TX_CMD_SLOTS;
+               actual_slots = TFD_TX_CMD_SLOTS;
+       }
 
        memset(txq->meta, 0, sizeof(struct il_cmd_meta) * actual_slots);
-
        txq->need_update = 0;
 
        /* Initialize queue's high/low-water marks, and head/tail idxes */
-       il_queue_init(il, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+       il_queue_init(il, &txq->q, slots, txq_id);
 
        /* Tell device where to find queue */
-       il->cfg->ops->lib->txq_init(il, txq);
+       il->ops->txq_init(il, txq);
 }
 EXPORT_SYMBOL(il_tx_queue_reset);
 
@@ -3100,7 +3084,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
        u32 idx;
        u16 fix_size;
 
-       cmd->len = il->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
+       cmd->len = il->ops->get_hcmd_size(cmd->id, cmd->len);
        fix_size = (u16) (cmd->len + sizeof(out_cmd->hdr));
 
        /* If any of the command structures end up being larger than
@@ -3179,9 +3163,9 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
 #endif
        txq->need_update = 1;
 
-       if (il->cfg->ops->lib->txq_update_byte_cnt_tbl)
+       if (il->ops->txq_update_byte_cnt_tbl)
                /* Set up entry in queue's byte count circular buffer */
-               il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq, 0);
+               il->ops->txq_update_byte_cnt_tbl(il, txq, 0);
 
        phys_addr =
            pci_map_single(il->pci_dev, &out_cmd->hdr, fix_size,
@@ -3189,8 +3173,8 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
        dma_unmap_addr_set(out_meta, mapping, phys_addr);
        dma_unmap_len_set(out_meta, len, fix_size);
 
-       il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size,
-                                                1, U32_PAD(cmd->len));
+       il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, 1,
+                                           U32_PAD(cmd->len));
 
        /* Increment and update queue's write idx */
        q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -3332,30 +3316,6 @@ EXPORT_SYMBOL(il_debug_level);
 const u8 il_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 EXPORT_SYMBOL(il_bcast_addr);
 
-/* This function both allocates and initializes hw and il. */
-struct ieee80211_hw *
-il_alloc_all(struct il_cfg *cfg)
-{
-       struct il_priv *il;
-       /* mac80211 allocates memory for this device instance, including
-        *   space for this driver's ilate structure */
-       struct ieee80211_hw *hw;
-
-       hw = ieee80211_alloc_hw(sizeof(struct il_priv),
-                               cfg->ops->ieee80211_ops);
-       if (hw == NULL) {
-               pr_err("%s: Can not allocate network device\n", cfg->name);
-               goto out;
-       }
-
-       il = hw->priv;
-       il->hw = hw;
-
-out:
-       return hw;
-}
-EXPORT_SYMBOL(il_alloc_all);
-
 #define MAX_BIT_RATE_40_MHZ 150        /* Mbps */
 #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
 static void
@@ -3562,10 +3522,9 @@ il_is_channel_extension(struct il_priv *il, enum ieee80211_band band,
 }
 
 bool
-il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx,
-                     struct ieee80211_sta_ht_cap *ht_cap)
+il_is_ht40_tx_allowed(struct il_priv *il, struct ieee80211_sta_ht_cap *ht_cap)
 {
-       if (!ctx->ht.enabled || !ctx->ht.is_40mhz)
+       if (!il->ht.enabled || !il->ht.is_40mhz)
                return false;
 
        /*
@@ -3581,8 +3540,8 @@ il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx,
 #endif
 
        return il_is_channel_extension(il, il->band,
-                                      le16_to_cpu(ctx->staging.channel),
-                                      ctx->ht.extension_chan_offset);
+                                      le16_to_cpu(il->staging.channel),
+                                      il->ht.extension_chan_offset);
 }
 EXPORT_SYMBOL(il_is_ht40_tx_allowed);
 
@@ -3621,22 +3580,22 @@ il_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
 }
 
 int
-il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx)
+il_send_rxon_timing(struct il_priv *il)
 {
        u64 tsf;
        s32 interval_tm, rem;
        struct ieee80211_conf *conf = NULL;
        u16 beacon_int;
-       struct ieee80211_vif *vif = ctx->vif;
+       struct ieee80211_vif *vif = il->vif;
 
        conf = &il->hw->conf;
 
        lockdep_assert_held(&il->mutex);
 
-       memset(&ctx->timing, 0, sizeof(struct il_rxon_time_cmd));
+       memset(&il->timing, 0, sizeof(struct il_rxon_time_cmd));
 
-       ctx->timing.timestamp = cpu_to_le64(il->timestamp);
-       ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval);
+       il->timing.timestamp = cpu_to_le64(il->timestamp);
+       il->timing.listen_interval = cpu_to_le16(conf->listen_interval);
 
        beacon_int = vif ? vif->bss_conf.beacon_int : 0;
 
@@ -3644,36 +3603,35 @@ il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx)
         * TODO: For IBSS we need to get atim_win from mac80211,
         *       for now just always use 0
         */
-       ctx->timing.atim_win = 0;
+       il->timing.atim_win = 0;
 
        beacon_int =
            il_adjust_beacon_interval(beacon_int,
                                      il->hw_params.max_beacon_itrvl *
                                      TIME_UNIT);
-       ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
+       il->timing.beacon_interval = cpu_to_le16(beacon_int);
 
        tsf = il->timestamp;    /* tsf is modifed by do_div: copy it */
        interval_tm = beacon_int * TIME_UNIT;
        rem = do_div(tsf, interval_tm);
-       ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
+       il->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
 
-       ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1;
+       il->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1;
 
        D_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n",
-               le16_to_cpu(ctx->timing.beacon_interval),
-               le32_to_cpu(ctx->timing.beacon_init_val),
-               le16_to_cpu(ctx->timing.atim_win));
+               le16_to_cpu(il->timing.beacon_interval),
+               le32_to_cpu(il->timing.beacon_init_val),
+               le16_to_cpu(il->timing.atim_win));
 
-       return il_send_cmd_pdu(il, ctx->rxon_timing_cmd, sizeof(ctx->timing),
-                              &ctx->timing);
+       return il_send_cmd_pdu(il, C_RXON_TIMING, sizeof(il->timing),
+                              &il->timing);
 }
 EXPORT_SYMBOL(il_send_rxon_timing);
 
 void
-il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx,
-                    int hw_decrypt)
+il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt)
 {
-       struct il_rxon_cmd *rxon = &ctx->staging;
+       struct il_rxon_cmd *rxon = &il->staging;
 
        if (hw_decrypt)
                rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
@@ -3685,9 +3643,9 @@ EXPORT_SYMBOL(il_set_rxon_hwcrypto);
 
 /* validate RXON structure is valid */
 int
-il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx)
+il_check_rxon_cmd(struct il_priv *il)
 {
-       struct il_rxon_cmd *rxon = &ctx->staging;
+       struct il_rxon_cmd *rxon = &il->staging;
        bool error = false;
 
        if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
@@ -3765,10 +3723,10 @@ EXPORT_SYMBOL(il_check_rxon_cmd);
  * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
  */
 int
-il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx)
+il_full_rxon_required(struct il_priv *il)
 {
-       const struct il_rxon_cmd *staging = &ctx->staging;
-       const struct il_rxon_cmd *active = &ctx->active;
+       const struct il_rxon_cmd *staging = &il->staging;
+       const struct il_rxon_cmd *active = &il->active;
 
 #define CHK(cond)                                                      \
        if ((cond)) {                                                   \
@@ -3785,7 +3743,7 @@ il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx)
        }
 
        /* These items are only settable from the full RXON command */
-       CHK(!il_is_associated_ctx(ctx));
+       CHK(!il_is_associated(il));
        CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr));
        CHK(compare_ether_addr(staging->node_addr, active->node_addr));
        CHK(compare_ether_addr
@@ -3819,13 +3777,13 @@ il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx)
 EXPORT_SYMBOL(il_full_rxon_required);
 
 u8
-il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx)
+il_get_lowest_plcp(struct il_priv *il)
 {
        /*
         * Assign the lowest rate -- should really get this from
         * the beacon skb from mac80211.
         */
-       if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK)
+       if (il->staging.flags & RXON_FLG_BAND_24G_MSK)
                return RATE_1M_PLCP;
        else
                return RATE_6M_PLCP;
@@ -3833,12 +3791,11 @@ il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx)
 EXPORT_SYMBOL(il_get_lowest_plcp);
 
 static void
-_il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
-               struct il_rxon_context *ctx)
+_il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf)
 {
-       struct il_rxon_cmd *rxon = &ctx->staging;
+       struct il_rxon_cmd *rxon = &il->staging;
 
-       if (!ctx->ht.enabled) {
+       if (!il->ht.enabled) {
                rxon->flags &=
                    ~(RXON_FLG_CHANNEL_MODE_MSK |
                      RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | RXON_FLG_HT40_PROT_MSK
@@ -3847,19 +3804,19 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
        }
 
        rxon->flags |=
-           cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
+           cpu_to_le32(il->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
 
        /* Set up channel bandwidth:
         * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
        /* clear the HT channel mode before set the mode */
        rxon->flags &=
            ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
-       if (il_is_ht40_tx_allowed(il, ctx, NULL)) {
+       if (il_is_ht40_tx_allowed(il, NULL)) {
                /* pure ht40 */
-               if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
+               if (il->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
                        rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
                        /* Note: control channel is opposite of extension channel */
-                       switch (ctx->ht.extension_chan_offset) {
+                       switch (il->ht.extension_chan_offset) {
                        case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
                                rxon->flags &=
                                    ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
@@ -3870,7 +3827,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
                        }
                } else {
                        /* Note: control channel is opposite of extension channel */
-                       switch (ctx->ht.extension_chan_offset) {
+                       switch (il->ht.extension_chan_offset) {
                        case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
                                rxon->flags &=
                                    ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
@@ -3891,18 +3848,18 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
                rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY;
        }
 
-       if (il->cfg->ops->hcmd->set_rxon_chain)
-               il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+       if (il->ops->set_rxon_chain)
+               il->ops->set_rxon_chain(il);
 
        D_ASSOC("rxon flags 0x%X operation mode :0x%X "
                "extension channel offset 0x%x\n", le32_to_cpu(rxon->flags),
-               ctx->ht.protection, ctx->ht.extension_chan_offset);
+               il->ht.protection, il->ht.extension_chan_offset);
 }
 
 void
 il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf)
 {
-       _il_set_rxon_ht(il, ht_conf, &il->ctx);
+       _il_set_rxon_ht(il, ht_conf);
 }
 EXPORT_SYMBOL(il_set_rxon_ht);
 
@@ -3925,7 +3882,7 @@ il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band)
 
        for (i = min; i < max; i++) {
                channel = il->channel_info[i].channel;
-               if (channel == le16_to_cpu(il->ctx.staging.channel))
+               if (channel == le16_to_cpu(il->staging.channel))
                        continue;
 
                ch_info = il_get_channel_info(il, band, channel);
@@ -3945,20 +3902,19 @@ EXPORT_SYMBOL(il_get_single_channel_number);
  * in the staging RXON flag structure based on the ch->band
  */
 int
-il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch,
-                   struct il_rxon_context *ctx)
+il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch)
 {
        enum ieee80211_band band = ch->band;
        u16 channel = ch->hw_value;
 
-       if (le16_to_cpu(ctx->staging.channel) == channel && il->band == band)
+       if (le16_to_cpu(il->staging.channel) == channel && il->band == band)
                return 0;
 
-       ctx->staging.channel = cpu_to_le16(channel);
+       il->staging.channel = cpu_to_le16(channel);
        if (band == IEEE80211_BAND_5GHZ)
-               ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
+               il->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
        else
-               ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
+               il->staging.flags |= RXON_FLG_BAND_24G_MSK;
 
        il->band = band;
 
@@ -3969,24 +3925,24 @@ il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch,
 EXPORT_SYMBOL(il_set_rxon_channel);
 
 void
-il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx,
-                     enum ieee80211_band band, struct ieee80211_vif *vif)
+il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band,
+                     struct ieee80211_vif *vif)
 {
        if (band == IEEE80211_BAND_5GHZ) {
-               ctx->staging.flags &=
+               il->staging.flags &=
                    ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
                      RXON_FLG_CCK_MSK);
-               ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+               il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
        } else {
                /* Copied from il_post_associate() */
                if (vif && vif->bss_conf.use_short_slot)
-                       ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+                       il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
                else
-                       ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+                       il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
-               ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
-               ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
-               ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
+               il->staging.flags |= RXON_FLG_BAND_24G_MSK;
+               il->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
+               il->staging.flags &= ~RXON_FLG_CCK_MSK;
        }
 }
 EXPORT_SYMBOL(il_set_flags_for_band);
@@ -3995,69 +3951,60 @@ EXPORT_SYMBOL(il_set_flags_for_band);
  * initialize rxon structure with default values from eeprom
  */
 void
-il_connection_init_rx_config(struct il_priv *il, struct il_rxon_context *ctx)
+il_connection_init_rx_config(struct il_priv *il)
 {
        const struct il_channel_info *ch_info;
 
-       memset(&ctx->staging, 0, sizeof(ctx->staging));
-
-       if (!ctx->vif) {
-               ctx->staging.dev_type = ctx->unused_devtype;
-       } else
-               switch (ctx->vif->type) {
-
-               case NL80211_IFTYPE_STATION:
-                       ctx->staging.dev_type = ctx->station_devtype;
-                       ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
-                       break;
-
-               case NL80211_IFTYPE_ADHOC:
-                       ctx->staging.dev_type = ctx->ibss_devtype;
-                       ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
-                       ctx->staging.filter_flags =
-                           RXON_FILTER_BCON_AWARE_MSK |
-                           RXON_FILTER_ACCEPT_GRP_MSK;
-                       break;
-
-               default:
-                       IL_ERR("Unsupported interface type %d\n",
-                              ctx->vif->type);
-                       break;
-               }
+       memset(&il->staging, 0, sizeof(il->staging));
+
+       if (!il->vif) {
+               il->staging.dev_type = RXON_DEV_TYPE_ESS;
+       } else if (il->vif->type == NL80211_IFTYPE_STATION) {
+               il->staging.dev_type = RXON_DEV_TYPE_ESS;
+               il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
+       } else if (il->vif->type == NL80211_IFTYPE_ADHOC) {
+               il->staging.dev_type = RXON_DEV_TYPE_IBSS;
+               il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
+               il->staging.filter_flags =
+                   RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
+       } else {
+               IL_ERR("Unsupported interface type %d\n", il->vif->type);
+               return;
+       }
 
 #if 0
        /* TODO:  Figure out when short_preamble would be set and cache from
         * that */
        if (!hw_to_local(il->hw)->short_preamble)
-               ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+               il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
        else
-               ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+               il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 #endif
 
        ch_info =
-           il_get_channel_info(il, il->band, le16_to_cpu(ctx->active.channel));
+           il_get_channel_info(il, il->band, le16_to_cpu(il->active.channel));
 
        if (!ch_info)
                ch_info = &il->channel_info[0];
 
-       ctx->staging.channel = cpu_to_le16(ch_info->channel);
+       il->staging.channel = cpu_to_le16(ch_info->channel);
        il->band = ch_info->band;
 
-       il_set_flags_for_band(il, ctx, il->band, ctx->vif);
+       il_set_flags_for_band(il, il->band, il->vif);
 
-       ctx->staging.ofdm_basic_rates =
+       il->staging.ofdm_basic_rates =
            (IL_OFDM_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF;
-       ctx->staging.cck_basic_rates =
+       il->staging.cck_basic_rates =
            (IL_CCK_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF;
 
        /* clear both MIX and PURE40 mode flag */
-       ctx->staging.flags &=
+       il->staging.flags &=
            ~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40);
-       if (ctx->vif)
-               memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
+       if (il->vif)
+               memcpy(il->staging.node_addr, il->vif->addr, ETH_ALEN);
 
-       ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;
-       ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
+       il->staging.ofdm_ht_single_stream_basic_rates = 0xff;
+       il->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
 }
 EXPORT_SYMBOL(il_connection_init_rx_config);
 
@@ -4084,10 +4031,10 @@ il_set_rate(struct il_priv *il)
 
        D_RATE("Set active_rate = %0x\n", il->active_rate);
 
-       il->ctx.staging.cck_basic_rates =
+       il->staging.cck_basic_rates =
            (IL_CCK_BASIC_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF;
 
-       il->ctx.staging.ofdm_basic_rates =
+       il->staging.ofdm_basic_rates =
            (IL_OFDM_BASIC_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF;
 }
 EXPORT_SYMBOL(il_set_rate);
@@ -4095,13 +4042,11 @@ EXPORT_SYMBOL(il_set_rate);
 void
 il_chswitch_done(struct il_priv *il, bool is_success)
 {
-       struct il_rxon_context *ctx = &il->ctx;
-
        if (test_bit(S_EXIT_PENDING, &il->status))
                return;
 
        if (test_and_clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status))
-               ieee80211_chswitch_done(ctx->vif, is_success);
+               ieee80211_chswitch_done(il->vif, is_success);
 }
 EXPORT_SYMBOL(il_chswitch_done);
 
@@ -4110,16 +4055,14 @@ il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb)
 {
        struct il_rx_pkt *pkt = rxb_addr(rxb);
        struct il_csa_notification *csa = &(pkt->u.csa_notif);
-
-       struct il_rxon_context *ctx = &il->ctx;
-       struct il_rxon_cmd *rxon = (void *)&ctx->active;
+       struct il_rxon_cmd *rxon = (void *)&il->active;
 
        if (!test_bit(S_CHANNEL_SWITCH_PENDING, &il->status))
                return;
 
        if (!le32_to_cpu(csa->status) && csa->channel == il->switch_channel) {
                rxon->channel = csa->channel;
-               ctx->staging.channel = csa->channel;
+               il->staging.channel = csa->channel;
                D_11H("CSA notif: channel %d\n", le16_to_cpu(csa->channel));
                il_chswitch_done(il, true);
        } else {
@@ -4132,9 +4075,9 @@ EXPORT_SYMBOL(il_hdl_csa);
 
 #ifdef CONFIG_IWLEGACY_DEBUG
 void
-il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx)
+il_print_rx_config_cmd(struct il_priv *il)
 {
-       struct il_rxon_cmd *rxon = &ctx->staging;
+       struct il_rxon_cmd *rxon = &il->staging;
 
        D_RADIO("RX CONFIG:\n");
        il_print_hex_dump(il, IL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
@@ -4164,12 +4107,12 @@ il_irq_handle_error(struct il_priv *il)
 
        IL_ERR("Loaded firmware version: %s\n", il->hw->wiphy->fw_version);
 
-       il->cfg->ops->lib->dump_nic_error_log(il);
-       if (il->cfg->ops->lib->dump_fh)
-               il->cfg->ops->lib->dump_fh(il, NULL, false);
+       il->ops->dump_nic_error_log(il);
+       if (il->ops->dump_fh)
+               il->ops->dump_fh(il, NULL, false);
 #ifdef CONFIG_IWLEGACY_DEBUG
        if (il_get_debug_level(il) & IL_DL_FW_ERRORS)
-               il_print_rx_config_cmd(il, &il->ctx);
+               il_print_rx_config_cmd(il);
 #endif
 
        wake_up(&il->wait_command_queue);
@@ -4189,17 +4132,17 @@ il_irq_handle_error(struct il_priv *il)
 EXPORT_SYMBOL(il_irq_handle_error);
 
 static int
-il_apm_stop_master(struct il_priv *il)
+_il_apm_stop_master(struct il_priv *il)
 {
        int ret = 0;
 
        /* stop device's busmaster DMA activity */
-       il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+       _il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 
        ret =
            _il_poll_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
                         CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
-       if (ret)
+       if (ret < 0)
                IL_WARN("Master Disable Timed Out, 100 usec\n");
 
        D_INFO("stop master\n");
@@ -4208,15 +4151,17 @@ il_apm_stop_master(struct il_priv *il)
 }
 
 void
-il_apm_stop(struct il_priv *il)
+_il_apm_stop(struct il_priv *il)
 {
+       lockdep_assert_held(&il->reg_lock);
+
        D_INFO("Stop card, put in low power state\n");
 
        /* Stop device's DMA activity */
-       il_apm_stop_master(il);
+       _il_apm_stop_master(il);
 
        /* Reset the entire device */
-       il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+       _il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 
        udelay(10);
 
@@ -4224,7 +4169,18 @@ il_apm_stop(struct il_priv *il)
         * Clear "initialization complete" bit to move adapter from
         * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
         */
-       il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+       _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+}
+EXPORT_SYMBOL(_il_apm_stop);
+
+void
+il_apm_stop(struct il_priv *il)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&il->reg_lock, flags);
+       _il_apm_stop(il);
+       spin_unlock_irqrestore(&il->reg_lock, flags);
 }
 EXPORT_SYMBOL(il_apm_stop);
 
@@ -4276,7 +4232,7 @@ il_apm_init(struct il_priv *il)
         * If not (unlikely), enable L0S, so there is at least some
         *    power savings, even without L1.
         */
-       if (il->cfg->base_params->set_l0s) {
+       if (il->cfg->set_l0s) {
                lctl = il_pcie_link_ctl(il);
                if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
                    PCI_CFG_LINK_CTRL_VAL_L1_EN) {
@@ -4293,9 +4249,9 @@ il_apm_init(struct il_priv *il)
        }
 
        /* Configure analog phase-lock-loop before activating to D0A */
-       if (il->cfg->base_params->pll_cfg_val)
+       if (il->cfg->pll_cfg_val)
                il_set_bit(il, CSR_ANA_PLL_CFG,
-                          il->cfg->base_params->pll_cfg_val);
+                          il->cfg->pll_cfg_val);
 
        /*
         * Set "initialization complete" bit to move adapter from
@@ -4325,7 +4281,7 @@ il_apm_init(struct il_priv *il)
         * do not disable clocks.  This preserves any hardware bits already
         * set by default in "CLK_CTRL_REG" after reset.
         */
-       if (il->cfg->base_params->use_bsm)
+       if (il->cfg->use_bsm)
                il_wr_prph(il, APMG_CLK_EN_REG,
                           APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
        else
@@ -4347,14 +4303,13 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force)
        int ret;
        s8 prev_tx_power;
        bool defer;
-       struct il_rxon_context *ctx = &il->ctx;
 
        lockdep_assert_held(&il->mutex);
 
        if (il->tx_power_user_lmt == tx_power && !force)
                return 0;
 
-       if (!il->cfg->ops->lib->send_tx_power)
+       if (!il->ops->send_tx_power)
                return -EOPNOTSUPP;
 
        /* 0 dBm mean 1 milliwatt */
@@ -4378,7 +4333,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force)
 
        /* do not set tx power when scanning or channel changing */
        defer = test_bit(S_SCANNING, &il->status) ||
-           memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging));
+           memcmp(&il->active, &il->staging, sizeof(il->staging));
        if (defer && !force) {
                D_INFO("Deferring tx power set\n");
                return 0;
@@ -4387,7 +4342,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force)
        prev_tx_power = il->tx_power_user_lmt;
        il->tx_power_user_lmt = tx_power;
 
-       ret = il->cfg->ops->lib->send_tx_power(il);
+       ret = il->ops->send_tx_power(il);
 
        /* if fail to set tx_power, restore the orig. tx power */
        if (ret) {
@@ -4505,15 +4460,15 @@ il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
 
        spin_lock_irqsave(&il->lock, flags);
 
-       il->ctx.qos_data.def_qos_parm.ac[q].cw_min =
+       il->qos_data.def_qos_parm.ac[q].cw_min =
            cpu_to_le16(params->cw_min);
-       il->ctx.qos_data.def_qos_parm.ac[q].cw_max =
+       il->qos_data.def_qos_parm.ac[q].cw_max =
            cpu_to_le16(params->cw_max);
-       il->ctx.qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
-       il->ctx.qos_data.def_qos_parm.ac[q].edca_txop =
+       il->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
+       il->qos_data.def_qos_parm.ac[q].edca_txop =
            cpu_to_le16((params->txop * 32));
 
-       il->ctx.qos_data.def_qos_parm.ac[q].reserved1 = 0;
+       il->qos_data.def_qos_parm.ac[q].reserved1 = 0;
 
        spin_unlock_irqrestore(&il->lock, flags);
 
@@ -4526,60 +4481,36 @@ int
 il_mac_tx_last_beacon(struct ieee80211_hw *hw)
 {
        struct il_priv *il = hw->priv;
+       int ret;
 
-       return il->ibss_manager == IL_IBSS_MANAGER;
-}
-EXPORT_SYMBOL_GPL(il_mac_tx_last_beacon);
-
-static int
-il_set_mode(struct il_priv *il, struct il_rxon_context *ctx)
-{
-       il_connection_init_rx_config(il, ctx);
+       D_MAC80211("enter\n");
 
-       if (il->cfg->ops->hcmd->set_rxon_chain)
-               il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+       ret = (il->ibss_manager == IL_IBSS_MANAGER);
 
-       return il_commit_rxon(il, ctx);
+       D_MAC80211("leave ret %d\n", ret);
+       return ret;
 }
+EXPORT_SYMBOL_GPL(il_mac_tx_last_beacon);
 
 static int
-il_setup_interface(struct il_priv *il, struct il_rxon_context *ctx)
+il_set_mode(struct il_priv *il)
 {
-       struct ieee80211_vif *vif = ctx->vif;
-       int err;
+       il_connection_init_rx_config(il);
 
-       lockdep_assert_held(&il->mutex);
+       if (il->ops->set_rxon_chain)
+               il->ops->set_rxon_chain(il);
 
-       /*
-        * This variable will be correct only when there's just
-        * a single context, but all code using it is for hardware
-        * that supports only one context.
-        */
-       il->iw_mode = vif->type;
-
-       ctx->is_active = true;
-
-       err = il_set_mode(il, ctx);
-       if (err) {
-               if (!ctx->always_active)
-                       ctx->is_active = false;
-               return err;
-       }
-
-       return 0;
+       return il_commit_rxon(il);
 }
 
 int
 il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
        struct il_priv *il = hw->priv;
-       struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
        int err;
-       u32 modes;
-
-       D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr);
 
        mutex_lock(&il->mutex);
+       D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr);
 
        if (!il_is_ready_rf(il)) {
                IL_WARN("Try to add interface when device not ready\n");
@@ -4587,32 +4518,24 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                goto out;
        }
 
-       /* check if busy context is exclusive */
-       if (il->ctx.vif &&
-           (il->ctx.exclusive_interface_modes & BIT(il->ctx.vif->type))) {
-               err = -EINVAL;
-               goto out;
-       }
-
-       modes = il->ctx.interface_modes | il->ctx.exclusive_interface_modes;
-       if (!(modes & BIT(vif->type))) {
+       if (il->vif) {
                err = -EOPNOTSUPP;
                goto out;
        }
 
-       vif_priv->ctx = &il->ctx;
-       il->ctx.vif = vif;
+       il->vif = vif;
+       il->iw_mode = vif->type;
 
-       err = il_setup_interface(il, &il->ctx);
+       err = il_set_mode(il);
        if (err) {
-               il->ctx.vif = NULL;
+               il->vif = NULL;
                il->iw_mode = NL80211_IFTYPE_STATION;
        }
 
 out:
+       D_MAC80211("leave err %d\n", err);
        mutex_unlock(&il->mutex);
 
-       D_MAC80211("leave\n");
        return err;
 }
 EXPORT_SYMBOL(il_mac_add_interface);
@@ -4621,8 +4544,6 @@ static void
 il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
                      bool mode_change)
 {
-       struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
-
        lockdep_assert_held(&il->mutex);
 
        if (il->scan_vif == vif) {
@@ -4630,33 +4551,27 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
                il_force_scan_end(il);
        }
 
-       if (!mode_change) {
-               il_set_mode(il, ctx);
-               if (!ctx->always_active)
-                       ctx->is_active = false;
-       }
+       if (!mode_change)
+               il_set_mode(il);
+
 }
 
 void
 il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
        struct il_priv *il = hw->priv;
-       struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
-
-       D_MAC80211("enter\n");
 
        mutex_lock(&il->mutex);
+       D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr);
 
-       WARN_ON(ctx->vif != vif);
-       ctx->vif = NULL;
+       WARN_ON(il->vif != vif);
+       il->vif = NULL;
 
        il_teardown_interface(il, vif, false);
-
        memset(il->bssid, 0, ETH_ALEN);
-       mutex_unlock(&il->mutex);
 
        D_MAC80211("leave\n");
-
+       mutex_unlock(&il->mutex);
 }
 EXPORT_SYMBOL(il_mac_remove_interface);
 
@@ -4666,7 +4581,7 @@ il_alloc_txq_mem(struct il_priv *il)
        if (!il->txq)
                il->txq =
                    kzalloc(sizeof(struct il_tx_queue) *
-                           il->cfg->base_params->num_of_queues, GFP_KERNEL);
+                           il->cfg->num_of_queues, GFP_KERNEL);
        if (!il->txq) {
                IL_ERR("Not enough memory for txq\n");
                return -ENOMEM;
@@ -4676,259 +4591,12 @@ il_alloc_txq_mem(struct il_priv *il)
 EXPORT_SYMBOL(il_alloc_txq_mem);
 
 void
-il_txq_mem(struct il_priv *il)
+il_free_txq_mem(struct il_priv *il)
 {
        kfree(il->txq);
        il->txq = NULL;
 }
-EXPORT_SYMBOL(il_txq_mem);
-
-#ifdef CONFIG_IWLEGACY_DEBUGFS
-
-#define IL_TRAFFIC_DUMP_SIZE   (IL_TRAFFIC_ENTRY_SIZE * IL_TRAFFIC_ENTRIES)
-
-void
-il_reset_traffic_log(struct il_priv *il)
-{
-       il->tx_traffic_idx = 0;
-       il->rx_traffic_idx = 0;
-       if (il->tx_traffic)
-               memset(il->tx_traffic, 0, IL_TRAFFIC_DUMP_SIZE);
-       if (il->rx_traffic)
-               memset(il->rx_traffic, 0, IL_TRAFFIC_DUMP_SIZE);
-}
-
-int
-il_alloc_traffic_mem(struct il_priv *il)
-{
-       u32 traffic_size = IL_TRAFFIC_DUMP_SIZE;
-
-       if (il_debug_level & IL_DL_TX) {
-               if (!il->tx_traffic) {
-                       il->tx_traffic = kzalloc(traffic_size, GFP_KERNEL);
-                       if (!il->tx_traffic)
-                               return -ENOMEM;
-               }
-       }
-       if (il_debug_level & IL_DL_RX) {
-               if (!il->rx_traffic) {
-                       il->rx_traffic = kzalloc(traffic_size, GFP_KERNEL);
-                       if (!il->rx_traffic)
-                               return -ENOMEM;
-               }
-       }
-       il_reset_traffic_log(il);
-       return 0;
-}
-EXPORT_SYMBOL(il_alloc_traffic_mem);
-
-void
-il_free_traffic_mem(struct il_priv *il)
-{
-       kfree(il->tx_traffic);
-       il->tx_traffic = NULL;
-
-       kfree(il->rx_traffic);
-       il->rx_traffic = NULL;
-}
-EXPORT_SYMBOL(il_free_traffic_mem);
-
-void
-il_dbg_log_tx_data_frame(struct il_priv *il, u16 length,
-                        struct ieee80211_hdr *header)
-{
-       __le16 fc;
-       u16 len;
-
-       if (likely(!(il_debug_level & IL_DL_TX)))
-               return;
-
-       if (!il->tx_traffic)
-               return;
-
-       fc = header->frame_control;
-       if (ieee80211_is_data(fc)) {
-               len =
-                   (length >
-                    IL_TRAFFIC_ENTRY_SIZE) ? IL_TRAFFIC_ENTRY_SIZE : length;
-               memcpy((il->tx_traffic +
-                       (il->tx_traffic_idx * IL_TRAFFIC_ENTRY_SIZE)), header,
-                      len);
-               il->tx_traffic_idx =
-                   (il->tx_traffic_idx + 1) % IL_TRAFFIC_ENTRIES;
-       }
-}
-EXPORT_SYMBOL(il_dbg_log_tx_data_frame);
-
-void
-il_dbg_log_rx_data_frame(struct il_priv *il, u16 length,
-                        struct ieee80211_hdr *header)
-{
-       __le16 fc;
-       u16 len;
-
-       if (likely(!(il_debug_level & IL_DL_RX)))
-               return;
-
-       if (!il->rx_traffic)
-               return;
-
-       fc = header->frame_control;
-       if (ieee80211_is_data(fc)) {
-               len =
-                   (length >
-                    IL_TRAFFIC_ENTRY_SIZE) ? IL_TRAFFIC_ENTRY_SIZE : length;
-               memcpy((il->rx_traffic +
-                       (il->rx_traffic_idx * IL_TRAFFIC_ENTRY_SIZE)), header,
-                      len);
-               il->rx_traffic_idx =
-                   (il->rx_traffic_idx + 1) % IL_TRAFFIC_ENTRIES;
-       }
-}
-EXPORT_SYMBOL(il_dbg_log_rx_data_frame);
-
-const char *
-il_get_mgmt_string(int cmd)
-{
-       switch (cmd) {
-               IL_CMD(MANAGEMENT_ASSOC_REQ);
-               IL_CMD(MANAGEMENT_ASSOC_RESP);
-               IL_CMD(MANAGEMENT_REASSOC_REQ);
-               IL_CMD(MANAGEMENT_REASSOC_RESP);
-               IL_CMD(MANAGEMENT_PROBE_REQ);
-               IL_CMD(MANAGEMENT_PROBE_RESP);
-               IL_CMD(MANAGEMENT_BEACON);
-               IL_CMD(MANAGEMENT_ATIM);
-               IL_CMD(MANAGEMENT_DISASSOC);
-               IL_CMD(MANAGEMENT_AUTH);
-               IL_CMD(MANAGEMENT_DEAUTH);
-               IL_CMD(MANAGEMENT_ACTION);
-       default:
-               return "UNKNOWN";
-
-       }
-}
-
-const char *
-il_get_ctrl_string(int cmd)
-{
-       switch (cmd) {
-               IL_CMD(CONTROL_BACK_REQ);
-               IL_CMD(CONTROL_BACK);
-               IL_CMD(CONTROL_PSPOLL);
-               IL_CMD(CONTROL_RTS);
-               IL_CMD(CONTROL_CTS);
-               IL_CMD(CONTROL_ACK);
-               IL_CMD(CONTROL_CFEND);
-               IL_CMD(CONTROL_CFENDACK);
-       default:
-               return "UNKNOWN";
-
-       }
-}
-
-void
-il_clear_traffic_stats(struct il_priv *il)
-{
-       memset(&il->tx_stats, 0, sizeof(struct traffic_stats));
-       memset(&il->rx_stats, 0, sizeof(struct traffic_stats));
-}
-
-/*
- * if CONFIG_IWLEGACY_DEBUGFS defined,
- * il_update_stats function will
- * record all the MGMT, CTRL and DATA pkt for both TX and Rx pass
- * Use debugFs to display the rx/rx_stats
- * if CONFIG_IWLEGACY_DEBUGFS not being defined, then no MGMT and CTRL
- * information will be recorded, but DATA pkt still will be recorded
- * for the reason of il_led.c need to control the led blinking based on
- * number of tx and rx data.
- *
- */
-void
-il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)
-{
-       struct traffic_stats *stats;
-
-       if (is_tx)
-               stats = &il->tx_stats;
-       else
-               stats = &il->rx_stats;
-
-       if (ieee80211_is_mgmt(fc)) {
-               switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
-               case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
-                       stats->mgmt[MANAGEMENT_ASSOC_REQ]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
-                       stats->mgmt[MANAGEMENT_ASSOC_RESP]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
-                       stats->mgmt[MANAGEMENT_REASSOC_REQ]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
-                       stats->mgmt[MANAGEMENT_REASSOC_RESP]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
-                       stats->mgmt[MANAGEMENT_PROBE_REQ]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
-                       stats->mgmt[MANAGEMENT_PROBE_RESP]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_BEACON):
-                       stats->mgmt[MANAGEMENT_BEACON]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_ATIM):
-                       stats->mgmt[MANAGEMENT_ATIM]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
-                       stats->mgmt[MANAGEMENT_DISASSOC]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_AUTH):
-                       stats->mgmt[MANAGEMENT_AUTH]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
-                       stats->mgmt[MANAGEMENT_DEAUTH]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_ACTION):
-                       stats->mgmt[MANAGEMENT_ACTION]++;
-                       break;
-               }
-       } else if (ieee80211_is_ctl(fc)) {
-               switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
-               case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):
-                       stats->ctrl[CONTROL_BACK_REQ]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_BACK):
-                       stats->ctrl[CONTROL_BACK]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_PSPOLL):
-                       stats->ctrl[CONTROL_PSPOLL]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_RTS):
-                       stats->ctrl[CONTROL_RTS]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_CTS):
-                       stats->ctrl[CONTROL_CTS]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_ACK):
-                       stats->ctrl[CONTROL_ACK]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_CFEND):
-                       stats->ctrl[CONTROL_CFEND]++;
-                       break;
-               case cpu_to_le16(IEEE80211_STYPE_CFENDACK):
-                       stats->ctrl[CONTROL_CFENDACK]++;
-                       break;
-               }
-       } else {
-               /* data */
-               stats->data_cnt++;
-               stats->data_bytes += len;
-       }
-}
-EXPORT_SYMBOL(il_update_stats);
-#endif
+EXPORT_SYMBOL(il_free_txq_mem);
 
 int
 il_force_reset(struct il_priv *il, bool external)
@@ -4987,15 +4655,18 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        enum nl80211_iftype newtype, bool newp2p)
 {
        struct il_priv *il = hw->priv;
-       struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
-       u32 modes;
        int err;
 
-       newtype = ieee80211_iftype_p2p(newtype, newp2p);
-
        mutex_lock(&il->mutex);
+       D_MAC80211("enter: type %d, addr %pM newtype %d newp2p %d\n",
+                   vif->type, vif->addr, newtype, newp2p);
 
-       if (!ctx->vif || !il_is_ready_rf(il)) {
+       if (newp2p) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (!il->vif || !il_is_ready_rf(il)) {
                /*
                 * Huh? But wait ... this can maybe happen when
                 * we're in the middle of a firmware restart!
@@ -5004,23 +4675,11 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                goto out;
        }
 
-       modes = ctx->interface_modes | ctx->exclusive_interface_modes;
-       if (!(modes & BIT(newtype))) {
-               err = -EOPNOTSUPP;
-               goto out;
-       }
-
-       if ((il->ctx.exclusive_interface_modes & BIT(il->ctx.vif->type)) ||
-           (il->ctx.exclusive_interface_modes & BIT(newtype))) {
-               err = -EINVAL;
-               goto out;
-       }
-
        /* success */
        il_teardown_interface(il, vif, true);
        vif->type = newtype;
-       vif->p2p = newp2p;
-       err = il_setup_interface(il, ctx);
+       vif->p2p = false;
+       err = il_set_mode(il);
        WARN_ON(err);
        /*
         * We've switched internally, but submitting to the
@@ -5032,7 +4691,9 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        err = 0;
 
 out:
+       D_MAC80211("leave err %d\n", err);
        mutex_unlock(&il->mutex);
+
        return err;
 }
 EXPORT_SYMBOL(il_mac_change_interface);
@@ -5056,11 +4717,11 @@ il_check_stuck_queue(struct il_priv *il, int cnt)
 
        timeout =
            txq->time_stamp +
-           msecs_to_jiffies(il->cfg->base_params->wd_timeout);
+           msecs_to_jiffies(il->cfg->wd_timeout);
 
        if (time_after(jiffies, timeout)) {
                IL_ERR("Queue %d stuck for %u ms.\n", q->id,
-                      il->cfg->base_params->wd_timeout);
+                      il->cfg->wd_timeout);
                ret = il_force_reset(il, false);
                return (ret == -EAGAIN) ? 0 : 1;
        }
@@ -5088,7 +4749,7 @@ il_bg_watchdog(unsigned long data)
        if (test_bit(S_EXIT_PENDING, &il->status))
                return;
 
-       timeout = il->cfg->base_params->wd_timeout;
+       timeout = il->cfg->wd_timeout;
        if (timeout == 0)
                return;
 
@@ -5115,7 +4776,7 @@ EXPORT_SYMBOL(il_bg_watchdog);
 void
 il_setup_watchdog(struct il_priv *il)
 {
-       unsigned int timeout = il->cfg->base_params->wd_timeout;
+       unsigned int timeout = il->cfg->wd_timeout;
 
        if (timeout)
                mod_timer(&il->watchdog,
@@ -5229,9 +4890,9 @@ il_pci_resume(struct device *device)
                hw_rfkill = true;
 
        if (hw_rfkill)
-               set_bit(S_RF_KILL_HW, &il->status);
+               set_bit(S_RFKILL, &il->status);
        else
-               clear_bit(S_RF_KILL_HW, &il->status);
+               clear_bit(S_RFKILL, &il->status);
 
        wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rfkill);
 
@@ -5252,28 +4913,25 @@ EXPORT_SYMBOL(il_pm_ops);
 #endif /* CONFIG_PM */
 
 static void
-il_update_qos(struct il_priv *il, struct il_rxon_context *ctx)
+il_update_qos(struct il_priv *il)
 {
        if (test_bit(S_EXIT_PENDING, &il->status))
                return;
 
-       if (!ctx->is_active)
-               return;
-
-       ctx->qos_data.def_qos_parm.qos_flags = 0;
+       il->qos_data.def_qos_parm.qos_flags = 0;
 
-       if (ctx->qos_data.qos_active)
-               ctx->qos_data.def_qos_parm.qos_flags |=
+       if (il->qos_data.qos_active)
+               il->qos_data.def_qos_parm.qos_flags |=
                    QOS_PARAM_FLG_UPDATE_EDCA_MSK;
 
-       if (ctx->ht.enabled)
-               ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+       if (il->ht.enabled)
+               il->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
 
        D_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
-             ctx->qos_data.qos_active, ctx->qos_data.def_qos_parm.qos_flags);
+             il->qos_data.qos_active, il->qos_data.def_qos_parm.qos_flags);
 
-       il_send_cmd_pdu_async(il, ctx->qos_cmd, sizeof(struct il_qosparam_cmd),
-                             &ctx->qos_data.def_qos_parm, NULL);
+       il_send_cmd_pdu_async(il, C_QOS_PARAM, sizeof(struct il_qosparam_cmd),
+                             &il->qos_data.def_qos_parm, NULL);
 }
 
 /**
@@ -5287,19 +4945,14 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
        struct ieee80211_conf *conf = &hw->conf;
        struct ieee80211_channel *channel = conf->channel;
        struct il_ht_config *ht_conf = &il->current_ht_config;
-       struct il_rxon_context *ctx = &il->ctx;
        unsigned long flags = 0;
        int ret = 0;
        u16 ch;
        int scan_active = 0;
        bool ht_changed = false;
 
-       if (WARN_ON(!il->cfg->ops->legacy))
-               return -EOPNOTSUPP;
-
        mutex_lock(&il->mutex);
-
-       D_MAC80211("enter to channel %d changed 0x%X\n", channel->hw_value,
+       D_MAC80211("enter: channel %d changed 0x%X\n", channel->hw_value,
                   changed);
 
        if (unlikely(test_bit(S_SCANNING, &il->status))) {
@@ -5319,8 +4972,8 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
                 * set up the SM PS mode to OFF if an HT channel is
                 * configured.
                 */
-               if (il->cfg->ops->hcmd->set_rxon_chain)
-                       il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
+               if (il->ops->set_rxon_chain)
+                       il->ops->set_rxon_chain(il);
        }
 
        /* during scanning mac80211 will delay channel setting until
@@ -5349,48 +5002,48 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
                spin_lock_irqsave(&il->lock, flags);
 
                /* Configure HT40 channels */
-               if (ctx->ht.enabled != conf_is_ht(conf)) {
-                       ctx->ht.enabled = conf_is_ht(conf);
+               if (il->ht.enabled != conf_is_ht(conf)) {
+                       il->ht.enabled = conf_is_ht(conf);
                        ht_changed = true;
                }
-               if (ctx->ht.enabled) {
+               if (il->ht.enabled) {
                        if (conf_is_ht40_minus(conf)) {
-                               ctx->ht.extension_chan_offset =
+                               il->ht.extension_chan_offset =
                                    IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-                               ctx->ht.is_40mhz = true;
+                               il->ht.is_40mhz = true;
                        } else if (conf_is_ht40_plus(conf)) {
-                               ctx->ht.extension_chan_offset =
+                               il->ht.extension_chan_offset =
                                    IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-                               ctx->ht.is_40mhz = true;
+                               il->ht.is_40mhz = true;
                        } else {
-                               ctx->ht.extension_chan_offset =
+                               il->ht.extension_chan_offset =
                                    IEEE80211_HT_PARAM_CHA_SEC_NONE;
-                               ctx->ht.is_40mhz = false;
+                               il->ht.is_40mhz = false;
                        }
                } else
-                       ctx->ht.is_40mhz = false;
+                       il->ht.is_40mhz = false;
 
                /*
                 * Default to no protection. Protection mode will
                 * later be set from BSS config in il_ht_conf
                 */
-               ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+               il->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
 
                /* if we are switching from ht to 2.4 clear flags
                 * from any ht related info since 2.4 does not
                 * support ht */
-               if ((le16_to_cpu(ctx->staging.channel) != ch))
-                       ctx->staging.flags = 0;
+               if ((le16_to_cpu(il->staging.channel) != ch))
+                       il->staging.flags = 0;
 
-               il_set_rxon_channel(il, channel, ctx);
+               il_set_rxon_channel(il, channel);
                il_set_rxon_ht(il, ht_conf);
 
-               il_set_flags_for_band(il, ctx, channel->band, ctx->vif);
+               il_set_flags_for_band(il, channel->band, il->vif);
 
                spin_unlock_irqrestore(&il->lock, flags);
 
-               if (il->cfg->ops->legacy->update_bcast_stations)
-                       ret = il->cfg->ops->legacy->update_bcast_stations(il);
+               if (il->ops->update_bcast_stations)
+                       ret = il->ops->update_bcast_stations(il);
 
 set_ch_out:
                /* The list of supported rates and rate mask can be different
@@ -5420,16 +5073,17 @@ set_ch_out:
        if (scan_active)
                goto out;
 
-       if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
-               il_commit_rxon(il, ctx);
+       if (memcmp(&il->active, &il->staging, sizeof(il->staging)))
+               il_commit_rxon(il);
        else
                D_INFO("Not re-sending same RXON configuration.\n");
        if (ht_changed)
-               il_update_qos(il, ctx);
+               il_update_qos(il);
 
 out:
-       D_MAC80211("leave\n");
+       D_MAC80211("leave ret %d\n", ret);
        mutex_unlock(&il->mutex);
+
        return ret;
 }
 EXPORT_SYMBOL(il_mac_config);
@@ -5439,26 +5093,18 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
        struct il_priv *il = hw->priv;
        unsigned long flags;
-       struct il_rxon_context *ctx = &il->ctx;
-
-       if (WARN_ON(!il->cfg->ops->legacy))
-               return;
 
        mutex_lock(&il->mutex);
-       D_MAC80211("enter\n");
+       D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr);
 
        spin_lock_irqsave(&il->lock, flags);
-       memset(&il->current_ht_config, 0, sizeof(struct il_ht_config));
-       spin_unlock_irqrestore(&il->lock, flags);
 
-       spin_lock_irqsave(&il->lock, flags);
+       memset(&il->current_ht_config, 0, sizeof(struct il_ht_config));
 
        /* new association get rid of ibss beacon skb */
        if (il->beacon_skb)
                dev_kfree_skb(il->beacon_skb);
-
        il->beacon_skb = NULL;
-
        il->timestamp = 0;
 
        spin_unlock_irqrestore(&il->lock, flags);
@@ -5470,17 +5116,14 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                return;
        }
 
-       /* we are restarting association process
-        * clear RXON_FILTER_ASSOC_MSK bit
-        */
-       ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       il_commit_rxon(il, ctx);
+       /* we are restarting association process */
+       il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+       il_commit_rxon(il);
 
        il_set_rate(il);
 
-       mutex_unlock(&il->mutex);
-
        D_MAC80211("leave\n");
+       mutex_unlock(&il->mutex);
 }
 EXPORT_SYMBOL(il_mac_reset_tsf);
 
@@ -5490,16 +5133,15 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif)
        struct il_ht_config *ht_conf = &il->current_ht_config;
        struct ieee80211_sta *sta;
        struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
-       struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
 
        D_ASSOC("enter:\n");
 
-       if (!ctx->ht.enabled)
+       if (!il->ht.enabled)
                return;
 
-       ctx->ht.protection =
+       il->ht.protection =
            bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
-       ctx->ht.non_gf_sta_present =
+       il->ht.non_gf_sta_present =
            !!(bss_conf->
               ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
 
@@ -5548,16 +5190,14 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif)
 static inline void
 il_set_no_assoc(struct il_priv *il, struct ieee80211_vif *vif)
 {
-       struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
-
        /*
         * inform the ucode that there is no longer an
         * association and that no more packets should be
         * sent
         */
-       ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       ctx->staging.assoc_id = 0;
-       il_commit_rxon(il, ctx);
+       il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+       il->staging.assoc_id = 0;
+       il_commit_rxon(il);
 }
 
 static void
@@ -5575,8 +5215,8 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 
        lockdep_assert_held(&il->mutex);
 
-       if (!il->beacon_ctx) {
-               IL_ERR("update beacon but no beacon context!\n");
+       if (!il->beacon_enabled) {
+               IL_ERR("update beacon with no beaconing enabled\n");
                dev_kfree_skb(skb);
                return;
        }
@@ -5599,7 +5239,7 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                return;
        }
 
-       il->cfg->ops->legacy->post_associate(il);
+       il->ops->post_associate(il);
 }
 
 void
@@ -5607,17 +5247,13 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        struct ieee80211_bss_conf *bss_conf, u32 changes)
 {
        struct il_priv *il = hw->priv;
-       struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
        int ret;
 
-       if (WARN_ON(!il->cfg->ops->legacy))
-               return;
-
-       D_MAC80211("changes = 0x%X\n", changes);
-
        mutex_lock(&il->mutex);
+       D_MAC80211("enter: changes 0x%x\n", changes);
 
        if (!il_is_alive(il)) {
+               D_MAC80211("leave - not alive\n");
                mutex_unlock(&il->mutex);
                return;
        }
@@ -5626,21 +5262,17 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                unsigned long flags;
 
                spin_lock_irqsave(&il->lock, flags);
-               ctx->qos_data.qos_active = bss_conf->qos;
-               il_update_qos(il, ctx);
+               il->qos_data.qos_active = bss_conf->qos;
+               il_update_qos(il);
                spin_unlock_irqrestore(&il->lock, flags);
        }
 
        if (changes & BSS_CHANGED_BEACON_ENABLED) {
-               /*
-                * the add_interface code must make sure we only ever
-                * have a single interface that could be beaconing at
-                * any time.
-                */
+               /* FIXME: can we remove beacon_enabled ? */
                if (vif->bss_conf.enable_beacon)
-                       il->beacon_ctx = ctx;
+                       il->beacon_enabled = true;
                else
-                       il->beacon_ctx = NULL;
+                       il->beacon_enabled = false;
        }
 
        if (changes & BSS_CHANGED_BSSID) {
@@ -5652,23 +5284,20 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                 * below/in post_associate will fail.
                 */
                if (il_scan_cancel_timeout(il, 100)) {
-                       IL_WARN("Aborted scan still in progress after 100ms\n");
-                       D_MAC80211("leaving - scan abort failed.\n");
+                       D_MAC80211("leave - scan abort failed\n");
                        mutex_unlock(&il->mutex);
                        return;
                }
 
                /* mac80211 only sets assoc when in STATION mode */
                if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
-                       memcpy(ctx->staging.bssid_addr, bss_conf->bssid,
+                       memcpy(il->staging.bssid_addr, bss_conf->bssid,
                               ETH_ALEN);
 
                        /* currently needed in a few places */
                        memcpy(il->bssid, bss_conf->bssid, ETH_ALEN);
-               } else {
-                       ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               }
-
+               } else
+                       il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        }
 
        /*
@@ -5682,21 +5311,21 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        if (changes & BSS_CHANGED_ERP_PREAMBLE) {
                D_MAC80211("ERP_PREAMBLE %d\n", bss_conf->use_short_preamble);
                if (bss_conf->use_short_preamble)
-                       ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+                       il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
                else
-                       ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+                       il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
        }
 
        if (changes & BSS_CHANGED_ERP_CTS_PROT) {
                D_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
                if (bss_conf->use_cts_prot && il->band != IEEE80211_BAND_5GHZ)
-                       ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
+                       il->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
                else
-                       ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+                       il->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
                if (bss_conf->use_cts_prot)
-                       ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+                       il->staging.flags |= RXON_FLG_SELF_CTS_EN;
                else
-                       ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
+                       il->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
        }
 
        if (changes & BSS_CHANGED_BASIC_RATES) {
@@ -5706,12 +5335,12 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                 * like this here:
                 *
                 if (A-band)
-                ctx->staging.ofdm_basic_rates =
+                il->staging.ofdm_basic_rates =
                 bss_conf->basic_rates;
                 else
-                ctx->staging.ofdm_basic_rates =
+                il->staging.ofdm_basic_rates =
                 bss_conf->basic_rates >> 4;
-                ctx->staging.cck_basic_rates =
+                il->staging.cck_basic_rates =
                 bss_conf->basic_rates & 0xF;
                 */
        }
@@ -5719,8 +5348,8 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        if (changes & BSS_CHANGED_HT) {
                il_ht_conf(il, vif);
 
-               if (il->cfg->ops->hcmd->set_rxon_chain)
-                       il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+               if (il->ops->set_rxon_chain)
+                       il->ops->set_rxon_chain(il);
        }
 
        if (changes & BSS_CHANGED_ASSOC) {
@@ -5729,45 +5358,42 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        il->timestamp = bss_conf->timestamp;
 
                        if (!il_is_rfkill(il))
-                               il->cfg->ops->legacy->post_associate(il);
+                               il->ops->post_associate(il);
                } else
                        il_set_no_assoc(il, vif);
        }
 
-       if (changes && il_is_associated_ctx(ctx) && bss_conf->aid) {
+       if (changes && il_is_associated(il) && bss_conf->aid) {
                D_MAC80211("Changes (%#x) while associated\n", changes);
-               ret = il_send_rxon_assoc(il, ctx);
+               ret = il_send_rxon_assoc(il);
                if (!ret) {
                        /* Sync active_rxon with latest change. */
-                       memcpy((void *)&ctx->active, &ctx->staging,
+                       memcpy((void *)&il->active, &il->staging,
                               sizeof(struct il_rxon_cmd));
                }
        }
 
        if (changes & BSS_CHANGED_BEACON_ENABLED) {
                if (vif->bss_conf.enable_beacon) {
-                       memcpy(ctx->staging.bssid_addr, bss_conf->bssid,
+                       memcpy(il->staging.bssid_addr, bss_conf->bssid,
                               ETH_ALEN);
                        memcpy(il->bssid, bss_conf->bssid, ETH_ALEN);
-                       il->cfg->ops->legacy->config_ap(il);
+                       il->ops->config_ap(il);
                } else
                        il_set_no_assoc(il, vif);
        }
 
        if (changes & BSS_CHANGED_IBSS) {
-               ret =
-                   il->cfg->ops->legacy->manage_ibss_station(il, vif,
-                                                             bss_conf->
-                                                             ibss_joined);
+               ret = il->ops->manage_ibss_station(il, vif,
+                                                  bss_conf->ibss_joined);
                if (ret)
                        IL_ERR("failed to %s IBSS station %pM\n",
                               bss_conf->ibss_joined ? "add" : "remove",
                               bss_conf->bssid);
        }
 
-       mutex_unlock(&il->mutex);
-
        D_MAC80211("leave\n");
+       mutex_unlock(&il->mutex);
 }
 EXPORT_SYMBOL(il_mac_bss_info_changed);
 
index abfa388588be71ac318262581ce9fc27e50da53c..5f5017767b9990b54096b705c23310e866ff2d92 100644 (file)
@@ -143,12 +143,6 @@ struct il_queue {
                                 * space less than this */
 };
 
-/* One for each TFD */
-struct il_tx_info {
-       struct sk_buff *skb;
-       struct il_rxon_context *ctx;
-};
-
 /**
  * struct il_tx_queue - Tx Queue for DMA
  * @q: generic Rx/Tx queue descriptor
@@ -156,7 +150,7 @@ struct il_tx_info {
  * @cmd: array of command/TX buffer pointers
  * @meta: array of meta data for each command/tx buffer
  * @dma_addr_cmd: physical address of cmd/tx buffer array
- * @txb: array of per-TFD driver data
+ * @skbs: array of per-TFD socket buffer pointers
  * @time_stamp: time (in jiffies) of last read_ptr change
  * @need_update: indicates need to update read/write idx
  * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
@@ -172,7 +166,7 @@ struct il_tx_queue {
        void *tfds;
        struct il_device_cmd **cmd;
        struct il_cmd_meta *meta;
-       struct il_tx_info *txb;
+       struct sk_buff **skbs;
        unsigned long time_stamp;
        u8 need_update;
        u8 sched_retry;
@@ -431,12 +425,6 @@ struct il_eeprom_calib_info {
 
 #define EEPROM_REGULATORY_BAND_NO_HT40                 (0)
 
-struct il_eeprom_ops {
-       const u32 regulatory_bands[7];
-       int (*acquire_semaphore) (struct il_priv *il);
-       void (*release_semaphore) (struct il_priv *il);
-};
-
 int il_eeprom_init(struct il_priv *il);
 void il_eeprom_free(struct il_priv *il);
 const u8 *il_eeprom_query_addr(const struct il_priv *il, size_t offset);
@@ -735,13 +723,12 @@ struct il_qos_info {
 struct il_station_entry {
        struct il_addsta_cmd sta;
        struct il_tid_data tid[MAX_TID_COUNT];
-       u8 used, ctxid;
+       u8 used;
        struct il_hw_key keyinfo;
        struct il_link_quality_cmd *lq;
 };
 
 struct il_station_priv_common {
-       struct il_rxon_context *ctx;
        u8 sta_id;
 };
 
@@ -752,7 +739,6 @@ struct il_station_priv_common {
  * space for us to put data into.
  */
 struct il_vif_priv {
-       struct il_rxon_context *ctx;
        u8 ibss_bssid_sta_id;
 };
 
@@ -816,6 +802,7 @@ struct il_sensitivity_ranges {
 
 /**
  * struct il_hw_params
+ * @bcast_id: f/w broadcast station ID
  * @max_txq_num: Max # Tx queues supported
  * @dma_chnl_num: Number of Tx DMA/FIFO channels
  * @scd_bc_tbls_size: size of scheduler byte count tables
@@ -836,6 +823,7 @@ struct il_sensitivity_ranges {
  * @struct il_sensitivity_ranges: range of sensitivity values
  */
 struct il_hw_params {
+       u8 bcast_id;
        u8 max_txq_num;
        u8 dma_chnl_num;
        u16 scd_bc_tbls_size;
@@ -968,26 +956,6 @@ enum il4965_chain_noise_state {
        IL_CHAIN_NOISE_DONE,
 };
 
-enum il4965_calib_enabled_state {
-       IL_CALIB_DISABLED = 0,  /* must be 0 */
-       IL_CALIB_ENABLED = 1,
-};
-
-/*
- * enum il_calib
- * defines the order in which results of initial calibrations
- * should be sent to the runtime uCode
- */
-enum il_calib {
-       IL_CALIB_MAX,
-};
-
-/* Opaque calibration results */
-struct il_calib_result {
-       void *buf;
-       size_t buf_len;
-};
-
 enum ucode_type {
        UCODE_NONE = 0,
        UCODE_INIT,
@@ -1152,55 +1120,6 @@ struct il_force_reset {
 
 struct il_rxon_context {
        struct ieee80211_vif *vif;
-
-       const u8 *ac_to_fifo;
-       const u8 *ac_to_queue;
-       u8 mcast_queue;
-
-       /*
-        * We could use the vif to indicate active, but we
-        * also need it to be active during disabling when
-        * we already removed the vif for type setting.
-        */
-       bool always_active, is_active;
-
-       bool ht_need_multiple_chains;
-
-       int ctxid;
-
-       u32 interface_modes, exclusive_interface_modes;
-       u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype;
-
-       /*
-        * We declare this const so it can only be
-        * changed via explicit cast within the
-        * routines that actually update the physical
-        * hardware.
-        */
-       const struct il_rxon_cmd active;
-       struct il_rxon_cmd staging;
-
-       struct il_rxon_time_cmd timing;
-
-       struct il_qos_info qos_data;
-
-       u8 bcast_sta_id, ap_sta_id;
-
-       u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd;
-       u8 qos_cmd;
-       u8 wep_key_cmd;
-
-       struct il_wep_key wep_keys[WEP_KEYS_MAX];
-       u8 key_mapping_keys;
-
-       __le32 station_flags;
-
-       struct {
-               bool non_gf_sta_present;
-               u8 protection;
-               bool enabled, is_40mhz;
-               u8 extension_chan_offset;
-       } ht;
 };
 
 struct il_power_mgr {
@@ -1211,12 +1130,15 @@ struct il_power_mgr {
 };
 
 struct il_priv {
-
-       /* ieee device used by generic ieee processing code */
        struct ieee80211_hw *hw;
        struct ieee80211_channel *ieee_channels;
        struct ieee80211_rate *ieee_rates;
+
        struct il_cfg *cfg;
+       const struct il_ops *ops;
+#ifdef CONFIG_IWLEGACY_DEBUGFS
+       const struct il_debugfs_ops *debugfs_ops;
+#endif
 
        /* temporary frame storage list */
        struct list_head free_frames;
@@ -1253,9 +1175,6 @@ struct il_priv {
        s32 temperature;        /* degrees Kelvin */
        s32 last_temperature;
 
-       /* init calibration results */
-       struct il_calib_result calib_results[IL_CALIB_MAX];
-
        /* Scan related variables */
        unsigned long scan_start;
        unsigned long scan_start_tsf;
@@ -1304,7 +1223,28 @@ struct il_priv {
        u8 ucode_write_complete;        /* the image write is complete */
        char firmware_name[25];
 
-       struct il_rxon_context ctx;
+       struct ieee80211_vif *vif;
+
+       struct il_qos_info qos_data;
+
+       struct {
+               bool enabled;
+               bool is_40mhz;
+               bool non_gf_sta_present;
+               u8 protection;
+               u8 extension_chan_offset;
+       } ht;
+
+       /*
+        * We declare this const so it can only be
+        * changed via explicit cast within the
+        * routines that actually update the physical
+        * hardware.
+        */
+       const struct il_rxon_cmd active;
+       struct il_rxon_cmd staging;
+
+       struct il_rxon_time_cmd timing;
 
        __le16 switch_channel;
 
@@ -1427,6 +1367,9 @@ struct il_priv {
                        u8 phy_calib_chain_noise_reset_cmd;
                        u8 phy_calib_chain_noise_gain_cmd;
 
+                       u8 key_mapping_keys;
+                       struct il_wep_key wep_keys[WEP_KEYS_MAX];
+
                        struct il_notif_stats stats;
 #ifdef CONFIG_IWLEGACY_DEBUGFS
                        struct il_notif_stats accum_stats;
@@ -1449,7 +1392,7 @@ struct il_priv {
        struct work_struct rx_replenish;
        struct work_struct abort_scan;
 
-       struct il_rxon_context *beacon_ctx;
+       bool beacon_enabled;
        struct sk_buff *beacon_skb;
 
        struct work_struct tx_flush;
@@ -1507,30 +1450,10 @@ il_txq_ctx_deactivate(struct il_priv *il, int txq_id)
        clear_bit(txq_id, &il->txq_ctx_active_msk);
 }
 
-static inline struct ieee80211_hdr *
-il_tx_queue_get_hdr(struct il_priv *il, int txq_id, int idx)
-{
-       if (il->txq[txq_id].txb[idx].skb)
-               return (struct ieee80211_hdr *)il->txq[txq_id].txb[idx].skb->
-                   data;
-       return NULL;
-}
-
-static inline struct il_rxon_context *
-il_rxon_ctx_from_vif(struct ieee80211_vif *vif)
-{
-       struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
-
-       return vif_priv->ctx;
-}
-
-#define for_each_context(il, _ctx) \
-       for (_ctx = &il->ctx; _ctx == &il->ctx; _ctx++)
-
 static inline int
 il_is_associated(struct il_priv *il)
 {
-       return (il->ctx.active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+       return (il->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
 }
 
 static inline int
@@ -1539,12 +1462,6 @@ il_is_any_associated(struct il_priv *il)
        return il_is_associated(il);
 }
 
-static inline int
-il_is_associated_ctx(struct il_rxon_context *ctx)
-{
-       return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
-}
-
 static inline int
 il_is_channel_valid(const struct il_channel_info *ch_info)
 {
@@ -1613,25 +1530,6 @@ il_free_pages(struct il_priv *il, unsigned long page)
 #define IL_RX_BUF_SIZE_4K (4 * 1024)
 #define IL_RX_BUF_SIZE_8K (8 * 1024)
 
-struct il_hcmd_ops {
-       int (*rxon_assoc) (struct il_priv *il, struct il_rxon_context *ctx);
-       int (*commit_rxon) (struct il_priv *il, struct il_rxon_context *ctx);
-       void (*set_rxon_chain) (struct il_priv *il,
-                               struct il_rxon_context *ctx);
-};
-
-struct il_hcmd_utils_ops {
-       u16(*get_hcmd_size) (u8 cmd_id, u16 len);
-       u16(*build_addsta_hcmd) (const struct il_addsta_cmd *cmd, u8 *data);
-       int (*request_scan) (struct il_priv *il, struct ieee80211_vif *vif);
-       void (*post_scan) (struct il_priv *il);
-};
-
-struct il_apm_ops {
-       int (*init) (struct il_priv *il);
-       void (*config) (struct il_priv *il);
-};
-
 #ifdef CONFIG_IWLEGACY_DEBUGFS
 struct il_debugfs_ops {
        ssize_t(*rx_stats_read) (struct file *file, char __user *user_buf,
@@ -1644,13 +1542,7 @@ struct il_debugfs_ops {
 };
 #endif
 
-struct il_temp_ops {
-       void (*temperature) (struct il_priv *il);
-};
-
-struct il_lib_ops {
-       /* set hw dependent parameters */
-       int (*set_hw_params) (struct il_priv *il);
+struct il_ops {
        /* Handling TX */
        void (*txq_update_byte_cnt_tbl) (struct il_priv *il,
                                         struct il_tx_queue *txq,
@@ -1660,8 +1552,6 @@ struct il_lib_ops {
                                      u16 len, u8 reset, u8 pad);
        void (*txq_free_tfd) (struct il_priv *il, struct il_tx_queue *txq);
        int (*txq_init) (struct il_priv *il, struct il_tx_queue *txq);
-       /* setup Rx handler */
-       void (*handler_setup) (struct il_priv *il);
        /* alive notification after init uCode load */
        void (*init_alive_start) (struct il_priv *il);
        /* check validity of rtc data address */
@@ -1674,45 +1564,33 @@ struct il_lib_ops {
        int (*set_channel_switch) (struct il_priv *il,
                                   struct ieee80211_channel_switch *ch_switch);
        /* power management */
-       struct il_apm_ops apm_ops;
+       int (*apm_init) (struct il_priv *il);
 
-       /* power */
+       /* tx power */
        int (*send_tx_power) (struct il_priv *il);
        void (*update_chain_flags) (struct il_priv *il);
 
        /* eeprom operations */
-       struct il_eeprom_ops eeprom_ops;
+       int (*eeprom_acquire_semaphore) (struct il_priv *il);
+       void (*eeprom_release_semaphore) (struct il_priv *il);
 
-       /* temperature */
-       struct il_temp_ops temp_ops;
-
-#ifdef CONFIG_IWLEGACY_DEBUGFS
-       struct il_debugfs_ops debugfs_ops;
-#endif
+       int (*rxon_assoc) (struct il_priv *il);
+       int (*commit_rxon) (struct il_priv *il);
+       void (*set_rxon_chain) (struct il_priv *il);
 
-};
-
-struct il_led_ops {
-       int (*cmd) (struct il_priv *il, struct il_led_cmd *led_cmd);
-};
+       u16(*get_hcmd_size) (u8 cmd_id, u16 len);
+       u16(*build_addsta_hcmd) (const struct il_addsta_cmd *cmd, u8 *data);
 
-struct il_legacy_ops {
+       int (*request_scan) (struct il_priv *il, struct ieee80211_vif *vif);
+       void (*post_scan) (struct il_priv *il);
        void (*post_associate) (struct il_priv *il);
        void (*config_ap) (struct il_priv *il);
        /* station management */
        int (*update_bcast_stations) (struct il_priv *il);
        int (*manage_ibss_station) (struct il_priv *il,
                                    struct ieee80211_vif *vif, bool add);
-};
 
-struct il_ops {
-       const struct il_lib_ops *lib;
-       const struct il_hcmd_ops *hcmd;
-       const struct il_hcmd_utils_ops *utils;
-       const struct il_led_ops *led;
-       const struct il_nic_ops *nic;
-       const struct il_legacy_ops *legacy;
-       const struct ieee80211_ops *ieee80211_ops;
+       int (*send_led_cmd) (struct il_priv *il, struct il_led_cmd *led_cmd);
 };
 
 struct il_mod_params {
@@ -1725,37 +1603,6 @@ struct il_mod_params {
        int restart_fw;         /* def: 1 = restart firmware */
 };
 
-/*
- * @led_compensation: compensate on the led on/off time per HW according
- *     to the deviation to achieve the desired led frequency.
- *     The detail algorithm is described in common.c
- * @chain_noise_num_beacons: number of beacons used to compute chain noise
- * @wd_timeout: TX queues watchdog timeout
- * @temperature_kelvin: temperature report by uCode in kelvin
- * @ucode_tracing: support ucode continuous tracing
- * @sensitivity_calib_by_driver: driver has the capability to perform
- *     sensitivity calibration operation
- * @chain_noise_calib_by_driver: driver has the capability to perform
- *     chain noise calibration operation
- */
-struct il_base_params {
-       int eeprom_size;
-       int num_of_queues;      /* def: HW dependent */
-       int num_of_ampdu_queues;        /* def: HW dependent */
-       /* for il_apm_init() */
-       u32 pll_cfg_val;
-       bool set_l0s;
-       bool use_bsm;
-
-       u16 led_compensation;
-       int chain_noise_num_beacons;
-       unsigned int wd_timeout;
-       bool temperature_kelvin;
-       const bool ucode_tracing;
-       const bool sensitivity_calib_by_driver;
-       const bool chain_noise_calib_by_driver;
-};
-
 #define IL_LED_SOLID 11
 #define IL_DEF_LED_INTRVL cpu_to_le32(1000)
 
@@ -1821,7 +1668,6 @@ struct il_cfg {
        unsigned int sku;
        u16 eeprom_ver;
        u16 eeprom_calib_ver;
-       const struct il_ops *ops;
        /* module based parameters which can be set from modprobe cmd */
        const struct il_mod_params *mod_params;
        /* params not likely to change within a device family */
@@ -1829,31 +1675,45 @@ struct il_cfg {
        /* params likely to change within a device family */
        u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
        enum il_led_mode led_mode;
+
+       int eeprom_size;
+       int num_of_queues;              /* def: HW dependent */
+       int num_of_ampdu_queues;        /* def: HW dependent */
+       /* for il_apm_init() */
+       u32 pll_cfg_val;
+       bool set_l0s;
+       bool use_bsm;
+
+       u16 led_compensation;
+       int chain_noise_num_beacons;
+       unsigned int wd_timeout;
+       bool temperature_kelvin;
+       const bool ucode_tracing;
+       const bool sensitivity_calib_by_driver;
+       const bool chain_noise_calib_by_driver;
+
+       const u32 regulatory_bands[7];
 };
 
 /***************************
  *   L i b                 *
  ***************************/
 
-struct ieee80211_hw *il_alloc_all(struct il_cfg *cfg);
 int il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                   u16 queue, const struct ieee80211_tx_queue_params *params);
 int il_mac_tx_last_beacon(struct ieee80211_hw *hw);
 
-void il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx,
-                         int hw_decrypt);
-int il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx);
-int il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx);
-int il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch,
-                       struct il_rxon_context *ctx);
-void il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx,
-                          enum ieee80211_band band, struct ieee80211_vif *vif);
+void il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt);
+int il_check_rxon_cmd(struct il_priv *il);
+int il_full_rxon_required(struct il_priv *il);
+int il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch);
+void il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band,
+                          struct ieee80211_vif *vif);
 u8 il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band);
 void il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf);
-bool il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx,
+bool il_is_ht40_tx_allowed(struct il_priv *il,
                           struct ieee80211_sta_ht_cap *ht_cap);
-void il_connection_init_rx_config(struct il_priv *il,
-                                 struct il_rxon_context *ctx);
+void il_connection_init_rx_config(struct il_priv *il);
 void il_set_rate(struct il_priv *il);
 int il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr,
                          u32 decrypt_res, struct ieee80211_rx_status *stats);
@@ -1864,60 +1724,24 @@ void il_mac_remove_interface(struct ieee80211_hw *hw,
 int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                            enum nl80211_iftype newtype, bool newp2p);
 int il_alloc_txq_mem(struct il_priv *il);
-void il_txq_mem(struct il_priv *il);
+void il_free_txq_mem(struct il_priv *il);
 
 #ifdef CONFIG_IWLEGACY_DEBUGFS
-int il_alloc_traffic_mem(struct il_priv *il);
-void il_free_traffic_mem(struct il_priv *il);
-void il_reset_traffic_log(struct il_priv *il);
-void il_dbg_log_tx_data_frame(struct il_priv *il, u16 length,
-                             struct ieee80211_hdr *header);
-void il_dbg_log_rx_data_frame(struct il_priv *il, u16 length,
-                             struct ieee80211_hdr *header);
-const char *il_get_mgmt_string(int cmd);
-const char *il_get_ctrl_string(int cmd);
-void il_clear_traffic_stats(struct il_priv *il);
-void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len);
+extern void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len);
 #else
-static inline int
-il_alloc_traffic_mem(struct il_priv *il)
-{
-       return 0;
-}
-
-static inline void
-il_free_traffic_mem(struct il_priv *il)
-{
-}
-
-static inline void
-il_reset_traffic_log(struct il_priv *il)
-{
-}
-
-static inline void
-il_dbg_log_tx_data_frame(struct il_priv *il, u16 length,
-                        struct ieee80211_hdr *header)
-{
-}
-
-static inline void
-il_dbg_log_rx_data_frame(struct il_priv *il, u16 length,
-                        struct ieee80211_hdr *header)
-{
-}
-
 static inline void
 il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)
 {
 }
 #endif
+
 /*****************************************************
- * RX handlers.
- * **************************************************/
+ * Handlers
+ ***************************************************/
 void il_hdl_pm_sleep(struct il_priv *il, struct il_rx_buf *rxb);
 void il_hdl_pm_debug_stats(struct il_priv *il, struct il_rx_buf *rxb);
 void il_hdl_error(struct il_priv *il, struct il_rx_buf *rxb);
+void il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb);
 
 /*****************************************************
 * RX
@@ -1928,25 +1752,20 @@ int il_rx_queue_alloc(struct il_priv *il);
 void il_rx_queue_update_write_ptr(struct il_priv *il, struct il_rx_queue *q);
 int il_rx_queue_space(const struct il_rx_queue *q);
 void il_tx_cmd_complete(struct il_priv *il, struct il_rx_buf *rxb);
-/* Handlers */
+
 void il_hdl_spectrum_measurement(struct il_priv *il, struct il_rx_buf *rxb);
 void il_recover_from_stats(struct il_priv *il, struct il_rx_pkt *pkt);
 void il_chswitch_done(struct il_priv *il, bool is_success);
-void il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb);
-
-/* TX helpers */
 
 /*****************************************************
 * TX
 ******************************************************/
-void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq);
-int il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
-                    u32 txq_id);
-void il_tx_queue_reset(struct il_priv *il, struct il_tx_queue *txq,
-                      int slots_num, u32 txq_id);
-void il_tx_queue_unmap(struct il_priv *il, int txq_id);
-void il_tx_queue_free(struct il_priv *il, int txq_id);
-void il_setup_watchdog(struct il_priv *il);
+extern void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq);
+extern int il_tx_queue_init(struct il_priv *il, u32 txq_id);
+extern void il_tx_queue_reset(struct il_priv *il, u32 txq_id);
+extern void il_tx_queue_unmap(struct il_priv *il, int txq_id);
+extern void il_tx_queue_free(struct il_priv *il, int txq_id);
+extern void il_setup_watchdog(struct il_priv *il);
 /*****************************************************
  * TX power
  ****************************************************/
@@ -1956,7 +1775,7 @@ int il_set_tx_power(struct il_priv *il, s8 tx_power, bool force);
  * Rate
  ******************************************************************************/
 
-u8 il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx);
+u8 il_get_lowest_plcp(struct il_priv *il);
 
 /*******************************************************************************
  * Scanning
@@ -2043,10 +1862,10 @@ extern const struct dev_pm_ops il_pm_ops;
 ******************************************************/
 void il4965_dump_nic_error_log(struct il_priv *il);
 #ifdef CONFIG_IWLEGACY_DEBUG
-void il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx);
+void il_print_rx_config_cmd(struct il_priv *il);
 #else
 static inline void
-il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx)
+il_print_rx_config_cmd(struct il_priv *il)
 {
 }
 #endif
@@ -2064,7 +1883,7 @@ void il_free_geos(struct il_priv *il);
 #define S_HCMD_ACTIVE  0       /* host command in progress */
 /* 1 is unused (used to be S_HCMD_SYNC_ACTIVE) */
 #define S_INT_ENABLED  2
-#define S_RF_KILL_HW   3
+#define S_RFKILL       3
 #define S_CT_KILL              4
 #define S_INIT         5
 #define S_ALIVE                6
@@ -2102,16 +1921,10 @@ il_is_init(struct il_priv *il)
        return test_bit(S_INIT, &il->status);
 }
 
-static inline int
-il_is_rfkill_hw(struct il_priv *il)
-{
-       return test_bit(S_RF_KILL_HW, &il->status);
-}
-
 static inline int
 il_is_rfkill(struct il_priv *il)
 {
-       return il_is_rfkill_hw(il);
+       return test_bit(S_RFKILL, &il->status);
 }
 
 static inline int
@@ -2132,20 +1945,23 @@ il_is_ready_rf(struct il_priv *il)
 
 extern void il_send_bt_config(struct il_priv *il);
 extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear);
-void il_apm_stop(struct il_priv *il);
+extern void il_apm_stop(struct il_priv *il);
+extern void _il_apm_stop(struct il_priv *il);
+
 int il_apm_init(struct il_priv *il);
 
-int il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx);
+int il_send_rxon_timing(struct il_priv *il);
+
 static inline int
-il_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
+il_send_rxon_assoc(struct il_priv *il)
 {
-       return il->cfg->ops->hcmd->rxon_assoc(il, ctx);
+       return il->ops->rxon_assoc(il);
 }
 
 static inline int
-il_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
+il_commit_rxon(struct il_priv *il)
 {
-       return il->cfg->ops->hcmd->commit_rxon(il, ctx);
+       return il->ops->commit_rxon(il);
 }
 
 static inline const struct ieee80211_supported_band *
@@ -2166,7 +1982,7 @@ irqreturn_t il_isr(int irq, void *data);
 
 extern void il_set_bit(struct il_priv *p, u32 r, u32 m);
 extern void il_clear_bit(struct il_priv *p, u32 r, u32 m);
-extern int _il_grab_nic_access(struct il_priv *il);
+extern bool _il_grab_nic_access(struct il_priv *il);
 extern int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout);
 extern int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout);
 extern u32 il_rd_prph(struct il_priv *il, u32 reg);
@@ -2177,20 +1993,20 @@ extern void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val);
 static inline void
 _il_write8(struct il_priv *il, u32 ofs, u8 val)
 {
-       iowrite8(val, il->hw_base + ofs);
+       writeb(val, il->hw_base + ofs);
 }
 #define il_write8(il, ofs, val) _il_write8(il, ofs, val)
 
 static inline void
 _il_wr(struct il_priv *il, u32 ofs, u32 val)
 {
-       iowrite32(val, il->hw_base + ofs);
+       writel(val, il->hw_base + ofs);
 }
 
 static inline u32
 _il_rd(struct il_priv *il, u32 ofs)
 {
-       return ioread32(il->hw_base + ofs);
+       return readl(il->hw_base + ofs);
 }
 
 static inline void
@@ -2209,6 +2025,13 @@ static inline void
 _il_release_nic_access(struct il_priv *il)
 {
        _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       /*
+        * In above we are reading CSR_GP_CNTRL register, what will flush any
+        * previous writes, but still want write, which clear MAC_ACCESS_REQ
+        * bit, be performed on PCI bus before any other writes scheduled on
+        * different CPUs (after we drop reg_lock).
+        */
+       mmiowb();
 }
 
 static inline u32
@@ -2231,7 +2054,7 @@ il_wr(struct il_priv *il, u32 reg, u32 value)
        unsigned long reg_flags;
 
        spin_lock_irqsave(&il->reg_lock, reg_flags);
-       if (!_il_grab_nic_access(il)) {
+       if (likely(_il_grab_nic_access(il))) {
                _il_wr(il, reg, value);
                _il_release_nic_access(il);
        }
@@ -2242,7 +2065,6 @@ static inline u32
 _il_rd_prph(struct il_priv *il, u32 reg)
 {
        _il_wr(il, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
-       rmb();
        return _il_rd(il, HBUS_TARG_PRPH_RDAT);
 }
 
@@ -2250,7 +2072,6 @@ static inline void
 _il_wr_prph(struct il_priv *il, u32 addr, u32 val)
 {
        _il_wr(il, HBUS_TARG_PRPH_WADDR, ((addr & 0x0000FFFF) | (3 << 24)));
-       wmb();
        _il_wr(il, HBUS_TARG_PRPH_WDAT, val);
 }
 
@@ -2260,9 +2081,10 @@ il_set_bits_prph(struct il_priv *il, u32 reg, u32 mask)
        unsigned long reg_flags;
 
        spin_lock_irqsave(&il->reg_lock, reg_flags);
-       _il_grab_nic_access(il);
-       _il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask));
-       _il_release_nic_access(il);
+       if (likely(_il_grab_nic_access(il))) {
+               _il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask));
+               _il_release_nic_access(il);
+       }
        spin_unlock_irqrestore(&il->reg_lock, reg_flags);
 }
 
@@ -2272,9 +2094,10 @@ il_set_bits_mask_prph(struct il_priv *il, u32 reg, u32 bits, u32 mask)
        unsigned long reg_flags;
 
        spin_lock_irqsave(&il->reg_lock, reg_flags);
-       _il_grab_nic_access(il);
-       _il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits));
-       _il_release_nic_access(il);
+       if (likely(_il_grab_nic_access(il))) {
+               _il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits));
+               _il_release_nic_access(il);
+       }
        spin_unlock_irqrestore(&il->reg_lock, reg_flags);
 }
 
@@ -2285,10 +2108,11 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask)
        u32 val;
 
        spin_lock_irqsave(&il->reg_lock, reg_flags);
-       _il_grab_nic_access(il);
-       val = _il_rd_prph(il, reg);
-       _il_wr_prph(il, reg, (val & ~mask));
-       _il_release_nic_access(il);
+       if (likely(_il_grab_nic_access(il))) {
+               val = _il_rd_prph(il, reg);
+               _il_wr_prph(il, reg, (val & ~mask));
+               _il_release_nic_access(il);
+       }
        spin_unlock_irqrestore(&il->reg_lock, reg_flags);
 }
 
@@ -2303,23 +2127,22 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask)
                                   (this is for the IBSS BSSID stations) */
 #define IL_STA_BCAST BIT(4)    /* this station is the special bcast station */
 
-void il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx);
-void il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx);
+void il_restore_stations(struct il_priv *il);
+void il_clear_ucode_stations(struct il_priv *il);
 void il_dealloc_bcast_stations(struct il_priv *il);
 int il_get_free_ucode_key_idx(struct il_priv *il);
 int il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags);
-int il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx,
-                         const u8 *addr, bool is_ap,
+int il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap,
                          struct ieee80211_sta *sta, u8 *sta_id_r);
 int il_remove_station(struct il_priv *il, const u8 sta_id, const u8 * addr);
 int il_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                      struct ieee80211_sta *sta);
 
-u8 il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
-                  const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
+u8 il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap,
+                  struct ieee80211_sta *sta);
 
-int il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,
-                  struct il_link_quality_cmd *lq, u8 flags, bool init);
+int il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq,
+                  u8 flags, bool init);
 
 /**
  * il_clear_driver_stations - clear knowledge of all stations from driver
@@ -2334,24 +2157,11 @@ static inline void
 il_clear_driver_stations(struct il_priv *il)
 {
        unsigned long flags;
-       struct il_rxon_context *ctx = &il->ctx;
 
        spin_lock_irqsave(&il->sta_lock, flags);
        memset(il->stations, 0, sizeof(il->stations));
        il->num_stations = 0;
-
        il->ucode_key_table = 0;
-
-       /*
-        * Remove all key information that is not stored as part
-        * of station information since mac80211 may not have had
-        * a chance to remove all the keys. When device is
-        * reconfigured by mac80211 after an error all keys will
-        * be reconfigured.
-        */
-       memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
-       ctx->key_mapping_keys = 0;
-
        spin_unlock_irqrestore(&il->sta_lock, flags);
 }
 
@@ -2376,13 +2186,12 @@ il_sta_id(struct ieee80211_sta *sta)
  * inline wraps that pattern.
  */
 static inline int
-il_sta_id_or_broadcast(struct il_priv *il, struct il_rxon_context *context,
-                      struct ieee80211_sta *sta)
+il_sta_id_or_broadcast(struct il_priv *il, struct ieee80211_sta *sta)
 {
        int sta_id;
 
        if (!sta)
-               return context->bcast_sta_id;
+               return il->hw_params.bcast_id;
 
        sta_id = il_sta_id(sta);
 
@@ -2565,10 +2374,10 @@ struct il_rb_status {
        __le32 __unused;        /* 3945 only */
 } __packed;
 
-#define TFD_QUEUE_SIZE_MAX      (256)
-#define TFD_QUEUE_SIZE_BC_DUP  (64)
+#define TFD_QUEUE_SIZE_MAX      256
+#define TFD_QUEUE_SIZE_BC_DUP  64
 #define TFD_QUEUE_BC_SIZE      (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP)
-#define IL_TX_DMA_MASK        DMA_BIT_MASK(36)
+#define IL_TX_DMA_MASK         DMA_BIT_MASK(36)
 #define IL_NUM_OF_TBS          20
 
 static inline u8
index b1b8926a9c7b3f16ff7be416663cbbe377148d9d..229849150aac0bb20e152b6a79b0658ebf3b18bb 100644 (file)
 
 #include "common.h"
 
+void
+il_clear_traffic_stats(struct il_priv *il)
+{
+       memset(&il->tx_stats, 0, sizeof(struct traffic_stats));
+       memset(&il->rx_stats, 0, sizeof(struct traffic_stats));
+}
+
+/*
+ * il_update_stats function record all the MGMT, CTRL and DATA pkt for
+ * both TX and Rx . Use debugfs to display the rx/rx_stats
+ */
+void
+il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)
+{
+       struct traffic_stats *stats;
+
+       if (is_tx)
+               stats = &il->tx_stats;
+       else
+               stats = &il->rx_stats;
+
+       if (ieee80211_is_mgmt(fc)) {
+               switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+               case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+                       stats->mgmt[MANAGEMENT_ASSOC_REQ]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
+                       stats->mgmt[MANAGEMENT_ASSOC_RESP]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
+                       stats->mgmt[MANAGEMENT_REASSOC_REQ]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
+                       stats->mgmt[MANAGEMENT_REASSOC_RESP]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
+                       stats->mgmt[MANAGEMENT_PROBE_REQ]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
+                       stats->mgmt[MANAGEMENT_PROBE_RESP]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_BEACON):
+                       stats->mgmt[MANAGEMENT_BEACON]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_ATIM):
+                       stats->mgmt[MANAGEMENT_ATIM]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+                       stats->mgmt[MANAGEMENT_DISASSOC]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_AUTH):
+                       stats->mgmt[MANAGEMENT_AUTH]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+                       stats->mgmt[MANAGEMENT_DEAUTH]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_ACTION):
+                       stats->mgmt[MANAGEMENT_ACTION]++;
+                       break;
+               }
+       } else if (ieee80211_is_ctl(fc)) {
+               switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+               case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):
+                       stats->ctrl[CONTROL_BACK_REQ]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_BACK):
+                       stats->ctrl[CONTROL_BACK]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_PSPOLL):
+                       stats->ctrl[CONTROL_PSPOLL]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_RTS):
+                       stats->ctrl[CONTROL_RTS]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_CTS):
+                       stats->ctrl[CONTROL_CTS]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_ACK):
+                       stats->ctrl[CONTROL_ACK]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_CFEND):
+                       stats->ctrl[CONTROL_CFEND]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_CFENDACK):
+                       stats->ctrl[CONTROL_CFENDACK]++;
+                       break;
+               }
+       } else {
+               /* data */
+               stats->data_cnt++;
+               stats->data_bytes += len;
+       }
+}
+EXPORT_SYMBOL(il_update_stats);
+
 /* create and remove of files */
 #define DEBUGFS_ADD_FILE(name, parent, mode) do {                      \
        if (!debugfs_create_file(#name, mode, parent, il,               \
@@ -98,6 +193,46 @@ static const struct file_operations il_dbgfs_##name##_ops = {       \
        .llseek = generic_file_llseek,                          \
 };
 
+static const char *
+il_get_mgmt_string(int cmd)
+{
+       switch (cmd) {
+       IL_CMD(MANAGEMENT_ASSOC_REQ);
+       IL_CMD(MANAGEMENT_ASSOC_RESP);
+       IL_CMD(MANAGEMENT_REASSOC_REQ);
+       IL_CMD(MANAGEMENT_REASSOC_RESP);
+       IL_CMD(MANAGEMENT_PROBE_REQ);
+       IL_CMD(MANAGEMENT_PROBE_RESP);
+       IL_CMD(MANAGEMENT_BEACON);
+       IL_CMD(MANAGEMENT_ATIM);
+       IL_CMD(MANAGEMENT_DISASSOC);
+       IL_CMD(MANAGEMENT_AUTH);
+       IL_CMD(MANAGEMENT_DEAUTH);
+       IL_CMD(MANAGEMENT_ACTION);
+       default:
+               return "UNKNOWN";
+
+       }
+}
+
+static const char *
+il_get_ctrl_string(int cmd)
+{
+       switch (cmd) {
+       IL_CMD(CONTROL_BACK_REQ);
+       IL_CMD(CONTROL_BACK);
+       IL_CMD(CONTROL_PSPOLL);
+       IL_CMD(CONTROL_RTS);
+       IL_CMD(CONTROL_CTS);
+       IL_CMD(CONTROL_ACK);
+       IL_CMD(CONTROL_CFEND);
+       IL_CMD(CONTROL_CFENDACK);
+       default:
+               return "UNKNOWN";
+
+       }
+}
+
 static ssize_t
 il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count,
                       loff_t *ppos)
@@ -361,7 +496,7 @@ il_dbgfs_nvm_read(struct file *file, char __user *user_buf, size_t count,
        const u8 *ptr;
        char *buf;
        u16 eeprom_ver;
-       size_t eeprom_len = il->cfg->base_params->eeprom_size;
+       size_t eeprom_len = il->cfg->eeprom_size;
        buf_size = 4 * eeprom_len + 256;
 
        if (eeprom_len % 16) {
@@ -495,8 +630,8 @@ il_dbgfs_status_read(struct file *file, char __user *user_buf, size_t count,
            scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n",
                      test_bit(S_INT_ENABLED, &il->status));
        pos +=
-           scnprintf(buf + pos, bufsz - pos, "S_RF_KILL_HW:\t %d\n",
-                     test_bit(S_RF_KILL_HW, &il->status));
+           scnprintf(buf + pos, bufsz - pos, "S_RFKILL:\t %d\n",
+                     test_bit(S_RFKILL, &il->status));
        pos +=
            scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",
                      test_bit(S_CT_KILL, &il->status));
@@ -644,12 +779,10 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count,
                  loff_t *ppos)
 {
        struct il_priv *il = file->private_data;
-       struct il_rxon_context *ctx = &il->ctx;
        int pos = 0, i;
        char buf[256];
        const size_t bufsz = sizeof(buf);
 
-       pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", ctx->ctxid);
        for (i = 0; i < AC_NUM; i++) {
                pos +=
                    scnprintf(buf + pos, bufsz - pos,
@@ -657,10 +790,10 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count,
                pos +=
                    scnprintf(buf + pos, bufsz - pos,
                              "AC[%d]\t%u\t%u\t%u\t%u\n", i,
-                             ctx->qos_data.def_qos_parm.ac[i].cw_min,
-                             ctx->qos_data.def_qos_parm.ac[i].cw_max,
-                             ctx->qos_data.def_qos_parm.ac[i].aifsn,
-                             ctx->qos_data.def_qos_parm.ac[i].edca_txop);
+                             il->qos_data.def_qos_parm.ac[i].cw_min,
+                             il->qos_data.def_qos_parm.ac[i].cw_max,
+                             il->qos_data.def_qos_parm.ac[i].aifsn,
+                             il->qos_data.def_qos_parm.ac[i].edca_txop);
        }
 
        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
@@ -716,112 +849,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
 DEBUGFS_READ_FILE_OPS(qos);
 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
 
-static ssize_t
-il_dbgfs_traffic_log_read(struct file *file, char __user *user_buf,
-                         size_t count, loff_t *ppos)
-{
-       struct il_priv *il = file->private_data;
-       int pos = 0, ofs = 0;
-       int cnt = 0, entry;
-       struct il_tx_queue *txq;
-       struct il_queue *q;
-       struct il_rx_queue *rxq = &il->rxq;
-       char *buf;
-       int bufsz =
-           ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
-           (il->cfg->base_params->num_of_queues * 32 * 8) + 400;
-       const u8 *ptr;
-       ssize_t ret;
-
-       if (!il->txq) {
-               IL_ERR("txq not ready\n");
-               return -EAGAIN;
-       }
-       buf = kzalloc(bufsz, GFP_KERNEL);
-       if (!buf) {
-               IL_ERR("Can not allocate buffer\n");
-               return -ENOMEM;
-       }
-       pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
-       for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
-               txq = &il->txq[cnt];
-               q = &txq->q;
-               pos +=
-                   scnprintf(buf + pos, bufsz - pos,
-                             "q[%d]: read_ptr: %u, write_ptr: %u\n", cnt,
-                             q->read_ptr, q->write_ptr);
-       }
-       if (il->tx_traffic && (il_debug_level & IL_DL_TX)) {
-               ptr = il->tx_traffic;
-               pos +=
-                   scnprintf(buf + pos, bufsz - pos, "Tx Traffic idx: %u\n",
-                             il->tx_traffic_idx);
-               for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
-                       for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
-                            entry++, ofs += 16) {
-                               pos +=
-                                   scnprintf(buf + pos, bufsz - pos, "0x%.4x ",
-                                             ofs);
-                               hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
-                                                  buf + pos, bufsz - pos, 0);
-                               pos += strlen(buf + pos);
-                               if (bufsz - pos > 0)
-                                       buf[pos++] = '\n';
-                       }
-               }
-       }
-
-       pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
-       pos +=
-           scnprintf(buf + pos, bufsz - pos, "read: %u, write: %u\n",
-                     rxq->read, rxq->write);
-
-       if (il->rx_traffic && (il_debug_level & IL_DL_RX)) {
-               ptr = il->rx_traffic;
-               pos +=
-                   scnprintf(buf + pos, bufsz - pos, "Rx Traffic idx: %u\n",
-                             il->rx_traffic_idx);
-               for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
-                       for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
-                            entry++, ofs += 16) {
-                               pos +=
-                                   scnprintf(buf + pos, bufsz - pos, "0x%.4x ",
-                                             ofs);
-                               hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
-                                                  buf + pos, bufsz - pos, 0);
-                               pos += strlen(buf + pos);
-                               if (bufsz - pos > 0)
-                                       buf[pos++] = '\n';
-                       }
-               }
-       }
-
-       ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-       kfree(buf);
-       return ret;
-}
-
-static ssize_t
-il_dbgfs_traffic_log_write(struct file *file, const char __user *user_buf,
-                          size_t count, loff_t *ppos)
-{
-       struct il_priv *il = file->private_data;
-       char buf[8];
-       int buf_size;
-       int traffic_log;
-
-       memset(buf, 0, sizeof(buf));
-       buf_size = min(count, sizeof(buf) - 1);
-       if (copy_from_user(buf, user_buf, buf_size))
-               return -EFAULT;
-       if (sscanf(buf, "%d", &traffic_log) != 1)
-               return -EFAULT;
-       if (traffic_log == 0)
-               il_reset_traffic_log(il);
-
-       return count;
-}
-
 static ssize_t
 il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
                       loff_t *ppos)
@@ -835,7 +862,7 @@ il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
        int cnt;
        int ret;
        const size_t bufsz =
-           sizeof(char) * 64 * il->cfg->base_params->num_of_queues;
+           sizeof(char) * 64 * il->cfg->num_of_queues;
 
        if (!il->txq) {
                IL_ERR("txq not ready\n");
@@ -903,8 +930,8 @@ il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf,
                             size_t count, loff_t *ppos)
 {
        struct il_priv *il = file->private_data;
-       return il->cfg->ops->lib->debugfs_ops.rx_stats_read(file, user_buf,
-                                                           count, ppos);
+
+       return il->debugfs_ops->rx_stats_read(file, user_buf, count, ppos);
 }
 
 static ssize_t
@@ -912,8 +939,8 @@ il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf,
                             size_t count, loff_t *ppos)
 {
        struct il_priv *il = file->private_data;
-       return il->cfg->ops->lib->debugfs_ops.tx_stats_read(file, user_buf,
-                                                           count, ppos);
+
+       return il->debugfs_ops->tx_stats_read(file, user_buf, count, ppos);
 }
 
 static ssize_t
@@ -921,8 +948,8 @@ il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf,
                                  size_t count, loff_t *ppos)
 {
        struct il_priv *il = file->private_data;
-       return il->cfg->ops->lib->debugfs_ops.general_stats_read(file, user_buf,
-                                                                count, ppos);
+
+       return il->debugfs_ops->general_stats_read(file, user_buf, count, ppos);
 }
 
 static ssize_t
@@ -1153,7 +1180,7 @@ il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf,
        int len = 0;
        char buf[20];
 
-       len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.flags));
+       len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.flags));
        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 
@@ -1167,7 +1194,7 @@ il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf,
        char buf[20];
 
        len =
-           sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.filter_flags));
+           sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags));
        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 
@@ -1180,8 +1207,8 @@ il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count,
        int pos = 0;
        ssize_t ret = -EFAULT;
 
-       if (il->cfg->ops->lib->dump_fh) {
-               ret = pos = il->cfg->ops->lib->dump_fh(il, &buf, true);
+       if (il->ops->dump_fh) {
+               ret = pos = il->ops->dump_fh(il, &buf, true);
                if (buf) {
                        ret =
                            simple_read_from_buffer(user_buf, count, ppos, buf,
@@ -1298,14 +1325,13 @@ il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf,
        if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
                timeout = IL_DEF_WD_TIMEOUT;
 
-       il->cfg->base_params->wd_timeout = timeout;
+       il->cfg->wd_timeout = timeout;
        il_setup_watchdog(il);
        return count;
 }
 
 DEBUGFS_READ_FILE_OPS(rx_stats);
 DEBUGFS_READ_FILE_OPS(tx_stats);
-DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
 DEBUGFS_READ_FILE_OPS(rx_queue);
 DEBUGFS_READ_FILE_OPS(tx_queue);
 DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
@@ -1359,7 +1385,6 @@ il_dbgfs_register(struct il_priv *il, const char *name)
        DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
        DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR);
        DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR);
-       DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
        DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
        DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
        DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
@@ -1372,17 +1397,17 @@ il_dbgfs_register(struct il_priv *il, const char *name)
        DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
        DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
 
-       if (il->cfg->base_params->sensitivity_calib_by_driver)
+       if (il->cfg->sensitivity_calib_by_driver)
                DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
-       if (il->cfg->base_params->chain_noise_calib_by_driver)
+       if (il->cfg->chain_noise_calib_by_driver)
                DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
        DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
        DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
        DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
-       if (il->cfg->base_params->sensitivity_calib_by_driver)
+       if (il->cfg->sensitivity_calib_by_driver)
                DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
                                 &il->disable_sens_cal);
-       if (il->cfg->base_params->chain_noise_calib_by_driver)
+       if (il->cfg->chain_noise_calib_by_driver)
                DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
                                 &il->disable_chain_noise_cal);
        DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal);
index ae08498dfcad98a91311e128ab9569f0f7c9534b..2fe62730dddd158b66ac80dceb8b20f9150fa99d 100644 (file)
@@ -1,6 +1,6 @@
 config IWLWIFI
        tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) "
-       depends on PCI && MAC80211
+       depends on PCI && MAC80211 && HAS_IOMEM
        select FW_LOADER
        select NEW_LEDS
        select LEDS_CLASS
@@ -127,3 +127,12 @@ config IWLWIFI_P2P
          support when it is loaded.
 
          Say Y only if you want to experiment with P2P.
+
+config IWLWIFI_EXPERIMENTAL_MFP
+       bool "support MFP (802.11w) even if uCode doesn't advertise"
+       depends on IWLWIFI
+       help
+         This option enables experimental MFP (802.11W) support
+         even if the microcode doesn't advertise it.
+
+         Say Y only if you want to experiment with MFP.
index 9dc84a7354dbbde1cdec1560dc91d019039c5feb..85d163ed3db18dd224477231fc0d1728b157f261 100644 (file)
@@ -1,7 +1,7 @@
 # WIFI
 obj-$(CONFIG_IWLWIFI)  += iwlwifi.o
 iwlwifi-objs           := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o
-iwlwifi-objs           += iwl-ucode.o iwl-agn-tx.o
+iwlwifi-objs           += iwl-ucode.o iwl-agn-tx.o iwl-debug.o
 iwlwifi-objs           += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
 iwlwifi-objs           += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o
 
@@ -13,7 +13,8 @@ iwlwifi-objs          += iwl-6000.o
 iwlwifi-objs           += iwl-1000.o
 iwlwifi-objs           += iwl-2000.o
 iwlwifi-objs           += iwl-pci.o
-iwlwifi-objs           += iwl-trans.o
+iwlwifi-objs           += iwl-drv.o
+iwlwifi-objs           += iwl-notif-wait.o
 iwlwifi-objs           += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o
 
 iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
index 1ef7bfc2ab2522629ec7a81125f7043804c32899..450250332e4be7e8631253225e43ddb10943c6a3 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -43,6 +43,7 @@
 #include "iwl-agn-hw.h"
 #include "iwl-shared.h"
 #include "iwl-cfg.h"
+#include "iwl-prph.h"
 
 /* Highest firmware API version supported */
 #define IWL1000_UCODE_API_MAX 6
@@ -84,20 +85,19 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
 static void iwl1000_nic_config(struct iwl_priv *priv)
 {
        /* set CSR_HW_CONFIG_REG for uCode use */
-       iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG,
+       iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
                    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
                    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 
        /* Setting digital SVR for 1000 card to 1.32V */
        /* locking is acquired in iwl_set_bits_mask_prph() function */
-       iwl_set_bits_mask_prph(bus(priv), APMG_DIGITAL_SVR_REG,
+       iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG,
                                APMG_SVR_DIGITAL_VOLTAGE_1_32,
                                ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
 }
 
-static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
+static const struct iwl_sensitivity_ranges iwl1000_sensitivity = {
        .min_nrg_cck = 95,
-       .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 90,
        .auto_corr_min_ofdm_mrc = 170,
        .auto_corr_min_ofdm_x1 = 120,
@@ -120,36 +120,24 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
        .nrg_th_cca = 62,
 };
 
-static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
+static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
 {
-       if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
-           iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
-               cfg(priv)->base_params->num_of_queues =
-                       iwlagn_mod_params.num_of_queues;
-
        hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-       priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
-
-       hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
-       hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
 
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ);
 
-       hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant);
+       hw_params(priv).tx_chains_num =
+               num_of_ant(hw_params(priv).valid_tx_ant);
        if (cfg(priv)->rx_with_siso_diversity)
                hw_params(priv).rx_chains_num = 1;
        else
                hw_params(priv).rx_chains_num =
-                       num_of_ant(cfg(priv)->valid_rx_ant);
-       hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
-       hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+                       num_of_ant(hw_params(priv).valid_rx_ant);
 
        iwl1000_set_ct_threshold(priv);
 
        /* Set initial sensitivity parameters */
        hw_params(priv).sens = &iwl1000_sensitivity;
-
-       return 0;
 }
 
 static struct iwl_lib_ops iwl1000_lib = {
@@ -169,7 +157,7 @@ static struct iwl_lib_ops iwl1000_lib = {
        .temperature = iwlagn_temperature,
 };
 
-static struct iwl_base_params iwl1000_base_params = {
+static const struct iwl_base_params iwl1000_base_params = {
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
@@ -184,7 +172,8 @@ static struct iwl_base_params iwl1000_base_params = {
        .max_event_log_size = 128,
        .wd_disable = true,
 };
-static struct iwl_ht_params iwl1000_ht_params = {
+
+static const struct iwl_ht_params iwl1000_ht_params = {
        .ht_greenfield_support = true,
        .use_rts_for_aggregation = true, /* use rts/cts protection */
        .smps_mode = IEEE80211_SMPS_DYNAMIC,
@@ -195,19 +184,21 @@ static struct iwl_ht_params iwl1000_ht_params = {
        .ucode_api_max = IWL1000_UCODE_API_MAX,                 \
        .ucode_api_ok = IWL1000_UCODE_API_OK,                   \
        .ucode_api_min = IWL1000_UCODE_API_MIN,                 \
+       .max_inst_size = IWLAGN_RTC_INST_SIZE,                  \
+       .max_data_size = IWLAGN_RTC_DATA_SIZE,                  \
        .eeprom_ver = EEPROM_1000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,       \
        .lib = &iwl1000_lib,                                    \
        .base_params = &iwl1000_base_params,                    \
        .led_mode = IWL_LED_BLINK
 
-struct iwl_cfg iwl1000_bgn_cfg = {
+const struct iwl_cfg iwl1000_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
        IWL_DEVICE_1000,
        .ht_params = &iwl1000_ht_params,
 };
 
-struct iwl_cfg iwl1000_bg_cfg = {
+const struct iwl_cfg iwl1000_bg_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
        IWL_DEVICE_1000,
 };
@@ -217,6 +208,8 @@ struct iwl_cfg iwl1000_bg_cfg = {
        .ucode_api_max = IWL100_UCODE_API_MAX,                  \
        .ucode_api_ok = IWL100_UCODE_API_OK,                    \
        .ucode_api_min = IWL100_UCODE_API_MIN,                  \
+       .max_inst_size = IWLAGN_RTC_INST_SIZE,                  \
+       .max_data_size = IWLAGN_RTC_DATA_SIZE,                  \
        .eeprom_ver = EEPROM_1000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,       \
        .lib = &iwl1000_lib,                                    \
@@ -224,13 +217,13 @@ struct iwl_cfg iwl1000_bg_cfg = {
        .led_mode = IWL_LED_RF_STATE,                           \
        .rx_with_siso_diversity = true
 
-struct iwl_cfg iwl100_bgn_cfg = {
+const struct iwl_cfg iwl100_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
        IWL_DEVICE_100,
        .ht_params = &iwl1000_ht_params,
 };
 
-struct iwl_cfg iwl100_bg_cfg = {
+const struct iwl_cfg iwl100_bg_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 100 BG",
        IWL_DEVICE_100,
 };
index 094693328dbb24ad971dc243052eb23b1b033df4..abfd901e81a210246920bcadf7f41db4cca1765d 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -87,13 +87,12 @@ static void iwl2000_nic_config(struct iwl_priv *priv)
        iwl_rf_config(priv);
 
        if (cfg(priv)->iq_invert)
-               iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
+               iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
                            CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
 }
 
-static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
+static const struct iwl_sensitivity_ranges iwl2000_sensitivity = {
        .min_nrg_cck = 97,
-       .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 80,
        .auto_corr_min_ofdm_mrc = 128,
        .auto_corr_min_ofdm_x1 = 105,
@@ -116,36 +115,24 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
        .nrg_th_cca = 62,
 };
 
-static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
+static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
 {
-       if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
-           iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
-               cfg(priv)->base_params->num_of_queues =
-                       iwlagn_mod_params.num_of_queues;
-
        hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-       priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
-
-       hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
-       hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE;
 
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ);
 
-       hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant);
+       hw_params(priv).tx_chains_num =
+               num_of_ant(hw_params(priv).valid_tx_ant);
        if (cfg(priv)->rx_with_siso_diversity)
                hw_params(priv).rx_chains_num = 1;
        else
                hw_params(priv).rx_chains_num =
-                       num_of_ant(cfg(priv)->valid_rx_ant);
-       hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
-       hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+                       num_of_ant(hw_params(priv).valid_rx_ant);
 
        iwl2000_set_ct_threshold(priv);
 
        /* Set initial sensitivity parameters */
        hw_params(priv).sens = &iwl2000_sensitivity;
-
-       return 0;
 }
 
 static struct iwl_lib_ops iwl2000_lib = {
@@ -161,16 +148,13 @@ static struct iwl_lib_ops iwl2000_lib = {
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REGULATORY_BAND_NO_HT40,
                },
-               .update_enhanced_txpower = iwl_eeprom_enhanced_txpower,
+               .enhanced_txpower = true,
        },
        .temperature = iwlagn_temperature,
 };
 
 static struct iwl_lib_ops iwl2030_lib = {
        .set_hw_params = iwl2000_hw_set_hw_params,
-       .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup,
-       .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work,
-       .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
        .nic_config = iwl2000_nic_config,
        .eeprom_ops = {
                .regulatory_bands = {
@@ -182,12 +166,12 @@ static struct iwl_lib_ops iwl2030_lib = {
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REGULATORY_BAND_NO_HT40,
                },
-               .update_enhanced_txpower = iwl_eeprom_enhanced_txpower,
+               .enhanced_txpower = true,
        },
        .temperature = iwlagn_temperature,
 };
 
-static struct iwl_base_params iwl2000_base_params = {
+static const struct iwl_base_params iwl2000_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -206,7 +190,7 @@ static struct iwl_base_params iwl2000_base_params = {
 };
 
 
-static struct iwl_base_params iwl2030_base_params = {
+static const struct iwl_base_params iwl2030_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -224,12 +208,12 @@ static struct iwl_base_params iwl2030_base_params = {
        .hd_v2 = true,
 };
 
-static struct iwl_ht_params iwl2000_ht_params = {
+static const struct iwl_ht_params iwl2000_ht_params = {
        .ht_greenfield_support = true,
        .use_rts_for_aggregation = true, /* use rts/cts protection */
 };
 
-static struct iwl_bt_params iwl2030_bt_params = {
+static const struct iwl_bt_params iwl2030_bt_params = {
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .advanced_bt_coexist = true,
        .agg_time_limit = BT_AGG_THRESHOLD_DEF,
@@ -244,6 +228,8 @@ static struct iwl_bt_params iwl2030_bt_params = {
        .ucode_api_max = IWL2000_UCODE_API_MAX,                 \
        .ucode_api_ok = IWL2000_UCODE_API_OK,                   \
        .ucode_api_min = IWL2000_UCODE_API_MIN,                 \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
        .lib = &iwl2000_lib,                                    \
@@ -253,13 +239,13 @@ static struct iwl_bt_params iwl2030_bt_params = {
        .led_mode = IWL_LED_RF_STATE,                           \
        .iq_invert = true                                       \
 
-struct iwl_cfg iwl2000_2bgn_cfg = {
+const struct iwl_cfg iwl2000_2bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN",
        IWL_DEVICE_2000,
        .ht_params = &iwl2000_ht_params,
 };
 
-struct iwl_cfg iwl2000_2bgn_d_cfg = {
+const struct iwl_cfg iwl2000_2bgn_d_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN",
        IWL_DEVICE_2000,
        .ht_params = &iwl2000_ht_params,
@@ -270,6 +256,8 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = {
        .ucode_api_max = IWL2030_UCODE_API_MAX,                 \
        .ucode_api_ok = IWL2030_UCODE_API_OK,                   \
        .ucode_api_min = IWL2030_UCODE_API_MIN,                 \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
        .lib = &iwl2030_lib,                                    \
@@ -281,7 +269,7 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = {
        .adv_pm = true,                                         \
        .iq_invert = true                                       \
 
-struct iwl_cfg iwl2030_2bgn_cfg = {
+const struct iwl_cfg iwl2030_2bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
        IWL_DEVICE_2030,
        .ht_params = &iwl2000_ht_params,
@@ -292,6 +280,8 @@ struct iwl_cfg iwl2030_2bgn_cfg = {
        .ucode_api_max = IWL105_UCODE_API_MAX,                  \
        .ucode_api_ok = IWL105_UCODE_API_OK,                    \
        .ucode_api_min = IWL105_UCODE_API_MIN,                  \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
        .lib = &iwl2000_lib,                                    \
@@ -303,13 +293,13 @@ struct iwl_cfg iwl2030_2bgn_cfg = {
        .rx_with_siso_diversity = true,                         \
        .iq_invert = true                                       \
 
-struct iwl_cfg iwl105_bgn_cfg = {
+const struct iwl_cfg iwl105_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 105 BGN",
        IWL_DEVICE_105,
        .ht_params = &iwl2000_ht_params,
 };
 
-struct iwl_cfg iwl105_bgn_d_cfg = {
+const struct iwl_cfg iwl105_bgn_d_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 105D BGN",
        IWL_DEVICE_105,
        .ht_params = &iwl2000_ht_params,
@@ -320,6 +310,8 @@ struct iwl_cfg iwl105_bgn_d_cfg = {
        .ucode_api_max = IWL135_UCODE_API_MAX,                  \
        .ucode_api_ok = IWL135_UCODE_API_OK,                    \
        .ucode_api_min = IWL135_UCODE_API_MIN,                  \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
        .lib = &iwl2030_lib,                                    \
@@ -332,7 +324,7 @@ struct iwl_cfg iwl105_bgn_d_cfg = {
        .rx_with_siso_diversity = true,                         \
        .iq_invert = true                                       \
 
-struct iwl_cfg iwl135_bgn_cfg = {
+const struct iwl_cfg iwl135_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 135 BGN",
        IWL_DEVICE_135,
        .ht_params = &iwl2000_ht_params,
index b3a365fea7bbd85b48cd22db06ccf0bdac1a5042..9e187f8f5ae411833b444c22562d4312657c0e3c 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -45,6 +45,7 @@
 #include "iwl-trans.h"
 #include "iwl-shared.h"
 #include "iwl-cfg.h"
+#include "iwl-prph.h"
 
 /* Highest firmware API version supported */
 #define IWL5000_UCODE_API_MAX 5
 /* NIC configuration for 5000 series */
 static void iwl5000_nic_config(struct iwl_priv *priv)
 {
-       unsigned long flags;
-
        iwl_rf_config(priv);
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
-
        /* W/A : NIC is stuck in a reset state after Early PCIe power off
         * (PCIe power is lost before PERST# is asserted),
         * causing ME FW to lose ownership and not being able to obtain it back.
         */
-       iwl_set_bits_mask_prph(bus(priv), APMG_PS_CTRL_REG,
+       iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG,
                                APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
                                ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
-
-
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
 }
 
-static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
+static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
        .min_nrg_cck = 100,
-       .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 90,
        .auto_corr_min_ofdm_mrc = 170,
        .auto_corr_min_ofdm_x1 = 105,
@@ -108,7 +101,6 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
 
 static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
        .min_nrg_cck = 95,
-       .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 90,
        .auto_corr_min_ofdm_mrc = 170,
        .auto_corr_min_ofdm_x1 = 105,
@@ -162,62 +154,40 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
        hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
 }
 
-static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
+static void iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 {
-       if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
-           iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
-               cfg(priv)->base_params->num_of_queues =
-                       iwlagn_mod_params.num_of_queues;
-
        hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-       priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
-
-       hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
-       hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
 
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
                                        BIT(IEEE80211_BAND_5GHZ);
 
-       hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant);
-       hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant);
-       hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
-       hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+       hw_params(priv).tx_chains_num =
+               num_of_ant(hw_params(priv).valid_tx_ant);
+       hw_params(priv).rx_chains_num =
+               num_of_ant(hw_params(priv).valid_rx_ant);
 
        iwl5000_set_ct_threshold(priv);
 
        /* Set initial sensitivity parameters */
        hw_params(priv).sens = &iwl5000_sensitivity;
-
-       return 0;
 }
 
-static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
+static void iwl5150_hw_set_hw_params(struct iwl_priv *priv)
 {
-       if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
-           iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
-               cfg(priv)->base_params->num_of_queues =
-                       iwlagn_mod_params.num_of_queues;
-
        hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-       priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
-
-       hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
-       hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
 
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
                                        BIT(IEEE80211_BAND_5GHZ);
 
-       hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant);
-       hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant);
-       hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
-       hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+       hw_params(priv).tx_chains_num =
+               num_of_ant(hw_params(priv).valid_tx_ant);
+       hw_params(priv).rx_chains_num =
+               num_of_ant(hw_params(priv).valid_rx_ant);
 
        iwl5150_set_ct_threshold(priv);
 
        /* Set initial sensitivity parameters */
        hw_params(priv).sens = &iwl5150_sensitivity;
-
-       return 0;
 }
 
 static void iwl5150_temperature(struct iwl_priv *priv)
@@ -300,7 +270,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
                return -EFAULT;
        }
 
-       return iwl_trans_send_cmd(trans(priv), &hcmd);
+       return iwl_dvm_send_cmd(priv, &hcmd);
 }
 
 static struct iwl_lib_ops iwl5000_lib = {
@@ -339,7 +309,7 @@ static struct iwl_lib_ops iwl5150_lib = {
        .temperature = iwl5150_temperature,
 };
 
-static struct iwl_base_params iwl5000_base_params = {
+static const struct iwl_base_params iwl5000_base_params = {
        .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -352,7 +322,8 @@ static struct iwl_base_params iwl5000_base_params = {
        .no_idle_support = true,
        .wd_disable = true,
 };
-static struct iwl_ht_params iwl5000_ht_params = {
+
+static const struct iwl_ht_params iwl5000_ht_params = {
        .ht_greenfield_support = true,
 };
 
@@ -360,13 +331,15 @@ static struct iwl_ht_params iwl5000_ht_params = {
        .fw_name_pre = IWL5000_FW_PRE,                          \
        .ucode_api_max = IWL5000_UCODE_API_MAX,                 \
        .ucode_api_min = IWL5000_UCODE_API_MIN,                 \
+       .max_inst_size = IWLAGN_RTC_INST_SIZE,                  \
+       .max_data_size = IWLAGN_RTC_DATA_SIZE,                  \
        .eeprom_ver = EEPROM_5000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,       \
        .lib = &iwl5000_lib,                                    \
        .base_params = &iwl5000_base_params,                    \
        .led_mode = IWL_LED_BLINK
 
-struct iwl_cfg iwl5300_agn_cfg = {
+const struct iwl_cfg iwl5300_agn_cfg = {
        .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
        IWL_DEVICE_5000,
        /* at least EEPROM 0x11A has wrong info */
@@ -375,7 +348,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
        .ht_params = &iwl5000_ht_params,
 };
 
-struct iwl_cfg iwl5100_bgn_cfg = {
+const struct iwl_cfg iwl5100_bgn_cfg = {
        .name = "Intel(R) WiFi Link 5100 BGN",
        IWL_DEVICE_5000,
        .valid_tx_ant = ANT_B,          /* .cfg overwrite */
@@ -383,14 +356,14 @@ struct iwl_cfg iwl5100_bgn_cfg = {
        .ht_params = &iwl5000_ht_params,
 };
 
-struct iwl_cfg iwl5100_abg_cfg = {
+const struct iwl_cfg iwl5100_abg_cfg = {
        .name = "Intel(R) WiFi Link 5100 ABG",
        IWL_DEVICE_5000,
        .valid_tx_ant = ANT_B,          /* .cfg overwrite */
        .valid_rx_ant = ANT_AB,         /* .cfg overwrite */
 };
 
-struct iwl_cfg iwl5100_agn_cfg = {
+const struct iwl_cfg iwl5100_agn_cfg = {
        .name = "Intel(R) WiFi Link 5100 AGN",
        IWL_DEVICE_5000,
        .valid_tx_ant = ANT_B,          /* .cfg overwrite */
@@ -398,11 +371,13 @@ struct iwl_cfg iwl5100_agn_cfg = {
        .ht_params = &iwl5000_ht_params,
 };
 
-struct iwl_cfg iwl5350_agn_cfg = {
+const struct iwl_cfg iwl5350_agn_cfg = {
        .name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
        .fw_name_pre = IWL5000_FW_PRE,
        .ucode_api_max = IWL5000_UCODE_API_MAX,
        .ucode_api_min = IWL5000_UCODE_API_MIN,
+       .max_inst_size = IWLAGN_RTC_INST_SIZE,
+       .max_data_size = IWLAGN_RTC_DATA_SIZE,
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
        .lib = &iwl5000_lib,
@@ -416,6 +391,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
        .fw_name_pre = IWL5150_FW_PRE,                          \
        .ucode_api_max = IWL5150_UCODE_API_MAX,                 \
        .ucode_api_min = IWL5150_UCODE_API_MIN,                 \
+       .max_inst_size = IWLAGN_RTC_INST_SIZE,                  \
+       .max_data_size = IWLAGN_RTC_DATA_SIZE,                  \
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,       \
        .lib = &iwl5150_lib,                                    \
@@ -424,14 +401,14 @@ struct iwl_cfg iwl5350_agn_cfg = {
        .led_mode = IWL_LED_BLINK,                              \
        .internal_wimax_coex = true
 
-struct iwl_cfg iwl5150_agn_cfg = {
+const struct iwl_cfg iwl5150_agn_cfg = {
        .name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
        IWL_DEVICE_5150,
        .ht_params = &iwl5000_ht_params,
 
 };
 
-struct iwl_cfg iwl5150_abg_cfg = {
+const struct iwl_cfg iwl5150_abg_cfg = {
        .name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
        IWL_DEVICE_5150,
 };
index 54b753399e6e8331006f6da436d0719412152e27..e64bc6b7bcbf7c073d0c1a938c0e618b45a88c01 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -82,7 +82,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv)
 {
        /* Indicate calibration version to uCode. */
        if (iwl_eeprom_calib_version(priv->shrd) >= 6)
-               iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
+               iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
                                CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
 }
 
@@ -90,31 +90,31 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv)
 {
        /* Indicate calibration version to uCode. */
        if (iwl_eeprom_calib_version(priv->shrd) >= 6)
-               iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
+               iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
                                CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
-       iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
+       iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
                    CSR_GP_DRIVER_REG_BIT_6050_1x2);
 }
 
+static void iwl6000i_additional_nic_config(struct iwl_priv *priv)
+{
+       /* 2x2 IPA phy type */
+       iwl_write32(trans(priv), CSR_GP_DRIVER_REG,
+                    CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
+}
+
 /* NIC configuration for 6000 series */
 static void iwl6000_nic_config(struct iwl_priv *priv)
 {
        iwl_rf_config(priv);
 
-       /* no locking required for register write */
-       if (cfg(priv)->pa_type == IWL_PA_INTERNAL) {
-               /* 2x2 IPA phy type */
-               iwl_write32(bus(priv), CSR_GP_DRIVER_REG,
-                            CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
-       }
        /* do additional nic configuration if needed */
        if (cfg(priv)->additional_nic_config)
-                       cfg(priv)->additional_nic_config(priv);
+               cfg(priv)->additional_nic_config(priv);
 }
 
-static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
+static const struct iwl_sensitivity_ranges iwl6000_sensitivity = {
        .min_nrg_cck = 110,
-       .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 80,
        .auto_corr_min_ofdm_mrc = 128,
        .auto_corr_min_ofdm_x1 = 105,
@@ -137,37 +137,26 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
        .nrg_th_cca = 62,
 };
 
-static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
+static void iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 {
-       if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
-           iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
-               cfg(priv)->base_params->num_of_queues =
-                       iwlagn_mod_params.num_of_queues;
-
        hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-       priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
-
-       hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
-       hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE;
 
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
                                        BIT(IEEE80211_BAND_5GHZ);
 
-       hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant);
+       hw_params(priv).tx_chains_num =
+               num_of_ant(hw_params(priv).valid_tx_ant);
        if (cfg(priv)->rx_with_siso_diversity)
                hw_params(priv).rx_chains_num = 1;
        else
                hw_params(priv).rx_chains_num =
-                       num_of_ant(cfg(priv)->valid_rx_ant);
-       hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
-       hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+                       num_of_ant(hw_params(priv).valid_rx_ant);
 
        iwl6000_set_ct_threshold(priv);
 
        /* Set initial sensitivity parameters */
        hw_params(priv).sens = &iwl6000_sensitivity;
 
-       return 0;
 }
 
 static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
@@ -238,7 +227,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
                return -EFAULT;
        }
 
-       return iwl_trans_send_cmd(trans(priv), &hcmd);
+       return iwl_dvm_send_cmd(priv, &hcmd);
 }
 
 static struct iwl_lib_ops iwl6000_lib = {
@@ -255,16 +244,13 @@ static struct iwl_lib_ops iwl6000_lib = {
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REG_BAND_52_HT40_CHANNELS
                },
-               .update_enhanced_txpower = iwl_eeprom_enhanced_txpower,
+               .enhanced_txpower = true,
        },
        .temperature = iwlagn_temperature,
 };
 
 static struct iwl_lib_ops iwl6030_lib = {
        .set_hw_params = iwl6000_hw_set_hw_params,
-       .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup,
-       .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work,
-       .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
        .set_channel_switch = iwl6000_hw_channel_switch,
        .nic_config = iwl6000_nic_config,
        .eeprom_ops = {
@@ -277,12 +263,12 @@ static struct iwl_lib_ops iwl6030_lib = {
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REG_BAND_52_HT40_CHANNELS
                },
-               .update_enhanced_txpower = iwl_eeprom_enhanced_txpower,
+               .enhanced_txpower = true,
        },
        .temperature = iwlagn_temperature,
 };
 
-static struct iwl_base_params iwl6000_base_params = {
+static const struct iwl_base_params iwl6000_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -299,7 +285,7 @@ static struct iwl_base_params iwl6000_base_params = {
        .shadow_reg_enable = true,
 };
 
-static struct iwl_base_params iwl6050_base_params = {
+static const struct iwl_base_params iwl6050_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -315,7 +301,8 @@ static struct iwl_base_params iwl6050_base_params = {
        .max_event_log_size = 1024,
        .shadow_reg_enable = true,
 };
-static struct iwl_base_params iwl6000_g2_base_params = {
+
+static const struct iwl_base_params iwl6000_g2_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -332,12 +319,12 @@ static struct iwl_base_params iwl6000_g2_base_params = {
        .shadow_reg_enable = true,
 };
 
-static struct iwl_ht_params iwl6000_ht_params = {
+static const struct iwl_ht_params iwl6000_ht_params = {
        .ht_greenfield_support = true,
        .use_rts_for_aggregation = true, /* use rts/cts protection */
 };
 
-static struct iwl_bt_params iwl6000_bt_params = {
+static const struct iwl_bt_params iwl6000_bt_params = {
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .advanced_bt_coexist = true,
        .agg_time_limit = BT_AGG_THRESHOLD_DEF,
@@ -351,6 +338,8 @@ static struct iwl_bt_params iwl6000_bt_params = {
        .ucode_api_max = IWL6000G2_UCODE_API_MAX,               \
        .ucode_api_ok = IWL6000G2_UCODE_API_OK,                 \
        .ucode_api_min = IWL6000G2_UCODE_API_MIN,               \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_6005_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION,       \
        .lib = &iwl6000_lib,                                    \
@@ -358,39 +347,53 @@ static struct iwl_bt_params iwl6000_bt_params = {
        .need_temp_offset_calib = true,                         \
        .led_mode = IWL_LED_RF_STATE
 
-struct iwl_cfg iwl6005_2agn_cfg = {
+const struct iwl_cfg iwl6005_2agn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
        IWL_DEVICE_6005,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6005_2abg_cfg = {
+const struct iwl_cfg iwl6005_2abg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG",
        IWL_DEVICE_6005,
 };
 
-struct iwl_cfg iwl6005_2bg_cfg = {
+const struct iwl_cfg iwl6005_2bg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6205 BG",
        IWL_DEVICE_6005,
 };
 
-struct iwl_cfg iwl6005_2agn_sff_cfg = {
+const struct iwl_cfg iwl6005_2agn_sff_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN",
        IWL_DEVICE_6005,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6005_2agn_d_cfg = {
+const struct iwl_cfg iwl6005_2agn_d_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN",
        IWL_DEVICE_6005,
        .ht_params = &iwl6000_ht_params,
 };
 
+const struct iwl_cfg iwl6005_2agn_mow1_cfg = {
+       .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN",
+       IWL_DEVICE_6005,
+       .ht_params = &iwl6000_ht_params,
+};
+
+const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
+       .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN",
+       IWL_DEVICE_6005,
+       .ht_params = &iwl6000_ht_params,
+};
+
 #define IWL_DEVICE_6030                                                \
        .fw_name_pre = IWL6030_FW_PRE,                          \
        .ucode_api_max = IWL6000G2_UCODE_API_MAX,               \
        .ucode_api_ok = IWL6000G2_UCODE_API_OK,                 \
        .ucode_api_min = IWL6000G2_UCODE_API_MIN,               \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_6030_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION,       \
        .lib = &iwl6030_lib,                                    \
@@ -400,53 +403,53 @@ struct iwl_cfg iwl6005_2agn_d_cfg = {
        .led_mode = IWL_LED_RF_STATE,                           \
        .adv_pm = true                                          \
 
-struct iwl_cfg iwl6030_2agn_cfg = {
+const struct iwl_cfg iwl6030_2agn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
        IWL_DEVICE_6030,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6030_2abg_cfg = {
+const struct iwl_cfg iwl6030_2abg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG",
        IWL_DEVICE_6030,
 };
 
-struct iwl_cfg iwl6030_2bgn_cfg = {
+const struct iwl_cfg iwl6030_2bgn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN",
        IWL_DEVICE_6030,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6030_2bg_cfg = {
+const struct iwl_cfg iwl6030_2bg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6230 BG",
        IWL_DEVICE_6030,
 };
 
-struct iwl_cfg iwl6035_2agn_cfg = {
+const struct iwl_cfg iwl6035_2agn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
        IWL_DEVICE_6030,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl1030_bgn_cfg = {
+const struct iwl_cfg iwl1030_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
        IWL_DEVICE_6030,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl1030_bg_cfg = {
+const struct iwl_cfg iwl1030_bg_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 1030 BG",
        IWL_DEVICE_6030,
 };
 
-struct iwl_cfg iwl130_bgn_cfg = {
+const struct iwl_cfg iwl130_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 130 BGN",
        IWL_DEVICE_6030,
        .ht_params = &iwl6000_ht_params,
        .rx_with_siso_diversity = true,
 };
 
-struct iwl_cfg iwl130_bg_cfg = {
+const struct iwl_cfg iwl130_bg_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 130 BG",
        IWL_DEVICE_6030,
        .rx_with_siso_diversity = true,
@@ -460,27 +463,29 @@ struct iwl_cfg iwl130_bg_cfg = {
        .ucode_api_max = IWL6000_UCODE_API_MAX,                 \
        .ucode_api_ok = IWL6000_UCODE_API_OK,                   \
        .ucode_api_min = IWL6000_UCODE_API_MIN,                 \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .valid_tx_ant = ANT_BC,         /* .cfg overwrite */    \
        .valid_rx_ant = ANT_BC,         /* .cfg overwrite */    \
        .eeprom_ver = EEPROM_6000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,       \
        .lib = &iwl6000_lib,                                    \
+       .additional_nic_config = iwl6000i_additional_nic_config,\
        .base_params = &iwl6000_base_params,                    \
-       .pa_type = IWL_PA_INTERNAL,                             \
        .led_mode = IWL_LED_BLINK
 
-struct iwl_cfg iwl6000i_2agn_cfg = {
+const struct iwl_cfg iwl6000i_2agn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
        IWL_DEVICE_6000i,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6000i_2abg_cfg = {
+const struct iwl_cfg iwl6000i_2abg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG",
        IWL_DEVICE_6000i,
 };
 
-struct iwl_cfg iwl6000i_2bg_cfg = {
+const struct iwl_cfg iwl6000i_2bg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6200 BG",
        IWL_DEVICE_6000i,
 };
@@ -489,6 +494,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
        .fw_name_pre = IWL6050_FW_PRE,                          \
        .ucode_api_max = IWL6050_UCODE_API_MAX,                 \
        .ucode_api_min = IWL6050_UCODE_API_MIN,                 \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .valid_tx_ant = ANT_AB,         /* .cfg overwrite */    \
        .valid_rx_ant = ANT_AB,         /* .cfg overwrite */    \
        .lib = &iwl6000_lib,                                    \
@@ -499,13 +506,13 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
        .led_mode = IWL_LED_BLINK,                              \
        .internal_wimax_coex = true
 
-struct iwl_cfg iwl6050_2agn_cfg = {
+const struct iwl_cfg iwl6050_2agn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
        IWL_DEVICE_6050,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6050_2abg_cfg = {
+const struct iwl_cfg iwl6050_2abg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
        IWL_DEVICE_6050,
 };
@@ -514,6 +521,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
        .fw_name_pre = IWL6050_FW_PRE,                          \
        .ucode_api_max = IWL6050_UCODE_API_MAX,                 \
        .ucode_api_min = IWL6050_UCODE_API_MIN,                 \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .lib = &iwl6000_lib,                                    \
        .additional_nic_config = iwl6150_additional_nic_config, \
        .eeprom_ver = EEPROM_6150_EEPROM_VERSION,               \
@@ -522,23 +531,25 @@ struct iwl_cfg iwl6050_2abg_cfg = {
        .led_mode = IWL_LED_BLINK,                              \
        .internal_wimax_coex = true
 
-struct iwl_cfg iwl6150_bgn_cfg = {
+const struct iwl_cfg iwl6150_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
        IWL_DEVICE_6150,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6150_bg_cfg = {
+const struct iwl_cfg iwl6150_bg_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG",
        IWL_DEVICE_6150,
 };
 
-struct iwl_cfg iwl6000_3agn_cfg = {
+const struct iwl_cfg iwl6000_3agn_cfg = {
        .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN",
        .fw_name_pre = IWL6000_FW_PRE,
        .ucode_api_max = IWL6000_UCODE_API_MAX,
        .ucode_api_ok = IWL6000_UCODE_API_OK,
        .ucode_api_min = IWL6000_UCODE_API_MIN,
+       .max_inst_size = IWL60_RTC_INST_SIZE,
+       .max_data_size = IWL60_RTC_DATA_SIZE,
        .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
        .lib = &iwl6000_lib,
index 50ff849c9f67a5849e4f70bd394a855f3a712401..84cbe7bb504cad1c3cfdb68cb9bcc1270c4d80ad 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * INIT calibrations framework
  *****************************************************************************/
 
+/* Opaque calibration results */
+struct iwl_calib_result {
+       struct list_head list;
+       size_t cmd_len;
+       struct iwl_calib_hdr hdr;
+       /* data follows */
+};
+
 struct statistics_general_data {
        u32 beacon_silence_rssi_a;
        u32 beacon_silence_rssi_b;
@@ -82,7 +90,7 @@ struct statistics_general_data {
        u32 beacon_energy_c;
 };
 
-int iwl_send_calib_results(struct iwl_trans *trans)
+int iwl_send_calib_results(struct iwl_priv *priv)
 {
        struct iwl_host_cmd hcmd = {
                .id = REPLY_PHY_CALIBRATION_CMD,
@@ -90,15 +98,15 @@ int iwl_send_calib_results(struct iwl_trans *trans)
        };
        struct iwl_calib_result *res;
 
-       list_for_each_entry(res, &trans->calib_results, list) {
+       list_for_each_entry(res, &priv->calib_results, list) {
                int ret;
 
                hcmd.len[0] = res->cmd_len;
                hcmd.data[0] = &res->hdr;
                hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
-               ret = iwl_trans_send_cmd(trans, &hcmd);
+               ret = iwl_dvm_send_cmd(priv, &hcmd);
                if (ret) {
-                       IWL_ERR(trans, "Error %d on calib cmd %d\n",
+                       IWL_ERR(priv, "Error %d on calib cmd %d\n",
                                ret, res->hdr.op_code);
                        return ret;
                }
@@ -107,7 +115,7 @@ int iwl_send_calib_results(struct iwl_trans *trans)
        return 0;
 }
 
-int iwl_calib_set(struct iwl_trans *trans,
+int iwl_calib_set(struct iwl_priv *priv,
                  const struct iwl_calib_hdr *cmd, int len)
 {
        struct iwl_calib_result *res, *tmp;
@@ -119,7 +127,7 @@ int iwl_calib_set(struct iwl_trans *trans,
        memcpy(&res->hdr, cmd, len);
        res->cmd_len = len;
 
-       list_for_each_entry(tmp, &trans->calib_results, list) {
+       list_for_each_entry(tmp, &priv->calib_results, list) {
                if (tmp->hdr.op_code == res->hdr.op_code) {
                        list_replace(&tmp->list, &res->list);
                        kfree(tmp);
@@ -128,16 +136,16 @@ int iwl_calib_set(struct iwl_trans *trans,
        }
 
        /* wasn't in list already */
-       list_add_tail(&res->list, &trans->calib_results);
+       list_add_tail(&res->list, &priv->calib_results);
 
        return 0;
 }
 
-void iwl_calib_free_results(struct iwl_trans *trans)
+void iwl_calib_free_results(struct iwl_priv *priv)
 {
        struct iwl_calib_result *res, *tmp;
 
-       list_for_each_entry_safe(res, tmp, &trans->calib_results, list) {
+       list_for_each_entry_safe(res, tmp, &priv->calib_results, list) {
                list_del(&res->list);
                kfree(res);
        }
@@ -492,7 +500,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
        memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
               sizeof(u16)*HD_TABLE_SIZE);
 
-       return iwl_trans_send_cmd(trans(priv), &cmd_out);
+       return iwl_dvm_send_cmd(priv, &cmd_out);
 }
 
 /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
@@ -581,7 +589,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
               &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]),
               sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES);
 
-       return iwl_trans_send_cmd(trans(priv), &cmd_out);
+       return iwl_dvm_send_cmd(priv, &cmd_out);
 }
 
 void iwl_init_sensitivity(struct iwl_priv *priv)
@@ -634,7 +642,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
        data->last_bad_plcp_cnt_cck = 0;
        data->last_fa_cnt_cck = 0;
 
-       if (priv->enhance_sensitivity_table)
+       if (priv->fw->enhance_sensitivity_table)
                ret |= iwl_enhance_sensitivity_write(priv);
        else
                ret |= iwl_sensitivity_write(priv);
@@ -653,7 +661,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
        struct iwl_sensitivity_data *data = NULL;
        struct statistics_rx_non_phy *rx_info;
        struct statistics_rx_phy *ofdm, *cck;
-       unsigned long flags;
        struct statistics_general_data statis;
 
        if (priv->disable_sens_cal)
@@ -666,13 +673,13 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
                return;
        }
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
+       spin_lock_bh(&priv->statistics.lock);
        rx_info = &priv->statistics.rx_non_phy;
        ofdm = &priv->statistics.rx_ofdm;
        cck = &priv->statistics.rx_cck;
        if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
                IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
-               spin_unlock_irqrestore(&priv->shrd->lock, flags);
+               spin_unlock_bh(&priv->statistics.lock);
                return;
        }
 
@@ -696,7 +703,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
        statis.beacon_energy_c =
                        le32_to_cpu(rx_info->beacon_energy_c);
 
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
+       spin_unlock_bh(&priv->statistics.lock);
 
        IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time);
 
@@ -745,7 +752,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
 
        iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
        iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
-       if (priv->enhance_sensitivity_table)
+       if (priv->fw->enhance_sensitivity_table)
                iwl_enhance_sensitivity_write(priv);
        else
                iwl_sensitivity_write(priv);
@@ -847,7 +854,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
                         * connect the first valid tx chain
                         */
                        first_chain =
-                               find_first_chain(cfg(priv)->valid_tx_ant);
+                               find_first_chain(hw_params(priv).valid_tx_ant);
                        data->disconn_array[first_chain] = 0;
                        active_chains |= BIT(first_chain);
                        IWL_DEBUG_CALIB(priv,
@@ -872,10 +879,8 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
 }
 
 static void iwlagn_gain_computation(struct iwl_priv *priv,
-               u32 average_noise[NUM_RX_CHAINS],
-               u16 min_average_noise_antenna_i,
-               u32 min_average_noise,
-               u8 default_chain)
+                                   u32 average_noise[NUM_RX_CHAINS],
+                                   u8 default_chain)
 {
        int i;
        s32 delta_g;
@@ -923,7 +928,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
                        priv->phy_calib_chain_noise_gain_cmd);
                cmd.delta_gain_1 = data->delta_gain_code[1];
                cmd.delta_gain_2 = data->delta_gain_code[2];
-               iwl_trans_send_cmd_pdu(trans(priv), REPLY_PHY_CALIBRATION_CMD,
+               iwl_dvm_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
                        CMD_ASYNC, sizeof(cmd), &cmd);
 
                data->radio_write = 1;
@@ -956,7 +961,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
        u16 stat_chnum = INITIALIZATION_VALUE;
        u8 rxon_band24;
        u8 stat_band24;
-       unsigned long flags;
        struct statistics_rx_non_phy *rx_info;
 
        /*
@@ -981,13 +985,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
                return;
        }
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
+       spin_lock_bh(&priv->statistics.lock);
 
        rx_info = &priv->statistics.rx_non_phy;
 
        if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
                IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
-               spin_unlock_irqrestore(&priv->shrd->lock, flags);
+               spin_unlock_bh(&priv->statistics.lock);
                return;
        }
 
@@ -1002,7 +1006,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
        if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) {
                IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n",
                                rxon_chnum, rxon_band24);
-               spin_unlock_irqrestore(&priv->shrd->lock, flags);
+               spin_unlock_bh(&priv->statistics.lock);
                return;
        }
 
@@ -1021,7 +1025,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
        chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER;
        chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER;
 
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
+       spin_unlock_bh(&priv->statistics.lock);
 
        data->beacon_count++;
 
@@ -1081,8 +1085,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
                        min_average_noise, min_average_noise_antenna_i);
 
        iwlagn_gain_computation(priv, average_noise,
-                               min_average_noise_antenna_i, min_average_noise,
-                               find_first_chain(cfg(priv)->valid_rx_ant));
+                               find_first_chain(hw_params(priv).valid_rx_ant));
 
        /* Some power changes may have been made during the calibration.
         * Update and commit the RXON
index 10275ce92bde8875f9807245cf32a0ec00addae6..9ed6683314a7fe3b493ca4fe86edf0b0c7367264 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 123ef5e129d5b734fc42ac31114cb8ea5a70765e..d0ec0abd3c896ec4391a596874660ed026419c7d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 64cf439035c3854593f27e51a838826a714518dd..915183a3a873b4e6d4cc99cee08fb7349c6b90d5 100644 (file)
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,6 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 
-#include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
@@ -52,7 +51,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
        struct iwlagn_tx_power_dbm_cmd tx_power_cmd;
        u8 tx_ant_cfg_cmd;
 
-       if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->shrd->status),
+       if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
                      "TX Power requested while scanning!\n"))
                return -EAGAIN;
 
@@ -77,17 +76,19 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
        tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED;
        tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO;
 
-       if (IWL_UCODE_API(priv->ucode_ver) == 1)
+       if (IWL_UCODE_API(priv->fw->ucode_ver) == 1)
                tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
        else
                tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
 
-       return iwl_trans_send_cmd_pdu(trans(priv), tx_ant_cfg_cmd, CMD_SYNC,
+       return iwl_dvm_send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC,
                        sizeof(tx_power_cmd), &tx_power_cmd);
 }
 
 void iwlagn_temperature(struct iwl_priv *priv)
 {
+       lockdep_assert_held(&priv->statistics.lock);
+
        /* store temperature from correct statistics (in Celsius) */
        priv->temperature = le32_to_cpu(priv->statistics.common.temperature);
        iwl_tt_handler(priv);
@@ -233,19 +234,19 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
                                IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK |
                                IWL_PAN_SCD_MULTICAST_MSK;
 
-       if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)
+       if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
                flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
 
        IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
                       flush_cmd.fifo_control);
        flush_cmd.flush_control = cpu_to_le16(flush_control);
 
-       return iwl_trans_send_cmd(trans(priv), &cmd);
+       return iwl_dvm_send_cmd(priv, &cmd);
 }
 
 void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
 {
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        ieee80211_stop_queues(priv->hw);
        if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) {
                IWL_ERR(priv, "flush request fail\n");
@@ -255,7 +256,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
        iwl_trans_wait_tx_queue_empty(trans(priv));
 done:
        ieee80211_wake_queues(priv->hw);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 /*
@@ -434,12 +435,12 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
        if (cfg(priv)->bt_params->bt_session_2) {
                memcpy(&bt_cmd_2000.basic, &basic,
                        sizeof(basic));
-               ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG,
+               ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
                        CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000);
        } else {
                memcpy(&bt_cmd_6000.basic, &basic,
                        sizeof(basic));
-               ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG,
+               ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
                        CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000);
        }
        if (ret)
@@ -452,7 +453,7 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena)
        struct iwl_rxon_context *ctx, *found_ctx = NULL;
        bool found_ap = false;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /* Check whether AP or GO mode is active. */
        if (rssi_ena) {
@@ -565,7 +566,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
                break;
        }
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        /*
         * We can not send command to firmware while scanning. When the scan
@@ -574,7 +575,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
         * STATUS_SCANNING to avoid race when queue_work two times from
         * different notifications, but quit and not perform any work at all.
         */
-       if (test_bit(STATUS_SCAN_HW, &priv->shrd->status))
+       if (test_bit(STATUS_SCAN_HW, &priv->status))
                goto out;
 
        iwl_update_chain_flags(priv);
@@ -593,7 +594,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
         */
        iwlagn_bt_coex_rssi_monitor(priv);
 out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 /*
@@ -700,17 +701,16 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv,
                priv->kill_cts_mask = bt_kill_cts_msg[kill_msk];
 
                /* schedule to send runtime bt_config */
-               queue_work(priv->shrd->workqueue, &priv->bt_runtime_config);
+               queue_work(priv->workqueue, &priv->bt_runtime_config);
        }
 }
 
 int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
-                                 struct iwl_rx_mem_buffer *rxb,
+                                 struct iwl_rx_cmd_buffer *rxb,
                                  struct iwl_device_cmd *cmd)
 {
-       unsigned long flags;
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
+       struct iwl_bt_coex_profile_notif *coex = (void *)pkt->data;
        struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
 
        if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
@@ -745,7 +745,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
                                        IWL_BT_COEX_TRAFFIC_LOAD_NONE;
                        }
                        priv->bt_status = coex->bt_status;
-                       queue_work(priv->shrd->workqueue,
+                       queue_work(priv->workqueue,
                                   &priv->bt_traffic_change_work);
                }
        }
@@ -754,9 +754,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
 
        /* FIXME: based on notification, adjust the prio_boost */
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
        priv->bt_ci_compliance = coex->bt_ci_compliance;
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
        return 0;
 }
 
@@ -959,7 +957,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
                               struct ieee80211_key_conf *key,
                               void *_data)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct wowlan_key_data *data = _data;
        struct iwl_rxon_context *ctx = data->ctx;
        struct aes_sc *aes_sc, *aes_tx_sc = NULL;
@@ -971,7 +969,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
        u16 p1k[IWLAGN_P1K_SIZE];
        int ret, i;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
             key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
@@ -1077,7 +1075,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
                break;
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 int iwlagn_send_patterns(struct iwl_priv *priv,
@@ -1117,13 +1115,12 @@ int iwlagn_send_patterns(struct iwl_priv *priv,
        }
 
        cmd.data[0] = pattern_cmd;
-       err = iwl_trans_send_cmd(trans(priv), &cmd);
+       err = iwl_dvm_send_cmd(priv, &cmd);
        kfree(pattern_cmd);
        return err;
 }
 
-int iwlagn_suspend(struct iwl_priv *priv,
-               struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan)
 {
        struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd;
        struct iwl_rxon_cmd rxon;
@@ -1194,9 +1191,9 @@ int iwlagn_suspend(struct iwl_priv *priv,
 
        iwl_trans_stop_device(trans(priv));
 
-       priv->shrd->wowlan = true;
+       priv->wowlan = true;
 
-       ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_WOWLAN);
+       ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
        if (ret)
                goto out;
 
@@ -1224,11 +1221,11 @@ int iwlagn_suspend(struct iwl_priv *priv,
                 * constraints. Since we're in the suspend path
                 * that isn't really a problem though.
                 */
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
                ieee80211_iter_keys(priv->hw, ctx->vif,
                                    iwlagn_wowlan_program_keys,
                                    &key_data);
-               mutex_lock(&priv->shrd->mutex);
+               mutex_lock(&priv->mutex);
                if (key_data.error) {
                        ret = -EIO;
                        goto out;
@@ -1243,13 +1240,13 @@ int iwlagn_suspend(struct iwl_priv *priv,
                                .len[0] = sizeof(key_data.rsc_tsc),
                        };
 
-                       ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd);
+                       ret = iwl_dvm_send_cmd(priv, &rsc_tsc_cmd);
                        if (ret)
                                goto out;
                }
 
                if (key_data.use_tkip) {
-                       ret = iwl_trans_send_cmd_pdu(trans(priv),
+                       ret = iwl_dvm_send_cmd_pdu(priv,
                                                 REPLY_WOWLAN_TKIP_PARAMS,
                                                 CMD_SYNC, sizeof(tkip_cmd),
                                                 &tkip_cmd);
@@ -1265,7 +1262,7 @@ int iwlagn_suspend(struct iwl_priv *priv,
                        kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN);
                        kek_kck_cmd.replay_ctr = priv->replay_ctr;
 
-                       ret = iwl_trans_send_cmd_pdu(trans(priv),
+                       ret = iwl_dvm_send_cmd_pdu(priv,
                                                 REPLY_WOWLAN_KEK_KCK_MATERIAL,
                                                 CMD_SYNC, sizeof(kek_kck_cmd),
                                                 &kek_kck_cmd);
@@ -1274,12 +1271,12 @@ int iwlagn_suspend(struct iwl_priv *priv,
                }
        }
 
-       ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC,
+       ret = iwl_dvm_send_cmd_pdu(priv, REPLY_D3_CONFIG, CMD_SYNC,
                                     sizeof(d3_cfg_cmd), &d3_cfg_cmd);
        if (ret)
                goto out;
 
-       ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER,
+       ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_WAKEUP_FILTER,
                                 CMD_SYNC, sizeof(wakeup_filter_cmd),
                                 &wakeup_filter_cmd);
        if (ret)
@@ -1291,3 +1288,41 @@ int iwlagn_suspend(struct iwl_priv *priv,
        return ret;
 }
 #endif
+
+int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+{
+       if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
+               IWL_WARN(priv, "Not sending command - %s KILL\n",
+                        iwl_is_rfkill(priv) ? "RF" : "CT");
+               return -EIO;
+       }
+
+       /*
+        * Synchronous commands from this op-mode must hold
+        * the mutex, this ensures we don't try to send two
+        * (or more) synchronous commands at a time.
+        */
+       if (cmd->flags & CMD_SYNC)
+               lockdep_assert_held(&priv->mutex);
+
+       if (priv->ucode_owner == IWL_OWNERSHIP_TM &&
+           !(cmd->flags & CMD_ON_DEMAND)) {
+               IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n");
+               return -EIO;
+       }
+
+       return iwl_trans_send_cmd(trans(priv), cmd);
+}
+
+int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id,
+                        u32 flags, u16 len, const void *data)
+{
+       struct iwl_host_cmd cmd = {
+               .id = id,
+               .len = { len, },
+               .data = { data, },
+               .flags = flags,
+       };
+
+       return iwl_dvm_send_cmd(priv, &cmd);
+}
index 334b5ae8fdd454ac69d9f760e28359e2b97429b7..53f8c51cfcdb021d292caf5f911694413df42d4c 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -38,6 +38,7 @@
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-agn.h"
+#include "iwl-op-mode.h"
 
 #define RS_NAME "iwl-agn-rs"
 
@@ -869,19 +870,16 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 {
        struct iwl_scale_tbl_info *tbl;
        bool full_concurrent = priv->bt_full_concurrent;
-       unsigned long flags;
 
        if (priv->bt_ant_couple_ok) {
                /*
                 * Is there a need to switch between
                 * full concurrency and 3-wire?
                 */
-               spin_lock_irqsave(&priv->shrd->lock, flags);
                if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
                        full_concurrent = true;
                else
                        full_concurrent = false;
-               spin_unlock_irqrestore(&priv->shrd->lock, flags);
        }
        if ((priv->bt_traffic_load != priv->last_bt_traffic_load) ||
            (priv->bt_full_concurrent != full_concurrent)) {
@@ -892,7 +890,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
                iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
 
-               queue_work(priv->shrd->workqueue, &priv->bt_full_concurrency);
+               queue_work(priv->workqueue, &priv->bt_full_concurrency);
        }
 }
 
@@ -909,7 +907,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        struct iwl_lq_sta *lq_sta = priv_sta;
        struct iwl_link_quality_cmd *table;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct iwl_priv *priv = (struct iwl_priv *)priv_r;
+       struct iwl_op_mode *op_mode = (struct iwl_op_mode *)priv_r;
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        enum mac80211_rate_control_flags mac_flags;
        u32 tx_rate;
@@ -2678,7 +2677,6 @@ out:
  *       which requires station table entry to exist).
  */
 static void rs_initialize_lq(struct iwl_priv *priv,
-                            struct ieee80211_conf *conf,
                             struct ieee80211_sta *sta,
                             struct iwl_lq_sta *lq_sta)
 {
@@ -2737,7 +2735,9 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
 
        struct sk_buff *skb = txrc->skb;
        struct ieee80211_supported_band *sband = txrc->sband;
-       struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r;
+       struct iwl_op_mode *op_mode __maybe_unused =
+                       (struct iwl_op_mode *)priv_r;
+       struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode);
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct iwl_lq_sta *lq_sta = priv_sta;
        int rate_idx;
@@ -2805,9 +2805,10 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
                          gfp_t gfp)
 {
        struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;
-       struct iwl_priv *priv;
+       struct iwl_op_mode *op_mode __maybe_unused =
+                       (struct iwl_op_mode *)priv_rate;
+       struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode);
 
-       priv = (struct iwl_priv *)priv_rate;
        IWL_DEBUG_RATE(priv, "create station rate scale window\n");
 
        return &sta_priv->lq_sta;
@@ -2910,7 +2911,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
        lq_sta->dbg_fixed_rate = 0;
 #endif
 
-       rs_initialize_lq(priv, conf, sta, lq_sta);
+       rs_initialize_lq(priv, sta, lq_sta);
 }
 
 static void rs_fill_link_cmd(struct iwl_priv *priv,
@@ -3074,7 +3075,8 @@ static void rs_free(void *priv_rate)
 static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
                        void *priv_sta)
 {
-       struct iwl_priv *priv __maybe_unused = priv_r;
+       struct iwl_op_mode *op_mode __maybe_unused = priv_r;
+       struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode);
 
        IWL_DEBUG_RATE(priv, "enter\n");
        IWL_DEBUG_RATE(priv, "leave\n");
index 6675b3c816d989e3a7f47f1a8f025fac98aab67e..203b1c13c491ffc00bb0b343caad9b54bdabf839 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index b22b2976f899e037cb73884c1ef66b9af565386f..cc0227c1f3525bb9cf45b9088c777741c4f7b933 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portionhelp of the ieee80211 subsystem header files.
@@ -131,26 +131,27 @@ const char *get_cmd_string(u8 cmd)
  ******************************************************************************/
 
 static int iwlagn_rx_reply_error(struct iwl_priv *priv,
-                              struct iwl_rx_mem_buffer *rxb,
+                              struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
+       struct iwl_error_resp *err_resp = (void *)pkt->data;
 
        IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
                "seq 0x%04X ser 0x%08X\n",
-               le32_to_cpu(pkt->u.err_resp.error_type),
-               get_cmd_string(pkt->u.err_resp.cmd_id),
-               pkt->u.err_resp.cmd_id,
-               le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
-               le32_to_cpu(pkt->u.err_resp.error_info));
+               le32_to_cpu(err_resp->error_type),
+               get_cmd_string(err_resp->cmd_id),
+               err_resp->cmd_id,
+               le16_to_cpu(err_resp->bad_cmd_seq_num),
+               le32_to_cpu(err_resp->error_info));
        return 0;
 }
 
-static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
+       struct iwl_csa_notification *csa = (void *)pkt->data;
        /*
         * MULTI-FIXME
         * See iwlagn_mac_channel_switch.
@@ -158,7 +159,7 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
 
-       if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status))
+       if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
                return 0;
 
        if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
@@ -177,11 +178,11 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
 
 
 static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv,
-                                         struct iwl_rx_mem_buffer *rxb,
+                                         struct iwl_rx_cmd_buffer *rxb,
                                          struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
+       struct iwl_spectrum_notification *report = (void *)pkt->data;
 
        if (!report->state) {
                IWL_DEBUG_11H(priv,
@@ -195,12 +196,12 @@ static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv,
 }
 
 static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv,
-                                 struct iwl_rx_mem_buffer *rxb,
+                                 struct iwl_rx_cmd_buffer *rxb,
                                  struct iwl_device_cmd *cmd)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
+       struct iwl_sleep_notification *sleep = (void *)pkt->data;
        IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
                     sleep->pm_sleep_mode, sleep->pm_wakeup_src);
 #endif
@@ -208,7 +209,7 @@ static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv,
 }
 
 static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
-                                            struct iwl_rx_mem_buffer *rxb,
+                                            struct iwl_rx_cmd_buffer *rxb,
                                             struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -217,16 +218,16 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
        IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
                        "notification for %s:\n", len,
                        get_cmd_string(pkt->hdr.cmd));
-       iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
+       iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len);
        return 0;
 }
 
 static int iwlagn_rx_beacon_notif(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb,
+                               struct iwl_rx_cmd_buffer *rxb,
                                struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw;
+       struct iwlagn_beacon_notif *beacon = (void *)pkt->data;
 #ifdef CONFIG_IWLWIFI_DEBUG
        u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status);
        u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
@@ -266,6 +267,8 @@ static bool iwlagn_good_ack_health(struct iwl_priv *priv,
        if (priv->agg_tids_count)
                return true;
 
+       lockdep_assert_held(&priv->statistics.lock);
+
        old = &priv->statistics.tx;
 
        actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
@@ -318,7 +321,7 @@ static bool iwlagn_good_plcp_health(struct iwl_priv *priv,
                                 unsigned int msecs)
 {
        int delta;
-       int threshold = cfg(priv)->base_params->plcp_delta_threshold;
+       int threshold = priv->plcp_delta_threshold;
 
        if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
                IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
@@ -352,7 +355,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv,
 {
        unsigned int msecs;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies);
@@ -487,7 +490,7 @@ iwlagn_accumulative_statistics(struct iwl_priv *priv,
 #endif
 
 static int iwlagn_rx_statistics(struct iwl_priv *priv,
-                             struct iwl_rx_mem_buffer *rxb,
+                             struct iwl_rx_cmd_buffer *rxb,
                              struct iwl_device_cmd *cmd)
 {
        unsigned long stamp = jiffies;
@@ -509,9 +512,11 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
        IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n",
                     len);
 
+       spin_lock(&priv->statistics.lock);
+
        if (len == sizeof(struct iwl_bt_notif_statistics)) {
                struct iwl_bt_notif_statistics *stats;
-               stats = &pkt->u.stats_bt;
+               stats = (void *)&pkt->data;
                flag = &stats->flag;
                common = &stats->general.common;
                rx_non_phy = &stats->rx.general.common;
@@ -529,7 +534,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
 #endif
        } else if (len == sizeof(struct iwl_notif_statistics)) {
                struct iwl_notif_statistics *stats;
-               stats = &pkt->u.stats;
+               stats = (void *)&pkt->data;
                flag = &stats->flag;
                common = &stats->general.common;
                rx_non_phy = &stats->rx.general;
@@ -542,6 +547,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
                WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n",
                          len, sizeof(struct iwl_bt_notif_statistics),
                          sizeof(struct iwl_notif_statistics));
+               spin_unlock(&priv->statistics.lock);
                return 0;
        }
 
@@ -569,7 +575,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
 
        priv->rx_statistics_jiffies = stamp;
 
-       set_bit(STATUS_STATISTICS, &priv->shrd->status);
+       set_bit(STATUS_STATISTICS, &priv->status);
 
        /* Reschedule the statistics timer to occur in
         * reg_recalib_period seconds to ensure we get a
@@ -578,23 +584,27 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
        mod_timer(&priv->statistics_periodic, jiffies +
                  msecs_to_jiffies(reg_recalib_period * 1000));
 
-       if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) &&
+       if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
            (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
                iwlagn_rx_calc_noise(priv);
-               queue_work(priv->shrd->workqueue, &priv->run_time_calib_work);
+               queue_work(priv->workqueue, &priv->run_time_calib_work);
        }
        if (cfg(priv)->lib->temperature && change)
                cfg(priv)->lib->temperature(priv);
+
+       spin_unlock(&priv->statistics.lock);
+
        return 0;
 }
 
 static int iwlagn_rx_reply_statistics(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb,
+                                   struct iwl_rx_cmd_buffer *rxb,
                                    struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
+       struct iwl_notif_statistics *stats = (void *)pkt->data;
 
-       if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
+       if (le32_to_cpu(stats->flag) & UCODE_STATISTICS_CLEAR_MSK) {
 #ifdef CONFIG_IWLWIFI_DEBUGFS
                memset(&priv->accum_stats, 0,
                        sizeof(priv->accum_stats));
@@ -612,12 +622,13 @@ static int iwlagn_rx_reply_statistics(struct iwl_priv *priv,
 /* Handle notification from uCode that card's power state is changing
  * due to software, hardware, or critical temperature RFKILL */
 static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb,
+                                   struct iwl_rx_cmd_buffer *rxb,
                                    struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
-       unsigned long status = priv->shrd->status;
+       struct iwl_card_state_notif *card_state_notif = (void *)pkt->data;
+       u32 flags = le32_to_cpu(card_state_notif->flags);
+       unsigned long status = priv->status;
 
        IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
                          (flags & HW_CARD_DISABLED) ? "Kill" : "On",
@@ -628,16 +639,16 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
        if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
                     CT_CARD_DISABLED)) {
 
-               iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET,
+               iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET,
                            CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
-               iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C,
+               iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C,
                                        HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 
                if (!(flags & RXON_CARD_DISABLED)) {
-                       iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR,
+                       iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
                                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-                       iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C,
+                       iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C,
                                        HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
                }
                if (flags & CT_CARD_DISABLED)
@@ -647,32 +658,31 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
                iwl_tt_exit_ct_kill(priv);
 
        if (flags & HW_CARD_DISABLED)
-               set_bit(STATUS_RF_KILL_HW, &priv->shrd->status);
+               set_bit(STATUS_RF_KILL_HW, &priv->status);
        else
-               clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status);
+               clear_bit(STATUS_RF_KILL_HW, &priv->status);
 
 
        if (!(flags & RXON_CARD_DISABLED))
                iwl_scan_cancel(priv);
 
        if ((test_bit(STATUS_RF_KILL_HW, &status) !=
-            test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)))
+            test_bit(STATUS_RF_KILL_HW, &priv->status)))
                wiphy_rfkill_set_hw_state(priv->hw->wiphy,
-                       test_bit(STATUS_RF_KILL_HW, &priv->shrd->status));
+                       test_bit(STATUS_RF_KILL_HW, &priv->status));
        else
                wake_up(&priv->shrd->wait_command_queue);
        return 0;
 }
 
 static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb,
+                                      struct iwl_rx_cmd_buffer *rxb,
                                       struct iwl_device_cmd *cmd)
 
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_missed_beacon_notif *missed_beacon;
+       struct iwl_missed_beacon_notif *missed_beacon = (void *)pkt->data;
 
-       missed_beacon = &pkt->u.missed_beacon;
        if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
            priv->missed_beacon_threshold) {
                IWL_DEBUG_CALIB(priv,
@@ -681,7 +691,7 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
                    le32_to_cpu(missed_beacon->total_missed_becons),
                    le32_to_cpu(missed_beacon->num_recvd_beacons),
                    le32_to_cpu(missed_beacon->num_expected_beacons));
-               if (!test_bit(STATUS_SCANNING, &priv->shrd->status))
+               if (!test_bit(STATUS_SCANNING, &priv->status))
                        iwl_init_sensitivity(priv);
        }
        return 0;
@@ -690,13 +700,13 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
 /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
  * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
 static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb,
+                               struct iwl_rx_cmd_buffer *rxb,
                                struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
        priv->last_phy_res_valid = true;
-       memcpy(&priv->last_phy_res, pkt->u.raw,
+       memcpy(&priv->last_phy_res, pkt->data,
               sizeof(struct iwl_rx_phy_res));
        return 0;
 }
@@ -757,12 +767,14 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
                                        struct ieee80211_hdr *hdr,
                                        u16 len,
                                        u32 ampdu_status,
-                                       struct iwl_rx_mem_buffer *rxb,
+                                       struct iwl_rx_cmd_buffer *rxb,
                                        struct ieee80211_rx_status *stats)
 {
        struct sk_buff *skb;
        __le16 fc = hdr->frame_control;
        struct iwl_rxon_context *ctx;
+       struct page *p;
+       int offset;
 
        /* We only process data packets if the interface is open */
        if (unlikely(!priv->is_open)) {
@@ -782,7 +794,9 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
                return;
        }
 
-       skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
+       offset = (void *)hdr - rxb_addr(rxb);
+       p = rxb_steal_page(rxb);
+       skb_add_rx_frag(skb, 0, p, offset, len);
 
        iwl_update_stats(priv, false, fc, len);
 
@@ -793,23 +807,18 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
        * sometimes even after already having transmitted frames for the
        * association because the new RXON may reset the information.
        */
-       if (unlikely(ieee80211_is_beacon(fc))) {
+       if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) {
                for_each_context(priv, ctx) {
-                       if (!ctx->last_tx_rejected)
-                               continue;
                        if (compare_ether_addr(hdr->addr3,
                                               ctx->active.bssid_addr))
                                continue;
-                       ctx->last_tx_rejected = false;
-                       iwl_trans_wake_any_queue(trans(priv), ctx->ctxid,
-                               "channel got active");
+                       iwlagn_lift_passive_no_rx(priv);
                }
        }
 
        memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
 
        ieee80211_rx(priv->hw, skb);
-       rxb->page = NULL;
 }
 
 static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
@@ -915,7 +924,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
 /* Called for REPLY_RX (legacy ABG frames), or
  * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
 static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
-                           struct iwl_rx_mem_buffer *rxb,
+                           struct iwl_rx_cmd_buffer *rxb,
                            struct iwl_device_cmd *cmd)
 {
        struct ieee80211_hdr *header;
@@ -938,12 +947,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
         * received.
         */
        if (pkt->hdr.cmd == REPLY_RX) {
-               phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
-               header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
+               phy_res = (struct iwl_rx_phy_res *)pkt->data;
+               header = (struct ieee80211_hdr *)(pkt->data + sizeof(*phy_res)
                                + phy_res->cfg_phy_cnt);
 
                len = le16_to_cpu(phy_res->byte_count);
-               rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
+               rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*phy_res) +
                                phy_res->cfg_phy_cnt + len);
                ampdu_status = le32_to_cpu(rx_pkt_status);
        } else {
@@ -952,10 +961,10 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
                        return 0;
                }
                phy_res = &priv->last_phy_res;
-               amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw;
-               header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
+               amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data;
+               header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu));
                len = le16_to_cpu(amsdu->byte_count);
-               rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
+               rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len);
                ampdu_status = iwlagn_translate_rx_status(priv,
                                                le32_to_cpu(rx_pkt_status));
        }
@@ -1035,12 +1044,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
 }
 
 static int iwlagn_rx_noa_notification(struct iwl_priv *priv,
-                                     struct iwl_rx_mem_buffer *rxb,
+                                     struct iwl_rx_cmd_buffer *rxb,
                                      struct iwl_device_cmd *cmd)
 {
        struct iwl_wipan_noa_data *new_data, *old_data;
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->u.raw;
+       struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->data;
 
        /* no condition -- we're in softirq */
        old_data = rcu_dereference_protected(priv->noa_data, true);
@@ -1086,7 +1095,7 @@ static int iwlagn_rx_noa_notification(struct iwl_priv *priv,
  */
 void iwl_setup_rx_handlers(struct iwl_priv *priv)
 {
-       int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+       int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd);
 
        handlers = priv->rx_handlers;
@@ -1131,20 +1140,20 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
        priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
 
        /* set up notification wait support */
-       spin_lock_init(&priv->shrd->notif_wait_lock);
-       INIT_LIST_HEAD(&priv->shrd->notif_waits);
-       init_waitqueue_head(&priv->shrd->notif_waitq);
+       iwl_notification_wait_init(&priv->notif_wait);
 
        /* Set up BT Rx handlers */
-       if (cfg(priv)->lib->bt_rx_handler_setup)
-               cfg(priv)->lib->bt_rx_handler_setup(priv);
-
+       if (cfg(priv)->bt_params)
+               iwlagn_bt_rx_handler_setup(priv);
 }
 
-int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
-                    struct iwl_device_cmd *cmd)
+int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
+                   struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+       void (*pre_rx_handler)(struct iwl_priv *,
+                              struct iwl_rx_cmd_buffer *);
        int err = 0;
 
        /*
@@ -1152,40 +1161,34 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
         * even if the RX handler consumes the RXB we have
         * access to it in the notification wait entry.
         */
-       if (!list_empty(&priv->shrd->notif_waits)) {
-               struct iwl_notification_wait *w;
-
-               spin_lock(&priv->shrd->notif_wait_lock);
-               list_for_each_entry(w, &priv->shrd->notif_waits, list) {
-                       if (w->cmd != pkt->hdr.cmd)
-                               continue;
+       iwl_notification_wait_notify(&priv->notif_wait, pkt);
+
+       /* RX data may be forwarded to userspace (using pre_rx_handler) in one
+        * of two cases: the first, that the user owns the uCode through
+        * testmode - in such case the pre_rx_handler is set and no further
+        * processing takes place. The other case is when the user want to
+        * monitor the rx w/o affecting the regular flow - the pre_rx_handler
+        * will be set but the ownership flag != IWL_OWNERSHIP_TM and the flow
+        * continues.
+        * We need to use ACCESS_ONCE to prevent a case where the handler
+        * changes between the check and the call.
+        */
+       pre_rx_handler = ACCESS_ONCE(priv->pre_rx_handler);
+       if (pre_rx_handler)
+               pre_rx_handler(priv, rxb);
+       if (priv->ucode_owner != IWL_OWNERSHIP_TM) {
+               /* Based on type of command response or notification,
+                *   handle those that need handling via function in
+                *   rx_handlers table.  See iwl_setup_rx_handlers() */
+               if (priv->rx_handlers[pkt->hdr.cmd]) {
+                       priv->rx_handlers_stats[pkt->hdr.cmd]++;
+                       err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
+               } else {
+                       /* No handling needed */
                        IWL_DEBUG_RX(priv,
-                               "Notif: %s, 0x%02x - wake the callers up\n",
-                               get_cmd_string(pkt->hdr.cmd),
-                               pkt->hdr.cmd);
-                       w->triggered = true;
-                       if (w->fn)
-                               w->fn(trans(priv), pkt, w->fn_data);
+                               "No handler needed for %s, 0x%02x\n",
+                               get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
                }
-               spin_unlock(&priv->shrd->notif_wait_lock);
-
-               wake_up_all(&priv->shrd->notif_waitq);
-       }
-
-       if (priv->pre_rx_handler)
-               priv->pre_rx_handler(priv, rxb);
-
-       /* Based on type of command response or notification,
-        *   handle those that need handling via function in
-        *   rx_handlers table.  See iwl_setup_rx_handlers() */
-       if (priv->rx_handlers[pkt->hdr.cmd]) {
-               priv->rx_handlers_stats[pkt->hdr.cmd]++;
-               err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
-       } else {
-               /* No handling needed */
-               IWL_DEBUG_RX(priv,
-                       "No handler needed for %s, 0x%02x\n",
-                       get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
        }
        return err;
 }
index 1c66594166216ead48f032417f34e10ea6ebd2f3..36909077f994917c72bbc80cad3ef5a5e613aaf3 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -39,7 +39,7 @@ static int iwlagn_disable_bss(struct iwl_priv *priv,
        int ret;
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd,
                                CMD_SYNC, sizeof(*send), send);
 
        send->filter_flags = old_filter;
@@ -60,13 +60,13 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
        u8 old_dev_type = send->dev_type;
        int ret;
 
-       iwl_init_notification_wait(priv->shrd, &disable_wait,
-                                     REPLY_WIPAN_DEACTIVATION_COMPLETE,
-                                     NULL, NULL);
+       iwl_init_notification_wait(&priv->notif_wait, &disable_wait,
+                                  REPLY_WIPAN_DEACTIVATION_COMPLETE,
+                                  NULL, NULL);
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        send->dev_type = RXON_DEV_TYPE_P2P;
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd,
                                CMD_SYNC, sizeof(*send), send);
 
        send->filter_flags = old_filter;
@@ -74,9 +74,10 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
 
        if (ret) {
                IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
-               iwl_remove_notification(priv->shrd, &disable_wait);
+               iwl_remove_notification(&priv->notif_wait, &disable_wait);
        } else {
-               ret = iwl_wait_notification(priv->shrd, &disable_wait, HZ);
+               ret = iwl_wait_notification(&priv->notif_wait,
+                                           &disable_wait, HZ);
                if (ret)
                        IWL_ERR(priv, "Timed out waiting for PAN disable\n");
        }
@@ -92,7 +93,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv,
        int ret;
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
                                sizeof(*send), send);
 
        send->filter_flags = old_filter;
@@ -121,7 +122,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv,
                      ctx->qos_data.qos_active,
                      ctx->qos_data.def_qos_parm.qos_flags);
 
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->qos_cmd, CMD_SYNC,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC,
                               sizeof(struct iwl_qosparam_cmd),
                               &ctx->qos_data.def_qos_parm);
        if (ret)
@@ -131,7 +132,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv,
 static int iwlagn_update_beacon(struct iwl_priv *priv,
                                struct ieee80211_vif *vif)
 {
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        dev_kfree_skb(priv->beacon_skb);
        priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif);
@@ -180,7 +181,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
                 ctx->staging.ofdm_ht_triple_stream_basic_rates;
        rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
 
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_assoc_cmd,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_assoc_cmd,
                                CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc);
        return ret;
 }
@@ -266,7 +267,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
         * Associated RXON doesn't clear the station table in uCode,
         * so we don't need to restore stations etc. after this.
         */
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
                      sizeof(struct iwl_rxon_cmd), &ctx->staging);
        if (ret) {
                IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
@@ -274,8 +275,6 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
        }
        memcpy(active, &ctx->staging, sizeof(*active));
 
-       iwl_reprogram_ap_sta(priv, ctx);
-
        /* IBSS beacon needs to be sent after setting assoc */
        if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
                if (iwlagn_update_beacon(priv, ctx->vif))
@@ -315,7 +314,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
 
        BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS];
        ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN];
@@ -362,7 +361,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
                slot0 = bcnint / 2;
                slot1 = bcnint - slot0;
 
-               if (test_bit(STATUS_SCAN_HW, &priv->shrd->status) ||
+               if (test_bit(STATUS_SCAN_HW, &priv->status) ||
                    (!ctx_bss->vif->bss_conf.idle &&
                     !ctx_bss->vif->bss_conf.assoc)) {
                        slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME;
@@ -378,7 +377,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
                                        ctx_pan->beacon_int;
                slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);
 
-               if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
+               if (test_bit(STATUS_SCAN_HW, &priv->status)) {
                        slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME;
                        slot1 = IWL_MIN_SLOT_TIME;
                }
@@ -387,7 +386,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
        cmd.slots[0].width = cpu_to_le16(slot0);
        cmd.slots[1].width = cpu_to_le16(slot1);
 
-       ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WIPAN_PARAMS, CMD_SYNC,
+       ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC,
                        sizeof(cmd), &cmd);
        if (ret)
                IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret);
@@ -420,12 +419,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
-
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-               return -EINVAL;
+       lockdep_assert_held(&priv->mutex);
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EBUSY;
 
        /* This function hardcodes a bunch of dual-mode assumptions */
@@ -434,10 +430,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        if (!ctx->is_active)
                return 0;
 
-       /* override BSSID if necessary due to preauth */
-       if (ctx->preauth_bssid)
-               memcpy(ctx->staging.bssid_addr, ctx->bssid, ETH_ALEN);
-
        /* always get timestamp with Rx frame */
        ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
 
@@ -445,8 +437,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
         * force CTS-to-self frames protection if RTS-CTS is not preferred
         * one aggregation protection method
         */
-       if (!(cfg(priv)->ht_params &&
-             cfg(priv)->ht_params->use_rts_for_aggregation))
+       if (!hw_params(priv).use_rts_for_aggregation)
                ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
 
        if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
@@ -466,7 +457,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
         * receive commit_rxon request
         * abort any previous channel switch if still in process
         */
-       if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status) &&
+       if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
            (priv->switch_channel != ctx->staging.channel)) {
                IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
                              le16_to_cpu(priv->switch_channel));
@@ -549,7 +540,7 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf,
 
 int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_rxon_context *ctx;
        struct ieee80211_conf *conf = &hw->conf;
        struct ieee80211_channel *channel = conf->channel;
@@ -558,17 +549,14 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
 
        IWL_DEBUG_MAC80211(priv, "enter: changed %#x", changed);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-               goto out;
-
-       if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) {
+       if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
                IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
                goto out;
        }
 
-       if (!iwl_is_ready(priv->shrd)) {
+       if (!iwl_is_ready(priv)) {
                IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
                goto out;
        }
@@ -590,8 +578,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
        }
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               unsigned long flags;
-
                ch_info = iwl_get_channel_info(priv, channel->band,
                                               channel->hw_value);
                if (!is_channel_valid(ch_info)) {
@@ -600,8 +586,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
                        goto out;
                }
 
-               spin_lock_irqsave(&priv->shrd->lock, flags);
-
                for_each_context(priv, ctx) {
                        /* Configure HT40 channels */
                        if (ctx->ht.enabled != conf_is_ht(conf))
@@ -636,8 +620,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
                                               ctx->vif);
                }
 
-               spin_unlock_irqrestore(&priv->shrd->lock, flags);
-
                iwl_update_bcast_stations(priv);
 
                /*
@@ -668,7 +650,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
                iwlagn_commit_rxon(priv, ctx);
        }
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return ret;
@@ -685,7 +667,7 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv,
        struct ieee80211_sta_ht_cap *ht_cap;
        bool need_multiple;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        switch (vif->type) {
        case NL80211_IFTYPE_STATION:
@@ -789,7 +771,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
                memset(&cmd, 0, sizeof(cmd));
                iwl_set_calib_hdr(&cmd.hdr,
                        priv->phy_calib_chain_noise_reset_cmd);
-               ret = iwl_trans_send_cmd_pdu(trans(priv),
+               ret = iwl_dvm_send_cmd_pdu(priv,
                                        REPLY_PHY_CALIBRATION_CMD,
                                        CMD_SYNC, sizeof(cmd), &cmd);
                if (ret)
@@ -805,22 +787,22 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                             struct ieee80211_bss_conf *bss_conf,
                             u32 changes)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
        int ret;
        bool force = false;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (unlikely(!iwl_is_ready(priv->shrd))) {
+       if (unlikely(!iwl_is_ready(priv))) {
                IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
                return;
         }
 
        if (unlikely(!ctx->vif)) {
                IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n");
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
                return;
        }
 
@@ -851,12 +833,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                         * not get stuck in this case either since it
                         * can happen if userspace gets confused.
                         */
-                       if (ctx->last_tx_rejected) {
-                               ctx->last_tx_rejected = false;
-                               iwl_trans_wake_any_queue(trans(priv),
-                                                        ctx->ctxid,
-                                                        "Disassoc: flush queue");
-                       }
+                       iwlagn_lift_passive_no_rx(priv);
+
                        ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 
                        if (ctx->ctxid == IWL_RXON_CTX_BSS)
@@ -900,6 +878,22 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                }
        }
 
+       /*
+        * If the ucode decides to do beacon filtering before
+        * association, it will lose beacons that are needed
+        * before sending frames out on passive channels. This
+        * causes association failures on those channels. Enable
+        * receiving beacons in such cases.
+        */
+
+       if (vif->type == NL80211_IFTYPE_STATION) {
+               if (!bss_conf->assoc)
+                       ctx->staging.filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
+               else
+                       ctx->staging.filter_flags &=
+                                                   ~RXON_FILTER_BCON_AWARE_MSK;
+       }
+
        if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
                iwlagn_commit_rxon(priv, ctx);
 
@@ -916,7 +910,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                if (!priv->disable_chain_noise_cal)
                        iwlagn_chain_noise_reset(priv);
                priv->start_calib = 1;
-               WARN_ON(ctx->preauth_bssid);
        }
 
        if (changes & BSS_CHANGED_IBSS) {
@@ -934,7 +927,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                        IWL_ERR(priv, "Error sending IBSS beacon\n");
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 void iwlagn_post_scan(struct iwl_priv *priv)
index 7353826095f110a8766d6c1a4425a71c49ba8a91..c4175603864b24f195cd0aa9dda554783a67a80f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -26,7 +26,7 @@
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *
  *****************************************************************************/
-
+#include <linux/etherdevice.h>
 #include <net/mac80211.h>
 
 #include "iwl-dev.h"
 #include "iwl-agn.h"
 #include "iwl-trans.h"
 
-/* priv->shrd->sta_lock must be held */
-static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
+static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
 {
+       lockdep_assert_held(&priv->sta_lock);
 
+       if (sta_id >= IWLAGN_STATION_COUNT) {
+               IWL_ERR(priv, "invalid sta_id %u", sta_id);
+               return -EINVAL;
+       }
        if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
                IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u "
                        "addr %pM\n",
@@ -53,14 +57,15 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
                IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
                                sta_id, priv->stations[sta_id].sta.sta.addr);
        }
+       return 0;
 }
 
 static int iwl_process_add_sta_resp(struct iwl_priv *priv,
                                    struct iwl_addsta_cmd *addsta,
                                    struct iwl_rx_packet *pkt)
 {
+       struct iwl_add_sta_resp *add_sta_resp = (void *)pkt->data;
        u8 sta_id = addsta->sta.sta_id;
-       unsigned long flags;
        int ret = -EIO;
 
        if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
@@ -72,13 +77,12 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
        IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
                       sta_id);
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock(&priv->sta_lock);
 
-       switch (pkt->u.add_sta.status) {
+       switch (add_sta_resp->status) {
        case ADD_STA_SUCCESS_MSK:
                IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
-               iwl_sta_ucode_activate(priv, sta_id);
-               ret = 0;
+               ret = iwl_sta_ucode_activate(priv, sta_id);
                break;
        case ADD_STA_NO_ROOM_IN_TABLE:
                IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
@@ -94,7 +98,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
                break;
        default:
                IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
-                               pkt->u.add_sta.status);
+                               add_sta_resp->status);
                break;
        }
 
@@ -115,12 +119,12 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
                       priv->stations[sta_id].sta.mode ==
                       STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
                       addsta->sta.addr);
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock(&priv->sta_lock);
 
        return ret;
 }
 
-int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -150,14 +154,14 @@ int iwl_send_add_sta(struct iwl_priv *priv,
                might_sleep();
        }
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
 
        if (ret || (flags & CMD_ASYNC))
                return ret;
        /*else the command was successfully sent in SYNC mode, need to free
         * the reply page */
 
-       iwl_free_pages(priv->shrd, cmd.reply_page);
+       iwl_free_resp(&cmd);
 
        if (cmd.handler_status)
                IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
@@ -166,34 +170,38 @@ int iwl_send_add_sta(struct iwl_priv *priv,
        return cmd.handler_status;
 }
 
-static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
-                                  struct ieee80211_sta *sta,
-                                  struct iwl_rxon_context *ctx)
+static void iwl_sta_calc_ht_flags(struct iwl_priv *priv,
+                                 struct ieee80211_sta *sta,
+                                 struct iwl_rxon_context *ctx,
+                                 __le32 *flags, __le32 *mask)
 {
        struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
-       __le32 sta_flags;
        u8 mimo_ps_mode;
 
+       *mask = STA_FLG_RTS_MIMO_PROT_MSK |
+               STA_FLG_MIMO_DIS_MSK |
+               STA_FLG_HT40_EN_MSK |
+               STA_FLG_MAX_AGG_SIZE_MSK |
+               STA_FLG_AGG_MPDU_DENSITY_MSK;
+       *flags = 0;
+
        if (!sta || !sta_ht_inf->ht_supported)
-               goto done;
+               return;
 
        mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
-       IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
+
+       IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n",
                        (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
                        "static" :
                        (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
                        "dynamic" : "disabled");
 
-       sta_flags = priv->stations[index].sta.station_flags;
-
-       sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
-
        switch (mimo_ps_mode) {
        case WLAN_HT_CAP_SM_PS_STATIC:
-               sta_flags |= STA_FLG_MIMO_DIS_MSK;
+               *flags |= STA_FLG_MIMO_DIS_MSK;
                break;
        case WLAN_HT_CAP_SM_PS_DYNAMIC:
-               sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
+               *flags |= STA_FLG_RTS_MIMO_PROT_MSK;
                break;
        case WLAN_HT_CAP_SM_PS_DISABLED:
                break;
@@ -202,20 +210,53 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
                break;
        }
 
-       sta_flags |= cpu_to_le32(
-             (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
+       *flags |= cpu_to_le32(
+               (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
 
-       sta_flags |= cpu_to_le32(
-             (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
+       *flags |= cpu_to_le32(
+               (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
 
        if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
-               sta_flags |= STA_FLG_HT40_EN_MSK;
-       else
-               sta_flags &= ~STA_FLG_HT40_EN_MSK;
+               *flags |= STA_FLG_HT40_EN_MSK;
+}
+
+int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                     struct ieee80211_sta *sta)
+{
+       u8 sta_id = iwl_sta_id(sta);
+       __le32 flags, mask;
+       struct iwl_addsta_cmd cmd;
+
+       if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION))
+               return -EINVAL;
+
+       iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask);
+
+       spin_lock_bh(&priv->sta_lock);
+       priv->stations[sta_id].sta.station_flags &= ~mask;
+       priv->stations[sta_id].sta.station_flags |= flags;
+       spin_unlock_bh(&priv->sta_lock);
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.mode = STA_CONTROL_MODIFY_MSK;
+       cmd.station_flags_msk = mask;
+       cmd.station_flags = flags;
+       cmd.sta.sta_id = sta_id;
+
+       return iwl_send_add_sta(priv, &cmd, CMD_SYNC);
+}
+
+static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
+                                  struct ieee80211_sta *sta,
+                                  struct iwl_rxon_context *ctx)
+{
+       __le32 flags, mask;
+
+       iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask);
 
-       priv->stations[index].sta.station_flags = sta_flags;
- done:
-       return;
+       lockdep_assert_held(&priv->sta_lock);
+       priv->stations[index].sta.station_flags &= ~mask;
+       priv->stations[index].sta.station_flags |= flags;
 }
 
 /**
@@ -314,18 +355,17 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                           const u8 *addr, bool is_ap,
                           struct ieee80211_sta *sta, u8 *sta_id_r)
 {
-       unsigned long flags_spin;
        int ret = 0;
        u8 sta_id;
        struct iwl_addsta_cmd sta_cmd;
 
        *sta_id_r = 0;
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta);
        if (sta_id == IWL_INVALID_STATION) {
                IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
                        addr);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EINVAL;
        }
 
@@ -337,7 +377,7 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
        if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
                IWL_DEBUG_INFO(priv, "STA %d already in process of being "
                               "added.\n", sta_id);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EEXIST;
        }
 
@@ -345,24 +385,24 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
            (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
                IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not "
                                "adding again.\n", sta_id, addr);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EEXIST;
        }
 
        priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta,
               sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
 
        /* Add station to device's station table */
        ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
        if (ret) {
-               spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+               spin_lock_bh(&priv->sta_lock);
                IWL_ERR(priv, "Adding station %pM failed.\n",
                        priv->stations[sta_id].sta.sta.addr);
                priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
                priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
        }
        *sta_id_r = sta_id;
        return ret;
@@ -370,11 +410,11 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 
 /**
  * iwl_sta_ucode_deactivate - deactivate ucode status for a station
- *
- * priv->shrd->sta_lock must be held
  */
 static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
 {
+       lockdep_assert_held(&priv->sta_lock);
+
        /* Ucode must be active and driver must be non active */
        if ((priv->stations[sta_id].used &
             (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) !=
@@ -393,8 +433,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 {
        struct iwl_rx_packet *pkt;
        int ret;
-
-       unsigned long flags_spin;
        struct iwl_rem_sta_cmd rm_sta_cmd;
 
        struct iwl_host_cmd cmd = {
@@ -410,12 +448,12 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 
        cmd.flags |= CMD_WANT_SKB;
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
 
        if (ret)
                return ret;
 
-       pkt = (struct iwl_rx_packet *)cmd.reply_page;
+       pkt = cmd.resp_pkt;
        if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
                          pkt->hdr.flags);
@@ -423,14 +461,13 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
        }
 
        if (!ret) {
-               switch (pkt->u.rem_sta.status) {
+               struct iwl_rem_sta_resp *rem_sta_resp = (void *)pkt->data;
+               switch (rem_sta_resp->status) {
                case REM_STA_SUCCESS_MSK:
                        if (!temporary) {
-                               spin_lock_irqsave(&priv->shrd->sta_lock,
-                                       flags_spin);
+                               spin_lock_bh(&priv->sta_lock);
                                iwl_sta_ucode_deactivate(priv, sta_id);
-                               spin_unlock_irqrestore(&priv->shrd->sta_lock,
-                                       flags_spin);
+                               spin_unlock_bh(&priv->sta_lock);
                        }
                        IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
                        break;
@@ -440,7 +477,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
                        break;
                }
        }
-       iwl_free_pages(priv->shrd, cmd.reply_page);
+       iwl_free_resp(&cmd);
 
        return ret;
 }
@@ -451,10 +488,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
                       const u8 *addr)
 {
-       unsigned long flags;
        u8 tid;
 
-       if (!iwl_is_ready(priv->shrd)) {
+       if (!iwl_is_ready(priv)) {
                IWL_DEBUG_INFO(priv,
                        "Unable to remove station %pM, device not ready.\n",
                        addr);
@@ -472,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
        if (WARN_ON(sta_id == IWL_INVALID_STATION))
                return -EINVAL;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
 
        if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
                IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
@@ -502,14 +538,49 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
        if (WARN_ON(priv->num_stations < 0))
                priv->num_stations = 0;
 
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_remove_station(priv, addr, sta_id, false);
 out_err:
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
        return -EINVAL;
 }
 
+void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
+                           const u8 *addr)
+{
+       u8 tid;
+
+       if (!iwl_is_ready(priv)) {
+               IWL_DEBUG_INFO(priv,
+                       "Unable to remove station %pM, device not ready.\n",
+                       addr);
+               return;
+       }
+
+       IWL_DEBUG_ASSOC(priv, "Deactivating STA: %pM (%d)\n", addr, sta_id);
+
+       if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION))
+               return;
+
+       spin_lock_bh(&priv->sta_lock);
+
+       WARN_ON_ONCE(!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE));
+
+       for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
+               memset(&priv->tid_data[sta_id][tid], 0,
+                       sizeof(priv->tid_data[sta_id][tid]));
+
+       priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
+
+       priv->num_stations--;
+
+       if (WARN_ON_ONCE(priv->num_stations < 0))
+               priv->num_stations = 0;
+
+       spin_unlock_bh(&priv->sta_lock);
+}
+
 /**
  * iwl_clear_ucode_stations - clear ucode station table bits
  *
@@ -522,12 +593,11 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv,
                              struct iwl_rxon_context *ctx)
 {
        int i;
-       unsigned long flags_spin;
        bool cleared = false;
 
        IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n");
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
                if (ctx && ctx->ctxid != priv->stations[i].ctxid)
                        continue;
@@ -539,7 +609,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv,
                        cleared = true;
                }
        }
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
 
        if (!cleared)
                IWL_DEBUG_INFO(priv,
@@ -558,20 +628,19 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
        struct iwl_addsta_cmd sta_cmd;
        struct iwl_link_quality_cmd lq;
-       unsigned long flags_spin;
        int i;
        bool found = false;
        int ret;
        bool send_lq;
 
-       if (!iwl_is_ready(priv->shrd)) {
+       if (!iwl_is_ready(priv)) {
                IWL_DEBUG_INFO(priv,
                               "Not ready yet, not restoring any stations.\n");
                return;
        }
 
        IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
                if (ctx->ctxid != priv->stations[i].ctxid)
                        continue;
@@ -591,27 +660,24 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                               sizeof(struct iwl_addsta_cmd));
                        send_lq = false;
                        if (priv->stations[i].lq) {
-                               if (priv->shrd->wowlan)
+                               if (priv->wowlan)
                                        iwl_sta_fill_lq(priv, ctx, i, &lq);
                                else
                                        memcpy(&lq, priv->stations[i].lq,
                                               sizeof(struct iwl_link_quality_cmd));
                                send_lq = true;
                        }
-                       spin_unlock_irqrestore(&priv->shrd->sta_lock,
-                                              flags_spin);
+                       spin_unlock_bh(&priv->sta_lock);
                        ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
                        if (ret) {
-                               spin_lock_irqsave(&priv->shrd->sta_lock,
-                                                 flags_spin);
+                               spin_lock_bh(&priv->sta_lock);
                                IWL_ERR(priv, "Adding station %pM failed.\n",
                                        priv->stations[i].sta.sta.addr);
                                priv->stations[i].used &=
                                                ~IWL_STA_DRIVER_ACTIVE;
                                priv->stations[i].used &=
                                                ~IWL_STA_UCODE_INPROGRESS;
-                               spin_unlock_irqrestore(&priv->shrd->sta_lock,
-                                                      flags_spin);
+                               spin_unlock_bh(&priv->sta_lock);
                        }
                        /*
                         * Rate scaling has already been initialized, send
@@ -620,12 +686,12 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        if (send_lq)
                                iwl_send_lq_cmd(priv, ctx, &lq,
                                                CMD_SYNC, true);
-                       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+                       spin_lock_bh(&priv->sta_lock);
                        priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
                }
        }
 
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
        if (!found)
                IWL_DEBUG_INFO(priv, "Restoring all known stations .... "
                        "no stations to be restored.\n");
@@ -634,52 +700,6 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        "complete.\n");
 }
 
-void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
-{
-       unsigned long flags;
-       int sta_id = ctx->ap_sta_id;
-       int ret;
-       struct iwl_addsta_cmd sta_cmd;
-       struct iwl_link_quality_cmd lq;
-       bool active, have_lq = false;
-
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-               return;
-       }
-
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
-       sta_cmd.mode = 0;
-       if (priv->stations[sta_id].lq) {
-               memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
-               have_lq = true;
-       }
-
-       active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
-       priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-
-       if (active) {
-               ret = iwl_send_remove_station(
-                       priv, priv->stations[sta_id].sta.sta.addr,
-                       sta_id, true);
-               if (ret)
-                       IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
-                               priv->stations[sta_id].sta.sta.addr, ret);
-       }
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-
-       ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-       if (ret)
-               IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
-                       priv->stations[sta_id].sta.sta.addr, ret);
-       if (have_lq)
-               iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
-}
-
 int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
 {
        int i;
@@ -693,10 +713,9 @@ int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
 
 void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
 {
-       unsigned long flags;
        int i;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
                if (!(priv->stations[i].used & IWL_STA_BCAST))
                        continue;
@@ -708,7 +727,7 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
                kfree(priv->stations[i].lq);
                priv->stations[i].lq = NULL;
        }
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -780,8 +799,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                    struct iwl_link_quality_cmd *lq, u8 flags, bool init)
 {
        int ret = 0;
-       unsigned long flags_spin;
-
        struct iwl_host_cmd cmd = {
                .id = REPLY_TX_LINK_QUALITY_CMD,
                .len = { sizeof(struct iwl_link_quality_cmd), },
@@ -793,19 +810,19 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                return -EINVAL;
 
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EINVAL;
        }
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
 
        iwl_dump_lq_cmd(priv, lq);
        if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
                return -EINVAL;
 
        if (is_lq_table_valid(priv, ctx, lq))
-               ret = iwl_trans_send_cmd(trans(priv), &cmd);
+               ret = iwl_dvm_send_cmd(priv, &cmd);
        else
                ret = -EINVAL;
 
@@ -816,9 +833,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                IWL_DEBUG_INFO(priv, "init LQ command complete, "
                               "clearing sta addition status for sta %d\n",
                               lq->sta_id);
-               spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+               spin_lock_bh(&priv->sta_lock);
                priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
        }
        return ret;
 }
@@ -831,7 +848,7 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
        u32 rate_flags = 0;
        __le32 rate_n_flags;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        memset(link_cmd, 0, sizeof(*link_cmd));
 
@@ -903,7 +920,6 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv,
        int ret;
        u8 sta_id;
        struct iwl_link_quality_cmd *link_cmd;
-       unsigned long flags;
 
        if (sta_id_r)
                *sta_id_r = IWL_INVALID_STATION;
@@ -917,9 +933,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv,
        if (sta_id_r)
                *sta_id_r = sta_id;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].used |= IWL_STA_LOCAL;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        /* Set up default rate scaling table in device's station table */
        link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
@@ -934,9 +950,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv,
        if (ret)
                IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].lq = link_cmd;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return 0;
 }
@@ -991,7 +1007,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
        cmd.len[0] = cmd_size;
 
        if (not_empty || send_if_empty)
-               return iwl_trans_send_cmd(trans(priv), &cmd);
+               return iwl_dvm_send_cmd(priv, &cmd);
        else
                return 0;
 }
@@ -999,7 +1015,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
 int iwl_restore_default_wep_keys(struct iwl_priv *priv,
                                 struct iwl_rxon_context *ctx)
 {
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        return iwl_send_static_wepkey_cmd(priv, ctx, false);
 }
@@ -1010,13 +1026,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
 {
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
                      keyconf->keyidx);
 
        memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
-       if (iwl_is_rfkill(priv->shrd)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_WEP(priv,
                        "Not sending REPLY_WEPKEY command due to RFKILL.\n");
                /* but keys in device are clear anyway so return success */
@@ -1035,7 +1051,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
 {
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (keyconf->keylen != WEP_KEY_LEN_128 &&
            keyconf->keylen != WEP_KEY_LEN_64) {
@@ -1077,32 +1093,19 @@ static u8 iwlagn_key_sta_id(struct iwl_priv *priv,
                            struct ieee80211_sta *sta)
 {
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
-       u8 sta_id = IWL_INVALID_STATION;
 
        if (sta)
-               sta_id = iwl_sta_id(sta);
+               return iwl_sta_id(sta);
 
        /*
         * The device expects GTKs for station interfaces to be
         * installed as GTKs for the AP station. If we have no
         * station ID, then use the ap_sta_id in that case.
         */
-       if (!sta && vif && vif_priv->ctx) {
-               switch (vif->type) {
-               case NL80211_IFTYPE_STATION:
-                       sta_id = vif_priv->ctx->ap_sta_id;
-                       break;
-               default:
-                       /*
-                        * In all other cases, the key will be
-                        * used either for TX only or is bound
-                        * to a station already.
-                        */
-                       break;
-               }
-       }
+       if (vif->type == NL80211_IFTYPE_STATION && vif_priv->ctx)
+               return vif_priv->ctx->ap_sta_id;
 
-       return sta_id;
+       return IWL_INVALID_STATION;
 }
 
 static int iwlagn_send_sta_key(struct iwl_priv *priv,
@@ -1110,14 +1113,13 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv,
                               u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k,
                               u32 cmd_flags)
 {
-       unsigned long flags;
        __le16 key_flags;
        struct iwl_addsta_cmd sta_cmd;
        int i;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
        key_flags |= STA_KEY_FLG_MAP_KEY_MSK;
@@ -1184,24 +1186,24 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
                           struct ieee80211_key_conf *keyconf,
                           struct ieee80211_sta *sta)
 {
-       unsigned long flags;
        struct iwl_addsta_cmd sta_cmd;
        u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta);
+       __le16 key_flags;
 
        /* if station isn't there, neither is the key */
        if (sta_id == IWL_INVALID_STATION)
                return -ENOENT;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
        if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE))
                sta_id = IWL_INVALID_STATION;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        if (sta_id == IWL_INVALID_STATION)
                return 0;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        ctx->key_mapping_keys--;
 
@@ -1212,7 +1214,14 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
                IWL_ERR(priv, "offset %d not used in uCode key table.\n",
                        keyconf->hw_key_idx);
 
-       sta_cmd.key.key_flags = STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
+       key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+       key_flags |= STA_KEY_FLG_MAP_KEY_MSK | STA_KEY_FLG_NO_ENC |
+                    STA_KEY_FLG_INVALID;
+
+       if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+               key_flags |= STA_KEY_MULTICAST_MSK;
+
+       sta_cmd.key.key_flags = key_flags;
        sta_cmd.key.key_offset = WEP_INVALID_OFFSET;
        sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK;
        sta_cmd.mode = STA_CONTROL_MODIFY_MSK;
@@ -1234,7 +1243,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
        if (sta_id == IWL_INVALID_STATION)
                return -EINVAL;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv);
        if (keyconf->hw_key_idx == WEP_INVALID_OFFSET)
@@ -1289,21 +1298,20 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
                               struct iwl_rxon_context *ctx)
 {
        struct iwl_link_quality_cmd *link_cmd;
-       unsigned long flags;
        u8 sta_id;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
        if (sta_id == IWL_INVALID_STATION) {
                IWL_ERR(priv, "Unable to prepare broadcast station\n");
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock_bh(&priv->sta_lock);
 
                return -EINVAL;
        }
 
        priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
        priv->stations[sta_id].used |= IWL_STA_BCAST;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
        if (!link_cmd) {
@@ -1312,9 +1320,9 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
                return -ENOMEM;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].lq = link_cmd;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return 0;
 }
@@ -1328,7 +1336,6 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
 int iwl_update_bcast_station(struct iwl_priv *priv,
                             struct iwl_rxon_context *ctx)
 {
-       unsigned long flags;
        struct iwl_link_quality_cmd *link_cmd;
        u8 sta_id = ctx->bcast_sta_id;
 
@@ -1338,13 +1345,13 @@ int iwl_update_bcast_station(struct iwl_priv *priv,
                return -ENOMEM;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        if (priv->stations[sta_id].lq)
                kfree(priv->stations[sta_id].lq);
        else
                IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
        priv->stations[sta_id].lq = link_cmd;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return 0;
 }
@@ -1368,18 +1375,17 @@ int iwl_update_bcast_stations(struct iwl_priv *priv)
  */
 int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
 {
-       unsigned long flags;
        struct iwl_addsta_cmd sta_cmd;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /* Remove "disable" flag, to enable Tx for this TID */
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
        priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
 }
@@ -1387,24 +1393,23 @@ int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
 int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
                         int tid, u16 ssn)
 {
-       unsigned long flags;
        int sta_id;
        struct iwl_addsta_cmd sta_cmd;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        sta_id = iwl_sta_id(sta);
        if (sta_id == IWL_INVALID_STATION)
                return -ENXIO;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].sta.station_flags_msk = 0;
        priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
        priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
        priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
 }
@@ -1412,11 +1417,10 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
 int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
                        int tid)
 {
-       unsigned long flags;
        int sta_id;
        struct iwl_addsta_cmd sta_cmd;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        sta_id = iwl_sta_id(sta);
        if (sta_id == IWL_INVALID_STATION) {
@@ -1424,13 +1428,13 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
                return -ENXIO;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].sta.station_flags_msk = 0;
        priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
        priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
 }
@@ -1439,16 +1443,14 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
 
 void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.sta.modify_mask =
-                                       STA_MODIFY_SLEEP_TX_COUNT_MSK;
-       priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       struct iwl_addsta_cmd cmd = {
+               .mode = STA_CONTROL_MODIFY_MSK,
+               .station_flags = STA_FLG_PWR_SAVE_MSK,
+               .station_flags_msk = STA_FLG_PWR_SAVE_MSK,
+               .sta.sta_id = sta_id,
+               .sta.modify_mask = STA_MODIFY_SLEEP_TX_COUNT_MSK,
+               .sleep_tx_count = cpu_to_le16(cnt),
+       };
 
+       iwl_send_add_sta(priv, &cmd, CMD_ASYNC);
 }
index b0dff7a753a56a5e60db10f6d5ab46dd024e7932..baaf5ba2fc38b79e818e8e2ef19b469a89bf72d1 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -34,6 +34,7 @@
 
 #include <net/mac80211.h>
 
+#include "iwl-agn.h"
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
@@ -173,24 +174,24 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
        unsigned long flags;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        if (tt->state == IWL_TI_CT_KILL) {
                if (priv->thermal_throttle.ct_kill_toggle) {
-                       iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR,
+                       iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
                                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
                        priv->thermal_throttle.ct_kill_toggle = false;
                } else {
-                       iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET,
+                       iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET,
                                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
                        priv->thermal_throttle.ct_kill_toggle = true;
                }
-               iwl_read32(bus(priv), CSR_UCODE_DRV_GP1);
-               spin_lock_irqsave(&bus(priv)->reg_lock, flags);
-               if (!iwl_grab_nic_access(bus(priv)))
-                       iwl_release_nic_access(bus(priv));
-               spin_unlock_irqrestore(&bus(priv)->reg_lock, flags);
+               iwl_read32(trans(priv), CSR_UCODE_DRV_GP1);
+               spin_lock_irqsave(&trans(priv)->reg_lock, flags);
+               if (likely(iwl_grab_nic_access(trans(priv))))
+                       iwl_release_nic_access(trans(priv));
+               spin_unlock_irqrestore(&trans(priv)->reg_lock, flags);
 
                /* Reschedule the ct_kill timer to occur in
                 * CT_KILL_EXIT_DURATION seconds to ensure we get a
@@ -224,7 +225,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data)
        struct iwl_priv *priv = (struct iwl_priv *)data;
        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        /* temperature timer expired, ready to go into CT_KILL state */
@@ -232,7 +233,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data)
                IWL_DEBUG_TEMP(priv, "entering CT_KILL state when "
                                "temperature timer expired\n");
                tt->state = IWL_TI_CT_KILL;
-               set_bit(STATUS_CT_KILL, &priv->shrd->status);
+               set_bit(STATUS_CT_KILL, &priv->status);
                iwl_perform_ct_kill_task(priv, true);
        }
 }
@@ -310,24 +311,23 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                        tt->tt_power_mode = IWL_POWER_INDEX_5;
                        break;
                }
-               mutex_lock(&priv->shrd->mutex);
+               mutex_lock(&priv->mutex);
                if (old_state == IWL_TI_CT_KILL)
-                       clear_bit(STATUS_CT_KILL, &priv->shrd->status);
+                       clear_bit(STATUS_CT_KILL, &priv->status);
                if (tt->state != IWL_TI_CT_KILL &&
                    iwl_power_update_mode(priv, true)) {
                        /* TT state not updated
                         * try again during next temperature read
                         */
                        if (old_state == IWL_TI_CT_KILL)
-                               set_bit(STATUS_CT_KILL, &priv->shrd->status);
+                               set_bit(STATUS_CT_KILL, &priv->status);
                        tt->state = old_state;
                        IWL_ERR(priv, "Cannot update power mode, "
                                        "TT state not updated\n");
                } else {
                        if (tt->state == IWL_TI_CT_KILL) {
                                if (force) {
-                                       set_bit(STATUS_CT_KILL,
-                                               &priv->shrd->status);
+                                       set_bit(STATUS_CT_KILL, &priv->status);
                                        iwl_perform_ct_kill_task(priv, true);
                                } else {
                                        iwl_prepare_ct_kill_task(priv);
@@ -341,7 +341,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                        IWL_DEBUG_TEMP(priv, "Power Index change to %u\n",
                                        tt->tt_power_mode);
                }
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
        }
 }
 
@@ -451,9 +451,9 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                         * in case get disabled before */
                        iwl_set_rxon_ht(priv, &priv->current_ht_config);
                }
-               mutex_lock(&priv->shrd->mutex);
+               mutex_lock(&priv->mutex);
                if (old_state == IWL_TI_CT_KILL)
-                       clear_bit(STATUS_CT_KILL, &priv->shrd->status);
+                       clear_bit(STATUS_CT_KILL, &priv->status);
                if (tt->state != IWL_TI_CT_KILL &&
                    iwl_power_update_mode(priv, true)) {
                        /* TT state not updated
@@ -462,7 +462,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                        IWL_ERR(priv, "Cannot update power mode, "
                                        "TT state not updated\n");
                        if (old_state == IWL_TI_CT_KILL)
-                               set_bit(STATUS_CT_KILL, &priv->shrd->status);
+                               set_bit(STATUS_CT_KILL, &priv->status);
                        tt->state = old_state;
                } else {
                        IWL_DEBUG_TEMP(priv,
@@ -473,8 +473,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                                if (force) {
                                        IWL_DEBUG_TEMP(priv,
                                                "Enter IWL_TI_CT_KILL\n");
-                                       set_bit(STATUS_CT_KILL,
-                                               &priv->shrd->status);
+                                       set_bit(STATUS_CT_KILL, &priv->status);
                                        iwl_perform_ct_kill_task(priv, true);
                                } else {
                                        iwl_prepare_ct_kill_task(priv);
@@ -486,7 +485,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                                iwl_perform_ct_kill_task(priv, false);
                        }
                }
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
        }
 }
 
@@ -505,10 +504,10 @@ static void iwl_bg_ct_enter(struct work_struct *work)
        struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       if (!iwl_is_ready(priv->shrd))
+       if (!iwl_is_ready(priv))
                return;
 
        if (tt->state != IWL_TI_CT_KILL) {
@@ -534,10 +533,10 @@ static void iwl_bg_ct_exit(struct work_struct *work)
        struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       if (!iwl_is_ready(priv->shrd))
+       if (!iwl_is_ready(priv))
                return;
 
        /* stop ct_kill_exit_tm timer */
@@ -564,20 +563,20 @@ static void iwl_bg_ct_exit(struct work_struct *work)
 
 void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
 {
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n");
-       queue_work(priv->shrd->workqueue, &priv->ct_enter);
+       queue_work(priv->workqueue, &priv->ct_enter);
 }
 
 void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
 {
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n");
-       queue_work(priv->shrd->workqueue, &priv->ct_exit);
+       queue_work(priv->workqueue, &priv->ct_exit);
 }
 
 static void iwl_bg_tt_work(struct work_struct *work)
@@ -585,7 +584,7 @@ static void iwl_bg_tt_work(struct work_struct *work)
        struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
        s32 temp = priv->temperature; /* degrees CELSIUS except specified */
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        if (!priv->thermal_throttle.advanced_tt)
@@ -596,11 +595,11 @@ static void iwl_bg_tt_work(struct work_struct *work)
 
 void iwl_tt_handler(struct iwl_priv *priv)
 {
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n");
-       queue_work(priv->shrd->workqueue, &priv->tt_work);
+       queue_work(priv->workqueue, &priv->tt_work);
 }
 
 /* Thermal throttling initialization
index 7282a23e8f1ce3faab9e3cf78080323a65b9a453..86bbf47501c1b90d956c9e9035233ca2701e0c08 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
index 63bbc60be28e461ada4e173b5caafbd43f243c31..9f224548b63621df03491785adee0e93bec477a8 100644 (file)
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -126,7 +126,7 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
        u8 data_retry_limit;
        u8 rate_plcp;
 
-       if (priv->shrd->wowlan) {
+       if (priv->wowlan) {
                rts_retry_limit = IWLAGN_LOW_RETRY_LIMIT;
                data_retry_limit = IWLAGN_LOW_RETRY_LIMIT;
        } else {
@@ -208,10 +208,9 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
 }
 
 static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
-                                     struct ieee80211_tx_info *info,
-                                     struct iwl_tx_cmd *tx_cmd,
-                                     struct sk_buff *skb_frag,
-                                     int sta_id)
+                                        struct ieee80211_tx_info *info,
+                                        struct iwl_tx_cmd *tx_cmd,
+                                        struct sk_buff *skb_frag)
 {
        struct ieee80211_key_conf *keyconf = info->control.hw_key;
 
@@ -249,6 +248,35 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
        }
 }
 
+/**
+ * iwl_sta_id_or_broadcast - return sta_id or broadcast sta
+ * @context: the current context
+ * @sta: mac80211 station
+ *
+ * In certain circumstances mac80211 passes a station pointer
+ * that may be %NULL, for example during TX or key setup. In
+ * that case, we need to use the broadcast station, so this
+ * inline wraps that pattern.
+ */
+static int iwl_sta_id_or_broadcast(struct iwl_rxon_context *context,
+                                  struct ieee80211_sta *sta)
+{
+       int sta_id;
+
+       if (!sta)
+               return context->bcast_sta_id;
+
+       sta_id = iwl_sta_id(sta);
+
+       /*
+        * mac80211 should not be passing a partially
+        * initialised station!
+        */
+       WARN_ON(sta_id == IWL_INVALID_STATION);
+
+       return sta_id;
+}
+
 /*
  * start REPLY_TX command process
  */
@@ -260,19 +288,16 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct iwl_device_cmd *dev_cmd = NULL;
        struct iwl_tx_cmd *tx_cmd;
-
        __le16 fc;
        u8 hdr_len;
        u16 len, seq_number = 0;
        u8 sta_id, tid = IWL_MAX_TID_COUNT;
-       unsigned long flags;
        bool is_agg = false;
 
        if (info->control.vif)
                ctx = iwl_rxon_ctx_from_vif(info->control.vif);
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
-       if (iwl_is_rfkill(priv->shrd)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
                goto drop_unlock_priv;
        }
@@ -308,7 +333,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                sta_id = ctx->bcast_sta_id;
        else {
                /* Find index into station table for destination station */
-               sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta);
+               sta_id = iwl_sta_id_or_broadcast(ctx, info->control.sta);
                if (sta_id == IWL_INVALID_STATION) {
                        IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
                                       hdr->addr1);
@@ -322,7 +347,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                sta_priv = (void *)info->control.sta->drv_priv;
 
        if (sta_priv && sta_priv->asleep &&
-           (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) {
+           (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) {
                /*
                 * This sends an asynchronous command to the device,
                 * but we can rely on it being processed before the
@@ -331,6 +356,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                 * counter.
                 * For now set the counter to just 1 since we do not
                 * support uAPSD yet.
+                *
+                * FIXME: If we get two non-bufferable frames one
+                * after the other, we might only send out one of
+                * them because this is racy.
                 */
                iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
        }
@@ -338,13 +367,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        if (info->flags & IEEE80211_TX_CTL_AMPDU)
                is_agg = true;
 
-       /* irqs already disabled/saved above when locking priv->shrd->lock */
-       spin_lock(&priv->shrd->sta_lock);
-
-       dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC);
+       dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC);
 
        if (unlikely(!dev_cmd))
-               goto drop_unlock_sta;
+               goto drop_unlock_priv;
 
        memset(dev_cmd, 0, sizeof(*dev_cmd));
        tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;
@@ -354,7 +380,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        tx_cmd->len = cpu_to_le16(len);
 
        if (info->control.hw_key)
-               iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
+               iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb);
 
        /* TODO need this for burst mode later on */
        iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id);
@@ -369,6 +395,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        info->driver_data[0] = ctx;
        info->driver_data[1] = dev_cmd;
 
+       spin_lock(&priv->sta_lock);
+
        if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) {
                u8 *qc = NULL;
                struct iwl_tid_data *tid_data;
@@ -414,8 +442,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
            !ieee80211_has_morefrags(fc))
                priv->tid_data[sta_id][tid].seq_number = seq_number;
 
-       spin_unlock(&priv->shrd->sta_lock);
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
+       spin_unlock(&priv->sta_lock);
 
        /*
         * Avoid atomic ops if it isn't an associated client.
@@ -431,10 +458,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
 drop_unlock_sta:
        if (dev_cmd)
-               kmem_cache_free(priv->tx_cmd_pool, dev_cmd);
-       spin_unlock(&priv->shrd->sta_lock);
+               kmem_cache_free(iwl_tx_cmd_pool, dev_cmd);
+       spin_unlock(&priv->sta_lock);
 drop_unlock_priv:
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
        return -1;
 }
 
@@ -442,7 +468,6 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta, u16 tid)
 {
        struct iwl_tid_data *tid_data;
-       unsigned long flags;
        int sta_id;
 
        sta_id = iwl_sta_id(sta);
@@ -452,7 +477,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                return -ENXIO;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
 
        tid_data = &priv->tid_data[sta_id][tid];
 
@@ -472,7 +497,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                IWL_WARN(priv, "Stopping AGG while state not ON "
                         "or starting for %d on %d (%d)\n", sta_id, tid,
                         priv->tid_data[sta_id][tid].agg.state);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock_bh(&priv->sta_lock);
                return 0;
        }
 
@@ -486,7 +511,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                                    tid_data->next_reclaimed);
                priv->tid_data[sta_id][tid].agg.state =
                        IWL_EMPTYING_HW_QUEUE_DELBA;
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock_bh(&priv->sta_lock);
                return 0;
        }
 
@@ -495,14 +520,10 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
 turn_off:
        priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;
 
-       /* do not restore/save irqs */
-       spin_unlock(&priv->shrd->sta_lock);
-       spin_lock(&priv->shrd->lock);
+       spin_unlock_bh(&priv->sta_lock);
 
        iwl_trans_tx_agg_disable(trans(priv), sta_id, tid);
 
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
-
        ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 
        return 0;
@@ -512,7 +533,6 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta, u16 tid, u16 *ssn)
 {
        struct iwl_tid_data *tid_data;
-       unsigned long flags;
        int sta_id;
        int ret;
 
@@ -536,7 +556,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
        if (ret)
                return ret;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
 
        tid_data = &priv->tid_data[sta_id][tid];
        tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number);
@@ -545,7 +565,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
 
        ret = iwl_trans_tx_agg_alloc(trans(priv), sta_id, tid);
        if (ret) {
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock_bh(&priv->sta_lock);
                return ret;
        }
 
@@ -562,7 +582,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
                tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
        }
 
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return ret;
 }
@@ -572,14 +592,13 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
 {
        struct iwl_station_priv *sta_priv = (void *) sta->drv_priv;
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
-       unsigned long flags;
        u16 ssn;
 
        buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, sta_priv->sta_id, tid,
                               buf_size, ssn);
@@ -604,8 +623,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
        sta_priv->max_agg_bufsize =
                min(sta_priv->max_agg_bufsize, buf_size);
 
-       if (cfg(priv)->ht_params &&
-           cfg(priv)->ht_params->use_rts_for_aggregation) {
+       if (hw_params(priv).use_rts_for_aggregation) {
                /*
                 * switch to RTS/CTS if it is the prefer protection
                 * method for HT traffic
@@ -635,7 +653,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid)
        struct ieee80211_vif *vif;
        u8 *addr;
 
-       lockdep_assert_held(&priv->shrd->sta_lock);
+       lockdep_assert_held(&priv->sta_lock);
 
        addr = priv->stations[sta_id].sta.sta.addr;
        ctx = priv->stations[sta_id].ctxid;
@@ -982,19 +1000,19 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
 {
        if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) {
                IWL_ERR(priv, "Tx flush command to flush out all frames\n");
-               if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-                       queue_work(priv->shrd->workqueue, &priv->tx_flush);
+               if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
+                       queue_work(priv->workqueue, &priv->tx_flush);
        }
 }
 
-int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        int txq_id = SEQ_TO_QUEUE(sequence);
        int cmd_index __maybe_unused = SEQ_TO_INDEX(sequence);
-       struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+       struct iwlagn_tx_resp *tx_resp = (void *)pkt->data;
        struct ieee80211_hdr *hdr;
        u32 status = le16_to_cpu(tx_resp->status.status);
        u16 ssn = iwlagn_get_scd_ssn(tx_resp);
@@ -1002,7 +1020,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
        int sta_id;
        int freed;
        struct ieee80211_tx_info *info;
-       unsigned long flags;
        struct sk_buff_head skbs;
        struct sk_buff *skb;
        struct iwl_rxon_context *ctx;
@@ -1013,11 +1030,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
        sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >>
                IWLAGN_TX_RES_RA_POS;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock(&priv->sta_lock);
 
        if (is_agg)
                iwl_rx_reply_tx_agg(priv, tx_resp);
 
+       __skb_queue_head_init(&skbs);
+
        if (tx_resp->frame_count == 1) {
                u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl);
                next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10);
@@ -1037,8 +1056,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                        next_reclaimed = ssn;
                }
 
-               __skb_queue_head_init(&skbs);
-
                if (tid != IWL_TID_NON_QOS) {
                        priv->tid_data[sta_id][tid].next_reclaimed =
                                next_reclaimed;
@@ -1047,12 +1064,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                }
 
                /*we can free until ssn % q.n_bd not inclusive */
-               WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id,
-                                 ssn, status, &skbs));
+               WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid,
+                                         txq_id, ssn, &skbs));
                iwlagn_check_ratid_empty(priv, sta_id, tid);
                freed = 0;
-               while (!skb_queue_empty(&skbs)) {
-                       skb = __skb_dequeue(&skbs);
+
+               /* process frames */
+               skb_queue_walk(&skbs, skb) {
                        hdr = (struct ieee80211_hdr *)skb->data;
 
                        if (!ieee80211_is_data_qos(hdr->frame_control))
@@ -1060,7 +1078,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
 
                        info = IEEE80211_SKB_CB(skb);
                        ctx = info->driver_data[0];
-                       kmem_cache_free(priv->tx_cmd_pool,
+                       kmem_cache_free(iwl_tx_cmd_pool,
                                        (info->driver_data[1]));
 
                        memset(&info->status, 0, sizeof(info->status));
@@ -1068,9 +1086,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                        if (status == TX_STATUS_FAIL_PASSIVE_NO_RX &&
                            iwl_is_associated_ctx(ctx) && ctx->vif &&
                            ctx->vif->type == NL80211_IFTYPE_STATION) {
-                               ctx->last_tx_rejected = true;
-                               iwl_trans_stop_queue(trans(priv), txq_id,
-                                       "Tx on passive channel");
+                               /* block and stop all queues */
+                               priv->passive_no_rx = true;
+                               IWL_DEBUG_TX_QUEUES(priv, "stop all queues: "
+                                                   "passive channel");
+                               ieee80211_stop_queues(priv->hw);
 
                                IWL_DEBUG_TX_REPLY(priv,
                                           "TXQ %d status %s (0x%08x) "
@@ -1094,8 +1114,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                        if (!is_agg)
                                iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
 
-                       ieee80211_tx_status_irqsafe(priv->hw, skb);
-
                        freed++;
                }
 
@@ -1103,7 +1121,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
        }
 
        iwl_check_abort_status(priv, tx_resp->frame_count, status);
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock(&priv->sta_lock);
+
+       while (!skb_queue_empty(&skbs)) {
+               skb = __skb_dequeue(&skbs);
+               ieee80211_tx_status(priv->hw, skb);
+       }
+
        return 0;
 }
 
@@ -1114,17 +1138,16 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
  * of frames sent via aggregation.
  */
 int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
-                                  struct iwl_rx_mem_buffer *rxb,
+                                  struct iwl_rx_cmd_buffer *rxb,
                                   struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
+       struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data;
        struct iwl_ht_agg *agg;
        struct sk_buff_head reclaimed_skbs;
        struct ieee80211_tx_info *info;
        struct ieee80211_hdr *hdr;
        struct sk_buff *skb;
-       unsigned long flags;
        int sta_id;
        int tid;
        int freed;
@@ -1146,12 +1169,12 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
        tid = ba_resp->tid;
        agg = &priv->tid_data[sta_id][tid].agg;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock(&priv->sta_lock);
 
        if (unlikely(!agg->wait_for_ba)) {
                if (unlikely(ba_resp->bitmap))
                        IWL_ERR(priv, "Received BA when not expected\n");
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock(&priv->sta_lock);
                return 0;
        }
 
@@ -1161,8 +1184,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
         * block-ack window (we assume that they've been successfully
         * transmitted ... if not, it's too late anyway). */
        if (iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow,
-                             ba_resp_scd_ssn, 0, &reclaimed_skbs)) {
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+                             ba_resp_scd_ssn, &reclaimed_skbs)) {
+               spin_unlock(&priv->sta_lock);
                return 0;
        }
 
@@ -1198,9 +1221,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
 
        iwlagn_check_ratid_empty(priv, sta_id, tid);
        freed = 0;
-       while (!skb_queue_empty(&reclaimed_skbs)) {
 
-               skb = __skb_dequeue(&reclaimed_skbs);
+       skb_queue_walk(&reclaimed_skbs, skb) {
                hdr = (struct ieee80211_hdr *)skb->data;
 
                if (ieee80211_is_data_qos(hdr->frame_control))
@@ -1209,7 +1231,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
                        WARN_ON_ONCE(1);
 
                info = IEEE80211_SKB_CB(skb);
-               kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1]));
+               kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1]));
 
                if (freed == 1) {
                        /* this is the first skb we deliver in this batch */
@@ -1223,10 +1245,14 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
                        iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags,
                                                    info);
                }
+       }
+
+       spin_unlock(&priv->sta_lock);
 
-               ieee80211_tx_status_irqsafe(priv->hw, skb);
+       while (!skb_queue_empty(&reclaimed_skbs)) {
+               skb = __skb_dequeue(&reclaimed_skbs);
+               ieee80211_tx_status(priv->hw, skb);
        }
 
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
        return 0;
 }
index b5c7c5f0a753f4da5520982f16b0ca8292958691..60f1dc640c945f451ea8b7a9b58256011258d549 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -34,7 +34,6 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
 #include <asm/div64.h>
 
 #include "iwl-eeprom.h"
-#include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-agn-calib.h"
 #include "iwl-agn.h"
 #include "iwl-shared.h"
-#include "iwl-bus.h"
 #include "iwl-trans.h"
+#include "iwl-op-mode.h"
 
 /******************************************************************************
  *
@@ -134,7 +132,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
         * beacon contents.
         */
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (!priv->beacon_ctx) {
                IWL_ERR(priv, "trying to build beacon w/o beacon context!\n");
@@ -199,7 +197,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
        cmd.data[1] = priv->beacon_skb->data;
        cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY;
 
-       return iwl_trans_send_cmd(trans(priv), &cmd);
+       return iwl_dvm_send_cmd(priv, &cmd);
 }
 
 static void iwl_bg_beacon_update(struct work_struct *work)
@@ -208,7 +206,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
                container_of(work, struct iwl_priv, beacon_update);
        struct sk_buff *beacon;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        if (!priv->beacon_ctx) {
                IWL_ERR(priv, "updating beacon w/o beacon context!\n");
                goto out;
@@ -238,7 +236,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
 
        iwlagn_send_beacon_cmd(priv);
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 static void iwl_bg_bt_runtime_config(struct work_struct *work)
@@ -246,11 +244,11 @@ static void iwl_bg_bt_runtime_config(struct work_struct *work)
        struct iwl_priv *priv =
                container_of(work, struct iwl_priv, bt_runtime_config);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        /* dont send host command if rf-kill is on */
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return;
        iwlagn_send_advance_bt_config(priv);
 }
@@ -261,13 +259,13 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
                container_of(work, struct iwl_priv, bt_full_concurrency);
        struct iwl_rxon_context *ctx;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                goto out;
 
        /* dont send host command if rf-kill is on */
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                goto out;
 
        IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
@@ -285,7 +283,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
 
        iwlagn_send_advance_bt_config(priv);
 out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 /**
@@ -302,11 +300,11 @@ static void iwl_bg_statistics_periodic(unsigned long data)
 {
        struct iwl_priv *priv = (struct iwl_priv *)data;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        /* dont send host command if rf-kill is on */
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return;
 
        iwl_send_statistics_request(priv, CMD_ASYNC, false);
@@ -315,7 +313,7 @@ static void iwl_bg_statistics_periodic(unsigned long data)
 
 static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
                                        u32 start_idx, u32 num_events,
-                                       u32 mode)
+                                       u32 capacity, u32 mode)
 {
        u32 i;
        u32 ptr;        /* SRAM byte address of log data */
@@ -328,87 +326,125 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
                ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32));
 
        /* Make sure device is powered up for SRAM reads */
-       spin_lock_irqsave(&bus(priv)->reg_lock, reg_flags);
-       if (iwl_grab_nic_access(bus(priv))) {
-               spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags);
+       spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags);
+       if (unlikely(!iwl_grab_nic_access(trans(priv)))) {
+               spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags);
                return;
        }
 
        /* Set starting address; reads will auto-increment */
-       iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr);
-       rmb();
+       iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr);
+
+       /*
+        * Refuse to read more than would have fit into the log from
+        * the current start_idx. This used to happen due to the race
+        * described below, but now WARN because the code below should
+        * prevent it from happening here.
+        */
+       if (WARN_ON(num_events > capacity - start_idx))
+               num_events = capacity - start_idx;
 
        /*
         * "time" is actually "data" for mode 0 (no timestamp).
         * place event id # at far right for easier visual parsing.
         */
        for (i = 0; i < num_events; i++) {
-               ev = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
-               time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
+               ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
+               time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
                if (mode == 0) {
-                       trace_iwlwifi_dev_ucode_cont_event(priv,
-                                                       0, time, ev);
+                       trace_iwlwifi_dev_ucode_cont_event(
+                                       trans(priv)->dev, 0, time, ev);
                } else {
-                       data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
-                       trace_iwlwifi_dev_ucode_cont_event(priv,
-                                               time, data, ev);
+                       data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
+                       trace_iwlwifi_dev_ucode_cont_event(
+                                       trans(priv)->dev, time, data, ev);
                }
        }
        /* Allow device to power down */
-       iwl_release_nic_access(bus(priv));
-       spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags);
+       iwl_release_nic_access(trans(priv));
+       spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags);
 }
 
 static void iwl_continuous_event_trace(struct iwl_priv *priv)
 {
        u32 capacity;   /* event log capacity in # entries */
+       struct {
+               u32 capacity;
+               u32 mode;
+               u32 wrap_counter;
+               u32 write_counter;
+       } __packed read;
        u32 base;       /* SRAM byte address of event log header */
        u32 mode;       /* 0 - no timestamp, 1 - timestamp recorded */
        u32 num_wraps;  /* # times uCode wrapped to top of log */
        u32 next_entry; /* index of next entry to be written by uCode */
 
-       base = priv->shrd->device_pointers.error_event_table;
+       base = priv->shrd->device_pointers.log_event_table;
        if (iwlagn_hw_valid_rtc_data_addr(base)) {
-               capacity = iwl_read_targ_mem(bus(priv), base);
-               num_wraps = iwl_read_targ_mem(bus(priv),
-                                               base + (2 * sizeof(u32)));
-               mode = iwl_read_targ_mem(bus(priv), base + (1 * sizeof(u32)));
-               next_entry = iwl_read_targ_mem(bus(priv),
-                                               base + (3 * sizeof(u32)));
+               iwl_read_targ_mem_words(trans(priv), base, &read, sizeof(read));
+
+               capacity = read.capacity;
+               mode = read.mode;
+               num_wraps = read.wrap_counter;
+               next_entry = read.write_counter;
        } else
                return;
 
+       /*
+        * Unfortunately, the uCode doesn't use temporary variables.
+        * Therefore, it can happen that we read next_entry == capacity,
+        * which really means next_entry == 0.
+        */
+       if (unlikely(next_entry == capacity))
+               next_entry = 0;
+       /*
+        * Additionally, the uCode increases the write pointer before
+        * the wraps counter, so if the write pointer is smaller than
+        * the old write pointer (wrap occurred) but we read that no
+        * wrap occurred, we actually read between the next_entry and
+        * num_wraps update (this does happen in practice!!) -- take
+        * that into account by increasing num_wraps.
+        */
+       if (unlikely(next_entry < priv->event_log.next_entry &&
+                    num_wraps == priv->event_log.num_wraps))
+               num_wraps++;
+
        if (num_wraps == priv->event_log.num_wraps) {
-               iwl_print_cont_event_trace(priv,
-                                      base, priv->event_log.next_entry,
-                                      next_entry - priv->event_log.next_entry,
-                                      mode);
+               iwl_print_cont_event_trace(
+                       priv, base, priv->event_log.next_entry,
+                       next_entry - priv->event_log.next_entry,
+                       capacity, mode);
+
                priv->event_log.non_wraps_count++;
        } else {
-               if ((num_wraps - priv->event_log.num_wraps) > 1)
+               if (num_wraps - priv->event_log.num_wraps > 1)
                        priv->event_log.wraps_more_count++;
                else
                        priv->event_log.wraps_once_count++;
-               trace_iwlwifi_dev_ucode_wrap_event(priv,
+
+               trace_iwlwifi_dev_ucode_wrap_event(trans(priv)->dev,
                                num_wraps - priv->event_log.num_wraps,
                                next_entry, priv->event_log.next_entry);
+
                if (next_entry < priv->event_log.next_entry) {
-                       iwl_print_cont_event_trace(priv, base,
-                              priv->event_log.next_entry,
-                              capacity - priv->event_log.next_entry,
-                              mode);
+                       iwl_print_cont_event_trace(
+                               priv, base, priv->event_log.next_entry,
+                               capacity - priv->event_log.next_entry,
+                               capacity, mode);
 
-                       iwl_print_cont_event_trace(priv, base, 0,
-                               next_entry, mode);
+                       iwl_print_cont_event_trace(
+                               priv, base, 0, next_entry, capacity, mode);
                } else {
-                       iwl_print_cont_event_trace(priv, base,
-                              next_entry, capacity - next_entry,
-                              mode);
+                       iwl_print_cont_event_trace(
+                               priv, base, next_entry,
+                               capacity - next_entry,
+                               capacity, mode);
 
-                       iwl_print_cont_event_trace(priv, base, 0,
-                               next_entry, mode);
+                       iwl_print_cont_event_trace(
+                               priv, base, 0, next_entry, capacity, mode);
                }
        }
+
        priv->event_log.num_wraps = num_wraps;
        priv->event_log.next_entry = next_entry;
 }
@@ -425,7 +461,7 @@ static void iwl_bg_ucode_trace(unsigned long data)
 {
        struct iwl_priv *priv = (struct iwl_priv *)data;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        if (priv->event_log.ucode_trace) {
@@ -441,11 +477,11 @@ static void iwl_bg_tx_flush(struct work_struct *work)
        struct iwl_priv *priv =
                container_of(work, struct iwl_priv, tx_flush);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        /* do nothing if rf-kill is on */
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return;
 
        IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
@@ -475,6 +511,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
        priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
        priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
        priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
+       priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
        priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
                BIT(NL80211_IFTYPE_ADHOC);
        priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
@@ -509,620 +546,15 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
        BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
 }
 
-static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
-
-#define UCODE_EXPERIMENTAL_INDEX       100
-#define UCODE_EXPERIMENTAL_TAG         "exp"
-
-static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
-{
-       const char *name_pre = cfg(priv)->fw_name_pre;
-       char tag[8];
-
-       if (first) {
-#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
-               priv->fw_index = UCODE_EXPERIMENTAL_INDEX;
-               strcpy(tag, UCODE_EXPERIMENTAL_TAG);
-       } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) {
-#endif
-               priv->fw_index = cfg(priv)->ucode_api_max;
-               sprintf(tag, "%d", priv->fw_index);
-       } else {
-               priv->fw_index--;
-               sprintf(tag, "%d", priv->fw_index);
-       }
-
-       if (priv->fw_index < cfg(priv)->ucode_api_min) {
-               IWL_ERR(priv, "no suitable firmware found!\n");
-               return -ENOENT;
-       }
-
-       sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
-
-       IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n",
-                      (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
-                               ? "EXPERIMENTAL " : "",
-                      priv->firmware_name);
-
-       return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
-                                      bus(priv)->dev,
-                                      GFP_KERNEL, priv, iwl_ucode_callback);
-}
-
-struct iwlagn_firmware_pieces {
-       const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data;
-       size_t inst_size, data_size, init_size, init_data_size,
-              wowlan_inst_size, wowlan_data_size;
-
-       u32 build;
-
-       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
-       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
-};
-
-static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
-                                      const struct firmware *ucode_raw,
-                                      struct iwlagn_firmware_pieces *pieces)
-{
-       struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
-       u32 api_ver, hdr_size;
-       const u8 *src;
-
-       priv->ucode_ver = le32_to_cpu(ucode->ver);
-       api_ver = IWL_UCODE_API(priv->ucode_ver);
-
-       switch (api_ver) {
-       default:
-               hdr_size = 28;
-               if (ucode_raw->size < hdr_size) {
-                       IWL_ERR(priv, "File size too small!\n");
-                       return -EINVAL;
-               }
-               pieces->build = le32_to_cpu(ucode->u.v2.build);
-               pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
-               pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
-               pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
-               pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
-               src = ucode->u.v2.data;
-               break;
-       case 0:
-       case 1:
-       case 2:
-               hdr_size = 24;
-               if (ucode_raw->size < hdr_size) {
-                       IWL_ERR(priv, "File size too small!\n");
-                       return -EINVAL;
-               }
-               pieces->build = 0;
-               pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size);
-               pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
-               pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
-               pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
-               src = ucode->u.v1.data;
-               break;
-       }
-
-       /* Verify size of file vs. image size info in file's header */
-       if (ucode_raw->size != hdr_size + pieces->inst_size +
-                               pieces->data_size + pieces->init_size +
-                               pieces->init_data_size) {
-
-               IWL_ERR(priv,
-                       "uCode file size %d does not match expected size\n",
-                       (int)ucode_raw->size);
-               return -EINVAL;
-       }
-
-       pieces->inst = src;
-       src += pieces->inst_size;
-       pieces->data = src;
-       src += pieces->data_size;
-       pieces->init = src;
-       src += pieces->init_size;
-       pieces->init_data = src;
-       src += pieces->init_data_size;
-
-       return 0;
-}
-
-static int iwlagn_load_firmware(struct iwl_priv *priv,
-                               const struct firmware *ucode_raw,
-                               struct iwlagn_firmware_pieces *pieces,
-                               struct iwlagn_ucode_capabilities *capa)
-{
-       struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
-       struct iwl_ucode_tlv *tlv;
-       size_t len = ucode_raw->size;
-       const u8 *data;
-       int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative;
-       int tmp;
-       u64 alternatives;
-       u32 tlv_len;
-       enum iwl_ucode_tlv_type tlv_type;
-       const u8 *tlv_data;
-
-       if (len < sizeof(*ucode)) {
-               IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
-               return -EINVAL;
-       }
-
-       if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
-               IWL_ERR(priv, "invalid uCode magic: 0X%x\n",
-                       le32_to_cpu(ucode->magic));
-               return -EINVAL;
-       }
-
-       /*
-        * Check which alternatives are present, and "downgrade"
-        * when the chosen alternative is not present, warning
-        * the user when that happens. Some files may not have
-        * any alternatives, so don't warn in that case.
-        */
-       alternatives = le64_to_cpu(ucode->alternatives);
-       tmp = wanted_alternative;
-       if (wanted_alternative > 63)
-               wanted_alternative = 63;
-       while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
-               wanted_alternative--;
-       if (wanted_alternative && wanted_alternative != tmp)
-               IWL_WARN(priv,
-                        "uCode alternative %d not available, choosing %d\n",
-                        tmp, wanted_alternative);
-
-       priv->ucode_ver = le32_to_cpu(ucode->ver);
-       pieces->build = le32_to_cpu(ucode->build);
-       data = ucode->data;
-
-       len -= sizeof(*ucode);
-
-       while (len >= sizeof(*tlv)) {
-               u16 tlv_alt;
-
-               len -= sizeof(*tlv);
-               tlv = (void *)data;
-
-               tlv_len = le32_to_cpu(tlv->length);
-               tlv_type = le16_to_cpu(tlv->type);
-               tlv_alt = le16_to_cpu(tlv->alternative);
-               tlv_data = tlv->data;
-
-               if (len < tlv_len) {
-                       IWL_ERR(priv, "invalid TLV len: %zd/%u\n",
-                               len, tlv_len);
-                       return -EINVAL;
-               }
-               len -= ALIGN(tlv_len, 4);
-               data += sizeof(*tlv) + ALIGN(tlv_len, 4);
-
-               /*
-                * Alternative 0 is always valid.
-                *
-                * Skip alternative TLVs that are not selected.
-                */
-               if (tlv_alt != 0 && tlv_alt != wanted_alternative)
-                       continue;
-
-               switch (tlv_type) {
-               case IWL_UCODE_TLV_INST:
-                       pieces->inst = tlv_data;
-                       pieces->inst_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_DATA:
-                       pieces->data = tlv_data;
-                       pieces->data_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_INIT:
-                       pieces->init = tlv_data;
-                       pieces->init_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_INIT_DATA:
-                       pieces->init_data = tlv_data;
-                       pieces->init_data_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_BOOT:
-                       IWL_ERR(priv, "Found unexpected BOOT ucode\n");
-                       break;
-               case IWL_UCODE_TLV_PROBE_MAX_LEN:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       capa->max_probe_length =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_PAN:
-                       if (tlv_len)
-                               goto invalid_tlv_len;
-                       capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
-                       break;
-               case IWL_UCODE_TLV_FLAGS:
-                       /* must be at least one u32 */
-                       if (tlv_len < sizeof(u32))
-                               goto invalid_tlv_len;
-                       /* and a proper number of u32s */
-                       if (tlv_len % sizeof(u32))
-                               goto invalid_tlv_len;
-                       /*
-                        * This driver only reads the first u32 as
-                        * right now no more features are defined,
-                        * if that changes then either the driver
-                        * will not work with the new firmware, or
-                        * it'll not take advantage of new features.
-                        */
-                       capa->flags = le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->init_evtlog_ptr =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->init_evtlog_size =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->init_errlog_ptr =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->inst_evtlog_ptr =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->inst_evtlog_size =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->inst_errlog_ptr =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
-                       if (tlv_len)
-                               goto invalid_tlv_len;
-                       priv->enhance_sensitivity_table = true;
-                       break;
-               case IWL_UCODE_TLV_WOWLAN_INST:
-                       pieces->wowlan_inst = tlv_data;
-                       pieces->wowlan_inst_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_WOWLAN_DATA:
-                       pieces->wowlan_data = tlv_data;
-                       pieces->wowlan_data_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       capa->standard_phy_calibration_size =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               default:
-                       IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type);
-                       break;
-               }
-       }
-
-       if (len) {
-               IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
-               iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
-               return -EINVAL;
-       }
-
-       return 0;
-
- invalid_tlv_len:
-       IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
-       iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len);
-
-       return -EINVAL;
-}
-
-/**
- * iwl_ucode_callback - callback when firmware was loaded
- *
- * If loaded successfully, copies the firmware into buffers
- * for the card to fetch (via DMA).
- */
-static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
-{
-       struct iwl_priv *priv = context;
-       struct iwl_ucode_header *ucode;
-       int err;
-       struct iwlagn_firmware_pieces pieces;
-       const unsigned int api_max = cfg(priv)->ucode_api_max;
-       unsigned int api_ok = cfg(priv)->ucode_api_ok;
-       const unsigned int api_min = cfg(priv)->ucode_api_min;
-       u32 api_ver;
-       char buildstr[25];
-       u32 build;
-       struct iwlagn_ucode_capabilities ucode_capa = {
-               .max_probe_length = 200,
-               .standard_phy_calibration_size =
-                       IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
-       };
-
-       if (!api_ok)
-               api_ok = api_max;
-
-       memset(&pieces, 0, sizeof(pieces));
-
-       if (!ucode_raw) {
-               if (priv->fw_index <= api_ok)
-                       IWL_ERR(priv,
-                               "request for firmware file '%s' failed.\n",
-                               priv->firmware_name);
-               goto try_again;
-       }
-
-       IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
-                      priv->firmware_name, ucode_raw->size);
-
-       /* Make sure that we got at least the API version number */
-       if (ucode_raw->size < 4) {
-               IWL_ERR(priv, "File size way too small!\n");
-               goto try_again;
-       }
-
-       /* Data from ucode file:  header followed by uCode images */
-       ucode = (struct iwl_ucode_header *)ucode_raw->data;
-
-       if (ucode->ver)
-               err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces);
-       else
-               err = iwlagn_load_firmware(priv, ucode_raw, &pieces,
-                                          &ucode_capa);
-
-       if (err)
-               goto try_again;
-
-       api_ver = IWL_UCODE_API(priv->ucode_ver);
-       build = pieces.build;
-
-       /*
-        * api_ver should match the api version forming part of the
-        * firmware filename ... but we don't check for that and only rely
-        * on the API version read from firmware header from here on forward
-        */
-       /* no api version check required for experimental uCode */
-       if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
-               if (api_ver < api_min || api_ver > api_max) {
-                       IWL_ERR(priv,
-                               "Driver unable to support your firmware API. "
-                               "Driver supports v%u, firmware is v%u.\n",
-                               api_max, api_ver);
-                       goto try_again;
-               }
-
-               if (api_ver < api_ok) {
-                       if (api_ok != api_max)
-                               IWL_ERR(priv, "Firmware has old API version, "
-                                       "expected v%u through v%u, got v%u.\n",
-                                       api_ok, api_max, api_ver);
-                       else
-                               IWL_ERR(priv, "Firmware has old API version, "
-                                       "expected v%u, got v%u.\n",
-                                       api_max, api_ver);
-                       IWL_ERR(priv, "New firmware can be obtained from "
-                                     "http://www.intellinuxwireless.org/.\n");
-               }
-       }
-
-       if (build)
-               sprintf(buildstr, " build %u%s", build,
-                      (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
-                               ? " (EXP)" : "");
-       else
-               buildstr[0] = '\0';
-
-       IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n",
-                IWL_UCODE_MAJOR(priv->ucode_ver),
-                IWL_UCODE_MINOR(priv->ucode_ver),
-                IWL_UCODE_API(priv->ucode_ver),
-                IWL_UCODE_SERIAL(priv->ucode_ver),
-                buildstr);
-
-       snprintf(priv->hw->wiphy->fw_version,
-                sizeof(priv->hw->wiphy->fw_version),
-                "%u.%u.%u.%u%s",
-                IWL_UCODE_MAJOR(priv->ucode_ver),
-                IWL_UCODE_MINOR(priv->ucode_ver),
-                IWL_UCODE_API(priv->ucode_ver),
-                IWL_UCODE_SERIAL(priv->ucode_ver),
-                buildstr);
-
-       /*
-        * For any of the failures below (before allocating pci memory)
-        * we will try to load a version with a smaller API -- maybe the
-        * user just got a corrupted version of the latest API.
-        */
-
-       IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
-                      priv->ucode_ver);
-       IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n",
-                      pieces.inst_size);
-       IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n",
-                      pieces.data_size);
-       IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n",
-                      pieces.init_size);
-       IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
-                      pieces.init_data_size);
-
-       /* Verify that uCode images will fit in card's SRAM */
-       if (pieces.inst_size > hw_params(priv).max_inst_size) {
-               IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n",
-                       pieces.inst_size);
-               goto try_again;
-       }
-
-       if (pieces.data_size > hw_params(priv).max_data_size) {
-               IWL_ERR(priv, "uCode data len %Zd too large to fit in\n",
-                       pieces.data_size);
-               goto try_again;
-       }
-
-       if (pieces.init_size > hw_params(priv).max_inst_size) {
-               IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n",
-                       pieces.init_size);
-               goto try_again;
-       }
-
-       if (pieces.init_data_size > hw_params(priv).max_data_size) {
-               IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n",
-                       pieces.init_data_size);
-               goto try_again;
-       }
-
-       /* Allocate ucode buffers for card's bus-master loading ... */
-
-       /* Runtime instructions and 2 copies of data:
-        * 1) unmodified from disk
-        * 2) backup cache for save/restore during power-downs */
-       if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.code,
-                             pieces.inst, pieces.inst_size))
-               goto err_pci_alloc;
-       if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.data,
-                             pieces.data, pieces.data_size))
-               goto err_pci_alloc;
-
-       /* Initialization instructions and data */
-       if (pieces.init_size && pieces.init_data_size) {
-               if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.code,
-                                     pieces.init, pieces.init_size))
-                       goto err_pci_alloc;
-               if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.data,
-                                     pieces.init_data, pieces.init_data_size))
-                       goto err_pci_alloc;
-       }
-
-       /* WoWLAN instructions and data */
-       if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
-               if (iwl_alloc_fw_desc(bus(priv),
-                                     &trans(priv)->ucode_wowlan.code,
-                                     pieces.wowlan_inst,
-                                     pieces.wowlan_inst_size))
-                       goto err_pci_alloc;
-               if (iwl_alloc_fw_desc(bus(priv),
-                                     &trans(priv)->ucode_wowlan.data,
-                                     pieces.wowlan_data,
-                                     pieces.wowlan_data_size))
-                       goto err_pci_alloc;
-       }
-
-       /* Now that we can no longer fail, copy information */
-
-       /*
-        * The (size - 16) / 12 formula is based on the information recorded
-        * for each event, which is of mode 1 (including timestamp) for all
-        * new microcodes that include this information.
-        */
-       priv->init_evtlog_ptr = pieces.init_evtlog_ptr;
-       if (pieces.init_evtlog_size)
-               priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
-       else
-               priv->init_evtlog_size =
-                       cfg(priv)->base_params->max_event_log_size;
-       priv->init_errlog_ptr = pieces.init_errlog_ptr;
-       priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
-       if (pieces.inst_evtlog_size)
-               priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
-       else
-               priv->inst_evtlog_size =
-                       cfg(priv)->base_params->max_event_log_size;
-       priv->inst_errlog_ptr = pieces.inst_errlog_ptr;
-#ifndef CONFIG_IWLWIFI_P2P
-       ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
-#endif
-
-       priv->new_scan_threshold_behaviour =
-               !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
-
-       if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE))
-               ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
-
-       /*
-        * if not PAN, then don't support P2P -- might be a uCode
-        * packaging bug or due to the eeprom check above
-        */
-       if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN))
-               ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
-
-       if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
-               priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
-               priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
-       } else {
-               priv->sta_key_max_num = STA_KEY_MAX_NUM;
-               priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
-       }
-       /*
-        * figure out the offset of chain noise reset and gain commands
-        * base on the size of standard phy calibration commands table size
-        */
-       if (ucode_capa.standard_phy_calibration_size >
-           IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
-               ucode_capa.standard_phy_calibration_size =
-                       IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
-
-       priv->phy_calib_chain_noise_reset_cmd =
-               ucode_capa.standard_phy_calibration_size;
-       priv->phy_calib_chain_noise_gain_cmd =
-               ucode_capa.standard_phy_calibration_size + 1;
-
-       /* initialize all valid contexts */
-       iwl_init_context(priv, ucode_capa.flags);
-
-       /**************************************************
-        * This is still part of probe() in a sense...
-        *
-        * 9. Setup and register with mac80211 and debugfs
-        **************************************************/
-       err = iwlagn_mac_setup_register(priv, &ucode_capa);
-       if (err)
-               goto out_unbind;
-
-       err = iwl_dbgfs_register(priv, DRV_NAME);
-       if (err)
-               IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
-
-       /* We have our copies now, allow OS release its copies */
-       release_firmware(ucode_raw);
-       complete(&priv->firmware_loading_complete);
-       return;
-
- try_again:
-       /* try next, if any */
-       if (iwl_request_firmware(priv, false))
-               goto out_unbind;
-       release_firmware(ucode_raw);
-       return;
-
- err_pci_alloc:
-       IWL_ERR(priv, "failed to allocate pci memory\n");
-       iwl_dealloc_ucode(trans(priv));
- out_unbind:
-       complete(&priv->firmware_loading_complete);
-       device_release_driver(bus(priv)->dev);
-       release_firmware(ucode_raw);
-}
-
 static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
 {
        struct iwl_ct_kill_config cmd;
        struct iwl_ct_kill_throttling_config adv_cmd;
-       unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
-       iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR,
+       iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
+
        priv->thermal_throttle.ct_kill_toggle = false;
 
        if (cfg(priv)->base_params->support_ct_kill_exit) {
@@ -1131,7 +563,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
                adv_cmd.critical_temperature_exit =
                        cpu_to_le32(hw_params(priv).ct_kill_exit_threshold);
 
-               ret = iwl_trans_send_cmd_pdu(trans(priv),
+               ret = iwl_dvm_send_cmd_pdu(priv,
                                       REPLY_CT_KILL_CONFIG_CMD,
                                       CMD_SYNC, sizeof(adv_cmd), &adv_cmd);
                if (ret)
@@ -1146,7 +578,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
                cmd.critical_temperature_R =
                        cpu_to_le32(hw_params(priv).ct_kill_threshold);
 
-               ret = iwl_trans_send_cmd_pdu(trans(priv),
+               ret = iwl_dvm_send_cmd_pdu(priv,
                                       REPLY_CT_KILL_CONFIG_CMD,
                                       CMD_SYNC, sizeof(cmd), &cmd);
                if (ret)
@@ -1172,7 +604,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
        calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL;
        calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
 
-       return iwl_trans_send_cmd(trans(priv), &cmd);
+       return iwl_dvm_send_cmd(priv, &cmd);
 }
 
 
@@ -1182,9 +614,9 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
          .valid = cpu_to_le32(valid_tx_ant),
        };
 
-       if (IWL_UCODE_API(priv->ucode_ver) > 1) {
+       if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) {
                IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
-               return iwl_trans_send_cmd_pdu(trans(priv),
+               return iwl_dvm_send_cmd_pdu(priv,
                                        TX_ANT_CONFIGURATION_CMD,
                                        CMD_SYNC,
                                        sizeof(struct iwl_tx_ant_config_cmd),
@@ -1205,20 +637,22 @@ int iwl_alive_start(struct iwl_priv *priv)
        int ret = 0;
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 
-       /*TODO: this should go to the transport layer */
-       iwl_reset_ict(trans(priv));
-
        IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
 
        /* After the ALIVE response, we can send host commands to the uCode */
-       set_bit(STATUS_ALIVE, &priv->shrd->status);
+       set_bit(STATUS_ALIVE, &priv->status);
 
        /* Enable watchdog to monitor the driver tx queues */
        iwl_setup_watchdog(priv);
 
-       if (iwl_is_rfkill(priv->shrd))
+       if (iwl_is_rfkill(priv))
                return -ERFKILL;
 
+       if (priv->event_log.ucode_trace) {
+               /* start collecting data now */
+               mod_timer(&priv->ucode_trace, jiffies);
+       }
+
        /* download priority table before any calibration request */
        if (cfg(priv)->bt_params &&
            cfg(priv)->bt_params->advanced_bt_coexist) {
@@ -1235,14 +669,14 @@ int iwl_alive_start(struct iwl_priv *priv)
                priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
                priv->cur_rssi_ctx = NULL;
 
-               iwl_send_prio_tbl(trans(priv));
+               iwl_send_prio_tbl(priv);
 
                /* FIXME: w/a to force change uCode BT state machine */
-               ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_OPEN,
+               ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
                                         BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
                if (ret)
                        return ret;
-               ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_CLOSE,
+               ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
                                         BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
                if (ret)
                        return ret;
@@ -1263,9 +697,9 @@ int iwl_alive_start(struct iwl_priv *priv)
        priv->active_rate = IWL_RATES_MASK;
 
        /* Configure Tx antenna selection based on H/W config */
-       iwlagn_send_tx_ant_config(priv, cfg(priv)->valid_tx_ant);
+       iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant);
 
-       if (iwl_is_associated_ctx(ctx) && !priv->shrd->wowlan) {
+       if (iwl_is_associated_ctx(ctx) && !priv->wowlan) {
                struct iwl_rxon_cmd *active_rxon =
                                (struct iwl_rxon_cmd *)&ctx->active;
                /* apply any changes in staging */
@@ -1280,12 +714,12 @@ int iwl_alive_start(struct iwl_priv *priv)
                iwlagn_set_rxon_chain(priv, ctx);
        }
 
-       if (!priv->shrd->wowlan) {
+       if (!priv->wowlan) {
                /* WoWLAN ucode will not reply in the same way, skip it */
                iwl_reset_run_time_calib(priv);
        }
 
-       set_bit(STATUS_READY, &priv->shrd->status);
+       set_bit(STATUS_READY, &priv->status);
 
        /* Configure the adapter for unassociated operation */
        ret = iwlagn_commit_rxon(priv, ctx);
@@ -1300,14 +734,48 @@ int iwl_alive_start(struct iwl_priv *priv)
        return iwl_power_update_mode(priv, true);
 }
 
-static void iwl_cancel_deferred_work(struct iwl_priv *priv);
+/**
+ * iwl_clear_driver_stations - clear knowledge of all stations from driver
+ * @priv: iwl priv struct
+ *
+ * This is called during iwl_down() to make sure that in the case
+ * we're coming there from a hardware restart mac80211 will be
+ * able to reconfigure stations -- if we're getting there in the
+ * normal down flow then the stations will already be cleared.
+ */
+static void iwl_clear_driver_stations(struct iwl_priv *priv)
+{
+       struct iwl_rxon_context *ctx;
+
+       spin_lock_bh(&priv->sta_lock);
+       memset(priv->stations, 0, sizeof(priv->stations));
+       priv->num_stations = 0;
+
+       priv->ucode_key_table = 0;
+
+       for_each_context(priv, ctx) {
+               /*
+                * Remove all key information that is not stored as part
+                * of station information since mac80211 may not have had
+                * a chance to remove all the keys. When device is
+                * reconfigured by mac80211 after an error all keys will
+                * be reconfigured.
+                */
+               memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
+               ctx->key_mapping_keys = 0;
+       }
+
+       spin_unlock_bh(&priv->sta_lock);
+}
 
-void __iwl_down(struct iwl_priv *priv)
+void iwl_down(struct iwl_priv *priv)
 {
        int exit_pending;
 
        IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
 
+       lockdep_assert_held(&priv->mutex);
+
        iwl_scan_cancel_timeout(priv, 200);
 
        /*
@@ -1318,7 +786,7 @@ void __iwl_down(struct iwl_priv *priv)
        ieee80211_remain_on_channel_expired(priv->hw);
 
        exit_pending =
-               test_and_set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
+               test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
 
        /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
         * to prevent rearm timer */
@@ -1343,7 +811,7 @@ void __iwl_down(struct iwl_priv *priv)
        /* Wipe out the EXIT_PENDING status bit if we are not actually
         * exiting the module */
        if (!exit_pending)
-               clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
+               clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
        if (priv->mac80211_registered)
                ieee80211_stop_queues(priv->hw);
@@ -1351,29 +819,20 @@ void __iwl_down(struct iwl_priv *priv)
        iwl_trans_stop_device(trans(priv));
 
        /* Clear out all status bits but a few that are stable across reset */
-       priv->shrd->status &=
-                       test_bit(STATUS_RF_KILL_HW, &priv->shrd->status) <<
+       priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
                                STATUS_RF_KILL_HW |
-                       test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) <<
+                       test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
                                STATUS_GEO_CONFIGURED |
-                       test_bit(STATUS_FW_ERROR, &priv->shrd->status) <<
-                               STATUS_FW_ERROR |
-                       test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) <<
+                       test_bit(STATUS_EXIT_PENDING, &priv->status) <<
                                STATUS_EXIT_PENDING;
+       priv->shrd->status &=
+                       test_bit(STATUS_FW_ERROR, &priv->shrd->status) <<
+                               STATUS_FW_ERROR;
 
        dev_kfree_skb(priv->beacon_skb);
        priv->beacon_skb = NULL;
 }
 
-void iwl_down(struct iwl_priv *priv)
-{
-       mutex_lock(&priv->shrd->mutex);
-       __iwl_down(priv);
-       mutex_unlock(&priv->shrd->mutex);
-
-       iwl_cancel_deferred_work(priv);
-}
-
 /*****************************************************************************
  *
  * Workqueue callbacks
@@ -1385,11 +844,11 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
        struct iwl_priv *priv = container_of(work, struct iwl_priv,
                        run_time_calib_work);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) ||
-           test_bit(STATUS_SCANNING, &priv->shrd->status)) {
-               mutex_unlock(&priv->shrd->mutex);
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
+           test_bit(STATUS_SCANNING, &priv->status)) {
+               mutex_unlock(&priv->mutex);
                return;
        }
 
@@ -1398,7 +857,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
                iwl_sensitivity_calibration(priv);
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 void iwlagn_prepare_restart(struct iwl_priv *priv)
@@ -1410,7 +869,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)
        u8 bt_status;
        bool bt_is_sco;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        for_each_context(priv, ctx)
                ctx->vif = NULL;
@@ -1431,7 +890,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)
        bt_status = priv->bt_status;
        bt_is_sco = priv->bt_is_sco;
 
-       __iwl_down(priv);
+       iwl_down(priv);
 
        priv->bt_full_concurrent = bt_full_concurrent;
        priv->bt_ci_compliance = bt_ci_compliance;
@@ -1444,13 +903,13 @@ static void iwl_bg_restart(struct work_struct *data)
 {
        struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) {
-               mutex_lock(&priv->shrd->mutex);
+               mutex_lock(&priv->mutex);
                iwlagn_prepare_restart(priv);
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
                iwl_cancel_deferred_work(priv);
                ieee80211_restart_hw(priv->hw);
        } else {
@@ -1465,7 +924,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv)
 {
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (!priv->hw_roc_setup)
                return;
@@ -1488,9 +947,9 @@ static void iwlagn_disable_roc_work(struct work_struct *work)
        struct iwl_priv *priv = container_of(work, struct iwl_priv,
                                             hw_roc_disable_work.work);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwlagn_disable_roc(priv);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 /*****************************************************************************
@@ -1501,7 +960,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work)
 
 static void iwl_setup_deferred_work(struct iwl_priv *priv)
 {
-       priv->shrd->workqueue = create_singlethread_workqueue(DRV_NAME);
+       priv->workqueue = create_singlethread_workqueue(DRV_NAME);
 
        init_waitqueue_head(&priv->shrd->wait_command_queue);
 
@@ -1516,8 +975,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
 
        iwl_setup_scan_deferred_work(priv);
 
-       if (cfg(priv)->lib->bt_setup_deferred_work)
-               cfg(priv)->lib->bt_setup_deferred_work(priv);
+       if (cfg(priv)->bt_params)
+               iwlagn_bt_setup_deferred_work(priv);
 
        init_timer(&priv->statistics_periodic);
        priv->statistics_periodic.data = (unsigned long)priv;
@@ -1532,10 +991,10 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
        priv->watchdog.function = iwl_bg_watchdog;
 }
 
-static void iwl_cancel_deferred_work(struct iwl_priv *priv)
+void iwl_cancel_deferred_work(struct iwl_priv *priv)
 {
-       if (cfg(priv)->lib->cancel_deferred_work)
-               cfg(priv)->lib->cancel_deferred_work(priv);
+       if (cfg(priv)->bt_params)
+               iwlagn_bt_cancel_deferred_work(priv);
 
        cancel_work_sync(&priv->run_time_calib_work);
        cancel_work_sync(&priv->beacon_update);
@@ -1550,8 +1009,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
        del_timer_sync(&priv->ucode_trace);
 }
 
-static void iwl_init_hw_rates(struct iwl_priv *priv,
-                             struct ieee80211_rate *rates)
+static void iwl_init_hw_rates(struct ieee80211_rate *rates)
 {
        int i;
 
@@ -1575,21 +1033,26 @@ static int iwl_init_drv(struct iwl_priv *priv)
 {
        int ret;
 
-       spin_lock_init(&priv->shrd->sta_lock);
+       spin_lock_init(&priv->sta_lock);
 
-       mutex_init(&priv->shrd->mutex);
+       mutex_init(&priv->mutex);
 
-       INIT_LIST_HEAD(&trans(priv)->calib_results);
+       INIT_LIST_HEAD(&priv->calib_results);
 
        priv->ieee_channels = NULL;
        priv->ieee_rates = NULL;
        priv->band = IEEE80211_BAND_2GHZ;
 
+       priv->plcp_delta_threshold =
+               cfg(priv)->base_params->plcp_delta_threshold;
+
        priv->iw_mode = NL80211_IFTYPE_STATION;
        priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
        priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
        priv->agg_tids_count = 0;
 
+       priv->ucode_owner = IWL_OWNERSHIP_DRIVER;
+
        /* initialize force reset */
        priv->force_reset[IWL_RF_RESET].reset_duration =
                IWL_DELAY_NEXT_FORCE_RF_RESET;
@@ -1625,7 +1088,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
                IWL_ERR(priv, "initializing geos failed: %d\n", ret);
                goto err_free_channel_map;
        }
-       iwl_init_hw_rates(priv, priv->ieee_rates);
+       iwl_init_hw_rates(priv->ieee_rates);
 
        return 0;
 
@@ -1639,29 +1102,25 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
 {
        iwl_free_geos(priv);
        iwl_free_channel_map(priv);
-       if (priv->tx_cmd_pool)
-               kmem_cache_destroy(priv->tx_cmd_pool);
        kfree(priv->scan_cmd);
        kfree(priv->beacon_cmd);
        kfree(rcu_dereference_raw(priv->noa_data));
+       iwl_calib_free_results(priv);
 #ifdef CONFIG_IWLWIFI_DEBUGFS
        kfree(priv->wowlan_sram);
 #endif
 }
 
-
-
-static u32 iwl_hw_detect(struct iwl_priv *priv)
-{
-       return iwl_read32(bus(priv), CSR_HW_REV);
-}
-
 /* Size of one Rx buffer in host DRAM */
 #define IWL_RX_BUF_SIZE_4K (4 * 1024)
 #define IWL_RX_BUF_SIZE_8K (8 * 1024)
 
-static int iwl_set_hw_params(struct iwl_priv *priv)
+static void iwl_set_hw_params(struct iwl_priv *priv)
 {
+       if (cfg(priv)->ht_params)
+               hw_params(priv).use_rts_for_aggregation =
+                       cfg(priv)->ht_params->use_rts_for_aggregation;
+
        if (iwlagn_mod_params.amsdu_size_8K)
                hw_params(priv).rx_page_order =
                        get_order(IWL_RX_BUF_SIZE_8K);
@@ -1670,49 +1129,46 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
                        get_order(IWL_RX_BUF_SIZE_4K);
 
        if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
-               cfg(priv)->sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
+               hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
 
        hw_params(priv).num_ampdu_queues =
                cfg(priv)->base_params->num_of_ampdu_queues;
-       hw_params(priv).shadow_reg_enable =
-               cfg(priv)->base_params->shadow_reg_enable;
-       hw_params(priv).sku = cfg(priv)->sku;
        hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout;
 
        /* Device-specific setup */
-       return cfg(priv)->lib->set_hw_params(priv);
+       cfg(priv)->lib->set_hw_params(priv);
 }
 
 
 
 static void iwl_debug_config(struct iwl_priv *priv)
 {
-       dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUG "
+       dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG "
 #ifdef CONFIG_IWLWIFI_DEBUG
                "enabled\n");
 #else
                "disabled\n");
 #endif
-       dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS "
+       dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS "
 #ifdef CONFIG_IWLWIFI_DEBUGFS
                "enabled\n");
 #else
                "disabled\n");
 #endif
-       dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING "
+       dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING "
 #ifdef CONFIG_IWLWIFI_DEVICE_TRACING
                "enabled\n");
 #else
                "disabled\n");
 #endif
 
-       dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE "
+       dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE "
 #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
                "enabled\n");
 #else
                "disabled\n");
 #endif
-       dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_P2P "
+       dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_P2P "
 #ifdef CONFIG_IWLWIFI_P2P
                "enabled\n");
 #else
@@ -1720,46 +1176,77 @@ static void iwl_debug_config(struct iwl_priv *priv)
 #endif
 }
 
-int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
-               struct iwl_cfg *cfg)
+static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
+                                                const struct iwl_fw *fw)
 {
        int err = 0;
        struct iwl_priv *priv;
        struct ieee80211_hw *hw;
+       struct iwl_op_mode *op_mode;
        u16 num_mac;
-       u32 hw_rev;
+       u32 ucode_flags;
+       struct iwl_trans_config trans_cfg;
 
        /************************
         * 1. Allocating HW data
         ************************/
        hw = iwl_alloc_all();
        if (!hw) {
-               pr_err("%s: Cannot allocate network device\n", cfg->name);
+               pr_err("%s: Cannot allocate network device\n",
+                               cfg(trans)->name);
                err = -ENOMEM;
                goto out;
        }
 
-       priv = hw->priv;
-       priv->shrd = &priv->_shrd;
-       bus->shrd = priv->shrd;
-       priv->shrd->bus = bus;
-       priv->shrd->priv = priv;
+       op_mode = hw->priv;
+       op_mode->ops = &iwl_dvm_ops;
+       priv = IWL_OP_MODE_GET_DVM(op_mode);
+       priv->shrd = trans->shrd;
+       priv->fw = fw;
+       /* TODO: remove fw from shared data later */
+       priv->shrd->fw = fw;
 
-       priv->shrd->trans = trans_ops->alloc(priv->shrd);
-       if (priv->shrd->trans == NULL) {
-               err = -ENOMEM;
-               goto out_free_traffic_mem;
-       }
+       /************************
+        * 2. Setup HW constants
+        ************************/
+       iwl_set_hw_params(priv);
+
+       ucode_flags = fw->ucode_capa.flags;
+
+#ifndef CONFIG_IWLWIFI_P2P
+       ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
+#endif
+       if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE))
+               ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
+
+       /*
+        * if not PAN, then don't support P2P -- might be a uCode
+        * packaging bug or due to the eeprom check above
+        */
+       if (!(ucode_flags & IWL_UCODE_TLV_FLAGS_PAN))
+               ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
+
+
+       /*****************************
+        * Configure transport layer
+        *****************************/
+       /*
+        * Populate the state variables that the transport layer needs
+        * to know about.
+        */
+       trans_cfg.op_mode = op_mode;
+
+       /* Configure transport layer */
+       iwl_trans_configure(trans(priv), &trans_cfg);
 
        /* At this point both hw and priv are allocated. */
 
-       SET_IEEE80211_DEV(hw, bus(priv)->dev);
+       SET_IEEE80211_DEV(priv->hw, trans(priv)->dev);
 
-       /* what debugging capabilities we have */
+       /* show what debugging capabilities we have */
        iwl_debug_config(priv);
 
        IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
-       cfg(priv) = cfg;
 
        /* is antenna coupling more than 35dB ? */
        priv->bt_ant_couple_ok =
@@ -1778,47 +1265,35 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
        /* these spin locks will be used in apm_ops.init and EEPROM access
         * we should init now
         */
-       spin_lock_init(&bus(priv)->reg_lock);
-       spin_lock_init(&priv->shrd->lock);
-
-       /*
-        * stop and reset the on-board processor just in case it is in a
-        * strange state ... like being left stranded by a primary kernel
-        * and this is now the kdump kernel trying to start up
-        */
-       iwl_write32(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+       spin_lock_init(&trans(priv)->reg_lock);
+       spin_lock_init(&priv->statistics.lock);
 
        /***********************
         * 3. Read REV register
         ***********************/
-       hw_rev = iwl_hw_detect(priv);
        IWL_INFO(priv, "Detected %s, REV=0x%X\n",
-               cfg(priv)->name, hw_rev);
+               cfg(priv)->name, trans(priv)->hw_rev);
 
-       err = iwl_trans_request_irq(trans(priv));
+       err = iwl_trans_start_hw(trans(priv));
        if (err)
-               goto out_free_trans;
-
-       if (iwl_trans_prepare_card_hw(trans(priv))) {
-               err = -EIO;
-               IWL_WARN(priv, "Failed, HW not ready\n");
-               goto out_free_trans;
-       }
+               goto out_free_traffic_mem;
 
        /*****************
         * 4. Read EEPROM
         *****************/
        /* Read the EEPROM */
-       err = iwl_eeprom_init(priv, hw_rev);
+       err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev);
+       /* Reset chip to save power until we load uCode during "up". */
+       iwl_trans_stop_hw(trans(priv));
        if (err) {
                IWL_ERR(priv, "Unable to init EEPROM\n");
-               goto out_free_trans;
+               goto out_free_traffic_mem;
        }
        err = iwl_eeprom_check_version(priv);
        if (err)
                goto out_free_eeprom;
 
-       err = iwl_eeprom_check_sku(priv);
+       err = iwl_eeprom_init_hw_params(priv);
        if (err)
                goto out_free_eeprom;
 
@@ -1835,15 +1310,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
                priv->hw->wiphy->n_addresses++;
        }
 
-       /************************
-        * 5. Setup HW constants
-        ************************/
-       if (iwl_set_hw_params(priv)) {
-               err = -ENOENT;
-               IWL_ERR(priv, "failed to set hw parameters\n");
-               goto out_free_eeprom;
-       }
-
        /*******************
         * 6. Setup priv
         *******************/
@@ -1860,62 +1326,71 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
        iwl_setup_rx_handlers(priv);
        iwl_testmode_init(priv);
 
-       /*********************************************
-        * 8. Enable interrupts
-        *********************************************/
+       iwl_power_initialize(priv);
+       iwl_tt_initialize(priv);
 
-       iwl_enable_rfkill_int(priv);
+       snprintf(priv->hw->wiphy->fw_version,
+                sizeof(priv->hw->wiphy->fw_version),
+                "%s", fw->fw_version);
 
-       /* If platform's RF_KILL switch is NOT set to KILL */
-       if (iwl_read32(bus(priv),
-                       CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-               clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status);
-       else
-               set_bit(STATUS_RF_KILL_HW, &priv->shrd->status);
+       priv->new_scan_threshold_behaviour =
+               !!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
 
-       wiphy_rfkill_set_hw_state(priv->hw->wiphy,
-               test_bit(STATUS_RF_KILL_HW, &priv->shrd->status));
+       if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) {
+               priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
+               priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
+       } else {
+               priv->sta_key_max_num = STA_KEY_MAX_NUM;
+               priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
+       }
 
-       iwl_power_initialize(priv);
-       iwl_tt_initialize(priv);
+       priv->phy_calib_chain_noise_reset_cmd =
+               fw->ucode_capa.standard_phy_calibration_size;
+       priv->phy_calib_chain_noise_gain_cmd =
+               fw->ucode_capa.standard_phy_calibration_size + 1;
 
-       init_completion(&priv->firmware_loading_complete);
+       /* initialize all valid contexts */
+       iwl_init_context(priv, ucode_flags);
 
-       err = iwl_request_firmware(priv, true);
+       /**************************************************
+        * This is still part of probe() in a sense...
+        *
+        * 9. Setup and register with mac80211 and debugfs
+        **************************************************/
+       err = iwlagn_mac_setup_register(priv, &fw->ucode_capa);
        if (err)
                goto out_destroy_workqueue;
 
-       return 0;
+       err = iwl_dbgfs_register(priv, DRV_NAME);
+       if (err)
+               IWL_ERR(priv,
+                       "failed to create debugfs files. Ignoring error: %d\n",
+                       err);
+
+       return op_mode;
 
 out_destroy_workqueue:
-       destroy_workqueue(priv->shrd->workqueue);
-       priv->shrd->workqueue = NULL;
+       destroy_workqueue(priv->workqueue);
+       priv->workqueue = NULL;
        iwl_uninit_drv(priv);
 out_free_eeprom:
        iwl_eeprom_free(priv->shrd);
-out_free_trans:
-       iwl_trans_free(trans(priv));
 out_free_traffic_mem:
        iwl_free_traffic_mem(priv);
        ieee80211_free_hw(priv->hw);
 out:
-       return err;
+       op_mode = NULL;
+       return op_mode;
 }
 
-void __devexit iwl_remove(struct iwl_priv * priv)
+static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
 {
-       wait_for_completion(&priv->firmware_loading_complete);
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
 
        IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
 
        iwl_dbgfs_unregister(priv);
 
-       /* ieee80211_unregister_hw call wil cause iwlagn_mac_stop to
-        * to be called and iwl_down since we are removing the device
-        * we need to set STATUS_EXIT_PENDING bit.
-        */
-       set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
-
        iwl_testmode_cleanup(priv);
        iwlagn_mac_unregister(priv);
 
@@ -1924,22 +1399,18 @@ void __devexit iwl_remove(struct iwl_priv * priv)
        /*This will stop the queues, move the device to low power state */
        iwl_trans_stop_device(trans(priv));
 
-       iwl_dealloc_ucode(trans(priv));
-
        iwl_eeprom_free(priv->shrd);
 
        /*netif_stop_queue(dev); */
-       flush_workqueue(priv->shrd->workqueue);
+       flush_workqueue(priv->workqueue);
 
        /* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes
-        * priv->shrd->workqueue... so we can't take down the workqueue
+        * priv->workqueue... so we can't take down the workqueue
         * until now... */
-       destroy_workqueue(priv->shrd->workqueue);
-       priv->shrd->workqueue = NULL;
+       destroy_workqueue(priv->workqueue);
+       priv->workqueue = NULL;
        iwl_free_traffic_mem(priv);
 
-       iwl_trans_free(trans(priv));
-
        iwl_uninit_drv(priv);
 
        dev_kfree_skb(priv->beacon_skb);
@@ -1947,12 +1418,81 @@ void __devexit iwl_remove(struct iwl_priv * priv)
        ieee80211_free_hw(priv->hw);
 }
 
+static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode)
+{
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+
+       if (!iwl_check_for_ct_kill(priv)) {
+               IWL_ERR(priv, "Restarting adapter queue is full\n");
+               iwl_nic_error(op_mode);
+       }
+}
+
+static void iwl_nic_config(struct iwl_op_mode *op_mode)
+{
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+
+       cfg(priv)->lib->nic_config(priv);
+}
+
+static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac)
+{
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+
+       set_bit(ac, &priv->transport_queue_stop);
+       ieee80211_stop_queue(priv->hw, ac);
+}
+
+static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac)
+{
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+
+       clear_bit(ac, &priv->transport_queue_stop);
+
+       if (!priv->passive_no_rx)
+               ieee80211_wake_queue(priv->hw, ac);
+}
+
+void iwlagn_lift_passive_no_rx(struct iwl_priv *priv)
+{
+       int ac;
+
+       if (!priv->passive_no_rx)
+               return;
+
+       for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) {
+               if (!test_bit(ac, &priv->transport_queue_stop)) {
+                       IWL_DEBUG_TX_QUEUES(priv, "Wake queue %d");
+                       ieee80211_wake_queue(priv->hw, ac);
+               } else {
+                       IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d");
+               }
+       }
+
+       priv->passive_no_rx = false;
+}
+
+const struct iwl_op_mode_ops iwl_dvm_ops = {
+       .start = iwl_op_mode_dvm_start,
+       .stop = iwl_op_mode_dvm_stop,
+       .rx = iwl_rx_dispatch,
+       .queue_full = iwl_stop_sw_queue,
+       .queue_not_full = iwl_wake_sw_queue,
+       .hw_rf_kill = iwl_set_hw_rfkill_state,
+       .free_skb = iwl_free_skb,
+       .nic_error = iwl_nic_error,
+       .cmd_queue_full = iwl_cmd_queue_full,
+       .nic_config = iwl_nic_config,
+};
 
 /*****************************************************************************
  *
  * driver and module entry point
  *
  *****************************************************************************/
+
+struct kmem_cache *iwl_tx_cmd_pool;
+
 static int __init iwl_init(void)
 {
 
@@ -1960,20 +1500,27 @@ static int __init iwl_init(void)
        pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
        pr_info(DRV_COPYRIGHT "\n");
 
+       iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd",
+                                           sizeof(struct iwl_device_cmd),
+                                           sizeof(void *), 0, NULL);
+       if (!iwl_tx_cmd_pool)
+               return -ENOMEM;
+
        ret = iwlagn_rate_control_register();
        if (ret) {
                pr_err("Unable to register rate control algorithm: %d\n", ret);
-               return ret;
+               goto error_rc_register;
        }
 
        ret = iwl_pci_register_driver();
-
        if (ret)
-               goto error_register;
+               goto error_pci_register;
        return ret;
 
-error_register:
+error_pci_register:
        iwlagn_rate_control_unregister();
+error_rc_register:
+       kmem_cache_destroy(iwl_tx_cmd_pool);
        return ret;
 }
 
@@ -1981,6 +1528,7 @@ static void __exit iwl_exit(void)
 {
        iwl_pci_unregister_driver();
        iwlagn_rate_control_unregister();
+       kmem_cache_destroy(iwl_tx_cmd_pool);
 }
 
 module_exit(iwl_exit);
@@ -1994,8 +1542,6 @@ MODULE_PARM_DESC(debug, "debug output mask");
 
 module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO);
 MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
-module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO);
-MODULE_PARM_DESC(queues_num, "number of hw queues.");
 module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO);
 MODULE_PARM_DESC(11n_disable,
        "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");
@@ -2054,7 +1600,7 @@ MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)");
 
 module_param_named(led_mode, iwlagn_mod_params.led_mode, int, S_IRUGO);
 MODULE_PARM_DESC(led_mode, "0=system default, "
-               "1=On(RF On)/Off(RF Off), 2=blinking (default: 0)");
+               "1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)");
 
 module_param_named(power_save, iwlagn_mod_params.power_save,
                bool, S_IRUGO);
index f84fb3c535639980f9e5f9d2ae157b236085d92c..3780a03f2716219197938c0815c10d048c9c914a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include "iwl-dev.h"
 
-struct iwlagn_ucode_capabilities {
-       u32 max_probe_length;
-       u32 standard_phy_calibration_size;
-       u32 flags;
-};
+struct iwl_ucode_capabilities;
 
 extern struct ieee80211_ops iwlagn_hw_ops;
 
-int iwl_reset_ict(struct iwl_trans *trans);
-
 static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
 {
        hdr->op_code = cmd;
@@ -83,16 +77,31 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
        hdr->data_valid = 1;
 }
 
-void __iwl_down(struct iwl_priv *priv);
 void iwl_down(struct iwl_priv *priv);
+void iwl_cancel_deferred_work(struct iwl_priv *priv);
 void iwlagn_prepare_restart(struct iwl_priv *priv);
+void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb);
+int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode,
+                                struct iwl_rx_cmd_buffer *rxb,
+                                struct iwl_device_cmd *cmd);
+void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state);
+void iwl_nic_error(struct iwl_op_mode *op_mode);
+
+bool iwl_check_for_ct_kill(struct iwl_priv *priv);
+
+void iwlagn_lift_passive_no_rx(struct iwl_priv *priv);
 
 /* MAC80211 */
 struct ieee80211_hw *iwl_alloc_all(void);
 int iwlagn_mac_setup_register(struct iwl_priv *priv,
-                             struct iwlagn_ucode_capabilities *capa);
+                             const struct iwl_ucode_capabilities *capa);
 void iwlagn_mac_unregister(struct iwl_priv *priv);
 
+/* commands */
+int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id,
+                        u32 flags, u16 len, const void *data);
+
 /* RXON */
 int iwlagn_set_pan_params(struct iwl_priv *priv);
 int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
@@ -107,8 +116,18 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf,
 
 /* uCode */
 int iwlagn_rx_calib_result(struct iwl_priv *priv,
-                           struct iwl_rx_mem_buffer *rxb,
+                           struct iwl_rx_cmd_buffer *rxb,
                            struct iwl_device_cmd *cmd);
+int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
+void iwl_send_prio_tbl(struct iwl_priv *priv);
+int iwl_init_alive_start(struct iwl_priv *priv);
+int iwl_run_init_ucode(struct iwl_priv *priv);
+int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
+                             enum iwl_ucode_type ucode_type);
+int iwl_send_calib_results(struct iwl_priv *priv);
+int iwl_calib_set(struct iwl_priv *priv,
+                 const struct iwl_calib_hdr *cmd, int len);
+void iwl_calib_free_results(struct iwl_priv *priv);
 
 /* lib */
 int iwlagn_send_tx_power(struct iwl_priv *priv);
@@ -120,8 +139,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
 #ifdef CONFIG_PM_SLEEP
 int iwlagn_send_patterns(struct iwl_priv *priv,
                         struct cfg80211_wowlan *wowlan);
-int iwlagn_suspend(struct iwl_priv *priv,
-                  struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
+int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan);
 #endif
 
 /* rx */
@@ -138,9 +156,9 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
 int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                       struct ieee80211_sta *sta, u16 tid);
 int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
-                                  struct iwl_rx_mem_buffer *rxb,
+                                  struct iwl_rx_cmd_buffer *rxb,
                                   struct iwl_device_cmd *cmd);
-int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd);
 
 static inline u32 iwl_tx_status_to_mac80211(u32 status)
@@ -175,7 +193,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv);
 /* bt coex */
 void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
 int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
-                                 struct iwl_rx_mem_buffer *rxb,
+                                 struct iwl_rx_cmd_buffer *rxb,
                                  struct iwl_device_cmd *cmd);
 void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv);
 void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
@@ -216,6 +234,8 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                           struct ieee80211_sta *sta, u8 *sta_id_r);
 int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
                       const u8 *addr);
+void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
+                           const u8 *addr);
 u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                    const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
 
@@ -223,46 +243,12 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                     u8 sta_id, struct iwl_link_quality_cmd *link_cmd);
 int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                    struct iwl_link_quality_cmd *lq, u8 flags, bool init);
-void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd);
+int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                     struct ieee80211_sta *sta);
 
 
-/**
- * iwl_clear_driver_stations - clear knowledge of all stations from driver
- * @priv: iwl priv struct
- *
- * This is called during iwl_down() to make sure that in the case
- * we're coming there from a hardware restart mac80211 will be
- * able to reconfigure stations -- if we're getting there in the
- * normal down flow then the stations will already be cleared.
- */
-static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
-{
-       unsigned long flags;
-       struct iwl_rxon_context *ctx;
-
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       memset(priv->stations, 0, sizeof(priv->stations));
-       priv->num_stations = 0;
-
-       priv->ucode_key_table = 0;
-
-       for_each_context(priv, ctx) {
-               /*
-                * Remove all key information that is not stored as part
-                * of station information since mac80211 may not have had
-                * a chance to remove all the keys. When device is
-                * reconfigured by mac80211 after an error all keys will
-                * be reconfigured.
-                */
-               memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
-               ctx->key_mapping_keys = 0;
-       }
-
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-}
-
 static inline int iwl_sta_id(struct ieee80211_sta *sta)
 {
        if (WARN_ON(!sta))
@@ -271,37 +257,6 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
        return ((struct iwl_station_priv *)sta->drv_priv)->sta_id;
 }
 
-/**
- * iwl_sta_id_or_broadcast - return sta_id or broadcast sta
- * @priv: iwl priv
- * @context: the current context
- * @sta: mac80211 station
- *
- * In certain circumstances mac80211 passes a station pointer
- * that may be %NULL, for example during TX or key setup. In
- * that case, we need to use the broadcast station, so this
- * inline wraps that pattern.
- */
-static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
-                                         struct iwl_rxon_context *context,
-                                         struct ieee80211_sta *sta)
-{
-       int sta_id;
-
-       if (!sta)
-               return context->bcast_sta_id;
-
-       sta_id = iwl_sta_id(sta);
-
-       /*
-        * mac80211 should not be passing a partially
-        * initialised station!
-        */
-       WARN_ON(sta_id == IWL_INVALID_STATION);
-
-       return sta_id;
-}
-
 int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
                               struct iwl_rxon_context *ctx);
 int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
@@ -351,7 +306,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
 }
 
 /* eeprom */
-void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv);
 void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac);
 
 extern int iwl_alive_start(struct iwl_priv *priv);
@@ -388,4 +342,68 @@ void iwl_testmode_cleanup(struct iwl_priv *priv)
 }
 #endif
 
+#ifdef CONFIG_IWLWIFI_DEBUG
+void iwl_print_rx_config_cmd(struct iwl_priv *priv,
+                            enum iwl_rxon_context_id ctxid);
+#else
+static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
+                                          enum iwl_rxon_context_id ctxid)
+{
+}
+#endif
+
+/* status checks */
+
+static inline int iwl_is_ready(struct iwl_priv *priv)
+{
+       /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
+        * set but EXIT_PENDING is not */
+       return test_bit(STATUS_READY, &priv->status) &&
+              test_bit(STATUS_GEO_CONFIGURED, &priv->status) &&
+              !test_bit(STATUS_EXIT_PENDING, &priv->status);
+}
+
+static inline int iwl_is_alive(struct iwl_priv *priv)
+{
+       return test_bit(STATUS_ALIVE, &priv->status);
+}
+
+static inline int iwl_is_rfkill(struct iwl_priv *priv)
+{
+       return test_bit(STATUS_RF_KILL_HW, &priv->status);
+}
+
+static inline int iwl_is_ctkill(struct iwl_priv *priv)
+{
+       return test_bit(STATUS_CT_KILL, &priv->status);
+}
+
+static inline int iwl_is_ready_rf(struct iwl_priv *priv)
+{
+       if (iwl_is_rfkill(priv))
+               return 0;
+
+       return iwl_is_ready(priv);
+}
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...)        \
+do {                                                                   \
+       if (!iwl_is_rfkill((m)))                                        \
+               IWL_ERR(m, fmt, ##args);                                \
+       else                                                            \
+               __iwl_err(trans(m)->dev, true,                          \
+                         !iwl_have_debug_level(IWL_DL_RADIO),          \
+                         fmt, ##args);                                 \
+} while (0)
+#else
+#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...)        \
+do {                                                                   \
+       if (!iwl_is_rfkill((m)))                                        \
+               IWL_ERR(m, fmt, ##args);                                \
+       else                                                            \
+               __iwl_err(trans(m)->dev, true, true, fmt, ##args);      \
+} while (0)
+#endif                         /* CONFIG_IWLWIFI_DEBUG */
+
 #endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h
deleted file mode 100644 (file)
index 940d503..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-#ifndef __iwl_bus_h__
-#define __iwl_bus_h__
-
-#include <linux/types.h>
-#include <linux/spinlock.h>
-
-/**
- * DOC: Bus layer - role and goal
- *
- * iwl-bus.h defines the API to the bus layer of the iwlwifi driver.
- * The bus layer is responsible for doing very basic bus operations that are
- * listed in the iwl_bus_ops structure.
- * The bus layer registers to the bus driver, advertises the supported HW and
- * gets notifications about enumeration, suspend, resume.
- * For the moment, the bus layer is not a linux kernel module as itself, and
- * the module_init function of the driver must call the bus specific
- * registration functions. These functions are listed at the end of this file.
- * For the moment, there is only one implementation of this interface: PCI-e.
- * This implementation is iwl-pci.c
- */
-
-/**
- * DOC: encapsulation and type safety
- *
- * The iwl_bus describes the data that is shared amongst all the bus layer
- * implementations. This data is visible to other layers. Data in the bus
- * specific area is not visible outside the bus specific implementation.
- * iwl_bus holds a pointer to iwl_shared which holds pointer to all the other
- * layers of the driver (iwl_priv, iwl_trans). In fact, this is the way to go
- * when the transport layer needs to call a function of another layer.
- *
- * In order to achieve encapsulation, iwl_priv cannot be dereferenced from the
- * bus layer. Type safety is still kept since functions that gets iwl_priv gets
- * a typed pointer (as opposed to void *).
- */
-
-/**
- * DOC: probe flow
- *
- * The module_init calls the bus specific registration function. The
- * registration to the bus layer will trigger an enumeration of the bus which
- * will call the bus specific probe function.
- * The first thing this function must do is to allocate the memory needed by
- * iwl_bus + the bus_specific data.
- * Once the bus specific probe function has configured the hardware, it
- * chooses the appropriate transport layer and calls iwl_probe that will run
- * the bus independent probe flow.
- *
- * Note: The bus specific code must set the following data in iwl_bus before it
- *       calls iwl_probe:
- *     * bus->dev
- *     * bus->irq
- *     * bus->ops
- */
-
-struct iwl_shared;
-struct iwl_bus;
-
-/**
- * struct iwl_bus_ops - bus specific operations
- * @get_pm_support: must returns true if the bus can go to sleep
- * @apm_config: will be called during the config of the APM
- * @get_hw_id_string: prints the hw_id in the provided buffer
- * @get_hw_id: get hw_id in u32
- * @write8: write a byte to register at offset ofs
- * @write32: write a dword to register at offset ofs
- * @wread32: read a dword at register at offset ofs
- */
-struct iwl_bus_ops {
-       bool (*get_pm_support)(struct iwl_bus *bus);
-       void (*apm_config)(struct iwl_bus *bus);
-       void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len);
-       u32 (*get_hw_id)(struct iwl_bus *bus);
-       void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val);
-       void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val);
-       u32 (*read32)(struct iwl_bus *bus, u32 ofs);
-};
-
-/**
- * struct iwl_bus - bus common data
- *
- * This data is common to all bus layer implementations.
- *
- * @dev - pointer to struct device * that represents the device
- * @ops - pointer to iwl_bus_ops
- * @shrd - pointer to iwl_shared which holds shared data from the upper layer
- *     NB: for the time being this needs to be set by the upper layer since
- *     it allocates the shared data
- * @irq - the irq number for the device
- * @reg_lock - protect hw register access
- */
-struct iwl_bus {
-       struct device *dev;
-       const struct iwl_bus_ops *ops;
-       struct iwl_shared *shrd;
-
-       unsigned int irq;
-       spinlock_t reg_lock;
-
-       /* pointer to bus specific struct */
-       /*Ensure that this pointer will always be aligned to sizeof pointer */
-       char bus_specific[0] __attribute__((__aligned__(sizeof(void *))));
-};
-
-static inline bool bus_get_pm_support(struct iwl_bus *bus)
-{
-       return bus->ops->get_pm_support(bus);
-}
-
-static inline void bus_apm_config(struct iwl_bus *bus)
-{
-       bus->ops->apm_config(bus);
-}
-
-static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[],
-               int buf_len)
-{
-       bus->ops->get_hw_id_string(bus, buf, buf_len);
-}
-
-static inline u32 bus_get_hw_id(struct iwl_bus *bus)
-{
-       return bus->ops->get_hw_id(bus);
-}
-
-static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val)
-{
-       bus->ops->write8(bus, ofs, val);
-}
-
-static inline void bus_write32(struct iwl_bus *bus, u32 ofs, u32 val)
-{
-       bus->ops->write32(bus, ofs, val);
-}
-
-static inline u32 bus_read32(struct iwl_bus *bus, u32 ofs)
-{
-       return bus->ops->read32(bus, ofs);
-}
-
-/*****************************************************
-* Bus layer registration functions
-******************************************************/
-int __must_check iwl_pci_register_driver(void);
-void iwl_pci_unregister_driver(void);
-
-#endif /* __iwl_bus_h__ */
index e1d78257e4a9426c0908a0b64acd7b31a1ca972b..82152311d73b3ebe5a89d3cdfac1732892327696 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * This file declares the config structures for all devices.
  */
 
-extern struct iwl_cfg iwl5300_agn_cfg;
-extern struct iwl_cfg iwl5100_agn_cfg;
-extern struct iwl_cfg iwl5350_agn_cfg;
-extern struct iwl_cfg iwl5100_bgn_cfg;
-extern struct iwl_cfg iwl5100_abg_cfg;
-extern struct iwl_cfg iwl5150_agn_cfg;
-extern struct iwl_cfg iwl5150_abg_cfg;
-extern struct iwl_cfg iwl6005_2agn_cfg;
-extern struct iwl_cfg iwl6005_2abg_cfg;
-extern struct iwl_cfg iwl6005_2bg_cfg;
-extern struct iwl_cfg iwl6005_2agn_sff_cfg;
-extern struct iwl_cfg iwl6005_2agn_d_cfg;
-extern struct iwl_cfg iwl1030_bgn_cfg;
-extern struct iwl_cfg iwl1030_bg_cfg;
-extern struct iwl_cfg iwl6030_2agn_cfg;
-extern struct iwl_cfg iwl6030_2abg_cfg;
-extern struct iwl_cfg iwl6030_2bgn_cfg;
-extern struct iwl_cfg iwl6030_2bg_cfg;
-extern struct iwl_cfg iwl6000i_2agn_cfg;
-extern struct iwl_cfg iwl6000i_2abg_cfg;
-extern struct iwl_cfg iwl6000i_2bg_cfg;
-extern struct iwl_cfg iwl6000_3agn_cfg;
-extern struct iwl_cfg iwl6050_2agn_cfg;
-extern struct iwl_cfg iwl6050_2abg_cfg;
-extern struct iwl_cfg iwl6150_bgn_cfg;
-extern struct iwl_cfg iwl6150_bg_cfg;
-extern struct iwl_cfg iwl1000_bgn_cfg;
-extern struct iwl_cfg iwl1000_bg_cfg;
-extern struct iwl_cfg iwl100_bgn_cfg;
-extern struct iwl_cfg iwl100_bg_cfg;
-extern struct iwl_cfg iwl130_bgn_cfg;
-extern struct iwl_cfg iwl130_bg_cfg;
-extern struct iwl_cfg iwl2000_2bgn_cfg;
-extern struct iwl_cfg iwl2000_2bgn_d_cfg;
-extern struct iwl_cfg iwl2030_2bgn_cfg;
-extern struct iwl_cfg iwl6035_2agn_cfg;
-extern struct iwl_cfg iwl105_bgn_cfg;
-extern struct iwl_cfg iwl105_bgn_d_cfg;
-extern struct iwl_cfg iwl135_bgn_cfg;
+extern const struct iwl_cfg iwl5300_agn_cfg;
+extern const struct iwl_cfg iwl5100_agn_cfg;
+extern const struct iwl_cfg iwl5350_agn_cfg;
+extern const struct iwl_cfg iwl5100_bgn_cfg;
+extern const struct iwl_cfg iwl5100_abg_cfg;
+extern const struct iwl_cfg iwl5150_agn_cfg;
+extern const struct iwl_cfg iwl5150_abg_cfg;
+extern const struct iwl_cfg iwl6005_2agn_cfg;
+extern const struct iwl_cfg iwl6005_2abg_cfg;
+extern const struct iwl_cfg iwl6005_2bg_cfg;
+extern const struct iwl_cfg iwl6005_2agn_sff_cfg;
+extern const struct iwl_cfg iwl6005_2agn_d_cfg;
+extern const struct iwl_cfg iwl6005_2agn_mow1_cfg;
+extern const struct iwl_cfg iwl6005_2agn_mow2_cfg;
+extern const struct iwl_cfg iwl1030_bgn_cfg;
+extern const struct iwl_cfg iwl1030_bg_cfg;
+extern const struct iwl_cfg iwl6030_2agn_cfg;
+extern const struct iwl_cfg iwl6030_2abg_cfg;
+extern const struct iwl_cfg iwl6030_2bgn_cfg;
+extern const struct iwl_cfg iwl6030_2bg_cfg;
+extern const struct iwl_cfg iwl6000i_2agn_cfg;
+extern const struct iwl_cfg iwl6000i_2abg_cfg;
+extern const struct iwl_cfg iwl6000i_2bg_cfg;
+extern const struct iwl_cfg iwl6000_3agn_cfg;
+extern const struct iwl_cfg iwl6050_2agn_cfg;
+extern const struct iwl_cfg iwl6050_2abg_cfg;
+extern const struct iwl_cfg iwl6150_bgn_cfg;
+extern const struct iwl_cfg iwl6150_bg_cfg;
+extern const struct iwl_cfg iwl1000_bgn_cfg;
+extern const struct iwl_cfg iwl1000_bg_cfg;
+extern const struct iwl_cfg iwl100_bgn_cfg;
+extern const struct iwl_cfg iwl100_bg_cfg;
+extern const struct iwl_cfg iwl130_bgn_cfg;
+extern const struct iwl_cfg iwl130_bg_cfg;
+extern const struct iwl_cfg iwl2000_2bgn_cfg;
+extern const struct iwl_cfg iwl2000_2bgn_d_cfg;
+extern const struct iwl_cfg iwl2030_2bgn_cfg;
+extern const struct iwl_cfg iwl6035_2agn_cfg;
+extern const struct iwl_cfg iwl105_bgn_cfg;
+extern const struct iwl_cfg iwl105_bgn_d_cfg;
+extern const struct iwl_cfg iwl135_bgn_cfg;
 
 #endif /* __iwl_pci_h__ */
index f822ac447c3bcd484979d9ce5179a6064bb2e2f9..9ed73e5154be908a18662fb9493292233594e0d8 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #ifndef __iwl_commands_h__
 #define __iwl_commands_h__
 
-#include <linux/etherdevice.h>
 #include <linux/ieee80211.h>
+#include <linux/types.h>
 
-struct iwl_priv;
-
-/* uCode version contains 4 values: Major/Minor/API/Serial */
-#define IWL_UCODE_MAJOR(ver)   (((ver) & 0xFF000000) >> 24)
-#define IWL_UCODE_MINOR(ver)   (((ver) & 0x00FF0000) >> 16)
-#define IWL_UCODE_API(ver)     (((ver) & 0x0000FF00) >> 8)
-#define IWL_UCODE_SERIAL(ver)  ((ver) & 0x000000FF)
-
-
-/* Tx rates */
-#define IWL_CCK_RATES  4
-#define IWL_OFDM_RATES 8
-#define IWL_MAX_RATES  (IWL_CCK_RATES + IWL_OFDM_RATES)
 
 enum {
        REPLY_ALIVE = 0x1,
@@ -213,48 +200,6 @@ enum {
 /* iwl_cmd_header flags value */
 #define IWL_CMD_FAILED_MSK 0x40
 
-#define SEQ_TO_QUEUE(s)        (((s) >> 8) & 0x1f)
-#define QUEUE_TO_SEQ(q)        (((q) & 0x1f) << 8)
-#define SEQ_TO_INDEX(s)        ((s) & 0xff)
-#define INDEX_TO_SEQ(i)        ((i) & 0xff)
-#define SEQ_RX_FRAME   cpu_to_le16(0x8000)
-
-/**
- * struct iwl_cmd_header
- *
- * This header format appears in the beginning of each command sent from the
- * driver, and each response/notification received from uCode.
- */
-struct iwl_cmd_header {
-       u8 cmd;         /* Command ID:  REPLY_RXON, etc. */
-       u8 flags;       /* 0:5 reserved, 6 abort, 7 internal */
-       /*
-        * The driver sets up the sequence number to values of its choosing.
-        * uCode does not use this value, but passes it back to the driver
-        * when sending the response to each driver-originated command, so
-        * the driver can match the response to the command.  Since the values
-        * don't get used by uCode, the driver may set up an arbitrary format.
-        *
-        * There is one exception:  uCode sets bit 15 when it originates
-        * the response/notification, i.e. when the response/notification
-        * is not a direct response to a command sent by the driver.  For
-        * example, uCode issues REPLY_RX when it sends a received frame
-        * to the driver; it is not a direct response to any driver command.
-        *
-        * The Linux driver uses the following format:
-        *
-        *  0:7         tfd index - position within TX queue
-        *  8:12        TX queue id
-        *  13:14       reserved
-        *  15          unsolicited RX or uCode-originated notification
-        */
-       __le16 sequence;
-
-       /* command or response/notification data follows immediately */
-       u8 data[0];
-} __packed;
-
-
 /**
  * iwlagn rate_n_flags bit fields
  *
@@ -3151,8 +3096,6 @@ struct iwl_enhance_sensitivity_cmd {
  */
 
 /* Phy calibration command for series */
-/* The default calibrate table size if not specified by firmware */
-#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE    18
 enum {
        IWL_PHY_CALIBRATE_DC_CMD                = 8,
        IWL_PHY_CALIBRATE_LO_CMD                = 9,
@@ -3161,11 +3104,8 @@ enum {
        IWL_PHY_CALIBRATE_BASE_BAND_CMD         = 16,
        IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD        = 17,
        IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD       = 18,
-       IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19,
 };
 
-#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE         (253)
-
 /* This enum defines the bitmap of various calibrations to enable in both
  * init ucode and runtime ucode through CALIBRATION_CFG_CMD.
  */
@@ -3905,50 +3845,6 @@ struct iwlagn_wowlan_kek_kck_material_cmd {
        __le64  replay_ctr;
 } __packed;
 
-/******************************************************************************
- * (13)
- * Union of all expected notifications/responses:
- *
- *****************************************************************************/
-#define FH_RSCSR_FRAME_SIZE_MSK        (0x00003FFF)    /* bits 0-13 */
-
-struct iwl_rx_packet {
-       /*
-        * The first 4 bytes of the RX frame header contain both the RX frame
-        * size and some flags.
-        * Bit fields:
-        * 31:    flag flush RB request
-        * 30:    flag ignore TC (terminal counter) request
-        * 29:    flag fast IRQ request
-        * 28-14: Reserved
-        * 13-00: RX frame size
-        */
-       __le32 len_n_flags;
-       struct iwl_cmd_header hdr;
-       union {
-               struct iwl_alive_resp alive_frame;
-               struct iwl_spectrum_notification spectrum_notif;
-               struct iwl_csa_notification csa_notif;
-               struct iwl_error_resp err_resp;
-               struct iwl_card_state_notif card_state_notif;
-               struct iwl_add_sta_resp add_sta;
-               struct iwl_rem_sta_resp rem_sta;
-               struct iwl_sleep_notification sleep_notif;
-               struct iwl_spectrum_resp spectrum;
-               struct iwl_notif_statistics stats;
-               struct iwl_bt_notif_statistics stats_bt;
-               struct iwl_compressed_ba_resp compressed_ba;
-               struct iwl_missed_beacon_notif missed_beacon;
-               struct iwl_coex_medium_notification coex_medium_notif;
-               struct iwl_coex_event_resp coex_event;
-               struct iwl_bt_coex_profile_notif bt_coex_profile_notif;
-               __le32 status;
-               u8 raw[0];
-       } u;
-} __packed;
-
-int iwl_agn_check_rxon_cmd(struct iwl_priv *priv);
-
 /*
  * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification)
  */
index 7bcfa781e0b914594c9157d561a7509d2a32a291..8b85940731f22992e51bca762727e5b5855e8420 100644 (file)
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -38,7 +38,6 @@
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-power.h"
-#include "iwl-agn.h"
 #include "iwl-shared.h"
 #include "iwl-agn.h"
 #include "iwl-trans.h"
@@ -114,7 +113,7 @@ int iwl_init_geos(struct iwl_priv *priv)
        if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
            priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
                IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n");
-               set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status);
+               set_bit(STATUS_GEO_CONFIGURED, &priv->status);
                return 0;
        }
 
@@ -137,7 +136,7 @@ int iwl_init_geos(struct iwl_priv *priv)
        sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
        sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE;
 
-       if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)
+       if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
                iwl_init_ht_hw_capab(priv, &sband->ht_cap,
                                         IEEE80211_BAND_5GHZ);
 
@@ -147,7 +146,7 @@ int iwl_init_geos(struct iwl_priv *priv)
        sband->bitrates = rates;
        sband->n_bitrates = IWL_RATE_COUNT_LEGACY;
 
-       if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)
+       if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
                iwl_init_ht_hw_capab(priv, &sband->ht_cap,
                                         IEEE80211_BAND_2GHZ);
 
@@ -202,19 +201,18 @@ int iwl_init_geos(struct iwl_priv *priv)
        priv->tx_power_next = max_tx_power;
 
        if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
-            cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) {
-               char buf[32];
-               bus_get_hw_id_string(bus(priv), buf, sizeof(buf));
+            hw_params(priv).sku & EEPROM_SKU_CAP_BAND_52GHZ) {
                IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
-                       "Please send your %s to maintainer.\n", buf);
-               cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
+                       "Please send your %s to maintainer.\n",
+                       trans(priv)->hw_id_str);
+               hw_params(priv).sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
        }
 
        IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
                   priv->bands[IEEE80211_BAND_2GHZ].n_channels,
                   priv->bands[IEEE80211_BAND_5GHZ].n_channels);
 
-       set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status);
+       set_bit(STATUS_GEO_CONFIGURED, &priv->status);
 
        return 0;
 }
@@ -226,7 +224,7 @@ void iwl_free_geos(struct iwl_priv *priv)
 {
        kfree(priv->ieee_channels);
        kfree(priv->ieee_rates);
-       clear_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status);
+       clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
 }
 
 static bool iwl_is_channel_extension(struct iwl_priv *priv,
@@ -318,7 +316,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 
        conf = &priv->hw->conf;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd));
 
@@ -371,7 +369,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        le32_to_cpu(ctx->timing.beacon_init_val),
                        le16_to_cpu(ctx->timing.atim_window));
 
-       return iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_timing_cmd,
+       return iwl_dvm_send_cmd_pdu(priv, ctx->rxon_timing_cmd,
                                CMD_SYNC, sizeof(ctx->timing), &ctx->timing);
 }
 
@@ -644,7 +642,7 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv,
  * NOTE:  Does not commit to the hardware; it sets appropriate bit fields
  * in the staging RXON flag structure based on the ch->band
  */
-int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
+void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
                         struct iwl_rxon_context *ctx)
 {
        enum ieee80211_band band = ch->band;
@@ -652,7 +650,7 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
 
        if ((le16_to_cpu(ctx->staging.channel) == channel) &&
            (priv->band == band))
-               return 0;
+               return;
 
        ctx->staging.channel = cpu_to_le16(channel);
        if (band == IEEE80211_BAND_5GHZ)
@@ -664,7 +662,6 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
 
        IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
 
-       return 0;
 }
 
 void iwl_set_flags_for_band(struct iwl_priv *priv,
@@ -801,11 +798,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
         */
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING,
-                               &priv->shrd->status))
+       if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
                ieee80211_chswitch_done(ctx->vif, is_success);
 }
 
@@ -832,22 +828,27 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
 }
 #endif
 
-void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
+static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
 {
        unsigned int reload_msec;
        unsigned long reload_jiffies;
 
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (iwl_have_debug_level(IWL_DL_FW_ERRORS))
+               iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
+#endif
+
        /* Set the FW error flag -- cleared on iwl_down */
        set_bit(STATUS_FW_ERROR, &priv->shrd->status);
 
        /* Cancel currently queued command. */
        clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status);
 
-       iwl_abort_notification_waits(priv->shrd);
+       iwl_abort_notification_waits(&priv->notif_wait);
 
        /* Keep the restart process from trying to send host
         * commands by clearing the ready bit */
-       clear_bit(STATUS_READY, &priv->shrd->status);
+       clear_bit(STATUS_READY, &priv->status);
 
        wake_up(&priv->shrd->wait_command_queue);
 
@@ -872,140 +873,17 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
                        priv->reload_count = 0;
        }
 
-       if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) {
+       if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
                if (iwlagn_mod_params.restart_fw) {
                        IWL_DEBUG_FW_ERRORS(priv,
                                  "Restarting adapter due to uCode error.\n");
-                       queue_work(priv->shrd->workqueue, &priv->restart);
+                       queue_work(priv->workqueue, &priv->restart);
                } else
                        IWL_DEBUG_FW_ERRORS(priv,
                                  "Detected FW error, but not restarting\n");
        }
 }
 
-static int iwl_apm_stop_master(struct iwl_priv *priv)
-{
-       int ret = 0;
-
-       /* stop device's busmaster DMA activity */
-       iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
-
-       ret = iwl_poll_bit(bus(priv), CSR_RESET,
-                       CSR_RESET_REG_FLAG_MASTER_DISABLED,
-                       CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
-       if (ret)
-               IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n");
-
-       IWL_DEBUG_INFO(priv, "stop master\n");
-
-       return ret;
-}
-
-void iwl_apm_stop(struct iwl_priv *priv)
-{
-       IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
-
-       clear_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status);
-
-       /* Stop device's DMA activity */
-       iwl_apm_stop_master(priv);
-
-       /* Reset the entire device */
-       iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-
-       udelay(10);
-
-       /*
-        * Clear "initialization complete" bit to move adapter from
-        * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
-        */
-       iwl_clear_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-}
-
-
-/*
- * Start up NIC's basic functionality after it has been reset
- * (e.g. after platform boot, or shutdown via iwl_apm_stop())
- * NOTE:  This does not load uCode nor start the embedded processor
- */
-int iwl_apm_init(struct iwl_priv *priv)
-{
-       int ret = 0;
-       IWL_DEBUG_INFO(priv, "Init card's basic functions\n");
-
-       /*
-        * Use "set_bit" below rather than "write", to preserve any hardware
-        * bits already set by default after reset.
-        */
-
-       /* Disable L0S exit timer (platform NMI Work/Around) */
-       iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS,
-                         CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-       /*
-        * Disable L0s without affecting L1;
-        *  don't wait for ICH L0s (ICH bug W/A)
-        */
-       iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS,
-                         CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
-       /* Set FH wait threshold to maximum (HW error during stress W/A) */
-       iwl_set_bit(bus(priv), CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
-
-       /*
-        * Enable HAP INTA (interrupt from management bus) to
-        * wake device's PCI Express link L1a -> L0s
-        */
-       iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG,
-                                   CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
-
-       bus_apm_config(bus(priv));
-
-       /* Configure analog phase-lock-loop before activating to D0A */
-       if (cfg(priv)->base_params->pll_cfg_val)
-               iwl_set_bit(bus(priv), CSR_ANA_PLL_CFG,
-                           cfg(priv)->base_params->pll_cfg_val);
-
-       /*
-        * Set "initialization complete" bit to move adapter from
-        * D0U* --> D0A* (powered-up active) state.
-        */
-       iwl_set_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-       /*
-        * Wait for clock stabilization; once stabilized, access to
-        * device-internal resources is supported, e.g. iwl_write_prph()
-        * and accesses to uCode SRAM.
-        */
-       ret = iwl_poll_bit(bus(priv), CSR_GP_CNTRL,
-                       CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-                       CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-       if (ret < 0) {
-               IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-               goto out;
-       }
-
-       /*
-        * Enable DMA clock and wait for it to stabilize.
-        *
-        * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
-        * do not disable clocks.  This preserves any hardware bits already
-        * set by default in "CLK_CTRL_REG" after reset.
-        */
-       iwl_write_prph(bus(priv), APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
-       udelay(20);
-
-       /* Disable L1-Active */
-       iwl_set_bits_prph(bus(priv), APMG_PCIDEV_STT_REG,
-                         APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
-       set_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status);
-
-out:
-       return ret;
-}
-
-
 int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
 {
        int ret;
@@ -1013,7 +891,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
        bool defer;
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (priv->tx_power_user_lmt == tx_power && !force)
                return 0;
@@ -1033,7 +911,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
                return -EINVAL;
        }
 
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return -EIO;
 
        /* scan complete and commit_rxon use tx_power_next value,
@@ -1041,7 +919,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
        priv->tx_power_next = tx_power;
 
        /* do not set tx power when scanning or channel changing */
-       defer = test_bit(STATUS_SCANNING, &priv->shrd->status) ||
+       defer = test_bit(STATUS_SCANNING, &priv->status) ||
                memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging));
        if (defer && !force) {
                IWL_DEBUG_INFO(priv, "Deferring tx power set\n");
@@ -1079,7 +957,7 @@ void iwl_send_bt_config(struct iwl_priv *priv)
        IWL_DEBUG_INFO(priv, "BT coex %s\n",
                (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
 
-       if (iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG,
+       if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
                             CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd))
                IWL_ERR(priv, "failed to send BT Coex Config\n");
 }
@@ -1092,12 +970,12 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
        };
 
        if (flags & CMD_ASYNC)
-               return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD,
+               return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
                                              CMD_ASYNC,
                                               sizeof(struct iwl_statistics_cmd),
                                               &statistics_cmd);
        else
-               return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD,
+               return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
                                        CMD_SYNC,
                                        sizeof(struct iwl_statistics_cmd),
                                        &statistics_cmd);
@@ -1124,7 +1002,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv)
 {
        u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE;
 
-       if (iwl_get_debug_level(priv->shrd) & IWL_DL_TX) {
+       if (iwl_have_debug_level(IWL_DL_TX)) {
                if (!priv->tx_traffic) {
                        priv->tx_traffic =
                                kzalloc(traffic_size, GFP_KERNEL);
@@ -1132,7 +1010,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv)
                                return -ENOMEM;
                }
        }
-       if (iwl_get_debug_level(priv->shrd) & IWL_DL_RX) {
+       if (iwl_have_debug_level(IWL_DL_RX)) {
                if (!priv->rx_traffic) {
                        priv->rx_traffic =
                                kzalloc(traffic_size, GFP_KERNEL);
@@ -1159,7 +1037,7 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv,
        __le16 fc;
        u16 len;
 
-       if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_TX)))
+       if (likely(!iwl_have_debug_level(IWL_DL_TX)))
                return;
 
        if (!priv->tx_traffic)
@@ -1183,7 +1061,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
        __le16 fc;
        u16 len;
 
-       if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_RX)))
+       if (likely(!iwl_have_debug_level(IWL_DL_RX)))
                return;
 
        if (!priv->rx_traffic)
@@ -1340,7 +1218,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
 
 static void iwl_force_rf_reset(struct iwl_priv *priv)
 {
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        if (!iwl_is_any_associated(priv)) {
@@ -1365,7 +1243,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
 {
        struct iwl_force_reset *force_reset;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return -EINVAL;
 
        if (mode >= IWL_MAX_FORCE_RESET) {
@@ -1421,7 +1299,7 @@ int iwl_cmd_echo_test(struct iwl_priv *priv)
                .flags = CMD_SYNC,
        };
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
        if (ret)
                IWL_ERR(priv, "echo testing fail: 0X%x\n", ret);
        else
@@ -1455,30 +1333,20 @@ void iwl_bg_watchdog(unsigned long data)
        int cnt;
        unsigned long timeout;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       if (iwl_is_rfkill(priv->shrd))
+       if (iwl_is_rfkill(priv))
                return;
 
-       timeout = cfg(priv)->base_params->wd_timeout;
+       timeout = hw_params(priv).wd_timeout;
        if (timeout == 0)
                return;
 
-       /* monitor and check for stuck cmd queue */
-       if (iwl_check_stuck_queue(priv, priv->shrd->cmd_queue))
-               return;
-
-       /* monitor and check for other stuck queues */
-       if (iwl_is_any_associated(priv)) {
-               for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) {
-                       /* skip as we already checked the command queue */
-                       if (cnt == priv->shrd->cmd_queue)
-                               continue;
-                       if (iwl_check_stuck_queue(priv, cnt))
-                               return;
-               }
-       }
+       /* monitor and check for stuck queues */
+       for (cnt = 0; cnt < cfg(priv)->base_params->num_of_queues; cnt++)
+               if (iwl_check_stuck_queue(priv, cnt))
+                       return;
 
        mod_timer(&priv->watchdog, jiffies +
                  msecs_to_jiffies(IWL_WD_TICK(timeout)));
@@ -1486,7 +1354,7 @@ void iwl_bg_watchdog(unsigned long data)
 
 void iwl_setup_watchdog(struct iwl_priv *priv)
 {
-       unsigned int timeout = cfg(priv)->base_params->wd_timeout;
+       unsigned int timeout = hw_params(priv).wd_timeout;
 
        if (!iwlagn_mod_params.wd_disable) {
                /* use system default */
@@ -1580,31 +1448,30 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
        return cpu_to_le32(res);
 }
 
-void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state)
+void iwl_nic_error(struct iwl_op_mode *op_mode)
 {
-       wiphy_rfkill_set_hw_state(priv->hw->wiphy, state);
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+
+       iwlagn_fw_error(priv, false);
 }
 
-void iwl_nic_config(struct iwl_priv *priv)
+void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
 {
-       cfg(priv)->lib->nic_config(priv);
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+
+       if (state)
+               set_bit(STATUS_RF_KILL_HW, &priv->status);
+       else
+               clear_bit(STATUS_RF_KILL_HW, &priv->status);
+
+       wiphy_rfkill_set_hw_state(priv->hw->wiphy, state);
 }
 
-void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb)
+void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
 {
        struct ieee80211_tx_info *info;
 
        info = IEEE80211_SKB_CB(skb);
-       kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1]));
+       kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1]));
        dev_kfree_skb_any(skb);
 }
-
-void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac)
-{
-       ieee80211_stop_queue(priv->hw, ac);
-}
-
-void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac)
-{
-       ieee80211_wake_queue(priv->hw, ac);
-}
index 7bf76ab94dd21afb5fc8d80351eca3788d8452fa..635eb685edeb9308b35d0a2d015aaeb3db795cd0 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -76,13 +76,7 @@ struct iwl_cmd;
 
 struct iwl_lib_ops {
        /* set hw dependent parameters */
-       int (*set_hw_params)(struct iwl_priv *priv);
-       /* setup BT Rx handler */
-       void (*bt_rx_handler_setup)(struct iwl_priv *priv);
-       /* setup BT related deferred work */
-       void (*bt_setup_deferred_work)(struct iwl_priv *priv);
-       /* cancel deferred work */
-       void (*cancel_deferred_work)(struct iwl_priv *priv);
+       void (*set_hw_params)(struct iwl_priv *priv);
        int (*set_channel_switch)(struct iwl_priv *priv,
                                  struct ieee80211_channel_switch *ch_switch);
        /* device specific configuration */
@@ -95,72 +89,6 @@ struct iwl_lib_ops {
        void (*temperature)(struct iwl_priv *priv);
 };
 
-/*
- * @max_ll_items: max number of OTP blocks
- * @shadow_ram_support: shadow support for OTP memory
- * @led_compensation: compensate on the led on/off time per HW according
- *     to the deviation to achieve the desired led frequency.
- *     The detail algorithm is described in iwl-led.c
- * @chain_noise_num_beacons: number of beacons used to compute chain noise
- * @adv_thermal_throttle: support advance thermal throttle
- * @support_ct_kill_exit: support ct kill exit condition
- * @support_wimax_coexist: support wimax/wifi co-exist
- * @plcp_delta_threshold: plcp error rate threshold used to trigger
- *     radio tuning when there is a high receiving plcp error rate
- * @chain_noise_scale: default chain noise scale used for gain computation
- * @wd_timeout: TX queues watchdog timeout
- * @max_event_log_size: size of event log buffer size for ucode event logging
- * @shadow_reg_enable: HW shadhow register bit
- * @no_idle_support: do not support idle mode
- * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
- * wd_disable: disable watchdog timer
- */
-struct iwl_base_params {
-       int eeprom_size;
-       int num_of_queues;      /* def: HW dependent */
-       int num_of_ampdu_queues;/* def: HW dependent */
-       /* for iwl_apm_init() */
-       u32 pll_cfg_val;
-
-       const u16 max_ll_items;
-       const bool shadow_ram_support;
-       u16 led_compensation;
-       bool adv_thermal_throttle;
-       bool support_ct_kill_exit;
-       const bool support_wimax_coexist;
-       u8 plcp_delta_threshold;
-       s32 chain_noise_scale;
-       unsigned int wd_timeout;
-       u32 max_event_log_size;
-       const bool shadow_reg_enable;
-       const bool no_idle_support;
-       const bool hd_v2;
-       const bool wd_disable;
-};
-/*
- * @advanced_bt_coexist: support advanced bt coexist
- * @bt_init_traffic_load: specify initial bt traffic load
- * @bt_prio_boost: default bt priority boost value
- * @agg_time_limit: maximum number of uSec in aggregation
- * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
- */
-struct iwl_bt_params {
-       bool advanced_bt_coexist;
-       u8 bt_init_traffic_load;
-       u8 bt_prio_boost;
-       u16 agg_time_limit;
-       bool bt_sco_disable;
-       bool bt_session_2;
-};
-/*
- * @use_rts_for_aggregation: use rts/cts protection for HT traffic
- */
-struct iwl_ht_params {
-       const bool ht_greenfield_support; /* if used set to true */
-       bool use_rts_for_aggregation;
-       enum ieee80211_smps_mode smps_mode;
-};
-
 /***************************
  *   L i b                 *
  ***************************/
@@ -169,7 +97,7 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                           int hw_decrypt);
 int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
+void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
                         struct iwl_rxon_context *ctx);
 void iwl_set_flags_for_band(struct iwl_priv *priv,
                            struct iwl_rxon_context *ctx,
@@ -197,6 +125,8 @@ const char *get_ctrl_string(int cmd);
 void iwl_clear_traffic_stats(struct iwl_priv *priv);
 void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc,
                      u16 len);
+void iwl_reset_traffic_log(struct iwl_priv *priv);
+
 #else
 static inline int iwl_alloc_traffic_mem(struct iwl_priv *priv)
 {
@@ -242,8 +172,6 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
 void iwl_force_scan_end(struct iwl_priv *priv);
 void iwl_internal_short_hw_scan(struct iwl_priv *priv);
 int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
-u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
-                      const u8 *ta, const u8 *ie, int ie_len, int left);
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
 void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
@@ -263,6 +191,10 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 
 #define IWL_SCAN_CHECK_WATCHDOG                (HZ * 7)
 
+/* traffic log definitions */
+#define IWL_TRAFFIC_ENTRIES    (256)
+#define IWL_TRAFFIC_ENTRY_SIZE  (64)
+
 /*****************************************************
  *   S e n d i n g     H o s t     C o m m a n d s   *
  *****************************************************/
@@ -297,12 +229,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
               cfg(priv)->bt_params->advanced_bt_coexist;
 }
 
-static inline void iwl_enable_rfkill_int(struct iwl_priv *priv)
-{
-       IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
-       iwl_write32(bus(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
-}
-
 extern bool bt_siso_mode;
 
 #endif /* __iwl_core_h__ */
index fbc3095c7b445b71f9ddf09bc15d3cf2fd308869..5f96ce105f08c1916abd41246a57b1ce610b3082 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c
new file mode 100644 (file)
index 0000000..059efab
--- /dev/null
@@ -0,0 +1,127 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+#include <linux/interrupt.h>
+#include "iwl-debug.h"
+
+#define __iwl_fn(fn)                                           \
+void __iwl_ ##fn(struct device *dev, const char *fmt, ...)     \
+{                                                              \
+       struct va_format vaf = {                                \
+               .fmt = fmt,                                     \
+       };                                                      \
+       va_list args;                                           \
+                                                               \
+       va_start(args, fmt);                                    \
+       vaf.va = &args;                                         \
+       dev_ ##fn(dev, "%pV", &vaf);                            \
+       trace_iwlwifi_ ##fn(&vaf);                              \
+       va_end(args);                                           \
+}
+
+__iwl_fn(warn)
+__iwl_fn(info)
+__iwl_fn(crit)
+
+void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
+               const char *fmt, ...)
+{
+       struct va_format vaf = {
+               .fmt = fmt,
+       };
+       va_list args;
+
+       va_start(args, fmt);
+       vaf.va = &args;
+       if (!trace_only) {
+               if (rfkill_prefix)
+                       dev_err(dev, "(RFKILL) %pV", &vaf);
+               else
+                       dev_err(dev, "%pV", &vaf);
+       }
+       trace_iwlwifi_err(&vaf);
+       va_end(args);
+}
+
+#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
+void __iwl_dbg(struct device *dev,
+              u32 level, bool limit, const char *function,
+              const char *fmt, ...)
+{
+       struct va_format vaf = {
+               .fmt = fmt,
+       };
+       va_list args;
+
+       va_start(args, fmt);
+       vaf.va = &args;
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (iwl_have_debug_level(level) &&
+           (!limit || net_ratelimit()))
+               dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U',
+                       function, &vaf);
+#endif
+       trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf);
+       va_end(args);
+}
+#endif
index f8fc2393dd4c15686755a702392dd936b963f95c..a6b32a11e103092fd11ce2d074034fca9e23d854 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
 #ifndef __iwl_debug_h__
 #define __iwl_debug_h__
 
-#include "iwl-bus.h"
 #include "iwl-shared.h"
+#include "iwl-devtrace.h"
 
 struct iwl_priv;
 
-/*No matter what is m (priv, bus, trans), this will work */
-#define IWL_ERR(m, f, a...) dev_err(bus(m)->dev, f, ## a)
-#define IWL_WARN(m, f, a...) dev_warn(bus(m)->dev, f, ## a)
-#define IWL_INFO(m, f, a...) dev_info(bus(m)->dev, f, ## a)
-#define IWL_CRIT(m, f, a...) dev_crit(bus(m)->dev, f, ## a)
+void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace,
+               const char *fmt, ...);
+void __iwl_warn(struct device *dev, const char *fmt, ...);
+void __iwl_info(struct device *dev, const char *fmt, ...);
+void __iwl_crit(struct device *dev, const char *fmt, ...);
+
+/* No matter what is m (priv, bus, trans), this will work */
+#define IWL_ERR(m, f, a...) __iwl_err(trans(m)->dev, false, false, f, ## a)
+#define IWL_WARN(m, f, a...) __iwl_warn(trans(m)->dev, f, ## a)
+#define IWL_INFO(m, f, a...) __iwl_info(trans(m)->dev, f, ## a)
+#define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a)
+
+#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
+void __iwl_dbg(struct device *dev,
+              u32 level, bool limit, const char *function,
+              const char *fmt, ...);
+#else
+static inline void
+__iwl_dbg(struct device *dev,
+         u32 level, bool limit, const char *function,
+         const char *fmt, ...)
+{}
+#endif
 
 #define iwl_print_hex_error(m, p, len)                                 \
 do {                                                                   \
@@ -46,54 +64,20 @@ do {                                                                        \
                       DUMP_PREFIX_OFFSET, 16, 1, p, len, 1);           \
 } while (0)
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-#define IWL_DEBUG(m, level, fmt, ...)                                  \
-do {                                                                   \
-       if (iwl_get_debug_level((m)->shrd) & (level))                   \
-               dev_err(bus(m)->dev, "%c %s " fmt,                      \
-                       in_interrupt() ? 'I' : 'U', __func__,           \
-                       ##__VA_ARGS__);                                 \
-} while (0)
-
-#define IWL_DEBUG_LIMIT(m, level, fmt, ...)                            \
-do {                                                                   \
-       if (iwl_get_debug_level((m)->shrd) & (level) &&                 \
-           net_ratelimit())                                            \
-               dev_err(bus(m)->dev, "%c %s " fmt,                      \
-                       in_interrupt() ? 'I' : 'U', __func__,           \
-                       ##__VA_ARGS__);                                 \
-} while (0)
+#define IWL_DEBUG(m, level, fmt, args...)                              \
+       __iwl_dbg(trans(m)->dev, level, false, __func__, fmt, ##args)
+#define IWL_DEBUG_LIMIT(m, level, fmt, args...)                                \
+       __iwl_dbg(trans(m)->dev, level, true, __func__, fmt, ##args)
 
+#ifdef CONFIG_IWLWIFI_DEBUG
 #define iwl_print_hex_dump(m, level, p, len)                           \
 do {                                                                   \
-       if (iwl_get_debug_level((m)->shrd) & level)                     \
+       if (iwl_have_debug_level(level))                                \
                print_hex_dump(KERN_DEBUG, "iwl data: ",                \
                               DUMP_PREFIX_OFFSET, 16, 1, p, len, 1);   \
 } while (0)
-
-#define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...)                            \
-do {                                                                   \
-       if (!iwl_is_rfkill(p->shrd))                                    \
-               dev_err(bus(p)->dev, "%s%c %s " fmt,                    \
-                       "",                                             \
-                       in_interrupt() ? 'I' : 'U', __func__,           \
-                       ##__VA_ARGS__);                                 \
-       else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO)           \
-               dev_err(bus(p)->dev, "%s%c %s " fmt,                    \
-                       "(RFKILL) ",                                    \
-                       in_interrupt() ? 'I' : 'U', __func__,           \
-                       ##__VA_ARGS__);                                 \
-} while (0)
-
 #else
-#define IWL_DEBUG(m, level, fmt, args...)
-#define IWL_DEBUG_LIMIT(m, level, fmt, args...)
 #define iwl_print_hex_dump(m, level, p, len)
-#define IWL_DEBUG_QUIET_RFKILL(p, fmt, args...)        \
-do {                                                   \
-       if (!iwl_is_rfkill(p->shrd))                    \
-               IWL_ERR(p, fmt, ##args);                \
-} while (0)
 #endif                         /* CONFIG_IWLWIFI_DEBUG */
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
index 04a3343f4610faf4e654b5232c2d0d29f6773c75..7a1334e8c3584cfedc6798b35d51a4ef9965e185 100644 (file)
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -234,12 +234,11 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
 
        /* default is to dump the entire data segment */
        if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
-               struct iwl_trans *trans = trans(priv);
                priv->dbgfs_sram_offset = 0x800000;
-               if (trans->shrd->ucode_type == IWL_UCODE_INIT)
-                       priv->dbgfs_sram_len = trans->ucode_init.data.len;
+               if (priv->shrd->ucode_type == IWL_UCODE_INIT)
+                       priv->dbgfs_sram_len = priv->fw->ucode_init.data.len;
                else
-                       priv->dbgfs_sram_len = trans->ucode_rt.data.len;
+                       priv->dbgfs_sram_len = priv->fw->ucode_rt.data.len;
        }
        len = priv->dbgfs_sram_len;
 
@@ -263,7 +262,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
        sram = priv->dbgfs_sram_offset & ~0x3;
 
        /* read the first u32 from sram */
-       val = iwl_read_targ_mem(bus(priv), sram);
+       val = iwl_read_targ_mem(trans(priv), sram);
 
        for (; len; len--) {
                /* put the address at the start of every line */
@@ -282,7 +281,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
                if (++offset == 4) {
                        sram += 4;
                        offset = 0;
-                       val = iwl_read_targ_mem(bus(priv), sram);
+                       val = iwl_read_targ_mem(trans(priv), sram);
                }
 
                /* put in extra spaces and split lines for human readability */
@@ -342,7 +341,7 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
 
        return simple_read_from_buffer(user_buf, count, ppos,
                                       priv->wowlan_sram,
-                                      trans(priv)->ucode_wowlan.data.len);
+                                      priv->fw->ucode_wowlan.data.len);
 }
 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
                                        size_t count, loff_t *ppos)
@@ -455,7 +454,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
        char *buf;
        ssize_t ret;
 
-       if (!test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status))
+       if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -526,32 +525,26 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
 
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
                test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status));
-       pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
-               test_bit(STATUS_INT_ENABLED, &priv->shrd->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
-               test_bit(STATUS_RF_KILL_HW, &priv->shrd->status));
+               test_bit(STATUS_RF_KILL_HW, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
-               test_bit(STATUS_CT_KILL, &priv->shrd->status));
-       pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
-               test_bit(STATUS_INIT, &priv->shrd->status));
+               test_bit(STATUS_CT_KILL, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
-               test_bit(STATUS_ALIVE, &priv->shrd->status));
+               test_bit(STATUS_ALIVE, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
-               test_bit(STATUS_READY, &priv->shrd->status));
-       pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
-               test_bit(STATUS_TEMPERATURE, &priv->shrd->status));
+               test_bit(STATUS_READY, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
-               test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status));
+               test_bit(STATUS_GEO_CONFIGURED, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
-               test_bit(STATUS_EXIT_PENDING, &priv->shrd->status));
+               test_bit(STATUS_EXIT_PENDING, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
-               test_bit(STATUS_STATISTICS, &priv->shrd->status));
+               test_bit(STATUS_STATISTICS, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
-               test_bit(STATUS_SCANNING, &priv->shrd->status));
+               test_bit(STATUS_SCANNING, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
-               test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status));
+               test_bit(STATUS_SCAN_ABORTING, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
-               test_bit(STATUS_SCAN_HW, &priv->shrd->status));
+               test_bit(STATUS_SCAN_HW, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
                test_bit(STATUS_POWER_PMI, &priv->shrd->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
@@ -757,14 +750,14 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
        if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
                return -EINVAL;
 
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return -EAGAIN;
 
        priv->power_data.debug_sleep_level_override = value;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_power_update_mode(priv, true);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        return count;
 }
@@ -844,8 +837,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
                IWL_ERR(priv, "Can not allocate buffer\n");
                return -ENOMEM;
        }
-       if (priv->tx_traffic &&
-               (iwl_get_debug_level(priv->shrd) & IWL_DL_TX)) {
+       if (priv->tx_traffic && iwl_have_debug_level(IWL_DL_TX)) {
                ptr = priv->tx_traffic;
                pos += scnprintf(buf + pos, bufsz - pos,
                                "Tx Traffic idx: %u\n", priv->tx_traffic_idx);
@@ -863,8 +855,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
                }
        }
 
-       if (priv->rx_traffic &&
-               (iwl_get_debug_level(priv->shrd) & IWL_DL_RX)) {
+       if (priv->rx_traffic && iwl_have_debug_level(IWL_DL_RX)) {
                ptr = priv->rx_traffic;
                pos += scnprintf(buf + pos, bufsz - pos,
                                "Rx Traffic idx: %u\n", priv->rx_traffic_idx);
@@ -919,6 +910,8 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
        int p = 0;
        u32 flag;
 
+       lockdep_assert_held(&priv->statistics.lock);
+
        flag = le32_to_cpu(priv->statistics.flag);
 
        p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
@@ -952,7 +945,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
        struct statistics_rx_non_phy *delta_general, *max_general;
        struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -966,6 +959,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
         * the last statistics notification from uCode
         * might not reflect the current uCode activity
         */
+       spin_lock_bh(&priv->statistics.lock);
        ofdm = &priv->statistics.rx_ofdm;
        cck = &priv->statistics.rx_cck;
        general = &priv->statistics.rx_non_phy;
@@ -1362,6 +1356,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
                         accum_ht->unsupport_mcs,
                         delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
 
+       spin_unlock_bh(&priv->statistics.lock);
+
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        kfree(buf);
        return ret;
@@ -1378,7 +1374,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
        ssize_t ret;
        struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -1391,6 +1387,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
         * the last statistics notification from uCode
         * might not reflect the current uCode activity
         */
+       spin_lock_bh(&priv->statistics.lock);
+
        tx = &priv->statistics.tx;
        accum_tx = &priv->accum_stats.tx;
        delta_tx = &priv->delta_stats.tx;
@@ -1540,19 +1538,25 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
        if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
                pos += scnprintf(buf + pos, bufsz - pos,
                        "tx power: (1/2 dB step)\n");
-               if ((cfg(priv)->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
+               if ((hw_params(priv).valid_tx_ant & ANT_A) &&
+                   tx->tx_power.ant_a)
                        pos += scnprintf(buf + pos, bufsz - pos,
                                        fmt_hex, "antenna A:",
                                        tx->tx_power.ant_a);
-               if ((cfg(priv)->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
+               if ((hw_params(priv).valid_tx_ant & ANT_B) &&
+                   tx->tx_power.ant_b)
                        pos += scnprintf(buf + pos, bufsz - pos,
                                        fmt_hex, "antenna B:",
                                        tx->tx_power.ant_b);
-               if ((cfg(priv)->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
+               if ((hw_params(priv).valid_tx_ant & ANT_C) &&
+                   tx->tx_power.ant_c)
                        pos += scnprintf(buf + pos, bufsz - pos,
                                        fmt_hex, "antenna C:",
                                        tx->tx_power.ant_c);
        }
+
+       spin_unlock_bh(&priv->statistics.lock);
+
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        kfree(buf);
        return ret;
@@ -1572,7 +1576,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
        struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
        struct statistics_div *div, *accum_div, *delta_div, *max_div;
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -1585,6 +1589,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
         * the last statistics notification from uCode
         * might not reflect the current uCode activity
         */
+
+       spin_lock_bh(&priv->statistics.lock);
+
        general = &priv->statistics.common;
        dbg = &priv->statistics.common.dbg;
        div = &priv->statistics.common.div;
@@ -1669,6 +1676,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
                         accum_general->num_of_sos_states,
                         delta_general->num_of_sos_states,
                         max_general->num_of_sos_states);
+
+       spin_unlock_bh(&priv->statistics.lock);
+
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        kfree(buf);
        return ret;
@@ -1685,16 +1695,16 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
        ssize_t ret;
        struct statistics_bt_activity *bt, *accum_bt;
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        if (!priv->bt_enable_flag)
                return -EINVAL;
 
        /* make request to uCode to retrieve statistics information */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        if (ret) {
                IWL_ERR(priv,
@@ -1712,6 +1722,9 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
         * the last statistics notification from uCode
         * might not reflect the current uCode activity
         */
+
+       spin_lock_bh(&priv->statistics.lock);
+
        bt = &priv->statistics.bt_activity;
        accum_bt = &priv->accum_stats.bt_activity;
 
@@ -1757,6 +1770,8 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
                         le32_to_cpu(priv->statistics.num_bt_kills),
                         priv->statistics.accum_num_bt_kills);
 
+       spin_unlock_bh(&priv->statistics.lock);
+
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        kfree(buf);
        return ret;
@@ -1773,7 +1788,7 @@ static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
                (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
        ssize_t ret;
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -2055,7 +2070,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
        const size_t bufsz = sizeof(buf);
        u32 pwrsave_status;
 
-       pwrsave_status = iwl_read32(bus(priv), CSR_GP_CNTRL) &
+       pwrsave_status = iwl_read32(trans(priv), CSR_GP_CNTRL) &
                        CSR_GP_REG_POWER_SAVE_STATUS_MSK;
 
        pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
@@ -2085,9 +2100,9 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
                return -EFAULT;
 
        /* make request to uCode to retrieve statistics information */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_send_statistics_request(priv, CMD_SYNC, true);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        return count;
 }
@@ -2131,9 +2146,10 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
 
        if (trace) {
                priv->event_log.ucode_trace = true;
-               /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
-               mod_timer(&priv->ucode_trace,
-                       jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
+               if (iwl_is_alive(priv)) {
+                       /* start collecting data now */
+                       mod_timer(&priv->ucode_trace, jiffies);
+               }
        } else {
                priv->event_log.ucode_trace = false;
                del_timer_sync(&priv->ucode_trace);
@@ -2219,7 +2235,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
        const size_t bufsz = sizeof(buf);
 
        pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
-                       cfg(priv)->base_params->plcp_delta_threshold);
+                       priv->plcp_delta_threshold);
 
        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
@@ -2241,10 +2257,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
                return -EINVAL;
        if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
                (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
-               cfg(priv)->base_params->plcp_delta_threshold =
+               priv->plcp_delta_threshold =
                        IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE;
        else
-               cfg(priv)->base_params->plcp_delta_threshold = plcp;
+               priv->plcp_delta_threshold = plcp;
        return count;
 }
 
@@ -2320,7 +2336,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
        if (sscanf(buf, "%d", &flush) != 1)
                return -EINVAL;
 
-       if (iwl_is_rfkill(priv->shrd))
+       if (iwl_is_rfkill(priv))
                return -EFAULT;
 
        iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
@@ -2346,7 +2362,7 @@ static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
        if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT)
                timeout = IWL_DEF_WD_TIMEOUT;
 
-       cfg(priv)->base_params->wd_timeout = timeout;
+       hw_params(priv).wd_timeout = timeout;
        iwl_setup_watchdog(priv);
        return count;
 }
@@ -2409,7 +2425,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
        if (cfg(priv)->ht_params)
                pos += scnprintf(buf + pos, bufsz - pos,
                         "use %s for aggregation\n",
-                        (cfg(priv)->ht_params->use_rts_for_aggregation) ?
+                        (hw_params(priv).use_rts_for_aggregation) ?
                                "rts/cts" : "cts-to-self");
        else
                pos += scnprintf(buf + pos, bufsz - pos, "N/A");
@@ -2436,9 +2452,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
        if (sscanf(buf, "%d", &rts) != 1)
                return -EINVAL;
        if (rts)
-               cfg(priv)->ht_params->use_rts_for_aggregation = true;
+               hw_params(priv).use_rts_for_aggregation = true;
        else
-               cfg(priv)->ht_params->use_rts_for_aggregation = false;
+               hw_params(priv).use_rts_for_aggregation = false;
        return count;
 }
 
@@ -2484,52 +2500,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
 DEBUGFS_READ_FILE_OPS(reply_tx_error);
 DEBUGFS_WRITE_FILE_OPS(echo_test);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static ssize_t iwl_dbgfs_debug_level_read(struct file *file,
-                                         char __user *user_buf,
-                                         size_t count, loff_t *ppos)
-{
-       struct iwl_priv *priv = file->private_data;
-       struct iwl_shared *shrd = priv->shrd;
-       char buf[11];
-       int len;
-
-       len = scnprintf(buf, sizeof(buf), "0x%.8x",
-                       iwl_get_debug_level(shrd));
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t iwl_dbgfs_debug_level_write(struct file *file,
-                                          const char __user *user_buf,
-                                          size_t count, loff_t *ppos)
-{
-       struct iwl_priv *priv = file->private_data;
-       struct iwl_shared *shrd = priv->shrd;
-       char buf[11];
-       unsigned long val;
-       int ret;
-
-       if (count > sizeof(buf))
-               return -EINVAL;
-
-       memset(buf, 0, sizeof(buf));
-       if (copy_from_user(buf, user_buf, count))
-               return -EFAULT;
-
-       ret = strict_strtoul(buf, 0, &val);
-       if (ret)
-               return ret;
-
-       shrd->dbg_level_dev = val;
-       if (iwl_alloc_traffic_mem(priv))
-               IWL_ERR(priv, "Not enough memory to generate traffic log\n");
-
-       return count;
-}
-DEBUGFS_READ_WRITE_FILE_OPS(debug_level);
-#endif /* CONFIG_IWLWIFI_DEBUG */
-
 /*
  * Create the debugfs files and directories
  *
@@ -2594,9 +2564,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
        DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR);
        if (iwl_advanced_bt_coexist(priv))
                DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
-#ifdef CONFIG_IWLWIFI_DEBUG
-       DEBUGFS_ADD_FILE(debug_level, dir_debug, S_IRUSR | S_IWUSR);
-#endif
 
        DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
                         &priv->disable_sens_cal);
index e54a4d11e5845316bbb2b1067b9e958e35b0dbaf..aa4b3b122da4d5a08e2f754409802181b81ebba0 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
 #include <linux/wait.h>
 #include <linux/leds.h>
 #include <linux/slab.h>
-#include <net/ieee80211_radiotap.h>
+#include <linux/mutex.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-csr.h"
-#include "iwl-prph.h"
 #include "iwl-debug.h"
 #include "iwl-agn-hw.h"
 #include "iwl-led.h"
 #include "iwl-power.h"
 #include "iwl-agn-rs.h"
 #include "iwl-agn-tt.h"
-#include "iwl-bus.h"
 #include "iwl-trans.h"
 #include "iwl-shared.h"
+#include "iwl-op-mode.h"
+#include "iwl-notif-wait.h"
 
 struct iwl_tx_queue;
 
@@ -292,117 +292,8 @@ struct iwl_vif_priv {
        u8 ibss_bssid_sta_id;
 };
 
-/* v1/v2 uCode file layout */
-struct iwl_ucode_header {
-       __le32 ver;     /* major/minor/API/serial */
-       union {
-               struct {
-                       __le32 inst_size;       /* bytes of runtime code */
-                       __le32 data_size;       /* bytes of runtime data */
-                       __le32 init_size;       /* bytes of init code */
-                       __le32 init_data_size;  /* bytes of init data */
-                       __le32 boot_size;       /* bytes of bootstrap code */
-                       u8 data[0];             /* in same order as sizes */
-               } v1;
-               struct {
-                       __le32 build;           /* build number */
-                       __le32 inst_size;       /* bytes of runtime code */
-                       __le32 data_size;       /* bytes of runtime data */
-                       __le32 init_size;       /* bytes of init code */
-                       __le32 init_data_size;  /* bytes of init data */
-                       __le32 boot_size;       /* bytes of bootstrap code */
-                       u8 data[0];             /* in same order as sizes */
-               } v2;
-       } u;
-};
-
-/*
- * new TLV uCode file layout
- *
- * The new TLV file format contains TLVs, that each specify
- * some piece of data. To facilitate "groups", for example
- * different instruction image with different capabilities,
- * bundled with the same init image, an alternative mechanism
- * is provided:
- * When the alternative field is 0, that means that the item
- * is always valid. When it is non-zero, then it is only
- * valid in conjunction with items of the same alternative,
- * in which case the driver (user) selects one alternative
- * to use.
- */
-
-enum iwl_ucode_tlv_type {
-       IWL_UCODE_TLV_INVALID           = 0, /* unused */
-       IWL_UCODE_TLV_INST              = 1,
-       IWL_UCODE_TLV_DATA              = 2,
-       IWL_UCODE_TLV_INIT              = 3,
-       IWL_UCODE_TLV_INIT_DATA         = 4,
-       IWL_UCODE_TLV_BOOT              = 5,
-       IWL_UCODE_TLV_PROBE_MAX_LEN     = 6, /* a u32 value */
-       IWL_UCODE_TLV_PAN               = 7,
-       IWL_UCODE_TLV_RUNT_EVTLOG_PTR   = 8,
-       IWL_UCODE_TLV_RUNT_EVTLOG_SIZE  = 9,
-       IWL_UCODE_TLV_RUNT_ERRLOG_PTR   = 10,
-       IWL_UCODE_TLV_INIT_EVTLOG_PTR   = 11,
-       IWL_UCODE_TLV_INIT_EVTLOG_SIZE  = 12,
-       IWL_UCODE_TLV_INIT_ERRLOG_PTR   = 13,
-       IWL_UCODE_TLV_ENHANCE_SENS_TBL  = 14,
-       IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
-       IWL_UCODE_TLV_WOWLAN_INST       = 16,
-       IWL_UCODE_TLV_WOWLAN_DATA       = 17,
-       IWL_UCODE_TLV_FLAGS             = 18,
-};
-
-/**
- * enum iwl_ucode_tlv_flag - ucode API flags
- * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
- *     was a separate TLV but moved here to save space.
- * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
- *     treats good CRC threshold as a boolean
- * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
- * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
- */
-enum iwl_ucode_tlv_flag {
-       IWL_UCODE_TLV_FLAGS_PAN         = BIT(0),
-       IWL_UCODE_TLV_FLAGS_NEWSCAN     = BIT(1),
-       IWL_UCODE_TLV_FLAGS_MFP         = BIT(2),
-       IWL_UCODE_TLV_FLAGS_P2P         = BIT(3),
-};
-
-struct iwl_ucode_tlv {
-       __le16 type;            /* see above */
-       __le16 alternative;     /* see comment */
-       __le32 length;          /* not including type/length fields */
-       u8 data[0];
-} __packed;
-
-#define IWL_TLV_UCODE_MAGIC    0x0a4c5749
-
-struct iwl_tlv_ucode_header {
-       /*
-        * The TLV style ucode header is distinguished from
-        * the v1/v2 style header by first four bytes being
-        * zero, as such is an invalid combination of
-        * major/minor/API/serial versions.
-        */
-       __le32 zero;
-       __le32 magic;
-       u8 human_readable[64];
-       __le32 ver;             /* major/minor/API/serial */
-       __le32 build;
-       __le64 alternatives;    /* bitmask of valid alternatives */
-       /*
-        * The data contained herein has a TLV layout,
-        * see above for the TLV header and types.
-        * Note that each TLV is padded to a length
-        * that is a multiple of 4 for alignment.
-        */
-       u8 data[0];
-};
-
 struct iwl_sensitivity_ranges {
        u16 min_nrg_cck;
-       u16 max_nrg_cck;
 
        u16 nrg_th_cck;
        u16 nrg_th_ofdm;
@@ -550,9 +441,6 @@ struct iwl_chain_noise_data {
        u8 state;
 };
 
-#define        EEPROM_SEM_TIMEOUT 10           /* milliseconds */
-#define EEPROM_SEM_RETRY_LIMIT 1000    /* number of attempts (not time) */
-
 enum {
        MEASUREMENT_READY = (1 << 0),
        MEASUREMENT_ACTIVE = (1 << 1),
@@ -661,7 +549,7 @@ struct traffic_stats {
  * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
  * to perform continuous uCode event logging operation if enabled
  */
-#define UCODE_TRACE_PERIOD (100)
+#define UCODE_TRACE_PERIOD (10)
 
 /*
  * iwl_event_log: current uCode event log position
@@ -781,11 +669,6 @@ struct iwl_rxon_context {
                bool enabled, is_40mhz;
                u8 extension_chan_offset;
        } ht;
-
-       u8 bssid[ETH_ALEN];
-       bool preauth_bssid;
-
-       bool last_tx_rejected;
 };
 
 enum iwl_scan_type {
@@ -804,11 +687,11 @@ struct iwl_testmode_trace {
        dma_addr_t dma_addr;
        bool trace_enabled;
 };
-struct iwl_testmode_sram {
+struct iwl_testmode_mem {
        u32 buff_size;
        u32 num_chunks;
        u8 *buff_addr;
-       bool sram_readed;
+       bool read_in_progress;
 };
 #endif
 
@@ -818,32 +701,55 @@ struct iwl_wipan_noa_data {
        u8 data[];
 };
 
+#define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \
+       ((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific))
+
+#define IWL_MAC80211_GET_DVM(_hw) \
+       ((struct iwl_priv *) ((struct iwl_op_mode *) \
+       (_hw)->priv)->op_mode_specific)
+
 struct iwl_priv {
 
        /*data shared among all the driver's layers */
-       struct iwl_shared _shrd;
        struct iwl_shared *shrd;
+       const struct iwl_fw *fw;
+       unsigned long status;
+
+       spinlock_t sta_lock;
+       struct mutex mutex;
+
+       unsigned long transport_queue_stop;
+       bool passive_no_rx;
 
        /* ieee device used by generic ieee processing code */
        struct ieee80211_hw *hw;
        struct ieee80211_channel *ieee_channels;
        struct ieee80211_rate *ieee_rates;
-       struct kmem_cache *tx_cmd_pool;
+
+       struct list_head calib_results;
+
+       struct workqueue_struct *workqueue;
 
        enum ieee80211_band band;
 
        void (*pre_rx_handler)(struct iwl_priv *priv,
-                              struct iwl_rx_mem_buffer *rxb);
+                              struct iwl_rx_cmd_buffer *rxb);
        int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb,
+                                      struct iwl_rx_cmd_buffer *rxb,
                                       struct iwl_device_cmd *cmd);
 
+       struct iwl_notif_wait_data notif_wait;
+
        struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
 
        /* spectrum measurement report caching */
        struct iwl_spectrum_notification measure_report;
        u8 measurement_status;
 
+#define IWL_OWNERSHIP_DRIVER   0
+#define IWL_OWNERSHIP_TM       1
+       u8 ucode_owner;
+
        /* ucode beacon time */
        u32 ucode_beacon_time;
        int missed_beacon_threshold;
@@ -869,6 +775,8 @@ struct iwl_priv {
        struct iwl_channel_info *channel_info;  /* channel info array */
        u8 channel_count;       /* # of channels */
 
+       u8 plcp_delta_threshold;
+
        /* thermal calibration */
        s32 temperature;        /* Celsius */
        s32 last_temperature;
@@ -891,16 +799,11 @@ struct iwl_priv {
 
        bool new_scan_threshold_behaviour;
 
+       bool wowlan;
+
        /* EEPROM MAC addresses */
        struct mac_address addresses[2];
 
-       /* uCode images, save to reload in case of failure */
-       int fw_index;                   /* firmware we're trying to load */
-       u32 ucode_ver;                  /* version of ucode, copy of
-                                          iwl_ucode.ver */
-
-       char firmware_name[25];
-
        struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
 
        __le16 switch_channel;
@@ -910,7 +813,6 @@ struct iwl_priv {
        u8 start_calib;
        struct iwl_sensitivity_data sensitivity_data;
        struct iwl_chain_noise_data chain_noise_data;
-       bool enhance_sensitivity_table;
        __le16 sensitivity_tbl[HD_TABLE_SIZE];
        __le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES];
 
@@ -956,6 +858,7 @@ struct iwl_priv {
                struct statistics_bt_activity bt_activity;
                __le32 num_bt_kills, accum_num_bt_kills;
 #endif
+               spinlock_t lock;
        } statistics;
 #ifdef CONFIG_IWLWIFI_DEBUGFS
        struct {
@@ -978,11 +881,6 @@ struct iwl_priv {
        struct iwl_rx_phy_res last_phy_res;
        bool last_phy_res_valid;
 
-       struct completion firmware_loading_complete;
-
-       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
-       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
-
        /*
         * chain noise reset and gain commands are the
         * two extra calibration commands follows the standard
@@ -1073,7 +971,7 @@ struct iwl_priv {
        bool led_registered;
 #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
        struct iwl_testmode_trace testmode_trace;
-       struct iwl_testmode_sram testmode_sram;
+       struct iwl_testmode_mem testmode_mem;
        u32 tm_fixed_rate;
 #endif
 
@@ -1084,6 +982,7 @@ struct iwl_priv {
        bool have_rekey_data;
 }; /*iwl_priv */
 
+extern struct kmem_cache *iwl_tx_cmd_pool;
 extern struct iwl_mod_params iwlagn_mod_params;
 
 static inline struct iwl_rxon_context *
index 2a2c8de64a04d135052d2e8ec421f2aebbd8553d..91f45e71e0a2568498e60f01003f8c79e27670f7 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 9b212a8f30bb8789bb4bd5c214e7841bd4672cf7..06203d6a1d86fe50c38c590ded15954aa0ab0c04 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
 #undef TRACE_EVENT
 #define TRACE_EVENT(name, proto, ...) \
 static inline void trace_ ## name(proto) {}
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(...)
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(evt_class, name, proto, ...) \
+static inline void trace_ ## name(proto) {}
 #endif
 
-#define PRIV_ENTRY     __field(void *, priv)
-#define PRIV_ASSIGN    __entry->priv = priv
+#define DEV_ENTRY      __string(dev, dev_name(dev))
+#define DEV_ASSIGN     __assign_str(dev, dev_name(dev))
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM iwlwifi_io
 
 TRACE_EVENT(iwlwifi_dev_ioread32,
-       TP_PROTO(void *priv, u32 offs, u32 val),
-       TP_ARGS(priv, offs, val),
+       TP_PROTO(const struct device *dev, u32 offs, u32 val),
+       TP_ARGS(dev, offs, val),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __field(u32, offs)
                __field(u32, val)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->offs = offs;
                __entry->val = val;
        ),
-       TP_printk("[%p] read io[%#x] = %#x", __entry->priv, __entry->offs, __entry->val)
+       TP_printk("[%s] read io[%#x] = %#x",
+                 __get_str(dev), __entry->offs, __entry->val)
 );
 
 TRACE_EVENT(iwlwifi_dev_iowrite8,
-       TP_PROTO(void *priv, u32 offs, u8 val),
-       TP_ARGS(priv, offs, val),
+       TP_PROTO(const struct device *dev, u32 offs, u8 val),
+       TP_ARGS(dev, offs, val),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __field(u32, offs)
                __field(u8, val)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->offs = offs;
                __entry->val = val;
        ),
-       TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val)
+       TP_printk("[%s] write io[%#x] = %#x)",
+                 __get_str(dev), __entry->offs, __entry->val)
 );
 
 TRACE_EVENT(iwlwifi_dev_iowrite32,
-       TP_PROTO(void *priv, u32 offs, u32 val),
-       TP_ARGS(priv, offs, val),
+       TP_PROTO(const struct device *dev, u32 offs, u32 val),
+       TP_ARGS(dev, offs, val),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __field(u32, offs)
                __field(u32, val)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->offs = offs;
                __entry->val = val;
        ),
-       TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val)
+       TP_printk("[%s] write io[%#x] = %#x)",
+                 __get_str(dev), __entry->offs, __entry->val)
 );
 
 TRACE_EVENT(iwlwifi_dev_irq,
-       TP_PROTO(void *priv),
-       TP_ARGS(priv),
+       TP_PROTO(const struct device *dev),
+       TP_ARGS(dev),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
        ),
        /* TP_printk("") doesn't compile */
        TP_printk("%d", 0)
 );
 
 TRACE_EVENT(iwlwifi_dev_ict_read,
-       TP_PROTO(void *priv, u32 index, u32 value),
-       TP_ARGS(priv, index, value),
+       TP_PROTO(const struct device *dev, u32 index, u32 value),
+       TP_ARGS(dev, index, value),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __field(u32, index)
                __field(u32, value)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->index = index;
                __entry->value = value;
        ),
-       TP_printk("read ict[%d] = %#.8x", __entry->index, __entry->value)
+       TP_printk("[%s] read ict[%d] = %#.8x",
+                 __get_str(dev), __entry->index, __entry->value)
 );
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM iwlwifi_ucode
 
 TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
-       TP_PROTO(void *priv, u32 time, u32 data, u32 ev),
-       TP_ARGS(priv, time, data, ev),
+       TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev),
+       TP_ARGS(dev, time, data, ev),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
 
                __field(u32, time)
                __field(u32, data)
                __field(u32, ev)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->time = time;
                __entry->data = data;
                __entry->ev = ev;
        ),
-       TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u",
-                 __entry->priv, __entry->time, __entry->data, __entry->ev)
+       TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u",
+                 __get_str(dev), __entry->time, __entry->data, __entry->ev)
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
-       TP_PROTO(void *priv, u32 wraps, u32 n_entry, u32 p_entry),
-       TP_ARGS(priv, wraps, n_entry, p_entry),
+       TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry),
+       TP_ARGS(dev, wraps, n_entry, p_entry),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
 
                __field(u32, wraps)
                __field(u32, n_entry)
                __field(u32, p_entry)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->wraps = wraps;
                __entry->n_entry = n_entry;
                __entry->p_entry = p_entry;
        ),
-       TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X",
-                 __entry->priv, __entry->wraps, __entry->n_entry,
+       TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X",
+                 __get_str(dev), __entry->wraps, __entry->n_entry,
                  __entry->p_entry)
 );
 
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM iwlwifi_msg
+
+#define MAX_MSG_LEN    100
+
+DECLARE_EVENT_CLASS(iwlwifi_msg_event,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf),
+       TP_STRUCT__entry(
+               __dynamic_array(char, msg, MAX_MSG_LEN)
+       ),
+       TP_fast_assign(
+               WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+                                      MAX_MSG_LEN, vaf->fmt,
+                                      *vaf->va) >= MAX_MSG_LEN);
+       ),
+       TP_printk("%s", (char *)__get_dynamic_array(msg))
+);
+
+DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf)
+);
+
+TRACE_EVENT(iwlwifi_dbg,
+       TP_PROTO(u32 level, bool in_interrupt, const char *function,
+                struct va_format *vaf),
+       TP_ARGS(level, in_interrupt, function, vaf),
+       TP_STRUCT__entry(
+               __field(u32, level)
+               __field(u8, in_interrupt)
+               __string(function, function)
+               __dynamic_array(char, msg, MAX_MSG_LEN)
+       ),
+       TP_fast_assign(
+               __entry->level = level;
+               __entry->in_interrupt = in_interrupt;
+               __assign_str(function, function);
+               WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+                                      MAX_MSG_LEN, vaf->fmt,
+                                      *vaf->va) >= MAX_MSG_LEN);
+       ),
+       TP_printk("%s", (char *)__get_dynamic_array(msg))
+);
+
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM iwlwifi
 
 TRACE_EVENT(iwlwifi_dev_hcmd,
-       TP_PROTO(void *priv, u32 flags,
+       TP_PROTO(const struct device *dev, u32 flags,
                 const void *hcmd0, size_t len0,
                 const void *hcmd1, size_t len1,
                 const void *hcmd2, size_t len2),
-       TP_ARGS(priv, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2),
+       TP_ARGS(dev, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __dynamic_array(u8, hcmd0, len0)
                __dynamic_array(u8, hcmd1, len1)
                __dynamic_array(u8, hcmd2, len2)
                __field(u32, flags)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                memcpy(__get_dynamic_array(hcmd0), hcmd0, len0);
                memcpy(__get_dynamic_array(hcmd1), hcmd1, len1);
                memcpy(__get_dynamic_array(hcmd2), hcmd2, len2);
                __entry->flags = flags;
        ),
-       TP_printk("[%p] hcmd %#.2x (%ssync)",
-                 __entry->priv, ((u8 *)__get_dynamic_array(hcmd0))[0],
+       TP_printk("[%s] hcmd %#.2x (%ssync)",
+                 __get_str(dev), ((u8 *)__get_dynamic_array(hcmd0))[0],
                  __entry->flags & CMD_ASYNC ? "a" : "")
 );
 
 TRACE_EVENT(iwlwifi_dev_rx,
-       TP_PROTO(void *priv, void *rxbuf, size_t len),
-       TP_ARGS(priv, rxbuf, len),
+       TP_PROTO(const struct device *dev, void *rxbuf, size_t len),
+       TP_ARGS(dev, rxbuf, len),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __dynamic_array(u8, rxbuf, len)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                memcpy(__get_dynamic_array(rxbuf), rxbuf, len);
        ),
-       TP_printk("[%p] RX cmd %#.2x",
-                 __entry->priv, ((u8 *)__get_dynamic_array(rxbuf))[4])
+       TP_printk("[%s] RX cmd %#.2x",
+                 __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4])
 );
 
 TRACE_EVENT(iwlwifi_dev_tx,
-       TP_PROTO(void *priv, void *tfd, size_t tfdlen,
+       TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen,
                 void *buf0, size_t buf0_len,
                 void *buf1, size_t buf1_len),
-       TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
+       TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
 
                __field(size_t, framelen)
                __dynamic_array(u8, tfd, tfdlen)
@@ -226,29 +295,28 @@ TRACE_EVENT(iwlwifi_dev_tx,
                __dynamic_array(u8, buf1, buf1_len)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->framelen = buf0_len + buf1_len;
                memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
                memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
                memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
        ),
-       TP_printk("[%p] TX %.2x (%zu bytes)",
-                 __entry->priv,
-                 ((u8 *)__get_dynamic_array(buf0))[0],
+       TP_printk("[%s] TX %.2x (%zu bytes)",
+                 __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
                  __entry->framelen)
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_error,
-       TP_PROTO(void *priv, u32 desc, u32 tsf_low,
+       TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low,
                 u32 data1, u32 data2, u32 line, u32 blink1,
                 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
                 u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver,
                 u32 brd_ver),
-       TP_ARGS(priv, desc, tsf_low, data1, data2, line,
+       TP_ARGS(dev, desc, tsf_low, data1, data2, line,
                blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
                gp3, ucode_ver, hw_ver, brd_ver),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __field(u32, desc)
                __field(u32, tsf_low)
                __field(u32, data1)
@@ -267,7 +335,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
                __field(u32, brd_ver)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->desc = desc;
                __entry->tsf_low = tsf_low;
                __entry->data1 = data1;
@@ -285,11 +353,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
                __entry->hw_ver = hw_ver;
                __entry->brd_ver = brd_ver;
        ),
-       TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, "
+       TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, "
                  "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
                  "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X "
                  "hw 0x%08X brd 0x%08X",
-                 __entry->priv, __entry->desc, __entry->tsf_low,
+                 __get_str(dev), __entry->desc, __entry->tsf_low,
                  __entry->data1,
                  __entry->data2, __entry->line, __entry->blink1,
                  __entry->blink2, __entry->ilink1, __entry->ilink2,
@@ -299,23 +367,23 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_event,
-       TP_PROTO(void *priv, u32 time, u32 data, u32 ev),
-       TP_ARGS(priv, time, data, ev),
+       TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev),
+       TP_ARGS(dev, time, data, ev),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
 
                __field(u32, time)
                __field(u32, data)
                __field(u32, ev)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->time = time;
                __entry->data = data;
                __entry->ev = ev;
        ),
-       TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u",
-                 __entry->priv, __entry->time, __entry->data, __entry->ev)
+       TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u",
+                 __get_str(dev), __entry->time, __entry->data, __entry->ev)
 );
 #endif /* __IWLWIFI_DEVICE_TRACE */
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
new file mode 100644 (file)
index 0000000..29a3ae4
--- /dev/null
@@ -0,0 +1,763 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#include <linux/completion.h>
+#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
+#include <linux/module.h>
+
+#include "iwl-drv.h"
+#include "iwl-trans.h"
+#include "iwl-shared.h"
+#include "iwl-op-mode.h"
+
+/* private includes */
+#include "iwl-fw-file.h"
+
+/**
+ * struct iwl_drv - drv common data
+ * @fw: the iwl_fw structure
+ * @shrd: pointer to common shared structure
+ * @op_mode: the running op_mode
+ * @fw_index: firmware revision to try loading
+ * @firmware_name: composite filename of ucode file to load
+ * @request_firmware_complete: the firmware has been obtained from user space
+ */
+struct iwl_drv {
+       struct iwl_fw fw;
+
+       struct iwl_shared *shrd;
+       struct iwl_op_mode *op_mode;
+
+       int fw_index;                   /* firmware we're trying to load */
+       char firmware_name[25];         /* name of firmware file to load */
+
+       struct completion request_firmware_complete;
+};
+
+
+
+static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)
+{
+       if (desc->v_addr)
+               dma_free_coherent(trans(drv)->dev, desc->len,
+                                 desc->v_addr, desc->p_addr);
+       desc->v_addr = NULL;
+       desc->len = 0;
+}
+
+static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img)
+{
+       iwl_free_fw_desc(drv, &img->code);
+       iwl_free_fw_desc(drv, &img->data);
+}
+
+static void iwl_dealloc_ucode(struct iwl_drv *drv)
+{
+       iwl_free_fw_img(drv, &drv->fw.ucode_rt);
+       iwl_free_fw_img(drv, &drv->fw.ucode_init);
+       iwl_free_fw_img(drv, &drv->fw.ucode_wowlan);
+}
+
+static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc,
+                     const void *data, size_t len)
+{
+       if (!len) {
+               desc->v_addr = NULL;
+               return -EINVAL;
+       }
+
+       desc->v_addr = dma_alloc_coherent(trans(drv)->dev, len,
+                                         &desc->p_addr, GFP_KERNEL);
+       if (!desc->v_addr)
+               return -ENOMEM;
+
+       desc->len = len;
+       memcpy(desc->v_addr, data, len);
+       return 0;
+}
+
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
+
+#define UCODE_EXPERIMENTAL_INDEX       100
+#define UCODE_EXPERIMENTAL_TAG         "exp"
+
+static int iwl_request_firmware(struct iwl_drv *drv, bool first)
+{
+       const struct iwl_cfg *cfg = cfg(drv);
+       const char *name_pre = cfg->fw_name_pre;
+       char tag[8];
+
+       if (first) {
+#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
+               drv->fw_index = UCODE_EXPERIMENTAL_INDEX;
+               strcpy(tag, UCODE_EXPERIMENTAL_TAG);
+       } else if (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) {
+#endif
+               drv->fw_index = cfg->ucode_api_max;
+               sprintf(tag, "%d", drv->fw_index);
+       } else {
+               drv->fw_index--;
+               sprintf(tag, "%d", drv->fw_index);
+       }
+
+       if (drv->fw_index < cfg->ucode_api_min) {
+               IWL_ERR(drv, "no suitable firmware found!\n");
+               return -ENOENT;
+       }
+
+       sprintf(drv->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
+
+       IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n",
+                      (drv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+                               ? "EXPERIMENTAL " : "",
+                      drv->firmware_name);
+
+       return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name,
+                                      trans(drv)->dev,
+                                      GFP_KERNEL, drv, iwl_ucode_callback);
+}
+
+struct iwlagn_firmware_pieces {
+       const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data;
+       size_t inst_size, data_size, init_size, init_data_size,
+              wowlan_inst_size, wowlan_data_size;
+
+       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
+       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
+};
+
+static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
+                                      const struct firmware *ucode_raw,
+                                      struct iwlagn_firmware_pieces *pieces)
+{
+       struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
+       u32 api_ver, hdr_size, build;
+       char buildstr[25];
+       const u8 *src;
+
+       drv->fw.ucode_ver = le32_to_cpu(ucode->ver);
+       api_ver = IWL_UCODE_API(drv->fw.ucode_ver);
+
+       switch (api_ver) {
+       default:
+               hdr_size = 28;
+               if (ucode_raw->size < hdr_size) {
+                       IWL_ERR(drv, "File size too small!\n");
+                       return -EINVAL;
+               }
+               build = le32_to_cpu(ucode->u.v2.build);
+               pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
+               pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
+               pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
+               pieces->init_data_size =
+                       le32_to_cpu(ucode->u.v2.init_data_size);
+               src = ucode->u.v2.data;
+               break;
+       case 0:
+       case 1:
+       case 2:
+               hdr_size = 24;
+               if (ucode_raw->size < hdr_size) {
+                       IWL_ERR(drv, "File size too small!\n");
+                       return -EINVAL;
+               }
+               build = 0;
+               pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size);
+               pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
+               pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
+               pieces->init_data_size =
+                       le32_to_cpu(ucode->u.v1.init_data_size);
+               src = ucode->u.v1.data;
+               break;
+       }
+
+       if (build)
+               sprintf(buildstr, " build %u%s", build,
+                      (drv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+                               ? " (EXP)" : "");
+       else
+               buildstr[0] = '\0';
+
+       snprintf(drv->fw.fw_version,
+                sizeof(drv->fw.fw_version),
+                "%u.%u.%u.%u%s",
+                IWL_UCODE_MAJOR(drv->fw.ucode_ver),
+                IWL_UCODE_MINOR(drv->fw.ucode_ver),
+                IWL_UCODE_API(drv->fw.ucode_ver),
+                IWL_UCODE_SERIAL(drv->fw.ucode_ver),
+                buildstr);
+
+       /* Verify size of file vs. image size info in file's header */
+       if (ucode_raw->size != hdr_size + pieces->inst_size +
+                               pieces->data_size + pieces->init_size +
+                               pieces->init_data_size) {
+
+               IWL_ERR(drv,
+                       "uCode file size %d does not match expected size\n",
+                       (int)ucode_raw->size);
+               return -EINVAL;
+       }
+
+       pieces->inst = src;
+       src += pieces->inst_size;
+       pieces->data = src;
+       src += pieces->data_size;
+       pieces->init = src;
+       src += pieces->init_size;
+       pieces->init_data = src;
+       src += pieces->init_data_size;
+
+       return 0;
+}
+
+static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
+                               const struct firmware *ucode_raw,
+                               struct iwlagn_firmware_pieces *pieces,
+                               struct iwl_ucode_capabilities *capa)
+{
+       struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
+       struct iwl_ucode_tlv *tlv;
+       size_t len = ucode_raw->size;
+       const u8 *data;
+       int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative;
+       int tmp;
+       u64 alternatives;
+       u32 tlv_len;
+       enum iwl_ucode_tlv_type tlv_type;
+       const u8 *tlv_data;
+       char buildstr[25];
+       u32 build;
+
+       if (len < sizeof(*ucode)) {
+               IWL_ERR(drv, "uCode has invalid length: %zd\n", len);
+               return -EINVAL;
+       }
+
+       if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
+               IWL_ERR(drv, "invalid uCode magic: 0X%x\n",
+                       le32_to_cpu(ucode->magic));
+               return -EINVAL;
+       }
+
+       /*
+        * Check which alternatives are present, and "downgrade"
+        * when the chosen alternative is not present, warning
+        * the user when that happens. Some files may not have
+        * any alternatives, so don't warn in that case.
+        */
+       alternatives = le64_to_cpu(ucode->alternatives);
+       tmp = wanted_alternative;
+       if (wanted_alternative > 63)
+               wanted_alternative = 63;
+       while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
+               wanted_alternative--;
+       if (wanted_alternative && wanted_alternative != tmp)
+               IWL_WARN(drv,
+                        "uCode alternative %d not available, choosing %d\n",
+                        tmp, wanted_alternative);
+
+       drv->fw.ucode_ver = le32_to_cpu(ucode->ver);
+       build = le32_to_cpu(ucode->build);
+
+       if (build)
+               sprintf(buildstr, " build %u%s", build,
+                      (drv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+                               ? " (EXP)" : "");
+       else
+               buildstr[0] = '\0';
+
+       snprintf(drv->fw.fw_version,
+                sizeof(drv->fw.fw_version),
+                "%u.%u.%u.%u%s",
+                IWL_UCODE_MAJOR(drv->fw.ucode_ver),
+                IWL_UCODE_MINOR(drv->fw.ucode_ver),
+                IWL_UCODE_API(drv->fw.ucode_ver),
+                IWL_UCODE_SERIAL(drv->fw.ucode_ver),
+                buildstr);
+
+       data = ucode->data;
+
+       len -= sizeof(*ucode);
+
+       while (len >= sizeof(*tlv)) {
+               u16 tlv_alt;
+
+               len -= sizeof(*tlv);
+               tlv = (void *)data;
+
+               tlv_len = le32_to_cpu(tlv->length);
+               tlv_type = le16_to_cpu(tlv->type);
+               tlv_alt = le16_to_cpu(tlv->alternative);
+               tlv_data = tlv->data;
+
+               if (len < tlv_len) {
+                       IWL_ERR(drv, "invalid TLV len: %zd/%u\n",
+                               len, tlv_len);
+                       return -EINVAL;
+               }
+               len -= ALIGN(tlv_len, 4);
+               data += sizeof(*tlv) + ALIGN(tlv_len, 4);
+
+               /*
+                * Alternative 0 is always valid.
+                *
+                * Skip alternative TLVs that are not selected.
+                */
+               if (tlv_alt != 0 && tlv_alt != wanted_alternative)
+                       continue;
+
+               switch (tlv_type) {
+               case IWL_UCODE_TLV_INST:
+                       pieces->inst = tlv_data;
+                       pieces->inst_size = tlv_len;
+                       break;
+               case IWL_UCODE_TLV_DATA:
+                       pieces->data = tlv_data;
+                       pieces->data_size = tlv_len;
+                       break;
+               case IWL_UCODE_TLV_INIT:
+                       pieces->init = tlv_data;
+                       pieces->init_size = tlv_len;
+                       break;
+               case IWL_UCODE_TLV_INIT_DATA:
+                       pieces->init_data = tlv_data;
+                       pieces->init_data_size = tlv_len;
+                       break;
+               case IWL_UCODE_TLV_BOOT:
+                       IWL_ERR(drv, "Found unexpected BOOT ucode\n");
+                       break;
+               case IWL_UCODE_TLV_PROBE_MAX_LEN:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       capa->max_probe_length =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_PAN:
+                       if (tlv_len)
+                               goto invalid_tlv_len;
+                       capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
+                       break;
+               case IWL_UCODE_TLV_FLAGS:
+                       /* must be at least one u32 */
+                       if (tlv_len < sizeof(u32))
+                               goto invalid_tlv_len;
+                       /* and a proper number of u32s */
+                       if (tlv_len % sizeof(u32))
+                               goto invalid_tlv_len;
+                       /*
+                        * This driver only reads the first u32 as
+                        * right now no more features are defined,
+                        * if that changes then either the driver
+                        * will not work with the new firmware, or
+                        * it'll not take advantage of new features.
+                        */
+                       capa->flags = le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->init_evtlog_ptr =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->init_evtlog_size =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->init_errlog_ptr =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->inst_evtlog_ptr =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->inst_evtlog_size =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->inst_errlog_ptr =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
+                       if (tlv_len)
+                               goto invalid_tlv_len;
+                       drv->fw.enhance_sensitivity_table = true;
+                       break;
+               case IWL_UCODE_TLV_WOWLAN_INST:
+                       pieces->wowlan_inst = tlv_data;
+                       pieces->wowlan_inst_size = tlv_len;
+                       break;
+               case IWL_UCODE_TLV_WOWLAN_DATA:
+                       pieces->wowlan_data = tlv_data;
+                       pieces->wowlan_data_size = tlv_len;
+                       break;
+               case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       capa->standard_phy_calibration_size =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               default:
+                       IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
+                       break;
+               }
+       }
+
+       if (len) {
+               IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len);
+               iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len);
+               return -EINVAL;
+       }
+
+       return 0;
+
+ invalid_tlv_len:
+       IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
+       iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len);
+
+       return -EINVAL;
+}
+
+/**
+ * iwl_ucode_callback - callback when firmware was loaded
+ *
+ * If loaded successfully, copies the firmware into buffers
+ * for the card to fetch (via DMA).
+ */
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
+{
+       struct iwl_drv *drv = context;
+       const struct iwl_cfg *cfg = cfg(drv);
+       struct iwl_fw *fw = &drv->fw;
+       struct iwl_ucode_header *ucode;
+       int err;
+       struct iwlagn_firmware_pieces pieces;
+       const unsigned int api_max = cfg->ucode_api_max;
+       unsigned int api_ok = cfg->ucode_api_ok;
+       const unsigned int api_min = cfg->ucode_api_min;
+       u32 api_ver;
+
+       fw->ucode_capa.max_probe_length = 200;
+       fw->ucode_capa.standard_phy_calibration_size =
+                       IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
+
+       if (!api_ok)
+               api_ok = api_max;
+
+       memset(&pieces, 0, sizeof(pieces));
+
+       if (!ucode_raw) {
+               if (drv->fw_index <= api_ok)
+                       IWL_ERR(drv,
+                               "request for firmware file '%s' failed.\n",
+                               drv->firmware_name);
+               goto try_again;
+       }
+
+       IWL_DEBUG_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n",
+                      drv->firmware_name, ucode_raw->size);
+
+       /* Make sure that we got at least the API version number */
+       if (ucode_raw->size < 4) {
+               IWL_ERR(drv, "File size way too small!\n");
+               goto try_again;
+       }
+
+       /* Data from ucode file:  header followed by uCode images */
+       ucode = (struct iwl_ucode_header *)ucode_raw->data;
+
+       if (ucode->ver)
+               err = iwl_parse_v1_v2_firmware(drv, ucode_raw, &pieces);
+       else
+               err = iwl_parse_tlv_firmware(drv, ucode_raw, &pieces,
+                                          &fw->ucode_capa);
+
+       if (err)
+               goto try_again;
+
+       api_ver = IWL_UCODE_API(drv->fw.ucode_ver);
+
+       /*
+        * api_ver should match the api version forming part of the
+        * firmware filename ... but we don't check for that and only rely
+        * on the API version read from firmware header from here on forward
+        */
+       /* no api version check required for experimental uCode */
+       if (drv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
+               if (api_ver < api_min || api_ver > api_max) {
+                       IWL_ERR(drv,
+                               "Driver unable to support your firmware API. "
+                               "Driver supports v%u, firmware is v%u.\n",
+                               api_max, api_ver);
+                       goto try_again;
+               }
+
+               if (api_ver < api_ok) {
+                       if (api_ok != api_max)
+                               IWL_ERR(drv, "Firmware has old API version, "
+                                       "expected v%u through v%u, got v%u.\n",
+                                       api_ok, api_max, api_ver);
+                       else
+                               IWL_ERR(drv, "Firmware has old API version, "
+                                       "expected v%u, got v%u.\n",
+                                       api_max, api_ver);
+                       IWL_ERR(drv, "New firmware can be obtained from "
+                                     "http://www.intellinuxwireless.org/.\n");
+               }
+       }
+
+       IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version);
+
+       /*
+        * For any of the failures below (before allocating pci memory)
+        * we will try to load a version with a smaller API -- maybe the
+        * user just got a corrupted version of the latest API.
+        */
+
+       IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n",
+                      drv->fw.ucode_ver);
+       IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n",
+                      pieces.inst_size);
+       IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n",
+                      pieces.data_size);
+       IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n",
+                      pieces.init_size);
+       IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n",
+                      pieces.init_data_size);
+
+       /* Verify that uCode images will fit in card's SRAM */
+       if (pieces.inst_size > cfg->max_inst_size) {
+               IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n",
+                       pieces.inst_size);
+               goto try_again;
+       }
+
+       if (pieces.data_size > cfg->max_data_size) {
+               IWL_ERR(drv, "uCode data len %Zd too large to fit in\n",
+                       pieces.data_size);
+               goto try_again;
+       }
+
+       if (pieces.init_size > cfg->max_inst_size) {
+               IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n",
+                       pieces.init_size);
+               goto try_again;
+       }
+
+       if (pieces.init_data_size > cfg->max_data_size) {
+               IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n",
+                       pieces.init_data_size);
+               goto try_again;
+       }
+
+       /* Allocate ucode buffers for card's bus-master loading ... */
+
+       /* Runtime instructions and 2 copies of data:
+        * 1) unmodified from disk
+        * 2) backup cache for save/restore during power-downs */
+       if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.code,
+                             pieces.inst, pieces.inst_size))
+               goto err_pci_alloc;
+       if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.data,
+                             pieces.data, pieces.data_size))
+               goto err_pci_alloc;
+
+       /* Initialization instructions and data */
+       if (pieces.init_size && pieces.init_data_size) {
+               if (iwl_alloc_fw_desc(drv,
+                                     &drv->fw.ucode_init.code,
+                                     pieces.init, pieces.init_size))
+                       goto err_pci_alloc;
+               if (iwl_alloc_fw_desc(drv,
+                                     &drv->fw.ucode_init.data,
+                                     pieces.init_data, pieces.init_data_size))
+                       goto err_pci_alloc;
+       }
+
+       /* WoWLAN instructions and data */
+       if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
+               if (iwl_alloc_fw_desc(drv,
+                                     &drv->fw.ucode_wowlan.code,
+                                     pieces.wowlan_inst,
+                                     pieces.wowlan_inst_size))
+                       goto err_pci_alloc;
+               if (iwl_alloc_fw_desc(drv,
+                                     &drv->fw.ucode_wowlan.data,
+                                     pieces.wowlan_data,
+                                     pieces.wowlan_data_size))
+                       goto err_pci_alloc;
+       }
+
+       /* Now that we can no longer fail, copy information */
+
+       /*
+        * The (size - 16) / 12 formula is based on the information recorded
+        * for each event, which is of mode 1 (including timestamp) for all
+        * new microcodes that include this information.
+        */
+       fw->init_evtlog_ptr = pieces.init_evtlog_ptr;
+       if (pieces.init_evtlog_size)
+               fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
+       else
+               fw->init_evtlog_size =
+                       cfg->base_params->max_event_log_size;
+       fw->init_errlog_ptr = pieces.init_errlog_ptr;
+       fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
+       if (pieces.inst_evtlog_size)
+               fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
+       else
+               fw->inst_evtlog_size =
+                       cfg->base_params->max_event_log_size;
+       fw->inst_errlog_ptr = pieces.inst_errlog_ptr;
+
+       /*
+        * figure out the offset of chain noise reset and gain commands
+        * base on the size of standard phy calibration commands table size
+        */
+       if (fw->ucode_capa.standard_phy_calibration_size >
+           IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
+               fw->ucode_capa.standard_phy_calibration_size =
+                       IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
+
+       /* We have our copies now, allow OS release its copies */
+       release_firmware(ucode_raw);
+       complete(&drv->request_firmware_complete);
+
+       drv->op_mode = iwl_dvm_ops.start(drv->shrd->trans, &drv->fw);
+
+       if (!drv->op_mode)
+               goto out_unbind;
+
+       return;
+
+ try_again:
+       /* try next, if any */
+       release_firmware(ucode_raw);
+       if (iwl_request_firmware(drv, false))
+               goto out_unbind;
+       return;
+
+ err_pci_alloc:
+       IWL_ERR(drv, "failed to allocate pci memory\n");
+       iwl_dealloc_ucode(drv);
+       release_firmware(ucode_raw);
+ out_unbind:
+       complete(&drv->request_firmware_complete);
+       device_release_driver(trans(drv)->dev);
+}
+
+int iwl_drv_start(struct iwl_shared *shrd,
+                 struct iwl_trans *trans, const struct iwl_cfg *cfg)
+{
+       struct iwl_drv *drv;
+       int ret;
+
+       shrd->cfg = cfg;
+
+       drv = kzalloc(sizeof(*drv), GFP_KERNEL);
+       if (!drv) {
+               dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_drv");
+               return -ENOMEM;
+       }
+       drv->shrd = shrd;
+       shrd->drv = drv;
+
+       init_completion(&drv->request_firmware_complete);
+
+       ret = iwl_request_firmware(drv, true);
+
+       if (ret) {
+               dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw");
+               kfree(drv);
+               shrd->drv = NULL;
+       }
+
+       return ret;
+}
+
+void iwl_drv_stop(struct iwl_shared *shrd)
+{
+       struct iwl_drv *drv = shrd->drv;
+
+       wait_for_completion(&drv->request_firmware_complete);
+
+       /* op_mode can be NULL if its start failed */
+       if (drv->op_mode)
+               iwl_op_mode_stop(drv->op_mode);
+
+       iwl_dealloc_ucode(drv);
+
+       kfree(drv);
+       shrd->drv = NULL;
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h
new file mode 100644 (file)
index 0000000..3b771c1
--- /dev/null
@@ -0,0 +1,123 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef __iwl_drv_h__
+#define __iwl_drv_h__
+
+#include "iwl-shared.h"
+
+/**
+ * DOC: Driver system flows - drv component
+ *
+ * This component implements the system flows such as bus enumeration, bus
+ * removal. Bus dependent parts of system flows (such as iwl_pci_probe) are in
+ * bus specific files (transport files). This is the code that is common among
+ * different buses.
+ *
+ * This component is also in charge of managing the several implementations of
+ * the wifi flows: it will allow to have several fw API implementation. These
+ * different implementations will differ in the way they implement mac80211's
+ * handlers too.
+
+ * The init flow wrt to the drv component looks like this:
+ * 1) The bus specific component is called from module_init
+ * 2) The bus specific component registers the bus driver
+ * 3) The bus driver calls the probe function
+ * 4) The bus specific component configures the bus
+ * 5) The bus specific component calls to the drv bus agnostic part
+ *    (iwl_drv_start)
+ * 6) iwl_drv_start fetches the fw ASYNC, iwl_ucode_callback
+ * 7) iwl_ucode_callback parses the fw file
+ * 8) iwl_ucode_callback starts the wifi implementation to matches the fw
+ */
+
+/**
+ * iwl_drv_start - start the drv
+ *
+ * @shrd: the shrd area
+ * @trans_ops: the ops of the transport
+ * @cfg: device specific constants / virtual functions
+ *
+ * TODO: review the parameters given to this function
+ *
+ * starts the driver: fetches the firmware. This should be called by bus
+ * specific system flows implementations. For example, the bus specific probe
+ * function should do bus related operations only, and then call to this
+ * function.
+ */
+int iwl_drv_start(struct iwl_shared *shrd,
+                 struct iwl_trans *trans, const struct iwl_cfg *cfg);
+
+/**
+ * iwl_drv_stop - stop the drv
+ *
+ * @shrd: the shrd area
+ *
+ * TODO: review the parameters given to this function
+ *
+ * Stop the driver. This should be called by bus specific system flows
+ * implementations. For example, the bus specific remove function should first
+ * call this function and then do the bus related operations only.
+ */
+void iwl_drv_stop(struct iwl_shared *shrd);
+
+#endif /* __iwl_drv_h__ */
index c1eda9724f42f41059b4e161f60a64d7b7f7bdf0..23cea42b94959ba5c09ad852b24b7c28ad3a85dc 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -75,6 +75,7 @@
 #include "iwl-agn.h"
 #include "iwl-eeprom.h"
 #include "iwl-io.h"
+#include "iwl-prph.h"
 
 /************************** EEPROM BANDS ****************************
  *
@@ -149,23 +150,27 @@ static const u8 iwl_eeprom_band_7[] = {       /* 5.2 ht40 channel */
  * EEPROM chip, not a single event, so even reads could conflict if they
  * weren't arbitrated by the semaphore.
  */
-static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus)
+
+#define        EEPROM_SEM_TIMEOUT 10           /* milliseconds */
+#define EEPROM_SEM_RETRY_LIMIT 1000    /* number of attempts (not time) */
+
+static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans)
 {
        u16 count;
        int ret;
 
        for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
                /* Request semaphore */
-               iwl_set_bit(bus, CSR_HW_IF_CONFIG_REG,
+               iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
                            CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
 
                /* See if we got it */
-               ret = iwl_poll_bit(bus, CSR_HW_IF_CONFIG_REG,
+               ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG,
                                CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
                                CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
                                EEPROM_SEM_TIMEOUT);
                if (ret >= 0) {
-                       IWL_DEBUG_EEPROM(bus,
+                       IWL_DEBUG_EEPROM(trans,
                                "Acquired semaphore after %d tries.\n",
                                count+1);
                        return ret;
@@ -175,16 +180,17 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus)
        return ret;
 }
 
-static void iwl_eeprom_release_semaphore(struct iwl_bus *bus)
+static void iwl_eeprom_release_semaphore(struct iwl_trans *trans)
 {
-       iwl_clear_bit(bus, CSR_HW_IF_CONFIG_REG,
+       iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG,
                CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
 
 }
 
 static int iwl_eeprom_verify_signature(struct iwl_trans *trans)
 {
-       u32 gp = iwl_read32(bus(trans), CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
+       u32 gp = iwl_read32(trans, CSR_EEPROM_GP) &
+                          CSR_EEPROM_GP_VALID_MSK;
        int ret = 0;
 
        IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp);
@@ -247,46 +253,46 @@ err:
 
 }
 
-int iwl_eeprom_check_sku(struct iwl_priv *priv)
+int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
 {
        struct iwl_shared *shrd = priv->shrd;
        u16 radio_cfg;
 
-       if (!cfg(priv)->sku) {
-               /* not using sku overwrite */
-               cfg(priv)->sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP);
-               if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE &&
-                   !cfg(priv)->ht_params) {
-                       IWL_ERR(priv, "Invalid 11n configuration\n");
-                       return -EINVAL;
-               }
+       hw_params(priv).sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP);
+       if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE &&
+           !cfg(priv)->ht_params) {
+               IWL_ERR(priv, "Invalid 11n configuration\n");
+               return -EINVAL;
        }
-       if (!cfg(priv)->sku) {
+
+       if (!hw_params(priv).sku) {
                IWL_ERR(priv, "Invalid device sku\n");
                return -EINVAL;
        }
 
-       IWL_INFO(priv, "Device SKU: 0x%X\n", cfg(priv)->sku);
-
-       if (!cfg(priv)->valid_tx_ant && !cfg(priv)->valid_rx_ant) {
-               /* not using .cfg overwrite */
-               radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG);
-               cfg(priv)->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
-               cfg(priv)->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
-               if (!cfg(priv)->valid_tx_ant || !cfg(priv)->valid_rx_ant) {
-                       IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n",
-                               cfg(priv)->valid_tx_ant,
-                               cfg(priv)->valid_rx_ant);
-                       return -EINVAL;
-               }
-               IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n",
-                        cfg(priv)->valid_tx_ant, cfg(priv)->valid_rx_ant);
+       IWL_INFO(priv, "Device SKU: 0x%X\n", hw_params(priv).sku);
+
+       radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG);
+
+       hw_params(priv).valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
+       hw_params(priv).valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
+
+       /* check overrides (some devices have wrong EEPROM) */
+       if (cfg(priv)->valid_tx_ant)
+               hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
+       if (cfg(priv)->valid_rx_ant)
+               hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+
+       if (!hw_params(priv).valid_tx_ant || !hw_params(priv).valid_rx_ant) {
+               IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n",
+                       hw_params(priv).valid_tx_ant,
+                       hw_params(priv).valid_rx_ant);
+               return -EINVAL;
        }
-       /*
-        * for some special cases,
-        * EEPROM did not reflect the correct antenna setting
-        * so overwrite the valid tx/rx antenna from .cfg
-        */
+
+       IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n",
+                hw_params(priv).valid_tx_ant, hw_params(priv).valid_rx_ant);
+
        return 0;
 }
 
@@ -303,19 +309,20 @@ void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac)
  *
 ******************************************************************************/
 
-static void iwl_set_otp_access(struct iwl_bus *bus, enum iwl_access_mode mode)
+static void iwl_set_otp_access(struct iwl_trans *trans,
+                              enum iwl_access_mode mode)
 {
-       iwl_read32(bus, CSR_OTP_GP_REG);
+       iwl_read32(trans, CSR_OTP_GP_REG);
 
        if (mode == IWL_OTP_ACCESS_ABSOLUTE)
-               iwl_clear_bit(bus, CSR_OTP_GP_REG,
+               iwl_clear_bit(trans, CSR_OTP_GP_REG,
                              CSR_OTP_GP_REG_OTP_ACCESS_MODE);
        else
-               iwl_set_bit(bus, CSR_OTP_GP_REG,
+               iwl_set_bit(trans, CSR_OTP_GP_REG,
                            CSR_OTP_GP_REG_OTP_ACCESS_MODE);
 }
 
-static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev)
+static int iwl_get_nvm_type(struct iwl_trans *trans, u32 hw_rev)
 {
        u32 otpgp;
        int nvm_type;
@@ -323,7 +330,7 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev)
        /* OTP only valid for CP/PP and after */
        switch (hw_rev & CSR_HW_REV_TYPE_MSK) {
        case CSR_HW_REV_TYPE_NONE:
-               IWL_ERR(bus, "Unknown hardware type\n");
+               IWL_ERR(trans, "Unknown hardware type\n");
                return -ENOENT;
        case CSR_HW_REV_TYPE_5300:
        case CSR_HW_REV_TYPE_5350:
@@ -332,7 +339,7 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev)
                nvm_type = NVM_DEVICE_TYPE_EEPROM;
                break;
        default:
-               otpgp = iwl_read32(bus, CSR_OTP_GP_REG);
+               otpgp = iwl_read32(trans, CSR_OTP_GP_REG);
                if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT)
                        nvm_type = NVM_DEVICE_TYPE_OTP;
                else
@@ -342,73 +349,74 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev)
        return  nvm_type;
 }
 
-static int iwl_init_otp_access(struct iwl_bus *bus)
+static int iwl_init_otp_access(struct iwl_trans *trans)
 {
        int ret;
 
        /* Enable 40MHz radio clock */
-       iwl_write32(bus, CSR_GP_CNTRL,
-                   iwl_read32(bus, CSR_GP_CNTRL) |
+       iwl_write32(trans, CSR_GP_CNTRL,
+                   iwl_read32(trans, CSR_GP_CNTRL) |
                    CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 
        /* wait for clock to be ready */
-       ret = iwl_poll_bit(bus, CSR_GP_CNTRL,
+       ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
                                 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
                                 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
                                 25000);
        if (ret < 0)
-               IWL_ERR(bus, "Time out access OTP\n");
+               IWL_ERR(trans, "Time out access OTP\n");
        else {
-               iwl_set_bits_prph(bus, APMG_PS_CTRL_REG,
+               iwl_set_bits_prph(trans, APMG_PS_CTRL_REG,
                                  APMG_PS_CTRL_VAL_RESET_REQ);
                udelay(5);
-               iwl_clear_bits_prph(bus, APMG_PS_CTRL_REG,
+               iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG,
                                    APMG_PS_CTRL_VAL_RESET_REQ);
 
                /*
                 * CSR auto clock gate disable bit -
                 * this is only applicable for HW with OTP shadow RAM
                 */
-               if (cfg(bus)->base_params->shadow_ram_support)
-                       iwl_set_bit(bus, CSR_DBG_LINK_PWR_MGMT_REG,
+               if (cfg(trans)->base_params->shadow_ram_support)
+                       iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
                                CSR_RESET_LINK_PWR_MGMT_DISABLED);
        }
        return ret;
 }
 
-static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data)
+static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr,
+                            __le16 *eeprom_data)
 {
        int ret = 0;
        u32 r;
        u32 otpgp;
 
-       iwl_write32(bus, CSR_EEPROM_REG,
+       iwl_write32(trans, CSR_EEPROM_REG,
                    CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
-       ret = iwl_poll_bit(bus, CSR_EEPROM_REG,
+       ret = iwl_poll_bit(trans, CSR_EEPROM_REG,
                                 CSR_EEPROM_REG_READ_VALID_MSK,
                                 CSR_EEPROM_REG_READ_VALID_MSK,
                                 IWL_EEPROM_ACCESS_TIMEOUT);
        if (ret < 0) {
-               IWL_ERR(bus, "Time out reading OTP[%d]\n", addr);
+               IWL_ERR(trans, "Time out reading OTP[%d]\n", addr);
                return ret;
        }
-       r = iwl_read32(bus, CSR_EEPROM_REG);
+       r = iwl_read32(trans, CSR_EEPROM_REG);
        /* check for ECC errors: */
-       otpgp = iwl_read32(bus, CSR_OTP_GP_REG);
+       otpgp = iwl_read32(trans, CSR_OTP_GP_REG);
        if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
                /* stop in this case */
                /* set the uncorrectable OTP ECC bit for acknowledgement */
-               iwl_set_bit(bus, CSR_OTP_GP_REG,
+               iwl_set_bit(trans, CSR_OTP_GP_REG,
                        CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
-               IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n");
+               IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n");
                return -EINVAL;
        }
        if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
                /* continue in this case */
                /* set the correctable OTP ECC bit for acknowledgement */
-               iwl_set_bit(bus, CSR_OTP_GP_REG,
+               iwl_set_bit(trans, CSR_OTP_GP_REG,
                                CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
-               IWL_ERR(bus, "Correctable OTP ECC error, continue read\n");
+               IWL_ERR(trans, "Correctable OTP ECC error, continue read\n");
        }
        *eeprom_data = cpu_to_le16(r >> 16);
        return 0;
@@ -417,20 +425,20 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data)
 /*
  * iwl_is_otp_empty: check for empty OTP
  */
-static bool iwl_is_otp_empty(struct iwl_bus *bus)
+static bool iwl_is_otp_empty(struct iwl_trans *trans)
 {
        u16 next_link_addr = 0;
        __le16 link_value;
        bool is_empty = false;
 
        /* locate the beginning of OTP link list */
-       if (!iwl_read_otp_word(bus, next_link_addr, &link_value)) {
+       if (!iwl_read_otp_word(trans, next_link_addr, &link_value)) {
                if (!link_value) {
-                       IWL_ERR(bus, "OTP is empty\n");
+                       IWL_ERR(trans, "OTP is empty\n");
                        is_empty = true;
                }
        } else {
-               IWL_ERR(bus, "Unable to read first block of OTP list.\n");
+               IWL_ERR(trans, "Unable to read first block of OTP list.\n");
                is_empty = true;
        }
 
@@ -447,7 +455,7 @@ static bool iwl_is_otp_empty(struct iwl_bus *bus)
  *   we should read and used to configure the device.
  *   only perform this operation if shadow RAM is disabled
  */
-static int iwl_find_otp_image(struct iwl_bus *bus,
+static int iwl_find_otp_image(struct iwl_trans *trans,
                                        u16 *validblockaddr)
 {
        u16 next_link_addr = 0, valid_addr;
@@ -455,10 +463,10 @@ static int iwl_find_otp_image(struct iwl_bus *bus,
        int usedblocks = 0;
 
        /* set addressing mode to absolute to traverse the link list */
-       iwl_set_otp_access(bus, IWL_OTP_ACCESS_ABSOLUTE);
+       iwl_set_otp_access(trans, IWL_OTP_ACCESS_ABSOLUTE);
 
        /* checking for empty OTP or error */
-       if (iwl_is_otp_empty(bus))
+       if (iwl_is_otp_empty(trans))
                return -EINVAL;
 
        /*
@@ -472,9 +480,9 @@ static int iwl_find_otp_image(struct iwl_bus *bus,
                 */
                valid_addr = next_link_addr;
                next_link_addr = le16_to_cpu(link_value) * sizeof(u16);
-               IWL_DEBUG_EEPROM(bus, "OTP blocks %d addr 0x%x\n",
+               IWL_DEBUG_EEPROM(trans, "OTP blocks %d addr 0x%x\n",
                               usedblocks, next_link_addr);
-               if (iwl_read_otp_word(bus, next_link_addr, &link_value))
+               if (iwl_read_otp_word(trans, next_link_addr, &link_value))
                        return -EINVAL;
                if (!link_value) {
                        /*
@@ -489,10 +497,10 @@ static int iwl_find_otp_image(struct iwl_bus *bus,
                }
                /* more in the link list, continue */
                usedblocks++;
-       } while (usedblocks <= cfg(bus)->base_params->max_ll_items);
+       } while (usedblocks <= cfg(trans)->base_params->max_ll_items);
 
        /* OTP has no valid blocks */
-       IWL_DEBUG_EEPROM(bus, "OTP has no valid blocks\n");
+       IWL_DEBUG_EEPROM(trans, "OTP has no valid blocks\n");
        return -EINVAL;
 }
 
@@ -505,7 +513,7 @@ static int iwl_find_otp_image(struct iwl_bus *bus,
  * iwl_get_max_txpower_avg - get the highest tx power from all chains.
  *     find the highest tx power from all chains for the channel
  */
-static s8 iwl_get_max_txpower_avg(struct iwl_cfg *cfg,
+static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg,
                struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
                int element, s8 *max_txpower_in_half_dbm)
 {
@@ -581,7 +589,7 @@ iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv,
 #define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \
                            ? # x " " : "")
 
-void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
+static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
 {
        struct iwl_shared *shrd = priv->shrd;
        struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
@@ -652,65 +660,62 @@ void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
  *
  * NOTE:  This routine uses the non-debug IO access functions.
  */
-int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
+int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev)
 {
-       struct iwl_shared *shrd = priv->shrd;
        __le16 *e;
-       u32 gp = iwl_read32(bus(priv), CSR_EEPROM_GP);
+       u32 gp = iwl_read32(trans, CSR_EEPROM_GP);
        int sz;
        int ret;
        u16 addr;
        u16 validblockaddr = 0;
        u16 cache_addr = 0;
 
-       trans(priv)->nvm_device_type = iwl_get_nvm_type(bus(priv), hw_rev);
-       if (trans(priv)->nvm_device_type == -ENOENT)
+       trans->nvm_device_type = iwl_get_nvm_type(trans, hw_rev);
+       if (trans->nvm_device_type == -ENOENT)
                return -ENOENT;
        /* allocate eeprom */
-       sz = cfg(priv)->base_params->eeprom_size;
-       IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz);
-       shrd->eeprom = kzalloc(sz, GFP_KERNEL);
-       if (!shrd->eeprom) {
+       sz = cfg(trans)->base_params->eeprom_size;
+       IWL_DEBUG_EEPROM(trans, "NVM size = %d\n", sz);
+       trans->shrd->eeprom = kzalloc(sz, GFP_KERNEL);
+       if (!trans->shrd->eeprom) {
                ret = -ENOMEM;
                goto alloc_err;
        }
-       e = (__le16 *)shrd->eeprom;
-
-       iwl_apm_init(priv);
+       e = (__le16 *)trans->shrd->eeprom;
 
-       ret = iwl_eeprom_verify_signature(trans(priv));
+       ret = iwl_eeprom_verify_signature(trans);
        if (ret < 0) {
-               IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
+               IWL_ERR(trans, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
                ret = -ENOENT;
                goto err;
        }
 
        /* Make sure driver (instead of uCode) is allowed to read EEPROM */
-       ret = iwl_eeprom_acquire_semaphore(bus(priv));
+       ret = iwl_eeprom_acquire_semaphore(trans);
        if (ret < 0) {
-               IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
+               IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n");
                ret = -ENOENT;
                goto err;
        }
 
-       if (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
+       if (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
 
-               ret = iwl_init_otp_access(bus(priv));
+               ret = iwl_init_otp_access(trans);
                if (ret) {
-                       IWL_ERR(priv, "Failed to initialize OTP access.\n");
+                       IWL_ERR(trans, "Failed to initialize OTP access.\n");
                        ret = -ENOENT;
                        goto done;
                }
-               iwl_write32(bus(priv), CSR_EEPROM_GP,
-                           iwl_read32(bus(priv), CSR_EEPROM_GP) &
+               iwl_write32(trans, CSR_EEPROM_GP,
+                           iwl_read32(trans, CSR_EEPROM_GP) &
                            ~CSR_EEPROM_GP_IF_OWNER_MSK);
 
-               iwl_set_bit(bus(priv), CSR_OTP_GP_REG,
+               iwl_set_bit(trans, CSR_OTP_GP_REG,
                             CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
                             CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
                /* traversing the linked list if no shadow ram supported */
-               if (!cfg(priv)->base_params->shadow_ram_support) {
-                       if (iwl_find_otp_image(bus(priv), &validblockaddr)) {
+               if (!cfg(trans)->base_params->shadow_ram_support) {
+                       if (iwl_find_otp_image(trans, &validblockaddr)) {
                                ret = -ENOENT;
                                goto done;
                        }
@@ -719,7 +724,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
                     addr += sizeof(u16)) {
                        __le16 eeprom_data;
 
-                       ret = iwl_read_otp_word(bus(priv), addr, &eeprom_data);
+                       ret = iwl_read_otp_word(trans, addr, &eeprom_data);
                        if (ret)
                                goto done;
                        e[cache_addr / 2] = eeprom_data;
@@ -730,36 +735,35 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
                for (addr = 0; addr < sz; addr += sizeof(u16)) {
                        u32 r;
 
-                       iwl_write32(bus(priv), CSR_EEPROM_REG,
+                       iwl_write32(trans, CSR_EEPROM_REG,
                                    CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
 
-                       ret = iwl_poll_bit(bus(priv), CSR_EEPROM_REG,
+                       ret = iwl_poll_bit(trans, CSR_EEPROM_REG,
                                                  CSR_EEPROM_REG_READ_VALID_MSK,
                                                  CSR_EEPROM_REG_READ_VALID_MSK,
                                                  IWL_EEPROM_ACCESS_TIMEOUT);
                        if (ret < 0) {
-                               IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
+                               IWL_ERR(trans,
+                                       "Time out reading EEPROM[%d]\n", addr);
                                goto done;
                        }
-                       r = iwl_read32(bus(priv), CSR_EEPROM_REG);
+                       r = iwl_read32(trans, CSR_EEPROM_REG);
                        e[addr / 2] = cpu_to_le16(r >> 16);
                }
        }
 
-       IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n",
-                      (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+       IWL_DEBUG_EEPROM(trans, "NVM Type: %s, version: 0x%x\n",
+                      (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP)
                       ? "OTP" : "EEPROM",
-                      iwl_eeprom_query16(shrd, EEPROM_VERSION));
+                      iwl_eeprom_query16(trans->shrd, EEPROM_VERSION));
 
        ret = 0;
 done:
-       iwl_eeprom_release_semaphore(bus(priv));
+       iwl_eeprom_release_semaphore(trans);
 
 err:
        if (ret)
-               iwl_eeprom_free(priv->shrd);
-       /* Reset chip to save power until we load uCode during "up". */
-       iwl_apm_stop(priv);
+               iwl_eeprom_free(trans->shrd);
 alloc_err:
        return ret;
 }
@@ -1021,8 +1025,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
         * driver need to process addition information
         * to determine the max channel tx power limits
         */
-       if (cfg(priv)->lib->eeprom_ops.update_enhanced_txpower)
-               cfg(priv)->lib->eeprom_ops.update_enhanced_txpower(priv);
+       if (cfg(priv)->lib->eeprom_ops.enhanced_txpower)
+               iwl_eeprom_enhanced_txpower(priv);
 
        return 0;
 }
@@ -1072,7 +1076,7 @@ void iwl_rf_config(struct iwl_priv *priv)
 
        /* write radio config values to register */
        if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) {
-               iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG,
+               iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
                            EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
                            EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
                            EEPROM_RF_CFG_DASH_MSK(radio_cfg));
@@ -1084,7 +1088,7 @@ void iwl_rf_config(struct iwl_priv *priv)
                WARN_ON(1);
 
        /* set CSR_HW_CONFIG_REG for uCode use */
-       iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG,
+       iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
                    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
                    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 }
index 9fa937ec35e38ca314284453ebad05de058c505e..e4a758340996211f8072c5cdb3223e536741802e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -67,6 +67,7 @@
 
 struct iwl_priv;
 struct iwl_shared;
+struct iwl_trans;
 
 /*
  * EEPROM access time values:
@@ -301,14 +302,14 @@ extern const u8 iwl_eeprom_band_1[14];
 
 struct iwl_eeprom_ops {
        const u32 regulatory_bands[7];
-       void (*update_enhanced_txpower) (struct iwl_priv *priv);
+       bool enhanced_txpower;
 };
 
 
-int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev);
+int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev);
 void iwl_eeprom_free(struct iwl_shared *shrd);
 int  iwl_eeprom_check_version(struct iwl_priv *priv);
-int  iwl_eeprom_check_sku(struct iwl_priv *priv);
+int iwl_eeprom_init_hw_params(struct iwl_priv *priv);
 const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset);
 u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset);
 int iwl_init_channel_map(struct iwl_priv *priv);
index 5bede9d7f9555ed04ea82a5ad76cb1d928381ba7..90208094b8ebdb472fcc9078ca605c83f37d9197 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
new file mode 100644 (file)
index 0000000..7ca6c95
--- /dev/null
@@ -0,0 +1,160 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef __iwl_fw_file_h__
+#define __iwl_fw_file_h__
+
+#include <linux/netdevice.h>
+
+/* v1/v2 uCode file layout */
+struct iwl_ucode_header {
+       __le32 ver;     /* major/minor/API/serial */
+       union {
+               struct {
+                       __le32 inst_size;       /* bytes of runtime code */
+                       __le32 data_size;       /* bytes of runtime data */
+                       __le32 init_size;       /* bytes of init code */
+                       __le32 init_data_size;  /* bytes of init data */
+                       __le32 boot_size;       /* bytes of bootstrap code */
+                       u8 data[0];             /* in same order as sizes */
+               } v1;
+               struct {
+                       __le32 build;           /* build number */
+                       __le32 inst_size;       /* bytes of runtime code */
+                       __le32 data_size;       /* bytes of runtime data */
+                       __le32 init_size;       /* bytes of init code */
+                       __le32 init_data_size;  /* bytes of init data */
+                       __le32 boot_size;       /* bytes of bootstrap code */
+                       u8 data[0];             /* in same order as sizes */
+               } v2;
+       } u;
+};
+
+/*
+ * new TLV uCode file layout
+ *
+ * The new TLV file format contains TLVs, that each specify
+ * some piece of data. To facilitate "groups", for example
+ * different instruction image with different capabilities,
+ * bundled with the same init image, an alternative mechanism
+ * is provided:
+ * When the alternative field is 0, that means that the item
+ * is always valid. When it is non-zero, then it is only
+ * valid in conjunction with items of the same alternative,
+ * in which case the driver (user) selects one alternative
+ * to use.
+ */
+
+enum iwl_ucode_tlv_type {
+       IWL_UCODE_TLV_INVALID           = 0, /* unused */
+       IWL_UCODE_TLV_INST              = 1,
+       IWL_UCODE_TLV_DATA              = 2,
+       IWL_UCODE_TLV_INIT              = 3,
+       IWL_UCODE_TLV_INIT_DATA         = 4,
+       IWL_UCODE_TLV_BOOT              = 5,
+       IWL_UCODE_TLV_PROBE_MAX_LEN     = 6, /* a u32 value */
+       IWL_UCODE_TLV_PAN               = 7,
+       IWL_UCODE_TLV_RUNT_EVTLOG_PTR   = 8,
+       IWL_UCODE_TLV_RUNT_EVTLOG_SIZE  = 9,
+       IWL_UCODE_TLV_RUNT_ERRLOG_PTR   = 10,
+       IWL_UCODE_TLV_INIT_EVTLOG_PTR   = 11,
+       IWL_UCODE_TLV_INIT_EVTLOG_SIZE  = 12,
+       IWL_UCODE_TLV_INIT_ERRLOG_PTR   = 13,
+       IWL_UCODE_TLV_ENHANCE_SENS_TBL  = 14,
+       IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
+       IWL_UCODE_TLV_WOWLAN_INST       = 16,
+       IWL_UCODE_TLV_WOWLAN_DATA       = 17,
+       IWL_UCODE_TLV_FLAGS             = 18,
+};
+
+struct iwl_ucode_tlv {
+       __le16 type;            /* see above */
+       __le16 alternative;     /* see comment */
+       __le32 length;          /* not including type/length fields */
+       u8 data[0];
+};
+
+#define IWL_TLV_UCODE_MAGIC    0x0a4c5749
+
+struct iwl_tlv_ucode_header {
+       /*
+        * The TLV style ucode header is distinguished from
+        * the v1/v2 style header by first four bytes being
+        * zero, as such is an invalid combination of
+        * major/minor/API/serial versions.
+        */
+       __le32 zero;
+       __le32 magic;
+       u8 human_readable[64];
+       __le32 ver;             /* major/minor/API/serial */
+       __le32 build;
+       __le64 alternatives;    /* bitmask of valid alternatives */
+       /*
+        * The data contained herein has a TLV layout,
+        * see above for the TLV header and types.
+        * Note that each TLV is padded to a length
+        * that is a multiple of 4 for alignment.
+        */
+       u8 data[0];
+};
+
+#endif  /* __iwl_fw_file_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
new file mode 100644 (file)
index 0000000..453812a
--- /dev/null
@@ -0,0 +1,146 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef __iwl_fw_h__
+#define __iwl_fw_h__
+#include <linux/types.h>
+
+/**
+ * enum iwl_ucode_tlv_flag - ucode API flags
+ * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
+ *     was a separate TLV but moved here to save space.
+ * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
+ *     treats good CRC threshold as a boolean
+ * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
+ * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
+ */
+enum iwl_ucode_tlv_flag {
+       IWL_UCODE_TLV_FLAGS_PAN         = BIT(0),
+       IWL_UCODE_TLV_FLAGS_NEWSCAN     = BIT(1),
+       IWL_UCODE_TLV_FLAGS_MFP         = BIT(2),
+       IWL_UCODE_TLV_FLAGS_P2P         = BIT(3),
+};
+
+/* The default calibrate table size if not specified by firmware file */
+#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE    18
+#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE                19
+#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE                 253
+
+struct iwl_ucode_capabilities {
+       u32 max_probe_length;
+       u32 standard_phy_calibration_size;
+       u32 flags;
+};
+
+/* one for each uCode image (inst/data, boot/init/runtime) */
+struct fw_desc {
+       dma_addr_t p_addr;      /* hardware address */
+       void *v_addr;           /* software address */
+       u32 len;                /* size in bytes */
+};
+
+struct fw_img {
+       struct fw_desc code;    /* firmware code image */
+       struct fw_desc data;    /* firmware data image */
+};
+
+/* uCode version contains 4 values: Major/Minor/API/Serial */
+#define IWL_UCODE_MAJOR(ver)   (((ver) & 0xFF000000) >> 24)
+#define IWL_UCODE_MINOR(ver)   (((ver) & 0x00FF0000) >> 16)
+#define IWL_UCODE_API(ver)     (((ver) & 0x0000FF00) >> 8)
+#define IWL_UCODE_SERIAL(ver)  ((ver) & 0x000000FF)
+
+/**
+ * struct iwl_fw - variables associated with the firmware
+ *
+ * @ucode_ver: ucode version from the ucode file
+ * @fw_version: firmware version string
+ * @ucode_rt: run time ucode image
+ * @ucode_init: init ucode image
+ * @ucode_wowlan: wake on wireless ucode image (optional)
+ * @ucode_capa: capabilities parsed from the ucode file.
+ * @enhance_sensitivity_table: device can do enhanced sensitivity.
+ * @init_evtlog_ptr: event log offset for init ucode.
+ * @init_evtlog_size: event log size for init ucode.
+ * @init_errlog_ptr: error log offfset for init ucode.
+ * @inst_evtlog_ptr: event log offset for runtime ucode.
+ * @inst_evtlog_size: event log size for runtime ucode.
+ * @inst_errlog_ptr: error log offfset for runtime ucode.
+ */
+struct iwl_fw {
+       u32 ucode_ver;
+
+       char fw_version[ETHTOOL_BUSINFO_LEN];
+
+       /* ucode images */
+       struct fw_img ucode_rt;
+       struct fw_img ucode_init;
+       struct fw_img ucode_wowlan;
+
+       struct iwl_ucode_capabilities ucode_capa;
+       bool enhance_sensitivity_table;
+
+       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
+       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
+};
+
+#endif  /* __iwl_fw_h__ */
index d57ea6484bbedf7529f47d6d79d4f79695bd6e19..081dd34d2387d1787ab575ebb2106c9d683ab119 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
 
 #define IWL_POLL_INTERVAL 10   /* microseconds */
 
-static inline void __iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask)
+static inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
 {
-       iwl_write32(bus, reg, iwl_read32(bus, reg) | mask);
+       iwl_write32(trans, reg, iwl_read32(trans, reg) | mask);
 }
 
-static inline void __iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask)
+static inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
 {
-       iwl_write32(bus, reg, iwl_read32(bus, reg) & ~mask);
+       iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask);
 }
 
-void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask)
+void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       __iwl_set_bit(bus, reg, mask);
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       __iwl_set_bit(trans, reg, mask);
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask)
+void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       __iwl_clear_bit(bus, reg, mask);
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       __iwl_clear_bit(trans, reg, mask);
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-int iwl_poll_bit(struct iwl_bus *bus, u32 addr,
+int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
                 u32 bits, u32 mask, int timeout)
 {
        int t = 0;
 
        do {
-               if ((iwl_read32(bus, addr) & mask) == (bits & mask))
+               if ((iwl_read32(trans, addr) & mask) == (bits & mask))
                        return t;
                udelay(IWL_POLL_INTERVAL);
                t += IWL_POLL_INTERVAL;
@@ -77,14 +77,15 @@ int iwl_poll_bit(struct iwl_bus *bus, u32 addr,
        return -ETIMEDOUT;
 }
 
-int iwl_grab_nic_access_silent(struct iwl_bus *bus)
+int iwl_grab_nic_access_silent(struct iwl_trans *trans)
 {
        int ret;
 
-       lockdep_assert_held(&bus->reg_lock);
+       lockdep_assert_held(&trans->reg_lock);
 
        /* this bit wakes up the NIC */
-       __iwl_set_bit(bus, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       __iwl_set_bit(trans, CSR_GP_CNTRL,
+                     CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 
        /*
         * These bits say the device is running, and should keep running for
@@ -105,70 +106,78 @@ int iwl_grab_nic_access_silent(struct iwl_bus *bus)
         * 5000 series and later (including 1000 series) have non-volatile SRAM,
         * and do not save/restore SRAM when power cycling.
         */
-       ret = iwl_poll_bit(bus, CSR_GP_CNTRL,
+       ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
                           CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
                           (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
                            CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
        if (ret < 0) {
-               iwl_write32(bus, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
+               iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
                return -EIO;
        }
 
        return 0;
 }
 
-int iwl_grab_nic_access(struct iwl_bus *bus)
+bool iwl_grab_nic_access(struct iwl_trans *trans)
 {
-       int ret = iwl_grab_nic_access_silent(bus);
-       if (ret) {
-               u32 val = iwl_read32(bus, CSR_GP_CNTRL);
-               IWL_ERR(bus,
-                       "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
+       int ret = iwl_grab_nic_access_silent(trans);
+       if (unlikely(ret)) {
+               u32 val = iwl_read32(trans, CSR_GP_CNTRL);
+               WARN_ONCE(1, "Timeout waiting for hardware access "
+                            "(CSR_GP_CNTRL 0x%08x)\n", val);
+               return false;
        }
 
-       return ret;
+       return true;
 }
 
-void iwl_release_nic_access(struct iwl_bus *bus)
+void iwl_release_nic_access(struct iwl_trans *trans)
 {
-       lockdep_assert_held(&bus->reg_lock);
-       __iwl_clear_bit(bus, CSR_GP_CNTRL,
+       lockdep_assert_held(&trans->reg_lock);
+       __iwl_clear_bit(trans, CSR_GP_CNTRL,
                        CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       /*
+        * Above we read the CSR_GP_CNTRL register, which will flush
+        * any previous writes, but we need the write that clears the
+        * MAC_ACCESS_REQ bit to be performed before any other writes
+        * scheduled on different CPUs (after we drop reg_lock).
+        */
+       mmiowb();
 }
 
-u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg)
+u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
 {
        u32 value;
        unsigned long flags;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       iwl_grab_nic_access(bus);
-       value = iwl_read32(bus, reg);
-       iwl_release_nic_access(bus);
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       iwl_grab_nic_access(trans);
+       value = iwl_read32(trans, reg);
+       iwl_release_nic_access(trans);
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
 
        return value;
 }
 
-void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value)
+void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       if (!iwl_grab_nic_access(bus)) {
-               iwl_write32(bus, reg, value);
-               iwl_release_nic_access(bus);
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       if (likely(iwl_grab_nic_access(trans))) {
+               iwl_write32(trans, reg, value);
+               iwl_release_nic_access(trans);
        }
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask,
+int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
                        int timeout)
 {
        int t = 0;
 
        do {
-               if ((iwl_read_direct32(bus, addr) & mask) == mask)
+               if ((iwl_read_direct32(trans, addr) & mask) == mask)
                        return t;
                udelay(IWL_POLL_INTERVAL);
                t += IWL_POLL_INTERVAL;
@@ -177,135 +186,132 @@ int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask,
        return -ETIMEDOUT;
 }
 
-static inline u32 __iwl_read_prph(struct iwl_bus *bus, u32 reg)
+static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg)
 {
-       iwl_write32(bus, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
-       rmb();
-       return iwl_read32(bus, HBUS_TARG_PRPH_RDAT);
+       iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
+       return iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
 }
 
-static inline void __iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val)
+static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
 {
-       iwl_write32(bus, HBUS_TARG_PRPH_WADDR,
+       iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
                    ((addr & 0x0000FFFF) | (3 << 24)));
-       wmb();
-       iwl_write32(bus, HBUS_TARG_PRPH_WDAT, val);
+       iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
 }
 
-u32 iwl_read_prph(struct iwl_bus *bus, u32 reg)
+u32 iwl_read_prph(struct iwl_trans *trans, u32 reg)
 {
        unsigned long flags;
        u32 val;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       iwl_grab_nic_access(bus);
-       val = __iwl_read_prph(bus, reg);
-       iwl_release_nic_access(bus);
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       iwl_grab_nic_access(trans);
+       val = __iwl_read_prph(trans, reg);
+       iwl_release_nic_access(trans);
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
        return val;
 }
 
-void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val)
+void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       if (!iwl_grab_nic_access(bus)) {
-               __iwl_write_prph(bus, addr, val);
-               iwl_release_nic_access(bus);
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       if (likely(iwl_grab_nic_access(trans))) {
+               __iwl_write_prph(trans, addr, val);
+               iwl_release_nic_access(trans);
        }
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask)
+void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       iwl_grab_nic_access(bus);
-       __iwl_write_prph(bus, reg, __iwl_read_prph(bus, reg) | mask);
-       iwl_release_nic_access(bus);
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       if (likely(iwl_grab_nic_access(trans))) {
+               __iwl_write_prph(trans, reg,
+                                __iwl_read_prph(trans, reg) | mask);
+               iwl_release_nic_access(trans);
+       }
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg,
+void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg,
                            u32 bits, u32 mask)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       iwl_grab_nic_access(bus);
-       __iwl_write_prph(bus, reg,
-                        (__iwl_read_prph(bus, reg) & mask) | bits);
-       iwl_release_nic_access(bus);
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       if (likely(iwl_grab_nic_access(trans))) {
+               __iwl_write_prph(trans, reg,
+                                (__iwl_read_prph(trans, reg) & mask) | bits);
+               iwl_release_nic_access(trans);
+       }
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask)
+void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
 {
        unsigned long flags;
        u32 val;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       iwl_grab_nic_access(bus);
-       val = __iwl_read_prph(bus, reg);
-       __iwl_write_prph(bus, reg, (val & ~mask));
-       iwl_release_nic_access(bus);
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       if (likely(iwl_grab_nic_access(trans))) {
+               val = __iwl_read_prph(trans, reg);
+               __iwl_write_prph(trans, reg, (val & ~mask));
+               iwl_release_nic_access(trans);
+       }
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr,
+void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr,
                              void *buf, int words)
 {
        unsigned long flags;
        int offs;
        u32 *vals = buf;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       iwl_grab_nic_access(bus);
-
-       iwl_write32(bus, HBUS_TARG_MEM_RADDR, addr);
-       rmb();
-
-       for (offs = 0; offs < words; offs++)
-               vals[offs] = iwl_read32(bus, HBUS_TARG_MEM_RDAT);
-
-       iwl_release_nic_access(bus);
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       if (likely(iwl_grab_nic_access(trans))) {
+               iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
+               for (offs = 0; offs < words; offs++)
+                       vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
+               iwl_release_nic_access(trans);
+       }
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr)
+u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr)
 {
        u32 value;
 
-       _iwl_read_targ_mem_words(bus, addr, &value, 1);
+       _iwl_read_targ_mem_words(trans, addr, &value, 1);
 
        return value;
 }
 
-int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr,
+int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
                                void *buf, int words)
 {
        unsigned long flags;
        int offs, result = 0;
        u32 *vals = buf;
 
-       spin_lock_irqsave(&bus->reg_lock, flags);
-       if (!iwl_grab_nic_access(bus)) {
-               iwl_write32(bus, HBUS_TARG_MEM_WADDR, addr);
-               wmb();
-
+       spin_lock_irqsave(&trans->reg_lock, flags);
+       if (likely(iwl_grab_nic_access(trans))) {
+               iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
                for (offs = 0; offs < words; offs++)
-                       iwl_write32(bus, HBUS_TARG_MEM_WDAT, vals[offs]);
-               iwl_release_nic_access(bus);
+                       iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);
+               iwl_release_nic_access(trans);
        } else
                result = -EBUSY;
-       spin_unlock_irqrestore(&bus->reg_lock, flags);
+       spin_unlock_irqrestore(&trans->reg_lock, flags);
 
        return result;
 }
 
-int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val)
+int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val)
 {
-       return _iwl_write_targ_mem_words(bus, addr, &val, 1);
+       return _iwl_write_targ_mem_words(trans, addr, &val, 1);
 }
index aae2eeb331a8e277e8cb668c9bfab6ddc5bad799..09b856768f628bb5aad2d00a09c4ffe360db6b7a 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
 
 #include "iwl-devtrace.h"
 #include "iwl-shared.h"
-#include "iwl-bus.h"
+#include "iwl-trans.h"
 
-static inline void iwl_write8(struct iwl_bus *bus, u32 ofs, u8 val)
+static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val)
 {
-       trace_iwlwifi_dev_iowrite8(priv(bus), ofs, val);
-       bus_write8(bus, ofs, val);
+       trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val);
+       iwl_trans_write8(trans, ofs, val);
 }
 
-static inline void iwl_write32(struct iwl_bus *bus, u32 ofs, u32 val)
+static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val)
 {
-       trace_iwlwifi_dev_iowrite32(priv(bus), ofs, val);
-       bus_write32(bus, ofs, val);
+       trace_iwlwifi_dev_iowrite32(trans->dev, ofs, val);
+       iwl_trans_write32(trans, ofs, val);
 }
 
-static inline u32 iwl_read32(struct iwl_bus *bus, u32 ofs)
+static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs)
 {
-       u32 val = bus_read32(bus, ofs);
-       trace_iwlwifi_dev_ioread32(priv(bus), ofs, val);
+       u32 val = iwl_trans_read32(trans, ofs);
+       trace_iwlwifi_dev_ioread32(trans->dev, ofs, val);
        return val;
 }
 
-void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask);
-void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask);
+void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask);
+void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask);
 
-int iwl_poll_bit(struct iwl_bus *bus, u32 addr,
+int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
                 u32 bits, u32 mask, int timeout);
-int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask,
+int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
                        int timeout);
 
-int iwl_grab_nic_access_silent(struct iwl_bus *bus);
-int iwl_grab_nic_access(struct iwl_bus *bus);
-void iwl_release_nic_access(struct iwl_bus *bus);
+int iwl_grab_nic_access_silent(struct iwl_trans *trans);
+bool iwl_grab_nic_access(struct iwl_trans *trans);
+void iwl_release_nic_access(struct iwl_trans *trans);
 
-u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg);
-void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value);
+u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg);
+void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value);
 
 
-u32 iwl_read_prph(struct iwl_bus *bus, u32 reg);
-void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val);
-void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask);
-void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg,
+u32 iwl_read_prph(struct iwl_trans *trans, u32 reg);
+void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val);
+void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask);
+void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg,
                            u32 bits, u32 mask);
-void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask);
+void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask);
 
-void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr,
+void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr,
                              void *buf, int words);
 
-#define iwl_read_targ_mem_words(bus, addr, buf, bufsize)       \
+#define iwl_read_targ_mem_words(trans, addr, buf, bufsize)     \
        do {                                                    \
                BUILD_BUG_ON((bufsize) % sizeof(u32));          \
-               _iwl_read_targ_mem_words(bus, addr, buf,        \
+               _iwl_read_targ_mem_words(trans, addr, buf,      \
                                         (bufsize) / sizeof(u32));\
        } while (0)
 
-int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr,
+int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
                              void *buf, int words);
 
-u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr);
-int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val);
+u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr);
+int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val);
 #endif
index 14dcbfcdc0fd3247a74f69f55460d9198840b1f9..1993a2b7ae63ce0a844b233254daf6d488d06cf9 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -71,7 +71,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = {
 /* Set led register off */
 void iwlagn_led_enable(struct iwl_priv *priv)
 {
-       iwl_write32(bus(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON);
+       iwl_write32(trans(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON);
 }
 
 /*
@@ -107,11 +107,12 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
        };
        u32 reg;
 
-       reg = iwl_read32(bus(priv), CSR_LED_REG);
+       reg = iwl_read32(trans(priv), CSR_LED_REG);
        if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
-               iwl_write32(bus(priv), CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
+               iwl_write32(trans(priv), CSR_LED_REG,
+                           reg & CSR_LED_BSM_CTRL_MSK);
 
-       return iwl_trans_send_cmd(trans(priv), &cmd);
+       return iwl_dvm_send_cmd(priv, &cmd);
 }
 
 /* Set led pattern command */
@@ -125,7 +126,7 @@ static int iwl_led_cmd(struct iwl_priv *priv,
        };
        int ret;
 
-       if (!test_bit(STATUS_READY, &priv->shrd->status))
+       if (!test_bit(STATUS_READY, &priv->status))
                return -EBUSY;
 
        if (priv->blink_on == on && priv->blink_off == off)
@@ -177,6 +178,10 @@ void iwl_leds_init(struct iwl_priv *priv)
        int mode = iwlagn_mod_params.led_mode;
        int ret;
 
+       if (mode == IWL_LED_DISABLE) {
+               IWL_INFO(priv, "Led disabled\n");
+               return;
+       }
        if (mode == IWL_LED_DEFAULT)
                mode = cfg(priv)->led_mode;
 
@@ -202,7 +207,7 @@ void iwl_leds_init(struct iwl_priv *priv)
                break;
        }
 
-       ret = led_classdev_register(bus(priv)->dev, &priv->led);
+       ret = led_classdev_register(trans(priv)->dev, &priv->led);
        if (ret) {
                kfree(priv->led.name);
                return;
index 2550b3c7dcbf4d26ed7a111944bf91ae0648bd79..b02a853103d380397b940afdfb1068c0ef37632a 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index f980e574e1f90dc38b2c9bc426107b9bb1fd400a..9212ee3bef9b5b702121575078bb3dccf1684015 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -35,7 +35,6 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
 #include <asm/div64.h>
 
 #include "iwl-eeprom.h"
-#include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-agn-calib.h"
 #include "iwl-agn.h"
 #include "iwl-shared.h"
-#include "iwl-bus.h"
 #include "iwl-trans.h"
+#include "iwl-op-mode.h"
 
 /*****************************************************************************
  *
@@ -136,7 +134,7 @@ iwlagn_iface_combinations_p2p[] = {
  * other mac80211 functions grouped here.
  */
 int iwlagn_mac_setup_register(struct iwl_priv *priv,
-                                 struct iwlagn_ucode_capabilities *capa)
+                             const struct iwl_ucode_capabilities *capa)
 {
        int ret;
        struct ieee80211_hw *hw = priv->hw;
@@ -161,11 +159,14 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
        hw->flags |= IEEE80211_HW_SUPPORTS_PS |
                     IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
 
-       if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)
+       if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
                hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
                             IEEE80211_HW_SUPPORTS_STATIC_SMPS;
 
+#ifndef CONFIG_IWLWIFI_EXPERIMENTAL_MFP
+       /* enable 11w if the uCode advertise */
        if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP)
+#endif /* !CONFIG_IWLWIFI_EXPERIMENTAL_MFP */
                hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 
        hw->sta_data_size = sizeof(struct iwl_station_priv);
@@ -195,8 +196,9 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
                            WIPHY_FLAG_DISABLE_BEACON_HINTS |
                            WIPHY_FLAG_IBSS_RSN;
 
-       if (trans(priv)->ucode_wowlan.code.len &&
-           device_can_wakeup(bus(priv)->dev)) {
+       if (priv->fw->ucode_wowlan.code.len &&
+           trans(priv)->ops->wowlan_suspend &&
+           device_can_wakeup(trans(priv)->dev)) {
                hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
                                          WIPHY_WOWLAN_DISCONNECT |
                                          WIPHY_WOWLAN_EAP_IDENTITY_REQ |
@@ -234,7 +236,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
                priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
                        &priv->bands[IEEE80211_BAND_5GHZ];
 
-       hw->wiphy->hw_version = bus_get_hw_id(bus(priv));
+       hw->wiphy->hw_version = trans(priv)->hw_id;
 
        iwl_leds_init(priv);
 
@@ -262,9 +264,9 @@ static int __iwl_up(struct iwl_priv *priv)
        struct iwl_rxon_context *ctx;
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) {
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
                IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
                return -EIO;
        }
@@ -277,13 +279,13 @@ static int __iwl_up(struct iwl_priv *priv)
                }
        }
 
-       ret = iwl_run_init_ucode(trans(priv));
+       ret = iwl_run_init_ucode(priv);
        if (ret) {
                IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret);
                goto error;
        }
 
-       ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_REGULAR);
+       ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR);
        if (ret) {
                IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret);
                goto error;
@@ -295,9 +297,9 @@ static int __iwl_up(struct iwl_priv *priv)
        return 0;
 
  error:
-       set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
-       __iwl_down(priv);
-       clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
+       set_bit(STATUS_EXIT_PENDING, &priv->status);
+       iwl_down(priv);
+       clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
        IWL_ERR(priv, "Unable to initialize device.\n");
        return ret;
@@ -305,22 +307,22 @@ static int __iwl_up(struct iwl_priv *priv)
 
 static int iwlagn_mac_start(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        int ret;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
        /* we should be verifying the device is ready to be opened */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        ret = __iwl_up(priv);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        if (ret)
                return ret;
 
        IWL_DEBUG_INFO(priv, "Start UP work done.\n");
 
        /* Now we should be done, and the READY bit should be set. */
-       if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status)))
+       if (WARN_ON(!test_bit(STATUS_READY, &priv->status)))
                ret = -EIO;
 
        iwlagn_led_enable(priv);
@@ -332,7 +334,7 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
 
 static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
@@ -341,14 +343,19 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 
        priv->is_open = 0;
 
+       mutex_lock(&priv->mutex);
        iwl_down(priv);
+       mutex_unlock(&priv->mutex);
+
+       iwl_cancel_deferred_work(priv);
 
-       flush_workqueue(priv->shrd->workqueue);
+       flush_workqueue(priv->workqueue);
 
        /* User space software may expect getting rfkill changes
-        * even if interface is down */
-       iwl_write32(bus(priv), CSR_INT, 0xFFFFFFFF);
-       iwl_enable_rfkill_int(priv);
+        * even if interface is down, trans->down will leave the RF
+        * kill interrupt enabled
+        */
+       iwl_trans_stop_hw(trans(priv));
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
@@ -357,13 +364,13 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
                                      struct ieee80211_vif *vif,
                                      struct cfg80211_gtk_rekey_data *data)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
        if (iwlagn_mod_params.sw_crypto)
                return;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif)
                goto out;
@@ -375,7 +382,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
        priv->have_rekey_data = true;
 
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
@@ -384,7 +391,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
 static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
                              struct cfg80211_wowlan *wowlan)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        int ret;
 
@@ -392,7 +399,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
                return -EINVAL;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        /* Don't attempt WoWLAN when not associated, tear down instead. */
        if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION ||
@@ -401,24 +408,22 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
                goto out;
        }
 
-       ret = iwlagn_suspend(priv, hw, wowlan);
+       ret = iwlagn_suspend(priv, wowlan);
        if (ret)
                goto error;
 
-       device_set_wakeup_enable(bus(priv)->dev, true);
+       device_set_wakeup_enable(trans(priv)->dev, true);
 
-       /* Now let the ucode operate on its own */
-       iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET,
-                         CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
+       iwl_trans_wowlan_suspend(trans(priv));
 
        goto out;
 
  error:
-       priv->shrd->wowlan = false;
+       priv->wowlan = false;
        iwlagn_prepare_restart(priv);
        ieee80211_restart_hw(priv->hw);
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return ret;
@@ -426,7 +431,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
 
 static int iwlagn_mac_resume(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct ieee80211_vif *vif;
        unsigned long flags;
@@ -434,34 +439,34 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
        int ret = -EIO;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR,
+       iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
                          CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
 
        base = priv->shrd->device_pointers.error_event_table;
        if (iwlagn_hw_valid_rtc_data_addr(base)) {
-               spin_lock_irqsave(&bus(priv)->reg_lock, flags);
-               ret = iwl_grab_nic_access_silent(bus(priv));
-               if (ret == 0) {
-                       iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, base);
-                       status = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
-                       iwl_release_nic_access(bus(priv));
+               spin_lock_irqsave(&trans(priv)->reg_lock, flags);
+               ret = iwl_grab_nic_access_silent(trans(priv));
+               if (likely(ret == 0)) {
+                       iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base);
+                       status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
+                       iwl_release_nic_access(trans(priv));
                }
-               spin_unlock_irqrestore(&bus(priv)->reg_lock, flags);
+               spin_unlock_irqrestore(&trans(priv)->reg_lock, flags);
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
                if (ret == 0) {
-                       struct iwl_trans *trans = trans(priv);
                        if (!priv->wowlan_sram)
                                priv->wowlan_sram =
-                                       kzalloc(trans->ucode_wowlan.data.len,
+                                       kzalloc(priv->fw->ucode_wowlan.data.len,
                                                GFP_KERNEL);
 
                        if (priv->wowlan_sram)
                                _iwl_read_targ_mem_words(
-                                       bus(priv), 0x800000, priv->wowlan_sram,
-                                       trans->ucode_wowlan.data.len / 4);
+                                       trans(priv), 0x800000,
+                                       priv->wowlan_sram,
+                                       priv->fw->ucode_wowlan.data.len / 4);
                }
 #endif
        }
@@ -469,9 +474,9 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
        /* we'll clear ctx->vif during iwlagn_prepare_restart() */
        vif = ctx->vif;
 
-       priv->shrd->wowlan = false;
+       priv->wowlan = false;
 
-       device_set_wakeup_enable(bus(priv)->dev, false);
+       device_set_wakeup_enable(trans(priv)->dev, false);
 
        iwlagn_prepare_restart(priv);
 
@@ -479,7 +484,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
        iwl_connection_init_rx_config(priv, ctx);
        iwlagn_set_rxon_chain(priv, ctx);
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        ieee80211_resume_disconnect(vif);
@@ -491,7 +496,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
 
 static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
        IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
                     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
@@ -506,7 +511,7 @@ static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
                                       struct ieee80211_sta *sta,
                                       u32 iv32, u16 *phase1key)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
        iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key);
 }
@@ -516,7 +521,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                              struct ieee80211_sta *sta,
                              struct ieee80211_key_conf *key)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
        struct iwl_rxon_context *ctx = vif_priv->ctx;
        int ret;
@@ -557,7 +562,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET)
                return 0;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_scan_cancel_timeout(priv, 100);
 
        BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT);
@@ -608,7 +613,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                ret = -EINVAL;
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return ret;
@@ -620,18 +625,18 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
                                   struct ieee80211_sta *sta, u16 tid, u16 *ssn,
                                   u8 buf_size)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        int ret = -EINVAL;
        struct iwl_station_priv *sta_priv = (void *) sta->drv_priv;
 
        IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
                     sta->addr, tid);
 
-       if (!(cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE))
+       if (!(hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE))
                return -EACCES;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
@@ -643,8 +648,6 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
        case IEEE80211_AMPDU_RX_STOP:
                IWL_DEBUG_HT(priv, "stop Rx\n");
                ret = iwl_sta_rx_agg_stop(priv, sta, tid);
-               if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-                       ret = 0;
                break;
        case IEEE80211_AMPDU_TX_START:
                if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG)
@@ -660,10 +663,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
                        IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
                                     priv->agg_tids_count);
                }
-               if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-                       ret = 0;
-               if (!priv->agg_tids_count && cfg(priv)->ht_params &&
-                   cfg(priv)->ht_params->use_rts_for_aggregation) {
+               if (!priv->agg_tids_count &&
+                   hw_params(priv).use_rts_for_aggregation) {
                        /*
                         * switch off RTS/CTS if it was previously enabled
                         */
@@ -677,7 +678,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
                ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size);
                break;
        }
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
        return ret;
 }
@@ -686,16 +687,13 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
                              struct ieee80211_vif *vif,
                              struct ieee80211_sta *sta)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
        bool is_ap = vif->type == NL80211_IFTYPE_STATION;
-       int ret = 0;
+       int ret;
        u8 sta_id;
 
-       IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n",
-                       sta->addr);
-       mutex_lock(&priv->shrd->mutex);
        IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
                        sta->addr);
        sta_priv->sta_id = IWL_INVALID_STATION;
@@ -710,17 +708,119 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
                IWL_ERR(priv, "Unable to add station %pM (%d)\n",
                        sta->addr, ret);
                /* Should we return success if return code is EEXIST ? */
-               goto out;
+               return ret;
        }
 
        sta_priv->sta_id = sta_id;
 
-       /* Initialize rate scaling */
-       IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
-                      sta->addr);
-       iwl_rs_rate_init(priv, sta, sta_id);
- out:
-       mutex_unlock(&priv->shrd->mutex);
+       return 0;
+}
+
+static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
+                                struct ieee80211_vif *vif,
+                                struct ieee80211_sta *sta)
+{
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+       struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+       int ret;
+
+       IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", sta->addr);
+
+       if (vif->type == NL80211_IFTYPE_STATION) {
+               /*
+                * Station will be removed from device when the RXON
+                * is set to unassociated -- just deactivate it here
+                * to avoid re-programming it.
+                */
+               ret = 0;
+               iwl_deactivate_station(priv, sta_priv->sta_id, sta->addr);
+       } else {
+               ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
+               if (ret)
+                       IWL_DEBUG_QUIET_RFKILL(priv,
+                               "Error removing station %pM\n", sta->addr);
+       }
+       return ret;
+}
+
+static int iwlagn_mac_sta_state(struct ieee80211_hw *hw,
+                               struct ieee80211_vif *vif,
+                               struct ieee80211_sta *sta,
+                               enum ieee80211_sta_state old_state,
+                               enum ieee80211_sta_state new_state)
+{
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+       struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+       enum {
+               NONE, ADD, REMOVE, HT_RATE_INIT, ADD_RATE_INIT,
+       } op = NONE;
+       int ret;
+
+       IWL_DEBUG_MAC80211(priv, "station %pM state change %d->%d\n",
+                          sta->addr, old_state, new_state);
+
+       mutex_lock(&priv->mutex);
+       if (vif->type == NL80211_IFTYPE_STATION) {
+               if (old_state == IEEE80211_STA_NOTEXIST &&
+                   new_state == IEEE80211_STA_NONE)
+                       op = ADD;
+               else if (old_state == IEEE80211_STA_NONE &&
+                        new_state == IEEE80211_STA_NOTEXIST)
+                       op = REMOVE;
+               else if (old_state == IEEE80211_STA_AUTH &&
+                        new_state == IEEE80211_STA_ASSOC)
+                       op = HT_RATE_INIT;
+       } else {
+               if (old_state == IEEE80211_STA_AUTH &&
+                   new_state == IEEE80211_STA_ASSOC)
+                       op = ADD_RATE_INIT;
+               else if (old_state == IEEE80211_STA_ASSOC &&
+                        new_state == IEEE80211_STA_AUTH)
+                       op = REMOVE;
+       }
+
+       switch (op) {
+       case ADD:
+               ret = iwlagn_mac_sta_add(hw, vif, sta);
+               break;
+       case REMOVE:
+               ret = iwlagn_mac_sta_remove(hw, vif, sta);
+               break;
+       case ADD_RATE_INIT:
+               ret = iwlagn_mac_sta_add(hw, vif, sta);
+               if (ret)
+                       break;
+               /* Initialize rate scaling */
+               IWL_DEBUG_INFO(priv,
+                              "Initializing rate scaling for station %pM\n",
+                              sta->addr);
+               iwl_rs_rate_init(priv, sta, iwl_sta_id(sta));
+               ret = 0;
+               break;
+       case HT_RATE_INIT:
+               /* Initialize rate scaling */
+               ret = iwl_sta_update_ht(priv, vif_priv->ctx, sta);
+               if (ret)
+                       break;
+               IWL_DEBUG_INFO(priv,
+                              "Initializing rate scaling for station %pM\n",
+                              sta->addr);
+               iwl_rs_rate_init(priv, sta, iwl_sta_id(sta));
+               ret = 0;
+               break;
+       default:
+               ret = 0;
+               break;
+       }
+
+       /*
+        * mac80211 might WARN if we fail, but due the way we
+        * (badly) handle hard rfkill, we might fail here
+        */
+       if (iwl_is_rfkill(priv))
+               ret = 0;
+
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return ret;
@@ -729,7 +829,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
 static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
                                struct ieee80211_channel_switch *ch_switch)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        const struct iwl_channel_info *ch_info;
        struct ieee80211_conf *conf = &hw->conf;
        struct ieee80211_channel *channel = ch_switch->channel;
@@ -747,14 +847,14 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (iwl_is_rfkill(priv->shrd))
+       if (iwl_is_rfkill(priv))
                goto out;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) ||
-           test_bit(STATUS_SCANNING, &priv->shrd->status) ||
-           test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
+           test_bit(STATUS_SCANNING, &priv->status) ||
+           test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
                goto out;
 
        if (!iwl_is_associated_ctx(ctx))
@@ -773,8 +873,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
                goto out;
        }
 
-       spin_lock_irq(&priv->shrd->lock);
-
        priv->current_ht_config.smps = conf->smps_mode;
 
        /* Configure HT40 channels */
@@ -791,23 +889,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
        iwl_set_rxon_ht(priv, ht_conf);
        iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif);
 
-       spin_unlock_irq(&priv->shrd->lock);
-
        iwl_set_rate(priv);
        /*
         * at this point, staging_rxon has the
         * configuration for channel switch
         */
-       set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status);
+       set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
        priv->switch_channel = cpu_to_le16(ch);
        if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) {
-               clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status);
+               clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
                priv->switch_channel = 0;
                ieee80211_chswitch_done(ctx->vif, false);
        }
 
 out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
@@ -816,7 +912,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
                                    unsigned int *total_flags,
                                    u64 multicast)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        __le32 filter_or = 0, filter_nand = 0;
        struct iwl_rxon_context *ctx;
 
@@ -837,7 +933,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
 
 #undef CHK
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        for_each_context(priv, ctx) {
                ctx->staging.filter_flags &= ~filter_nand;
@@ -849,7 +945,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
                 */
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        /*
         * Receiving all multicast frames is always enabled by the
@@ -863,16 +959,16 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
 
 static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) {
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
                IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n");
                goto done;
        }
-       if (iwl_is_rfkill(priv->shrd)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n");
                goto done;
        }
@@ -891,7 +987,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
        IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
        iwl_trans_wait_tx_queue_empty(trans(priv));
 done:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
@@ -900,7 +996,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
                                     enum nl80211_channel_type channel_type,
                                     int duration)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
        int err = 0;
 
@@ -911,9 +1007,9 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
                return -EOPNOTSUPP;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
+       if (test_bit(STATUS_SCAN_HW, &priv->status)) {
                err = -EBUSY;
                goto out;
        }
@@ -982,7 +1078,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
                iwlagn_disable_roc(priv);
 
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return err;
@@ -990,108 +1086,28 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
 
 static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
        if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
                return -EOPNOTSUPP;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_scan_cancel_timeout(priv, priv->hw_roc_duration);
        iwlagn_disable_roc(priv);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return 0;
 }
 
-static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw,
-                             struct ieee80211_vif *vif,
-                             const u8 *bssid,
-                             enum ieee80211_tx_sync_type type)
-{
-       struct iwl_priv *priv = hw->priv;
-       struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
-       struct iwl_rxon_context *ctx = vif_priv->ctx;
-       int ret;
-       u8 sta_id;
-
-       if (ctx->ctxid != IWL_RXON_CTX_PAN)
-               return 0;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
-
-       if (iwl_is_associated_ctx(ctx)) {
-               ret = 0;
-               goto out;
-       }
-
-       if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW,
-           &priv->shrd->status)) {
-               ret = -EBUSY;
-               goto out;
-       }
-
-       ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id);
-       if (ret)
-               goto out;
-
-       if (WARN_ON(sta_id != ctx->ap_sta_id)) {
-               ret = -EIO;
-               goto out_remove_sta;
-       }
-
-       memcpy(ctx->bssid, bssid, ETH_ALEN);
-       ctx->preauth_bssid = true;
-
-       ret = iwlagn_commit_rxon(priv, ctx);
-
-       if (ret == 0)
-               goto out;
-
- out_remove_sta:
-       iwl_remove_station(priv, sta_id, bssid);
- out:
-       mutex_unlock(&priv->shrd->mutex);
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-
-       return ret;
-}
-
-static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw,
-                                  struct ieee80211_vif *vif,
-                                  const u8 *bssid,
-                                  enum ieee80211_tx_sync_type type)
-{
-       struct iwl_priv *priv = hw->priv;
-       struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
-       struct iwl_rxon_context *ctx = vif_priv->ctx;
-
-       if (ctx->ctxid != IWL_RXON_CTX_PAN)
-               return;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
-
-       if (iwl_is_associated_ctx(ctx))
-               goto out;
-
-       iwl_remove_station(priv, ctx->ap_sta_id, bssid);
-       ctx->preauth_bssid = false;
-       /* no need to commit */
- out:
-       mutex_unlock(&priv->shrd->mutex);
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
 static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
                           enum ieee80211_rssi_event rssi_event)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        if (cfg(priv)->bt_params &&
                        cfg(priv)->bt_params->advanced_bt_coexist) {
@@ -1106,16 +1122,16 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
                                "ignoring RSSI callback\n");
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
 static int iwlagn_mac_set_tim(struct ieee80211_hw *hw,
                           struct ieee80211_sta *sta, bool set)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
-       queue_work(priv->shrd->workqueue, &priv->beacon_update);
+       queue_work(priv->workqueue, &priv->beacon_update);
 
        return 0;
 }
@@ -1124,10 +1140,9 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
                    struct ieee80211_vif *vif, u16 queue,
                    const struct ieee80211_tx_queue_params *params)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
        struct iwl_rxon_context *ctx = vif_priv->ctx;
-       unsigned long flags;
        int q;
 
        if (WARN_ON(!ctx))
@@ -1135,7 +1150,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       if (!iwl_is_ready_rf(priv->shrd)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
                return -EIO;
        }
@@ -1147,7 +1162,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
 
        q = AC_NUM - 1 - queue;
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
+       mutex_lock(&priv->mutex);
 
        ctx->qos_data.def_qos_parm.ac[q].cw_min =
                cpu_to_le16(params->cw_min);
@@ -1159,7 +1174,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
 
        ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0;
 
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
+       mutex_unlock(&priv->mutex);
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
        return 0;
@@ -1167,7 +1182,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
 
 static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
        return priv->ibss_manager == IWL_IBSS_MANAGER;
 }
@@ -1187,7 +1202,7 @@ static int iwl_setup_interface(struct iwl_priv *priv,
        struct ieee80211_vif *vif = ctx->vif;
        int err;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /*
         * This variable will be correct only when there's just
@@ -1221,7 +1236,7 @@ static int iwl_setup_interface(struct iwl_priv *priv,
 static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
                             struct ieee80211_vif *vif)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
        struct iwl_rxon_context *tmp, *ctx = NULL;
        int err;
@@ -1232,11 +1247,11 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
 
        cancel_delayed_work_sync(&priv->hw_roc_disable_work);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        iwlagn_disable_roc(priv);
 
-       if (!iwl_is_ready_rf(priv->shrd)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_WARN(priv, "Try to add interface when device not ready\n");
                err = -EINVAL;
                goto out;
@@ -1279,7 +1294,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
        ctx->vif = NULL;
        priv->iw_mode = NL80211_IFTYPE_STATION;
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
        return err;
@@ -1291,7 +1306,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv,
 {
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (priv->scan_vif == vif) {
                iwl_scan_cancel_timeout(priv, 200);
@@ -1318,12 +1333,12 @@ static void iwl_teardown_interface(struct iwl_priv *priv,
 static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw,
                              struct ieee80211_vif *vif)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        if (WARN_ON(ctx->vif != vif)) {
                struct iwl_rxon_context *tmp;
@@ -1336,7 +1351,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw,
 
        iwl_teardown_interface(priv, vif, false);
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
@@ -1346,7 +1361,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
                                struct ieee80211_vif *vif,
                                enum nl80211_iftype newtype, bool newp2p)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
        struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct iwl_rxon_context *tmp;
@@ -1358,9 +1373,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
 
        newtype = ieee80211_iftype_p2p(newtype, newp2p);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) {
+       if (!ctx->vif || !iwl_is_ready_rf(priv)) {
                /*
                 * Huh? But wait ... this can maybe happen when
                 * we're in the middle of a firmware restart!
@@ -1422,7 +1437,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
        err = 0;
 
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return err;
@@ -1432,7 +1447,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
                    struct ieee80211_vif *vif,
                    struct cfg80211_scan_request *req)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        int ret;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -1440,7 +1455,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
        if (req->n_channels == 0)
                return -EINVAL;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        /*
         * If an internal scan is in progress, just set
@@ -1469,47 +1484,20 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
-       mutex_unlock(&priv->shrd->mutex);
-
-       return ret;
-}
-
-static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
-                      struct ieee80211_vif *vif,
-                      struct ieee80211_sta *sta)
-{
-       struct iwl_priv *priv = hw->priv;
-       struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
-       int ret;
-
-       IWL_DEBUG_MAC80211(priv, "enter: received request to remove "
-                          "station %pM\n", sta->addr);
-       mutex_lock(&priv->shrd->mutex);
-       IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
-                       sta->addr);
-       ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
-       if (ret)
-               IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n",
-                       sta->addr);
-       mutex_unlock(&priv->shrd->mutex);
-       IWL_DEBUG_MAC80211(priv, "leave\n");
+       mutex_unlock(&priv->mutex);
 
        return ret;
 }
 
 static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.sta.modify_mask = 0;
-       priv->stations[sta_id].sta.sleep_tx_count = 0;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       struct iwl_addsta_cmd cmd = {
+               .mode = STA_CONTROL_MODIFY_MSK,
+               .station_flags_msk = STA_FLG_PWR_SAVE_MSK,
+               .sta.sta_id = sta_id,
+       };
 
+       iwl_send_add_sta(priv, &cmd, CMD_ASYNC);
 }
 
 static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
@@ -1517,7 +1505,7 @@ static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
                           enum sta_notify_cmd cmd,
                           struct ieee80211_sta *sta)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
        int sta_id;
 
@@ -1566,8 +1554,7 @@ struct ieee80211_ops iwlagn_hw_ops = {
        .ampdu_action = iwlagn_mac_ampdu_action,
        .hw_scan = iwlagn_mac_hw_scan,
        .sta_notify = iwlagn_mac_sta_notify,
-       .sta_add = iwlagn_mac_sta_add,
-       .sta_remove = iwlagn_mac_sta_remove,
+       .sta_state = iwlagn_mac_sta_state,
        .channel_switch = iwlagn_mac_channel_switch,
        .flush = iwlagn_mac_flush,
        .tx_last_beacon = iwlagn_mac_tx_last_beacon,
@@ -1576,8 +1563,6 @@ struct ieee80211_ops iwlagn_hw_ops = {
        .rssi_callback = iwlagn_mac_rssi_callback,
        CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd)
        CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump)
-       .tx_sync = iwlagn_mac_tx_sync,
-       .finish_tx_sync = iwlagn_mac_finish_tx_sync,
        .set_tim = iwlagn_mac_set_tim,
 };
 
@@ -1585,15 +1570,18 @@ struct ieee80211_ops iwlagn_hw_ops = {
 struct ieee80211_hw *iwl_alloc_all(void)
 {
        struct iwl_priv *priv;
+       struct iwl_op_mode *op_mode;
        /* mac80211 allocates memory for this device instance, including
         *   space for this driver's private structure */
        struct ieee80211_hw *hw;
 
-       hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops);
+       hw = ieee80211_alloc_hw(sizeof(struct iwl_priv) +
+                               sizeof(struct iwl_op_mode), &iwlagn_hw_ops);
        if (!hw)
                goto out;
 
-       priv = hw->priv;
+       op_mode = hw->priv;
+       priv = IWL_OP_MODE_GET_DVM(op_mode);
        priv->hw = hw;
 
 out:
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
new file mode 100644 (file)
index 0000000..88dc4a0
--- /dev/null
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#include <linux/sched.h>
+
+#include "iwl-notif-wait.h"
+
+
+void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait)
+{
+       spin_lock_init(&notif_wait->notif_wait_lock);
+       INIT_LIST_HEAD(&notif_wait->notif_waits);
+       init_waitqueue_head(&notif_wait->notif_waitq);
+}
+
+void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait,
+                                 struct iwl_rx_packet *pkt)
+{
+       if (!list_empty(&notif_wait->notif_waits)) {
+               struct iwl_notification_wait *w;
+
+               spin_lock(&notif_wait->notif_wait_lock);
+               list_for_each_entry(w, &notif_wait->notif_waits, list) {
+                       if (w->cmd != pkt->hdr.cmd)
+                               continue;
+                       w->triggered = true;
+                       if (w->fn)
+                               w->fn(notif_wait, pkt, w->fn_data);
+               }
+               spin_unlock(&notif_wait->notif_wait_lock);
+
+               wake_up_all(&notif_wait->notif_waitq);
+       }
+}
+
+void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
+{
+       unsigned long flags;
+       struct iwl_notification_wait *wait_entry;
+
+       spin_lock_irqsave(&notif_wait->notif_wait_lock, flags);
+       list_for_each_entry(wait_entry, &notif_wait->notif_waits, list)
+               wait_entry->aborted = true;
+       spin_unlock_irqrestore(&notif_wait->notif_wait_lock, flags);
+
+       wake_up_all(&notif_wait->notif_waitq);
+}
+
+
+void
+iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait,
+                          struct iwl_notification_wait *wait_entry,
+                          u8 cmd,
+                          void (*fn)(struct iwl_notif_wait_data *notif_wait,
+                                     struct iwl_rx_packet *pkt, void *data),
+                          void *fn_data)
+{
+       wait_entry->fn = fn;
+       wait_entry->fn_data = fn_data;
+       wait_entry->cmd = cmd;
+       wait_entry->triggered = false;
+       wait_entry->aborted = false;
+
+       spin_lock_bh(&notif_wait->notif_wait_lock);
+       list_add(&wait_entry->list, &notif_wait->notif_waits);
+       spin_unlock_bh(&notif_wait->notif_wait_lock);
+}
+
+int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
+                         struct iwl_notification_wait *wait_entry,
+                         unsigned long timeout)
+{
+       int ret;
+
+       ret = wait_event_timeout(notif_wait->notif_waitq,
+                                wait_entry->triggered || wait_entry->aborted,
+                                timeout);
+
+       spin_lock_bh(&notif_wait->notif_wait_lock);
+       list_del(&wait_entry->list);
+       spin_unlock_bh(&notif_wait->notif_wait_lock);
+
+       if (wait_entry->aborted)
+               return -EIO;
+
+       /* return value is always >= 0 */
+       if (ret <= 0)
+               return -ETIMEDOUT;
+       return 0;
+}
+
+void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
+                            struct iwl_notification_wait *wait_entry)
+{
+       spin_lock_bh(&notif_wait->notif_wait_lock);
+       list_del(&wait_entry->list);
+       spin_unlock_bh(&notif_wait->notif_wait_lock);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
new file mode 100644 (file)
index 0000000..5e8af95
--- /dev/null
@@ -0,0 +1,129 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#ifndef __iwl_notif_wait_h__
+#define __iwl_notif_wait_h__
+
+#include <linux/wait.h>
+
+#include "iwl-trans.h"
+
+struct iwl_notif_wait_data {
+       struct list_head notif_waits;
+       spinlock_t notif_wait_lock;
+       wait_queue_head_t notif_waitq;
+};
+
+/**
+ * struct iwl_notification_wait - notification wait entry
+ * @list: list head for global list
+ * @fn: function called with the notification
+ * @cmd: command ID
+ *
+ * This structure is not used directly, to wait for a
+ * notification declare it on the stack, and call
+ * iwlagn_init_notification_wait() with appropriate
+ * parameters. Then do whatever will cause the ucode
+ * to notify the driver, and to wait for that then
+ * call iwlagn_wait_notification().
+ *
+ * Each notification is one-shot. If at some point we
+ * need to support multi-shot notifications (which
+ * can't be allocated on the stack) we need to modify
+ * the code for them.
+ */
+struct iwl_notification_wait {
+       struct list_head list;
+
+       void (*fn)(struct iwl_notif_wait_data *notif_data,
+                  struct iwl_rx_packet *pkt, void *data);
+       void *fn_data;
+
+       u8 cmd;
+       bool triggered, aborted;
+};
+
+
+/* caller functions */
+void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data);
+void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data,
+                                 struct iwl_rx_packet *pkt);
+void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data);
+
+/* user functions */
+void __acquires(wait_entry)
+iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data,
+                          struct iwl_notification_wait *wait_entry,
+                          u8 cmd,
+                          void (*fn)(struct iwl_notif_wait_data *notif_data,
+                                     struct iwl_rx_packet *pkt, void *data),
+                          void *fn_data);
+
+int __must_check __releases(wait_entry)
+iwl_wait_notification(struct iwl_notif_wait_data *notif_data,
+                     struct iwl_notification_wait *wait_entry,
+                     unsigned long timeout);
+
+void __releases(wait_entry)
+iwl_remove_notification(struct iwl_notif_wait_data *notif_data,
+                       struct iwl_notification_wait *wait_entry);
+
+#endif /* __iwl_notif_wait_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
new file mode 100644 (file)
index 0000000..6ea4163
--- /dev/null
@@ -0,0 +1,216 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#ifndef __iwl_op_mode_h__
+#define __iwl_op_mode_h__
+
+struct iwl_op_mode;
+struct iwl_trans;
+struct sk_buff;
+struct iwl_device_cmd;
+struct iwl_rx_cmd_buffer;
+struct iwl_fw;
+
+/**
+ * DOC: Operational mode - what is it ?
+ *
+ * The operational mode (a.k.a. op_mode) is the layer that implements
+ * mac80211's handlers. It knows two APIs: mac80211's and the fw's. It uses
+ * the transport API to access the HW. The op_mode doesn't need to know how the
+ * underlying HW works, since the transport layer takes care of that.
+ *
+ * There can be several op_mode: i.e. different fw APIs will require two
+ * different op_modes. This is why the op_mode is virtualized.
+ */
+
+/**
+ * DOC: Life cycle of the Operational mode
+ *
+ * The operational mode has a very simple life cycle.
+ *
+ *     1) The driver layer (iwl-drv.c) chooses the op_mode based on the
+ *        capabilities advertized by the fw file (in TLV format).
+ *     2) The driver layer starts the op_mode (ops->start)
+ *     3) The op_mode registers registers mac80211
+ *     4) The op_mode is governed by mac80211
+ *     5) The driver layer stops the op_mode
+ */
+
+/**
+ * struct iwl_op_mode_ops - op_mode specific operations
+ *
+ * The op_mode exports its ops so that external components can start it and
+ * interact with it. The driver layer typically calls the start and stop
+ * handlers, the transport layer calls the others.
+ *
+ * All the handlers MUST be implemented
+ *
+ * @start: start the op_mode. The transport layer is already allocated.
+ *     May sleep
+ * @stop: stop the op_mode. Must free all the memory allocated.
+ *     May sleep
+ * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the
+ *     HCMD the this Rx responds to.
+ *     Must be atomic.
+ * @queue_full: notifies that a HW queue is full. Ac is the ac of the queue
+ *     Must be atomic
+ * @queue_not_full: notifies that a HW queue is not full any more.
+ *     Ac is the ac of the queue. Must be atomic
+ * @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that
+ *     the radio is killed. Must be atomic.
+ * @free_skb: allows the transport layer to free skbs that haven't been
+ *     reclaimed by the op_mode. This can happen when the driver is freed and
+ *     there are Tx packets pending in the transport layer.
+ *     Must be atomic
+ * @nic_error: error notification. Must be atomic
+ * @cmd_queue_full: Called when the command queue gets full. Must be atomic.
+ * @nic_config: configure NIC, called before firmware is started.
+ *     May sleep
+ */
+struct iwl_op_mode_ops {
+       struct iwl_op_mode *(*start)(struct iwl_trans *trans,
+                                    const struct iwl_fw *fw);
+       void (*stop)(struct iwl_op_mode *op_mode);
+       int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
+                 struct iwl_device_cmd *cmd);
+       void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac);
+       void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac);
+       void (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state);
+       void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
+       void (*nic_error)(struct iwl_op_mode *op_mode);
+       void (*cmd_queue_full)(struct iwl_op_mode *op_mode);
+       void (*nic_config)(struct iwl_op_mode *op_mode);
+};
+
+/**
+ * struct iwl_op_mode - operational mode
+ *
+ * This holds an implementation of the mac80211 / fw API.
+ *
+ * @ops - pointer to its own ops
+ */
+struct iwl_op_mode {
+       const struct iwl_op_mode_ops *ops;
+       const struct iwl_trans *trans;
+
+       char op_mode_specific[0] __aligned(sizeof(void *));
+};
+
+static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)
+{
+       might_sleep();
+
+       op_mode->ops->stop(op_mode);
+}
+
+static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode,
+                                 struct iwl_rx_cmd_buffer *rxb,
+                                 struct iwl_device_cmd *cmd)
+{
+       return op_mode->ops->rx(op_mode, rxb, cmd);
+}
+
+static inline void iwl_op_mode_queue_full(struct iwl_op_mode *op_mode, u8 ac)
+{
+       op_mode->ops->queue_full(op_mode, ac);
+}
+
+static inline void iwl_op_mode_queue_not_full(struct iwl_op_mode *op_mode,
+                                             u8 ac)
+{
+       op_mode->ops->queue_not_full(op_mode, ac);
+}
+
+static inline void iwl_op_mode_hw_rf_kill(struct iwl_op_mode *op_mode,
+                                         bool state)
+{
+       op_mode->ops->hw_rf_kill(op_mode, state);
+}
+
+static inline void iwl_op_mode_free_skb(struct iwl_op_mode *op_mode,
+                                       struct sk_buff *skb)
+{
+       op_mode->ops->free_skb(op_mode, skb);
+}
+
+static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode)
+{
+       op_mode->ops->nic_error(op_mode);
+}
+
+static inline void iwl_op_mode_cmd_queue_full(struct iwl_op_mode *op_mode)
+{
+       op_mode->ops->cmd_queue_full(op_mode);
+}
+
+static inline void iwl_op_mode_nic_config(struct iwl_op_mode *op_mode)
+{
+       might_sleep();
+       op_mode->ops->nic_config(op_mode);
+}
+
+/*****************************************************
+* Op mode layers implementations
+******************************************************/
+extern const struct iwl_op_mode_ops iwl_dvm_ops;
+
+#endif /* __iwl_op_mode_h__ */
index fb30ea7ca96b54d43aa1bf0048d52a7c0f4df161..c5e339ee918b03bb49c689eca7f33b0fc7ad592a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
 
-#include "iwl-bus.h"
 #include "iwl-io.h"
 #include "iwl-shared.h"
 #include "iwl-trans.h"
 #include "iwl-csr.h"
 #include "iwl-cfg.h"
-
-/* PCI registers */
-#define PCI_CFG_RETRY_TIMEOUT  0x041
-#define PCI_CFG_LINK_CTRL_VAL_L0S_EN   0x01
-#define PCI_CFG_LINK_CTRL_VAL_L1_EN    0x02
-
-struct iwl_pci_bus {
-       /* basic pci-network driver stuff */
-       struct pci_dev *pci_dev;
-
-       /* pci hardware address support */
-       void __iomem *hw_base;
-};
-
-#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \
-                       ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific))
-
-#define IWL_BUS_GET_PCI_DEV(_iwl_bus) \
-                       ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev)
-
-static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus)
-{
-       int pos;
-       u16 pci_lnk_ctl;
-
-       struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
-
-       pos = pci_pcie_cap(pci_dev);
-       pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
-       return pci_lnk_ctl;
-}
-
-static bool iwl_pci_is_pm_supported(struct iwl_bus *bus)
-{
-       u16 lctl = iwl_pciexp_link_ctrl(bus);
-
-       return !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
-}
-
-static void iwl_pci_apm_config(struct iwl_bus *bus)
-{
-       /*
-        * HW bug W/A for instability in PCIe bus L0S->L1 transition.
-        * Check if BIOS (or OS) enabled L1-ASPM on this device.
-        * If so (likely), disable L0S, so device moves directly L0->L1;
-        *    costs negligible amount of power savings.
-        * If not (unlikely), enable L0S, so there is at least some
-        *    power savings, even without L1.
-        */
-       u16 lctl = iwl_pciexp_link_ctrl(bus);
-
-       if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
-                               PCI_CFG_LINK_CTRL_VAL_L1_EN) {
-               /* L1-ASPM enabled; disable(!) L0S */
-               iwl_set_bit(bus, CSR_GIO_REG,
-                               CSR_GIO_REG_VAL_L0S_ENABLED);
-               dev_printk(KERN_INFO, bus->dev, "L1 Enabled; Disabling L0S\n");
-       } else {
-               /* L1-ASPM disabled; enable(!) L0S */
-               iwl_clear_bit(bus, CSR_GIO_REG,
-                               CSR_GIO_REG_VAL_L0S_ENABLED);
-               dev_printk(KERN_INFO, bus->dev, "L1 Disabled; Enabling L0S\n");
-       }
-}
-
-static void iwl_pci_get_hw_id_string(struct iwl_bus *bus, char buf[],
-                             int buf_len)
-{
-       struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
-
-       snprintf(buf, buf_len, "PCI ID: 0x%04X:0x%04X", pci_dev->device,
-                pci_dev->subsystem_device);
-}
-
-static u32 iwl_pci_get_hw_id(struct iwl_bus *bus)
-{
-       struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
-
-       return (pci_dev->device << 16) + pci_dev->subsystem_device;
-}
-
-static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val)
-{
-       iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs);
-}
-
-static void iwl_pci_write32(struct iwl_bus *bus, u32 ofs, u32 val)
-{
-       iowrite32(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs);
-}
-
-static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs)
-{
-       u32 val = ioread32(IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs);
-       return val;
-}
-
-static const struct iwl_bus_ops bus_ops_pci = {
-       .get_pm_support = iwl_pci_is_pm_supported,
-       .apm_config = iwl_pci_apm_config,
-       .get_hw_id_string = iwl_pci_get_hw_id_string,
-       .get_hw_id = iwl_pci_get_hw_id,
-       .write8 = iwl_pci_write8,
-       .write32 = iwl_pci_write32,
-       .read32 = iwl_pci_read32,
-};
+#include "iwl-drv.h"
+#include "iwl-trans.h"
 
 #define IWL_PCI_DEVICE(dev, subdev, cfg) \
        .vendor = PCI_VENDOR_ID_INTEL,  .device = (dev), \
@@ -263,9 +158,9 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
        {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)},
        {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)},
        {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)},
-       {IWL_PCI_DEVICE(0x0082, 0x1341, iwl6005_2agn_d_cfg)},
-       {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_cfg)},/* low 5GHz active */
-       {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_cfg)},/* high 5GHz active */
+       {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)},
+       {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */
+       {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */
 
 /* 6x30 Series */
        {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)},
@@ -346,6 +241,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
        {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)},
        {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)},
        {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)},
+       {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)},
 
 /* 105 Series */
        {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)},
@@ -362,132 +258,62 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 };
 MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
 
+/* PCI registers */
+#define PCI_CFG_RETRY_TIMEOUT  0x041
+
 static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
-       struct iwl_bus *bus;
-       struct iwl_pci_bus *pci_bus;
-       u16 pci_cmd;
+       const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
+       struct iwl_shared *shrd;
+       struct iwl_trans *iwl_trans;
        int err;
 
-       bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL);
-       if (!bus) {
+       shrd = kzalloc(sizeof(*iwl_trans->shrd), GFP_KERNEL);
+       if (!shrd) {
                dev_printk(KERN_ERR, &pdev->dev,
-                          "Couldn't allocate iwl_pci_bus");
+                          "Couldn't allocate iwl_shared");
                err = -ENOMEM;
-               goto out_no_pci;
+               goto out_free_bus;
        }
 
-       pci_bus = IWL_BUS_GET_PCI_BUS(bus);
-       pci_bus->pci_dev = pdev;
-
-       pci_set_drvdata(pdev, bus);
-
-       /* W/A - seems to solve weird behavior. We need to remove this if we
-        * don't want to stay in L1 all the time. This wastes a lot of power */
-       pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
-                               PCIE_LINK_STATE_CLKPM);
-
-       if (pci_enable_device(pdev)) {
-               err = -ENODEV;
-               goto out_no_pci;
-       }
-
-       pci_set_master(pdev);
-
-       err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
-       if (!err)
-               err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
-       if (err) {
-               err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-               if (!err)
-                       err = pci_set_consistent_dma_mask(pdev,
-                                                       DMA_BIT_MASK(32));
-               /* both attempts failed: */
-               if (err) {
-                       dev_printk(KERN_ERR, bus->dev,
-                                  "No suitable DMA available.\n");
-                       goto out_pci_disable_device;
-               }
-       }
-
-       err = pci_request_regions(pdev, DRV_NAME);
-       if (err) {
-               dev_printk(KERN_ERR, bus->dev, "pci_request_regions failed");
-               goto out_pci_disable_device;
-       }
-
-       pci_bus->hw_base = pci_iomap(pdev, 0, 0);
-       if (!pci_bus->hw_base) {
-               dev_printk(KERN_ERR, bus->dev, "pci_iomap failed");
-               err = -ENODEV;
-               goto out_pci_release_regions;
+#ifdef CONFIG_IWLWIFI_IDI
+       iwl_trans = iwl_trans_idi_alloc(shrd, pdev, ent);
+#else
+       iwl_trans = iwl_trans_pcie_alloc(shrd, pdev, ent);
+#endif
+       if (iwl_trans == NULL) {
+               err = -ENOMEM;
+               goto out_free_bus;
        }
 
-       dev_printk(KERN_INFO, &pdev->dev,
-               "pci_resource_len = 0x%08llx\n",
-               (unsigned long long) pci_resource_len(pdev, 0));
-       dev_printk(KERN_INFO, &pdev->dev,
-               "pci_resource_base = %p\n", pci_bus->hw_base);
+       shrd->trans = iwl_trans;
+       pci_set_drvdata(pdev, iwl_trans);
 
-       dev_printk(KERN_INFO, &pdev->dev,
-               "HW Revision ID = 0x%X\n", pdev->revision);
-
-       /* We disable the RETRY_TIMEOUT register (0x41) to keep
-        * PCI Tx retries from interfering with C3 CPU state */
-       pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
-
-       err = pci_enable_msi(pdev);
+       err = iwl_drv_start(shrd, iwl_trans, cfg);
        if (err)
-               dev_printk(KERN_ERR, &pdev->dev,
-                       "pci_enable_msi failed(0X%x)", err);
-
-       /* TODO: Move this away, not needed if not MSI */
-       /* enable rfkill interrupt: hw bug w/a */
-       pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
-       if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
-               pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
-               pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
-       }
-
-       bus->dev = &pdev->dev;
-       bus->irq = pdev->irq;
-       bus->ops = &bus_ops_pci;
+               goto out_free_trans;
 
-       err = iwl_probe(bus, &trans_ops_pcie, cfg);
-       if (err)
-               goto out_disable_msi;
        return 0;
 
-out_disable_msi:
-       pci_disable_msi(pdev);
-       pci_iounmap(pdev, pci_bus->hw_base);
-out_pci_release_regions:
+out_free_trans:
+       iwl_trans_free(iwl_trans);
        pci_set_drvdata(pdev, NULL);
-       pci_release_regions(pdev);
-out_pci_disable_device:
-       pci_disable_device(pdev);
-out_no_pci:
-       kfree(bus);
+out_free_bus:
+       kfree(shrd);
        return err;
 }
 
 static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 {
-       struct iwl_bus *bus = pci_get_drvdata(pdev);
-       struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus);
-       struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
-       struct iwl_shared *shrd = bus->shrd;
+       struct iwl_trans *iwl_trans = pci_get_drvdata(pdev);
+       struct iwl_shared *shrd = iwl_trans->shrd;
 
-       iwl_remove(shrd->priv);
+       iwl_drv_stop(shrd);
+       iwl_trans_free(shrd->trans);
 
-       pci_disable_msi(pci_dev);
-       pci_iounmap(pci_dev, pci_bus->hw_base);
-       pci_release_regions(pci_dev);
-       pci_disable_device(pci_dev);
-       pci_set_drvdata(pci_dev, NULL);
+       pci_set_drvdata(pdev, NULL);
 
-       kfree(bus);
+       kfree(shrd);
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -495,22 +321,20 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 static int iwl_pci_suspend(struct device *device)
 {
        struct pci_dev *pdev = to_pci_dev(device);
-       struct iwl_bus *bus = pci_get_drvdata(pdev);
-       struct iwl_shared *shrd = bus->shrd;
+       struct iwl_trans *iwl_trans = pci_get_drvdata(pdev);
 
        /* Before you put code here, think about WoWLAN. You cannot check here
         * whether WoWLAN is enabled or not, and your code will run even if
         * WoWLAN is enabled - don't kill the NIC, someone may need it in Sx.
         */
 
-       return iwl_trans_suspend(shrd->trans);
+       return iwl_trans_suspend(iwl_trans);
 }
 
 static int iwl_pci_resume(struct device *device)
 {
        struct pci_dev *pdev = to_pci_dev(device);
-       struct iwl_bus *bus = pci_get_drvdata(pdev);
-       struct iwl_shared *shrd = bus->shrd;
+       struct iwl_trans *iwl_trans = pci_get_drvdata(pdev);
 
        /* Before you put code here, think about WoWLAN. You cannot check here
         * whether WoWLAN is enabled or not, and your code will run even if
@@ -523,7 +347,7 @@ static int iwl_pci_resume(struct device *device)
         */
        pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
 
-       return iwl_trans_resume(shrd->trans);
+       return iwl_trans_resume(iwl_trans);
 }
 
 static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume);
index 2b188a6025b319ac7fcc3aa804b117ba3d29bdca..958d9d09aee3f0e55137ac58b7095a535481591d 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -215,7 +215,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
        else
                cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
 
-       if (hw_params(priv).shadow_reg_enable)
+       if (cfg(priv)->base_params->shadow_reg_enable)
                cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
        else
                cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
@@ -301,7 +301,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
        if (priv->power_data.bus_pm)
                cmd->flags |= IWL_POWER_PCI_PM_MSK;
 
-       if (hw_params(priv).shadow_reg_enable)
+       if (cfg(priv)->base_params->shadow_reg_enable)
                cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
        else
                cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
@@ -336,7 +336,7 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
                        le32_to_cpu(cmd->sleep_interval[3]),
                        le32_to_cpu(cmd->sleep_interval[4]));
 
-       return iwl_trans_send_cmd_pdu(trans(priv), POWER_TABLE_CMD, CMD_SYNC,
+       return iwl_dvm_send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC,
                                sizeof(struct iwl_powertable_cmd), cmd);
 }
 
@@ -348,7 +348,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
 
        dtimper = priv->hw->conf.ps_dtim_period ?: 1;
 
-       if (priv->shrd->wowlan)
+       if (priv->wowlan)
                iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper);
        else if (!cfg(priv)->base_params->no_idle_support &&
                 priv->hw->conf.flags & IEEE80211_CONF_IDLE)
@@ -383,7 +383,7 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
        int ret;
        bool update_chains;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /* Don't update the RX chain when chain noise calibration is running */
        update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
@@ -392,12 +392,12 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
        if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force)
                return 0;
 
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return -EIO;
 
        /* scan complete use sleep_power_next, need to be updated */
        memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd));
-       if (test_bit(STATUS_SCANNING, &priv->shrd->status) && !force) {
+       if (test_bit(STATUS_SCANNING, &priv->status) && !force) {
                IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n");
                return 0;
        }
@@ -436,7 +436,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 /* initialize to default */
 void iwl_power_initialize(struct iwl_priv *priv)
 {
-       priv->power_data.bus_pm = bus_get_pm_support(bus(priv));
+       priv->power_data.bus_pm = trans(priv)->pm_support;
 
        priv->power_data.debug_sleep_level_override = -1;
 
index 5f7b720cf1a4335236c86ed5cc1f8230658c9f01..07a19fce5fdc7cfb77b2b25cc00a976914b61d26 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
index bebdd828f324ef2295e6bc92525c401792dcdc59..a4d11016c3b46a9eea12c80180bc06d66e95b466 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index a6454726737e04b207d0c9ae710098f98cef6c63..902efe4bc89845e578a352d9f2565958f88d5e7a 100644 (file)
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
 static int iwl_send_scan_abort(struct iwl_priv *priv)
 {
        int ret;
-       struct iwl_rx_packet *pkt;
        struct iwl_host_cmd cmd = {
                .id = REPLY_SCAN_ABORT_CMD,
                .flags = CMD_SYNC | CMD_WANT_SKB,
        };
+       __le32 *status;
 
        /* Exit instantly with error when device is not ready
         * to receive scan abort command or it does not perform
         * hardware scan currently */
-       if (!test_bit(STATUS_READY, &priv->shrd->status) ||
-           !test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) ||
-           !test_bit(STATUS_SCAN_HW, &priv->shrd->status) ||
-           test_bit(STATUS_FW_ERROR, &priv->shrd->status) ||
-           test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (!test_bit(STATUS_READY, &priv->status) ||
+           !test_bit(STATUS_GEO_CONFIGURED, &priv->status) ||
+           !test_bit(STATUS_SCAN_HW, &priv->status) ||
+           test_bit(STATUS_FW_ERROR, &priv->shrd->status))
                return -EIO;
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
        if (ret)
                return ret;
 
-       pkt = (struct iwl_rx_packet *)cmd.reply_page;
-       if (pkt->u.status != CAN_ABORT_STATUS) {
+       status = (void *)cmd.resp_pkt->data;
+       if (*status != CAN_ABORT_STATUS) {
                /* The scan abort will return 1 for success or
                 * 2 for "failure".  A failure condition can be
                 * due to simply not being in an active scan which
                 * can occur if we send the scan abort before we
                 * the microcode has notified us that a scan is
                 * completed. */
-               IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
+               IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n",
+                              le32_to_cpu(*status));
                ret = -EIO;
        }
 
-       iwl_free_pages(priv->shrd, cmd.reply_page);
+       iwl_free_resp(&cmd);
        return ret;
 }
 
@@ -116,20 +116,20 @@ static void iwl_process_scan_complete(struct iwl_priv *priv)
 {
        bool aborted;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
-       if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status))
+       if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->status))
                return;
 
        IWL_DEBUG_SCAN(priv, "Completed scan.\n");
 
        cancel_delayed_work(&priv->scan_check);
 
-       aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status);
+       aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status);
        if (aborted)
                IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");
 
-       if (!test_and_clear_bit(STATUS_SCANNING, &priv->shrd->status)) {
+       if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
                goto out_settings;
        }
@@ -165,7 +165,7 @@ out_complete:
 
 out_settings:
        /* Can we still talk to firmware ? */
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return;
 
        iwlagn_post_scan(priv);
@@ -173,18 +173,18 @@ out_settings:
 
 void iwl_force_scan_end(struct iwl_priv *priv)
 {
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
-       if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) {
+       if (!test_bit(STATUS_SCANNING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n");
                return;
        }
 
        IWL_DEBUG_SCAN(priv, "Forcing scan end\n");
-       clear_bit(STATUS_SCANNING, &priv->shrd->status);
-       clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
-       clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status);
-       clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status);
+       clear_bit(STATUS_SCANNING, &priv->status);
+       clear_bit(STATUS_SCAN_HW, &priv->status);
+       clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+       clear_bit(STATUS_SCAN_COMPLETE, &priv->status);
        iwl_complete_scan(priv, true);
 }
 
@@ -192,14 +192,14 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
 {
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
-       if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) {
+       if (!test_bit(STATUS_SCANNING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n");
                return;
        }
 
-       if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) {
+       if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan abort in progress\n");
                return;
        }
@@ -218,7 +218,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
 int iwl_scan_cancel(struct iwl_priv *priv)
 {
        IWL_DEBUG_SCAN(priv, "Queuing abort scan\n");
-       queue_work(priv->shrd->workqueue, &priv->abort_scan);
+       queue_work(priv->workqueue, &priv->abort_scan);
        return 0;
 }
 
@@ -231,14 +231,14 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 {
        unsigned long timeout = jiffies + msecs_to_jiffies(ms);
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n");
 
        iwl_do_scan_abort(priv);
 
        while (time_before_eq(jiffies, timeout)) {
-               if (!test_bit(STATUS_SCAN_HW, &priv->shrd->status))
+               if (!test_bit(STATUS_SCAN_HW, &priv->status))
                        goto finished;
                msleep(20);
        }
@@ -261,13 +261,12 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 
 /* Service response to REPLY_SCAN_CMD (0x80) */
 static int iwl_rx_reply_scan(struct iwl_priv *priv,
-                             struct iwl_rx_mem_buffer *rxb,
+                             struct iwl_rx_cmd_buffer *rxb,
                              struct iwl_device_cmd *cmd)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_scanreq_notification *notif =
-           (struct iwl_scanreq_notification *)pkt->u.raw;
+       struct iwl_scanreq_notification *notif = (void *)pkt->data;
 
        IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
 #endif
@@ -276,12 +275,12 @@ static int iwl_rx_reply_scan(struct iwl_priv *priv,
 
 /* Service SCAN_START_NOTIFICATION (0x82) */
 static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb,
+                                   struct iwl_rx_cmd_buffer *rxb,
                                    struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_scanstart_notification *notif =
-           (struct iwl_scanstart_notification *)pkt->u.raw;
+       struct iwl_scanstart_notification *notif = (void *)pkt->data;
+
        priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
        IWL_DEBUG_SCAN(priv, "Scan start: "
                       "%d [802.11%s] "
@@ -303,13 +302,12 @@ static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
 
 /* Service SCAN_RESULTS_NOTIFICATION (0x83) */
 static int iwl_rx_scan_results_notif(struct iwl_priv *priv,
-                                     struct iwl_rx_mem_buffer *rxb,
+                                     struct iwl_rx_cmd_buffer *rxb,
                                      struct iwl_device_cmd *cmd)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_scanresults_notification *notif =
-           (struct iwl_scanresults_notification *)pkt->u.raw;
+       struct iwl_scanresults_notification *notif = (void *)pkt->data;
 
        IWL_DEBUG_SCAN(priv, "Scan ch.res: "
                       "%d [802.11%s] "
@@ -329,11 +327,11 @@ static int iwl_rx_scan_results_notif(struct iwl_priv *priv,
 
 /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
 static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb,
+                                      struct iwl_rx_cmd_buffer *rxb,
                                       struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
+       struct iwl_scancomplete_notification *scan_notif = (void *)pkt->data;
 
        IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
                       scan_notif->scanned_channels,
@@ -352,9 +350,9 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
         * to clear, we need to set SCAN_COMPLETE before clearing SCAN_HW
         * to avoid a race there.
         */
-       set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status);
-       clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
-       queue_work(priv->shrd->workqueue, &priv->scan_completed);
+       set_bit(STATUS_SCAN_COMPLETE, &priv->status);
+       clear_bit(STATUS_SCAN_HW, &priv->status);
+       queue_work(priv->workqueue, &priv->scan_completed);
 
        if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
            iwl_advanced_bt_coexist(priv) &&
@@ -374,7 +372,7 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
                                IWL_BT_COEX_TRAFFIC_LOAD_NONE;
                }
                priv->bt_status = scan_notif->bt_status;
-               queue_work(priv->shrd->workqueue,
+               queue_work(priv->workqueue,
                           &priv->bt_traffic_change_work);
        }
        return 0;
@@ -414,10 +412,25 @@ static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time)
        for_each_context(priv, ctx) {
                u16 value;
 
-               if (!iwl_is_associated_ctx(ctx))
-                       continue;
-               if (ctx->staging.dev_type == RXON_DEV_TYPE_P2P)
+               switch (ctx->staging.dev_type) {
+               case RXON_DEV_TYPE_P2P:
+                       /* no timing constraints */
                        continue;
+               case RXON_DEV_TYPE_ESS:
+               default:
+                       /* timing constraints if associated */
+                       if (!iwl_is_associated_ctx(ctx))
+                               continue;
+                       break;
+               case RXON_DEV_TYPE_CP:
+               case RXON_DEV_TYPE_2STA:
+                       /*
+                        * These seem to always have timers for TBTT
+                        * active in uCode even when not associated yet.
+                        */
+                       break;
+               }
+
                value = ctx->beacon_int;
                if (!value)
                        value = IWL_PASSIVE_DWELL_BASE;
@@ -559,6 +572,53 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
        return added;
 }
 
+/**
+ * iwl_fill_probe_req - fill in all required fields and IE for probe request
+ */
+
+static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
+                             const u8 *ies, int ie_len, int left)
+{
+       int len = 0;
+       u8 *pos = NULL;
+
+       /* Make sure there is enough space for the probe request,
+        * two mandatory IEs and the data */
+       left -= 24;
+       if (left < 0)
+               return 0;
+
+       frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+       memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
+       memcpy(frame->sa, ta, ETH_ALEN);
+       memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
+       frame->seq_ctrl = 0;
+
+       len += 24;
+
+       /* ...next IE... */
+       pos = &frame->u.probe_req.variable[0];
+
+       /* fill in our indirect SSID IE */
+       left -= 2;
+       if (left < 0)
+               return 0;
+       *pos++ = WLAN_EID_SSID;
+       *pos++ = 0;
+
+       len += 2;
+
+       if (WARN_ON(left < ie_len))
+               return len;
+
+       if (ies && ie_len) {
+               memcpy(pos, ies, ie_len);
+               len += ie_len;
+       }
+
+       return (u16)len;
+}
+
 static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 {
        struct iwl_host_cmd cmd = {
@@ -581,7 +641,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        u8 scan_tx_antennas = hw_params(priv).valid_tx_ant;
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (vif)
                ctx = iwl_rxon_ctx_from_vif(vif);
@@ -778,7 +838,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        scan->rx_chain = cpu_to_le16(rx_chain);
        switch (priv->scan_type) {
        case IWL_SCAN_NORMAL:
-               cmd_len = iwl_fill_probe_req(priv,
+               cmd_len = iwl_fill_probe_req(
                                        (struct ieee80211_mgmt *)scan->data,
                                        vif->addr,
                                        priv->scan_request->ie,
@@ -788,7 +848,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        case IWL_SCAN_RADIO_RESET:
        case IWL_SCAN_ROC:
                /* use bcast addr, will not be transmitted but must be valid */
-               cmd_len = iwl_fill_probe_req(priv,
+               cmd_len = iwl_fill_probe_req(
                                        (struct ieee80211_mgmt *)scan->data,
                                        iwl_bcast_addr, NULL, 0,
                                        IWL_MAX_SCAN_SIZE - sizeof(*scan));
@@ -867,15 +927,15 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        scan->len = cpu_to_le16(cmd.len[0]);
 
        /* set scan bit here for PAN params */
-       set_bit(STATUS_SCAN_HW, &priv->shrd->status);
+       set_bit(STATUS_SCAN_HW, &priv->status);
 
        ret = iwlagn_set_pan_params(priv);
        if (ret)
                return ret;
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
        if (ret) {
-               clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
+               clear_bit(STATUS_SCAN_HW, &priv->status);
                iwlagn_set_pan_params(priv);
        }
 
@@ -898,22 +958,22 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 {
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        cancel_delayed_work(&priv->scan_check);
 
-       if (!iwl_is_ready_rf(priv->shrd)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_WARN(priv, "Request scan called when driver not ready.\n");
                return -EIO;
        }
 
-       if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
+       if (test_bit(STATUS_SCAN_HW, &priv->status)) {
                IWL_DEBUG_SCAN(priv,
                        "Multiple concurrent scan requests in parallel.\n");
                return -EBUSY;
        }
 
-       if (test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) {
+       if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n");
                return -EBUSY;
        }
@@ -923,19 +983,19 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
                        scan_type == IWL_SCAN_ROC ? "remain-on-channel " :
                        "internal short ");
 
-       set_bit(STATUS_SCANNING, &priv->shrd->status);
+       set_bit(STATUS_SCANNING, &priv->status);
        priv->scan_type = scan_type;
        priv->scan_start = jiffies;
        priv->scan_band = band;
 
        ret = iwlagn_request_scan(priv, vif);
        if (ret) {
-               clear_bit(STATUS_SCANNING, &priv->shrd->status);
+               clear_bit(STATUS_SCANNING, &priv->status);
                priv->scan_type = IWL_SCAN_NORMAL;
                return ret;
        }
 
-       queue_delayed_work(priv->shrd->workqueue, &priv->scan_check,
+       queue_delayed_work(priv->workqueue, &priv->scan_check,
                           IWL_SCAN_CHECK_WATCHDOG);
 
        return 0;
@@ -948,7 +1008,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
  */
 void iwl_internal_short_hw_scan(struct iwl_priv *priv)
 {
-       queue_work(priv->shrd->workqueue, &priv->start_internal_scan);
+       queue_work(priv->workqueue, &priv->start_internal_scan);
 }
 
 static void iwl_bg_start_internal_scan(struct work_struct *work)
@@ -958,14 +1018,14 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
 
        IWL_DEBUG_SCAN(priv, "Start internal scan\n");
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        if (priv->scan_type == IWL_SCAN_RADIO_RESET) {
                IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n");
                goto unlock;
        }
 
-       if (test_bit(STATUS_SCANNING, &priv->shrd->status)) {
+       if (test_bit(STATUS_SCANNING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
                goto unlock;
        }
@@ -973,7 +1033,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
        if (iwl_scan_initiate(priv, NULL, IWL_SCAN_RADIO_RESET, priv->band))
                IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n");
  unlock:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 static void iwl_bg_scan_check(struct work_struct *data)
@@ -986,56 +1046,9 @@ static void iwl_bg_scan_check(struct work_struct *data)
        /* Since we are here firmware does not finish scan and
         * most likely is in bad shape, so we don't bother to
         * send abort command, just force scan complete to mac80211 */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_force_scan_end(priv);
-       mutex_unlock(&priv->shrd->mutex);
-}
-
-/**
- * iwl_fill_probe_req - fill in all required fields and IE for probe request
- */
-
-u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
-                      const u8 *ta, const u8 *ies, int ie_len, int left)
-{
-       int len = 0;
-       u8 *pos = NULL;
-
-       /* Make sure there is enough space for the probe request,
-        * two mandatory IEs and the data */
-       left -= 24;
-       if (left < 0)
-               return 0;
-
-       frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
-       memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
-       memcpy(frame->sa, ta, ETH_ALEN);
-       memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
-       frame->seq_ctrl = 0;
-
-       len += 24;
-
-       /* ...next IE... */
-       pos = &frame->u.probe_req.variable[0];
-
-       /* fill in our indirect SSID IE */
-       left -= 2;
-       if (left < 0)
-               return 0;
-       *pos++ = WLAN_EID_SSID;
-       *pos++ = 0;
-
-       len += 2;
-
-       if (WARN_ON(left < ie_len))
-               return len;
-
-       if (ies && ie_len) {
-               memcpy(pos, ies, ie_len);
-               len += ie_len;
-       }
-
-       return (u16)len;
+       mutex_unlock(&priv->mutex);
 }
 
 static void iwl_bg_abort_scan(struct work_struct *work)
@@ -1046,9 +1059,9 @@ static void iwl_bg_abort_scan(struct work_struct *work)
 
        /* We keep scan_check work queued in case when firmware will not
         * report back scan completed notification */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_scan_cancel_timeout(priv, 200);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 static void iwl_bg_scan_completed(struct work_struct *work)
@@ -1056,9 +1069,9 @@ static void iwl_bg_scan_completed(struct work_struct *work)
        struct iwl_priv *priv =
                container_of(work, struct iwl_priv, scan_completed);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_process_scan_complete(priv);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
@@ -1076,8 +1089,8 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv)
        cancel_work_sync(&priv->scan_completed);
 
        if (cancel_delayed_work_sync(&priv->scan_check)) {
-               mutex_lock(&priv->shrd->mutex);
+               mutex_lock(&priv->mutex);
                iwl_force_scan_end(priv);
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
        }
 }
index dc55cc4a8108191fbdb84ccdb7296cd25d394d98..45409fcfbbd78acc533fc5d0aebed34616e99233 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include <linux/types.h>
 #include <linux/spinlock.h>
-#include <linux/mutex.h>
 #include <linux/gfp.h>
-#include <linux/mm.h> /* for page_address */
 #include <net/mac80211.h>
 
 #include "iwl-commands.h"
+#include "iwl-fw.h"
 
 /**
  * DOC: shared area - role and goal
@@ -94,7 +93,6 @@
  * This implementation is iwl-pci.c
  */
 
-struct iwl_bus;
 struct iwl_priv;
 struct iwl_trans;
 struct iwl_sensitivity_ranges;
@@ -102,7 +100,7 @@ struct iwl_trans_ops;
 
 #define DRV_NAME        "iwlwifi"
 #define IWLWIFI_VERSION "in-tree:"
-#define DRV_COPYRIGHT  "Copyright(c) 2003-2011 Intel Corporation"
+#define DRV_COPYRIGHT  "Copyright(c) 2003-2012 Intel Corporation"
 #define DRV_AUTHOR     "<ilw@linux.intel.com>"
 
 extern struct iwl_mod_params iwlagn_mod_params;
@@ -117,7 +115,6 @@ extern struct iwl_mod_params iwlagn_mod_params;
  * Holds the module parameters
  *
  * @sw_crypto: using hardware encryption, default = 0
- * @num_of_queues: number of tx queue, HW dependent
  * @disable_11n: disable 11n capabilities, default = 0,
  *     use IWL_DISABLE_HT_* constants
  * @amsdu_size_8K: enable 8K amsdu size, default = 1
@@ -139,7 +136,6 @@ extern struct iwl_mod_params iwlagn_mod_params;
  */
 struct iwl_mod_params {
        int sw_crypto;
-       int num_of_queues;
        unsigned int disable_11n;
        int amsdu_size_8K;
        int antenna;
@@ -173,13 +169,12 @@ struct iwl_mod_params {
  * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX)
  * @sku: sku read from EEPROM
  * @rx_page_order: Rx buffer page order
- * @max_inst_size: for ucode use
- * @max_data_size: for ucode use
  * @ct_kill_threshold: temperature threshold - in hw dependent unit
  * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit
  *     relevant for 1000, 6000 and up
  * @wd_timeout: TX queues watchdog timeout
  * @struct iwl_sensitivity_ranges: range of sensitivity values
+ * @use_rts_for_aggregation: use rts/cts protection for HT traffic
  */
 struct iwl_hw_params {
        u8  max_txq_num;
@@ -189,11 +184,9 @@ struct iwl_hw_params {
        u8  valid_tx_ant;
        u8  valid_rx_ant;
        u8  ht40_channel;
-       bool shadow_reg_enable;
+       bool use_rts_for_aggregation;
        u16 sku;
        u32 rx_page_order;
-       u32 max_inst_size;
-       u32 max_data_size;
        u32 ct_kill_threshold;
        u32 ct_kill_exit_threshold;
        unsigned int wd_timeout;
@@ -218,45 +211,6 @@ enum iwl_ucode_type {
        IWL_UCODE_WOWLAN,
 };
 
-/**
- * struct iwl_notification_wait - notification wait entry
- * @list: list head for global list
- * @fn: function called with the notification
- * @cmd: command ID
- *
- * This structure is not used directly, to wait for a
- * notification declare it on the stack, and call
- * iwlagn_init_notification_wait() with appropriate
- * parameters. Then do whatever will cause the ucode
- * to notify the driver, and to wait for that then
- * call iwlagn_wait_notification().
- *
- * Each notification is one-shot. If at some point we
- * need to support multi-shot notifications (which
- * can't be allocated on the stack) we need to modify
- * the code for them.
- */
-struct iwl_notification_wait {
-       struct list_head list;
-
-       void (*fn)(struct iwl_trans *trans, struct iwl_rx_packet *pkt,
-                  void *data);
-       void *fn_data;
-
-       u8 cmd;
-       bool triggered, aborted;
-};
-
-/**
- * enum iwl_pa_type - Power Amplifier type
- * @IWL_PA_SYSTEM:  based on uCode configuration
- * @IWL_PA_INTERNAL: use Internal only
- */
-enum iwl_pa_type {
-       IWL_PA_SYSTEM = 0,
-       IWL_PA_INTERNAL = 1,
-};
-
 /*
  * LED mode
  *    IWL_LED_DEFAULT:  use device default
@@ -264,11 +218,80 @@ enum iwl_pa_type {
  *                     LED ON  = RF ON
  *                     LED OFF = RF OFF
  *    IWL_LED_BLINK:    adjust led blink rate based on blink table
+ *    IWL_LED_DISABLE: led disabled
  */
 enum iwl_led_mode {
        IWL_LED_DEFAULT,
        IWL_LED_RF_STATE,
        IWL_LED_BLINK,
+       IWL_LED_DISABLE,
+};
+
+/*
+ * @max_ll_items: max number of OTP blocks
+ * @shadow_ram_support: shadow support for OTP memory
+ * @led_compensation: compensate on the led on/off time per HW according
+ *     to the deviation to achieve the desired led frequency.
+ *     The detail algorithm is described in iwl-led.c
+ * @chain_noise_num_beacons: number of beacons used to compute chain noise
+ * @adv_thermal_throttle: support advance thermal throttle
+ * @support_ct_kill_exit: support ct kill exit condition
+ * @support_wimax_coexist: support wimax/wifi co-exist
+ * @plcp_delta_threshold: plcp error rate threshold used to trigger
+ *     radio tuning when there is a high receiving plcp error rate
+ * @chain_noise_scale: default chain noise scale used for gain computation
+ * @wd_timeout: TX queues watchdog timeout
+ * @max_event_log_size: size of event log buffer size for ucode event logging
+ * @shadow_reg_enable: HW shadhow register bit
+ * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
+ * @no_idle_support: do not support idle mode
+ * wd_disable: disable watchdog timer
+ */
+struct iwl_base_params {
+       int eeprom_size;
+       int num_of_queues;      /* def: HW dependent */
+       int num_of_ampdu_queues;/* def: HW dependent */
+       /* for iwl_apm_init() */
+       u32 pll_cfg_val;
+
+       const u16 max_ll_items;
+       const bool shadow_ram_support;
+       u16 led_compensation;
+       bool adv_thermal_throttle;
+       bool support_ct_kill_exit;
+       const bool support_wimax_coexist;
+       u8 plcp_delta_threshold;
+       s32 chain_noise_scale;
+       unsigned int wd_timeout;
+       u32 max_event_log_size;
+       const bool shadow_reg_enable;
+       const bool hd_v2;
+       const bool no_idle_support;
+       const bool wd_disable;
+};
+
+/*
+ * @advanced_bt_coexist: support advanced bt coexist
+ * @bt_init_traffic_load: specify initial bt traffic load
+ * @bt_prio_boost: default bt priority boost value
+ * @agg_time_limit: maximum number of uSec in aggregation
+ * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
+ */
+struct iwl_bt_params {
+       bool advanced_bt_coexist;
+       u8 bt_init_traffic_load;
+       u8 bt_prio_boost;
+       u16 agg_time_limit;
+       bool bt_sco_disable;
+       bool bt_session_2;
+};
+/*
+ * @use_rts_for_aggregation: use rts/cts protection for HT traffic
+ */
+struct iwl_ht_params {
+       const bool ht_greenfield_support; /* if used set to true */
+       bool use_rts_for_aggregation;
+       enum ieee80211_smps_mode smps_mode;
 };
 
 /**
@@ -281,9 +304,10 @@ enum iwl_led_mode {
  * @ucode_api_ok: oldest version of the uCode API that is OK to load
  *     without a warning, for use in transitions
  * @ucode_api_min: Lowest version of uCode API supported by driver.
+ * @max_inst_size: The maximal length of the fw inst section
+ * @max_data_size: The maximal length of the fw data section
  * @valid_tx_ant: valid transmit antenna
  * @valid_rx_ant: valid receive antenna
- * @sku: sku information from EEPROM
  * @eeprom_ver: EEPROM version
  * @eeprom_calib_ver: EEPROM calibration version
  * @lib: pointer to the lib ops
@@ -291,7 +315,6 @@ enum iwl_led_mode {
  * @base_params: pointer to basic parameters
  * @ht_params: point to ht patameters
  * @bt_params: pointer to bt parameters
- * @pa_type: used by 6000 series only to identify the type of Power Amplifier
  * @need_temp_offset_calib: need to perform temperature offset calibration
  * @no_xtal_calib: some devices do not need crystal calibration data,
  *     don't send it to those
@@ -318,19 +341,19 @@ struct iwl_cfg {
        const unsigned int ucode_api_max;
        const unsigned int ucode_api_ok;
        const unsigned int ucode_api_min;
+       const u32 max_data_size;
+       const u32 max_inst_size;
        u8   valid_tx_ant;
        u8   valid_rx_ant;
-       u16  sku;
        u16  eeprom_ver;
        u16  eeprom_calib_ver;
        const struct iwl_lib_ops *lib;
        void (*additional_nic_config)(struct iwl_priv *priv);
        /* params not likely to change within a device family */
-       struct iwl_base_params *base_params;
+       const struct iwl_base_params *base_params;
        /* params likely to change within a device family */
-       struct iwl_ht_params *ht_params;
-       struct iwl_bt_params *bt_params;
-       enum iwl_pa_type pa_type;         /* if used set to IWL_PA_SYSTEM */
+       const struct iwl_ht_params *ht_params;
+       const struct iwl_bt_params *bt_params;
        const bool need_temp_offset_calib; /* if used set to true */
        const bool no_xtal_calib;
        u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
@@ -345,9 +368,6 @@ struct iwl_cfg {
 /**
  * struct iwl_shared - shared fields for all the layers of the driver
  *
- * @dbg_level_dev: dbg level set per device. Prevails on
- *     iwlagn_mod_params.debug_level if set (!= 0)
- * @ucode_owner: IWL_OWNERSHIP_*
  * @cmd_queue: command queue number
  * @status: STATUS_*
  * @wowlan: are we running wowlan uCode
@@ -356,43 +376,24 @@ struct iwl_cfg {
  * @cfg: see struct iwl_cfg
  * @priv: pointer to the upper layer data
  * @trans: pointer to the transport layer data
+ * @nic: pointer to the nic data
  * @hw_params: see struct iwl_hw_params
- * @workqueue: the workqueue used by all the layers of the driver
  * @lock: protect general shared data
- * @sta_lock: protects the station table.
- *     If lock and sta_lock are needed, lock must be acquired first.
- * @mutex:
- * @wait_command_queue: the wait_queue for SYNC host command nad uCode load
+ * @wait_command_queue: the wait_queue for SYNC host commands
  * @eeprom: pointer to the eeprom/OTP image
  * @ucode_type: indicator of loaded ucode image
- * @notif_waits: things waiting for notification
- * @notif_wait_lock: lock protecting notification
- * @notif_waitq: head of notification wait queue
  * @device_pointers: pointers to ucode event tables
  */
 struct iwl_shared {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       u32 dbg_level_dev;
-#endif /* CONFIG_IWLWIFI_DEBUG */
-
-#define IWL_OWNERSHIP_DRIVER   0
-#define IWL_OWNERSHIP_TM       1
-       u8 ucode_owner;
        u8 cmd_queue;
        unsigned long status;
-       bool wowlan;
        u8 valid_contexts;
 
-       struct iwl_bus *bus;
-       struct iwl_cfg *cfg;
-       struct iwl_priv *priv;
+       const struct iwl_cfg *cfg;
        struct iwl_trans *trans;
+       void *drv;
        struct iwl_hw_params hw_params;
-
-       struct workqueue_struct *workqueue;
-       spinlock_t lock;
-       spinlock_t sta_lock;
-       struct mutex mutex;
+       const struct iwl_fw *fw;
 
        wait_queue_head_t wait_command_queue;
 
@@ -402,11 +403,6 @@ struct iwl_shared {
        /* ucode related variables */
        enum iwl_ucode_type ucode_type;
 
-       /* notification wait support */
-       struct list_head notif_waits;
-       spinlock_t notif_wait_lock;
-       wait_queue_head_t notif_waitq;
-
        struct {
                u32 error_event_table;
                u32 log_event_table;
@@ -414,112 +410,14 @@ struct iwl_shared {
 
 };
 
-/*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */
-#define priv(_m)       ((_m)->shrd->priv)
+/*Whatever _m is (iwl_trans, iwl_priv, these macros will work */
 #define cfg(_m)                ((_m)->shrd->cfg)
-#define bus(_m)                ((_m)->shrd->bus)
 #define trans(_m)      ((_m)->shrd->trans)
 #define hw_params(_m)  ((_m)->shrd->hw_params)
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-/*
- * iwl_get_debug_level: Return active debug level for device
- *
- * Using sysfs it is possible to set per device debug level. This debug
- * level will be used if set, otherwise the global debug level which can be
- * set via module parameter is used.
- */
-static inline u32 iwl_get_debug_level(struct iwl_shared *shrd)
-{
-       if (shrd->dbg_level_dev)
-               return shrd->dbg_level_dev;
-       else
-               return iwlagn_mod_params.debug_level;
-}
-#else
-static inline u32 iwl_get_debug_level(struct iwl_shared *shrd)
-{
-       return iwlagn_mod_params.debug_level;
-}
-#endif
-
-static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page)
-{
-       free_pages(page, shrd->hw_params.rx_page_order);
-}
-
-/**
- * iwl_queue_inc_wrap - increment queue index, wrap back to beginning
- * @index -- current index
- * @n_bd -- total number of entries in queue (must be power of 2)
- */
-static inline int iwl_queue_inc_wrap(int index, int n_bd)
-{
-       return ++index & (n_bd - 1);
-}
-
-/**
- * iwl_queue_dec_wrap - decrement queue index, wrap back to end
- * @index -- current index
- * @n_bd -- total number of entries in queue (must be power of 2)
- */
-static inline int iwl_queue_dec_wrap(int index, int n_bd)
-{
-       return --index & (n_bd - 1);
-}
-
-struct iwl_rx_mem_buffer {
-       dma_addr_t page_dma;
-       struct page *page;
-       struct list_head list;
-};
-
-#define rxb_addr(r) page_address(r->page)
-
-/*
- * mac80211 queues, ACs, hardware queues, FIFOs.
- *
- * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues
- *
- * Mac80211 uses the following numbers, which we get as from it
- * by way of skb_get_queue_mapping(skb):
- *
- *     VO      0
- *     VI      1
- *     BE      2
- *     BK      3
- *
- *
- * Regular (not A-MPDU) frames are put into hardware queues corresponding
- * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their
- * own queue per aggregation session (RA/TID combination), such queues are
- * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In
- * order to map frames to the right queue, we also need an AC->hw queue
- * mapping. This is implemented here.
- *
- * Due to the way hw queues are set up (by the hw specific modules like
- * iwl-4965.c, iwl-5000.c etc.), the AC->hw queue mapping is the identity
- * mapping.
- */
-
-static const u8 tid_to_ac[] = {
-       IEEE80211_AC_BE,
-       IEEE80211_AC_BK,
-       IEEE80211_AC_BK,
-       IEEE80211_AC_BE,
-       IEEE80211_AC_VI,
-       IEEE80211_AC_VI,
-       IEEE80211_AC_VO,
-       IEEE80211_AC_VO
-};
-
-static inline int get_ac_from_tid(u16 tid)
+static inline bool iwl_have_debug_level(u32 level)
 {
-       if (likely(tid < ARRAY_SIZE(tid_to_ac)))
-               return tid_to_ac[tid];
-
-       /* no support for TIDs 8-15 yet */
-       return -EINVAL;
+       return iwlagn_mod_params.debug_level & level;
 }
 
 enum iwl_rxon_context_id {
@@ -529,64 +427,10 @@ enum iwl_rxon_context_id {
        NUM_IWL_RXON_CTX
 };
 
-int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
-               struct iwl_cfg *cfg);
-void __devexit iwl_remove(struct iwl_priv * priv);
-struct iwl_device_cmd;
-int __must_check iwl_rx_dispatch(struct iwl_priv *priv,
-                                struct iwl_rx_mem_buffer *rxb,
-                                struct iwl_device_cmd *cmd);
-
 int iwlagn_hw_valid_rtc_data_addr(u32 addr);
-void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state);
-void iwl_nic_config(struct iwl_priv *priv);
-void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb);
-void iwl_apm_stop(struct iwl_priv *priv);
-int iwl_apm_init(struct iwl_priv *priv);
-void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
 const char *get_cmd_string(u8 cmd);
-bool iwl_check_for_ct_kill(struct iwl_priv *priv);
-
-void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac);
-void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac);
-
-/* notification wait support */
-void iwl_abort_notification_waits(struct iwl_shared *shrd);
-void __acquires(wait_entry)
-iwl_init_notification_wait(struct iwl_shared *shrd,
-                             struct iwl_notification_wait *wait_entry,
-                             u8 cmd,
-                             void (*fn)(struct iwl_trans *trans,
-                                        struct iwl_rx_packet *pkt,
-                                        void *data),
-                             void *fn_data);
-int __must_check __releases(wait_entry)
-iwl_wait_notification(struct iwl_shared *shrd,
-                        struct iwl_notification_wait *wait_entry,
-                        unsigned long timeout);
-void __releases(wait_entry)
-iwl_remove_notification(struct iwl_shared *shrd,
-                          struct iwl_notification_wait *wait_entry);
-
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-void iwl_reset_traffic_log(struct iwl_priv *priv);
-#endif /* CONFIG_IWLWIFI_DEBUGFS */
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-void iwl_print_rx_config_cmd(struct iwl_priv *priv,
-                            enum iwl_rxon_context_id ctxid);
-#else
-static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
-                                          enum iwl_rxon_context_id ctxid)
-{
-}
-#endif
 
 #define IWL_CMD(x) case x: return #x
-#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
-
-#define IWL_TRAFFIC_ENTRIES    (256)
-#define IWL_TRAFFIC_ENTRY_SIZE  (64)
 
 /*****************************************************
 * DRIVER STATUS FUNCTIONS
@@ -612,46 +456,4 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
 #define STATUS_CHANNEL_SWITCH_PENDING 19
 #define STATUS_SCAN_COMPLETE   20
 
-static inline int iwl_is_ready(struct iwl_shared *shrd)
-{
-       /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
-        * set but EXIT_PENDING is not */
-       return test_bit(STATUS_READY, &shrd->status) &&
-              test_bit(STATUS_GEO_CONFIGURED, &shrd->status) &&
-              !test_bit(STATUS_EXIT_PENDING, &shrd->status);
-}
-
-static inline int iwl_is_alive(struct iwl_shared *shrd)
-{
-       return test_bit(STATUS_ALIVE, &shrd->status);
-}
-
-static inline int iwl_is_init(struct iwl_shared *shrd)
-{
-       return test_bit(STATUS_INIT, &shrd->status);
-}
-
-static inline int iwl_is_rfkill_hw(struct iwl_shared *shrd)
-{
-       return test_bit(STATUS_RF_KILL_HW, &shrd->status);
-}
-
-static inline int iwl_is_rfkill(struct iwl_shared *shrd)
-{
-       return iwl_is_rfkill_hw(shrd);
-}
-
-static inline int iwl_is_ctkill(struct iwl_shared *shrd)
-{
-       return test_bit(STATUS_CT_KILL, &shrd->status);
-}
-
-static inline int iwl_is_ready_rf(struct iwl_shared *shrd)
-{
-       if (iwl_is_rfkill(shrd))
-               return 0;
-
-       return iwl_is_ready(shrd);
-}
-
 #endif /* #__iwl_shared_h__ */
index 4a5cddd2d56bfb867a21c6d00f49cd219743ce2a..b06c6763cb7aac9023181eb77ab77a237aadafeb 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,7 +70,6 @@
 #include <net/mac80211.h>
 #include <net/netlink.h>
 
-#include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-debug.h"
 #include "iwl-agn.h"
 #include "iwl-testmode.h"
 #include "iwl-trans.h"
-#include "iwl-bus.h"
+#include "iwl-fh.h"
+#include "iwl-prph.h"
+
+
+/* Periphery registers absolute lower bound. This is used in order to
+ * differentiate registery access through HBUS_TARG_PRPH_* and
+ * HBUS_TARG_MEM_* accesses.
+ */
+#define IWL_TM_ABS_PRPH_START (0xA00000)
 
 /* The TLVs used in the gnl message policy between the kernel module and
  * user space application. iwl_testmode_gnl_msg_policy is to be carried
@@ -109,19 +116,24 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
 
        [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
 
-       [IWL_TM_ATTR_SRAM_ADDR] = { .type = NLA_U32, },
-       [IWL_TM_ATTR_SRAM_SIZE] = { .type = NLA_U32, },
-       [IWL_TM_ATTR_SRAM_DUMP] = { .type = NLA_UNSPEC, },
+       [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, },
+       [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, },
+       [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, },
 
        [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
        [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
+       [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
+       [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
+       [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
+
+       [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, },
 };
 
 /*
  * See the struct iwl_rx_packet in iwl-commands.h for the format of the
  * received events from the device
  */
-static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
+static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        if (pkt)
@@ -152,7 +164,7 @@ static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
  */
 
 static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+                                     struct iwl_rx_cmd_buffer *rxb)
 {
        struct ieee80211_hw *hw = priv->hw;
        struct sk_buff *skb;
@@ -168,35 +180,36 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
        skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
                                                                GFP_ATOMIC);
        if (skb == NULL) {
-               IWL_DEBUG_INFO(priv,
+               IWL_ERR(priv,
                         "Run out of memory for messages to user space ?\n");
                return;
        }
        NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
-       NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data);
+       /* the length doesn't include len_n_flags field, so add it manually */
+       NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data);
        cfg80211_testmode_event(skb, GFP_ATOMIC);
        return;
 
 nla_put_failure:
        kfree_skb(skb);
-       IWL_DEBUG_INFO(priv, "Ouch, overran buffer, check allocation!\n");
+       IWL_ERR(priv, "Ouch, overran buffer, check allocation!\n");
 }
 
 void iwl_testmode_init(struct iwl_priv *priv)
 {
-       priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+       priv->pre_rx_handler = NULL;
        priv->testmode_trace.trace_enabled = false;
-       priv->testmode_sram.sram_readed = false;
+       priv->testmode_mem.read_in_progress = false;
 }
 
-static void iwl_sram_cleanup(struct iwl_priv *priv)
+static void iwl_mem_cleanup(struct iwl_priv *priv)
 {
-       if (priv->testmode_sram.sram_readed) {
-               kfree(priv->testmode_sram.buff_addr);
-               priv->testmode_sram.buff_addr = NULL;
-               priv->testmode_sram.buff_size = 0;
-               priv->testmode_sram.num_chunks = 0;
-               priv->testmode_sram.sram_readed = false;
+       if (priv->testmode_mem.read_in_progress) {
+               kfree(priv->testmode_mem.buff_addr);
+               priv->testmode_mem.buff_addr = NULL;
+               priv->testmode_mem.buff_size = 0;
+               priv->testmode_mem.num_chunks = 0;
+               priv->testmode_mem.read_in_progress = false;
        }
 }
 
@@ -205,7 +218,7 @@ static void iwl_trace_cleanup(struct iwl_priv *priv)
        if (priv->testmode_trace.trace_enabled) {
                if (priv->testmode_trace.cpu_addr &&
                    priv->testmode_trace.dma_addr)
-                       dma_free_coherent(bus(priv)->dev,
+                       dma_free_coherent(trans(priv)->dev,
                                        priv->testmode_trace.total_size,
                                        priv->testmode_trace.cpu_addr,
                                        priv->testmode_trace.dma_addr);
@@ -222,9 +235,10 @@ static void iwl_trace_cleanup(struct iwl_priv *priv)
 void iwl_testmode_cleanup(struct iwl_priv *priv)
 {
        iwl_trace_cleanup(priv);
-       iwl_sram_cleanup(priv);
+       iwl_mem_cleanup(priv);
 }
 
+
 /*
  * This function handles the user application commands to the ucode.
  *
@@ -233,35 +247,80 @@ void iwl_testmode_cleanup(struct iwl_priv *priv)
  * host command to the ucode.
  *
  * If any mandatory field is missing, -ENOMSG is replied to the user space
- * application; otherwise, the actual execution result of the host command to
- * ucode is replied.
+ * application; otherwise, waits for the host command to be sent and checks
+ * the return code. In case or error, it is returned, otherwise a reply is
+ * allocated and the reply RX packet
+ * is returned.
  *
  * @hw: ieee80211_hw object that represents the device
  * @tb: gnl message fields from the user space
  */
 static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_host_cmd cmd;
+       struct iwl_rx_packet *pkt;
+       struct sk_buff *skb;
+       void *reply_buf;
+       u32 reply_len;
+       int ret;
+       bool cmd_want_skb;
 
        memset(&cmd, 0, sizeof(struct iwl_host_cmd));
 
        if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
            !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
-               IWL_DEBUG_INFO(priv,
-                       "Error finding ucode command mandatory fields\n");
+               IWL_ERR(priv, "Missing ucode command mandatory fields\n");
                return -ENOMSG;
        }
 
-       cmd.flags = CMD_ON_DEMAND;
+       cmd.flags = CMD_ON_DEMAND | CMD_SYNC;
+       cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]);
+       if (cmd_want_skb)
+               cmd.flags |= CMD_WANT_SKB;
+
        cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
        cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
        cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
        cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
-       IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
+       IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
                                " len %d\n", cmd.id, cmd.flags, cmd.len[0]);
-       /* ok, let's submit the command to ucode */
-       return iwl_trans_send_cmd(trans(priv), &cmd);
+
+       ret = iwl_dvm_send_cmd(priv, &cmd);
+       if (ret) {
+               IWL_ERR(priv, "Failed to send hcmd\n");
+               return ret;
+       }
+       if (!cmd_want_skb)
+               return ret;
+
+       /* Handling return of SKB to the user */
+       pkt = cmd.resp_pkt;
+       if (!pkt) {
+               IWL_ERR(priv, "HCMD received a null response packet\n");
+               return ret;
+       }
+
+       reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+       skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, reply_len + 20);
+       reply_buf = kmalloc(reply_len, GFP_KERNEL);
+       if (!skb || !reply_buf) {
+               kfree_skb(skb);
+               kfree(reply_buf);
+               return -ENOMEM;
+       }
+
+       /* The reply is in a page, that we cannot send to user space. */
+       memcpy(reply_buf, &(pkt->hdr), reply_len);
+       iwl_free_resp(&cmd);
+
+       NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
+       NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf);
+       return cfg80211_testmode_reply(skb);
+
+nla_put_failure:
+       IWL_DEBUG_INFO(priv, "Failed creating NL attributes\n");
+       return -ENOMSG;
 }
 
 
@@ -284,84 +343,69 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
  */
 static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
 {
-       struct iwl_priv *priv = hw->priv;
-       u32 ofs, val32;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+       u32 ofs, val32, cmd;
        u8 val8;
        struct sk_buff *skb;
        int status = 0;
 
        if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
-               IWL_DEBUG_INFO(priv, "Error finding register offset\n");
+               IWL_ERR(priv, "Missing register offset\n");
                return -ENOMSG;
        }
        ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
        IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
 
-       switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+       /* Allow access only to FH/CSR/HBUS in direct mode.
+       Since we don't have the upper bounds for the CSR and HBUS segments,
+       we will use only the upper bound of FH for sanity check. */
+       cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
+       if ((cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 ||
+               cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 ||
+               cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) &&
+               (ofs >= FH_MEM_UPPER_BOUND)) {
+               IWL_ERR(priv, "offset out of segment (0x0 - 0x%x)\n",
+                       FH_MEM_UPPER_BOUND);
+               return -EINVAL;
+       }
+
+       switch (cmd) {
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
-               val32 = iwl_read32(bus(priv), ofs);
+               val32 = iwl_read_direct32(trans(priv), ofs);
                IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
 
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
                NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
                status = cfg80211_testmode_reply(skb);
                if (status < 0)
-                       IWL_DEBUG_INFO(priv,
-                                      "Error sending msg : %d\n", status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                break;
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
                if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
-                       IWL_DEBUG_INFO(priv,
-                                      "Error finding value to write\n");
+                       IWL_ERR(priv, "Missing value to write\n");
                        return -ENOMSG;
                } else {
                        val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
                        IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
-                       iwl_write32(bus(priv), ofs, val32);
+                       iwl_write_direct32(trans(priv), ofs, val32);
                }
                break;
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
                if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
-                       IWL_DEBUG_INFO(priv, "Error finding value to write\n");
+                       IWL_ERR(priv, "Missing value to write\n");
                        return -ENOMSG;
                } else {
                        val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
                        IWL_INFO(priv, "8bit value to write 0x%x\n", val8);
-                       iwl_write8(bus(priv), ofs, val8);
-               }
-               break;
-       case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
-               val32 = iwl_read_prph(bus(priv), ofs);
-               IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
-
-               skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
-               if (!skb) {
-                       IWL_DEBUG_INFO(priv, "Error allocating memory\n");
-                       return -ENOMEM;
-               }
-               NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
-               status = cfg80211_testmode_reply(skb);
-               if (status < 0)
-                       IWL_DEBUG_INFO(priv,
-                                       "Error sending msg : %d\n", status);
-               break;
-       case IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
-               if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
-                       IWL_DEBUG_INFO(priv,
-                                       "Error finding value to write\n");
-                       return -ENOMSG;
-               } else {
-                       val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
-                       IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
-                       iwl_write_prph(bus(priv), ofs, val32);
+                       iwl_write8(trans(priv), ofs, val8);
                }
                break;
        default:
-               IWL_DEBUG_INFO(priv, "Unknown testmode register command ID\n");
+               IWL_ERR(priv, "Unknown testmode register command ID\n");
                return -ENOSYS;
        }
 
@@ -378,24 +422,23 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
        struct iwl_notification_wait calib_wait;
        int ret;
 
-       iwl_init_notification_wait(priv->shrd, &calib_wait,
-                                     CALIBRATION_COMPLETE_NOTIFICATION,
-                                     NULL, NULL);
-       ret = iwl_init_alive_start(trans(priv));
+       iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
+                                  CALIBRATION_COMPLETE_NOTIFICATION,
+                                  NULL, NULL);
+       ret = iwl_init_alive_start(priv);
        if (ret) {
-               IWL_DEBUG_INFO(priv,
-                       "Error configuring init calibration: %d\n", ret);
+               IWL_ERR(priv, "Fail init calibration: %d\n", ret);
                goto cfg_init_calib_error;
        }
 
-       ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ);
+       ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ);
        if (ret)
-               IWL_DEBUG_INFO(priv, "Error detecting"
+               IWL_ERR(priv, "Error detecting"
                        " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
        return ret;
 
 cfg_init_calib_error:
-       iwl_remove_notification(priv->shrd, &calib_wait);
+       iwl_remove_notification(&priv->notif_wait, &calib_wait);
        return ret;
 }
 
@@ -417,12 +460,12 @@ cfg_init_calib_error:
  */
 static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_trans *trans = trans(priv);
        struct sk_buff *skb;
        unsigned char *rsp_data_ptr = NULL;
        int status = 0, rsp_data_len = 0;
-       u32 devid;
+       u32 devid, inst_size = 0, data_size = 0;
 
        switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
        case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
@@ -431,8 +474,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
                                                        rsp_data_len + 20);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv,
-                                      "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
                NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
@@ -441,15 +483,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                        rsp_data_len, rsp_data_ptr);
                status = cfg80211_testmode_reply(skb);
                if (status < 0)
-                       IWL_DEBUG_INFO(priv, "Error sending msg : %d\n",
-                                      status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                break;
 
        case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
-               status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT);
+               status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT);
                if (status)
-                       IWL_DEBUG_INFO(priv,
-                               "Error loading init ucode: %d\n", status);
+                       IWL_ERR(priv, "Error loading init ucode: %d\n", status);
                break;
 
        case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
@@ -458,30 +498,30 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                break;
 
        case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
-               status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR);
+               status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR);
                if (status) {
-                       IWL_DEBUG_INFO(priv,
+                       IWL_ERR(priv,
                                "Error loading runtime ucode: %d\n", status);
                        break;
                }
                status = iwl_alive_start(priv);
                if (status)
-                       IWL_DEBUG_INFO(priv,
+                       IWL_ERR(priv,
                                "Error starting the device: %d\n", status);
                break;
 
        case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
                iwl_scan_cancel_timeout(priv, 200);
                iwl_trans_stop_device(trans);
-               status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN);
+               status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
                if (status) {
-                       IWL_DEBUG_INFO(priv,
+                       IWL_ERR(priv,
                                "Error loading WOWLAN ucode: %d\n", status);
                        break;
                }
                status = iwl_alive_start(priv);
                if (status)
-                       IWL_DEBUG_INFO(priv,
+                       IWL_ERR(priv,
                                "Error starting the device: %d\n", status);
                break;
 
@@ -490,8 +530,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                        skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
                                cfg(priv)->base_params->eeprom_size + 20);
                        if (!skb) {
-                               IWL_DEBUG_INFO(priv,
-                                      "Error allocating memory\n");
+                               IWL_ERR(priv, "Memory allocation fail\n");
                                return -ENOMEM;
                        }
                        NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
@@ -501,55 +540,87 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                                priv->shrd->eeprom);
                        status = cfg80211_testmode_reply(skb);
                        if (status < 0)
-                               IWL_DEBUG_INFO(priv,
-                                              "Error sending msg : %d\n",
-                                              status);
+                               IWL_ERR(priv, "Error sending msg : %d\n",
+                                       status);
                } else
                        return -EFAULT;
                break;
 
        case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
                if (!tb[IWL_TM_ATTR_FIXRATE]) {
-                       IWL_DEBUG_INFO(priv,
-                                      "Error finding fixrate setting\n");
+                       IWL_ERR(priv, "Missing fixrate setting\n");
                        return -ENOMSG;
                }
                priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
                break;
 
        case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
-               IWL_INFO(priv, "uCode version raw: 0x%x\n", priv->ucode_ver);
+               IWL_INFO(priv, "uCode version raw: 0x%x\n",
+                        priv->fw->ucode_ver);
 
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
-               NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, priv->ucode_ver);
+               NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION,
+                           priv->fw->ucode_ver);
                status = cfg80211_testmode_reply(skb);
                if (status < 0)
-                       IWL_DEBUG_INFO(priv,
-                                       "Error sending msg : %d\n", status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                break;
 
        case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
-               devid = bus_get_hw_id(bus(priv));
+               devid = trans(priv)->hw_id;
                IWL_INFO(priv, "hw version: 0x%x\n", devid);
 
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
                NLA_PUT_U32(skb, IWL_TM_ATTR_DEVICE_ID, devid);
                status = cfg80211_testmode_reply(skb);
                if (status < 0)
-                       IWL_DEBUG_INFO(priv,
-                                       "Error sending msg : %d\n", status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
+               break;
+
+       case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
+               skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8);
+               if (!skb) {
+                       IWL_ERR(priv, "Memory allocation fail\n");
+                       return -ENOMEM;
+               }
+               switch (priv->shrd->ucode_type) {
+               case IWL_UCODE_REGULAR:
+                       inst_size = priv->fw->ucode_rt.code.len;
+                       data_size = priv->fw->ucode_rt.data.len;
+                       break;
+               case IWL_UCODE_INIT:
+                       inst_size = priv->fw->ucode_init.code.len;
+                       data_size = priv->fw->ucode_init.data.len;
+                       break;
+               case IWL_UCODE_WOWLAN:
+                       inst_size = priv->fw->ucode_wowlan.code.len;
+                       data_size = priv->fw->ucode_wowlan.data.len;
+                       break;
+               case IWL_UCODE_NONE:
+                       IWL_ERR(priv, "No uCode has not been loaded\n");
+                       break;
+               default:
+                       IWL_ERR(priv, "Unsupported uCode type\n");
+                       break;
+               }
+               NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type);
+               NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
+               NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size);
+               status = cfg80211_testmode_reply(skb);
+               if (status < 0)
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                break;
 
        default:
-               IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
+               IWL_ERR(priv, "Unknown testmode driver command ID\n");
                return -ENOSYS;
        }
        return status;
@@ -574,10 +645,10 @@ nla_put_failure:
  */
 static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct sk_buff *skb;
        int status = 0;
-       struct device *dev = bus(priv)->dev;
+       struct device *dev = trans(priv)->dev;
 
        switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
        case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
@@ -612,8 +683,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
                        sizeof(priv->testmode_trace.dma_addr) + 20);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv,
-                               "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        iwl_trace_cleanup(priv);
                        return -ENOMEM;
                }
@@ -622,9 +692,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
                        (u64 *)&priv->testmode_trace.dma_addr);
                status = cfg80211_testmode_reply(skb);
                if (status < 0) {
-                       IWL_DEBUG_INFO(priv,
-                                      "Error sending msg : %d\n",
-                                      status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                }
                priv->testmode_trace.num_chunks =
                        DIV_ROUND_UP(priv->testmode_trace.buff_size,
@@ -635,7 +703,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
                iwl_trace_cleanup(priv);
                break;
        default:
-               IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n");
+               IWL_ERR(priv, "Unknown testmode mem command ID\n");
                return -ENOSYS;
        }
        return status;
@@ -648,11 +716,11 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
-static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
+static int iwl_testmode_trace_dump(struct ieee80211_hw *hw,
                                   struct sk_buff *skb,
                                   struct netlink_callback *cb)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        int idx, length;
 
        if (priv->testmode_trace.trace_enabled &&
@@ -696,24 +764,105 @@ static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
  */
 static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        u8 owner;
 
        if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
-               IWL_DEBUG_INFO(priv, "Error finding ucode owner\n");
+               IWL_ERR(priv, "Missing ucode owner\n");
                return -ENOMSG;
        }
 
        owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
-       if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM))
-               priv->shrd->ucode_owner = owner;
-       else {
-               IWL_DEBUG_INFO(priv, "Invalid owner\n");
+       if (owner == IWL_OWNERSHIP_DRIVER) {
+               priv->ucode_owner = owner;
+               priv->pre_rx_handler = NULL;
+       } else if (owner == IWL_OWNERSHIP_TM) {
+               priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+               priv->ucode_owner = owner;
+       } else {
+               IWL_ERR(priv, "Invalid owner\n");
                return -EINVAL;
        }
        return 0;
 }
 
+static int iwl_testmode_indirect_read(struct iwl_priv *priv, u32 addr, u32 size)
+{
+       struct iwl_trans *trans = trans(priv);
+       unsigned long flags;
+       int i;
+
+       if (size & 0x3)
+               return -EINVAL;
+       priv->testmode_mem.buff_size = size;
+       priv->testmode_mem.buff_addr =
+               kmalloc(priv->testmode_mem.buff_size, GFP_KERNEL);
+       if (priv->testmode_mem.buff_addr == NULL)
+               return -ENOMEM;
+
+       /* Hard-coded periphery absolute address */
+       if (IWL_TM_ABS_PRPH_START <= addr &&
+               addr < IWL_TM_ABS_PRPH_START + PRPH_END) {
+                       spin_lock_irqsave(&trans->reg_lock, flags);
+                       iwl_grab_nic_access(trans);
+                       iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
+                               addr | (3 << 24));
+                       for (i = 0; i < size; i += 4)
+                               *(u32 *)(priv->testmode_mem.buff_addr + i) =
+                                       iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
+                       iwl_release_nic_access(trans);
+                       spin_unlock_irqrestore(&trans->reg_lock, flags);
+       } else { /* target memory (SRAM) */
+               _iwl_read_targ_mem_words(trans, addr,
+                       priv->testmode_mem.buff_addr,
+                       priv->testmode_mem.buff_size / 4);
+       }
+
+       priv->testmode_mem.num_chunks =
+               DIV_ROUND_UP(priv->testmode_mem.buff_size, DUMP_CHUNK_SIZE);
+       priv->testmode_mem.read_in_progress = true;
+       return 0;
+
+}
+
+static int iwl_testmode_indirect_write(struct iwl_priv *priv, u32 addr,
+       u32 size, unsigned char *buf)
+{
+       struct iwl_trans *trans = trans(priv);
+       u32 val, i;
+       unsigned long flags;
+
+       if (IWL_TM_ABS_PRPH_START <= addr &&
+               addr < IWL_TM_ABS_PRPH_START + PRPH_END) {
+                       /* Periphery writes can be 1-3 bytes long, or DWORDs */
+                       if (size < 4) {
+                               memcpy(&val, buf, size);
+                               spin_lock_irqsave(&trans->reg_lock, flags);
+                               iwl_grab_nic_access(trans);
+                               iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
+                                           (addr & 0x0000FFFF) |
+                                           ((size - 1) << 24));
+                               iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
+                               iwl_release_nic_access(trans);
+                               /* needed after consecutive writes w/o read */
+                               mmiowb();
+                               spin_unlock_irqrestore(&trans->reg_lock, flags);
+                       } else {
+                               if (size % 4)
+                                       return -EINVAL;
+                               for (i = 0; i < size; i += 4)
+                                       iwl_write_prph(trans, addr+i,
+                                               *(u32 *)(buf+i));
+                       }
+       } else if (iwlagn_hw_valid_rtc_data_addr(addr) ||
+               (IWLAGN_RTC_INST_LOWER_BOUND <= addr &&
+               addr < IWLAGN_RTC_INST_UPPER_BOUND)) {
+                       _iwl_write_targ_mem_words(trans, addr, buf, size/4);
+       } else
+               return -EINVAL;
+       return 0;
+}
+
 /*
  * This function handles the user application commands for SRAM data dump
  *
@@ -730,83 +879,60 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
  * @hw: ieee80211_hw object that represents the device
  * @tb: gnl message fields from the user space
  */
-static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
+static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw,
+       struct nlattr **tb)
 {
-       struct iwl_priv *priv = hw->priv;
-       u32 base, ofs, size, maxsize;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+       u32 addr, size, cmd;
+       unsigned char *buf;
 
-       if (priv->testmode_sram.sram_readed)
+       /* Both read and write should be blocked, for atomicity */
+       if (priv->testmode_mem.read_in_progress)
                return -EBUSY;
 
-       if (!tb[IWL_TM_ATTR_SRAM_ADDR]) {
-               IWL_DEBUG_INFO(priv, "Error finding SRAM offset address\n");
+       cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
+       if (!tb[IWL_TM_ATTR_MEM_ADDR]) {
+               IWL_ERR(priv, "Error finding memory offset address\n");
                return -ENOMSG;
        }
-       ofs = nla_get_u32(tb[IWL_TM_ATTR_SRAM_ADDR]);
-       if (!tb[IWL_TM_ATTR_SRAM_SIZE]) {
-               IWL_DEBUG_INFO(priv, "Error finding size for SRAM reading\n");
+       addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]);
+       if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) {
+               IWL_ERR(priv, "Error finding size for memory reading\n");
                return -ENOMSG;
        }
-       size = nla_get_u32(tb[IWL_TM_ATTR_SRAM_SIZE]);
-       switch (priv->shrd->ucode_type) {
-       case IWL_UCODE_REGULAR:
-               maxsize = trans(priv)->ucode_rt.data.len;
-               break;
-       case IWL_UCODE_INIT:
-               maxsize = trans(priv)->ucode_init.data.len;
-               break;
-       case IWL_UCODE_WOWLAN:
-               maxsize = trans(priv)->ucode_wowlan.data.len;
-               break;
-       case IWL_UCODE_NONE:
-               IWL_DEBUG_INFO(priv, "Error, uCode does not been loaded\n");
-               return -ENOSYS;
-       default:
-               IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n");
-               return -ENOSYS;
-       }
-       if ((ofs + size) > maxsize) {
-               IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n");
-               return -EINVAL;
-       }
-       priv->testmode_sram.buff_size = (size / 4) * 4;
-       priv->testmode_sram.buff_addr =
-               kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL);
-       if (priv->testmode_sram.buff_addr == NULL) {
-               IWL_DEBUG_INFO(priv, "Error allocating memory\n");
-               return -ENOMEM;
+       size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]);
+
+       if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ)
+               return iwl_testmode_indirect_read(priv, addr,  size);
+       else {
+               if (!tb[IWL_TM_ATTR_BUFFER_DUMP])
+                       return -EINVAL;
+               buf = (unsigned char *) nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]);
+               return iwl_testmode_indirect_write(priv, addr, size, buf);
        }
-       base = 0x800000;
-       _iwl_read_targ_mem_words(bus(priv), base + ofs,
-                                       priv->testmode_sram.buff_addr,
-                                       priv->testmode_sram.buff_size / 4);
-       priv->testmode_sram.num_chunks =
-               DIV_ROUND_UP(priv->testmode_sram.buff_size, DUMP_CHUNK_SIZE);
-       priv->testmode_sram.sram_readed = true;
-       return 0;
 }
 
-static int iwl_testmode_sram_dump(struct ieee80211_hw *hw, struct nlattr **tb,
-                                  struct sk_buff *skb,
-                                  struct netlink_callback *cb)
+static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw,
+                                   struct sk_buff *skb,
+                                   struct netlink_callback *cb)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        int idx, length;
 
-       if (priv->testmode_sram.sram_readed) {
+       if (priv->testmode_mem.read_in_progress) {
                idx = cb->args[4];
-               if (idx >= priv->testmode_sram.num_chunks) {
-                       iwl_sram_cleanup(priv);
+               if (idx >= priv->testmode_mem.num_chunks) {
+                       iwl_mem_cleanup(priv);
                        return -ENOENT;
                }
                length = DUMP_CHUNK_SIZE;
-               if (((idx + 1) == priv->testmode_sram.num_chunks) &&
-                   (priv->testmode_sram.buff_size % DUMP_CHUNK_SIZE))
-                       length = priv->testmode_sram.buff_size %
+               if (((idx + 1) == priv->testmode_mem.num_chunks) &&
+                   (priv->testmode_mem.buff_size % DUMP_CHUNK_SIZE))
+                       length = priv->testmode_mem.buff_size %
                                DUMP_CHUNK_SIZE;
 
-               NLA_PUT(skb, IWL_TM_ATTR_SRAM_DUMP, length,
-                       priv->testmode_sram.buff_addr +
+               NLA_PUT(skb, IWL_TM_ATTR_BUFFER_DUMP, length,
+                       priv->testmode_mem.buff_addr +
                        (DUMP_CHUNK_SIZE * idx));
                idx++;
                cb->args[4] = idx;
@@ -818,6 +944,20 @@ static int iwl_testmode_sram_dump(struct ieee80211_hw *hw, struct nlattr **tb,
        return -ENOBUFS;
 }
 
+static int iwl_testmode_notifications(struct ieee80211_hw *hw,
+       struct nlattr **tb)
+{
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+       bool enable;
+
+       enable = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]);
+       if (enable)
+               priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+       else
+               priv->pre_rx_handler = NULL;
+       return 0;
+}
+
 
 /* The testmode gnl message handler that takes the gnl message from the
  * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
@@ -841,24 +981,23 @@ static int iwl_testmode_sram_dump(struct ieee80211_hw *hw, struct nlattr **tb,
 int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
 {
        struct nlattr *tb[IWL_TM_ATTR_MAX];
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        int result;
 
        result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
                        iwl_testmode_gnl_msg_policy);
        if (result != 0) {
-               IWL_DEBUG_INFO(priv,
-                              "Error parsing the gnl message : %d\n", result);
+               IWL_ERR(priv, "Error parsing the gnl message : %d\n", result);
                return result;
        }
 
        /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
        if (!tb[IWL_TM_ATTR_COMMAND]) {
-               IWL_DEBUG_INFO(priv, "Error finding testmode command type\n");
+               IWL_ERR(priv, "Missing testmode command type\n");
                return -ENOMSG;
        }
        /* in case multiple accesses to the device happens */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
        case IWL_TM_CMD_APP2DEV_UCODE:
@@ -868,8 +1007,6 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
-       case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
-       case IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
                IWL_DEBUG_INFO(priv, "testmode cmd to register\n");
                result = iwl_testmode_reg(hw, tb);
                break;
@@ -882,6 +1019,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
        case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
        case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
        case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
+       case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
                IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
                result = iwl_testmode_driver(hw, tb);
                break;
@@ -898,18 +1036,26 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
                result = iwl_testmode_ownership(hw, tb);
                break;
 
-       case IWL_TM_CMD_APP2DEV_READ_SRAM:
-               IWL_DEBUG_INFO(priv, "testmode sram read cmd to driver\n");
-               result = iwl_testmode_sram(hw, tb);
+       case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
+       case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
+               IWL_DEBUG_INFO(priv, "testmode indirect memory cmd "
+                       "to driver\n");
+               result = iwl_testmode_indirect_mem(hw, tb);
+               break;
+
+       case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
+               IWL_DEBUG_INFO(priv, "testmode notifications cmd "
+                       "to driver\n");
+               result = iwl_testmode_notifications(hw, tb);
                break;
 
        default:
-               IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
+               IWL_ERR(priv, "Unknown testmode command\n");
                result = -ENOSYS;
                break;
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        return result;
 }
 
@@ -918,7 +1064,7 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
                      void *data, int len)
 {
        struct nlattr *tb[IWL_TM_ATTR_MAX];
-       struct iwl_priv *priv = hw->priv;
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        int result;
        u32 cmd;
 
@@ -929,15 +1075,14 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
                result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
                                iwl_testmode_gnl_msg_policy);
                if (result) {
-                       IWL_DEBUG_INFO(priv,
-                              "Error parsing the gnl message : %d\n", result);
+                       IWL_ERR(priv,
+                               "Error parsing the gnl message : %d\n", result);
                        return result;
                }
 
                /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
                if (!tb[IWL_TM_ATTR_COMMAND]) {
-                       IWL_DEBUG_INFO(priv,
-                               "Error finding testmode command type\n");
+                       IWL_ERR(priv, "Missing testmode command type\n");
                        return -ENOMSG;
                }
                cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
@@ -945,21 +1090,21 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
        }
 
        /* in case multiple accesses to the device happens */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        switch (cmd) {
        case IWL_TM_CMD_APP2DEV_READ_TRACE:
                IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n");
-               result = iwl_testmode_trace_dump(hw, tb, skb, cb);
+               result = iwl_testmode_trace_dump(hw, skb, cb);
                break;
-       case IWL_TM_CMD_APP2DEV_DUMP_SRAM:
+       case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
                IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n");
-               result = iwl_testmode_sram_dump(hw, tb, skb, cb);
+               result = iwl_testmode_buffer_dump(hw, skb, cb);
                break;
        default:
                result = -EINVAL;
                break;
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        return result;
 }
index 26138f110340819fc68407d21e3a827cce101591..6ba211b09426044df2a6564ae4cb08a749aa2d06 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -99,7 +99,7 @@
  *     to user application
  * @IWL_TM_CMD_DEV2APP_UCODE_RX_PKT:
  *     commands from kernel space to multicast the spontaneous messages
- *     to user application
+ *     to user application, or reply of host commands
  * @IWL_TM_CMD_DEV2APP_EEPROM_RSP:
  *     commands from kernel space to carry the eeprom response
  *     to user application
  *     if application has the ownership, the only host command from
  *     testmode will deliver to uCode. Default owner is driver
  *
- * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
- * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
- *     commands from user applicaiton to indirectly access peripheral register
- *
- * @IWL_TM_CMD_APP2DEV_READ_SRAM:
- * @IWL_TM_CMD_APP2DEV_DUMP_SRAM:
- *     commands from user applicaiton to read data in sram
- *
- * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Weak On Wireless LAN uCode image
+ * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image
  * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version
  * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device
- *
+ * @IWL_TM_CMD_APP2DEV_GET_FW_INFO:
+ *     retrieve information of existing loaded uCode image
+ *
+ * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
+ * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
+ * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
+ *     Commands to read/write data from periphery or SRAM memory ranges.
+ *     Fore reading, a READ command is sent from the userspace and the data
+ *     is returned when the user calls a DUMP command.
+ *     For writing, only a WRITE command is used.
+ * @IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
+ *     Command to enable/disable notifications (currently RX packets) from the
+ *     driver to userspace.
  */
 enum iwl_tm_cmd_t {
        IWL_TM_CMD_APP2DEV_UCODE                = 1,
@@ -140,14 +144,19 @@ enum iwl_tm_cmd_t {
        IWL_TM_CMD_DEV2APP_UCODE_RX_PKT         = 15,
        IWL_TM_CMD_DEV2APP_EEPROM_RSP           = 16,
        IWL_TM_CMD_APP2DEV_OWNERSHIP            = 17,
-       IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32  = 18,
-       IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32 = 19,
-       IWL_TM_CMD_APP2DEV_READ_SRAM            = 20,
-       IWL_TM_CMD_APP2DEV_DUMP_SRAM            = 21,
+       RESERVED_18                             = 18,
+       RESERVED_19                             = 19,
+       RESERVED_20                             = 20,
+       RESERVED_21                             = 21,
        IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW       = 22,
        IWL_TM_CMD_APP2DEV_GET_FW_VERSION       = 23,
        IWL_TM_CMD_APP2DEV_GET_DEVICE_ID        = 24,
-       IWL_TM_CMD_MAX                          = 25,
+       IWL_TM_CMD_APP2DEV_GET_FW_INFO          = 25,
+       IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26,
+       IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27,
+       IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28,
+       IWL_TM_CMD_APP2DEV_NOTIFICATIONS        = 29,
+       IWL_TM_CMD_MAX                          = 30,
 };
 
 /*
@@ -168,8 +177,6 @@ enum iwl_tm_cmd_t {
  *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
  *     The mandatory fields are :
  *     IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
- *     IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands;
- *     The optional fields are:
  *     IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
  *     to the ucode
  *
@@ -218,16 +225,19 @@ enum iwl_tm_cmd_t {
  *     The mandatory fields are:
  *     IWL_TM_ATTR_UCODE_OWNER for the new owner
  *
- * @IWL_TM_ATTR_SRAM_ADDR:
- * @IWL_TM_ATTR_SRAM_SIZE:
- *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_READ_SRAM,
+ * @IWL_TM_ATTR_MEM_ADDR:
+ * @IWL_TM_ATTR_BUFFER_SIZE:
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ
+ *     or IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE.
  *     The mandatory fields are:
- *     IWL_TM_ATTR_SRAM_ADDR for the address in sram
- *     IWL_TM_ATTR_SRAM_SIZE for the buffer size of data reading
+ *     IWL_TM_ATTR_MEM_ADDR for the address in SRAM/periphery to read/write
+ *     IWL_TM_ATTR_BUFFER_SIZE for the buffer size of data to read/write.
  *
- * @IWL_TM_ATTR_SRAM_DUMP:
- *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_DUMP_SRAM,
- *     IWL_TM_ATTR_SRAM_DUMP for the data in sram
+ * @IWL_TM_ATTR_BUFFER_DUMP:
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP,
+ *     IWL_TM_ATTR_BUFFER_DUMP is used for the data that was read.
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE,
+ *     this attribute contains the data to write.
  *
  * @IWL_TM_ATTR_FW_VERSION:
  *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_VERSION,
@@ -237,6 +247,23 @@ enum iwl_tm_cmd_t {
  *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_DEVICE_ID,
  *     IWL_TM_ATTR_DEVICE_ID for the device ID information
  *
+ * @IWL_TM_ATTR_FW_TYPE:
+ * @IWL_TM_ATTR_FW_INST_SIZE:
+ * @IWL_TM_ATTR_FW_DATA_SIZE:
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_INFO,
+ *     The mandatory fields are:
+ *     IWL_TM_ATTR_FW_TYPE for the uCode type (INIT/RUNTIME/...)
+ *     IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section
+ *     IWL_TM_ATTR_FW_DATA_SIZE for the size of data section
+ *
+ * @IWL_TM_ATTR_UCODE_CMD_SKB:
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag
+ *     indicates that the user wants to receive the response of the command
+ *     in a reply SKB. If it's not present, the response is not returned.
+ * @IWL_TM_ATTR_ENABLE_NOTIFICATIONS:
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_NOTIFICATIONS, this
+ *     flag enables (if present) or disables (if not) the forwarding
+ *     to userspace.
  */
 enum iwl_tm_attr_t {
        IWL_TM_ATTR_NOT_APPLICABLE              = 0,
@@ -254,12 +281,17 @@ enum iwl_tm_attr_t {
        IWL_TM_ATTR_TRACE_DUMP                  = 12,
        IWL_TM_ATTR_FIXRATE                     = 13,
        IWL_TM_ATTR_UCODE_OWNER                 = 14,
-       IWL_TM_ATTR_SRAM_ADDR                   = 15,
-       IWL_TM_ATTR_SRAM_SIZE                   = 16,
-       IWL_TM_ATTR_SRAM_DUMP                   = 17,
+       IWL_TM_ATTR_MEM_ADDR                    = 15,
+       IWL_TM_ATTR_BUFFER_SIZE                 = 16,
+       IWL_TM_ATTR_BUFFER_DUMP                 = 17,
        IWL_TM_ATTR_FW_VERSION                  = 18,
        IWL_TM_ATTR_DEVICE_ID                   = 19,
-       IWL_TM_ATTR_MAX                         = 20,
+       IWL_TM_ATTR_FW_TYPE                     = 20,
+       IWL_TM_ATTR_FW_INST_SIZE                = 21,
+       IWL_TM_ATTR_FW_DATA_SIZE                = 22,
+       IWL_TM_ATTR_UCODE_CMD_SKB               = 23,
+       IWL_TM_ATTR_ENABLE_NOTIFICATION         = 24,
+       IWL_TM_ATTR_MAX                         = 25,
 };
 
 /* uCode trace buffer */
@@ -271,4 +303,7 @@ enum iwl_tm_attr_t {
 /* Maximum data size of each dump it packet */
 #define DUMP_CHUNK_SIZE                (PAGE_SIZE - 1024)
 
+/* Address offset of data segment in SRAM */
+#define SRAM_DATA_SEG_OFFSET   0x800000
+
 #endif
index f6debf91d7b514036baf05530af28507440cab3e..c0e68097fcb5590a1fa39904ead35aabac88d7e3 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -32,6 +32,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/skbuff.h>
+#include <linux/wait.h>
 #include <linux/pci.h>
 
 #include "iwl-fh.h"
@@ -40,6 +41,7 @@
 #include "iwl-trans.h"
 #include "iwl-debug.h"
 #include "iwl-io.h"
+#include "iwl-op-mode.h"
 
 struct iwl_tx_queue;
 struct iwl_queue;
@@ -48,6 +50,12 @@ struct iwl_host_cmd;
 /*This file includes the declaration that are internal to the
  * trans_pcie layer */
 
+struct iwl_rx_mem_buffer {
+       dma_addr_t page_dma;
+       struct page *page;
+       struct list_head list;
+};
+
 /**
  * struct isr_statistics - interrupt statistics
  *
@@ -108,6 +116,26 @@ struct iwl_dma_ptr {
        size_t size;
 };
 
+/**
+ * iwl_queue_inc_wrap - increment queue index, wrap back to beginning
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (must be power of 2)
+ */
+static inline int iwl_queue_inc_wrap(int index, int n_bd)
+{
+       return ++index & (n_bd - 1);
+}
+
+/**
+ * iwl_queue_dec_wrap - decrement queue index, wrap back to end
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (must be power of 2)
+ */
+static inline int iwl_queue_dec_wrap(int index, int n_bd)
+{
+       return --index & (n_bd - 1);
+}
+
 /*
  * This queue number is required for proper operation
  * because the ucode will stop/start the scheduler as
@@ -168,6 +196,7 @@ struct iwl_queue {
  * @meta: array of meta data for each command/tx buffer
  * @dma_addr_cmd: physical address of cmd/tx buffer array
  * @txb: array of per-TFD driver data
+ * lock: queue lock
  * @time_stamp: time (in jiffies) of last read_ptr change
  * @need_update: indicates need to update read/write index
  * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
@@ -186,6 +215,7 @@ struct iwl_tx_queue {
        struct iwl_device_cmd **cmd;
        struct iwl_cmd_meta *meta;
        struct sk_buff **skbs;
+       spinlock_t lock;
        unsigned long time_stamp;
        u8 need_update;
        u8 sched_retry;
@@ -201,6 +231,8 @@ struct iwl_tx_queue {
  * @rxq: all the RX queue data
  * @rx_replenish: work that will be called when buffers need to be allocated
  * @trans: pointer to the generic transport area
+ * @irq - the irq number for the device
+ * @irq_requested: true when the irq has been requested
  * @scd_base_addr: scheduler sram base address in SRAM
  * @scd_bc_tbls: pointer to the byte count table of the scheduler
  * @kw: keep warm address
@@ -211,6 +243,11 @@ struct iwl_tx_queue {
  * @txq_ctx_active_msk: what queue is active
  * queue_stopped: tracks what queue is stopped
  * queue_stop_count: tracks what SW queue is stopped
+ * @pci_dev: basic pci-network driver stuff
+ * @hw_base: pci hardware address support
+ * @ucode_write_complete: indicates that the ucode has been copied.
+ * @ucode_write_waitq: wait queue for uCode load
+ * @status - transport specific status flags
  */
 struct iwl_trans_pcie {
        struct iwl_rx_queue rxq;
@@ -223,9 +260,12 @@ struct iwl_trans_pcie {
        int ict_index;
        u32 inta;
        bool use_ict;
+       bool irq_requested;
        struct tasklet_struct irq_tasklet;
        struct isr_statistics isr_stats;
 
+       unsigned int irq;
+       spinlock_t irq_lock;
        u32 inta_mask;
        u32 scd_base_addr;
        struct iwl_dma_ptr scd_bc_tbls;
@@ -241,6 +281,14 @@ struct iwl_trans_pcie {
 #define IWL_MAX_HW_QUEUES      32
        unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
        atomic_t queue_stop_count[4];
+
+       /* PCI bus related data */
+       struct pci_dev *pci_dev;
+       void __iomem *hw_base;
+
+       bool ucode_write_complete;
+       wait_queue_head_t ucode_write_waitq;
+       unsigned long status;
 };
 
 #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
@@ -258,7 +306,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans,
 /*****************************************************
 * ICT
 ******************************************************/
-int iwl_reset_ict(struct iwl_trans *trans);
+void iwl_reset_ict(struct iwl_trans *trans);
 void iwl_disable_ict(struct iwl_trans *trans);
 int iwl_alloc_isr_ict(struct iwl_trans *trans);
 void iwl_free_isr_ict(struct iwl_trans *trans);
@@ -275,7 +323,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans,
 int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id);
 int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
 void iwl_tx_cmd_complete(struct iwl_trans *trans,
-                        struct iwl_rx_mem_buffer *rxb, int handler_status);
+                        struct iwl_rx_cmd_buffer *rxb, int handler_status);
 void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
                                           struct iwl_tx_queue *txq,
                                           u16 byte_cnt);
@@ -308,26 +356,32 @@ void iwl_dump_csr(struct iwl_trans *trans);
 ******************************************************/
 static inline void iwl_disable_interrupts(struct iwl_trans *trans)
 {
-       clear_bit(STATUS_INT_ENABLED, &trans->shrd->status);
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       clear_bit(STATUS_INT_ENABLED, &trans_pcie->status);
 
        /* disable interrupts from uCode/NIC to host */
-       iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000);
+       iwl_write32(trans, CSR_INT_MASK, 0x00000000);
 
        /* acknowledge/clear/reset any interrupts still pending
         * from uCode or flow handler (Rx/Tx DMA) */
-       iwl_write32(bus(trans), CSR_INT, 0xffffffff);
-       iwl_write32(bus(trans), CSR_FH_INT_STATUS, 0xffffffff);
+       iwl_write32(trans, CSR_INT, 0xffffffff);
+       iwl_write32(trans, CSR_FH_INT_STATUS, 0xffffffff);
        IWL_DEBUG_ISR(trans, "Disabled interrupts\n");
 }
 
 static inline void iwl_enable_interrupts(struct iwl_trans *trans)
 {
-       struct iwl_trans_pcie *trans_pcie =
-               IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
        IWL_DEBUG_ISR(trans, "Enabling interrupts\n");
-       set_bit(STATUS_INT_ENABLED, &trans->shrd->status);
-       iwl_write32(bus(trans), CSR_INT_MASK, trans_pcie->inta_mask);
+       set_bit(STATUS_INT_ENABLED, &trans_pcie->status);
+       iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
+}
+
+static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
+{
+       IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
+       iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
 }
 
 /*
@@ -355,7 +409,7 @@ static inline u8 iwl_get_queue_ac(struct iwl_tx_queue *txq)
 }
 
 static inline void iwl_wake_queue(struct iwl_trans *trans,
-                                 struct iwl_tx_queue *txq, const char *msg)
+                                 struct iwl_tx_queue *txq)
 {
        u8 queue = txq->swq_id;
        u8 ac = queue & 3;
@@ -365,20 +419,20 @@ static inline void iwl_wake_queue(struct iwl_trans *trans,
 
        if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) {
                if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) {
-                       iwl_wake_sw_queue(priv(trans), ac);
-                       IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s",
-                                           hwq, ac, msg);
+                       iwl_op_mode_queue_not_full(trans->op_mode, ac);
+                       IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d",
+                                           hwq, ac);
                } else {
-                       IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d"
-                                           " stop count %d. %s",
-                                           hwq, ac, atomic_read(&trans_pcie->
-                                           queue_stop_count[ac]), msg);
+                       IWL_DEBUG_TX_QUEUES(trans,
+                               "Don't wake hwq %d ac %d stop count %d",
+                               hwq, ac,
+                               atomic_read(&trans_pcie->queue_stop_count[ac]));
                }
        }
 }
 
 static inline void iwl_stop_queue(struct iwl_trans *trans,
-                                 struct iwl_tx_queue *txq, const char *msg)
+                                 struct iwl_tx_queue *txq)
 {
        u8 queue = txq->swq_id;
        u8 ac = queue & 3;
@@ -388,35 +442,23 @@ static inline void iwl_stop_queue(struct iwl_trans *trans,
 
        if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) {
                if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) {
-                       iwl_stop_sw_queue(priv(trans), ac);
-                       IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d"
-                                           " stop count %d. %s",
-                                           hwq, ac, atomic_read(&trans_pcie->
-                                           queue_stop_count[ac]), msg);
+                       iwl_op_mode_queue_full(trans->op_mode, ac);
+                       IWL_DEBUG_TX_QUEUES(trans,
+                               "Stop hwq %d ac %d stop count %d",
+                               hwq, ac,
+                               atomic_read(&trans_pcie->queue_stop_count[ac]));
                } else {
-                       IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d"
-                                           " stop count %d. %s",
-                                           hwq, ac, atomic_read(&trans_pcie->
-                                           queue_stop_count[ac]), msg);
+                       IWL_DEBUG_TX_QUEUES(trans,
+                               "Don't stop hwq %d ac %d stop count %d",
+                               hwq, ac,
+                               atomic_read(&trans_pcie->queue_stop_count[ac]));
                }
        } else {
-               IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s",
-                                   hwq, msg);
+               IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped",
+                                   hwq);
        }
 }
 
-#ifdef ieee80211_stop_queue
-#undef ieee80211_stop_queue
-#endif
-
-#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
-
-#ifdef ieee80211_wake_queue
-#undef ieee80211_wake_queue
-#endif
-
-#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
-
 static inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie,
                                        int txq_id)
 {
index 65d1f05007be0e0b6ba421e24b273b3bb77adc97..32820913a2fd0523479c262efca9a72aab4e3ea3 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
 #include <linux/wait.h>
 #include <linux/gfp.h>
 
-/*TODO: Remove include to iwl-core.h*/
-#include "iwl-core.h"
+#include "iwl-prph.h"
 #include "iwl-io.h"
 #include "iwl-trans-pcie-int.h"
+#include "iwl-op-mode.h"
+
+#ifdef CONFIG_IWLWIFI_IDI
+#include "iwl-amfh.h"
+#endif
 
 /******************************************************************************
  *
@@ -136,34 +140,34 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans,
        if (q->need_update == 0)
                goto exit_unlock;
 
-       if (hw_params(trans).shadow_reg_enable) {
+       if (cfg(trans)->base_params->shadow_reg_enable) {
                /* shadow register enabled */
                /* Device expects a multiple of 8 */
                q->write_actual = (q->write & ~0x7);
-               iwl_write32(bus(trans), FH_RSCSR_CHNL0_WPTR, q->write_actual);
+               iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual);
        } else {
                /* If power-saving is in use, make sure device is awake */
                if (test_bit(STATUS_POWER_PMI, &trans->shrd->status)) {
-                       reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1);
+                       reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
 
                        if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
                                IWL_DEBUG_INFO(trans,
                                        "Rx queue requesting wakeup,"
                                        " GP1 = 0x%x\n", reg);
-                               iwl_set_bit(bus(trans), CSR_GP_CNTRL,
+                               iwl_set_bit(trans, CSR_GP_CNTRL,
                                        CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
                                goto exit_unlock;
                        }
 
                        q->write_actual = (q->write & ~0x7);
-                       iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR,
+                       iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
                                        q->write_actual);
 
                /* Else device is assumed to be awake */
                } else {
                        /* Device expects a multiple of 8 */
                        q->write_actual = (q->write & ~0x7);
-                       iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR,
+                       iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
                                q->write_actual);
                }
        }
@@ -223,7 +227,7 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
        /* If the pre-allocated buffer pool is dropping low, schedule to
         * refill it */
        if (rxq->free_count <= RX_LOW_WATERMARK)
-               queue_work(trans->shrd->workqueue, &trans_pcie->rx_replenish);
+               schedule_work(&trans_pcie->rx_replenish);
 
 
        /* If we've added more space for the firmware to place data, tell it.
@@ -308,7 +312,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
                BUG_ON(rxb->page);
                rxb->page = page;
                /* Get physical address of the RB */
-               rxb->page_dma = dma_map_page(bus(trans)->dev, page, 0,
+               rxb->page_dma = dma_map_page(trans->dev, page, 0,
                                PAGE_SIZE << hw_params(trans).rx_page_order,
                                DMA_FROM_DEVICE);
                /* dma address must be no more than 36 bits */
@@ -327,13 +331,14 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
 
 void iwlagn_rx_replenish(struct iwl_trans *trans)
 {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        unsigned long flags;
 
        iwlagn_rx_allocate(trans, GFP_KERNEL);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwlagn_rx_queue_restock(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 static void iwlagn_rx_replenish_now(struct iwl_trans *trans)
@@ -347,14 +352,115 @@ void iwl_bg_rx_replenish(struct work_struct *data)
 {
        struct iwl_trans_pcie *trans_pcie =
            container_of(data, struct iwl_trans_pcie, rx_replenish);
-       struct iwl_trans *trans = trans_pcie->trans;
 
-       if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
+       iwlagn_rx_replenish(trans_pcie->trans);
+}
+
+static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
+                               struct iwl_rx_mem_buffer *rxb)
+{
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct iwl_rx_queue *rxq = &trans_pcie->rxq;
+       struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
+       struct iwl_device_cmd *cmd;
+       unsigned long flags;
+       int len, err;
+       u16 sequence;
+       struct iwl_rx_cmd_buffer rxcb;
+       struct iwl_rx_packet *pkt;
+       bool reclaim;
+       int index, cmd_index;
+
+       if (WARN_ON(!rxb))
                return;
 
-       mutex_lock(&trans->shrd->mutex);
-       iwlagn_rx_replenish(trans);
-       mutex_unlock(&trans->shrd->mutex);
+       dma_unmap_page(trans->dev, rxb->page_dma,
+                      PAGE_SIZE << hw_params(trans).rx_page_order,
+                      DMA_FROM_DEVICE);
+
+       rxcb._page = rxb->page;
+       pkt = rxb_addr(&rxcb);
+
+       IWL_DEBUG_RX(trans, "%s, 0x%02x\n",
+                    get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
+
+
+       len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+       len += sizeof(u32); /* account for status word */
+       trace_iwlwifi_dev_rx(trans->dev, pkt, len);
+
+       /* Reclaim a command buffer only if this packet is a response
+        *   to a (driver-originated) command.
+        * If the packet (e.g. Rx frame) originated from uCode,
+        *   there is no command buffer to reclaim.
+        * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
+        *   but apparently a few don't get set; catch them here. */
+       reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
+                 (pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
+                 (pkt->hdr.cmd != REPLY_RX) &&
+                 (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
+                 (pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
+                 (pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
+                 (pkt->hdr.cmd != REPLY_TX);
+
+       sequence = le16_to_cpu(pkt->hdr.sequence);
+       index = SEQ_TO_INDEX(sequence);
+       cmd_index = get_cmd_index(&txq->q, index);
+
+       if (reclaim)
+               cmd = txq->cmd[cmd_index];
+       else
+               cmd = NULL;
+
+       /* warn if this is cmd response / notification and the uCode
+        * didn't set the SEQ_RX_FRAME for a frame that is
+        * uCode-originated
+        * If you saw this code after the second half of 2012, then
+        * please remove it
+        */
+       WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false &&
+            (!(pkt->hdr.sequence & SEQ_RX_FRAME)),
+            "reclaim is false, SEQ_RX_FRAME unset: %s\n",
+            get_cmd_string(pkt->hdr.cmd));
+
+       err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
+
+       /*
+        * XXX: After here, we should always check rxcb._page
+        * against NULL before touching it or its virtual
+        * memory (pkt). Because some rx_handler might have
+        * already taken or freed the pages.
+        */
+
+       if (reclaim) {
+               /* Invoke any callbacks, transfer the buffer to caller,
+                * and fire off the (possibly) blocking
+                * iwl_trans_send_cmd()
+                * as we reclaim the driver command queue */
+               if (rxcb._page)
+                       iwl_tx_cmd_complete(trans, &rxcb, err);
+               else
+                       IWL_WARN(trans, "Claim null rxb?\n");
+       }
+
+       /* page was stolen from us */
+       if (rxcb._page == NULL)
+               rxb->page = NULL;
+
+       /* Reuse the page if possible. For notification packets and
+        * SKBs that fail to Rx correctly, add them back into the
+        * rx_free list for reuse later. */
+       spin_lock_irqsave(&rxq->lock, flags);
+       if (rxb->page != NULL) {
+               rxb->page_dma =
+                       dma_map_page(trans->dev, rxb->page, 0,
+                               PAGE_SIZE << hw_params(trans).rx_page_order,
+                               DMA_FROM_DEVICE);
+               list_add_tail(&rxb->list, &rxq->rx_free);
+               rxq->free_count++;
+       } else
+               list_add_tail(&rxb->list, &rxq->rx_used);
+       spin_unlock_irqrestore(&rxq->lock, flags);
 }
 
 /**
@@ -366,20 +472,12 @@ void iwl_bg_rx_replenish(struct work_struct *data)
  */
 static void iwl_rx_handle(struct iwl_trans *trans)
 {
-       struct iwl_rx_mem_buffer *rxb;
-       struct iwl_rx_packet *pkt;
-       struct iwl_trans_pcie *trans_pcie =
-               IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_rx_queue *rxq = &trans_pcie->rxq;
-       struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
-       struct iwl_device_cmd *cmd;
        u32 r, i;
-       int reclaim;
-       unsigned long flags;
        u8 fill_rx = 0;
        u32 count = 8;
        int total_empty;
-       int index, cmd_index;
 
        /* uCode's read index (stored in shared DRAM) indicates the last Rx
         * buffer that the driver may process (last buffer filled by ucode). */
@@ -399,102 +497,14 @@ static void iwl_rx_handle(struct iwl_trans *trans)
                fill_rx = 1;
 
        while (i != r) {
-               int len, err;
-               u16 sequence;
+               struct iwl_rx_mem_buffer *rxb;
 
                rxb = rxq->queue[i];
-
-               /* If an RXB doesn't have a Rx queue slot associated with it,
-                * then a bug has been introduced in the queue refilling
-                * routines -- catch it here */
-               if (WARN_ON(rxb == NULL)) {
-                       i = (i + 1) & RX_QUEUE_MASK;
-                       continue;
-               }
-
                rxq->queue[i] = NULL;
 
-               dma_unmap_page(bus(trans)->dev, rxb->page_dma,
-                              PAGE_SIZE << hw_params(trans).rx_page_order,
-                              DMA_FROM_DEVICE);
-               pkt = rxb_addr(rxb);
-
-               IWL_DEBUG_RX(trans, "r = %d, i = %d, %s, 0x%02x\n", r,
-                       i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
-
-               len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
-               len += sizeof(u32); /* account for status word */
-               trace_iwlwifi_dev_rx(priv(trans), pkt, len);
-
-               /* Reclaim a command buffer only if this packet is a response
-                *   to a (driver-originated) command.
-                * If the packet (e.g. Rx frame) originated from uCode,
-                *   there is no command buffer to reclaim.
-                * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
-                *   but apparently a few don't get set; catch them here. */
-               reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
-                       (pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
-                       (pkt->hdr.cmd != REPLY_RX) &&
-                       (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
-                       (pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
-                       (pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
-                       (pkt->hdr.cmd != REPLY_TX);
-
-               sequence = le16_to_cpu(pkt->hdr.sequence);
-               index = SEQ_TO_INDEX(sequence);
-               cmd_index = get_cmd_index(&txq->q, index);
-
-               if (reclaim)
-                       cmd = txq->cmd[cmd_index];
-               else
-                       cmd = NULL;
-
-               /* warn if this is cmd response / notification and the uCode
-                * didn't set the SEQ_RX_FRAME for a frame that is
-                * uCode-originated
-                * If you saw this code after the second half of 2012, then
-                * please remove it
-                */
-               WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false &&
-                    (!(pkt->hdr.sequence & SEQ_RX_FRAME)),
-                    "reclaim is false, SEQ_RX_FRAME unset: %s\n",
-                    get_cmd_string(pkt->hdr.cmd));
+               IWL_DEBUG_RX(trans, "rxbuf: r = %d, i = %d (%p)\n", rxb);
 
-               err = iwl_rx_dispatch(priv(trans), rxb, cmd);
-
-               /*
-                * XXX: After here, we should always check rxb->page
-                * against NULL before touching it or its virtual
-                * memory (pkt). Because some rx_handler might have
-                * already taken or freed the pages.
-                */
-
-               if (reclaim) {
-                       /* Invoke any callbacks, transfer the buffer to caller,
-                        * and fire off the (possibly) blocking
-                        * iwl_trans_send_cmd()
-                        * as we reclaim the driver command queue */
-                       if (rxb->page)
-                               iwl_tx_cmd_complete(trans, rxb, err);
-                       else
-                               IWL_WARN(trans, "Claim null rxb?\n");
-               }
-
-               /* Reuse the page if possible. For notification packets and
-                * SKBs that fail to Rx correctly, add them back into the
-                * rx_free list for reuse later. */
-               spin_lock_irqsave(&rxq->lock, flags);
-               if (rxb->page != NULL) {
-                       rxb->page_dma = dma_map_page(bus(trans)->dev, rxb->page,
-                               0, PAGE_SIZE <<
-                                   hw_params(trans).rx_page_order,
-                               DMA_FROM_DEVICE);
-                       list_add_tail(&rxb->list, &rxq->rx_free);
-                       rxq->free_count++;
-               } else
-                       list_add_tail(&rxb->list, &rxq->rx_used);
-
-               spin_unlock_irqrestore(&rxq->lock, flags);
+               iwl_rx_handle_rxbuf(trans, rxb);
 
                i = (i + 1) & RX_QUEUE_MASK;
                /* If there are a lot of unused frames,
@@ -590,17 +600,16 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
 {
        u32 base;
        struct iwl_error_event_table table;
-       struct iwl_priv *priv = priv(trans);
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
        base = trans->shrd->device_pointers.error_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
                if (!base)
-                       base = priv->init_errlog_ptr;
+                       base = trans->shrd->fw->init_errlog_ptr;
        } else {
                if (!base)
-                       base = priv->inst_errlog_ptr;
+                       base = trans->shrd->fw->inst_errlog_ptr;
        }
 
        if (!iwlagn_hw_valid_rtc_data_addr(base)) {
@@ -612,7 +621,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
                return;
        }
 
-       iwl_read_targ_mem_words(bus(priv), base, &table, sizeof(table));
+       iwl_read_targ_mem_words(trans, base, &table, sizeof(table));
 
        if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
                IWL_ERR(trans, "Start IWL Error Log Dump:\n");
@@ -622,7 +631,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
 
        trans_pcie->isr_stats.err_code = table.error_id;
 
-       trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low,
+       trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
                                      table.data1, table.data2, table.line,
                                      table.blink1, table.blink2, table.ilink1,
                                      table.ilink2, table.bcon_time, table.gp1,
@@ -670,12 +679,11 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
  */
 static void iwl_irq_handle_error(struct iwl_trans *trans)
 {
-       struct iwl_priv *priv = priv(trans);
        /* W/A for WiFi/WiMAX coex and WiMAX own the RF */
-       if (cfg(priv)->internal_wimax_coex &&
-           (!(iwl_read_prph(bus(trans), APMG_CLK_CTRL_REG) &
+       if (cfg(trans)->internal_wimax_coex &&
+           (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) &
                        APMS_CLK_VAL_MRB_FUNC_MODE) ||
-            (iwl_read_prph(bus(trans), APMG_PS_CTRL_REG) &
+            (iwl_read_prph(trans, APMG_PS_CTRL_REG) &
                        APMG_PS_CTRL_VAL_RESET_REQ))) {
                /*
                 * Keep the restart process from trying to send host
@@ -683,24 +691,20 @@ static void iwl_irq_handle_error(struct iwl_trans *trans)
                 */
                clear_bit(STATUS_READY, &trans->shrd->status);
                clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
-               wake_up(&priv->shrd->wait_command_queue);
+               wake_up(&trans->shrd->wait_command_queue);
                IWL_ERR(trans, "RF is used by WiMAX\n");
                return;
        }
 
        IWL_ERR(trans, "Loaded firmware version: %s\n",
-               priv->hw->wiphy->fw_version);
+               trans->shrd->fw->fw_version);
 
        iwl_dump_nic_error_log(trans);
        iwl_dump_csr(trans);
        iwl_dump_fh(trans, NULL, false);
        iwl_dump_nic_event_log(trans, false, NULL, false);
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS)
-               iwl_print_rx_config_cmd(priv(trans), IWL_RXON_CTX_BSS);
-#endif
 
-       iwlagn_fw_error(priv, false);
+       iwl_op_mode_nic_error(trans->op_mode);
 }
 
 #define EVENT_START_OFFSET  (4 * sizeof(u32))
@@ -719,7 +723,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
        u32 ptr;        /* SRAM byte address of log data */
        u32 ev, time, data; /* event log data */
        unsigned long reg_flags;
-       struct iwl_priv *priv = priv(trans);
 
        if (num_events == 0)
                return pos;
@@ -727,10 +730,10 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
        base = trans->shrd->device_pointers.log_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
                if (!base)
-                       base = priv->init_evtlog_ptr;
+                       base = trans->shrd->fw->init_evtlog_ptr;
        } else {
                if (!base)
-                       base = priv->inst_evtlog_ptr;
+                       base = trans->shrd->fw->inst_evtlog_ptr;
        }
 
        if (mode == 0)
@@ -741,18 +744,18 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
        ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
 
        /* Make sure device is powered up for SRAM reads */
-       spin_lock_irqsave(&bus(trans)->reg_lock, reg_flags);
-       iwl_grab_nic_access(bus(trans));
+       spin_lock_irqsave(&trans->reg_lock, reg_flags);
+       if (unlikely(!iwl_grab_nic_access(trans)))
+               goto out_unlock;
 
        /* Set starting address; reads will auto-increment */
-       iwl_write32(bus(trans), HBUS_TARG_MEM_RADDR, ptr);
-       rmb();
+       iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr);
 
        /* "time" is actually "data" for mode 0 (no timestamp).
        * place event id # at far right for easier visual parsing. */
        for (i = 0; i < num_events; i++) {
-               ev = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
-               time = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
+               ev = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
+               time = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
                if (mode == 0) {
                        /* data, ev */
                        if (bufsz) {
@@ -760,13 +763,13 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
                                                "EVT_LOG:0x%08x:%04u\n",
                                                time, ev);
                        } else {
-                               trace_iwlwifi_dev_ucode_event(priv, 0,
+                               trace_iwlwifi_dev_ucode_event(trans->dev, 0,
                                        time, ev);
                                IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n",
                                        time, ev);
                        }
                } else {
-                       data = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
+                       data = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
                        if (bufsz) {
                                pos += scnprintf(*buf + pos, bufsz - pos,
                                                "EVT_LOGT:%010u:0x%08x:%04u\n",
@@ -774,15 +777,16 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
                        } else {
                                IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n",
                                        time, data, ev);
-                               trace_iwlwifi_dev_ucode_event(priv, time,
+                               trace_iwlwifi_dev_ucode_event(trans->dev, time,
                                        data, ev);
                        }
                }
        }
 
        /* Allow device to power down */
-       iwl_release_nic_access(bus(trans));
-       spin_unlock_irqrestore(&bus(trans)->reg_lock, reg_flags);
+       iwl_release_nic_access(trans);
+out_unlock:
+       spin_unlock_irqrestore(&trans->reg_lock, reg_flags);
        return pos;
 }
 
@@ -836,17 +840,16 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
        u32 logsize;
        int pos = 0;
        size_t bufsz = 0;
-       struct iwl_priv *priv = priv(trans);
 
        base = trans->shrd->device_pointers.log_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
-               logsize = priv->init_evtlog_size;
+               logsize = trans->shrd->fw->init_evtlog_size;
                if (!base)
-                       base = priv->init_evtlog_ptr;
+                       base = trans->shrd->fw->init_evtlog_ptr;
        } else {
-               logsize = priv->inst_evtlog_size;
+               logsize = trans->shrd->fw->inst_evtlog_size;
                if (!base)
-                       base = priv->inst_evtlog_ptr;
+                       base = trans->shrd->fw->inst_evtlog_ptr;
        }
 
        if (!iwlagn_hw_valid_rtc_data_addr(base)) {
@@ -859,10 +862,10 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
        }
 
        /* event log header */
-       capacity = iwl_read_targ_mem(bus(trans), base);
-       mode = iwl_read_targ_mem(bus(trans), base + (1 * sizeof(u32)));
-       num_wraps = iwl_read_targ_mem(bus(trans), base + (2 * sizeof(u32)));
-       next_entry = iwl_read_targ_mem(bus(trans), base + (3 * sizeof(u32)));
+       capacity = iwl_read_targ_mem(trans, base);
+       mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32)));
+       num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32)));
+       next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32)));
 
        if (capacity > logsize) {
                IWL_ERR(trans, "Log capacity %d is bogus, limit to %d "
@@ -885,7 +888,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log)
+       if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log)
                size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
                        ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
 #else
@@ -905,7 +908,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
                if (!*buf)
                        return -ENOMEM;
        }
-       if ((iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) || full_log) {
+       if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) {
                /*
                 * if uCode has wrapped back to top of log,
                 * start at the oldest entry,
@@ -945,7 +948,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
 
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Ack/clear/reset pending uCode interrupts.
         * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
@@ -958,15 +961,15 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
         * hardware bugs here by ACKing all the possible interrupts so that
         * interrupt coalescing can still be achieved.
         */
-       iwl_write32(bus(trans), CSR_INT,
+       iwl_write32(trans, CSR_INT,
                trans_pcie->inta | ~trans_pcie->inta_mask);
 
        inta = trans_pcie->inta;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) {
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
                /* just for debug */
-               inta_mask = iwl_read32(bus(trans), CSR_INT_MASK);
+               inta_mask = iwl_read32(trans, CSR_INT_MASK);
                IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ",
                                inta, inta_mask);
        }
@@ -975,7 +978,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        /* saved interrupt in inta variable now we can reset trans_pcie->inta */
        trans_pcie->inta = 0;
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* Now service all interrupt bits discovered above. */
        if (inta & CSR_INT_BIT_HW_ERR) {
@@ -993,7 +996,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) {
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
                /* NIC fires this, but we don't use it, redundant with WAKEUP */
                if (inta & CSR_INT_BIT_SCD) {
                        IWL_DEBUG_ISR(trans, "Scheduler finished to transmit "
@@ -1013,30 +1016,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 
        /* HW RF KILL switch toggled */
        if (inta & CSR_INT_BIT_RF_KILL) {
-               int hw_rf_kill = 0;
-               if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) &
-                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
-                       hw_rf_kill = 1;
+               bool hw_rfkill;
 
+               hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
                IWL_WARN(trans, "RF_KILL bit toggled to %s.\n",
-                               hw_rf_kill ? "disable radio" : "enable radio");
+                               hw_rfkill ? "disable radio" : "enable radio");
 
                isr_stats->rfkill++;
 
-               /* driver only loads ucode once setting the interface up.
-                * the driver allows loading the ucode even if the radio
-                * is killed. Hence update the killswitch state here. The
-                * rfkill handler will care about restarting if needed.
-                */
-               if (!test_bit(STATUS_ALIVE, &trans->shrd->status)) {
-                       if (hw_rf_kill)
-                               set_bit(STATUS_RF_KILL_HW,
-                                       &trans->shrd->status);
-                       else
-                               clear_bit(STATUS_RF_KILL_HW,
-                                         &trans->shrd->status);
-                       iwl_set_hw_rfkill_state(priv(trans), hw_rf_kill);
-               }
+               iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
                handled |= CSR_INT_BIT_RF_KILL;
        }
@@ -1078,12 +1067,12 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
                IWL_DEBUG_ISR(trans, "Rx interrupt\n");
                if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
                        handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
-                       iwl_write32(bus(trans), CSR_FH_INT_STATUS,
+                       iwl_write32(trans, CSR_FH_INT_STATUS,
                                        CSR_FH_INT_RX_MASK);
                }
                if (inta & CSR_INT_BIT_RX_PERIODIC) {
                        handled |= CSR_INT_BIT_RX_PERIODIC;
-                       iwl_write32(bus(trans),
+                       iwl_write32(trans,
                                CSR_INT, CSR_INT_BIT_RX_PERIODIC);
                }
                /* Sending RX interrupt require many steps to be done in the
@@ -1098,10 +1087,13 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
                 */
 
                /* Disable periodic interrupt; we use it as just a one-shot. */
-               iwl_write8(bus(trans), CSR_INT_PERIODIC_REG,
+               iwl_write8(trans, CSR_INT_PERIODIC_REG,
                            CSR_INT_PERIODIC_DIS);
+#ifdef CONFIG_IWLWIFI_IDI
+               iwl_amfh_rx_handler();
+#else
                iwl_rx_handle(trans);
-
+#endif
                /*
                 * Enable periodic interrupt in 8 msec only if we received
                 * real RX interrupt (instead of just periodic int), to catch
@@ -1110,7 +1102,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
                 * to extend the periodic interrupt; one-shot is enough.
                 */
                if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX))
-                       iwl_write8(bus(trans), CSR_INT_PERIODIC_REG,
+                       iwl_write8(trans, CSR_INT_PERIODIC_REG,
                                    CSR_INT_PERIODIC_ENA);
 
                isr_stats->rx++;
@@ -1118,13 +1110,13 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 
        /* This "Tx" DMA channel is used only for loading uCode */
        if (inta & CSR_INT_BIT_FH_TX) {
-               iwl_write32(bus(trans), CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
+               iwl_write32(trans, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
                IWL_DEBUG_ISR(trans, "uCode load interrupt\n");
                isr_stats->tx++;
                handled |= CSR_INT_BIT_FH_TX;
                /* Wake up uCode load routine, now that load is complete */
-               trans->ucode_write_complete = 1;
-               wake_up(&trans->shrd->wait_command_queue);
+               trans_pcie->ucode_write_complete = true;
+               wake_up(&trans_pcie->ucode_write_waitq);
        }
 
        if (inta & ~handled) {
@@ -1139,11 +1131,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 
        /* Re-enable all interrupts */
        /* only Re-enable if disabled by irq */
-       if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status))
+       if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status))
                iwl_enable_interrupts(trans);
        /* Re-enable RF_KILL if it occurred */
        else if (handled & CSR_INT_BIT_RF_KILL)
-               iwl_enable_rfkill_int(priv(trans));
+               iwl_enable_rfkill_int(trans);
 }
 
 /******************************************************************************
@@ -1164,7 +1156,7 @@ void iwl_free_isr_ict(struct iwl_trans *trans)
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
        if (trans_pcie->ict_tbl) {
-               dma_free_coherent(bus(trans)->dev, ICT_SIZE,
+               dma_free_coherent(trans->dev, ICT_SIZE,
                                  trans_pcie->ict_tbl,
                                  trans_pcie->ict_tbl_dma);
                trans_pcie->ict_tbl = NULL;
@@ -1184,7 +1176,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans)
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
        trans_pcie->ict_tbl =
-               dma_alloc_coherent(bus(trans)->dev, ICT_SIZE,
+               dma_alloc_coherent(trans->dev, ICT_SIZE,
                                   &trans_pcie->ict_tbl_dma,
                                   GFP_KERNEL);
        if (!trans_pcie->ict_tbl)
@@ -1213,7 +1205,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans)
 /* Device is going up inform it about using ICT interrupt table,
  * also we need to tell the driver to start using ICT interrupt.
  */
-int iwl_reset_ict(struct iwl_trans *trans)
+void iwl_reset_ict(struct iwl_trans *trans)
 {
        u32 val;
        unsigned long flags;
@@ -1221,9 +1213,9 @@ int iwl_reset_ict(struct iwl_trans *trans)
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
        if (!trans_pcie->ict_tbl)
-               return 0;
+               return;
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_disable_interrupts(trans);
 
        memset(trans_pcie->ict_tbl, 0, ICT_SIZE);
@@ -1235,14 +1227,12 @@ int iwl_reset_ict(struct iwl_trans *trans)
 
        IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val);
 
-       iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val);
+       iwl_write32(trans, CSR_DRAM_INT_TBL_REG, val);
        trans_pcie->use_ict = true;
        trans_pcie->ict_index = 0;
-       iwl_write32(bus(trans), CSR_INT, trans_pcie->inta_mask);
+       iwl_write32(trans, CSR_INT, trans_pcie->inta_mask);
        iwl_enable_interrupts(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
-
-       return 0;
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 /* Device is going down disable ict interrupt usage */
@@ -1253,9 +1243,9 @@ void iwl_disable_ict(struct iwl_trans *trans)
 
        unsigned long flags;
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        trans_pcie->use_ict = false;
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 static irqreturn_t iwl_isr(int irq, void *data)
@@ -1270,21 +1260,21 @@ static irqreturn_t iwl_isr(int irq, void *data)
        if (!trans)
                return IRQ_NONE;
 
-       trace_iwlwifi_dev_irq(priv(trans));
+       trace_iwlwifi_dev_irq(trans->dev);
 
        trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Disable (but don't clear!) interrupts here to avoid
         *    back-to-back ISRs and sporadic interrupts from our NIC.
         * If we have something to service, the tasklet will re-enable ints.
         * If we *don't* have something, we'll re-enable before leaving here. */
-       inta_mask = iwl_read32(bus(trans), CSR_INT_MASK);  /* just for debug */
-       iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000);
+       inta_mask = iwl_read32(trans, CSR_INT_MASK);  /* just for debug */
+       iwl_write32(trans, CSR_INT_MASK, 0x00000000);
 
        /* Discover which interrupts are active/pending */
-       inta = iwl_read32(bus(trans), CSR_INT);
+       inta = iwl_read32(trans, CSR_INT);
 
        /* Ignore interrupt if there's nothing in NIC to service.
         * This may be due to IRQ shared with another device,
@@ -1302,8 +1292,8 @@ static irqreturn_t iwl_isr(int irq, void *data)
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) {
-               inta_fh = iwl_read32(bus(trans), CSR_FH_INT_STATUS);
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
+               inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS);
                IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, "
                              "fh 0x%08x\n", inta, inta_mask, inta_fh);
        }
@@ -1313,22 +1303,22 @@ static irqreturn_t iwl_isr(int irq, void *data)
        /* iwl_irq_tasklet() will service interrupts and re-enable them */
        if (likely(inta))
                tasklet_schedule(&trans_pcie->irq_tasklet);
-       else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) &&
+       else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
                        !trans_pcie->inta)
                iwl_enable_interrupts(trans);
 
  unplugged:
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_HANDLED;
 
  none:
        /* re-enable interrupts here since we don't have anything to service. */
        /* only Re-enable if disabled by irq  and no schedules tasklet. */
-       if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) &&
+       if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
                !trans_pcie->inta)
                iwl_enable_interrupts(trans);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_NONE;
 }
 
@@ -1360,24 +1350,24 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
        if (!trans_pcie->use_ict)
                return iwl_isr(irq, data);
 
-       trace_iwlwifi_dev_irq(priv(trans));
+       trace_iwlwifi_dev_irq(trans->dev);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Disable (but don't clear!) interrupts here to avoid
         * back-to-back ISRs and sporadic interrupts from our NIC.
         * If we have something to service, the tasklet will re-enable ints.
         * If we *don't* have something, we'll re-enable before leaving here.
         */
-       inta_mask = iwl_read32(bus(trans), CSR_INT_MASK);  /* just for debug */
-       iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000);
+       inta_mask = iwl_read32(trans, CSR_INT_MASK);  /* just for debug */
+       iwl_write32(trans, CSR_INT_MASK, 0x00000000);
 
 
        /* Ignore interrupt if there's nothing in NIC to service.
         * This may be due to IRQ shared with another device,
         * or due to sporadic interrupts thrown from our NIC. */
        read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]);
-       trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, read);
+       trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read);
        if (!read) {
                IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n");
                goto none;
@@ -1396,7 +1386,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
                        iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT);
 
                read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]);
-               trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index,
+               trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index,
                                           read);
        } while (read);
 
@@ -1424,7 +1414,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
        /* iwl_irq_tasklet() will service interrupts and re-enable them */
        if (likely(inta))
                tasklet_schedule(&trans_pcie->irq_tasklet);
-       else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) &&
+       else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
                 !trans_pcie->inta) {
                /* Allow interrupt if was disabled by this handler and
                 * no tasklet was schedules, We should not enable interrupt,
@@ -1433,17 +1423,17 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
                iwl_enable_interrupts(trans);
        }
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_HANDLED;
 
  none:
        /* re-enable interrupts here since we don't have anything to service.
         * only Re-enable if disabled by irq.
         */
-       if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) &&
+       if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
            !trans_pcie->inta)
                iwl_enable_interrupts(trans);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_NONE;
 }
index bd29568177e6354eb2f6523c0a782155221072a5..73febc9726cbf4fc2cbae51b9d13911be7592c29 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
 #include "iwl-prph.h"
 #include "iwl-io.h"
 #include "iwl-agn-hw.h"
+#include "iwl-op-mode.h"
 #include "iwl-trans-pcie-int.h"
 
 #define IWL_TX_CRC_SIZE 4
 #define IWL_TX_DELIMITER_SIZE 4
 
+/*
+ * mac80211 queues, ACs, hardware queues, FIFOs.
+ *
+ * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues
+ *
+ * Mac80211 uses the following numbers, which we get as from it
+ * by way of skb_get_queue_mapping(skb):
+ *
+ *     VO      0
+ *     VI      1
+ *     BE      2
+ *     BK      3
+ *
+ *
+ * Regular (not A-MPDU) frames are put into hardware queues corresponding
+ * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their
+ * own queue per aggregation session (RA/TID combination), such queues are
+ * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In
+ * order to map frames to the right queue, we also need an AC->hw queue
+ * mapping. This is implemented here.
+ *
+ * Due to the way hw queues are set up (by the hw specific code), the AC->hw
+ * queue mapping is the identity mapping.
+ */
+
+static const u8 tid_to_ac[] = {
+       IEEE80211_AC_BE,
+       IEEE80211_AC_BK,
+       IEEE80211_AC_BK,
+       IEEE80211_AC_BE,
+       IEEE80211_AC_VI,
+       IEEE80211_AC_VI,
+       IEEE80211_AC_VO,
+       IEEE80211_AC_VO
+};
+
+
 /**
  * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
  */
@@ -98,9 +136,9 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq)
        if (txq->need_update == 0)
                return;
 
-       if (hw_params(trans).shadow_reg_enable) {
+       if (cfg(trans)->base_params->shadow_reg_enable) {
                /* shadow register enabled */
-               iwl_write32(bus(trans), HBUS_TARG_WRPTR,
+               iwl_write32(trans, HBUS_TARG_WRPTR,
                            txq->q.write_ptr | (txq_id << 8));
        } else {
                /* if we're trying to save power */
@@ -108,18 +146,18 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq)
                        /* wake up nic if it's powered down ...
                         * uCode will wake up, and interrupt us again, so next
                         * time we'll skip this part. */
-                       reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1);
+                       reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
 
                        if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
                                IWL_DEBUG_INFO(trans,
                                        "Tx queue %d requesting wakeup,"
                                        " GP1 = 0x%x\n", txq_id, reg);
-                               iwl_set_bit(bus(trans), CSR_GP_CNTRL,
+                               iwl_set_bit(trans, CSR_GP_CNTRL,
                                        CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
                                return;
                        }
 
-                       iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR,
+                       iwl_write_direct32(trans, HBUS_TARG_WRPTR,
                                     txq->q.write_ptr | (txq_id << 8));
 
                /*
@@ -128,7 +166,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq)
                 * trying to tx (during RFKILL, we're not trying to tx).
                 */
                } else
-                       iwl_write32(bus(trans), HBUS_TARG_WRPTR,
+                       iwl_write32(trans, HBUS_TARG_WRPTR,
                                    txq->q.write_ptr | (txq_id << 8));
        }
        txq->need_update = 0;
@@ -190,14 +228,14 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta,
 
        /* Unmap tx_cmd */
        if (num_tbs)
-               dma_unmap_single(bus(trans)->dev,
+               dma_unmap_single(trans->dev,
                                dma_unmap_addr(meta, mapping),
                                dma_unmap_len(meta, len),
                                DMA_BIDIRECTIONAL);
 
        /* Unmap chunks, if any. */
        for (i = 1; i < num_tbs; i++)
-               dma_unmap_single(bus(trans)->dev, iwl_tfd_tb_get_addr(tfd, i),
+               dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i),
                                iwl_tfd_tb_get_len(tfd, i), dma_dir);
 }
 
@@ -216,6 +254,8 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
 {
        struct iwl_tfd *tfd_tmp = txq->tfds;
 
+       lockdep_assert_held(&txq->lock);
+
        iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], dma_dir);
 
        /* free SKB */
@@ -229,7 +269,7 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
                 * freed and that the queue is not empty - free the skb
                 */
                if (skb) {
-                       iwl_free_skb(priv(trans), skb);
+                       iwl_op_mode_free_skb(trans->op_mode, skb);
                        txq->skbs[index] = NULL;
                }
        }
@@ -383,14 +423,14 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid,
        tbl_dw_addr = trans_pcie->scd_base_addr +
                        SCD_TRANS_TBL_OFFSET_QUEUE(txq_id);
 
-       tbl_dw = iwl_read_targ_mem(bus(trans), tbl_dw_addr);
+       tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr);
 
        if (txq_id & 0x1)
                tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
        else
                tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
 
-       iwl_write_targ_mem(bus(trans), tbl_dw_addr, tbl_dw);
+       iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw);
 
        return 0;
 }
@@ -399,7 +439,7 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id)
 {
        /* Simply stop the queue, but don't change any configuration;
         * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
-       iwl_write_prph(bus(trans),
+       iwl_write_prph(trans,
                SCD_QUEUE_STATUS_BITS(txq_id),
                (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
                (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
@@ -409,9 +449,9 @@ void iwl_trans_set_wr_ptrs(struct iwl_trans *trans,
                                int txq_id, u32 index)
 {
        IWL_DEBUG_TX_QUEUES(trans, "Q %d  WrPtr: %d", txq_id, index & 0xff);
-       iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR,
+       iwl_write_direct32(trans, HBUS_TARG_WRPTR,
                        (index & 0xff) | (txq_id << 8));
-       iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(txq_id), index);
+       iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index);
 }
 
 void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
@@ -423,7 +463,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
        int active =
                test_bit(txq_id, &trans_pcie->txq_ctx_active_msk) ? 1 : 0;
 
-       iwl_write_prph(bus(trans), SCD_QUEUE_STATUS_BITS(txq_id),
+       iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
                        (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
                        (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) |
                        (1 << SCD_QUEUE_STTS_REG_POS_WSL) |
@@ -431,9 +471,21 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
 
        txq->sched_retry = scd_retry;
 
-       IWL_DEBUG_TX_QUEUES(trans, "%s %s Queue %d on FIFO %d\n",
-                      active ? "Activate" : "Deactivate",
-                      scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
+       if (active)
+               IWL_DEBUG_TX_QUEUES(trans, "Activate %s Queue %d on FIFO %d\n",
+                       scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
+       else
+               IWL_DEBUG_TX_QUEUES(trans, "Deactivate %s Queue %d\n",
+                       scd_retry ? "BA" : "AC/CMD", txq_id);
+}
+
+static inline int get_ac_from_tid(u16 tid)
+{
+       if (likely(tid < ARRAY_SIZE(tid_to_ac)))
+               return tid_to_ac[tid];
+
+       /* no support for TIDs 8-15 yet */
+       return -EINVAL;
 }
 
 static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie,
@@ -489,7 +541,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
 
        ra_tid = BUILD_RAxTID(sta_id, tid);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Stop this Tx queue before configuring it */
        iwlagn_tx_queue_stop_scheduler(trans, txq_id);
@@ -498,10 +550,10 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
        iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id);
 
        /* Set this queue as a chain-building queue */
-       iwl_set_bits_prph(bus(trans), SCD_QUEUECHAIN_SEL, (1<<txq_id));
+       iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, (1<<txq_id));
 
        /* enable aggregations for the queue */
-       iwl_set_bits_prph(bus(trans), SCD_AGGR_SEL, (1<<txq_id));
+       iwl_set_bits_prph(trans, SCD_AGGR_SEL, (1<<txq_id));
 
        /* Place first TFD at index corresponding to start sequence number.
         * Assumes that ssn_idx is valid (!= 0xFFF) */
@@ -510,7 +562,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
        iwl_trans_set_wr_ptrs(trans, txq_id, ssn);
 
        /* Set up Tx window size and frame limit for this queue */
-       iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr +
+       iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
                        SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
                        sizeof(u32),
                        ((frame_limit <<
@@ -520,7 +572,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
                        SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
                        SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
 
-       iwl_set_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id));
+       iwl_set_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id));
 
        /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
        iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id],
@@ -529,7 +581,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
        trans_pcie->txq[txq_id].sta_id = sta_id;
        trans_pcie->txq[txq_id].tid = tid;
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 /*
@@ -584,7 +636,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid)
 
        iwlagn_tx_queue_stop_scheduler(trans, txq_id);
 
-       iwl_clear_bits_prph(bus(trans), SCD_AGGR_SEL, (1 << txq_id));
+       iwl_clear_bits_prph(trans, SCD_AGGR_SEL, (1 << txq_id));
 
        trans_pcie->agg_txq[sta_id][tid] = 0;
        trans_pcie->txq[txq_id].q.read_ptr = 0;
@@ -592,7 +644,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid)
        /* supposes that ssn_idx is valid (!= 0xFFF) */
        iwl_trans_set_wr_ptrs(trans, txq_id, 0);
 
-       iwl_clear_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id));
+       iwl_clear_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id));
        iwl_txq_ctx_deactivate(trans_pcie, txq_id);
        iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 0, 0);
        return 0;
@@ -617,10 +669,8 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        struct iwl_device_cmd *out_cmd;
        struct iwl_cmd_meta *out_meta;
        dma_addr_t phys_addr;
-       unsigned long flags;
        u32 idx;
        u16 copy_size, cmd_size;
-       bool is_ct_kill = false;
        bool had_nocopy = false;
        int i;
        u8 *cmd_dest;
@@ -635,12 +685,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
                return -EIO;
        }
 
-       if ((trans->shrd->ucode_owner == IWL_OWNERSHIP_TM) &&
-           !(cmd->flags & CMD_ON_DEMAND)) {
-               IWL_DEBUG_HC(trans, "tm own the uCode, no regular hcmd send\n");
-               return -EIO;
-       }
-
        copy_size = sizeof(out_cmd->hdr);
        cmd_size = sizeof(out_cmd->hdr);
 
@@ -670,23 +714,13 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE))
                return -EINVAL;
 
-       if (iwl_is_rfkill(trans->shrd) || iwl_is_ctkill(trans->shrd)) {
-               IWL_WARN(trans, "Not sending command - %s KILL\n",
-                        iwl_is_rfkill(trans->shrd) ? "RF" : "CT");
-               return -EIO;
-       }
-
-       spin_lock_irqsave(&trans->hcmd_lock, flags);
+       spin_lock_bh(&txq->lock);
 
        if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
-               spin_unlock_irqrestore(&trans->hcmd_lock, flags);
+               spin_unlock_bh(&txq->lock);
 
                IWL_ERR(trans, "No space in command queue\n");
-               is_ct_kill = iwl_check_for_ct_kill(priv(trans));
-               if (!is_ct_kill) {
-                       IWL_ERR(trans, "Restarting adapter queue is full\n");
-                       iwlagn_fw_error(priv(trans), false);
-               }
+               iwl_op_mode_cmd_queue_full(trans->op_mode);
                return -ENOSPC;
        }
 
@@ -725,9 +759,9 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
                        le16_to_cpu(out_cmd->hdr.sequence), cmd_size,
                        q->write_ptr, idx, trans->shrd->cmd_queue);
 
-       phys_addr = dma_map_single(bus(trans)->dev, &out_cmd->hdr, copy_size,
+       phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
                                DMA_BIDIRECTIONAL);
-       if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) {
+       if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
                idx = -ENOMEM;
                goto out;
        }
@@ -748,10 +782,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
                        continue;
                if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
                        continue;
-               phys_addr = dma_map_single(bus(trans)->dev,
+               phys_addr = dma_map_single(trans->dev,
                                           (void *)cmd->data[i],
                                           cmd->len[i], DMA_BIDIRECTIONAL);
-               if (dma_mapping_error(bus(trans)->dev, phys_addr)) {
+               if (dma_mapping_error(trans->dev, phys_addr)) {
                        iwlagn_unmap_tfd(trans, out_meta,
                                         &txq->tfds[q->write_ptr],
                                         DMA_BIDIRECTIONAL);
@@ -775,7 +809,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        /* check that tracing gets all possible blocks */
        BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3);
 #ifdef CONFIG_IWLWIFI_DEVICE_TRACING
-       trace_iwlwifi_dev_hcmd(priv(trans), cmd->flags,
+       trace_iwlwifi_dev_hcmd(trans->dev, cmd->flags,
                               trace_bufs[0], trace_lens[0],
                               trace_bufs[1], trace_lens[1],
                               trace_bufs[2], trace_lens[2]);
@@ -786,7 +820,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        iwl_txq_update_write_ptr(trans, txq);
 
  out:
-       spin_unlock_irqrestore(&trans->hcmd_lock, flags);
+       spin_unlock_bh(&txq->lock);
        return idx;
 }
 
@@ -805,6 +839,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
        struct iwl_queue *q = &txq->q;
        int nfreed = 0;
 
+       lockdep_assert_held(&txq->lock);
+
        if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
                IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), "
                          "index %d is out of range [0-%d] %d %d.\n", __func__,
@@ -818,7 +854,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
                if (nfreed++ > 0) {
                        IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", idx,
                                        q->write_ptr, q->read_ptr);
-                       iwlagn_fw_error(priv(trans), false);
+                       iwl_op_mode_nic_error(trans->op_mode);
                }
 
        }
@@ -834,7 +870,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
  * will be executed.  The attached skb (if present) will only be freed
  * if the callback returns 1
  */
-void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
+void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
                         int handler_status)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -846,7 +882,6 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
        struct iwl_cmd_meta *meta;
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
-       unsigned long flags;
 
        /* If a Tx command is being handled and it isn't in the actual
         * command queue then there a command routing bug has been introduced
@@ -860,6 +895,8 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
                return;
        }
 
+       spin_lock(&txq->lock);
+
        cmd_index = get_cmd_index(&txq->q, index);
        cmd = txq->cmd[cmd_index];
        meta = &txq->meta[cmd_index];
@@ -871,13 +908,14 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
 
        /* Input error checking is done when commands are added to queue. */
        if (meta->flags & CMD_WANT_SKB) {
-               meta->source->reply_page = (unsigned long)rxb_addr(rxb);
+               struct page *p = rxb_steal_page(rxb);
+
+               meta->source->resp_pkt = pkt;
+               meta->source->_rx_page_addr = (unsigned long)page_address(p);
+               meta->source->_rx_page_order = hw_params(trans).rx_page_order;
                meta->source->handler_status = handler_status;
-               rxb->page = NULL;
        }
 
-       spin_lock_irqsave(&trans->hcmd_lock, flags);
-
        iwl_hcmd_queue_reclaim(trans, txq_id, index);
 
        if (!(meta->flags & CMD_ASYNC)) {
@@ -894,7 +932,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
 
        meta->flags = 0;
 
-       spin_unlock_irqrestore(&trans->hcmd_lock, flags);
+       spin_unlock(&txq->lock);
 }
 
 #define HOST_COMPLETE_TIMEOUT (2 * HZ)
@@ -908,12 +946,9 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
                return -EINVAL;
 
 
-       if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
-               return -EBUSY;
-
        ret = iwl_enqueue_hcmd(trans, cmd);
        if (ret < 0) {
-               IWL_DEBUG_QUIET_RFKILL(trans,
+               IWL_ERR(trans,
                        "Error sending %s: enqueue_hcmd failed: %d\n",
                          get_cmd_string(cmd->id), ret);
                return ret;
@@ -927,26 +962,22 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        int cmd_idx;
        int ret;
 
-       lockdep_assert_held(&trans->shrd->mutex);
-
        IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
                        get_cmd_string(cmd->id));
 
-       if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
-               return -EBUSY;
-
-
-       if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) {
-               IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n",
-                              get_cmd_string(cmd->id));
-               return -ECANCELED;
-       }
        if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) {
                IWL_ERR(trans, "Command %s failed: FW Error\n",
                               get_cmd_string(cmd->id));
                return -EIO;
        }
-       set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
+
+       if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE,
+                                    &trans->shrd->status))) {
+               IWL_ERR(trans, "Command %s: a command is already active!\n",
+                       get_cmd_string(cmd->id));
+               return -EIO;
+       }
+
        IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n",
                        get_cmd_string(cmd->id));
 
@@ -954,7 +985,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        if (cmd_idx < 0) {
                ret = cmd_idx;
                clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
-               IWL_DEBUG_QUIET_RFKILL(trans,
+               IWL_ERR(trans,
                        "Error sending %s: enqueue_hcmd failed: %d\n",
                          get_cmd_string(cmd->id), ret);
                return ret;
@@ -969,12 +1000,12 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
                                &trans_pcie->txq[trans->shrd->cmd_queue];
                        struct iwl_queue *q = &txq->q;
 
-                       IWL_DEBUG_QUIET_RFKILL(trans,
+                       IWL_ERR(trans,
                                "Error sending %s: time out after %dms.\n",
                                get_cmd_string(cmd->id),
                                jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
 
-                       IWL_DEBUG_QUIET_RFKILL(trans,
+                       IWL_ERR(trans,
                                "Current CMD queue read_ptr %d write_ptr %d\n",
                                q->read_ptr, q->write_ptr);
 
@@ -986,7 +1017,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
                }
        }
 
-       if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) {
+       if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) {
                IWL_ERR(trans, "Error: Response NULL in '%s'\n",
                          get_cmd_string(cmd->id));
                ret = -EIO;
@@ -1007,9 +1038,9 @@ cancel:
                                                        ~CMD_WANT_SKB;
        }
 
-       if (cmd->reply_page) {
-               iwl_free_pages(trans->shrd, cmd->reply_page);
-               cmd->reply_page = 0;
+       if (cmd->resp_pkt) {
+               iwl_free_resp(cmd);
+               cmd->resp_pkt = NULL;
        }
 
        return ret;
@@ -1037,6 +1068,8 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
        if (WARN_ON(txq_id == trans->shrd->cmd_queue))
                return 0;
 
+       lockdep_assert_held(&txq->lock);
+
        /*Since we free until index _not_ inclusive, the one before index is
         * the last we will free. This one must be used */
        last_to_free = iwl_queue_dec_wrap(index, q->n_bd);
index 324d06dfb69003ca14ac5ab024d800a750057568..6172651d7e250ab06562fdabd714742711c02d1c 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
+#include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/interrupt.h>
 #include <linux/debugfs.h>
+#include <linux/sched.h>
 #include <linux/bitops.h>
 #include <linux/gfp.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-agn-hw.h"
 
+#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
+
 static int iwl_trans_rx_alloc(struct iwl_trans *trans)
 {
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_rx_queue *rxq = &trans_pcie->rxq;
-       struct device *dev = bus(trans)->dev;
+       struct device *dev = trans->dev;
 
        memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq));
 
@@ -122,7 +127,7 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans)
                /* In the reset function, these buffers may have been allocated
                 * to an SKB, so we need to unmap and free potential storage */
                if (rxq->pool[i].page != NULL) {
-                       dma_unmap_page(bus(trans)->dev, rxq->pool[i].page_dma,
+                       dma_unmap_page(trans->dev, rxq->pool[i].page_dma,
                                PAGE_SIZE << hw_params(trans).rx_page_order,
                                DMA_FROM_DEVICE);
                        __free_pages(rxq->pool[i].page,
@@ -146,17 +151,17 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans,
                rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
 
        /* Stop Rx DMA */
-       iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+       iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
 
        /* Reset driver's Rx queue write index */
-       iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
+       iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
 
        /* Tell device where to find RBD circular buffer in DRAM */
-       iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_BASE_REG,
+       iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
                           (u32)(rxq->bd_dma >> 8));
 
        /* Tell device where in DRAM to update its Rx status */
-       iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_STTS_WPTR_REG,
+       iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG,
                           rxq->rb_stts_dma >> 4);
 
        /* Enable Rx DMA
@@ -167,7 +172,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans,
         * RB timeout 0x10
         * 256 RBDs
         */
-       iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG,
+       iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG,
                           FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
                           FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
                           FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
@@ -177,7 +182,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans,
                           (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
 
        /* Set interrupt coalescing timer to default (2048 usecs) */
-       iwl_write8(bus(trans), CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
+       iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
 }
 
 static int iwl_rx_init(struct iwl_trans *trans)
@@ -215,10 +220,10 @@ static int iwl_rx_init(struct iwl_trans *trans)
 
        iwl_trans_rx_hw_init(trans, rxq);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        rxq->need_update = 1;
        iwl_rx_queue_update_write_ptr(trans, rxq);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        return 0;
 }
@@ -242,13 +247,13 @@ static void iwl_trans_pcie_rx_free(struct iwl_trans *trans)
        iwl_trans_rxq_free_rx_bufs(trans);
        spin_unlock_irqrestore(&rxq->lock, flags);
 
-       dma_free_coherent(bus(trans)->dev, sizeof(__le32) * RX_QUEUE_SIZE,
+       dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE,
                          rxq->bd, rxq->bd_dma);
        memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
        rxq->bd = NULL;
 
        if (rxq->rb_stts)
-               dma_free_coherent(bus(trans)->dev,
+               dma_free_coherent(trans->dev,
                                  sizeof(struct iwl_rb_status),
                                  rxq->rb_stts, rxq->rb_stts_dma);
        else
@@ -261,8 +266,8 @@ static int iwl_trans_rx_stop(struct iwl_trans *trans)
 {
 
        /* stop Rx DMA */
-       iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
-       return iwl_poll_direct_bit(bus(trans), FH_MEM_RSSR_RX_STATUS_REG,
+       iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+       return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG,
                            FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
 }
 
@@ -272,7 +277,7 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_trans *trans,
        if (WARN_ON(ptr->addr))
                return -EINVAL;
 
-       ptr->addr = dma_alloc_coherent(bus(trans)->dev, size,
+       ptr->addr = dma_alloc_coherent(trans->dev, size,
                                       &ptr->dma, GFP_KERNEL);
        if (!ptr->addr)
                return -ENOMEM;
@@ -286,7 +291,7 @@ static inline void iwlagn_free_dma_ptr(struct iwl_trans *trans,
        if (unlikely(!ptr->addr))
                return;
 
-       dma_free_coherent(bus(trans)->dev, ptr->size, ptr->addr, ptr->dma);
+       dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma);
        memset(ptr, 0, sizeof(*ptr));
 }
 
@@ -333,7 +338,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
 
        /* Circular buffer of transmit frame descriptors (TFDs),
         * shared with device */
-       txq->tfds = dma_alloc_coherent(bus(trans)->dev, tfd_sz,
+       txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz,
                                       &txq->q.dma_addr, GFP_KERNEL);
        if (!txq->tfds) {
                IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
@@ -385,11 +390,13 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq,
        if (ret)
                return ret;
 
+       spin_lock_init(&txq->lock);
+
        /*
         * Tell nic where to find circular buffer of Tx Frame Descriptors for
         * given Tx queue, and enable the DMA channel used for that queue.
         * Circular buffer (TFD queue in DRAM) physical base address */
-       iwl_write_direct32(bus(trans), FH_MEM_CBBC_QUEUE(txq_id),
+       iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id),
                             txq->q.dma_addr >> 8);
 
        return 0;
@@ -404,8 +411,6 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
        struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
        struct iwl_queue *q = &txq->q;
        enum dma_data_direction dma_dir;
-       unsigned long flags;
-       spinlock_t *lock;
 
        if (!q->n_bd)
                return;
@@ -413,22 +418,19 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
        /* In the command queue, all the TBs are mapped as BIDI
         * so unmap them as such.
         */
-       if (txq_id == trans->shrd->cmd_queue) {
+       if (txq_id == trans->shrd->cmd_queue)
                dma_dir = DMA_BIDIRECTIONAL;
-               lock = &trans->hcmd_lock;
-       } else {
+       else
                dma_dir = DMA_TO_DEVICE;
-               lock = &trans->shrd->sta_lock;
-       }
 
-       spin_lock_irqsave(lock, flags);
+       spin_lock_bh(&txq->lock);
        while (q->write_ptr != q->read_ptr) {
                /* The read_ptr needs to bound by q->n_window */
                iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr),
                                    dma_dir);
                q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
        }
-       spin_unlock_irqrestore(lock, flags);
+       spin_unlock_bh(&txq->lock);
 }
 
 /**
@@ -443,7 +445,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
-       struct device *dev = bus(trans)->dev;
+       struct device *dev = trans->dev;
        int i;
        if (WARN_ON(!txq))
                return;
@@ -581,16 +583,16 @@ static int iwl_tx_init(struct iwl_trans *trans)
                alloc = true;
        }
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Turn off all Tx DMA fifos */
-       iwl_write_prph(bus(trans), SCD_TXFACT, 0);
+       iwl_write_prph(trans, SCD_TXFACT, 0);
 
        /* Tell NIC where to find the "keep warm" buffer */
-       iwl_write_direct32(bus(trans), FH_KW_MEM_ADDR_REG,
+       iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
                           trans_pcie->kw.dma >> 4);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* Alloc and init all Tx queues, including the command queue (#4/#9) */
        for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) {
@@ -619,49 +621,220 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans)
  * to set power to V_AUX, do:
 
                if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
-                       iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG,
+                       iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG,
                                               APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
                                               ~APMG_PS_CTRL_MSK_PWR_SRC);
  */
 
-       iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG,
+       iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG,
                               APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
                               ~APMG_PS_CTRL_MSK_PWR_SRC);
 }
 
+/* PCI registers */
+#define PCI_CFG_RETRY_TIMEOUT  0x041
+#define PCI_CFG_LINK_CTRL_VAL_L0S_EN   0x01
+#define PCI_CFG_LINK_CTRL_VAL_L1_EN    0x02
+
+static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans)
+{
+       int pos;
+       u16 pci_lnk_ctl;
+       struct iwl_trans_pcie *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+
+       struct pci_dev *pci_dev = trans_pcie->pci_dev;
+
+       pos = pci_pcie_cap(pci_dev);
+       pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+       return pci_lnk_ctl;
+}
+
+static void iwl_apm_config(struct iwl_trans *trans)
+{
+       /*
+        * HW bug W/A for instability in PCIe bus L0S->L1 transition.
+        * Check if BIOS (or OS) enabled L1-ASPM on this device.
+        * If so (likely), disable L0S, so device moves directly L0->L1;
+        *    costs negligible amount of power savings.
+        * If not (unlikely), enable L0S, so there is at least some
+        *    power savings, even without L1.
+        */
+       u16 lctl = iwl_pciexp_link_ctrl(trans);
+
+       if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
+                               PCI_CFG_LINK_CTRL_VAL_L1_EN) {
+               /* L1-ASPM enabled; disable(!) L0S */
+               iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
+               dev_printk(KERN_INFO, trans->dev,
+                          "L1 Enabled; Disabling L0S\n");
+       } else {
+               /* L1-ASPM disabled; enable(!) L0S */
+               iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
+               dev_printk(KERN_INFO, trans->dev,
+                          "L1 Disabled; Enabling L0S\n");
+       }
+       trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
+}
+
+/*
+ * Start up NIC's basic functionality after it has been reset
+ * (e.g. after platform boot, or shutdown via iwl_apm_stop())
+ * NOTE:  This does not load uCode nor start the embedded processor
+ */
+static int iwl_apm_init(struct iwl_trans *trans)
+{
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       int ret = 0;
+       IWL_DEBUG_INFO(trans, "Init card's basic functions\n");
+
+       /*
+        * Use "set_bit" below rather than "write", to preserve any hardware
+        * bits already set by default after reset.
+        */
+
+       /* Disable L0S exit timer (platform NMI Work/Around) */
+       iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS,
+                         CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+
+       /*
+        * Disable L0s without affecting L1;
+        *  don't wait for ICH L0s (ICH bug W/A)
+        */
+       iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS,
+                         CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
+
+       /* Set FH wait threshold to maximum (HW error during stress W/A) */
+       iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
+
+       /*
+        * Enable HAP INTA (interrupt from management bus) to
+        * wake device's PCI Express link L1a -> L0s
+        */
+       iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
+                                   CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
+
+       iwl_apm_config(trans);
+
+       /* Configure analog phase-lock-loop before activating to D0A */
+       if (cfg(trans)->base_params->pll_cfg_val)
+               iwl_set_bit(trans, CSR_ANA_PLL_CFG,
+                           cfg(trans)->base_params->pll_cfg_val);
+
+       /*
+        * Set "initialization complete" bit to move adapter from
+        * D0U* --> D0A* (powered-up active) state.
+        */
+       iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+       /*
+        * Wait for clock stabilization; once stabilized, access to
+        * device-internal resources is supported, e.g. iwl_write_prph()
+        * and accesses to uCode SRAM.
+        */
+       ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
+                       CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+                       CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+       if (ret < 0) {
+               IWL_DEBUG_INFO(trans, "Failed to init the card\n");
+               goto out;
+       }
+
+       /*
+        * Enable DMA clock and wait for it to stabilize.
+        *
+        * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
+        * do not disable clocks.  This preserves any hardware bits already
+        * set by default in "CLK_CTRL_REG" after reset.
+        */
+       iwl_write_prph(trans, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+       udelay(20);
+
+       /* Disable L1-Active */
+       iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG,
+                         APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
+       set_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status);
+
+out:
+       return ret;
+}
+
+static int iwl_apm_stop_master(struct iwl_trans *trans)
+{
+       int ret = 0;
+
+       /* stop device's busmaster DMA activity */
+       iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+
+       ret = iwl_poll_bit(trans, CSR_RESET,
+                       CSR_RESET_REG_FLAG_MASTER_DISABLED,
+                       CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
+       if (ret)
+               IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n");
+
+       IWL_DEBUG_INFO(trans, "stop master\n");
+
+       return ret;
+}
+
+static void iwl_apm_stop(struct iwl_trans *trans)
+{
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
+
+       clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status);
+
+       /* Stop device's DMA activity */
+       iwl_apm_stop_master(trans);
+
+       /* Reset the entire device */
+       iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+
+       udelay(10);
+
+       /*
+        * Clear "initialization complete" bit to move adapter from
+        * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
+        */
+       iwl_clear_bit(trans, CSR_GP_CNTRL,
+                     CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+}
+
 static int iwl_nic_init(struct iwl_trans *trans)
 {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        unsigned long flags;
 
        /* nic_init */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
-       iwl_apm_init(priv(trans));
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
+       iwl_apm_init(trans);
 
        /* Set interrupt coalescing calibration timer to default (512 usecs) */
-       iwl_write8(bus(trans), CSR_INT_COALESCING,
+       iwl_write8(trans, CSR_INT_COALESCING,
                IWL_HOST_INT_CALIB_TIMEOUT_DEF);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        iwl_set_pwr_vmain(trans);
 
-       iwl_nic_config(priv(trans));
+       iwl_op_mode_nic_config(trans->op_mode);
 
+#ifndef CONFIG_IWLWIFI_IDI
        /* Allocate the RX queue, or reset if it is already allocated */
        iwl_rx_init(trans);
+#endif
 
        /* Allocate or reset and init all Tx and Command queues */
        if (iwl_tx_init(trans))
                return -ENOMEM;
 
-       if (hw_params(trans).shadow_reg_enable) {
+       if (cfg(trans)->base_params->shadow_reg_enable) {
                /* enable shadow regs in HW */
-               iwl_set_bit(bus(trans), CSR_MAC_SHADOW_REG_CTRL,
+               iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL,
                        0x800FFFFF);
        }
 
-       set_bit(STATUS_INIT, &trans->shrd->status);
-
        return 0;
 }
 
@@ -672,11 +845,11 @@ static int iwl_set_hw_ready(struct iwl_trans *trans)
 {
        int ret;
 
-       iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
+       iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
                CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
 
        /* See if we got it */
-       ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
+       ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG,
                                CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
                                CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
                                HW_READY_TIMEOUT);
@@ -686,21 +859,22 @@ static int iwl_set_hw_ready(struct iwl_trans *trans)
 }
 
 /* Note: returns standard 0/-ERROR code */
-static int iwl_trans_pcie_prepare_card_hw(struct iwl_trans *trans)
+static int iwl_prepare_card_hw(struct iwl_trans *trans)
 {
        int ret;
 
        IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n");
 
        ret = iwl_set_hw_ready(trans);
+       /* If the card is ready, exit 0 */
        if (ret >= 0)
                return 0;
 
        /* If HW is not ready, prepare the conditions to check again */
-       iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
+       iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
                        CSR_HW_IF_CONFIG_REG_PREPARE);
 
-       ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
+       ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG,
                        ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
                        CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
 
@@ -767,13 +941,88 @@ static const u8 iwlagn_pan_ac_to_queue[] = {
        7, 6, 5, 4,
 };
 
-static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
+/*
+ * ucode
+ */
+static int iwl_load_section(struct iwl_trans *trans, const char *name,
+                           const struct fw_desc *image, u32 dst_addr)
+{
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       dma_addr_t phy_addr = image->p_addr;
+       u32 byte_cnt = image->len;
+       int ret;
+
+       trans_pcie->ucode_write_complete = false;
+
+       iwl_write_direct32(trans,
+               FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
+               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
+
+       iwl_write_direct32(trans,
+               FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
+
+       iwl_write_direct32(trans,
+               FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
+               phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
+
+       iwl_write_direct32(trans,
+               FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
+               (iwl_get_dma_hi_addr(phy_addr)
+                       << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
+
+       iwl_write_direct32(trans,
+               FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
+               1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
+               1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
+               FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
+
+       iwl_write_direct32(trans,
+               FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
+               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE       |
+               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE    |
+               FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
+
+       IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name);
+       ret = wait_event_timeout(trans_pcie->ucode_write_waitq,
+                                trans_pcie->ucode_write_complete, 5 * HZ);
+       if (!ret) {
+               IWL_ERR(trans, "Could not load the %s uCode section\n",
+                       name);
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+static int iwl_load_given_ucode(struct iwl_trans *trans,
+                               const struct fw_img *image)
+{
+       int ret = 0;
+
+       ret = iwl_load_section(trans, "INST", &image->code,
+                                  IWLAGN_RTC_INST_LOWER_BOUND);
+       if (ret)
+               return ret;
+
+       ret = iwl_load_section(trans, "DATA", &image->data,
+                                   IWLAGN_RTC_DATA_LOWER_BOUND);
+       if (ret)
+               return ret;
+
+       /* Remove all resets to allow NIC to operate */
+       iwl_write32(trans, CSR_RESET, 0);
+
+       return 0;
+}
+
+static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
+                                  const struct fw_img *fw)
 {
        int ret;
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
+       bool hw_rfkill;
 
-       trans->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER;
        trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue;
        trans_pcie->ac_to_queue[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_queue;
 
@@ -783,26 +1032,23 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
        trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0;
        trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE;
 
-       if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
-            iwl_trans_pcie_prepare_card_hw(trans)) {
+       /* This may fail if AMT took ownership of the device */
+       if (iwl_prepare_card_hw(trans)) {
                IWL_WARN(trans, "Exit HW not ready\n");
                return -EIO;
        }
 
        /* If platform's RF_KILL switch is NOT set to KILL */
-       if (iwl_read32(bus(trans), CSR_GP_CNTRL) &
-                       CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-               clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
-       else
-               set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
+       hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
+       iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
-       if (iwl_is_rfkill(trans->shrd)) {
-               iwl_set_hw_rfkill_state(priv(trans), true);
-               iwl_enable_interrupts(trans);
+       if (hw_rfkill) {
+               iwl_enable_rfkill_int(trans);
                return -ERFKILL;
        }
 
-       iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF);
+       iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
 
        ret = iwl_nic_init(trans);
        if (ret) {
@@ -811,31 +1057,37 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
        }
 
        /* make sure rfkill handshake bits are cleared */
-       iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR,
+       iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
        /* clear (again), then enable host interrupts */
-       iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF);
+       iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
        iwl_enable_interrupts(trans);
 
        /* really make sure rfkill handshake bits are cleared */
-       iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
-       return 0;
+       /* Load the given image to the HW */
+       return iwl_load_given_ucode(trans, fw);
 }
 
 /*
  * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
- * must be called under priv->shrd->lock and mac access
+ * must be called under the irq lock and with MAC access
  */
 static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
 {
-       iwl_write_prph(bus(trans), SCD_TXFACT, mask);
+       struct iwl_trans_pcie __maybe_unused *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+
+       lockdep_assert_held(&trans_pcie->irq_lock);
+
+       iwl_write_prph(trans, SCD_TXFACT, mask);
 }
 
-static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
+static void iwl_tx_start(struct iwl_trans *trans)
 {
        const struct queue_to_fifo_ac *queue_to_fifo;
        struct iwl_trans_pcie *trans_pcie =
@@ -845,49 +1097,49 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
        int i, chan;
        u32 reg_val;
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        trans_pcie->scd_base_addr =
-               iwl_read_prph(bus(trans), SCD_SRAM_BASE_ADDR);
+               iwl_read_prph(trans, SCD_SRAM_BASE_ADDR);
        a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND;
        /* reset conext data memory */
        for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND;
                a += 4)
-               iwl_write_targ_mem(bus(trans), a, 0);
+               iwl_write_targ_mem(trans, a, 0);
        /* reset tx status memory */
        for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND;
                a += 4)
-               iwl_write_targ_mem(bus(trans), a, 0);
+               iwl_write_targ_mem(trans, a, 0);
        for (; a < trans_pcie->scd_base_addr +
               SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num);
               a += 4)
-               iwl_write_targ_mem(bus(trans), a, 0);
+               iwl_write_targ_mem(trans, a, 0);
 
-       iwl_write_prph(bus(trans), SCD_DRAM_BASE_ADDR,
+       iwl_write_prph(trans, SCD_DRAM_BASE_ADDR,
                       trans_pcie->scd_bc_tbls.dma >> 10);
 
        /* Enable DMA channel */
        for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++)
-               iwl_write_direct32(bus(trans), FH_TCSR_CHNL_TX_CONFIG_REG(chan),
+               iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
                                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
                                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
 
        /* Update FH chicken bits */
-       reg_val = iwl_read_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG);
-       iwl_write_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG,
+       reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG);
+       iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG,
                           reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
 
-       iwl_write_prph(bus(trans), SCD_QUEUECHAIN_SEL,
+       iwl_write_prph(trans, SCD_QUEUECHAIN_SEL,
                SCD_QUEUECHAIN_SEL_ALL(trans));
-       iwl_write_prph(bus(trans), SCD_AGGR_SEL, 0);
+       iwl_write_prph(trans, SCD_AGGR_SEL, 0);
 
        /* initiate the queues */
        for (i = 0; i < hw_params(trans).max_txq_num; i++) {
-               iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(i), 0);
-               iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, 0 | (i << 8));
-               iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr +
+               iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0);
+               iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8));
+               iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
                                SCD_CONTEXT_QUEUE_OFFSET(i), 0);
-               iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr +
+               iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
                                SCD_CONTEXT_QUEUE_OFFSET(i) +
                                sizeof(u32),
                                ((SCD_WIN_SIZE <<
@@ -898,7 +1150,7 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
                                SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
        }
 
-       iwl_write_prph(bus(trans), SCD_INTERRUPT_MASK,
+       iwl_write_prph(trans, SCD_INTERRUPT_MASK,
                        IWL_MASK(0, hw_params(trans).max_txq_num));
 
        /* Activate all Tx DMA/FIFO channels */
@@ -941,40 +1193,47 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
                                              fifo, 0);
        }
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* Enable L1-Active */
-       iwl_clear_bits_prph(bus(trans), APMG_PCIDEV_STT_REG,
+       iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
                          APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 }
 
+static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans)
+{
+       iwl_reset_ict(trans);
+       iwl_tx_start(trans);
+}
+
 /**
  * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
  */
 static int iwl_trans_tx_stop(struct iwl_trans *trans)
 {
-       int ch, txq_id;
+       int ch, txq_id, ret;
        unsigned long flags;
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
        /* Turn off all Tx DMA fifos */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        iwl_trans_txq_set_sched(trans, 0);
 
        /* Stop each Tx DMA channel, and wait for it to be idle */
        for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
-               iwl_write_direct32(bus(trans),
+               iwl_write_direct32(trans,
                                   FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
-               if (iwl_poll_direct_bit(bus(trans), FH_TSSR_TX_STATUS_REG,
+               ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG,
                                    FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
-                                   1000))
+                                   1000);
+               if (ret < 0)
                        IWL_ERR(trans, "Failing on timeout while stopping"
                            " DMA channel %d [0x%08x]", ch,
-                           iwl_read_direct32(bus(trans),
+                           iwl_read_direct32(trans,
                                              FH_TSSR_TX_STATUS_REG));
        }
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        if (!trans_pcie->txq) {
                IWL_WARN(trans, "Stopping tx queues that aren't allocated...");
@@ -994,9 +1253,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
        /* tell the device to stop sending interrupts */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_disable_interrupts(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* device going down, Stop using ICT table */
        iwl_disable_ict(trans);
@@ -1008,36 +1267,50 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
         * restart. So don't process again if the device is
         * already dead.
         */
-       if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) {
+       if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) {
                iwl_trans_tx_stop(trans);
+#ifndef CONFIG_IWLWIFI_IDI
                iwl_trans_rx_stop(trans);
-
+#endif
                /* Power-down device's busmaster DMA clocks */
-               iwl_write_prph(bus(trans), APMG_CLK_DIS_REG,
+               iwl_write_prph(trans, APMG_CLK_DIS_REG,
                               APMG_CLK_VAL_DMA_CLK_RQT);
                udelay(5);
        }
 
        /* Make sure (redundant) we've released our request to stay awake */
-       iwl_clear_bit(bus(trans), CSR_GP_CNTRL,
+       iwl_clear_bit(trans, CSR_GP_CNTRL,
                        CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 
        /* Stop the device, and put it in low power state */
-       iwl_apm_stop(priv(trans));
+       iwl_apm_stop(trans);
 
        /* Upon stop, the APM issues an interrupt if HW RF kill is set.
         * Clean again the interrupt here
         */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_disable_interrupts(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* wait to make sure we flush pending tasklet*/
-       synchronize_irq(bus(trans)->irq);
+       synchronize_irq(trans_pcie->irq);
        tasklet_kill(&trans_pcie->irq_tasklet);
 
+       cancel_work_sync(&trans_pcie->rx_replenish);
+
        /* stop and reset the on-board processor */
-       iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+       iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+}
+
+static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans)
+{
+       /* let the ucode operate on its own */
+       iwl_write32(trans, CSR_UCODE_DRV_GP1_SET,
+                   CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
+
+       iwl_disable_interrupts(trans);
+       iwl_clear_bit(trans, CSR_GP_CNTRL,
+                     CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 }
 
 static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
@@ -1092,6 +1365,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
        txq = &trans_pcie->txq[txq_id];
        q = &txq->q;
 
+       spin_lock(&txq->lock);
+
        /* In AGG mode, the index in the ring must correspond to the WiFi
         * sequence number. This is a HW requirements to help the SCD to parse
         * the BA.
@@ -1134,11 +1409,11 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
 
        /* Physical address of this Tx command's header (not MAC header!),
         * within command buffer array. */
-       txcmd_phys = dma_map_single(bus(trans)->dev,
+       txcmd_phys = dma_map_single(trans->dev,
                                    &dev_cmd->hdr, firstlen,
                                    DMA_BIDIRECTIONAL);
-       if (unlikely(dma_mapping_error(bus(trans)->dev, txcmd_phys)))
-               return -1;
+       if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
+               goto out_err;
        dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
        dma_unmap_len_set(out_meta, len, firstlen);
 
@@ -1153,14 +1428,14 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
         * if any (802.11 null frames have no payload). */
        secondlen = skb->len - hdr_len;
        if (secondlen > 0) {
-               phys_addr = dma_map_single(bus(trans)->dev, skb->data + hdr_len,
+               phys_addr = dma_map_single(trans->dev, skb->data + hdr_len,
                                           secondlen, DMA_TO_DEVICE);
-               if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) {
-                       dma_unmap_single(bus(trans)->dev,
+               if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
+                       dma_unmap_single(trans->dev,
                                         dma_unmap_addr(out_meta, mapping),
                                         dma_unmap_len(out_meta, len),
                                         DMA_BIDIRECTIONAL);
-                       return -1;
+                       goto out_err;
                }
        }
 
@@ -1174,7 +1449,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                                offsetof(struct iwl_tx_cmd, scratch);
 
        /* take back ownership of DMA buffer to enable update */
-       dma_sync_single_for_cpu(bus(trans)->dev, txcmd_phys, firstlen,
+       dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,
                        DMA_BIDIRECTIONAL);
        tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
        tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
@@ -1188,10 +1463,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
        /* Set up entry for this TFD in Tx byte-count array */
        iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
 
-       dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen,
+       dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
                        DMA_BIDIRECTIONAL);
 
-       trace_iwlwifi_dev_tx(priv(trans),
+       trace_iwlwifi_dev_tx(trans->dev,
                             &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
                             sizeof(struct iwl_tfd),
                             &dev_cmd->hdr, firstlen,
@@ -1212,46 +1487,77 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                        txq->need_update = 1;
                        iwl_txq_update_write_ptr(trans, txq);
                } else {
-                       iwl_stop_queue(trans, txq, "Queue is full");
+                       iwl_stop_queue(trans, txq);
                }
        }
+       spin_unlock(&txq->lock);
        return 0;
+ out_err:
+       spin_unlock(&txq->lock);
+       return -1;
 }
 
-static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans)
-{
-       /* Remove all resets to allow NIC to operate */
-       iwl_write32(bus(trans), CSR_RESET, 0);
-}
-
-static int iwl_trans_pcie_request_irq(struct iwl_trans *trans)
+static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
 {
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
        int err;
+       bool hw_rfkill;
 
        trans_pcie->inta_mask = CSR_INI_SET_MASK;
 
-       tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long))
-               iwl_irq_tasklet, (unsigned long)trans);
+       if (!trans_pcie->irq_requested) {
+               tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long))
+                       iwl_irq_tasklet, (unsigned long)trans);
+
+               iwl_alloc_isr_ict(trans);
+
+               err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED,
+                       DRV_NAME, trans);
+               if (err) {
+                       IWL_ERR(trans, "Error allocating IRQ %d\n",
+                               trans_pcie->irq);
+                       goto error;
+               }
 
-       iwl_alloc_isr_ict(trans);
+               INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish);
+               trans_pcie->irq_requested = true;
+       }
 
-       err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED,
-               DRV_NAME, trans);
+       err = iwl_prepare_card_hw(trans);
        if (err) {
-               IWL_ERR(trans, "Error allocating IRQ %d\n", bus(trans)->irq);
-               iwl_free_isr_ict(trans);
-               return err;
+               IWL_ERR(trans, "Error while preparing HW: %d", err);
+               goto err_free_irq;
        }
 
-       INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish);
-       return 0;
+       iwl_apm_init(trans);
+
+       hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
+       iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
+
+       return err;
+
+err_free_irq:
+       free_irq(trans_pcie->irq, trans);
+error:
+       iwl_free_isr_ict(trans);
+       tasklet_kill(&trans_pcie->irq_tasklet);
+       return err;
+}
+
+static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans)
+{
+       iwl_apm_stop(trans);
+
+       iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
+
+       /* Even if we stop the HW, we still want the RF kill interrupt */
+       iwl_enable_rfkill_int(trans);
 }
 
 static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
-                     int txq_id, int ssn, u32 status,
-                     struct sk_buff_head *skbs)
+                     int txq_id, int ssn, struct sk_buff_head *skbs)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
@@ -1259,6 +1565,8 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
        int tfd_num = ssn & (txq->q.n_bd - 1);
        int freed = 0;
 
+       spin_lock(&txq->lock);
+
        txq->time_stamp = jiffies;
 
        if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE &&
@@ -1273,6 +1581,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
                IWL_DEBUG_TX_QUEUES(trans, "Bad queue mapping txq_id %d, "
                        "agg_txq[sta_id[tid] %d", txq_id,
                        trans_pcie->agg_txq[sta_id][tid]);
+               spin_unlock(&txq->lock);
                return 1;
        }
 
@@ -1281,21 +1590,48 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
                                txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr,
                                tfd_num, ssn);
                freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs);
-               if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
-                  (!txq->sched_retry ||
-                  status != TX_STATUS_FAIL_PASSIVE_NO_RX))
-                       iwl_wake_queue(trans, txq, "Packets reclaimed");
+               if (iwl_queue_space(&txq->q) > txq->q.low_mark)
+                       iwl_wake_queue(trans, txq);
        }
+
+       spin_unlock(&txq->lock);
        return 0;
 }
 
+static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val)
+{
+       writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
+}
+
+static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val)
+{
+       writel(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
+}
+
+static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs)
+{
+       return readl(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
+}
+
 static void iwl_trans_pcie_free(struct iwl_trans *trans)
 {
-       iwl_calib_free_results(trans);
+       struct iwl_trans_pcie *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+
        iwl_trans_pcie_tx_free(trans);
+#ifndef CONFIG_IWLWIFI_IDI
        iwl_trans_pcie_rx_free(trans);
-       free_irq(bus(trans)->irq, trans);
-       iwl_free_isr_ict(trans);
+#endif
+       if (trans_pcie->irq_requested == true) {
+               free_irq(trans_pcie->irq, trans);
+               iwl_free_isr_ict(trans);
+       }
+
+       pci_disable_msi(trans_pcie->pci_dev);
+       iounmap(trans_pcie->hw_base);
+       pci_release_regions(trans_pcie->pci_dev);
+       pci_disable_device(trans_pcie->pci_dev);
+
        trans->shrd->trans = NULL;
        kfree(trans);
 }
@@ -1303,94 +1639,27 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans)
 #ifdef CONFIG_PM_SLEEP
 static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
 {
-       /*
-        * This function is called when system goes into suspend state
-        * mac80211 will call iwlagn_mac_stop() from the mac80211 suspend
-        * function first but since iwlagn_mac_stop() has no knowledge of
-        * who the caller is,
-        * it will not call apm_ops.stop() to stop the DMA operation.
-        * Calling apm_ops.stop here to make sure we stop the DMA.
-        *
-        * But of course ... if we have configured WoWLAN then we did other
-        * things already :-)
-        */
-       if (!trans->shrd->wowlan) {
-               iwl_apm_stop(priv(trans));
-       } else {
-               iwl_disable_interrupts(trans);
-               iwl_clear_bit(bus(trans), CSR_GP_CNTRL,
-                             CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-       }
-
        return 0;
 }
 
 static int iwl_trans_pcie_resume(struct iwl_trans *trans)
 {
-       bool hw_rfkill = false;
-
-       iwl_enable_interrupts(trans);
+       bool hw_rfkill;
 
-       if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) &
-                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
-               hw_rfkill = true;
+       hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
 
        if (hw_rfkill)
-               set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
+               iwl_enable_rfkill_int(trans);
        else
-               clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
+               iwl_enable_interrupts(trans);
 
-       iwl_set_hw_rfkill_state(priv(trans), hw_rfkill);
+       iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
        return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
 
-static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans,
-                                         enum iwl_rxon_context_id ctx,
-                                         const char *msg)
-{
-       u8 ac, txq_id;
-       struct iwl_trans_pcie *trans_pcie =
-               IWL_TRANS_GET_PCIE_TRANS(trans);
-
-       for (ac = 0; ac < AC_NUM; ac++) {
-               txq_id = trans_pcie->ac_to_queue[ctx][ac];
-               IWL_DEBUG_TX_QUEUES(trans, "Queue Status: Q[%d] %s\n",
-                       ac,
-                       (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0)
-                             ? "stopped" : "awake");
-               iwl_wake_queue(trans, &trans_pcie->txq[txq_id], msg);
-       }
-}
-
-const struct iwl_trans_ops trans_ops_pcie;
-
-static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd)
-{
-       struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) +
-                                             sizeof(struct iwl_trans_pcie),
-                                             GFP_KERNEL);
-       if (iwl_trans) {
-               struct iwl_trans_pcie *trans_pcie =
-                       IWL_TRANS_GET_PCIE_TRANS(iwl_trans);
-               iwl_trans->ops = &trans_ops_pcie;
-               iwl_trans->shrd = shrd;
-               trans_pcie->trans = iwl_trans;
-               spin_lock_init(&iwl_trans->hcmd_lock);
-       }
-
-       return iwl_trans;
-}
-
-static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id,
-                                     const char *msg)
-{
-       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-
-       iwl_stop_queue(trans, &trans_pcie->txq[txq_id], msg);
-}
-
 #define IWL_FLUSH_WAIT_MS      2000
 
 static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans)
@@ -1446,9 +1715,9 @@ static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt)
                IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
                        q->read_ptr, q->write_ptr);
                IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n",
-                       iwl_read_prph(bus(trans), SCD_QUEUE_RDPTR(cnt))
+                       iwl_read_prph(trans, SCD_QUEUE_RDPTR(cnt))
                                & (TFD_QUEUE_SIZE_MAX - 1),
-                       iwl_read_prph(bus(trans), SCD_QUEUE_WRPTR(cnt)));
+                       iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt)));
                return 1;
        }
 
@@ -1502,7 +1771,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display)
                        pos += scnprintf(*buf + pos, bufsz - pos,
                                "  %34s: 0X%08x\n",
                                get_fh_string(fh_tbl[i]),
-                               iwl_read_direct32(bus(trans), fh_tbl[i]));
+                               iwl_read_direct32(trans, fh_tbl[i]));
                }
                return pos;
        }
@@ -1511,7 +1780,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display)
        for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) {
                IWL_ERR(trans, "  %34s: 0X%08x\n",
                        get_fh_string(fh_tbl[i]),
-                       iwl_read_direct32(bus(trans), fh_tbl[i]));
+                       iwl_read_direct32(trans, fh_tbl[i]));
        }
        return 0;
 }
@@ -1581,7 +1850,7 @@ void iwl_dump_csr(struct iwl_trans *trans)
        for (i = 0; i <  ARRAY_SIZE(csr_tbl); i++) {
                IWL_ERR(trans, "  %25s: 0X%08x\n",
                        get_csr_string(csr_tbl[i]),
-                       iwl_read32(bus(trans), csr_tbl[i]));
+                       iwl_read32(trans, csr_tbl[i]));
        }
 }
 
@@ -1902,14 +2171,13 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
 #endif /*CONFIG_IWLWIFI_DEBUGFS */
 
 const struct iwl_trans_ops trans_ops_pcie = {
-       .alloc = iwl_trans_pcie_alloc,
-       .request_irq = iwl_trans_pcie_request_irq,
-       .start_device = iwl_trans_pcie_start_device,
-       .prepare_card_hw = iwl_trans_pcie_prepare_card_hw,
+       .start_hw = iwl_trans_pcie_start_hw,
+       .stop_hw = iwl_trans_pcie_stop_hw,
+       .fw_alive = iwl_trans_pcie_fw_alive,
+       .start_fw = iwl_trans_pcie_start_fw,
        .stop_device = iwl_trans_pcie_stop_device,
 
-       .tx_start = iwl_trans_pcie_tx_start,
-       .wake_any_queue = iwl_trans_pcie_wake_any_queue,
+       .wowlan_suspend = iwl_trans_pcie_wowlan_suspend,
 
        .send_cmd = iwl_trans_pcie_send_cmd,
 
@@ -1920,10 +2188,7 @@ const struct iwl_trans_ops trans_ops_pcie = {
        .tx_agg_alloc = iwl_trans_pcie_tx_agg_alloc,
        .tx_agg_setup = iwl_trans_pcie_tx_agg_setup,
 
-       .kick_nic = iwl_trans_pcie_kick_nic,
-
        .free = iwl_trans_pcie_free,
-       .stop_queue = iwl_trans_pcie_stop_queue,
 
        .dbgfs_register = iwl_trans_pcie_dbgfs_register,
 
@@ -1934,4 +2199,117 @@ const struct iwl_trans_ops trans_ops_pcie = {
        .suspend = iwl_trans_pcie_suspend,
        .resume = iwl_trans_pcie_resume,
 #endif
+       .write8 = iwl_trans_pcie_write8,
+       .write32 = iwl_trans_pcie_write32,
+       .read32 = iwl_trans_pcie_read32,
 };
+
+struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
+                                      struct pci_dev *pdev,
+                                      const struct pci_device_id *ent)
+{
+       struct iwl_trans_pcie *trans_pcie;
+       struct iwl_trans *trans;
+       u16 pci_cmd;
+       int err;
+
+       trans = kzalloc(sizeof(struct iwl_trans) +
+                            sizeof(struct iwl_trans_pcie), GFP_KERNEL);
+
+       if (WARN_ON(!trans))
+               return NULL;
+
+       trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+       trans->ops = &trans_ops_pcie;
+       trans->shrd = shrd;
+       trans_pcie->trans = trans;
+       spin_lock_init(&trans_pcie->irq_lock);
+       init_waitqueue_head(&trans_pcie->ucode_write_waitq);
+
+       /* W/A - seems to solve weird behavior. We need to remove this if we
+        * don't want to stay in L1 all the time. This wastes a lot of power */
+       pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+                               PCIE_LINK_STATE_CLKPM);
+
+       if (pci_enable_device(pdev)) {
+               err = -ENODEV;
+               goto out_no_pci;
+       }
+
+       pci_set_master(pdev);
+
+       err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
+       if (!err)
+               err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
+       if (err) {
+               err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+               if (!err)
+                       err = pci_set_consistent_dma_mask(pdev,
+                                                       DMA_BIT_MASK(32));
+               /* both attempts failed: */
+               if (err) {
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "No suitable DMA available.\n");
+                       goto out_pci_disable_device;
+               }
+       }
+
+       err = pci_request_regions(pdev, DRV_NAME);
+       if (err) {
+               dev_printk(KERN_ERR, &pdev->dev, "pci_request_regions failed");
+               goto out_pci_disable_device;
+       }
+
+       trans_pcie->hw_base = pci_ioremap_bar(pdev, 0);
+       if (!trans_pcie->hw_base) {
+               dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed");
+               err = -ENODEV;
+               goto out_pci_release_regions;
+       }
+
+       dev_printk(KERN_INFO, &pdev->dev,
+               "pci_resource_len = 0x%08llx\n",
+               (unsigned long long) pci_resource_len(pdev, 0));
+       dev_printk(KERN_INFO, &pdev->dev,
+               "pci_resource_base = %p\n", trans_pcie->hw_base);
+
+       dev_printk(KERN_INFO, &pdev->dev,
+               "HW Revision ID = 0x%X\n", pdev->revision);
+
+       /* We disable the RETRY_TIMEOUT register (0x41) to keep
+        * PCI Tx retries from interfering with C3 CPU state */
+       pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
+
+       err = pci_enable_msi(pdev);
+       if (err)
+               dev_printk(KERN_ERR, &pdev->dev,
+                       "pci_enable_msi failed(0X%x)", err);
+
+       trans->dev = &pdev->dev;
+       trans_pcie->irq = pdev->irq;
+       trans_pcie->pci_dev = pdev;
+       trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
+       trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
+       snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
+                "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
+
+       /* TODO: Move this away, not needed if not MSI */
+       /* enable rfkill interrupt: hw bug w/a */
+       pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
+       if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
+               pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+               pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
+       }
+
+       return trans;
+
+out_pci_release_regions:
+       pci_release_regions(pdev);
+out_pci_disable_device:
+       pci_disable_device(pdev);
+out_no_pci:
+       kfree(trans);
+       return NULL;
+}
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
deleted file mode 100644 (file)
index 1b20c4f..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-
-#include "iwl-trans.h"
-
-int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id,
-                          u32 flags, u16 len, const void *data)
-{
-       struct iwl_host_cmd cmd = {
-               .id = id,
-               .len = { len, },
-               .data = { data, },
-               .flags = flags,
-       };
-
-       return iwl_trans_send_cmd(trans, &cmd);
-}
index e6bf3f554772354ed816c2e707b5fed2f3d28105..b6fd4277962479ff34081523d06c2caea32dad48 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #ifndef __iwl_trans_h__
 #define __iwl_trans_h__
 
-#include <linux/debugfs.h>
-#include <linux/skbuff.h>
+#include <linux/ieee80211.h>
+#include <linux/mm.h> /* for page_address */
 
 #include "iwl-shared.h"
-#include "iwl-commands.h"
+#include "iwl-debug.h"
 
- /*This file includes the declaration that are exported from the transport
- * layer */
+/**
+ * DOC: Transport layer - what is it ?
+ *
+ * The tranport layer is the layer that deals with the HW directly. It provides
+ * an abstraction of the underlying HW to the upper layer. The transport layer
+ * doesn't provide any policy, algorithm or anything of this kind, but only
+ * mechanisms to make the HW do something.It is not completely stateless but
+ * close to it.
+ * We will have an implementation for each different supported bus.
+ */
+
+/**
+ * DOC: Life cycle of the transport layer
+ *
+ * The transport layer has a very precise life cycle.
+ *
+ *     1) A helper function is called during the module initialization and
+ *        registers the bus driver's ops with the transport's alloc function.
+ *     2) Bus's probe calls to the transport layer's allocation functions.
+ *        Of course this function is bus specific.
+ *     3) This allocation functions will spawn the upper layer which will
+ *        register mac80211.
+ *
+ *     4) At some point (i.e. mac80211's start call), the op_mode will call
+ *        the following sequence:
+ *        start_hw
+ *        start_fw
+ *
+ *     5) Then when finished (or reset):
+ *        stop_fw (a.k.a. stop device for the moment)
+ *        stop_hw
+ *
+ *     6) Eventually, the free function will be called.
+ */
 
 struct iwl_priv;
 struct iwl_shared;
+struct iwl_op_mode;
+struct fw_img;
+struct sk_buff;
+struct dentry;
 
+/**
+ * DOC: Host command section
+ *
+ * A host command is a commaned issued by the upper layer to the fw. There are
+ * several versions of fw that have several APIs. The transport layer is
+ * completely agnostic to these differences.
+ * The transport does provide helper functionnality (i.e. SYNC / ASYNC mode),
+ */
 #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
 #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
 #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
+#define SEQ_TO_QUEUE(s)        (((s) >> 8) & 0x1f)
+#define QUEUE_TO_SEQ(q)        (((q) & 0x1f) << 8)
+#define SEQ_TO_INDEX(s)        ((s) & 0xff)
+#define INDEX_TO_SEQ(i)        ((i) & 0xff)
+#define SEQ_RX_FRAME   cpu_to_le16(0x8000)
+
+/**
+ * struct iwl_cmd_header
+ *
+ * This header format appears in the beginning of each command sent from the
+ * driver, and each response/notification received from uCode.
+ */
+struct iwl_cmd_header {
+       u8 cmd;         /* Command ID:  REPLY_RXON, etc. */
+       u8 flags;       /* 0:5 reserved, 6 abort, 7 internal */
+       /*
+        * The driver sets up the sequence number to values of its choosing.
+        * uCode does not use this value, but passes it back to the driver
+        * when sending the response to each driver-originated command, so
+        * the driver can match the response to the command.  Since the values
+        * don't get used by uCode, the driver may set up an arbitrary format.
+        *
+        * There is one exception:  uCode sets bit 15 when it originates
+        * the response/notification, i.e. when the response/notification
+        * is not a direct response to a command sent by the driver.  For
+        * example, uCode issues REPLY_RX when it sends a received frame
+        * to the driver; it is not a direct response to any driver command.
+        *
+        * The Linux driver uses the following format:
+        *
+        *  0:7         tfd index - position within TX queue
+        *  8:12        TX queue id
+        *  13:14       reserved
+        *  15          unsolicited RX or uCode-originated notification
+        */
+       __le16 sequence;
+} __packed;
 
-enum {
+
+#define FH_RSCSR_FRAME_SIZE_MSK                0x00003FFF      /* bits 0-13 */
+
+struct iwl_rx_packet {
+       /*
+        * The first 4 bytes of the RX frame header contain both the RX frame
+        * size and some flags.
+        * Bit fields:
+        * 31:    flag flush RB request
+        * 30:    flag ignore TC (terminal counter) request
+        * 29:    flag fast IRQ request
+        * 28-14: Reserved
+        * 13-00: RX frame size
+        */
+       __le32 len_n_flags;
+       struct iwl_cmd_header hdr;
+       u8 data[];
+} __packed;
+
+/**
+ * enum CMD_MODE - how to send the host commands ?
+ *
+ * @CMD_SYNC: The caller will be stalled until the fw responds to the command
+ * @CMD_ASYNC: Return right away and don't want for the response
+ * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
+ *     response.
+ * @CMD_ON_DEMAND: This command is sent by the test mode pipe.
+ */
+enum CMD_MODE {
        CMD_SYNC = 0,
        CMD_ASYNC = BIT(0),
        CMD_WANT_SKB = BIT(1),
@@ -104,25 +213,38 @@ struct iwl_device_cmd {
 
 #define IWL_MAX_CMD_TFDS       2
 
+/**
+ * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command
+ *
+ * IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's
+ *     ring. The transport layer doesn't map the command's buffer to DMA, but
+ *     rather copies it to an previously allocated DMA buffer. This flag tells
+ *     the transport layer not to copy the command, but to map the existing
+ *     buffer. This can save memcpy and is worth with very big comamnds.
+ */
 enum iwl_hcmd_dataflag {
        IWL_HCMD_DFL_NOCOPY     = BIT(0),
 };
 
 /**
  * struct iwl_host_cmd - Host command to the uCode
+ *
  * @data: array of chunks that composes the data of the host command
- * @reply_page: pointer to the page that holds the response to the host command
+ * @resp_pkt: response packet, if %CMD_WANT_SKB was set
+ * @_rx_page_order: (internally used to free response packet)
+ * @_rx_page_addr: (internally used to free response packet)
  * @handler_status: return value of the handler of the command
  *     (put in setup_rx_handlers) - valid for SYNC mode only
- * @callback:
- * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC
+ * @flags: can be CMD_*
  * @len: array of the lenths of the chunks in data
- * @dataflags:
+ * @dataflags: IWL_HCMD_DFL_*
  * @id: id of the host command
  */
 struct iwl_host_cmd {
        const void *data[IWL_MAX_CMD_TFDS];
-       unsigned long reply_page;
+       struct iwl_rx_packet *resp_pkt;
+       unsigned long _rx_page_addr;
+       u32 _rx_page_order;
        int handler_status;
 
        u32 flags;
@@ -131,48 +253,94 @@ struct iwl_host_cmd {
        u8 id;
 };
 
+static inline void iwl_free_resp(struct iwl_host_cmd *cmd)
+{
+       free_pages(cmd->_rx_page_addr, cmd->_rx_page_order);
+}
+
+struct iwl_rx_cmd_buffer {
+       struct page *_page;
+};
+
+static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r)
+{
+       return page_address(r->_page);
+}
+
+static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
+{
+       struct page *p = r->_page;
+       r->_page = NULL;
+       return p;
+}
+
+/**
+ * struct iwl_trans_config - transport configuration
+ *
+ * @op_mode: pointer to the upper layer.
+ *     Must be set before any other call.
+ */
+struct iwl_trans_config {
+       struct iwl_op_mode *op_mode;
+};
+
 /**
  * struct iwl_trans_ops - transport specific operations
- * @alloc: allocates the meta data (not the queues themselves)
- * @request_irq: requests IRQ - will be called before the FW load in probe flow
- * @start_device: allocates and inits all the resources for the transport
- *                layer.
- * @prepare_card_hw: claim the ownership on the HW. Will be called during
- *                   probe.
- * @tx_start: starts and configures all the Tx fifo - usually done once the fw
- *           is alive.
- * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_*
+ *
+ * All the handlers MUST be implemented
+ *
+ * @start_hw: starts the HW- from that point on, the HW can send interrupts
+ *     May sleep
+ * @stop_hw: stops the HW- from that point on, the HW will be in low power but
+ *     will still issue interrupt if the HW RF kill is triggered.
+ *     May sleep
+ * @start_fw: allocates and inits all the resources for the transport
+ *     layer. Also kick a fw image.
+ *     May sleep
+ * @fw_alive: called when the fw sends alive notification
+ *     May sleep
  * @stop_device:stops the whole device (embedded CPU put to reset)
+ *     May sleep
+ * @wowlan_suspend: put the device into the correct mode for WoWLAN during
+ *     suspend. This is optional, if not implemented WoWLAN will not be
+ *     supported. This callback may sleep.
  * @send_cmd:send a host command
+ *     May sleep only if CMD_SYNC is set
  * @tx: send an skb
+ *     Must be atomic
  * @reclaim: free packet until ssn. Returns a list of freed packets.
+ *     Must be atomic
  * @tx_agg_alloc: allocate resources for a TX BA session
+ *     Must be atomic
  * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is
- *                 ready and a successful ADDBA response has been received.
+ *     ready and a successful ADDBA response has been received.
+ *     May sleep
  * @tx_agg_disable: de-configure a Tx queue to send AMPDUs
- * @kick_nic: remove the RESET from the embedded CPU and let it run
+ *     Must be atomic
  * @free: release all the ressource for the transport layer itself such as
- *        irq, tasklet etc...
- * @stop_queue: stop a specific queue
+ *     irq, tasklet etc... From this point on, the device may not issue
+ *     any interrupt (incl. RFKILL).
+ *     May sleep
  * @check_stuck_queue: check if a specific queue is stuck
  * @wait_tx_queue_empty: wait until all tx queues are empty
+ *     May sleep
  * @dbgfs_register: add the dbgfs files under this directory. Files will be
  *     automatically deleted.
  * @suspend: stop the device unless WoWLAN is configured
  * @resume: resume activity of the device
+ * @write8: write a u8 to a register at offset ofs from the BAR
+ * @write32: write a u32 to a register at offset ofs from the BAR
+ * @read32: read a u32 register at offset ofs from the BAR
  */
 struct iwl_trans_ops {
 
-       struct iwl_trans *(*alloc)(struct iwl_shared *shrd);
-       int (*request_irq)(struct iwl_trans *iwl_trans);
-       int (*start_device)(struct iwl_trans *trans);
-       int (*prepare_card_hw)(struct iwl_trans *trans);
+       int (*start_hw)(struct iwl_trans *iwl_trans);
+       void (*stop_hw)(struct iwl_trans *iwl_trans);
+       int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw);
+       void (*fw_alive)(struct iwl_trans *trans);
        void (*stop_device)(struct iwl_trans *trans);
-       void (*tx_start)(struct iwl_trans *trans);
 
-       void (*wake_any_queue)(struct iwl_trans *trans,
-                              enum iwl_rxon_context_id ctx,
-                              const char *msg);
+       void (*wowlan_suspend)(struct iwl_trans *trans);
 
        int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
 
@@ -180,8 +348,7 @@ struct iwl_trans_ops {
                struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx,
                u8 sta_id, u8 tid);
        int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid,
-                       int txq_id, int ssn, u32 status,
-                       struct sk_buff_head *skbs);
+                       int txq_id, int ssn, struct sk_buff_head *skbs);
 
        int (*tx_agg_disable)(struct iwl_trans *trans,
                              int sta_id, int tid);
@@ -191,12 +358,8 @@ struct iwl_trans_ops {
                             enum iwl_rxon_context_id ctx, int sta_id, int tid,
                             int frame_limit, u16 ssn);
 
-       void (*kick_nic)(struct iwl_trans *trans);
-
        void (*free)(struct iwl_trans *trans);
 
-       void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg);
-
        int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
        int (*check_stuck_queue)(struct iwl_trans *trans, int q);
        int (*wait_tx_queue_empty)(struct iwl_trans *trans);
@@ -204,127 +367,158 @@ struct iwl_trans_ops {
        int (*suspend)(struct iwl_trans *trans);
        int (*resume)(struct iwl_trans *trans);
 #endif
+       void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
+       void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
+       u32 (*read32)(struct iwl_trans *trans, u32 ofs);
 };
 
-/* one for each uCode image (inst/data, boot/init/runtime) */
-struct fw_desc {
-       dma_addr_t p_addr;      /* hardware address */
-       void *v_addr;           /* software address */
-       u32 len;                /* size in bytes */
-};
-
-struct fw_img {
-       struct fw_desc code;    /* firmware code image */
-       struct fw_desc data;    /* firmware data image */
-};
-
-/* Opaque calibration results */
-struct iwl_calib_result {
-       struct list_head list;
-       size_t cmd_len;
-       struct iwl_calib_hdr hdr;
-       /* data follows */
+/**
+ * enum iwl_trans_state - state of the transport layer
+ *
+ * @IWL_TRANS_NO_FW: no fw has sent an alive response
+ * @IWL_TRANS_FW_ALIVE: a fw has sent an alive response
+ */
+enum iwl_trans_state {
+       IWL_TRANS_NO_FW = 0,
+       IWL_TRANS_FW_ALIVE      = 1,
 };
 
 /**
  * struct iwl_trans - transport common data
+ *
  * @ops - pointer to iwl_trans_ops
+ * @op_mode - pointer to the op_mode
  * @shrd - pointer to iwl_shared which holds shared data from the upper layer
- * @hcmd_lock: protects HCMD
- * @ucode_write_complete: indicates that the ucode has been copied.
- * @ucode_rt: run time ucode image
- * @ucode_init: init ucode image
- * @ucode_wowlan: wake on wireless ucode image (optional)
+ * @reg_lock - protect hw register access
+ * @dev - pointer to struct device * that represents the device
+ * @hw_id: a u32 with the ID of the device / subdevice.
+ *     Set during transport allocation.
+ * @hw_id_str: a string with info about HW ID. Set during transport allocation.
  * @nvm_device_type: indicates OTP or eeprom
- * @calib_results: list head for init calibration results
+ * @pm_support: set to true in start_hw if link pm is supported
  */
 struct iwl_trans {
        const struct iwl_trans_ops *ops;
+       struct iwl_op_mode *op_mode;
        struct iwl_shared *shrd;
-       spinlock_t hcmd_lock;
+       enum iwl_trans_state state;
+       spinlock_t reg_lock;
 
-       u8 ucode_write_complete;        /* the image write is complete */
-       struct fw_img ucode_rt;
-       struct fw_img ucode_init;
-       struct fw_img ucode_wowlan;
+       struct device *dev;
+       u32 hw_rev;
+       u32 hw_id;
+       char hw_id_str[52];
 
-       /* eeprom related variables */
        int    nvm_device_type;
-
-       /* init calibration results */
-       struct list_head calib_results;
+       bool pm_support;
 
        /* pointer to trans specific struct */
        /*Ensure that this pointer will always be aligned to sizeof pointer */
-       char trans_specific[0] __attribute__((__aligned__(sizeof(void *))));
+       char trans_specific[0] __aligned(sizeof(void *));
 };
 
-static inline int iwl_trans_request_irq(struct iwl_trans *trans)
+static inline void iwl_trans_configure(struct iwl_trans *trans,
+                                      const struct iwl_trans_config *trans_cfg)
 {
-       return trans->ops->request_irq(trans);
+       /*
+        * only set the op_mode for the moment. Later on, this function will do
+        * more
+        */
+       trans->op_mode = trans_cfg->op_mode;
 }
 
-static inline int iwl_trans_start_device(struct iwl_trans *trans)
+static inline int iwl_trans_start_hw(struct iwl_trans *trans)
 {
-       return trans->ops->start_device(trans);
+       might_sleep();
+
+       return trans->ops->start_hw(trans);
 }
 
-static inline int iwl_trans_prepare_card_hw(struct iwl_trans *trans)
+static inline void iwl_trans_stop_hw(struct iwl_trans *trans)
 {
-       return trans->ops->prepare_card_hw(trans);
+       might_sleep();
+
+       trans->ops->stop_hw(trans);
+
+       trans->state = IWL_TRANS_NO_FW;
 }
 
-static inline void iwl_trans_stop_device(struct iwl_trans *trans)
+static inline void iwl_trans_fw_alive(struct iwl_trans *trans)
 {
-       trans->ops->stop_device(trans);
+       might_sleep();
+
+       trans->ops->fw_alive(trans);
+
+       trans->state = IWL_TRANS_FW_ALIVE;
 }
 
-static inline void iwl_trans_tx_start(struct iwl_trans *trans)
+static inline int iwl_trans_start_fw(struct iwl_trans *trans,
+                                    const struct fw_img *fw)
 {
-       trans->ops->tx_start(trans);
+       might_sleep();
+
+       return trans->ops->start_fw(trans, fw);
 }
 
-static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans,
-                                           enum iwl_rxon_context_id ctx,
-                                           const char *msg)
+static inline void iwl_trans_stop_device(struct iwl_trans *trans)
 {
-       trans->ops->wake_any_queue(trans, ctx, msg);
+       might_sleep();
+
+       trans->ops->stop_device(trans);
+
+       trans->state = IWL_TRANS_NO_FW;
 }
 
+static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans)
+{
+       might_sleep();
+       trans->ops->wowlan_suspend(trans);
+}
 
 static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
                                struct iwl_host_cmd *cmd)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->send_cmd(trans, cmd);
 }
 
-int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id,
-                          u32 flags, u16 len, const void *data);
-
 static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
                struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx,
                u8 sta_id, u8 tid)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->tx(trans, skb, dev_cmd, ctx, sta_id, tid);
 }
 
 static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id,
-                                int tid, int txq_id, int ssn, u32 status,
+                                int tid, int txq_id, int ssn,
                                 struct sk_buff_head *skbs)
 {
-       return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn,
-                                  status, skbs);
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
+       return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs);
 }
 
 static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans,
                                            int sta_id, int tid)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->tx_agg_disable(trans, sta_id, tid);
 }
 
 static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans,
                                         int sta_id, int tid)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->tx_agg_alloc(trans, sta_id, tid);
 }
 
@@ -334,12 +528,12 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans,
                                           int sta_id, int tid,
                                           int frame_limit, u16 ssn)
 {
-       trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn);
-}
+       might_sleep();
 
-static inline void iwl_trans_kick_nic(struct iwl_trans *trans)
-{
-       trans->ops->kick_nic(trans);
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
+       trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn);
 }
 
 static inline void iwl_trans_free(struct iwl_trans *trans)
@@ -347,19 +541,19 @@ static inline void iwl_trans_free(struct iwl_trans *trans)
        trans->ops->free(trans);
 }
 
-static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q,
-                                       const char *msg)
-{
-       trans->ops->stop_queue(trans, q, msg);
-}
-
 static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->wait_tx_queue_empty(trans);
 }
 
 static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->check_stuck_queue(trans, q);
 }
 static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
@@ -380,18 +574,35 @@ static inline int iwl_trans_resume(struct iwl_trans *trans)
 }
 #endif
 
-/*****************************************************
-* Transport layers implementations
-******************************************************/
-extern const struct iwl_trans_ops trans_ops_pcie;
+static inline void iwl_trans_write8(struct iwl_trans *trans, u32 ofs, u8 val)
+{
+       trans->ops->write8(trans, ofs, val);
+}
 
-int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc,
-                     const void *data, size_t len);
-void iwl_dealloc_ucode(struct iwl_trans *trans);
+static inline void iwl_trans_write32(struct iwl_trans *trans, u32 ofs, u32 val)
+{
+       trans->ops->write32(trans, ofs, val);
+}
 
-int iwl_send_calib_results(struct iwl_trans *trans);
-int iwl_calib_set(struct iwl_trans *trans,
-                 const struct iwl_calib_hdr *cmd, int len);
-void iwl_calib_free_results(struct iwl_trans *trans);
+static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs)
+{
+       return trans->ops->read32(trans, ofs);
+}
 
+/*****************************************************
+* Transport layers implementations + their allocation function
+******************************************************/
+struct pci_dev;
+struct pci_device_id;
+extern const struct iwl_trans_ops trans_ops_pcie;
+struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
+                                      struct pci_dev *pdev,
+                                      const struct pci_device_id *ent);
+int __must_check iwl_pci_register_driver(void);
+void iwl_pci_unregister_driver(void);
+
+extern const struct iwl_trans_ops trans_ops_idi;
+struct iwl_trans *iwl_trans_idi_alloc(struct iwl_shared *shrd,
+                                     void *pdev_void,
+                                     const void *ent_void);
 #endif /* __iwl_trans_h__ */
index 36a1b5b2585898094d158c7a5f874958d35c7851..d97cf44b75baa2037e22abaa48be19b71218397c 100644 (file)
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
  *****************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/dma-mapping.h>
 
-#include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
@@ -42,6 +38,7 @@
 #include "iwl-agn-calib.h"
 #include "iwl-trans.h"
 #include "iwl-fh.h"
+#include "iwl-op-mode.h"
 
 static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
        {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
@@ -80,157 +77,42 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
  *
  ******************************************************************************/
 
-static void iwl_free_fw_desc(struct iwl_bus *bus, struct fw_desc *desc)
-{
-       if (desc->v_addr)
-               dma_free_coherent(bus->dev, desc->len,
-                                 desc->v_addr, desc->p_addr);
-       desc->v_addr = NULL;
-       desc->len = 0;
-}
-
-static void iwl_free_fw_img(struct iwl_bus *bus, struct fw_img *img)
-{
-       iwl_free_fw_desc(bus, &img->code);
-       iwl_free_fw_desc(bus, &img->data);
-}
-
-void iwl_dealloc_ucode(struct iwl_trans *trans)
-{
-       iwl_free_fw_img(bus(trans), &trans->ucode_rt);
-       iwl_free_fw_img(bus(trans), &trans->ucode_init);
-       iwl_free_fw_img(bus(trans), &trans->ucode_wowlan);
-}
-
-int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc,
-                     const void *data, size_t len)
-{
-       if (!len) {
-               desc->v_addr = NULL;
-               return -EINVAL;
-       }
-
-       desc->v_addr = dma_alloc_coherent(bus->dev, len,
-                                         &desc->p_addr, GFP_KERNEL);
-       if (!desc->v_addr)
-               return -ENOMEM;
-
-       desc->len = len;
-       memcpy(desc->v_addr, data, len);
-       return 0;
-}
-
-/*
- * ucode
- */
-static int iwl_load_section(struct iwl_trans *trans, const char *name,
-                               struct fw_desc *image, u32 dst_addr)
-{
-       struct iwl_bus *bus = bus(trans);
-       dma_addr_t phy_addr = image->p_addr;
-       u32 byte_cnt = image->len;
-       int ret;
-
-       trans->ucode_write_complete = 0;
-
-       iwl_write_direct32(bus,
-               FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
-               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
-
-       iwl_write_direct32(bus,
-               FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
-
-       iwl_write_direct32(bus,
-               FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
-               phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
-
-       iwl_write_direct32(bus,
-               FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
-               (iwl_get_dma_hi_addr(phy_addr)
-                       << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
-
-       iwl_write_direct32(bus,
-               FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
-               1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
-               1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
-               FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
-
-       iwl_write_direct32(bus,
-               FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
-               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE       |
-               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE    |
-               FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
-
-       IWL_DEBUG_FW(bus, "%s uCode section being loaded...\n", name);
-       ret = wait_event_timeout(trans->shrd->wait_command_queue,
-                                trans->ucode_write_complete, 5 * HZ);
-       if (!ret) {
-               IWL_ERR(trans, "Could not load the %s uCode section\n",
-                       name);
-               return -ETIMEDOUT;
-       }
-
-       return 0;
-}
-
-static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans,
-                                       enum iwl_ucode_type ucode_type)
+static inline const struct fw_img *
+iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type)
 {
        switch (ucode_type) {
        case IWL_UCODE_INIT:
-               return &trans->ucode_init;
+               return &priv->fw->ucode_init;
        case IWL_UCODE_WOWLAN:
-               return &trans->ucode_wowlan;
+               return &priv->fw->ucode_wowlan;
        case IWL_UCODE_REGULAR:
-               return &trans->ucode_rt;
+               return &priv->fw->ucode_rt;
        case IWL_UCODE_NONE:
                break;
        }
        return NULL;
 }
 
-static int iwl_load_given_ucode(struct iwl_trans *trans,
-                                  enum iwl_ucode_type ucode_type)
-{
-       int ret = 0;
-       struct fw_img *image = iwl_get_ucode_image(trans, ucode_type);
-
-
-       if (!image) {
-               IWL_ERR(trans, "Invalid ucode requested (%d)\n",
-                       ucode_type);
-               return -EINVAL;
-       }
-
-       ret = iwl_load_section(trans, "INST", &image->code,
-                                  IWLAGN_RTC_INST_LOWER_BOUND);
-       if (ret)
-               return ret;
-
-       return iwl_load_section(trans, "DATA", &image->data,
-                                   IWLAGN_RTC_DATA_LOWER_BOUND);
-}
-
 /*
  *  Calibration
  */
-static int iwl_set_Xtal_calib(struct iwl_trans *trans)
+static int iwl_set_Xtal_calib(struct iwl_priv *priv)
 {
        struct iwl_calib_xtal_freq_cmd cmd;
        __le16 *xtal_calib =
-               (__le16 *)iwl_eeprom_query_addr(trans->shrd, EEPROM_XTAL);
+               (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL);
 
        iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD);
        cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
        cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
-       return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd));
+       return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
 }
 
-static int iwl_set_temperature_offset_calib(struct iwl_trans *trans)
+static int iwl_set_temperature_offset_calib(struct iwl_priv *priv)
 {
        struct iwl_calib_temperature_offset_cmd cmd;
        __le16 *offset_calib =
-               (__le16 *)iwl_eeprom_query_addr(trans->shrd,
+               (__le16 *)iwl_eeprom_query_addr(priv->shrd,
                                                EEPROM_RAW_TEMPERATURE);
 
        memset(&cmd, 0, sizeof(cmd));
@@ -239,48 +121,48 @@ static int iwl_set_temperature_offset_calib(struct iwl_trans *trans)
        if (!(cmd.radio_sensor_offset))
                cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET;
 
-       IWL_DEBUG_CALIB(trans, "Radio sensor offset: %d\n",
+       IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
                        le16_to_cpu(cmd.radio_sensor_offset));
-       return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd));
+       return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
 }
 
-static int iwl_set_temperature_offset_calib_v2(struct iwl_trans *trans)
+static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv)
 {
        struct iwl_calib_temperature_offset_v2_cmd cmd;
-       __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(trans->shrd,
+       __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd,
                                     EEPROM_KELVIN_TEMPERATURE);
        __le16 *offset_calib_low =
-               (__le16 *)iwl_eeprom_query_addr(trans->shrd,
+               (__le16 *)iwl_eeprom_query_addr(priv->shrd,
                                                EEPROM_RAW_TEMPERATURE);
        struct iwl_eeprom_calib_hdr *hdr;
 
        memset(&cmd, 0, sizeof(cmd));
        iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD);
-       hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(trans->shrd,
+       hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd,
                                                        EEPROM_CALIB_ALL);
        memcpy(&cmd.radio_sensor_offset_high, offset_calib_high,
                sizeof(*offset_calib_high));
        memcpy(&cmd.radio_sensor_offset_low, offset_calib_low,
                sizeof(*offset_calib_low));
        if (!(cmd.radio_sensor_offset_low)) {
-               IWL_DEBUG_CALIB(trans, "no info in EEPROM, use default\n");
+               IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n");
                cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET;
                cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET;
        }
        memcpy(&cmd.burntVoltageRef, &hdr->voltage,
                sizeof(hdr->voltage));
 
-       IWL_DEBUG_CALIB(trans, "Radio sensor offset high: %d\n",
+       IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n",
                        le16_to_cpu(cmd.radio_sensor_offset_high));
-       IWL_DEBUG_CALIB(trans, "Radio sensor offset low: %d\n",
+       IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n",
                        le16_to_cpu(cmd.radio_sensor_offset_low));
-       IWL_DEBUG_CALIB(trans, "Voltage Ref: %d\n",
+       IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n",
                        le16_to_cpu(cmd.burntVoltageRef));
 
-       return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd));
+       return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
 }
 
-static int iwl_send_calib_cfg(struct iwl_trans *trans)
+static int iwl_send_calib_cfg(struct iwl_priv *priv)
 {
        struct iwl_calib_cfg_cmd calib_cfg_cmd;
        struct iwl_host_cmd cmd = {
@@ -296,47 +178,47 @@ static int iwl_send_calib_cfg(struct iwl_trans *trans)
        calib_cfg_cmd.ucd_calib_cfg.flags =
                IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK;
 
-       return iwl_trans_send_cmd(trans, &cmd);
+       return iwl_dvm_send_cmd(priv, &cmd);
 }
 
 int iwlagn_rx_calib_result(struct iwl_priv *priv,
-                           struct iwl_rx_mem_buffer *rxb,
+                           struct iwl_rx_cmd_buffer *rxb,
                            struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
+       struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->data;
        int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
 
        /* reduce the size of the length field itself */
        len -= 4;
 
-       if (iwl_calib_set(trans(priv), hdr, len))
+       if (iwl_calib_set(priv, hdr, len))
                IWL_ERR(priv, "Failed to record calibration data %d\n",
                        hdr->op_code);
 
        return 0;
 }
 
-int iwl_init_alive_start(struct iwl_trans *trans)
+int iwl_init_alive_start(struct iwl_priv *priv)
 {
        int ret;
 
-       if (cfg(trans)->bt_params &&
-           cfg(trans)->bt_params->advanced_bt_coexist) {
+       if (cfg(priv)->bt_params &&
+           cfg(priv)->bt_params->advanced_bt_coexist) {
                /*
                 * Tell uCode we are ready to perform calibration
                 * need to perform this before any calibration
                 * no need to close the envlope since we are going
                 * to load the runtime uCode later.
                 */
-               ret = iwl_send_bt_env(trans, IWL_BT_COEX_ENV_OPEN,
+               ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
                        BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
                if (ret)
                        return ret;
 
        }
 
-       ret = iwl_send_calib_cfg(trans);
+       ret = iwl_send_calib_cfg(priv);
        if (ret)
                return ret;
 
@@ -344,21 +226,21 @@ int iwl_init_alive_start(struct iwl_trans *trans)
         * temperature offset calibration is only needed for runtime ucode,
         * so prepare the value now.
         */
-       if (cfg(trans)->need_temp_offset_calib) {
-               if (cfg(trans)->temp_offset_v2)
-                       return iwl_set_temperature_offset_calib_v2(trans);
+       if (cfg(priv)->need_temp_offset_calib) {
+               if (cfg(priv)->temp_offset_v2)
+                       return iwl_set_temperature_offset_calib_v2(priv);
                else
-                       return iwl_set_temperature_offset_calib(trans);
+                       return iwl_set_temperature_offset_calib(priv);
        }
 
        return 0;
 }
 
-static int iwl_send_wimax_coex(struct iwl_trans *trans)
+static int iwl_send_wimax_coex(struct iwl_priv *priv)
 {
        struct iwl_wimax_coex_cmd coex_cmd;
 
-       if (cfg(trans)->base_params->support_wimax_coexist) {
+       if (cfg(priv)->base_params->support_wimax_coexist) {
                /* UnMask wake up src at associated sleep */
                coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
 
@@ -377,7 +259,7 @@ static int iwl_send_wimax_coex(struct iwl_trans *trans)
                /* coexistence is disabled */
                memset(&coex_cmd, 0, sizeof(coex_cmd));
        }
-       return iwl_trans_send_cmd_pdu(trans,
+       return iwl_dvm_send_cmd_pdu(priv,
                                COEX_PRIORITY_TABLE_CMD, CMD_SYNC,
                                sizeof(coex_cmd), &coex_cmd);
 }
@@ -404,64 +286,54 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
        0, 0, 0, 0, 0, 0, 0
 };
 
-void iwl_send_prio_tbl(struct iwl_trans *trans)
+void iwl_send_prio_tbl(struct iwl_priv *priv)
 {
        struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd;
 
        memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl,
                sizeof(iwl_bt_prio_tbl));
-       if (iwl_trans_send_cmd_pdu(trans,
+       if (iwl_dvm_send_cmd_pdu(priv,
                                REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC,
                                sizeof(prio_tbl_cmd), &prio_tbl_cmd))
-               IWL_ERR(trans, "failed to send BT prio tbl command\n");
+               IWL_ERR(priv, "failed to send BT prio tbl command\n");
 }
 
-int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type)
+int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
 {
        struct iwl_bt_coex_prot_env_cmd env_cmd;
        int ret;
 
        env_cmd.action = action;
        env_cmd.type = type;
-       ret = iwl_trans_send_cmd_pdu(trans,
+       ret = iwl_dvm_send_cmd_pdu(priv,
                               REPLY_BT_COEX_PROT_ENV, CMD_SYNC,
                               sizeof(env_cmd), &env_cmd);
        if (ret)
-               IWL_ERR(trans, "failed to send BT env command\n");
+               IWL_ERR(priv, "failed to send BT env command\n");
        return ret;
 }
 
 
-static int iwl_alive_notify(struct iwl_trans *trans)
+static int iwl_alive_notify(struct iwl_priv *priv)
 {
-       struct iwl_priv *priv = priv(trans);
-       struct iwl_rxon_context *ctx;
        int ret;
 
-       if (!priv->tx_cmd_pool)
-               priv->tx_cmd_pool =
-                       kmem_cache_create("iwl_dev_cmd",
-                                         sizeof(struct iwl_device_cmd),
-                                         sizeof(void *), 0, NULL);
+       iwl_trans_fw_alive(trans(priv));
 
-       if (!priv->tx_cmd_pool)
-               return -ENOMEM;
+       priv->passive_no_rx = false;
+       priv->transport_queue_stop = 0;
 
-       iwl_trans_tx_start(trans);
-       for_each_context(priv, ctx)
-               ctx->last_tx_rejected = false;
-
-       ret = iwl_send_wimax_coex(trans);
+       ret = iwl_send_wimax_coex(priv);
        if (ret)
                return ret;
 
        if (!cfg(priv)->no_xtal_calib) {
-               ret = iwl_set_Xtal_calib(trans);
+               ret = iwl_set_Xtal_calib(priv);
                if (ret)
                        return ret;
        }
 
-       return iwl_send_calib_results(trans);
+       return iwl_send_calib_results(priv);
 }
 
 
@@ -470,23 +342,23 @@ static int iwl_alive_notify(struct iwl_trans *trans)
  *   using sample data 100 bytes apart.  If these sample points are good,
  *   it's a pretty good bet that everything between them is good, too.
  */
-static int iwl_verify_inst_sparse(struct iwl_bus *bus,
-                                     struct fw_desc *fw_desc)
+static int iwl_verify_inst_sparse(struct iwl_priv *priv,
+                                 const struct fw_desc *fw_desc)
 {
        __le32 *image = (__le32 *)fw_desc->v_addr;
        u32 len = fw_desc->len;
        u32 val;
        u32 i;
 
-       IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len);
+       IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len);
 
        for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
                /* read data comes through single port, auto-incr addr */
                /* NOTE: Use the debugless read so we don't flood kernel log
                 * if IWL_DL_IO is set */
-               iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR,
+               iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR,
                        i + IWLAGN_RTC_INST_LOWER_BOUND);
-               val = iwl_read32(bus, HBUS_TARG_MEM_RDAT);
+               val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image))
                        return -EIO;
        }
@@ -494,8 +366,8 @@ static int iwl_verify_inst_sparse(struct iwl_bus *bus,
        return 0;
 }
 
-static void iwl_print_mismatch_inst(struct iwl_bus *bus,
-                                   struct fw_desc *fw_desc)
+static void iwl_print_mismatch_inst(struct iwl_priv *priv,
+                                   const struct fw_desc *fw_desc)
 {
        __le32 *image = (__le32 *)fw_desc->v_addr;
        u32 len = fw_desc->len;
@@ -503,18 +375,18 @@ static void iwl_print_mismatch_inst(struct iwl_bus *bus,
        u32 offs;
        int errors = 0;
 
-       IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len);
+       IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len);
 
-       iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR,
+       iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR,
                           IWLAGN_RTC_INST_LOWER_BOUND);
 
        for (offs = 0;
             offs < len && errors < 20;
             offs += sizeof(u32), image++) {
                /* read data comes through single port, auto-incr addr */
-               val = iwl_read32(bus, HBUS_TARG_MEM_RDAT);
+               val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image)) {
-                       IWL_ERR(bus, "uCode INST section at "
+                       IWL_ERR(priv, "uCode INST section at "
                                "offset 0x%x, is 0x%x, s/b 0x%x\n",
                                offs, val, le32_to_cpu(*image));
                        errors++;
@@ -526,24 +398,24 @@ static void iwl_print_mismatch_inst(struct iwl_bus *bus,
  * iwl_verify_ucode - determine which instruction image is in SRAM,
  *    and verify its contents
  */
-static int iwl_verify_ucode(struct iwl_trans *trans,
+static int iwl_verify_ucode(struct iwl_priv *priv,
                            enum iwl_ucode_type ucode_type)
 {
-       struct fw_img *img = iwl_get_ucode_image(trans, ucode_type);
+       const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type);
 
        if (!img) {
-               IWL_ERR(trans, "Invalid ucode requested (%d)\n", ucode_type);
+               IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type);
                return -EINVAL;
        }
 
-       if (!iwl_verify_inst_sparse(bus(trans), &img->code)) {
-               IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n");
+       if (!iwl_verify_inst_sparse(priv, &img->code)) {
+               IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n");
                return 0;
        }
 
-       IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
+       IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
 
-       iwl_print_mismatch_inst(bus(trans), &img->code);
+       iwl_print_mismatch_inst(priv, &img->code);
        return -EIO;
 }
 
@@ -552,137 +424,74 @@ struct iwl_alive_data {
        u8 subtype;
 };
 
-static void iwl_alive_fn(struct iwl_trans *trans,
+static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
                            struct iwl_rx_packet *pkt,
                            void *data)
 {
+       struct iwl_priv *priv =
+               container_of(notif_wait, struct iwl_priv, notif_wait);
        struct iwl_alive_data *alive_data = data;
        struct iwl_alive_resp *palive;
 
-       palive = &pkt->u.alive_frame;
+       palive = (void *)pkt->data;
 
-       IWL_DEBUG_FW(trans, "Alive ucode status 0x%08X revision "
+       IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision "
                       "0x%01X 0x%01X\n",
                       palive->is_valid, palive->ver_type,
                       palive->ver_subtype);
 
-       trans->shrd->device_pointers.error_event_table =
+       priv->shrd->device_pointers.error_event_table =
                le32_to_cpu(palive->error_event_table_ptr);
-       trans->shrd->device_pointers.log_event_table =
+       priv->shrd->device_pointers.log_event_table =
                le32_to_cpu(palive->log_event_table_ptr);
 
        alive_data->subtype = palive->ver_subtype;
        alive_data->valid = palive->is_valid == UCODE_VALID_OK;
 }
 
-/* notification wait support */
-void iwl_init_notification_wait(struct iwl_shared *shrd,
-                                  struct iwl_notification_wait *wait_entry,
-                                  u8 cmd,
-                                  void (*fn)(struct iwl_trans *trans,
-                                             struct iwl_rx_packet *pkt,
-                                             void *data),
-                                  void *fn_data)
-{
-       wait_entry->fn = fn;
-       wait_entry->fn_data = fn_data;
-       wait_entry->cmd = cmd;
-       wait_entry->triggered = false;
-       wait_entry->aborted = false;
-
-       spin_lock_bh(&shrd->notif_wait_lock);
-       list_add(&wait_entry->list, &shrd->notif_waits);
-       spin_unlock_bh(&shrd->notif_wait_lock);
-}
-
-int iwl_wait_notification(struct iwl_shared *shrd,
-                            struct iwl_notification_wait *wait_entry,
-                            unsigned long timeout)
-{
-       int ret;
-
-       ret = wait_event_timeout(shrd->notif_waitq,
-                                wait_entry->triggered || wait_entry->aborted,
-                                timeout);
-
-       spin_lock_bh(&shrd->notif_wait_lock);
-       list_del(&wait_entry->list);
-       spin_unlock_bh(&shrd->notif_wait_lock);
-
-       if (wait_entry->aborted)
-               return -EIO;
-
-       /* return value is always >= 0 */
-       if (ret <= 0)
-               return -ETIMEDOUT;
-       return 0;
-}
-
-void iwl_remove_notification(struct iwl_shared *shrd,
-                               struct iwl_notification_wait *wait_entry)
-{
-       spin_lock_bh(&shrd->notif_wait_lock);
-       list_del(&wait_entry->list);
-       spin_unlock_bh(&shrd->notif_wait_lock);
-}
-
-void iwl_abort_notification_waits(struct iwl_shared *shrd)
-{
-       unsigned long flags;
-       struct iwl_notification_wait *wait_entry;
-
-       spin_lock_irqsave(&shrd->notif_wait_lock, flags);
-       list_for_each_entry(wait_entry, &shrd->notif_waits, list)
-               wait_entry->aborted = true;
-       spin_unlock_irqrestore(&shrd->notif_wait_lock, flags);
-
-       wake_up_all(&shrd->notif_waitq);
-}
-
 #define UCODE_ALIVE_TIMEOUT    HZ
 #define UCODE_CALIB_TIMEOUT    (2*HZ)
 
-int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
+int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
                                 enum iwl_ucode_type ucode_type)
 {
        struct iwl_notification_wait alive_wait;
        struct iwl_alive_data alive_data;
+       const struct fw_img *fw;
        int ret;
        enum iwl_ucode_type old_type;
 
-       ret = iwl_trans_start_device(trans);
-       if (ret)
-               return ret;
+       old_type = priv->shrd->ucode_type;
+       priv->shrd->ucode_type = ucode_type;
+       fw = iwl_get_ucode_image(priv, ucode_type);
 
-       iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE,
-                                     iwl_alive_fn, &alive_data);
+       if (!fw)
+               return -EINVAL;
 
-       old_type = trans->shrd->ucode_type;
-       trans->shrd->ucode_type = ucode_type;
+       iwl_init_notification_wait(&priv->notif_wait, &alive_wait, REPLY_ALIVE,
+                                     iwl_alive_fn, &alive_data);
 
-       ret = iwl_load_given_ucode(trans, ucode_type);
+       ret = iwl_trans_start_fw(trans(priv), fw);
        if (ret) {
-               trans->shrd->ucode_type = old_type;
-               iwl_remove_notification(trans->shrd, &alive_wait);
+               priv->shrd->ucode_type = old_type;
+               iwl_remove_notification(&priv->notif_wait, &alive_wait);
                return ret;
        }
 
-       iwl_trans_kick_nic(trans);
-
        /*
         * Some things may run in the background now, but we
         * just wait for the ALIVE notification here.
         */
-       ret = iwl_wait_notification(trans->shrd, &alive_wait,
+       ret = iwl_wait_notification(&priv->notif_wait, &alive_wait,
                                        UCODE_ALIVE_TIMEOUT);
        if (ret) {
-               trans->shrd->ucode_type = old_type;
+               priv->shrd->ucode_type = old_type;
                return ret;
        }
 
        if (!alive_data.valid) {
-               IWL_ERR(trans, "Loaded ucode is not valid!\n");
-               trans->shrd->ucode_type = old_type;
+               IWL_ERR(priv, "Loaded ucode is not valid!\n");
+               priv->shrd->ucode_type = old_type;
                return -EIO;
        }
 
@@ -692,9 +501,9 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
         * skip it for WoWLAN.
         */
        if (ucode_type != IWL_UCODE_WOWLAN) {
-               ret = iwl_verify_ucode(trans, ucode_type);
+               ret = iwl_verify_ucode(priv, ucode_type);
                if (ret) {
-                       trans->shrd->ucode_type = old_type;
+                       priv->shrd->ucode_type = old_type;
                        return ret;
                }
 
@@ -702,41 +511,41 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
                msleep(5);
        }
 
-       ret = iwl_alive_notify(trans);
+       ret = iwl_alive_notify(priv);
        if (ret) {
-               IWL_WARN(trans,
+               IWL_WARN(priv,
                        "Could not complete ALIVE transition: %d\n", ret);
-               trans->shrd->ucode_type = old_type;
+               priv->shrd->ucode_type = old_type;
                return ret;
        }
 
        return 0;
 }
 
-int iwl_run_init_ucode(struct iwl_trans *trans)
+int iwl_run_init_ucode(struct iwl_priv *priv)
 {
        struct iwl_notification_wait calib_wait;
        int ret;
 
-       lockdep_assert_held(&trans->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /* No init ucode required? Curious, but maybe ok */
-       if (!trans->ucode_init.code.len)
+       if (!priv->fw->ucode_init.code.len)
                return 0;
 
-       if (trans->shrd->ucode_type != IWL_UCODE_NONE)
+       if (priv->shrd->ucode_type != IWL_UCODE_NONE)
                return 0;
 
-       iwl_init_notification_wait(trans->shrd, &calib_wait,
+       iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
                                      CALIBRATION_COMPLETE_NOTIFICATION,
                                      NULL, NULL);
 
        /* Will also start the device */
-       ret = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT);
+       ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT);
        if (ret)
                goto error;
 
-       ret = iwl_init_alive_start(trans);
+       ret = iwl_init_alive_start(priv);
        if (ret)
                goto error;
 
@@ -744,15 +553,15 @@ int iwl_run_init_ucode(struct iwl_trans *trans)
         * Some things may run in the background now, but we
         * just wait for the calibration complete notification.
         */
-       ret = iwl_wait_notification(trans->shrd, &calib_wait,
+       ret = iwl_wait_notification(&priv->notif_wait, &calib_wait,
                                        UCODE_CALIB_TIMEOUT);
 
        goto out;
 
  error:
-       iwl_remove_notification(trans->shrd, &calib_wait);
+       iwl_remove_notification(&priv->notif_wait, &calib_wait);
  out:
        /* Whatever happened, stop the device */
-       iwl_trans_stop_device(trans);
+       iwl_trans_stop_device(trans(priv));
        return ret;
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-wifi.h
deleted file mode 100644 (file)
index 1850110..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-
-#ifndef __iwl_wifi_h__
-#define __iwl_wifi_h__
-
-#include "iwl-shared.h"
-
-int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type);
-void iwl_send_prio_tbl(struct iwl_trans *trans);
-int iwl_init_alive_start(struct iwl_trans *trans);
-int iwl_run_init_ucode(struct iwl_trans *trans);
-int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
-                                enum iwl_ucode_type ucode_type);
-#endif  /* __iwl_wifi_h__ */
index abb4805fa8dfe2b82d8aee77ece564524ca7f596..f5f7070b7e222e8c41cc72eaae2c50f06e78e25a 100644 (file)
@@ -144,7 +144,7 @@ TRACE_EVENT(iwm_tx_packets,
 
        TP_printk(
                IWM_PR_FMT " Tx %spacket: eot %d, seq 0x%x, sta_color 0x%x, "
-               "ra_tid 0x%x, credit_group 0x%x, embeded_packets %d, %d bytes",
+               "ra_tid 0x%x, credit_group 0x%x, embedded_packets %d, %d bytes",
                IWM_PR_ARG, !__entry->eot ? "concatenated " : "",
                __entry->eot, __entry->seq, __entry->color, __entry->ra_tid,
                __entry->credit_group, __entry->npkt, __entry->bytes
index 4b9e730d2c8a13cc184f1ee5b5cba868f59398a7..b4f6cb3298a46c08826fda462f963ef4b52a4459 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/etherdevice.h>
 #include <linux/debugfs.h>
 #include <linux/module.h>
+#include <linux/ktime.h>
 #include <net/genetlink.h>
 #include "mac80211_hwsim.h"
 
@@ -321,11 +322,15 @@ struct mac80211_hwsim_data {
        struct dentry *debugfs_group;
 
        int power_level;
+
+       /* difference between this hw's clock and the real clock, in usecs */
+       u64 tsf_offset;
 };
 
 
 struct hwsim_radiotap_hdr {
        struct ieee80211_radiotap_header hdr;
+       __le64 rt_tsft;
        u8 rt_flags;
        u8 rt_rate;
        __le16 rt_channel;
@@ -367,6 +372,28 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
        return NETDEV_TX_OK;
 }
 
+static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data)
+{
+       struct timeval tv = ktime_to_timeval(ktime_get_real());
+       u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
+       return cpu_to_le64(now + data->tsf_offset);
+}
+
+static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw,
+               struct ieee80211_vif *vif)
+{
+       struct mac80211_hwsim_data *data = hw->priv;
+       return le64_to_cpu(__mac80211_hwsim_get_tsf(data));
+}
+
+static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
+               struct ieee80211_vif *vif, u64 tsf)
+{
+       struct mac80211_hwsim_data *data = hw->priv;
+       struct timeval tv = ktime_to_timeval(ktime_get_real());
+       u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
+       data->tsf_offset = tsf - now;
+}
 
 static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
                                      struct sk_buff *tx_skb)
@@ -391,7 +418,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
        hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
        hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
                                          (1 << IEEE80211_RADIOTAP_RATE) |
+                                         (1 << IEEE80211_RADIOTAP_TSFT) |
                                          (1 << IEEE80211_RADIOTAP_CHANNEL));
+       hdr->rt_tsft = __mac80211_hwsim_get_tsf(data);
        hdr->rt_flags = 0;
        hdr->rt_rate = txrate->bitrate / 5;
        hdr->rt_channel = cpu_to_le16(data->channel->center_freq);
@@ -592,7 +621,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
        return;
 
 nla_put_failure:
-       printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+       printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
 }
 
 static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
@@ -610,7 +639,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
        }
 
        memset(&rx_status, 0, sizeof(rx_status));
-       /* TODO: set mactime */
+       rx_status.mactime = le64_to_cpu(__mac80211_hwsim_get_tsf(data));
+       rx_status.flag |= RX_FLAG_MACTIME_MPDU;
        rx_status.freq = data->channel->center_freq;
        rx_status.band = data->channel->band;
        rx_status.rate_idx = info->control.rates[0].idx;
@@ -667,6 +697,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        bool ack;
        struct ieee80211_tx_info *txi;
        u32 _pid;
+       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
+       struct mac80211_hwsim_data *data = hw->priv;
+
+       if (ieee80211_is_beacon(mgmt->frame_control) ||
+           ieee80211_is_probe_resp(mgmt->frame_control))
+               mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data);
 
        mac80211_hwsim_monitor_rx(hw, skb);
 
@@ -763,9 +799,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
                                     struct ieee80211_vif *vif)
 {
        struct ieee80211_hw *hw = arg;
+       struct mac80211_hwsim_data *data = hw->priv;
        struct sk_buff *skb;
        struct ieee80211_tx_info *info;
        u32 _pid;
+       struct ieee80211_mgmt *mgmt;
 
        hwsim_check_magic(vif);
 
@@ -779,6 +817,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
                return;
        info = IEEE80211_SKB_CB(skb);
 
+       mgmt = (struct ieee80211_mgmt *) skb->data;
+       mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data);
+
        mac80211_hwsim_monitor_rx(hw, skb);
 
        /* wmediumd mode check */
@@ -1199,6 +1240,8 @@ static struct ieee80211_ops mac80211_hwsim_ops =
        .sw_scan_start = mac80211_hwsim_sw_scan,
        .sw_scan_complete = mac80211_hwsim_sw_scan_complete,
        .flush = mac80211_hwsim_flush,
+       .get_tsf = mac80211_hwsim_get_tsf,
+       .set_tsf = mac80211_hwsim_set_tsf,
 };
 
 
@@ -1564,7 +1607,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
 
        return 0;
 err:
-       printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+       printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
        goto out;
 out:
        dev_kfree_skb(skb);
@@ -1580,11 +1623,11 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2,
        wmediumd_pid = info->snd_pid;
 
        printk(KERN_DEBUG "mac80211_hwsim: received a REGISTER, "
-       "switching to wmediumd mode with pid %d\n", info->snd_pid);
+              "switching to wmediumd mode with pid %d\n", info->snd_pid);
 
        return 0;
 out:
-       printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+       printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
        return -EINVAL;
 }
 
@@ -1647,7 +1690,7 @@ static int hwsim_init_netlink(void)
        return 0;
 
 failure:
-       printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+       printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
        return -EINVAL;
 }
 
index 079e5532e686c0c9f4256fc5b4207316b0248f1c..ea6832dc6677d7e689b8ac1bd6b620f7be2706b5 100644 (file)
@@ -182,7 +182,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
        skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
        tx_info_aggr =  MWIFIEX_SKB_TXCB(skb_aggr);
 
-       tx_info_aggr->bss_index = tx_info_src->bss_index;
+       tx_info_aggr->bss_type = tx_info_src->bss_type;
+       tx_info_aggr->bss_num = tx_info_src->bss_num;
        skb_aggr->priority = skb_src->priority;
 
        do {
index c3b6c4652cd6cd87d6a5fd8e22506013bcfe1e92..84508b0652653f435ac29def452c87e4e64834ed 100644 (file)
@@ -79,7 +79,7 @@ static int
 mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
                         u8 key_index, bool pairwise, const u8 *mac_addr)
 {
-       struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 
        if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) {
                wiphy_err(wiphy, "deleting the crypto keys\n");
@@ -122,7 +122,7 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
                                struct net_device *dev,
                                bool enabled, int timeout)
 {
-       struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
        u32 ps_mode;
 
        if (timeout)
@@ -143,10 +143,10 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
                                 u8 key_index, bool unicast,
                                 bool multicast)
 {
-       struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 
        /* Return if WEP key not configured */
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED)
+       if (!priv->sec_info.wep_enabled)
                return 0;
 
        if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) {
@@ -165,7 +165,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
                         u8 key_index, bool pairwise, const u8 *mac_addr,
                         struct key_params *params)
 {
-       struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 
        if (mwifiex_set_encode(priv, params->key, params->key_len,
                                                        key_index, 0)) {
@@ -376,7 +376,12 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
                             struct ieee80211_channel *chan,
                             enum nl80211_channel_type channel_type)
 {
-       struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+       struct mwifiex_private *priv;
+
+       if (dev)
+               priv = mwifiex_netdev_get_priv(dev);
+       else
+               priv = mwifiex_cfg80211_get_priv(wiphy);
 
        if (priv->media_connected) {
                wiphy_err(wiphy, "This setting is valid only when station "
@@ -534,6 +539,11 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
                ret = -EFAULT;
        }
 
+       /* Get DTIM period information from firmware */
+       mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
+                             HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
+                             &priv->dtim_period);
+
        /*
         * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid
         * MCS index values for us are 0 to 7.
@@ -557,6 +567,22 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
        /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */
        sinfo->txrate.legacy = rate.rate * 5;
 
+       if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+               sinfo->filled |= STATION_INFO_BSS_PARAM;
+               sinfo->bss_param.flags = 0;
+               if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
+                                               WLAN_CAPABILITY_SHORT_PREAMBLE)
+                       sinfo->bss_param.flags |=
+                                       BSS_PARAM_FLAGS_SHORT_PREAMBLE;
+               if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
+                                               WLAN_CAPABILITY_SHORT_SLOT_TIME)
+                       sinfo->bss_param.flags |=
+                                       BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
+               sinfo->bss_param.dtim_period = priv->dtim_period;
+               sinfo->bss_param.beacon_interval =
+                       priv->curr_bss_params.bss_descriptor.beacon_period;
+       }
+
        return ret;
 }
 
@@ -587,7 +613,6 @@ static struct ieee80211_rate mwifiex_rates[] = {
        {.bitrate = 20, .hw_value = 4, },
        {.bitrate = 55, .hw_value = 11, },
        {.bitrate = 110, .hw_value = 22, },
-       {.bitrate = 220, .hw_value = 44, },
        {.bitrate = 60, .hw_value = 12, },
        {.bitrate = 90, .hw_value = 18, },
        {.bitrate = 120, .hw_value = 24, },
@@ -596,7 +621,6 @@ static struct ieee80211_rate mwifiex_rates[] = {
        {.bitrate = 360, .hw_value = 72, },
        {.bitrate = 480, .hw_value = 96, },
        {.bitrate = 540, .hw_value = 108, },
-       {.bitrate = 720, .hw_value = 144, },
 };
 
 /* Channel definitions to be advertised to cfg80211 */
@@ -622,7 +646,7 @@ static struct ieee80211_supported_band mwifiex_band_2ghz = {
        .channels = mwifiex_channels_2ghz,
        .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz),
        .bitrates = mwifiex_rates,
-       .n_bitrates = 14,
+       .n_bitrates = ARRAY_SIZE(mwifiex_rates),
 };
 
 static struct ieee80211_channel mwifiex_channels_5ghz[] = {
@@ -662,8 +686,8 @@ static struct ieee80211_channel mwifiex_channels_5ghz[] = {
 static struct ieee80211_supported_band mwifiex_band_5ghz = {
        .channels = mwifiex_channels_5ghz,
        .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz),
-       .bitrates = mwifiex_rates - 4,
-       .n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4,
+       .bitrates = mwifiex_rates + 4,
+       .n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4,
 };
 
 
@@ -815,12 +839,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
                       u8 *bssid, int mode, struct ieee80211_channel *channel,
                       struct cfg80211_connect_params *sme, bool privacy)
 {
-       struct mwifiex_802_11_ssid req_ssid;
+       struct cfg80211_ssid req_ssid;
        int ret, auth_type = 0;
        struct cfg80211_bss *bss = NULL;
        u8 is_scanning_required = 0;
 
-       memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid));
+       memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
 
        req_ssid.ssid_len = ssid_len;
        if (ssid_len > IEEE80211_MAX_SSID_LEN) {
@@ -841,7 +865,14 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
                ret = mwifiex_set_rf_channel(priv, channel,
                                                priv->adapter->channel_type);
 
-       ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);  /* Disable keys */
+       /* As this is new association, clear locally stored
+        * keys and security related flags */
+       priv->sec_info.wpa_enabled = false;
+       priv->sec_info.wpa2_enabled = false;
+       priv->wep_key_curr_index = 0;
+       priv->sec_info.encryption_mode = 0;
+       priv->sec_info.is_authtype_auto = 0;
+       ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);
 
        if (mode == NL80211_IFTYPE_ADHOC) {
                /* "privacy" is set only for ad-hoc mode */
@@ -862,11 +893,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
        }
 
        /* Now handle infra mode. "sme" is valid for infra mode only */
-       if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC
-                       || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
+       if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
                auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
-       else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
-               auth_type = NL80211_AUTHTYPE_SHARED_KEY;
+               priv->sec_info.is_authtype_auto = 1;
+       } else {
+               auth_type = sme->auth_type;
+       }
 
        if (sme->crypto.n_ciphers_pairwise) {
                priv->sec_info.encryption_mode =
@@ -886,17 +918,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
                        dev_dbg(priv->adapter->dev,
                                "info: setting wep encryption"
                                " with key len %d\n", sme->key_len);
+                       priv->wep_key_curr_index = sme->key_idx;
                        ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
                                                        sme->key_idx, 0);
                }
        }
 done:
-       /* Do specific SSID scanning */
-       if (mwifiex_request_scan(priv, &req_ssid)) {
-               dev_err(priv->adapter->dev, "scan error\n");
-               return -EFAULT;
-       }
-
        /*
         * Scan entries are valid for some time (15 sec). So we can save one
         * active scan time if we just try cfg80211_get_bss first. If it fails
@@ -1004,7 +1031,7 @@ static int
 mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
                           struct cfg80211_ibss_params *params)
 {
-       struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
        int ret = 0;
 
        if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
@@ -1042,7 +1069,7 @@ done:
 static int
 mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 {
-       struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
        wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
                        priv->cfg_bssid);
@@ -1079,12 +1106,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
                dev_err(priv->adapter->dev, "failed to alloc scan_req\n");
                return -ENOMEM;
        }
-       for (i = 0; i < request->n_ssids; i++) {
-               memcpy(priv->user_scan_cfg->ssid_list[i].ssid,
-                       request->ssids[i].ssid, request->ssids[i].ssid_len);
-               priv->user_scan_cfg->ssid_list[i].max_len =
-                       request->ssids[i].ssid_len;
-       }
+
+       priv->user_scan_cfg->num_ssids = request->n_ssids;
+       priv->user_scan_cfg->ssid_list = request->ssids;
+
        for (i = 0; i < request->n_channels; i++) {
                chan = request->channels[i];
                priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
@@ -1217,7 +1242,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
                priv->bss_priority = 0;
                priv->bss_role = MWIFIEX_BSS_ROLE_STA;
-               priv->bss_index = 0;
                priv->bss_num = 0;
 
                break;
@@ -1281,10 +1305,7 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
  */
 int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
 {
-       struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
-
-       if (!priv || !dev)
-               return 0;
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
 #ifdef CONFIG_DEBUG_FS
        mwifiex_dev_debugfs_remove(priv);
index 6e0a3eaecf7070bcdcce90eb91e63d7fe6cc6aab..c82eb7ff2fa26bb381626ec8059a3b550a450fe0 100644 (file)
@@ -391,7 +391,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
 
        if (skb) {
                rx_info = MWIFIEX_SKB_RXCB(skb);
-               rx_info->bss_index = priv->bss_index;
+               rx_info->bss_num = priv->bss_num;
+               rx_info->bss_type = priv->bss_type;
        }
 
        if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) {
@@ -770,7 +771,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
 
        /* Check init command response */
        if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) {
-               if (ret == -1) {
+               if (ret) {
                        dev_err(adapter->dev, "%s: cmd %#x failed during "
                                "initialization\n", __func__, cmdresp_no);
                        mwifiex_init_fw_complete(adapter);
@@ -780,10 +781,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
        }
 
        if (adapter->curr_cmd) {
-               if (adapter->curr_cmd->wait_q_enabled && (!ret))
-                       adapter->cmd_wait_q.status = 0;
-               else if (adapter->curr_cmd->wait_q_enabled && (ret == -1))
-                       adapter->cmd_wait_q.status = -1;
+               if (adapter->curr_cmd->wait_q_enabled)
+                       adapter->cmd_wait_q.status = ret;
 
                /* Clean up and put current command back to cmd_free_q */
                mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
index ae17ce02a3d0f074d24924a39f54a8a59748f30f..be5fd1652e53a3d5930f14c42f4ec77439858373 100644 (file)
@@ -91,18 +91,14 @@ struct mwifiex_fw_image {
        u32 fw_len;
 };
 
-struct mwifiex_802_11_ssid {
-       u32 ssid_len;
-       u8 ssid[IEEE80211_MAX_SSID_LEN];
-};
-
 struct mwifiex_wait_queue {
        wait_queue_head_t wait;
        int status;
 };
 
 struct mwifiex_rxinfo {
-       u8 bss_index;
+       u8 bss_num;
+       u8 bss_type;
        struct sk_buff *parent;
        u8 use_count;
 };
@@ -110,7 +106,8 @@ struct mwifiex_rxinfo {
 struct mwifiex_txinfo {
        u32 status_code;
        u8 flags;
-       u8 bss_index;
+       u8 bss_num;
+       u8 bss_type;
 };
 
 enum mwifiex_wmm_ac_e {
index 51c5417c569c42570e0a3300c59529c2c6af767c..fc4ffee6c6b9ce4021a52b94b5a336f4d4207898 100644 (file)
@@ -86,11 +86,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
        MWIFIEX_802_11_PRIV_FILTER_8021X_WEP
 };
 
-enum MWIFIEX_802_11_WEP_STATUS {
-       MWIFIEX_802_11_WEP_ENABLED,
-       MWIFIEX_802_11_WEP_DISABLED,
-};
-
 #define CAL_SNR(RSSI, NF)              ((s16)((s16)(RSSI)-(s16)(NF)))
 
 #define PROPRIETARY_TLV_BASE_ID                 0x0100
@@ -857,11 +852,6 @@ struct mwifiex_user_scan_chan {
        u32 scan_time;
 } __packed;
 
-struct mwifiex_user_scan_ssid {
-       u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
-       u8 max_len;
-} __packed;
-
 struct mwifiex_user_scan_cfg {
        /*
         *  BSS mode to be sent in the firmware command
@@ -872,8 +862,9 @@ struct mwifiex_user_scan_cfg {
        u8 reserved;
        /* BSSID filter sent in the firmware command to limit the results */
        u8 specific_bssid[ETH_ALEN];
-       /* SSID filter list used in the to limit the scan results */
-       struct mwifiex_user_scan_ssid ssid_list[MWIFIEX_MAX_SSID_LIST_LENGTH];
+       /* SSID filter list used in the firmware to limit the scan results */
+       struct cfg80211_ssid *ssid_list;
+       u8 num_ssids;
        /* Variable number (fixed maximum) of channels to scan up */
        struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX];
 } __packed;
index 1d0ec57a0143d8f0a2b15cfbb2220ba065171045..e81bf6ef1666d3a9c55b8521eef6f34531771099 100644 (file)
@@ -82,7 +82,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv)
        priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
        priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
 
-       priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED;
+       priv->sec_info.wep_enabled = 0;
        priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
        priv->sec_info.encryption_mode = 0;
        for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++)
@@ -280,6 +280,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
        adapter->adhoc_awake_period = 0;
        memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
        adapter->arp_filter_size = 0;
+       adapter->channel_type = NL80211_CHAN_HT20;
 }
 
 /*
@@ -527,8 +528,9 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
                cur = &adapter->bss_prio_tbl[i].bss_prio_cur;
                lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
                dev_dbg(adapter->dev, "info: delete BSS priority table,"
-                               " index = %d, i = %d, head = %p, cur = %p\n",
-                             priv->bss_index, i, head, *cur);
+                               " bss_type = %d, bss_num = %d, i = %d,"
+                               " head = %p, cur = %p\n",
+                             priv->bss_type, priv->bss_num, i, head, *cur);
                if (*cur) {
                        spin_lock_irqsave(lock, flags);
                        if (list_empty(head)) {
index d5d81f1fe41c9c5b310e21cf0778284a43478f86..7ca4e8234f3ee6512dc9599a6a3d2a3d1bcaa012 100644 (file)
@@ -50,7 +50,7 @@ struct mwifiex_chan_freq {
 };
 
 struct mwifiex_ssid_bssid {
-       struct mwifiex_802_11_ssid ssid;
+       struct cfg80211_ssid ssid;
        u8 bssid[ETH_ALEN];
 };
 
@@ -122,7 +122,7 @@ struct mwifiex_ver_ext {
 
 struct mwifiex_bss_info {
        u32 bss_mode;
-       struct mwifiex_802_11_ssid ssid;
+       struct cfg80211_ssid ssid;
        u32 bss_chan;
        u32 region_code;
        u32 media_connected;
index 0b0eb5efba9dd4206d08b8f79c817319ab4c8037..bce9991612c8cea2a01ec73ac8433165c07c47ed 100644 (file)
@@ -417,7 +417,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
        auth_tlv = (struct mwifiex_ie_types_auth_type *) pos;
        auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
        auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type));
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
+       if (priv->sec_info.wep_enabled)
                auth_tlv->auth_type = cpu_to_le16(
                                (u16) priv->sec_info.authentication_mode);
        else
@@ -585,7 +585,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
                       le16_to_cpu(assoc_rsp->cap_info_bitmap),
                       le16_to_cpu(assoc_rsp->a_id));
 
-               ret = -1;
+               ret = le16_to_cpu(assoc_rsp->status_code);
                goto done;
        }
 
@@ -714,7 +714,7 @@ done:
 int
 mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
                                struct host_cmd_ds_command *cmd,
-                               struct mwifiex_802_11_ssid *req_ssid)
+                               struct cfg80211_ssid *req_ssid)
 {
        int rsn_ie_len = 0;
        struct mwifiex_adapter *adapter = priv->adapter;
@@ -1069,8 +1069,7 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
        priv->curr_bss_params.bss_descriptor.channel = bss_desc->channel;
        priv->curr_bss_params.band = (u8) bss_desc->bss_band;
 
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED
-           || priv->sec_info.wpa_enabled)
+       if (priv->sec_info.wep_enabled || priv->sec_info.wpa_enabled)
                tmp_cap |= WLAN_CAPABILITY_PRIVACY;
 
        if (IS_SUPPORT_MULTI_BANDS(priv->adapter)) {
@@ -1246,7 +1245,7 @@ int mwifiex_associate(struct mwifiex_private *priv,
  */
 int
 mwifiex_adhoc_start(struct mwifiex_private *priv,
-                   struct mwifiex_802_11_ssid *adhoc_ssid)
+                   struct cfg80211_ssid *adhoc_ssid)
 {
        dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n",
                priv->adhoc_channel);
index b728f54451e48e65bf4bef4841d0bd69f2e03492..790a3796483c9421a533033f591f6a9e4a43936a 100644 (file)
@@ -424,8 +424,8 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct sk_buff *new_skb;
        struct mwifiex_txinfo *tx_info;
 
-       dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n",
-                               jiffies, priv->bss_index);
+       dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
+                               jiffies, priv->bss_type, priv->bss_num);
 
        if (priv->adapter->surprise_removed) {
                kfree_skb(skb);
@@ -458,10 +458,11 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        tx_info = MWIFIEX_SKB_TXCB(skb);
-       tx_info->bss_index = priv->bss_index;
+       tx_info->bss_num = priv->bss_num;
+       tx_info->bss_type = priv->bss_type;
        mwifiex_fill_buffer(skb);
 
-       mwifiex_wmm_add_buf_txqueue(priv->adapter, skb);
+       mwifiex_wmm_add_buf_txqueue(priv, skb);
        atomic_inc(&priv->adapter->tx_pending);
 
        if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
@@ -531,8 +532,8 @@ mwifiex_tx_timeout(struct net_device *dev)
 {
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
-       dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n",
-                               jiffies, priv->bss_index);
+       dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n",
+                               jiffies, priv->bss_type, priv->bss_num);
        mwifiex_set_trans_start(dev);
        priv->num_tx_timeout++;
 }
@@ -604,18 +605,6 @@ int is_command_pending(struct mwifiex_adapter *adapter)
        return !is_cmd_pend_q_empty;
 }
 
-/*
- * This function returns the correct private structure pointer based
- * upon the BSS number.
- */
-struct mwifiex_private *
-mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index)
-{
-       if (!adapter || (bss_index >= adapter->priv_num))
-               return NULL;
-       return adapter->priv[bss_index];
-}
-
 /*
  * This is the main work queue function.
  *
index 3186aa437f421272f929ebdfb8872312c768782f..6dc116647411255741f2157b9063cb070b27bee3 100644 (file)
@@ -217,8 +217,9 @@ struct mwifiex_802_11_security {
        u8 wpa2_enabled;
        u8 wapi_enabled;
        u8 wapi_key_on;
-       enum MWIFIEX_802_11_WEP_STATUS wep_status;
+       u8 wep_enabled;
        u32 authentication_mode;
+       u8 is_authtype_auto;
        u32 encryption_mode;
 };
 
@@ -243,7 +244,7 @@ struct ieee_types_generic {
 
 struct mwifiex_bssdescriptor {
        u8 mac_address[ETH_ALEN];
-       struct mwifiex_802_11_ssid ssid;
+       struct cfg80211_ssid ssid;
        u32 privacy;
        s32 rssi;
        u32 channel;
@@ -352,7 +353,6 @@ struct mwifiex_private;
 
 struct mwifiex_private {
        struct mwifiex_adapter *adapter;
-       u8 bss_index;
        u8 bss_type;
        u8 bss_role;
        u8 bss_priority;
@@ -388,10 +388,11 @@ struct mwifiex_private {
        s16 bcn_rssi_avg;
        s16 bcn_nf_avg;
        struct mwifiex_bssdescriptor *attempted_bss_desc;
-       struct mwifiex_802_11_ssid prev_ssid;
+       struct cfg80211_ssid prev_ssid;
        u8 prev_bssid[ETH_ALEN];
        struct mwifiex_current_bss_params curr_bss_params;
        u16 beacon_period;
+       u8 dtim_period;
        u16 listen_interval;
        u16 atim_window;
        u8 adhoc_channel;
@@ -746,8 +747,7 @@ void mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
                            struct cmd_ctrl_node *cmd_node);
 int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                            struct host_cmd_ds_command *resp);
-s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
-                      struct mwifiex_802_11_ssid *ssid2);
+s32 mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2);
 int mwifiex_associate(struct mwifiex_private *priv,
                      struct mwifiex_bssdescriptor *bss_desc);
 int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
@@ -759,12 +759,12 @@ void mwifiex_reset_connect_state(struct mwifiex_private *priv);
 u8 mwifiex_band_to_radio_type(u8 band);
 int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
 int mwifiex_adhoc_start(struct mwifiex_private *priv,
-                       struct mwifiex_802_11_ssid *adhoc_ssid);
+                       struct cfg80211_ssid *adhoc_ssid);
 int mwifiex_adhoc_join(struct mwifiex_private *priv,
                       struct mwifiex_bssdescriptor *bss_desc);
 int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
                                    struct host_cmd_ds_command *cmd,
-                                   struct mwifiex_802_11_ssid *req_ssid);
+                                   struct cfg80211_ssid *req_ssid);
 int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
                                   struct host_cmd_ds_command *cmd,
                                   struct mwifiex_bssdescriptor *bss_desc);
@@ -884,8 +884,6 @@ mwifiex_netdev_get_priv(struct net_device *dev)
        return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev));
 }
 
-struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter
-                                               *adapter, u8 bss_index);
 int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
                             u32 func_init_shutdown);
 int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
@@ -899,7 +897,7 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
                            struct net_device *dev);
 int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
 int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
-                     struct mwifiex_802_11_ssid *req_ssid);
+                     struct cfg80211_ssid *req_ssid);
 int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
 int mwifiex_enable_hs(struct mwifiex_adapter *adapter);
 int mwifiex_disable_auto_ds(struct mwifiex_private *priv);
@@ -908,13 +906,12 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv,
 int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
                              struct mwifiex_rate_cfg *rate);
 int mwifiex_request_scan(struct mwifiex_private *priv,
-                        struct mwifiex_802_11_ssid *req_ssid);
+                        struct cfg80211_ssid *req_ssid);
 int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
                                struct mwifiex_user_scan_cfg *scan_req);
-int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel);
 int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
 
-int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel);
+int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel);
 
 int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
                       int key_len, u8 key_index, int disable);
index 6396d3318ead1e3b3afb26858d57873a228022b4..fd0302fe5bd84a9ecc75a77efee5150600a0c9c2 100644 (file)
@@ -163,8 +163,7 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
  * This function compares two SSIDs and checks if they match.
  */
 s32
-mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
-                struct mwifiex_802_11_ssid *ssid2)
+mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2)
 {
        if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len))
                return -1;
@@ -196,9 +195,8 @@ static bool
 mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv,
                                       struct mwifiex_bssdescriptor *bss_desc)
 {
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
-           && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
-           && ((!bss_desc->bcn_wpa_ie) ||
+       if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
+           !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
                ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id !=
            WLAN_EID_WPA))
            && ((!bss_desc->bcn_rsn_ie) ||
@@ -219,9 +217,8 @@ static bool
 mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv,
                                       struct mwifiex_bssdescriptor *bss_desc)
 {
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED
-           && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
-           && bss_desc->privacy) {
+       if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
+           !priv->sec_info.wpa2_enabled && bss_desc->privacy) {
                return true;
        }
        return false;
@@ -235,10 +232,9 @@ static bool
 mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
                                      struct mwifiex_bssdescriptor *bss_desc)
 {
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
-           && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
-           && ((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
-                                               element_id == WLAN_EID_WPA))
+       if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled &&
+           !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) &&
+           ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == WLAN_EID_WPA))
           /*
            * Privacy bit may NOT be set in some APs like
            * LinkSys WRT54G && bss_desc->privacy
@@ -253,8 +249,7 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
                        (bss_desc->bcn_rsn_ie) ?
                        (*(bss_desc->bcn_rsn_ie)).
                        ieee_hdr.element_id : 0,
-                       (priv->sec_info.wep_status ==
-                       MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
+                       (priv->sec_info.wep_enabled) ? "e" : "d",
                        (priv->sec_info.wpa_enabled) ? "e" : "d",
                        (priv->sec_info.wpa2_enabled) ? "e" : "d",
                        priv->sec_info.encryption_mode,
@@ -272,10 +267,9 @@ static bool
 mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
                                       struct mwifiex_bssdescriptor *bss_desc)
 {
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
-          && !priv->sec_info.wpa_enabled && priv->sec_info.wpa2_enabled
-          && ((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
-                                               element_id == WLAN_EID_RSN))
+       if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
+           priv->sec_info.wpa2_enabled && ((bss_desc->bcn_rsn_ie) &&
+           ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))
           /*
            * Privacy bit may NOT be set in some APs like
            * LinkSys WRT54G && bss_desc->privacy
@@ -290,8 +284,7 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
                        (bss_desc->bcn_rsn_ie) ?
                        (*(bss_desc->bcn_rsn_ie)).
                        ieee_hdr.element_id : 0,
-                       (priv->sec_info.wep_status ==
-                       MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
+                       (priv->sec_info.wep_enabled) ? "e" : "d",
                        (priv->sec_info.wpa_enabled) ? "e" : "d",
                        (priv->sec_info.wpa2_enabled) ? "e" : "d",
                        priv->sec_info.encryption_mode,
@@ -309,10 +302,9 @@ static bool
 mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv,
                                       struct mwifiex_bssdescriptor *bss_desc)
 {
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
-           && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
-           && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
-                  element_id != WLAN_EID_WPA))
+       if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
+           !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
+           ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA))
            && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
                   element_id != WLAN_EID_RSN))
            && !priv->sec_info.encryption_mode
@@ -330,10 +322,9 @@ static bool
 mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
                                       struct mwifiex_bssdescriptor *bss_desc)
 {
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
-           && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
-           && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
-                  element_id != WLAN_EID_WPA))
+       if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
+           !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
+           ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA))
            && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
                   element_id != WLAN_EID_RSN))
            && priv->sec_info.encryption_mode
@@ -468,8 +459,7 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
                       (bss_desc->bcn_rsn_ie) ?
                       (*(bss_desc->bcn_rsn_ie)).ieee_hdr.
                       element_id : 0,
-                      (priv->sec_info.wep_status ==
-                               MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
+                      (priv->sec_info.wep_enabled) ? "e" : "d",
                       (priv->sec_info.wpa_enabled) ? "e" : "d",
                       (priv->sec_info.wpa2_enabled) ? "e" : "d",
                       priv->sec_info.encryption_mode, bss_desc->privacy);
@@ -747,7 +737,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
        u16 scan_dur;
        u8 channel;
        u8 radio_type;
-       u32 ssid_idx;
+       int i;
        u8 ssid_filter;
        u8 rates[MWIFIEX_SUPPORTED_RATES];
        u32 rates_size;
@@ -802,14 +792,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                       user_scan_in->specific_bssid,
                       sizeof(scan_cfg_out->specific_bssid));
 
-               for (ssid_idx = 0;
-                    ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list))
-                     && (*user_scan_in->ssid_list[ssid_idx].ssid
-                         || user_scan_in->ssid_list[ssid_idx].max_len));
-                    ssid_idx++) {
-
-                       ssid_len = strlen(user_scan_in->ssid_list[ssid_idx].
-                                         ssid) + 1;
+               for (i = 0; i < user_scan_in->num_ssids; i++) {
+                       ssid_len = user_scan_in->ssid_list[i].ssid_len;
 
                        wildcard_ssid_tlv =
                                (struct mwifiex_ie_types_wildcard_ssid_params *)
@@ -820,19 +804,26 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                                (u16) (ssid_len + sizeof(wildcard_ssid_tlv->
                                                         max_ssid_length)));
 
-                       /* max_ssid_length = 0 tells firmware to perform
-                          specific scan for the SSID filled */
-                       wildcard_ssid_tlv->max_ssid_length = 0;
+                       /*
+                        * max_ssid_length = 0 tells firmware to perform
+                        * specific scan for the SSID filled, whereas
+                        * max_ssid_length = IEEE80211_MAX_SSID_LEN is for
+                        * wildcard scan.
+                        */
+                       if (ssid_len)
+                               wildcard_ssid_tlv->max_ssid_length = 0;
+                       else
+                               wildcard_ssid_tlv->max_ssid_length =
+                                                       IEEE80211_MAX_SSID_LEN;
 
                        memcpy(wildcard_ssid_tlv->ssid,
-                              user_scan_in->ssid_list[ssid_idx].ssid,
-                              ssid_len);
+                              user_scan_in->ssid_list[i].ssid, ssid_len);
 
                        tlv_pos += (sizeof(wildcard_ssid_tlv->header)
                                + le16_to_cpu(wildcard_ssid_tlv->header.len));
 
-                       dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n",
-                               ssid_idx, wildcard_ssid_tlv->ssid,
+                       dev_dbg(adapter->dev, "info: scan: ssid[%d]: %s, %d\n",
+                               i, wildcard_ssid_tlv->ssid,
                                wildcard_ssid_tlv->max_ssid_length);
 
                        /* Empty wildcard ssid with a maxlen will match many or
@@ -841,7 +832,6 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                           filtered. */
                        if (!ssid_len && wildcard_ssid_tlv->max_ssid_length)
                                ssid_filter = false;
-
                }
 
                /*
@@ -850,7 +840,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                 *  truncate scan results.  That is not an issue with an SSID
                 *  or BSSID filter applied to the scan results in the firmware.
                 */
-               if ((ssid_idx && ssid_filter)
+               if ((i && ssid_filter)
                    || memcmp(scan_cfg_out->specific_bssid, &zero_mac,
                              sizeof(zero_mac)))
                        *filtered_scan = true;
@@ -1860,7 +1850,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
  * firmware, filtered on a specific SSID.
  */
 static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
-                                     struct mwifiex_802_11_ssid *req_ssid)
+                                     struct cfg80211_ssid *req_ssid)
 {
        struct mwifiex_adapter *adapter = priv->adapter;
        int ret = 0;
@@ -1886,8 +1876,8 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
                return -ENOMEM;
        }
 
-       memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid,
-              req_ssid->ssid_len);
+       scan_cfg->ssid_list = req_ssid;
+       scan_cfg->num_ssids = 1;
 
        ret = mwifiex_scan_networks(priv, scan_cfg);
 
@@ -1905,7 +1895,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
  * scan, depending upon whether an SSID is provided or not.
  */
 int mwifiex_request_scan(struct mwifiex_private *priv,
-                        struct mwifiex_802_11_ssid *req_ssid)
+                        struct cfg80211_ssid *req_ssid)
 {
        int ret;
 
@@ -2001,7 +1991,7 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
 
                kfree(priv->curr_bcn_buf);
                priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
-                                               GFP_KERNEL);
+                                               GFP_ATOMIC);
                if (!priv->curr_bcn_buf) {
                        dev_err(priv->adapter->dev,
                                        "failed to alloc curr_bcn_buf\n");
index 6e443ffa0465c7ecb93a0ab8165f90fe6127bd0f..324c651527cb6c43d5d73b8bcb607103a0abcfe9 100644 (file)
@@ -103,7 +103,7 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv,
 static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
                                       struct host_cmd_ds_command *cmd,
                                       u16 cmd_action, u32 cmd_oid,
-                                      u32 *ul_temp)
+                                      u16 *ul_temp)
 {
        struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib;
 
@@ -112,62 +112,18 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
        cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
                - 1 + S_DS_GEN);
 
+       snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
        if (cmd_action == HostCmd_ACT_GEN_GET) {
                snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET);
                snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE);
-               cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
-                       + MAX_SNMP_BUF_SIZE);
+               le16_add_cpu(&cmd->size, MAX_SNMP_BUF_SIZE);
+       } else if (cmd_action == HostCmd_ACT_GEN_SET) {
+               snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
+               snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
+               *((__le16 *) (snmp_mib->value)) = cpu_to_le16(*ul_temp);
+               le16_add_cpu(&cmd->size, sizeof(u16));
        }
 
-       switch (cmd_oid) {
-       case FRAG_THRESH_I:
-               snmp_mib->oid = cpu_to_le16((u16) FRAG_THRESH_I);
-               if (cmd_action == HostCmd_ACT_GEN_SET) {
-                       snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
-                       snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
-                       *((__le16 *) (snmp_mib->value)) =
-                               cpu_to_le16((u16) *ul_temp);
-                       cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
-                               + sizeof(u16));
-               }
-               break;
-       case RTS_THRESH_I:
-               snmp_mib->oid = cpu_to_le16((u16) RTS_THRESH_I);
-               if (cmd_action == HostCmd_ACT_GEN_SET) {
-                       snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
-                       snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
-                       *(__le16 *) (snmp_mib->value) =
-                               cpu_to_le16((u16) *ul_temp);
-                       cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
-                               + sizeof(u16));
-               }
-               break;
-
-       case SHORT_RETRY_LIM_I:
-               snmp_mib->oid = cpu_to_le16((u16) SHORT_RETRY_LIM_I);
-               if (cmd_action == HostCmd_ACT_GEN_SET) {
-                       snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
-                       snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
-                       *((__le16 *) (snmp_mib->value)) =
-                               cpu_to_le16((u16) *ul_temp);
-                       cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
-                               + sizeof(u16));
-               }
-               break;
-       case DOT11D_I:
-               snmp_mib->oid = cpu_to_le16((u16) DOT11D_I);
-               if (cmd_action == HostCmd_ACT_GEN_SET) {
-                       snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
-                       snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
-                       *((__le16 *) (snmp_mib->value)) =
-                               cpu_to_le16((u16) *ul_temp);
-                       cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
-                               + sizeof(u16));
-               }
-               break;
-       default:
-               break;
-       }
        dev_dbg(priv->adapter->dev,
                "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x,"
                " Value=0x%x\n",
index e812db8b695cabdfa294c19d9ab08e92b4cb88b7..0d8618a8443fb8bf007b8db85be3367ffde57aa6 100644 (file)
@@ -210,6 +210,9 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
                        dev_dbg(priv->adapter->dev,
                                "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp);
                        break;
+               case DTIM_PERIOD_I:
+                       dev_dbg(priv->adapter->dev,
+                               "info: SNMP_RESP: DTIM period=%u\n", ul_temp);
                default:
                        break;
                }
index d7aa21da84d0124fd78a181da4bd7d711094c6eb..b9b59db60454b900087086dc34789adf95cbf0d6 100644 (file)
@@ -101,7 +101,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
 
        memcpy(&priv->prev_ssid,
               &priv->curr_bss_params.bss_descriptor.ssid,
-              sizeof(struct mwifiex_802_11_ssid));
+              sizeof(struct cfg80211_ssid));
 
        memcpy(priv->prev_bssid,
               priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN);
index b0fbf5d4fea0bd6fbc9b8b340339f1db145059ee..0ae1209646c14859e76cc311f3cfdff585b501d8 100644 (file)
@@ -192,7 +192,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
  * first.
  */
 int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
-                     struct mwifiex_802_11_ssid *req_ssid)
+                     struct cfg80211_ssid *req_ssid)
 {
        int ret;
        struct mwifiex_adapter *adapter = priv->adapter;
@@ -249,6 +249,17 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                 * application retrieval */
                priv->assoc_rsp_size = 0;
                ret = mwifiex_associate(priv, bss_desc);
+
+               /* If auth type is auto and association fails using open mode,
+                * try to connect using shared mode */
+               if (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
+                   priv->sec_info.is_authtype_auto &&
+                   priv->sec_info.wep_enabled) {
+                       priv->sec_info.authentication_mode =
+                                               NL80211_AUTHTYPE_SHARED_KEY;
+                       ret = mwifiex_associate(priv, bss_desc);
+               }
+
                if (bss)
                        cfg80211_put_bss(bss);
        } else {
@@ -453,8 +464,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
 
        info->bss_mode = priv->bss_mode;
 
-       memcpy(&info->ssid, &bss_desc->ssid,
-              sizeof(struct mwifiex_802_11_ssid));
+       memcpy(&info->ssid, &bss_desc->ssid, sizeof(struct cfg80211_ssid));
 
        memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN);
 
@@ -471,7 +481,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
 
        info->bcn_nf_last = priv->bcn_nf_last;
 
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
+       if (priv->sec_info.wep_enabled)
                info->wep_status = true;
        else
                info->wep_status = false;
@@ -599,7 +609,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
  *          - Start/Join the IBSS
  */
 int
-mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
+mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel)
 {
        int ret;
        struct mwifiex_bss_info bss_info;
@@ -636,7 +646,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
        ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid);
 
        ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET,
-                                            (u16 *) &channel);
+                                            &channel);
 
        /* Do specific SSID scanning */
        if (mwifiex_request_scan(priv, &bss_info.ssid)) {
@@ -1020,7 +1030,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
        wep_key = &priv->wep_key[priv->wep_key_curr_index];
        index = encrypt_key->key_index;
        if (encrypt_key->key_disable) {
-               priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED;
+               priv->sec_info.wep_enabled = 0;
        } else if (!encrypt_key->key_len) {
                /* Copy the required key as the current key */
                wep_key = &priv->wep_key[index];
@@ -1030,7 +1040,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
                        return -1;
                }
                priv->wep_key_curr_index = (u16) index;
-               priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED;
+               priv->sec_info.wep_enabled = 1;
        } else {
                wep_key = &priv->wep_key[index];
                memset(wep_key, 0, sizeof(struct mwifiex_wep_key));
@@ -1040,7 +1050,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
                       encrypt_key->key_len);
                wep_key->key_index = index;
                wep_key->key_length = encrypt_key->key_len;
-               priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED;
+               priv->sec_info.wep_enabled = 1;
        }
        if (wep_key->key_length) {
                /* Send request to firmware */
@@ -1050,7 +1060,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
                if (ret)
                        return ret;
        }
-       if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
+       if (priv->sec_info.wep_enabled)
                priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
        else
                priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
index 5e1ef7e5da4f3f5b2679c47d012588e642be093f..d7a5d7616f227cfa14f181062c625c2b2ed15381 100644 (file)
@@ -43,7 +43,8 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
 {
        int ret;
        struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
-       struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
+       struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter,
+                       rx_info->bss_num, rx_info->bss_type);
        struct rx_packet_hdr *rx_pkt_hdr;
        struct rxpd *local_rx_pd;
        int hdr_chop;
@@ -124,7 +125,8 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
        struct rx_packet_hdr *rx_pkt_hdr;
        u8 ta[ETH_ALEN];
        u16 rx_pkt_type;
-       struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
+       struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter,
+                       rx_info->bss_num, rx_info->bss_type);
 
        if (!priv)
                return -1;
index d97facd70e88b48c45c6f0602f7bfb259d0c1a7c..94d31a94620a75cc4e1ead5384b4ed87ae7d567c 100644 (file)
@@ -136,7 +136,8 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
                return -1;
 
        tx_info = MWIFIEX_SKB_TXCB(skb);
-       tx_info->bss_index = priv->bss_index;
+       tx_info->bss_num = priv->bss_num;
+       tx_info->bss_type = priv->bss_type;
        skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN);
        skb_push(skb, sizeof(struct txpd));
 
index d9274a1b77acabce253e6400af854d71c29b814b..9a6eacc9d6f9fee4b1f1374a2e006cf532523b15 100644 (file)
@@ -48,7 +48,8 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
        if (!priv)
                priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
 
-       rx_info->bss_index = priv->bss_index;
+       rx_info->bss_num = priv->bss_num;
+       rx_info->bss_type = priv->bss_type;
 
        return mwifiex_process_sta_rx_packet(adapter, skb);
 }
@@ -130,7 +131,8 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
                return 0;
 
        tx_info = MWIFIEX_SKB_TXCB(skb);
-       priv = mwifiex_bss_index_to_priv(adapter, tx_info->bss_index);
+       priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
+                       tx_info->bss_type);
        if (!priv)
                goto done;
 
index 06976f517f6603998a43e419988aa50b79378d48..9c48f37069f70b17096c75c2382e49aecc8f40e0 100644 (file)
@@ -159,7 +159,8 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
                return -1;
 
        rx_info = MWIFIEX_SKB_RXCB(skb);
-       priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index);
+       priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num,
+                       rx_info->bss_type);
        if (!priv)
                return -1;
 
index 6c239c3c8249c31395d337213b5a1c0e3176e4ab..75f79ef9f6cfed068497e384a36384224985bb83 100644 (file)
@@ -599,11 +599,10 @@ mwifiex_is_ralist_valid(struct mwifiex_private *priv,
  * is queued at the list tail.
  */
 void
-mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
+mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
                            struct sk_buff *skb)
 {
-       struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
-       struct mwifiex_private *priv = adapter->priv[tx_info->bss_index];
+       struct mwifiex_adapter *adapter = priv->adapter;
        u32 tid;
        struct mwifiex_ra_list_tbl *ra_list;
        u8 ra[ETH_ALEN], tid_down;
index fcea1f68792f8c06e053352a69a17164194d0987..ec839952d2e77bc01bf57bb63be53086913821f0 100644 (file)
@@ -80,8 +80,8 @@ mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead)
        return true;
 }
 
-void mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
-                                struct sk_buff *skb);
+void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
+                                       struct sk_buff *skb);
 void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra);
 
 int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter);
index dd5aeaff44ba3483804df003bd5779cbf0138794..ac7c983f1638e2f2f431a6339ff2080e793d11e8 100644 (file)
@@ -402,6 +402,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
 #define MWL8K_CMD_SET_MAC_ADDR         0x0202          /* per-vif */
 #define MWL8K_CMD_SET_RATEADAPT_MODE   0x0203
 #define MWL8K_CMD_GET_WATCHDOG_BITMAP  0x0205
+#define MWL8K_CMD_DEL_MAC_ADDR         0x0206          /* per-vif */
 #define MWL8K_CMD_BSS_START            0x1100          /* per-vif */
 #define MWL8K_CMD_SET_NEW_STN          0x1111          /* per-vif */
 #define MWL8K_CMD_UPDATE_ENCRYPTION    0x1122          /* per-vif */
@@ -3430,10 +3431,7 @@ static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable)
        return rc;
 }
 
-/*
- * CMD_SET_MAC_ADDR.
- */
-struct mwl8k_cmd_set_mac_addr {
+struct mwl8k_cmd_update_mac_addr {
        struct mwl8k_cmd_pkt header;
        union {
                struct {
@@ -3449,12 +3447,12 @@ struct mwl8k_cmd_set_mac_addr {
 #define MWL8K_MAC_TYPE_PRIMARY_AP              2
 #define MWL8K_MAC_TYPE_SECONDARY_AP            3
 
-static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
-                                 struct ieee80211_vif *vif, u8 *mac)
+static int mwl8k_cmd_update_mac_addr(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif, u8 *mac, bool set)
 {
        struct mwl8k_priv *priv = hw->priv;
        struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
-       struct mwl8k_cmd_set_mac_addr *cmd;
+       struct mwl8k_cmd_update_mac_addr *cmd;
        int mac_type;
        int rc;
 
@@ -3475,7 +3473,11 @@ static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
        if (cmd == NULL)
                return -ENOMEM;
 
-       cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
+       if (set)
+               cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
+       else
+               cmd->header.code = cpu_to_le16(MWL8K_CMD_DEL_MAC_ADDR);
+
        cmd->header.length = cpu_to_le16(sizeof(*cmd));
        if (priv->ap_fw) {
                cmd->mbss.mac_type = cpu_to_le16(mac_type);
@@ -3490,6 +3492,24 @@ static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
        return rc;
 }
 
+/*
+ * MWL8K_CMD_SET_MAC_ADDR.
+ */
+static inline int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif, u8 *mac)
+{
+       return mwl8k_cmd_update_mac_addr(hw, vif, mac, true);
+}
+
+/*
+ * MWL8K_CMD_DEL_MAC_ADDR.
+ */
+static inline int mwl8k_cmd_del_mac_addr(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif, u8 *mac)
+{
+       return mwl8k_cmd_update_mac_addr(hw, vif, mac, false);
+}
+
 /*
  * CMD_SET_RATEADAPT_MODE.
  */
@@ -4093,7 +4113,7 @@ static int mwl8k_set_key(struct ieee80211_hw *hw,
                return -EOPNOTSUPP;
 
        if (sta == NULL)
-               addr = hw->wiphy->perm_addr;
+               addr = vif->addr;
        else
                addr = sta->addr;
 
@@ -4542,7 +4562,7 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw,
        if (priv->ap_fw)
                mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr);
 
-       mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00");
+       mwl8k_cmd_del_mac_addr(hw, vif, vif->addr);
 
        mwl8k_remove_vif(priv, mwl8k_vif);
 }
index ae8ce56670b6734cec89ee5688263dcf2ba39db9..f634d4582bfe9d1d18890870ac74e499dc315a1b 100644 (file)
@@ -1754,11 +1754,6 @@ static struct usb_driver orinoco_driver = {
        .id_table = ezusb_table,
 };
 
-/* Can't be declared "const" or the whole __initdata section will
- * become const */
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-       " (Manuel Estrada Sainz)";
-
 module_usb_driver(orinoco_driver);
 
 MODULE_AUTHOR("Manuel Estrada Sainz");
index af2ca1a9c7d32ed014f11d1390e5c1d8bcf09fb6..ee8af1f047c8834f3f5cf5be4952616b6f44e5f9 100644 (file)
@@ -227,6 +227,9 @@ static int p54_add_interface(struct ieee80211_hw *dev,
                             struct ieee80211_vif *vif)
 {
        struct p54_common *priv = dev->priv;
+       int err;
+
+       vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
 
        mutex_lock(&priv->conf_mutex);
        if (priv->mode != NL80211_IFTYPE_MONITOR) {
@@ -249,9 +252,9 @@ static int p54_add_interface(struct ieee80211_hw *dev,
        }
 
        memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
-       p54_setup_mac(priv);
+       err = p54_setup_mac(priv);
        mutex_unlock(&priv->conf_mutex);
-       return 0;
+       return err;
 }
 
 static void p54_remove_interface(struct ieee80211_hw *dev,
@@ -734,7 +737,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
                     IEEE80211_HW_SIGNAL_DBM |
                     IEEE80211_HW_SUPPORTS_PS |
                     IEEE80211_HW_PS_NULLFUNC_STACK |
-                    IEEE80211_HW_BEACON_FILTER |
                     IEEE80211_HW_REPORTS_TX_ACK_STATUS;
 
        dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
index b1f51a215792028783223984dec8f0b0ac1a8f17..45df728183fdec6b4bd12017a154103d7069821f 100644 (file)
@@ -624,36 +624,39 @@ static void __devexit p54p_remove(struct pci_dev *pdev)
 }
 
 #ifdef CONFIG_PM
-static int p54p_suspend(struct pci_dev *pdev, pm_message_t state)
+static int p54p_suspend(struct device *device)
 {
-       struct ieee80211_hw *dev = pci_get_drvdata(pdev);
-       struct p54p_priv *priv = dev->priv;
-
-       if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) {
-               ieee80211_stop_queues(dev);
-               p54p_stop(dev);
-       }
+       struct pci_dev *pdev = to_pci_dev(device);
 
        pci_save_state(pdev);
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+       pci_set_power_state(pdev, PCI_D3hot);
+       pci_disable_device(pdev);
        return 0;
 }
 
-static int p54p_resume(struct pci_dev *pdev)
+static int p54p_resume(struct device *device)
 {
-       struct ieee80211_hw *dev = pci_get_drvdata(pdev);
-       struct p54p_priv *priv = dev->priv;
+       struct pci_dev *pdev = to_pci_dev(device);
+       int err;
 
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
+       err = pci_reenable_device(pdev);
+       if (err)
+               return err;
+       return pci_set_power_state(pdev, PCI_D0);
+}
 
-       if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) {
-               p54p_open(dev);
-               ieee80211_wake_queues(dev);
-       }
+static const struct dev_pm_ops p54pci_pm_ops = {
+       .suspend = p54p_suspend,
+       .resume = p54p_resume,
+       .freeze = p54p_suspend,
+       .thaw = p54p_resume,
+       .poweroff = p54p_suspend,
+       .restore = p54p_resume,
+};
 
-       return 0;
-}
+#define P54P_PM_OPS (&p54pci_pm_ops)
+#else
+#define P54P_PM_OPS (NULL)
 #endif /* CONFIG_PM */
 
 static struct pci_driver p54p_driver = {
@@ -661,10 +664,7 @@ static struct pci_driver p54p_driver = {
        .id_table       = p54p_table,
        .probe          = p54p_probe,
        .remove         = __devexit_p(p54p_remove),
-#ifdef CONFIG_PM
-       .suspend        = p54p_suspend,
-       .resume         = p54p_resume,
-#endif /* CONFIG_PM */
+       .driver.pm      = P54P_PM_OPS,
 };
 
 static int __init p54p_init(void)
index 7faed62c63786a629c64cfbd423dc228227e8768..f7929906d4371bd59ccdc0ad14ca6a9d5dff7a39 100644 (file)
@@ -618,19 +618,19 @@ static int __devinit p54spi_probe(struct spi_device *spi)
        ret = spi_setup(spi);
        if (ret < 0) {
                dev_err(&priv->spi->dev, "spi_setup failed");
-               goto err_free_common;
+               goto err_free;
        }
 
        ret = gpio_request(p54spi_gpio_power, "p54spi power");
        if (ret < 0) {
                dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret);
-               goto err_free_common;
+               goto err_free;
        }
 
        ret = gpio_request(p54spi_gpio_irq, "p54spi irq");
        if (ret < 0) {
                dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret);
-               goto err_free_common;
+               goto err_free_gpio_power;
        }
 
        gpio_direction_output(p54spi_gpio_power, 0);
@@ -641,7 +641,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)
                          priv->spi);
        if (ret < 0) {
                dev_err(&priv->spi->dev, "request_irq() failed");
-               goto err_free_common;
+               goto err_free_gpio_irq;
        }
 
        irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
@@ -673,6 +673,12 @@ static int __devinit p54spi_probe(struct spi_device *spi)
        return 0;
 
 err_free_common:
+       free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
+err_free_gpio_irq:
+       gpio_free(p54spi_gpio_irq);
+err_free_gpio_power:
+       gpio_free(p54spi_gpio_power);
+err_free:
        p54_free_common(priv->hw);
        return ret;
 }
index 42b97bc3847717fa017d923fd840c6c12261bd8a..a08a6f0e4dd118064606754e3fbd3be369d7bee5 100644 (file)
@@ -690,7 +690,7 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
        if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
                *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
 
-       if (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)
+       if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
                *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
 
        if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
index a330c69583d62a07dc935ebef2c617b4ee135496..d66e2980bc27bab54ddd06867a8fccd50f6cfb0c 100644 (file)
@@ -518,7 +518,7 @@ struct rndis_wlan_private {
        __le32 current_command_oid;
 
        /* encryption stuff */
-       int  encr_tx_key_index;
+       u8 encr_tx_key_index;
        struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS];
        int  wpa_version;
 
@@ -634,7 +634,7 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv)
        }
 }
 
-static bool is_wpa_key(struct rndis_wlan_private *priv, int idx)
+static bool is_wpa_key(struct rndis_wlan_private *priv, u8 idx)
 {
        int cipher = priv->encr_keys[idx].cipher;
 
@@ -1350,7 +1350,7 @@ static int set_channel(struct usbnet *usbdev, int channel)
 }
 
 static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev,
-                                                    u16 *beacon_interval)
+                                                    u32 *beacon_period)
 {
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ieee80211_channel *channel;
@@ -1370,14 +1370,14 @@ static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev,
        if (!channel)
                return NULL;
 
-       if (beacon_interval)
-               *beacon_interval = le16_to_cpu(config.beacon_period);
+       if (beacon_period)
+               *beacon_period = le32_to_cpu(config.beacon_period);
        return channel;
 }
 
 /* index must be 0 - N, as per NDIS  */
 static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
-                                                               int index)
+                                                               u8 index)
 {
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_wep_key ndis_key;
@@ -1387,13 +1387,15 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
        netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n",
                   __func__, index, key_len);
 
-       if ((key_len != 5 && key_len != 13) || index < 0 || index > 3)
+       if (index >= RNDIS_WLAN_NUM_KEYS)
                return -EINVAL;
 
        if (key_len == 5)
                cipher = WLAN_CIPHER_SUITE_WEP40;
-       else
+       else if (key_len == 13)
                cipher = WLAN_CIPHER_SUITE_WEP104;
+       else
+               return -EINVAL;
 
        memset(&ndis_key, 0, sizeof(ndis_key));
 
@@ -1428,7 +1430,7 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
 }
 
 static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
-                       int index, const u8 *addr, const u8 *rx_seq,
+                       u8 index, const u8 *addr, const u8 *rx_seq,
                        int seq_len, u32 cipher, __le32 flags)
 {
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1436,7 +1438,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
        bool is_addr_ok;
        int ret;
 
-       if (index < 0 || index >= 4) {
+       if (index >= RNDIS_WLAN_NUM_KEYS) {
                netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n",
                           __func__, index);
                return -EINVAL;
@@ -1524,7 +1526,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
        return 0;
 }
 
-static int restore_key(struct usbnet *usbdev, int key_idx)
+static int restore_key(struct usbnet *usbdev, u8 key_idx)
 {
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct rndis_wlan_encr_key key;
@@ -1550,13 +1552,13 @@ static void restore_keys(struct usbnet *usbdev)
                restore_key(usbdev, i);
 }
 
-static void clear_key(struct rndis_wlan_private *priv, int idx)
+static void clear_key(struct rndis_wlan_private *priv, u8 idx)
 {
        memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx]));
 }
 
 /* remove_key is for both wep and wpa */
-static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid)
+static int remove_key(struct usbnet *usbdev, u8 index, const u8 *bssid)
 {
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_remove_key remove_key;
@@ -1790,9 +1792,9 @@ static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev,
                                                struct cfg80211_pmksa *pmksa,
                                                int max_pmkids)
 {
-       int i, len, count, newlen, err;
+       int i, newlen, err;
+       unsigned int count;
 
-       len = le32_to_cpu(pmkids->length);
        count = le32_to_cpu(pmkids->bssid_info_count);
 
        if (count > max_pmkids)
@@ -1831,9 +1833,9 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev,
                                                struct cfg80211_pmksa *pmksa,
                                                int max_pmkids)
 {
-       int i, err, len, count, newlen;
+       int i, err, newlen;
+       unsigned int count;
 
-       len = le32_to_cpu(pmkids->length);
        count = le32_to_cpu(pmkids->bssid_info_count);
 
        if (count > max_pmkids)
@@ -2683,7 +2685,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
        s32 signal;
        u64 timestamp;
        u16 capability;
-       u16 beacon_interval = 0;
+       u32 beacon_period = 0;
        __le32 rssi;
        u8 ie_buf[34];
        int len, ret, ie_len;
@@ -2708,7 +2710,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
        }
 
        /* Get channel and beacon interval */
-       channel = get_current_channel(usbdev, &beacon_interval);
+       channel = get_current_channel(usbdev, &beacon_period);
        if (!channel) {
                netdev_warn(usbdev->net, "%s(): could not get channel.\n",
                                        __func__);
@@ -2738,11 +2740,11 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
        netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, "
                "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), "
                "signal:%d\n", __func__, (channel ? channel->center_freq : -1),
-               bssid, (u32)timestamp, capability, beacon_interval, ie_len,
+               bssid, (u32)timestamp, capability, beacon_period, ie_len,
                ssid.essid, signal);
 
        bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid,
-               timestamp, capability, beacon_interval, ie_buf, ie_len,
+               timestamp, capability, beacon_period, ie_buf, ie_len,
                signal, GFP_KERNEL);
        cfg80211_put_bss(bss);
 }
@@ -2755,9 +2757,10 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_assoc_info *info = NULL;
        u8 bssid[ETH_ALEN];
-       int resp_ie_len, req_ie_len;
+       unsigned int resp_ie_len, req_ie_len;
+       unsigned int offset;
        u8 *req_ie, *resp_ie;
-       int ret, offset;
+       int ret;
        bool roamed = false;
        bool match_bss;
 
@@ -2785,7 +2788,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
                ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE);
                if (!ret) {
                        req_ie_len = le32_to_cpu(info->req_ie_length);
-                       if (req_ie_len > 0) {
+                       if (req_ie_len > CONTROL_BUFFER_SIZE)
+                               req_ie_len = CONTROL_BUFFER_SIZE;
+                       if (req_ie_len != 0) {
                                offset = le32_to_cpu(info->offset_req_ies);
 
                                if (offset > CONTROL_BUFFER_SIZE)
@@ -2799,7 +2804,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
                        }
 
                        resp_ie_len = le32_to_cpu(info->resp_ie_length);
-                       if (resp_ie_len > 0) {
+                       if (resp_ie_len > CONTROL_BUFFER_SIZE)
+                               resp_ie_len = CONTROL_BUFFER_SIZE;
+                       if (resp_ie_len != 0) {
                                offset = le32_to_cpu(info->offset_resp_ies);
 
                                if (offset > CONTROL_BUFFER_SIZE)
@@ -3038,7 +3045,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev,
                        struct rndis_indicate *msg, int buflen)
 {
        struct ndis_80211_status_indication *indication;
-       int len, offset;
+       unsigned int len, offset;
 
        offset = offsetof(struct rndis_indicate, status) +
                        le32_to_cpu(msg->offset);
@@ -3050,7 +3057,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev,
                return;
        }
 
-       if (offset + len > buflen) {
+       if (len > buflen || offset > buflen || offset + len > buflen) {
                netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n",
                            offset + len, buflen);
                return;
index a0a7854facc08e17a40f04f5eccd0a09a3c68c63..299c3879582da14e12ca00d7f11184da8c61bed7 100644 (file)
@@ -163,7 +163,7 @@ config RT2800USB_RT53XX
        depends on EXPERIMENTAL
        ---help---
          This adds support for rt53xx wireless chipset family to the
-         rt2800pci driver.
+         rt2800usb driver.
          Supported chips: RT5370
 
 config RT2800USB_UNKNOWN
index 2571a2fa3d09c67a87dc6a685f4b9114533d7a39..e5c05d8c74486bf14ca435b0a4634e4ba5ecd050 100644 (file)
@@ -68,6 +68,7 @@
 #define RF3322                         0x000c
 #define RF3053                         0x000d
 #define RF5370                         0x5370
+#define RF5372                         0x5372
 #define RF5390                         0x5390
 
 /*
  * TX_PIN_CFG:
  */
 #define TX_PIN_CFG                     0x1328
+#define TX_PIN_CFG_PA_PE_DISABLE       0xfcfffff0
 #define TX_PIN_CFG_PA_PE_A0_EN         FIELD32(0x00000001)
 #define TX_PIN_CFG_PA_PE_G0_EN         FIELD32(0x00000002)
 #define TX_PIN_CFG_PA_PE_A1_EN         FIELD32(0x00000004)
 #define TX_PIN_CFG_RFTR_POL            FIELD32(0x00020000)
 #define TX_PIN_CFG_TRSW_EN             FIELD32(0x00040000)
 #define TX_PIN_CFG_TRSW_POL            FIELD32(0x00080000)
+#define TX_PIN_CFG_PA_PE_A2_EN         FIELD32(0x01000000)
+#define TX_PIN_CFG_PA_PE_G2_EN         FIELD32(0x02000000)
+#define TX_PIN_CFG_PA_PE_A2_POL                FIELD32(0x04000000)
+#define TX_PIN_CFG_PA_PE_G2_POL                FIELD32(0x08000000)
+#define TX_PIN_CFG_LNA_PE_A2_EN                FIELD32(0x10000000)
+#define TX_PIN_CFG_LNA_PE_G2_EN                FIELD32(0x20000000)
+#define TX_PIN_CFG_LNA_PE_A2_POL       FIELD32(0x40000000)
+#define TX_PIN_CFG_LNA_PE_G2_POL       FIELD32(0x80000000)
 
 /*
  * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz
@@ -1627,6 +1637,7 @@ struct mac_iveiv_entry {
 
 /*
  * H2M_MAILBOX_CSR: Host-to-MCU Mailbox.
+ * CMD_TOKEN: Command id, 0xff disable status reporting.
  */
 #define H2M_MAILBOX_CSR                        0x7010
 #define H2M_MAILBOX_CSR_ARG0           FIELD32(0x000000ff)
@@ -1636,6 +1647,8 @@ struct mac_iveiv_entry {
 
 /*
  * H2M_MAILBOX_CID:
+ * Free slots contain 0xff. MCU will store command's token to lowest free slot.
+ * If all slots are occupied status will be dropped.
  */
 #define H2M_MAILBOX_CID                        0x7014
 #define H2M_MAILBOX_CID_CMD0           FIELD32(0x000000ff)
@@ -1645,6 +1658,7 @@ struct mac_iveiv_entry {
 
 /*
  * H2M_MAILBOX_STATUS:
+ * Command status will be saved to same slot as command id.
  */
 #define H2M_MAILBOX_STATUS             0x701c
 
@@ -1795,6 +1809,14 @@ struct mac_iveiv_entry {
  */
 #define RFCSR2_RESCAL_EN               FIELD8(0x80)
 
+/*
+ * RFCSR 3:
+ */
+#define RFCSR3_K                       FIELD8(0x0f)
+/* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */
+#define RFCSR3_PA1_BIAS_CCK            FIELD8(0x70);
+#define RFCSR3_PA2_CASCODE_BIAS_CCKK   FIELD8(0x80);
+
 /*
  * FRCSR 5:
  */
@@ -1811,10 +1833,12 @@ struct mac_iveiv_entry {
  * RFCSR 7:
  */
 #define RFCSR7_RF_TUNING               FIELD8(0x01)
-#define RFCSR7_R02                             FIELD8(0x07)
-#define RFCSR7_R3                              FIELD8(0x08)
-#define RFCSR7_R45                             FIELD8(0x30)
-#define RFCSR7_R67                             FIELD8(0xc0)
+#define RFCSR7_BIT1                    FIELD8(0x02)
+#define RFCSR7_BIT2                    FIELD8(0x04)
+#define RFCSR7_BIT3                    FIELD8(0x08)
+#define RFCSR7_BIT4                    FIELD8(0x10)
+#define RFCSR7_BIT5                    FIELD8(0x20)
+#define RFCSR7_BITS67                  FIELD8(0xc0)
 
 /*
  * RFCSR 11:
@@ -1838,6 +1862,11 @@ struct mac_iveiv_entry {
  */
 #define RFCSR15_TX_LO2_EN              FIELD8(0x08)
 
+/*
+ * RFCSR 16:
+ */
+#define RFCSR16_TXMIXER_GAIN           FIELD8(0x07)
+
 /*
  * RFCSR 17:
  */
@@ -1866,6 +1895,13 @@ struct mac_iveiv_entry {
  */
 #define RFCSR23_FREQ_OFFSET            FIELD8(0x7f)
 
+/*
+ * RFCSR 24:
+ */
+#define RFCSR24_TX_AGC_FC              FIELD8(0x1f)
+#define RFCSR24_TX_H20M                        FIELD8(0x20)
+#define RFCSR24_TX_CALIB               FIELD8(0x7f)
+
 /*
  * RFCSR 27:
  */
@@ -1887,6 +1923,7 @@ struct mac_iveiv_entry {
  */
 #define RFCSR31_RX_AGC_FC              FIELD8(0x1f)
 #define RFCSR31_RX_H20M                        FIELD8(0x20)
+#define RFCSR31_RX_CALIB               FIELD8(0x7f)
 
 /*
  * RFCSR 38:
@@ -2092,6 +2129,12 @@ struct mac_iveiv_entry {
 #define EEPROM_RSSI_A2_OFFSET2         FIELD16(0x00ff)
 #define EEPROM_RSSI_A2_LNA_A2          FIELD16(0xff00)
 
+/*
+ * EEPROM TXMIXER GAIN A offset (note overlaps with EEPROM RSSI A2).
+ */
+#define EEPROM_TXMIXER_GAIN_A          0x0026
+#define EEPROM_TXMIXER_GAIN_A_VAL      FIELD16(0x0007)
+
 /*
  * EEPROM EIRP Maximum TX power values(unit: dbm)
  */
@@ -2259,6 +2302,12 @@ struct mac_iveiv_entry {
 
 /*
  * MCU mailbox commands.
+ * MCU_SLEEP - go to power-save mode.
+ *             arg1: 1: save as much power as possible, 0: save less power.
+ *             status: 1: success, 2: already asleep,
+ *                     3: maybe MAC is busy so can't finish this task.
+ * MCU_RADIO_OFF
+ *             arg0: 0: do power-saving, NOT turn off radio.
  */
 #define MCU_SLEEP                      0x30
 #define MCU_WAKEUP                     0x31
@@ -2279,7 +2328,10 @@ struct mac_iveiv_entry {
 /*
  * MCU mailbox tokens
  */
-#define TOKEN_WAKUP                    3
+#define TOKEN_SLEEP                    1
+#define TOKEN_RADIO_OFF                        2
+#define TOKEN_WAKEUP                   3
+
 
 /*
  * DMA descriptor defines.
@@ -2422,4 +2474,16 @@ struct mac_iveiv_entry {
  */
 #define EIRP_MAX_TX_POWER_LIMIT        0x50
 
+/*
+ * RT2800 driver data structure
+ */
+struct rt2800_drv_data {
+       u8 calibration_bw20;
+       u8 calibration_bw40;
+       u8 bbp25;
+       u8 bbp26;
+       u8 txmixer_gain_24g;
+       u8 txmixer_gain_5g;
+};
+
 #endif /* RT2800_H */
index 7bef66def10c469166f6689adefbfe1d477bf034..474b5b9e6238a151cac006257153eae1c0a80d9e 100644 (file)
@@ -402,7 +402,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
 
        if (rt2x00_is_pci(rt2x00dev)) {
                if (rt2x00_rt(rt2x00dev, RT3572) ||
-                   rt2x00_rt(rt2x00dev, RT5390)) {
+                   rt2x00_rt(rt2x00dev, RT5390) ||
+                   rt2x00_rt(rt2x00dev, RT5392)) {
                        rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
                        rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
                        rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
@@ -411,18 +412,6 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
                rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002);
        }
 
-       /*
-        * Disable DMA, will be reenabled later when enabling
-        * the radio.
-        */
-       rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
-       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
-       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
-       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
-       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
-       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
-       rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
        /*
         * Write firmware to the device.
         */
@@ -443,11 +432,22 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
                return -EBUSY;
        }
 
+       /*
+        * Disable DMA, will be reenabled later when enabling
+        * the radio.
+        */
+       rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+       rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
        /*
         * Initialize firmware.
         */
        rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
        rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+       if (rt2x00_is_usb(rt2x00dev))
+               rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
        msleep(1);
 
        return 0;
@@ -1646,10 +1646,14 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
                                         struct rf_channel *rf,
                                         struct channel_info *info)
 {
-       u8 rfcsr;
+       struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+       u8 rfcsr, calib_tx, calib_rx;
 
        rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1);
-       rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3);
+
+       rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR3_K, rf->rf3);
+       rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
 
        rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
        rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2);
@@ -1663,16 +1667,82 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2);
        rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
 
+       rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
+       rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
+       if (rt2x00_rt(rt2x00dev, RT3390)) {
+               rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD,
+                                 rt2x00dev->default_ant.rx_chain_num == 1);
+               rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD,
+                                 rt2x00dev->default_ant.tx_chain_num == 1);
+       } else {
+               rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
+               rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+               rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
+               rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
+
+               switch (rt2x00dev->default_ant.tx_chain_num) {
+               case 1:
+                       rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
+                       /* fall through */
+               case 2:
+                       rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+                       break;
+               }
+
+               switch (rt2x00dev->default_ant.rx_chain_num) {
+               case 1:
+                       rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
+                       /* fall through */
+               case 2:
+                       rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+                       break;
+               }
+       }
+       rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+       rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+       rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+       msleep(1);
+       rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
+       rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+
        rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
        rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
        rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
 
-       rt2800_rfcsr_write(rt2x00dev, 24,
-                             rt2x00dev->calibration[conf_is_ht40(conf)]);
+       if (rt2x00_rt(rt2x00dev, RT3390)) {
+               calib_tx = conf_is_ht40(conf) ? 0x68 : 0x4f;
+               calib_rx = conf_is_ht40(conf) ? 0x6f : 0x4f;
+       } else {
+               if (conf_is_ht40(conf)) {
+                       calib_tx = drv_data->calibration_bw40;
+                       calib_rx = drv_data->calibration_bw40;
+               } else {
+                       calib_tx = drv_data->calibration_bw20;
+                       calib_rx = drv_data->calibration_bw20;
+               }
+       }
+
+       rt2800_rfcsr_read(rt2x00dev, 24, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR24_TX_CALIB, calib_tx);
+       rt2800_rfcsr_write(rt2x00dev, 24, rfcsr);
+
+       rt2800_rfcsr_read(rt2x00dev, 31, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR31_RX_CALIB, calib_rx);
+       rt2800_rfcsr_write(rt2x00dev, 31, rfcsr);
 
        rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
        rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
        rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+
+       rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+       rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+       msleep(1);
+       rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
+       rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
 }
 
 static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
@@ -1680,12 +1750,13 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
                                         struct rf_channel *rf,
                                         struct channel_info *info)
 {
+       struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
        u8 rfcsr;
        u32 reg;
 
        if (rf->channel <= 14) {
-               rt2800_bbp_write(rt2x00dev, 25, 0x15);
-               rt2800_bbp_write(rt2x00dev, 26, 0x85);
+               rt2800_bbp_write(rt2x00dev, 25, drv_data->bbp25);
+               rt2800_bbp_write(rt2x00dev, 26, drv_data->bbp26);
        } else {
                rt2800_bbp_write(rt2x00dev, 25, 0x09);
                rt2800_bbp_write(rt2x00dev, 26, 0xff);
@@ -1713,8 +1784,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
        if (rf->channel <= 14) {
                rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3);
                rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
-                               (info->default_power1 & 0x3) |
-                               ((info->default_power1 & 0xC) << 1));
+                                 info->default_power1);
        } else {
                rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7);
                rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
@@ -1727,8 +1797,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
        if (rf->channel <= 14) {
                rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3);
                rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
-                               (info->default_power2 & 0x3) |
-                               ((info->default_power2 & 0xC) << 1));
+                                 info->default_power2);
        } else {
                rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7);
                rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
@@ -1738,11 +1807,12 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
        rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
 
        rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
-       rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
        rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
        rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
        rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
        rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+       rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
+       rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
        if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
                if (rf->channel <= 14) {
                        rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
@@ -1773,10 +1843,13 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
        rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
 
-       rt2800_rfcsr_write(rt2x00dev, 24,
-                             rt2x00dev->calibration[conf_is_ht40(conf)]);
-       rt2800_rfcsr_write(rt2x00dev, 31,
-                             rt2x00dev->calibration[conf_is_ht40(conf)]);
+       if (conf_is_ht40(conf)) {
+               rt2800_rfcsr_write(rt2x00dev, 24, drv_data->calibration_bw40);
+               rt2800_rfcsr_write(rt2x00dev, 31, drv_data->calibration_bw40);
+       } else {
+               rt2800_rfcsr_write(rt2x00dev, 24, drv_data->calibration_bw20);
+               rt2800_rfcsr_write(rt2x00dev, 31, drv_data->calibration_bw20);
+       }
 
        if (rf->channel <= 14) {
                rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
@@ -1784,7 +1857,10 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
                rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
                rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
                rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
-               rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
+               rfcsr = 0x4c;
+               rt2x00_set_field8(&rfcsr, RFCSR16_TXMIXER_GAIN,
+                                 drv_data->txmixer_gain_24g);
+               rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
                rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
                rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
                rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
@@ -1793,12 +1869,20 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
                rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
                rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
        } else {
-               rt2800_rfcsr_write(rt2x00dev, 7, 0x14);
+               rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR7_BIT2, 1);
+               rt2x00_set_field8(&rfcsr, RFCSR7_BIT3, 0);
+               rt2x00_set_field8(&rfcsr, RFCSR7_BIT4, 1);
+               rt2x00_set_field8(&rfcsr, RFCSR7_BITS67, 0);
+               rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
                rt2800_rfcsr_write(rt2x00dev, 9, 0xc0);
                rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
                rt2800_rfcsr_write(rt2x00dev, 11, 0x00);
                rt2800_rfcsr_write(rt2x00dev, 15, 0x43);
-               rt2800_rfcsr_write(rt2x00dev, 16, 0x7a);
+               rfcsr = 0x7a;
+               rt2x00_set_field8(&rfcsr, RFCSR16_TXMIXER_GAIN,
+                                 drv_data->txmixer_gain_5g);
+               rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
                rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
                if (rf->channel <= 64) {
                        rt2800_rfcsr_write(rt2x00dev, 19, 0xb7);
@@ -1906,7 +1990,8 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
                                                   r55_nonbt_rev[idx]);
                                rt2800_rfcsr_write(rt2x00dev, 59,
                                                   r59_nonbt_rev[idx]);
-                       } else if (rt2x00_rt(rt2x00dev, RT5390)) {
+                       } else if (rt2x00_rt(rt2x00dev, RT5390) ||
+                                          rt2x00_rt(rt2x00dev, RT5392)) {
                                static const char r59_non_bt[] = {0x8f, 0x8f,
                                        0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d,
                                        0x8a, 0x88, 0x88, 0x87, 0x87, 0x86};
@@ -1956,6 +2041,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
                rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
                break;
        case RF5370:
+       case RF5372:
        case RF5390:
                rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info);
                break;
@@ -1972,7 +2058,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        rt2800_bbp_write(rt2x00dev, 86, 0);
 
        if (rf->channel <= 14) {
-               if (!rt2x00_rt(rt2x00dev, RT5390)) {
+               if (!rt2x00_rt(rt2x00dev, RT5390) &&
+                       !rt2x00_rt(rt2x00dev, RT5392)) {
                        if (test_bit(CAPABILITY_EXTERNAL_LNA_BG,
                                     &rt2x00dev->cap_flags)) {
                                rt2800_bbp_write(rt2x00dev, 82, 0x62);
@@ -2414,6 +2501,80 @@ void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
 }
 EXPORT_SYMBOL_GPL(rt2800_gain_calibration);
 
+void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
+{
+       u32     tx_pin;
+       u8      rfcsr;
+
+       /*
+        * A voltage-controlled oscillator(VCO) is an electronic oscillator
+        * designed to be controlled in oscillation frequency by a voltage
+        * input. Maybe the temperature will affect the frequency of
+        * oscillation to be shifted. The VCO calibration will be called
+        * periodically to adjust the frequency to be precision.
+       */
+
+       rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin);
+       tx_pin &= TX_PIN_CFG_PA_PE_DISABLE;
+       rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+
+       switch (rt2x00dev->chip.rf) {
+       case RF2020:
+       case RF3020:
+       case RF3021:
+       case RF3022:
+       case RF3320:
+       case RF3052:
+               rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
+               rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+               break;
+       case RF5370:
+       case RF5372:
+       case RF5390:
+               rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+               rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
+               break;
+       default:
+               return;
+       }
+
+       mdelay(1);
+
+       rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin);
+       if (rt2x00dev->rf_channel <= 14) {
+               switch (rt2x00dev->default_ant.tx_chain_num) {
+               case 3:
+                       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G2_EN, 1);
+                       /* fall through */
+               case 2:
+                       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
+                       /* fall through */
+               case 1:
+               default:
+                       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
+                       break;
+               }
+       } else {
+               switch (rt2x00dev->default_ant.tx_chain_num) {
+               case 3:
+                       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A2_EN, 1);
+                       /* fall through */
+               case 2:
+                       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
+                       /* fall through */
+               case 1:
+               default:
+                       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, 1);
+                       break;
+               }
+       }
+       rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+
+}
+EXPORT_SYMBOL_GPL(rt2800_vco_calibration);
+
 static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
                                      struct rt2x00lib_conf *libconf)
 {
@@ -2502,7 +2663,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
                    rt2x00_rt(rt2x00dev, RT3071) ||
                    rt2x00_rt(rt2x00dev, RT3090) ||
                    rt2x00_rt(rt2x00dev, RT3390) ||
-                   rt2x00_rt(rt2x00dev, RT5390))
+                   rt2x00_rt(rt2x00dev, RT5390) ||
+                   rt2x00_rt(rt2x00dev, RT5392))
                        return 0x1c + (2 * rt2x00dev->lna_gain);
                else
                        return 0x2e + rt2x00dev->lna_gain;
@@ -2637,7 +2799,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        } else if (rt2x00_rt(rt2x00dev, RT3572)) {
                rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
                rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
-       } else if (rt2x00_rt(rt2x00dev, RT5390)) {
+       } else if (rt2x00_rt(rt2x00dev, RT5390) ||
+                          rt2x00_rt(rt2x00dev, RT5392)) {
                rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
                rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
                rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
@@ -3013,7 +3176,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
                     rt2800_wait_bbp_ready(rt2x00dev)))
                return -EACCES;
 
-       if (rt2x00_rt(rt2x00dev, RT5390)) {
+       if (rt2x00_rt(rt2x00dev, RT5390) ||
+               rt2x00_rt(rt2x00dev, RT5392)) {
                rt2800_bbp_read(rt2x00dev, 4, &value);
                rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1);
                rt2800_bbp_write(rt2x00dev, 4, value);
@@ -3021,19 +3185,22 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
 
        if (rt2800_is_305x_soc(rt2x00dev) ||
            rt2x00_rt(rt2x00dev, RT3572) ||
-           rt2x00_rt(rt2x00dev, RT5390))
+           rt2x00_rt(rt2x00dev, RT5390) ||
+           rt2x00_rt(rt2x00dev, RT5392))
                rt2800_bbp_write(rt2x00dev, 31, 0x08);
 
        rt2800_bbp_write(rt2x00dev, 65, 0x2c);
        rt2800_bbp_write(rt2x00dev, 66, 0x38);
 
-       if (rt2x00_rt(rt2x00dev, RT5390))
+       if (rt2x00_rt(rt2x00dev, RT5390) ||
+               rt2x00_rt(rt2x00dev, RT5392))
                rt2800_bbp_write(rt2x00dev, 68, 0x0b);
 
        if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
                rt2800_bbp_write(rt2x00dev, 69, 0x16);
                rt2800_bbp_write(rt2x00dev, 73, 0x12);
-       } else if (rt2x00_rt(rt2x00dev, RT5390)) {
+       } else if (rt2x00_rt(rt2x00dev, RT5390) ||
+                          rt2x00_rt(rt2x00dev, RT5392)) {
                rt2800_bbp_write(rt2x00dev, 69, 0x12);
                rt2800_bbp_write(rt2x00dev, 73, 0x13);
                rt2800_bbp_write(rt2x00dev, 75, 0x46);
@@ -3051,7 +3218,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
            rt2x00_rt(rt2x00dev, RT3090) ||
            rt2x00_rt(rt2x00dev, RT3390) ||
            rt2x00_rt(rt2x00dev, RT3572) ||
-           rt2x00_rt(rt2x00dev, RT5390)) {
+           rt2x00_rt(rt2x00dev, RT5390) ||
+           rt2x00_rt(rt2x00dev, RT5392)) {
                rt2800_bbp_write(rt2x00dev, 79, 0x13);
                rt2800_bbp_write(rt2x00dev, 80, 0x05);
                rt2800_bbp_write(rt2x00dev, 81, 0x33);
@@ -3063,64 +3231,88 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
        }
 
        rt2800_bbp_write(rt2x00dev, 82, 0x62);
-       if (rt2x00_rt(rt2x00dev, RT5390))
+       if (rt2x00_rt(rt2x00dev, RT5390) ||
+               rt2x00_rt(rt2x00dev, RT5392))
                rt2800_bbp_write(rt2x00dev, 83, 0x7a);
        else
                rt2800_bbp_write(rt2x00dev, 83, 0x6a);
 
        if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
                rt2800_bbp_write(rt2x00dev, 84, 0x19);
-       else if (rt2x00_rt(rt2x00dev, RT5390))
+       else if (rt2x00_rt(rt2x00dev, RT5390) ||
+                        rt2x00_rt(rt2x00dev, RT5392))
                rt2800_bbp_write(rt2x00dev, 84, 0x9a);
        else
                rt2800_bbp_write(rt2x00dev, 84, 0x99);
 
-       if (rt2x00_rt(rt2x00dev, RT5390))
+       if (rt2x00_rt(rt2x00dev, RT5390) ||
+               rt2x00_rt(rt2x00dev, RT5392))
                rt2800_bbp_write(rt2x00dev, 86, 0x38);
        else
                rt2800_bbp_write(rt2x00dev, 86, 0x00);
 
+       if (rt2x00_rt(rt2x00dev, RT5392))
+               rt2800_bbp_write(rt2x00dev, 88, 0x90);
+
        rt2800_bbp_write(rt2x00dev, 91, 0x04);
 
-       if (rt2x00_rt(rt2x00dev, RT5390))
+       if (rt2x00_rt(rt2x00dev, RT5390) ||
+               rt2x00_rt(rt2x00dev, RT5392))
                rt2800_bbp_write(rt2x00dev, 92, 0x02);
        else
                rt2800_bbp_write(rt2x00dev, 92, 0x00);
 
+       if (rt2x00_rt(rt2x00dev, RT5392)) {
+               rt2800_bbp_write(rt2x00dev, 95, 0x9a);
+               rt2800_bbp_write(rt2x00dev, 98, 0x12);
+       }
+
        if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
            rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
            rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
            rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
            rt2x00_rt(rt2x00dev, RT3572) ||
            rt2x00_rt(rt2x00dev, RT5390) ||
+           rt2x00_rt(rt2x00dev, RT5392) ||
            rt2800_is_305x_soc(rt2x00dev))
                rt2800_bbp_write(rt2x00dev, 103, 0xc0);
        else
                rt2800_bbp_write(rt2x00dev, 103, 0x00);
 
-       if (rt2x00_rt(rt2x00dev, RT5390))
+       if (rt2x00_rt(rt2x00dev, RT5390) ||
+               rt2x00_rt(rt2x00dev, RT5392))
                rt2800_bbp_write(rt2x00dev, 104, 0x92);
 
        if (rt2800_is_305x_soc(rt2x00dev))
                rt2800_bbp_write(rt2x00dev, 105, 0x01);
-       else if (rt2x00_rt(rt2x00dev, RT5390))
+       else if (rt2x00_rt(rt2x00dev, RT5390) ||
+                        rt2x00_rt(rt2x00dev, RT5392))
                rt2800_bbp_write(rt2x00dev, 105, 0x3c);
        else
                rt2800_bbp_write(rt2x00dev, 105, 0x05);
 
        if (rt2x00_rt(rt2x00dev, RT5390))
                rt2800_bbp_write(rt2x00dev, 106, 0x03);
+       else if (rt2x00_rt(rt2x00dev, RT5392))
+               rt2800_bbp_write(rt2x00dev, 106, 0x12);
        else
                rt2800_bbp_write(rt2x00dev, 106, 0x35);
 
-       if (rt2x00_rt(rt2x00dev, RT5390))
+       if (rt2x00_rt(rt2x00dev, RT5390) ||
+               rt2x00_rt(rt2x00dev, RT5392))
                rt2800_bbp_write(rt2x00dev, 128, 0x12);
 
+       if (rt2x00_rt(rt2x00dev, RT5392)) {
+               rt2800_bbp_write(rt2x00dev, 134, 0xd0);
+               rt2800_bbp_write(rt2x00dev, 135, 0xf6);
+       }
+
        if (rt2x00_rt(rt2x00dev, RT3071) ||
            rt2x00_rt(rt2x00dev, RT3090) ||
            rt2x00_rt(rt2x00dev, RT3390) ||
            rt2x00_rt(rt2x00dev, RT3572) ||
-           rt2x00_rt(rt2x00dev, RT5390)) {
+           rt2x00_rt(rt2x00dev, RT5390) ||
+           rt2x00_rt(rt2x00dev, RT5392)) {
                rt2800_bbp_read(rt2x00dev, 138, &value);
 
                rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
@@ -3132,7 +3324,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
                rt2800_bbp_write(rt2x00dev, 138, value);
        }
 
-       if (rt2x00_rt(rt2x00dev, RT5390)) {
+       if (rt2x00_rt(rt2x00dev, RT5390) ||
+               rt2x00_rt(rt2x00dev, RT5392)) {
                int ant, div_mode;
 
                rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
@@ -3247,6 +3440,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev,
 
 static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 {
+       struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
        u8 rfcsr;
        u8 bbp;
        u32 reg;
@@ -3258,13 +3452,15 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
            !rt2x00_rt(rt2x00dev, RT3390) &&
            !rt2x00_rt(rt2x00dev, RT3572) &&
            !rt2x00_rt(rt2x00dev, RT5390) &&
+           !rt2x00_rt(rt2x00dev, RT5392) &&
            !rt2800_is_305x_soc(rt2x00dev))
                return 0;
 
        /*
         * Init RF calibration.
         */
-       if (rt2x00_rt(rt2x00dev, RT5390)) {
+       if (rt2x00_rt(rt2x00dev, RT5390) ||
+               rt2x00_rt(rt2x00dev, RT5392)) {
                rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
                rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
                rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
@@ -3482,6 +3678,66 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                        rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
                rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
                rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
+       }       else if (rt2x00_rt(rt2x00dev, RT5392)) {
+                       rt2800_rfcsr_write(rt2x00dev, 1, 0x17);
+                       rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
+                       rt2800_rfcsr_write(rt2x00dev, 3, 0x88);
+                       rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
+                       rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
+                       rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
+                       rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
+                       rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
+                       rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
+                       rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
+                       rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
+                       rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
+                       rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
+                       rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
+                       rt2800_rfcsr_write(rt2x00dev, 19, 0x4d);
+                       rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
+                       rt2800_rfcsr_write(rt2x00dev, 21, 0x8d);
+                       rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
+                       rt2800_rfcsr_write(rt2x00dev, 23, 0x0b);
+                       rt2800_rfcsr_write(rt2x00dev, 24, 0x44);
+                       rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
+                       rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
+                       rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
+                       rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
+                       rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
+                       rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
+                       rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
+                       rt2800_rfcsr_write(rt2x00dev, 32, 0x20);
+                       rt2800_rfcsr_write(rt2x00dev, 33, 0xC0);
+                       rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
+                       rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
+                       rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
+                       rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
+                       rt2800_rfcsr_write(rt2x00dev, 38, 0x89);
+                       rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
+                       rt2800_rfcsr_write(rt2x00dev, 40, 0x0f);
+                       rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
+                       rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
+                       rt2800_rfcsr_write(rt2x00dev, 43, 0x9b);
+                       rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
+                       rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
+                       rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
+                       rt2800_rfcsr_write(rt2x00dev, 47, 0x0c);
+                       rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
+                       rt2800_rfcsr_write(rt2x00dev, 49, 0x94);
+                       rt2800_rfcsr_write(rt2x00dev, 50, 0x94);
+                       rt2800_rfcsr_write(rt2x00dev, 51, 0x3a);
+                       rt2800_rfcsr_write(rt2x00dev, 52, 0x48);
+                       rt2800_rfcsr_write(rt2x00dev, 53, 0x44);
+                       rt2800_rfcsr_write(rt2x00dev, 54, 0x38);
+                       rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
+                       rt2800_rfcsr_write(rt2x00dev, 56, 0xa1);
+                       rt2800_rfcsr_write(rt2x00dev, 57, 0x00);
+                       rt2800_rfcsr_write(rt2x00dev, 58, 0x39);
+                       rt2800_rfcsr_write(rt2x00dev, 59, 0x07);
+                       rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
+                       rt2800_rfcsr_write(rt2x00dev, 61, 0x91);
+                       rt2800_rfcsr_write(rt2x00dev, 62, 0x39);
+                       rt2800_rfcsr_write(rt2x00dev, 63, 0x07);
        }
 
        if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
@@ -3535,21 +3791,28 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
         * Set RX Filter calibration for 20MHz and 40MHz
         */
        if (rt2x00_rt(rt2x00dev, RT3070)) {
-               rt2x00dev->calibration[0] =
+               drv_data->calibration_bw20 =
                        rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
-               rt2x00dev->calibration[1] =
+               drv_data->calibration_bw40 =
                        rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
        } else if (rt2x00_rt(rt2x00dev, RT3071) ||
                   rt2x00_rt(rt2x00dev, RT3090) ||
                   rt2x00_rt(rt2x00dev, RT3390) ||
                   rt2x00_rt(rt2x00dev, RT3572)) {
-               rt2x00dev->calibration[0] =
+               drv_data->calibration_bw20 =
                        rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
-               rt2x00dev->calibration[1] =
+               drv_data->calibration_bw40 =
                        rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15);
        }
 
-       if (!rt2x00_rt(rt2x00dev, RT5390)) {
+       /*
+        * Save BBP 25 & 26 values for later use in channel switching
+        */
+       rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25);
+       rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26);
+
+       if (!rt2x00_rt(rt2x00dev, RT5390) &&
+               !rt2x00_rt(rt2x00dev, RT5392)) {
                /*
                 * Set back to initial state
                 */
@@ -3577,7 +3840,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, OPT_14_CSR_BIT0, 1);
        rt2800_register_write(rt2x00dev, OPT_14_CSR, reg);
 
-       if (!rt2x00_rt(rt2x00dev, RT5390)) {
+       if (!rt2x00_rt(rt2x00dev, RT5390) &&
+               !rt2x00_rt(rt2x00dev, RT5392)) {
                rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
                rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
                if (rt2x00_rt(rt2x00dev, RT3070) ||
@@ -3588,11 +3852,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                                      &rt2x00dev->cap_flags))
                                rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
                }
-               rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
-               if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1)
-                       rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
-                                       rt2x00_get_field16(eeprom,
-                                               EEPROM_TXMIXER_GAIN_BG_VAL));
+               rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
+                                 drv_data->txmixer_gain_24g);
                rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
        }
 
@@ -3645,7 +3906,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                rt2800_rfcsr_write(rt2x00dev, 27, rfcsr);
        }
 
-       if (rt2x00_rt(rt2x00dev, RT5390)) {
+       if (rt2x00_rt(rt2x00dev, RT5390) ||
+               rt2x00_rt(rt2x00dev, RT5392)) {
                rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
                rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0);
                rt2800_rfcsr_write(rt2x00dev, 38, rfcsr);
@@ -3800,6 +4062,7 @@ EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse);
 
 int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 {
+       struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
        u16 word;
        u8 *mac;
        u8 default_lna_gain;
@@ -3883,6 +4146,14 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
                rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
        rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
 
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
+       if ((word & 0x00ff) != 0x00ff) {
+               drv_data->txmixer_gain_24g =
+                       rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
+       } else {
+               drv_data->txmixer_gain_24g = 0;
+       }
+
        rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
        if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
                rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
@@ -3892,6 +4163,14 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
                                   default_lna_gain);
        rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
 
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
+       if ((word & 0x00ff) != 0x00ff) {
+               drv_data->txmixer_gain_5g =
+                       rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
+       } else {
+               drv_data->txmixer_gain_5g = 0;
+       }
+
        rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
        if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
                rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
@@ -3929,7 +4208,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
         * RT53xx: defined in "EEPROM_CHIP_ID" field
         */
        rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
-       if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390)
+       if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 ||
+               rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392)
                rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value);
        else
                value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
@@ -3947,9 +4227,10 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
        case RT3390:
        case RT3572:
        case RT5390:
+       case RT5392:
                break;
        default:
-               ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
+               ERROR(rt2x00dev, "Invalid RT chipset 0x%04x detected.\n", rt2x00dev->chip.rt);
                return -ENODEV;
        }
 
@@ -3965,10 +4246,11 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
        case RF3052:
        case RF3320:
        case RF5370:
+       case RF5372:
        case RF5390:
                break;
        default:
-               ERROR(rt2x00dev, "Invalid RF chipset 0x%x detected.\n",
+               ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n",
                      rt2x00dev->chip.rf);
                return -ENODEV;
        }
@@ -4271,6 +4553,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                   rt2x00_rf(rt2x00dev, RF3022) ||
                   rt2x00_rf(rt2x00dev, RF3320) ||
                   rt2x00_rf(rt2x00dev, RF5370) ||
+                  rt2x00_rf(rt2x00dev, RF5372) ||
                   rt2x00_rf(rt2x00dev, RF5390)) {
                spec->num_channels = 14;
                spec->channels = rf_vals_3x;
@@ -4347,6 +4630,20 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                }
        }
 
+       switch (rt2x00dev->chip.rf) {
+       case RF2020:
+       case RF3020:
+       case RF3021:
+       case RF3022:
+       case RF3320:
+       case RF3052:
+       case RF5370:
+       case RF5372:
+       case RF5390:
+               __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags);
+               break;
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(rt2800_probe_hw_mode);
index 8c3c281904fe7f4a08a4e9c16100920ea502e022..419e36cb06be3d393ec036ccc614414e4e3f2ddc 100644 (file)
@@ -184,6 +184,7 @@ void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual);
 void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
                       const u32 count);
 void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev);
+void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev);
 
 int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev);
 void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
index dc88baefa72e88bd2b2f60b3ea2e8f7174ff34ed..9375db455456f316145e824db4957b46373726b9 100644 (file)
@@ -480,7 +480,8 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
 
        if (rt2x00_is_pcie(rt2x00dev) &&
            (rt2x00_rt(rt2x00dev, RT3572) ||
-            rt2x00_rt(rt2x00dev, RT5390))) {
+            rt2x00_rt(rt2x00dev, RT5390) ||
+            rt2x00_rt(rt2x00dev, RT5392))) {
                rt2x00pci_register_read(rt2x00dev, AUX_CTRL, &reg);
                rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
                rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
@@ -489,7 +490,7 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
 
        rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
 
-       rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+       reg = 0;
        rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
        rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
        rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
@@ -501,11 +502,27 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
 
 static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 {
+       int retval;
+
        if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
                     rt2800pci_init_queues(rt2x00dev)))
                return -EIO;
 
-       return rt2800_enable_radio(rt2x00dev);
+       retval = rt2800_enable_radio(rt2x00dev);
+       if (retval)
+               return retval;
+
+       /* After resume MCU_BOOT_SIGNAL will trash these. */
+       rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+       rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+
+       rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02);
+       rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF);
+
+       rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKEUP, 0, 0);
+       rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP);
+
+       return retval;
 }
 
 static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
@@ -521,14 +538,16 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
                               enum dev_state state)
 {
        if (state == STATE_AWAKE) {
-               rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0x02);
-               rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP);
+               rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKEUP,
+                                  0, 0x02);
+               rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP);
        } else if (state == STATE_SLEEP) {
                rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS,
                                         0xffffffff);
                rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID,
                                         0xffffffff);
-               rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0x01, 0xff, 0x01);
+               rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP,
+                                  0xff, 0x01);
        }
 
        return 0;
@@ -541,13 +560,6 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 
        switch (state) {
        case STATE_RADIO_ON:
-               /*
-                * Before the radio can be enabled, the device first has
-                * to be woken up. After that it needs a bit of time
-                * to be fully awake and then the radio can be enabled.
-                */
-               rt2800pci_set_state(rt2x00dev, STATE_AWAKE);
-               msleep(1);
                retval = rt2800pci_enable_radio(rt2x00dev);
                break;
        case STATE_RADIO_OFF:
@@ -1050,6 +1062,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
        .reset_tuner            = rt2800_reset_tuner,
        .link_tuner             = rt2800_link_tuner,
        .gain_calibration       = rt2800_gain_calibration,
+       .vco_calibration        = rt2800_vco_calibration,
        .start_queue            = rt2800pci_start_queue,
        .kick_queue             = rt2800pci_kick_queue,
        .stop_queue             = rt2800pci_stop_queue,
@@ -1093,6 +1106,7 @@ static const struct data_queue_desc rt2800pci_queue_bcn = {
 
 static const struct rt2x00_ops rt2800pci_ops = {
        .name                   = KBUILD_MODNAME,
+       .drv_data_size          = sizeof(struct rt2800_drv_data),
        .max_sta_intf           = 1,
        .max_ap_intf            = 8,
        .eeprom_size            = EEPROM_SIZE,
index 262ee9eefb6f08dc7d8b404c3f1f143060951633..2c11137c1eb0dbf2bcfe8bf04dbc0cd5d68ad47d 100644 (file)
@@ -226,9 +226,7 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
        rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
 
-       rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
-
-       rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+       reg = 0;
        rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
        rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
        rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
@@ -783,6 +781,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
        .reset_tuner            = rt2800_reset_tuner,
        .link_tuner             = rt2800_link_tuner,
        .gain_calibration       = rt2800_gain_calibration,
+       .vco_calibration        = rt2800_vco_calibration,
        .watchdog               = rt2800usb_watchdog,
        .start_queue            = rt2800usb_start_queue,
        .kick_queue             = rt2x00usb_kick_queue,
@@ -829,6 +828,7 @@ static const struct data_queue_desc rt2800usb_queue_bcn = {
 
 static const struct rt2x00_ops rt2800usb_ops = {
        .name                   = KBUILD_MODNAME,
+       .drv_data_size          = sizeof(struct rt2800_drv_data),
        .max_sta_intf           = 1,
        .max_ap_intf            = 8,
        .eeprom_size            = EEPROM_SIZE,
@@ -922,6 +922,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x07d1, 0x3c13) },
        { USB_DEVICE(0x07d1, 0x3c15) },
        { USB_DEVICE(0x07d1, 0x3c16) },
+       { USB_DEVICE(0x2001, 0x3c1b) },
        /* Draytek */
        { USB_DEVICE(0x07fa, 0x7712) },
        /* DVICO */
@@ -1101,12 +1102,26 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x5a57, 0x0284) },
 #endif
 #ifdef CONFIG_RT2800USB_RT53XX
+       /* Alpha */
+       { USB_DEVICE(0x2001, 0x3c15) },
+       { USB_DEVICE(0x2001, 0x3c19) },
+       /* Arcadyan */
+       { USB_DEVICE(0x043e, 0x7a12) },
        /* Azurewave */
        { USB_DEVICE(0x13d3, 0x3329) },
        { USB_DEVICE(0x13d3, 0x3365) },
+       /* LG innotek */
+       { USB_DEVICE(0x043e, 0x7a22) },
+       /* Panasonic */
+       { USB_DEVICE(0x04da, 0x1801) },
+       { USB_DEVICE(0x04da, 0x1800) },
+       /* Philips */
+       { USB_DEVICE(0x0471, 0x2104) },
        /* Ralink */
        { USB_DEVICE(0x148f, 0x5370) },
        { USB_DEVICE(0x148f, 0x5372) },
+       /* Unknown */
+       { USB_DEVICE(0x04da, 0x23f6) },
 #endif
 #ifdef CONFIG_RT2800USB_UNKNOWN
        /*
index b03b22c47b187753269ed1a69cf1189af4e71dd6..65275efcf279f3c2cd05739fa839f45dfc392f89 100644 (file)
@@ -192,6 +192,7 @@ struct rt2x00_chip {
 #define RT3593         0x3593
 #define RT3883         0x3883  /* WSOC */
 #define RT5390         0x5390  /* 2.4GHz */
+#define RT5392         0x5392  /* 2.4GHz */
 
        u16 rf;
        u16 rev;
@@ -355,6 +356,11 @@ struct link {
         * Work structure for scheduling periodic AGC adjustments.
         */
        struct delayed_work agc_work;
+
+       /*
+        * Work structure for scheduling periodic VCO calibration.
+        */
+       struct delayed_work vco_work;
 };
 
 enum rt2x00_delayed_flags {
@@ -579,6 +585,7 @@ struct rt2x00lib_ops {
        void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
                            struct link_qual *qual, const u32 count);
        void (*gain_calibration) (struct rt2x00_dev *rt2x00dev);
+       void (*vco_calibration) (struct rt2x00_dev *rt2x00dev);
 
        /*
         * Data queue handlers.
@@ -647,6 +654,7 @@ struct rt2x00lib_ops {
  */
 struct rt2x00_ops {
        const char *name;
+       const unsigned int drv_data_size;
        const unsigned int max_sta_intf;
        const unsigned int max_ap_intf;
        const unsigned int eeprom_size;
@@ -721,6 +729,7 @@ enum rt2x00_capability_flags {
        CAPABILITY_EXTERNAL_LNA_BG,
        CAPABILITY_DOUBLE_ANTENNA,
        CAPABILITY_BT_COEXIST,
+       CAPABILITY_VCO_RECALIBRATION,
 };
 
 /*
@@ -741,6 +750,11 @@ struct rt2x00_dev {
         */
        const struct rt2x00_ops *ops;
 
+       /*
+        * Driver data.
+        */
+       void *drv_data;
+
        /*
         * IEEE80211 control structure.
         */
@@ -886,17 +900,10 @@ struct rt2x00_dev {
        u8 rssi_offset;
 
        /*
-        * Frequency offset (for rt61pci & rt73usb).
+        * Frequency offset.
         */
        u8 freq_offset;
 
-       /*
-        * Calibration information (for rt2800usb & rt2800pci).
-        * [0] -> BW20
-        * [1] -> BW40
-        */
-       u8 calibration[2];
-
        /*
         * Association id.
         */
@@ -978,6 +985,11 @@ struct rt2x00_dev {
        struct tasklet_struct rxdone_tasklet;
        struct tasklet_struct autowake_tasklet;
 
+       /*
+        * Used for VCO periodic calibration.
+        */
+       int rf_channel;
+
        /*
         * Protect the interrupt mask register.
         */
index b704e5b183d0bc539e8bec6d08776774854d5479..d7c0f86c9e435bfab86fc620c5ac6d49e5433784 100644 (file)
@@ -232,6 +232,9 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
                memcpy(&libconf.channel,
                       &rt2x00dev->spec.channels_info[hw_value],
                       sizeof(libconf.channel));
+
+               /* Used for VCO periodic calibration */
+               rt2x00dev->rf_channel = libconf.rf.channel;
        }
 
        if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
index c3e1aa7c1a8057b7eb19270f8aacb3f718b86577..49a51b4195ef7a4a652a428c75cab5d8e2887f26 100644 (file)
@@ -88,6 +88,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
        rt2x00queue_start_queues(rt2x00dev);
        rt2x00link_start_tuner(rt2x00dev);
        rt2x00link_start_agc(rt2x00dev);
+       if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags))
+               rt2x00link_start_vcocal(rt2x00dev);
 
        /*
         * Start watchdog monitoring.
@@ -111,6 +113,8 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
         * Stop all queues
         */
        rt2x00link_stop_agc(rt2x00dev);
+       if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags))
+               rt2x00link_stop_vcocal(rt2x00dev);
        rt2x00link_stop_tuner(rt2x00dev);
        rt2x00queue_stop_queues(rt2x00dev);
        rt2x00queue_flush_queues(rt2x00dev, true);
@@ -1121,6 +1125,18 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 {
        int retval = -ENOMEM;
 
+       /*
+        * Allocate the driver data memory, if necessary.
+        */
+       if (rt2x00dev->ops->drv_data_size > 0) {
+               rt2x00dev->drv_data = kzalloc(rt2x00dev->ops->drv_data_size,
+                                             GFP_KERNEL);
+               if (!rt2x00dev->drv_data) {
+                       retval = -ENOMEM;
+                       goto exit;
+               }
+       }
+
        spin_lock_init(&rt2x00dev->irqmask_lock);
        mutex_init(&rt2x00dev->csr_mutex);
 
@@ -1220,7 +1236,8 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
                cancel_work_sync(&rt2x00dev->rxdone_work);
                cancel_work_sync(&rt2x00dev->txdone_work);
        }
-       destroy_workqueue(rt2x00dev->workqueue);
+       if (rt2x00dev->workqueue)
+               destroy_workqueue(rt2x00dev->workqueue);
 
        /*
         * Free the tx status fifo.
@@ -1261,6 +1278,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
         * Free queue structures.
         */
        rt2x00queue_free(rt2x00dev);
+
+       /*
+        * Free the driver data.
+        */
+       if (rt2x00dev->drv_data)
+               kfree(rt2x00dev->drv_data);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
 
index 4cdf247a870d6e21dbc5557e1e1aad18fa4253c7..78bd43b8961f74f1df8c89178faa5457482f6714 100644 (file)
@@ -33,6 +33,7 @@
 #define WATCHDOG_INTERVAL      round_jiffies_relative(HZ)
 #define LINK_TUNE_INTERVAL     round_jiffies_relative(HZ)
 #define AGC_INTERVAL           round_jiffies_relative(4 * HZ)
+#define VCO_INTERVAL           round_jiffies_relative(10 * HZ) /* 10 sec */
 
 /*
  * rt2x00_rate: Per rate device information
@@ -277,12 +278,24 @@ void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev);
  */
 void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev);
 
+/**
+ * rt2x00link_start_vcocal - Start periodic VCO calibration
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ */
+void rt2x00link_start_vcocal(struct rt2x00_dev *rt2x00dev);
+
 /**
  * rt2x00link_stop_agc - Stop periodic gain calibration
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
  */
 void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev);
 
+/**
+ * rt2x00link_stop_vcocal - Stop periodic VCO calibration
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ */
+void rt2x00link_stop_vcocal(struct rt2x00_dev *rt2x00dev);
+
 /**
  * rt2x00link_register - Initialize link tuning & watchdog functionality
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
index ea10b0068f823f503e827f45d9e4c52dd9f8a74f..8368aab86f286ee6ff5be65b85a73940f3c24cd0 100644 (file)
@@ -447,11 +447,27 @@ void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev)
                                             AGC_INTERVAL);
 }
 
+void rt2x00link_start_vcocal(struct rt2x00_dev *rt2x00dev)
+{
+       struct link *link = &rt2x00dev->link;
+
+       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+           rt2x00dev->ops->lib->vco_calibration)
+               ieee80211_queue_delayed_work(rt2x00dev->hw,
+                                            &link->vco_work,
+                                            VCO_INTERVAL);
+}
+
 void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev)
 {
        cancel_delayed_work_sync(&rt2x00dev->link.agc_work);
 }
 
+void rt2x00link_stop_vcocal(struct rt2x00_dev *rt2x00dev)
+{
+       cancel_delayed_work_sync(&rt2x00dev->link.vco_work);
+}
+
 static void rt2x00link_agc(struct work_struct *work)
 {
        struct rt2x00_dev *rt2x00dev =
@@ -473,9 +489,32 @@ static void rt2x00link_agc(struct work_struct *work)
                                             AGC_INTERVAL);
 }
 
+static void rt2x00link_vcocal(struct work_struct *work)
+{
+       struct rt2x00_dev *rt2x00dev =
+           container_of(work, struct rt2x00_dev, link.vco_work.work);
+       struct link *link = &rt2x00dev->link;
+
+       /*
+        * When the radio is shutting down we should
+        * immediately cease the VCO calibration.
+        */
+       if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               return;
+
+       rt2x00dev->ops->lib->vco_calibration(rt2x00dev);
+
+       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               ieee80211_queue_delayed_work(rt2x00dev->hw,
+                                            &link->vco_work,
+                                            VCO_INTERVAL);
+}
+
 void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
 {
        INIT_DELAYED_WORK(&rt2x00dev->link.agc_work, rt2x00link_agc);
+       if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags))
+               INIT_DELAYED_WORK(&rt2x00dev->link.vco_work, rt2x00link_vcocal);
        INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog);
        INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner);
 }
index 638fbef693e676372e39c2f20d7a2e7127c1a083..cf53ac9d6f23f2787561883f15985a974abb7f8d 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
  *
  * The driver was extended to the RTL8187B in 2008 by:
- *     Herton Ronaldo Krzesinski <herton@mandriva.com.br>
+ *     Herton Ronaldo Krzesinski <herton@mandriva.com.br>
  *     Hin-Tak Leung <htl10@users.sourceforge.net>
  *     Larry Finger <Larry.Finger@lwfinger.net>
  *
@@ -232,6 +232,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct rtl8187_priv *priv = dev->priv;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *tx_hdr =  (struct ieee80211_hdr *)(skb->data);
        unsigned int ep;
        void *buf;
        struct urb *urb;
@@ -249,7 +250,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        flags |= RTL818X_TX_DESC_FLAG_NO_ENC;
 
        flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24;
-       if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control))
+       if (ieee80211_has_morefrags(tx_hdr->frame_control))
                flags |= RTL818X_TX_DESC_FLAG_MOREFRAG;
        if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                flags |= RTL818X_TX_DESC_FLAG_RTS;
@@ -261,6 +262,13 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
                flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
        }
 
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+                       priv->seqno += 0x10;
+               tx_hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+               tx_hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
+       }
+
        if (!priv->is_rtl8187b) {
                struct rtl8187_tx_hdr *hdr =
                        (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
@@ -274,8 +282,6 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        } else {
                /* fc needs to be calculated before skb_push() */
                unsigned int epmap[4] = { 6, 7, 5, 4 };
-               struct ieee80211_hdr *tx_hdr =
-                       (struct ieee80211_hdr *)(skb->data);
                u16 fc = le16_to_cpu(tx_hdr->frame_control);
 
                struct rtl8187b_tx_hdr *hdr =
@@ -1031,10 +1037,61 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
                cancel_delayed_work_sync(&priv->work);
 }
 
+static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif)
+{
+       struct rtl8187_priv *priv = dev->priv;
+
+       return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
+              (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
+}
+
+
+static void rtl8187_beacon_work(struct work_struct *work)
+{
+       struct rtl8187_vif *vif_priv =
+               container_of(work, struct rtl8187_vif, beacon_work.work);
+       struct ieee80211_vif *vif =
+               container_of((void *)vif_priv, struct ieee80211_vif, drv_priv);
+       struct ieee80211_hw *dev = vif_priv->dev;
+       struct ieee80211_mgmt *mgmt;
+       struct sk_buff *skb;
+
+       /* don't overflow the tx ring */
+       if (ieee80211_queue_stopped(dev, 0))
+               goto resched;
+
+       /* grab a fresh beacon */
+       skb = ieee80211_beacon_get(dev, vif);
+       if (!skb)
+               goto resched;
+
+       /*
+        * update beacon timestamp w/ TSF value
+        * TODO: make hardware update beacon timestamp
+        */
+       mgmt = (struct ieee80211_mgmt *)skb->data;
+       mgmt->u.beacon.timestamp = cpu_to_le64(rtl8187_get_tsf(dev, vif));
+
+       /* TODO: use actual beacon queue */
+       skb_set_queue_mapping(skb, 0);
+
+       rtl8187_tx(dev, skb);
+
+resched:
+       /*
+        * schedule next beacon
+        * TODO: use hardware support for beacon timing
+        */
+       schedule_delayed_work(&vif_priv->beacon_work,
+                       usecs_to_jiffies(1024 * vif->bss_conf.beacon_int));
+}
+
+
 static int rtl8187_add_interface(struct ieee80211_hw *dev,
                                 struct ieee80211_vif *vif)
 {
        struct rtl8187_priv *priv = dev->priv;
+       struct rtl8187_vif *vif_priv;
        int i;
        int ret = -EOPNOTSUPP;
 
@@ -1044,6 +1101,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
 
        switch (vif->type) {
        case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_ADHOC:
                break;
        default:
                goto exit;
@@ -1052,6 +1110,13 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
        ret = 0;
        priv->vif = vif;
 
+       /* Initialize driver private area */
+       vif_priv = (struct rtl8187_vif *)&vif->drv_priv;
+       vif_priv->dev = dev;
+       INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8187_beacon_work);
+       vif_priv->enable_beacon = false;
+
+
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
        for (i = 0; i < ETH_ALEN; i++)
                rtl818x_iowrite8(priv, &priv->map->MAC[i],
@@ -1175,9 +1240,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
                                     u32 changed)
 {
        struct rtl8187_priv *priv = dev->priv;
+       struct rtl8187_vif *vif_priv;
        int i;
        u8 reg;
 
+       vif_priv = (struct rtl8187_vif *)&vif->drv_priv;
+
        if (changed & BSS_CHANGED_BSSID) {
                mutex_lock(&priv->conf_mutex);
                for (i = 0; i < ETH_ALEN; i++)
@@ -1189,8 +1257,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
                else
                        reg = 0;
 
-               if (is_valid_ether_addr(info->bssid))
-                       reg |= RTL818X_MSR_INFRA;
+               if (is_valid_ether_addr(info->bssid)) {
+                       if (vif->type == NL80211_IFTYPE_ADHOC)
+                               reg |= RTL818X_MSR_ADHOC;
+                       else
+                               reg |= RTL818X_MSR_INFRA;
+               }
                else
                        reg |= RTL818X_MSR_NO_LINK;
 
@@ -1202,6 +1274,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
        if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE))
                rtl8187_conf_erp(priv, info->use_short_slot,
                                 info->use_short_preamble);
+
+       if (changed & BSS_CHANGED_BEACON_ENABLED)
+               vif_priv->enable_beacon = info->enable_beacon;
+
+       if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) {
+               cancel_delayed_work_sync(&vif_priv->beacon_work);
+               if (vif_priv->enable_beacon)
+                       schedule_work(&vif_priv->beacon_work.work);
+       }
+
 }
 
 static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev,
@@ -1279,13 +1361,6 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev,
        return 0;
 }
 
-static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif)
-{
-       struct rtl8187_priv *priv = dev->priv;
-
-       return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
-              (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
-}
 
 static const struct ieee80211_ops rtl8187_ops = {
        .tx                     = rtl8187_tx,
@@ -1514,12 +1589,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
                if (reg & 0xFF00)
                        priv->rfkill_mask = RFKILL_MASK_8198;
        }
-
-       /*
-        * XXX: Once this driver supports anything that requires
-        *      beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ.
-        */
-       dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+       dev->vif_data_size = sizeof(struct rtl8187_vif);
+       dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                     BIT(NL80211_IFTYPE_ADHOC) ;
 
        if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
                printk(KERN_INFO "rtl8187: inconsistency between id with OEM"
index f1cc90751dbf519a576f5baee035e94aa183e378..e19a20a8e9558f38549df067334ad1b8ce81b793 100644 (file)
@@ -89,6 +89,14 @@ enum {
        DEVICE_RTL8187B
 };
 
+struct rtl8187_vif {
+       struct ieee80211_hw *dev;
+
+       /* beaconing */
+       struct delayed_work beacon_work;
+       bool enable_beacon;
+};
+
 struct rtl8187_priv {
        /* common between rtl818x drivers */
        struct rtl818x_csr *map;
@@ -141,6 +149,7 @@ struct rtl8187_priv {
                __le32 bits32;
        } *io_dmabuf;
        bool rfkill_off;
+       u16 seqno;
 };
 
 void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
index d6c42e69bdbd467225d4db746f0e0f82d860fd68..cefac6a43601e17ca6ca9ef6db36589e7d055daf 100644 (file)
@@ -49,6 +49,11 @@ config RTLWIFI
        depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
        default m
 
+config RTLWIFI_DEBUG
+       bool "Additional debugging output"
+       depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
+       default y
+
 config RTL8192C_COMMON
        tristate
        depends on RTL8192CE || RTL8192CU
index 8d6eb0f56c031b7b4b7ac2d43756c88cd9b0f28b..510023554e5f43ba0105a2cd5de09e8987b861dd 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/ip.h>
-#include <linux/module.h>
 #include "wifi.h"
 #include "rc.h"
 #include "base.h"
 #include "ps.h"
 #include "regd.h"
 
+#include <linux/ip.h>
+#include <linux/module.h>
+
 /*
- *NOTICE!!!: This file will be very big, we hsould
- *keep it clear under follwing roles:
+ *NOTICE!!!: This file will be very big, we should
+ *keep it clear under following roles:
  *
- *This file include follwing part, so, if you add new
+ *This file include following parts, so, if you add new
  *functions into this file, please check which part it
  *should includes. or check if you should add new part
  *for this file:
@@ -211,7 +210,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
         */
        if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) {
 
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T2R or 2T2R\n");
 
                ht_cap->mcs.rx_mask[0] = 0xFF;
                ht_cap->mcs.rx_mask[1] = 0xFF;
@@ -220,7 +219,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
                ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
        } else if (get_rf_type(rtlphy) == RF_1T1R) {
 
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n");
 
                ht_cap->mcs.rx_mask[0] = 0xFF;
                ht_cap->mcs.rx_mask[1] = 0x00;
@@ -302,15 +301,13 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
                        /* <4> set mac->sband to wiphy->sband */
                        hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
                } else {
-                       RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                                ("Err BAND %d\n",
-                                rtlhal->current_bandtype));
+                       RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Err BAND %d\n",
+                                rtlhal->current_bandtype);
                }
        }
        /* <5> set hw caps */
        hw->flags = IEEE80211_HW_SIGNAL_DBM |
            IEEE80211_HW_RX_INCLUDES_FCS |
-           IEEE80211_HW_BEACON_FILTER |
            IEEE80211_HW_AMPDU_AGGREGATION |
            IEEE80211_HW_CONNECTION_MONITOR |
            /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */
@@ -413,6 +410,7 @@ void rtl_init_rfkill(struct ieee80211_hw *hw)
 
        wiphy_rfkill_start_polling(hw->wiphy);
 }
+EXPORT_SYMBOL(rtl_init_rfkill);
 
 void rtl_deinit_rfkill(struct ieee80211_hw *hw)
 {
@@ -436,13 +434,13 @@ int rtl_init_core(struct ieee80211_hw *hw)
         * mac80211 hw  in _rtl_init_mac80211.
         */
        if (rtl_regd_init(hw, rtl_reg_notifier)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "REGD init failed\n");
                return 1;
        } else {
                /* CRDA regd hint must after init CRDA */
                if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                ("regulatory_hint fail\n"));
+                                "regulatory_hint fail\n");
                }
        }
 
@@ -922,17 +920,17 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
                                return false;
 
                        RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-                                ("%s ACT_ADDBAREQ From :%pM\n",
-                                 is_tx ? "Tx" : "Rx", hdr->addr2));
+                                "%s ACT_ADDBAREQ From :%pM\n",
+                                is_tx ? "Tx" : "Rx", hdr->addr2);
                        break;
                case ACT_ADDBARSP:
                        RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-                                ("%s ACT_ADDBARSP From :%pM\n",
-                                 is_tx ? "Tx" : "Rx", hdr->addr2));
+                                "%s ACT_ADDBARSP From :%pM\n",
+                                is_tx ? "Tx" : "Rx", hdr->addr2);
                        break;
                case ACT_DELBA:
                        RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-                                ("ACT_ADDBADEL From :%pM\n", hdr->addr2));
+                                "ACT_ADDBADEL From :%pM\n", hdr->addr2);
                        break;
                }
                break;
@@ -975,8 +973,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
                                 * 67 : UDP BOOTP server
                                 */
                                RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
-                                        DBG_DMESG, ("dhcp %s !!\n",
-                                                    (is_tx) ? "Tx" : "Rx"));
+                                        DBG_DMESG, "dhcp %s !!\n",
+                                        is_tx ? "Tx" : "Rx");
 
                                if (is_tx) {
                                        rtl_lps_leave(hw);
@@ -996,7 +994,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
                return true;
        } else if (ETH_P_PAE == ether_type) {
                RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-                        ("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"));
+                        "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx");
 
                if (is_tx) {
                        rtl_lps_leave(hw);
@@ -1036,9 +1034,8 @@ int rtl_tx_agg_start(struct ieee80211_hw *hw,
                return -ENXIO;
        tid_data = &sta_entry->tids[tid];
 
-       RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
-                ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid,
-                tid_data->seq_number));
+       RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d seq:%d\n",
+                sta->addr, tid, tid_data->seq_number);
 
        *ssn = tid_data->seq_number;
        tid_data->agg.agg_state = RTL_AGG_START;
@@ -1059,12 +1056,12 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw,
                return -EINVAL;
 
        if (!sta->addr) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n");
                return -EINVAL;
        }
 
-       RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
-                ("on ra = %pM tid = %d\n", sta->addr, tid));
+       RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n",
+                sta->addr, tid);
 
        if (unlikely(tid >= MAX_TID_COUNT))
                return -EINVAL;
@@ -1087,12 +1084,12 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw,
                return -EINVAL;
 
        if (!sta->addr) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n");
                return -EINVAL;
        }
 
-       RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
-                ("on ra = %pM tid = %d\n", sta->addr, tid));
+       RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n",
+                sta->addr, tid);
 
        if (unlikely(tid >= MAX_TID_COUNT))
                return -EINVAL;
@@ -1474,29 +1471,29 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
                (memcmp(mac->bssid, ap5_6, 3) == 0) ||
                vendor == PEER_ATH) {
                vendor = PEER_ATH;
-               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n"));
+               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n");
        } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) ||
                (memcmp(mac->bssid, ap4_5, 3) == 0) ||
                (memcmp(mac->bssid, ap4_1, 3) == 0) ||
                (memcmp(mac->bssid, ap4_2, 3) == 0) ||
                (memcmp(mac->bssid, ap4_3, 3) == 0) ||
                vendor == PEER_RAL) {
-               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n"));
+               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n");
                vendor = PEER_RAL;
        } else if (memcmp(mac->bssid, ap6_1, 3) == 0 ||
                vendor == PEER_CISCO) {
                vendor = PEER_CISCO;
-               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n"));
+               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n");
        } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) ||
                (memcmp(mac->bssid, ap3_2, 3) == 0) ||
                (memcmp(mac->bssid, ap3_3, 3) == 0) ||
                vendor == PEER_BROAD) {
-               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n"));
+               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n");
                vendor = PEER_BROAD;
        } else if (memcmp(mac->bssid, ap7_1, 3) == 0 ||
                vendor == PEER_MARV) {
                vendor = PEER_MARV;
-               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n"));
+               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n");
        }
 
        mac->vendor = vendor;
index f66b5757f6b9b5bfef1a5111b517fa65131eed78..5a23a6d0f49d4b7f6dd8c35da72e16ff21a715f6 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index dc36d7461caaaecd07a8f60a93941b843c094ff2..5c7d57947d2338731f7fed6e78cd3460114d17c9 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/export.h>
 #include "wifi.h"
 #include "cam.h"
@@ -55,10 +53,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
        u8 entry_i;
 
        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
-                 key_cont_128[0], key_cont_128[1],
-                 key_cont_128[2], key_cont_128[3],
-                 key_cont_128[4], key_cont_128[5]));
+                "key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
+                key_cont_128[0], key_cont_128[1],
+                key_cont_128[2], key_cont_128[3],
+                key_cont_128[4], key_cont_128[5]);
 
        for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
                target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
@@ -73,14 +71,12 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
                        rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
                                        target_command);
 
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE %x: %x\n",
+                                rtlpriv->cfg->maps[WCAMI], target_content);
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("WRITE %x: %x\n",
-                                 rtlpriv->cfg->maps[WCAMI], target_content));
-                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("The Key ID is %d\n", entry_no));
-                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("WRITE %x: %x\n",
-                                 rtlpriv->cfg->maps[RWCAM], target_command));
+                                "The Key ID is %d\n", entry_no);
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE %x: %x\n",
+                                rtlpriv->cfg->maps[RWCAM], target_command);
 
                } else if (entry_i == 1) {
 
@@ -94,10 +90,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
                        rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
                                        target_command);
 
-                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("WRITE A4: %x\n", target_content));
-                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("WRITE A0: %x\n", target_command));
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A4: %x\n",
+                                target_content);
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A0: %x\n",
+                                target_command);
 
                } else {
 
@@ -114,15 +110,15 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
                                        target_command);
                        udelay(100);
 
-                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("WRITE A4: %x\n", target_content));
-                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("WRITE A0: %x\n", target_command));
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A4: %x\n",
+                                target_content);
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A0: %x\n",
+                                target_command);
                }
        }
 
-       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                ("after set key, usconfig:%x\n", us_config));
+       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "after set key, usconfig:%x\n",
+                us_config);
 }
 
 u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
@@ -133,14 +129,13 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, "
-                 "ulUseDK=%x MacAddr %pM\n",
-                 ul_entry_idx, ul_key_id, ul_enc_alg,
-                 ul_default_key, mac_addr));
+                "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n",
+                ul_entry_idx, ul_key_id, ul_enc_alg,
+                ul_default_key, mac_addr);
 
        if (ul_key_id == TOTAL_CAM_ENTRY) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("<=== ulKeyId exceed!\n"));
+                        "<=== ulKeyId exceed!\n");
                return 0;
        }
 
@@ -153,7 +148,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
        rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
                              (u8 *) key_content, us_config);
 
-       RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("<===\n"));
+       RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "<===\n");
 
        return 1;
 
@@ -166,7 +161,7 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
        u32 ul_command;
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-       RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id));
+       RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id);
 
        ul_command = ul_key_id * CAM_CONTENT_COUNT;
        ul_command = ul_command | BIT(31) | BIT(16);
@@ -175,9 +170,9 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
        rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
 
        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                ("rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0));
+                "rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0);
        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                ("rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command));
+                "rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command);
 
        return 0;
 
@@ -229,9 +224,9 @@ void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
        rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
 
        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                ("rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content));
+                "rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content);
        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                ("rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command));
+                "rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command);
 }
 EXPORT_SYMBOL(rtl_cam_mark_invalid);
 
@@ -279,11 +274,11 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
                rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
 
                RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                        ("rtl_cam_empty_entry(): WRITE A4: %x\n",
-                         ul_content));
+                        "rtl_cam_empty_entry(): WRITE A4: %x\n",
+                        ul_content);
                RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                        ("rtl_cam_empty_entry(): WRITE A0: %x\n",
-                         ul_command));
+                        "rtl_cam_empty_entry(): WRITE A0: %x\n",
+                        ul_command);
        }
 
 }
@@ -297,8 +292,7 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
        u8 i, *addr;
 
        if (NULL == sta_addr) {
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
-                       ("sta_addr is NULL.\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "sta_addr is NULL\n");
                return TOTAL_CAM_ENTRY;
        }
        /* Does STA already exist? */
@@ -311,8 +305,8 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
        for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) {
                if ((bitmap & BIT(0)) == 0) {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
-                               ("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n",
-                                rtlpriv->sec.hwsec_cam_bitmap, entry_idx));
+                                "-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n",
+                                rtlpriv->sec.hwsec_cam_bitmap, entry_idx);
                        rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx;
                        memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx],
                               sta_addr, ETH_ALEN);
@@ -331,14 +325,13 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
        u8 i, *addr;
 
        if (NULL == sta_addr) {
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
-                       ("sta_addr is NULL.\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "sta_addr is NULL\n");
        }
 
        if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\
                                sta_addr[4]|sta_addr[5]) == 0) {
                RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
-                       ("sta_addr is 00:00:00:00:00:00.\n"));
+                        "sta_addr is 00:00:00:00:00:00\n");
                return;
        }
        /* Does STA already exist? */
index c62da4eefc75e85f11d6aea2d9b9afbb5e111482..35e00086a520bf06393237b3aebf0aa3bbb9e617 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 3f0f056fae9cda0a4e232d401dd886f834f4e076..278e9f957e0dfcc44e0985453bf2ba54085219d9 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
 #include "core.h"
 #include "cam.h"
 #include "base.h"
+#include "pci.h"
 #include "ps.h"
 
+#include <linux/export.h>
+
+void rtl_fw_cb(const struct firmware *firmware, void *context)
+{
+       struct ieee80211_hw *hw = context;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int err;
+
+       RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+                        "Firmware callback routine entered!\n");
+       complete(&rtlpriv->firmware_loading_complete);
+       if (!firmware) {
+               pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
+               rtlpriv->max_fw_size = 0;
+               return;
+       }
+       if (firmware->size > rtlpriv->max_fw_size) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        "Firmware is too big!\n");
+               release_firmware(firmware);
+               return;
+       }
+       memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+       rtlpriv->rtlhal.fwsize = firmware->size;
+       release_firmware(firmware);
+
+       err = ieee80211_register_hw(hw);
+       if (err) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        "Can't register mac80211 hw\n");
+               return;
+       } else {
+               rtlpriv->mac80211.mac80211_registered = 1;
+       }
+       set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+
+       /*init rfkill */
+       rtl_init_rfkill(hw);
+}
+EXPORT_SYMBOL(rtl_fw_cb);
+
 /*mutex for start & stop is must here. */
 static int rtl_op_start(struct ieee80211_hw *hw)
 {
@@ -112,9 +154,11 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        int err = 0;
 
+       vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+
        if (mac->vif) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("vif has been set!! mac->vif = 0x%p\n", mac->vif));
+                        "vif has been set!! mac->vif = 0x%p\n", mac->vif);
                return -EOPNOTSUPP;
        }
 
@@ -125,7 +169,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
        case NL80211_IFTYPE_STATION:
                if (mac->beacon_enabled == 1) {
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                                ("NL80211_IFTYPE_STATION\n"));
+                                "NL80211_IFTYPE_STATION\n");
                        mac->beacon_enabled = 0;
                        rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
                                        rtlpriv->cfg->maps
@@ -134,7 +178,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
                break;
        case NL80211_IFTYPE_ADHOC:
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                        ("NL80211_IFTYPE_ADHOC\n"));
+                        "NL80211_IFTYPE_ADHOC\n");
 
                mac->link_state = MAC80211_LINKED;
                rtlpriv->cfg->ops->set_bcn_reg(hw);
@@ -148,7 +192,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
                break;
        case NL80211_IFTYPE_AP:
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                        ("NL80211_IFTYPE_AP\n"));
+                        "NL80211_IFTYPE_AP\n");
 
                mac->link_state = MAC80211_LINKED;
                rtlpriv->cfg->ops->set_bcn_reg(hw);
@@ -161,7 +205,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("operation mode %d is not support!\n", vif->type));
+                        "operation mode %d is not supported!\n", vif->type);
                err = -EOPNOTSUPP;
                goto out;
        }
@@ -221,7 +265,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
        mutex_lock(&rtlpriv->locks.conf_mutex);
        if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {  /*BIT(2)*/
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                        ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"));
+                        "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n");
        }
 
        /*For IPS */
@@ -264,8 +308,8 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
 
        if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                        ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
-                         hw->conf.long_frame_max_tx_count));
+                        "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
+                        hw->conf.long_frame_max_tx_count);
                mac->retry_long = hw->conf.long_frame_max_tx_count;
                mac->retry_short = hw->conf.long_frame_max_tx_count;
                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
@@ -320,7 +364,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
                default:
                        mac->bw_40 = false;
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                       ("switch case not processed\n"));
+                                "switch case not processed\n");
                        break;
                }
 
@@ -369,12 +413,12 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
                        mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
                            rtlpriv->cfg->maps[MAC_RCR_AB];
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                                ("Enable receive multicast frame.\n"));
+                                "Enable receive multicast frame\n");
                } else {
                        mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
                                          rtlpriv->cfg->maps[MAC_RCR_AB]);
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                                ("Disable receive multicast frame.\n"));
+                                "Disable receive multicast frame\n");
                }
        }
 
@@ -382,11 +426,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
                if (*new_flags & FIF_FCSFAIL) {
                        mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                                ("Enable receive FCS error frame.\n"));
+                                "Enable receive FCS error frame\n");
                } else {
                        mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                                ("Disable receive FCS error frame.\n"));
+                                "Disable receive FCS error frame\n");
                }
        }
 
@@ -409,11 +453,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
                        mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
 
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                                ("Enable receive control frame.\n"));
+                                "Enable receive control frame\n");
                } else {
                        mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                                ("Disable receive control frame.\n"));
+                                "Disable receive control frame\n");
                }
        }
 
@@ -421,11 +465,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
                if (*new_flags & FIF_OTHER_BSS) {
                        mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                                ("Enable receive other BSS's frame.\n"));
+                                "Enable receive other BSS's frame\n");
                } else {
                        mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                                ("Disable receive other BSS's frame.\n"));
+                                "Disable receive other BSS's frame\n");
                }
        }
 }
@@ -456,7 +500,7 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw,
                        sta_entry->wireless_mode = WIRELESS_MODE_G;
 
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-                       ("Add sta addr is %pM\n", sta->addr));
+                        "Add sta addr is %pM\n", sta->addr);
                rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
        }
        return 0;
@@ -469,7 +513,7 @@ static int rtl_op_sta_remove(struct ieee80211_hw *hw,
        struct rtl_sta_info *sta_entry;
        if (sta) {
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-                       ("Remove sta addr is %pM\n", sta->addr));
+                        "Remove sta addr is %pM\n", sta->addr);
                sta_entry = (struct rtl_sta_info *) sta->drv_priv;
                sta_entry->wireless_mode = 0;
                sta_entry->ratr_index = 0;
@@ -514,7 +558,7 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw,
 
        if (queue >= AC_MAX) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("queue number %d is incorrect!\n", queue));
+                        "queue number %d is incorrect!\n", queue);
                return -EINVAL;
        }
 
@@ -547,7 +591,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
                     bss_conf->enable_beacon)) {
                        if (mac->beacon_enabled == 0) {
                                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-                                        ("BSS_CHANGED_BEACON_ENABLED\n"));
+                                        "BSS_CHANGED_BEACON_ENABLED\n");
 
                                /*start hw beacon interrupt. */
                                /*rtlpriv->cfg->ops->set_bcn_reg(hw); */
@@ -565,7 +609,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
                        !bss_conf->enable_beacon)) {
                        if (mac->beacon_enabled == 1) {
                                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-                                        ("ADHOC DISABLE BEACON\n"));
+                                        "ADHOC DISABLE BEACON\n");
 
                                mac->beacon_enabled = 0;
                                rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
@@ -575,7 +619,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
                }
                if (changed & BSS_CHANGED_BEACON_INT) {
                        RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE,
-                                ("BSS_CHANGED_BEACON_INT\n"));
+                                "BSS_CHANGED_BEACON_INT\n");
                        mac->beacon_interval = bss_conf->beacon_int;
                        rtlpriv->cfg->ops->set_bcn_intv(hw);
                }
@@ -604,7 +648,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
                        if (mac->opmode == NL80211_IFTYPE_STATION && sta)
                                rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-                                ("BSS_CHANGED_ASSOC\n"));
+                                "BSS_CHANGED_ASSOC\n");
                } else {
                        if (mac->link_state == MAC80211_LINKED)
                                rtl_lps_leave(hw);
@@ -619,20 +663,20 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
                        mac->vendor = PEER_UNKNOWN;
 
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-                                ("BSS_CHANGED_UN_ASSOC\n"));
+                                "BSS_CHANGED_UN_ASSOC\n");
                }
        }
 
        if (changed & BSS_CHANGED_ERP_CTS_PROT) {
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-                        ("BSS_CHANGED_ERP_CTS_PROT\n"));
+                        "BSS_CHANGED_ERP_CTS_PROT\n");
                mac->use_cts_protect = bss_conf->use_cts_prot;
        }
 
        if (changed & BSS_CHANGED_ERP_PREAMBLE) {
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-                        ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n",
-                         bss_conf->use_short_preamble));
+                        "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n",
+                        bss_conf->use_short_preamble);
 
                mac->short_preamble = bss_conf->use_short_preamble;
                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE,
@@ -641,7 +685,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 
        if (changed & BSS_CHANGED_ERP_SLOT) {
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-                        ("BSS_CHANGED_ERP_SLOT\n"));
+                        "BSS_CHANGED_ERP_SLOT\n");
 
                if (bss_conf->use_short_slot)
                        mac->slot_time = RTL_SLOT_TIME_9;
@@ -653,8 +697,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
        }
 
        if (changed & BSS_CHANGED_HT) {
-               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-                        ("BSS_CHANGED_HT\n"));
+               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, "BSS_CHANGED_HT\n");
                rcu_read_lock();
                sta = get_sta(hw, vif, bss_conf->bssid);
                if (sta) {
@@ -683,8 +726,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
                                              (u8 *) bss_conf->bssid);
 
-               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-                        ("%pM\n", bss_conf->bssid));
+               RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, "%pM\n",
+                        bss_conf->bssid);
 
                mac->vendor = PEER_UNKNOWN;
                memcpy(mac->bssid, bss_conf->bssid, 6);
@@ -831,30 +874,30 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
        switch (action) {
        case IEEE80211_AMPDU_TX_START:
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-                        ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid));
+                        "IEEE80211_AMPDU_TX_START: TID:%d\n", tid);
                return rtl_tx_agg_start(hw, sta, tid, ssn);
                break;
        case IEEE80211_AMPDU_TX_STOP:
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-                        ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid));
+                        "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid);
                return rtl_tx_agg_stop(hw, sta, tid);
                break;
        case IEEE80211_AMPDU_TX_OPERATIONAL:
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-                        ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid));
+                        "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid);
                rtl_tx_agg_oper(hw, sta, tid);
                break;
        case IEEE80211_AMPDU_RX_START:
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-                        ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid));
+                        "IEEE80211_AMPDU_RX_START:TID:%d\n", tid);
                break;
        case IEEE80211_AMPDU_RX_STOP:
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-                        ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid));
+                        "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid);
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("IEEE80211_AMPDU_ERR!!!!:\n"));
+                        "IEEE80211_AMPDU_ERR!!!!:\n");
                return -EOPNOTSUPP;
        }
        return 0;
@@ -867,7 +910,7 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
 
        mac->act_scanning = true;
 
-       RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
+       RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
 
        if (mac->link_state == MAC80211_LINKED) {
                rtl_lps_leave(hw);
@@ -888,7 +931,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
-       RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
+       RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
        mac->act_scanning = false;
        /* Dual mac */
        rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
@@ -921,13 +964,13 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("not open hw encryption\n"));
+                        "not open hw encryption\n");
                return -ENOSPC; /*User disabled HW-crypto */
        }
        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                ("%s hardware based encryption for keyidx: %d, mac: %pM\n",
-                 cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
-                 sta ? sta->addr : bcast_addr));
+                "%s hardware based encryption for keyidx: %d, mac: %pM\n",
+                cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
+                sta ? sta->addr : bcast_addr);
        rtlpriv->sec.being_setkey = true;
        rtl_ips_nic_on(hw);
        mutex_lock(&rtlpriv->locks.conf_mutex);
@@ -936,24 +979,23 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        switch (key->cipher) {
        case WLAN_CIPHER_SUITE_WEP40:
                key_type = WEP40_ENCRYPTION;
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n");
                break;
        case WLAN_CIPHER_SUITE_WEP104:
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                        ("alg:WEP104\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n");
                key_type = WEP104_ENCRYPTION;
                break;
        case WLAN_CIPHER_SUITE_TKIP:
                key_type = TKIP_ENCRYPTION;
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n");
                break;
        case WLAN_CIPHER_SUITE_CCMP:
                key_type = AESCCMP_ENCRYPTION;
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n");
                break;
        default:
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("alg_err:%x!!!!:\n", key->cipher));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "alg_err:%x!!!!\n",
+                        key->cipher);
                goto out_unlock;
        }
        if (key_type == WEP40_ENCRYPTION ||
@@ -995,8 +1037,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                                wep_only = true;
                        rtlpriv->sec.pairwise_enc_algorithm = key_type;
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                               ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1"
-                               " TKIP:2 AES:4 WEP104:5)\n", key_type));
+                                "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n",
+                                key_type);
                        rtlpriv->cfg->ops->enable_hw_sec(hw);
                }
        }
@@ -1005,7 +1047,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        case SET_KEY:
                if (wep_only) {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("set WEP(group/pairwise) key\n"));
+                                "set WEP(group/pairwise) key\n");
                        /* Pairwise key with an assigned MAC address. */
                        rtlpriv->sec.pairwise_enc_algorithm = key_type;
                        rtlpriv->sec.group_enc_algorithm = key_type;
@@ -1016,7 +1058,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                        memcpy(mac_addr, zero_addr, ETH_ALEN);
                } else if (group_key) { /* group key */
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("set group key\n"));
+                                "set group key\n");
                        /* group key */
                        rtlpriv->sec.group_enc_algorithm = key_type;
                        /*set local buf about group key. */
@@ -1026,10 +1068,10 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                        memcpy(mac_addr, bcast_addr, ETH_ALEN);
                } else {        /* pairwise key */
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("set pairwise key\n"));
+                                "set pairwise key\n");
                        if (!sta) {
-                               RT_ASSERT(false, ("pairwise key withnot"
-                                                 "mac_addr\n"));
+                               RT_ASSERT(false,
+                                         "pairwise key without mac_addr\n");
 
                                err = -EOPNOTSUPP;
                                goto out_unlock;
@@ -1056,7 +1098,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                break;
        case DISABLE_KEY:
                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                        ("disable key delete one entry\n"));
+                        "disable key delete one entry\n");
                /*set local buf about wep key. */
                if (mac->opmode == NL80211_IFTYPE_AP) {
                        if (sta)
@@ -1077,7 +1119,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("cmd_err:%x!!!!:\n", cmd));
+                        "cmd_err:%x!!!!\n", cmd);
        }
 out_unlock:
        mutex_unlock(&rtlpriv->locks.conf_mutex);
@@ -1106,8 +1148,8 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
                        rtlpriv->rfkill.rfkill_state = radio_state;
 
                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                (KERN_INFO "wireless radio switch turned %s\n",
-                                 radio_state ? "on" : "off"));
+                                "wireless radio switch turned %s\n",
+                                radio_state ? "on" : "off");
 
                        blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
                        wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
index f02824a3b74736d9db8529affc777fe9550cd14c..2fe46a1b4f1f12c3e77ba985d59c4aaff1d88357 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * Tmis program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -30,8 +30,6 @@
 #ifndef __RTL_CORE_H__
 #define __RTL_CORE_H__
 
-#include <net/mac80211.h>
-
 #define RTL_SUPPORTED_FILTERS          \
        (FIF_PROMISC_IN_BSS | \
        FIF_ALLMULTI | FIF_CONTROL | \
@@ -42,4 +40,6 @@
 #define RTL_SUPPORTED_CTRL_FILTER      0xFF
 
 extern const struct ieee80211_ops rtl_ops;
+void rtl_fw_cb(const struct firmware *firmware, void *context);
+
 #endif
index 1b5cb7153a526b97a3f3ad63d8714ec48b8e2e27..bdda9b2fffe151f79af75eb3042d311e054ff3ed 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * Tmis program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -28,6 +28,8 @@
 
 #include "wifi.h"
 
+#include <linux/moduleparam.h>
+
 void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
index 160dd06852136d2a8616b115fdb426c93b093fa2..07493d2957f2a11d313275643b1fee0bc7c6196f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * Tmis program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -156,53 +156,78 @@ enum dbgp_flag_e {
        DBGP_TYPE_MAX
 };
 
-#define RT_ASSERT(_exp, fmt)                           \
-       do {                                            \
-               if (!(_exp)) {                  \
-                       printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \
-                       __func__);                      \
-                       printk fmt;                     \
-               } \
-       } while (0);
-
-#define RT_TRACE(rtlpriv, comp, level, fmt)\
-       do { \
-               if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \
-                       ((level) <= rtlpriv->dbg.global_debuglevel))) {\
-                       printk(KERN_DEBUG "%s:%s():<%lx-%x> ", KBUILD_MODNAME, \
-                       __func__, in_interrupt(), in_atomic()); \
-                       printk fmt;                             \
-               } \
-       } while (0);
-
-#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr)   \
-       do {                                            \
-               if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \
-                       printk(KERN_DEBUG "%s: ", KBUILD_MODNAME);      \
-                       printk printstr;                \
-               }                                       \
-       } while (0);
-
-#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \
-               _hexdatalen) \
-       do {\
-               if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&\
-                       (_level <= rtlpriv->dbg.global_debuglevel)))    { \
-                       int __i;                                        \
-                       u8*     ptr = (u8 *)_hexdata;                   \
-                       printk(KERN_DEBUG "%s: ", KBUILD_MODNAME);      \
-                       printk("In process \"%s\" (pid %i):", current->comm,\
-                                       current->pid); \
-                       printk(_titlestring);           \
-                       for (__i = 0; __i < (int)_hexdatalen; __i++) {  \
-                               printk("%02X%s", ptr[__i], (((__i + 1) % 4)\
-                                                       == 0) ? "  " : " ");\
-                               if (((__i + 1) % 16) == 0)              \
-                                       printk("\n");                   \
-                       }                               \
-                       printk(KERN_DEBUG "\n");                        \
-               } \
-       } while (0);
+#ifdef CONFIG_RTLWIFI_DEBUG
+
+#define RT_ASSERT(_exp, fmt, ...)                                      \
+do {                                                                   \
+       if (!(_exp)) {                                                  \
+               printk(KERN_DEBUG KBUILD_MODNAME ":%s(): " fmt,         \
+                      __func__, ##__VA_ARGS__);                        \
+       }                                                               \
+} while (0)
+
+#define RT_TRACE(rtlpriv, comp, level, fmt, ...)                       \
+do {                                                                   \
+       if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) &&  \
+                    ((level) <= rtlpriv->dbg.global_debuglevel))) {    \
+               printk(KERN_DEBUG KBUILD_MODNAME ":%s():<%lx-%x> " fmt, \
+                      __func__, in_interrupt(), in_atomic(),           \
+                      ##__VA_ARGS__);                                  \
+       }                                                               \
+} while (0)
+
+#define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...)                   \
+do {                                                                   \
+       if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) {      \
+               printk(KERN_DEBUG KBUILD_MODNAME ": " fmt,              \
+                      ##__VA_ARGS__);                                  \
+       }                                                               \
+} while (0)
+
+#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata,  \
+                     _hexdatalen)                                      \
+do {                                                                   \
+       if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) && \
+                    (_level <= rtlpriv->dbg.global_debuglevel))) {     \
+               printk(KERN_DEBUG "%s: In process \"%s\" (pid %i): %s\n", \
+                      KBUILD_MODNAME, current->comm, current->pid,     \
+                      _titlestring);                                   \
+               print_hex_dump_bytes("", DUMP_PREFIX_NONE,              \
+                                    _hexdata, _hexdatalen);            \
+       }                                                               \
+} while (0)
+
+#else
+
+struct rtl_priv;
+
+__printf(2, 3)
+static inline void RT_ASSERT(int exp, const char *fmt, ...)
+{
+}
+
+__printf(4, 5)
+static inline void RT_TRACE(struct rtl_priv *rtlpriv,
+                           int comp, int level,
+                           const char *fmt, ...)
+{
+}
+
+__printf(4, 5)
+static inline void RTPRINT(struct rtl_priv *rtlpriv,
+                          int dbgtype, int dbgflag,
+                          const char *fmt, ...)
+{
+}
+
+static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv,
+                                int comp, int level,
+                                const char *titlestring,
+                                const void *hexdata, size_t hexdatalen)
+{
+}
+
+#endif
 
 void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
 #endif
index ed1058b7158700c6eb65cc1f373472577b85ab1f..b24cbe6e16d893581317ce40ea39f8838ffaf2db 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * Tmis program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -162,8 +162,8 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
        const u32 efuse_len =
                rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
 
-       RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-                ("Addr=%x Data =%x\n", address, value));
+       RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n",
+                address, value);
 
        if (address < efuse_len) {
                rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
@@ -252,8 +252,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
 
        if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
                RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-                        ("read_efuse(): Invalid offset(%#x) with read "
-                         "bytes(%#x)!!\n", _offset, _size_byte));
+                        "read_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n",
+                        _offset, _size_byte);
                return;
        }
 
@@ -280,7 +280,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
        if (*rtemp8 != 0xFF) {
                efuse_utilized++;
                RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
-                       ("Addr=%d\n", efuse_addr));
+                       "Addr=%d\n", efuse_addr);
                efuse_addr++;
        }
 
@@ -290,13 +290,13 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
                if (offset < efuse_max_section) {
                        wren = (*rtemp8 & 0x0f);
                        RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
-                               ("offset-%d Worden=%x\n", offset, wren));
+                               "offset-%d Worden=%x\n", offset, wren);
 
                        for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
                                if (!(wren & 0x01)) {
                                        RTPRINT(rtlpriv, FEEPROM,
-                                               EFUSE_READ_ALL, ("Addr=%d\n",
-                                                                efuse_addr));
+                                               EFUSE_READ_ALL,
+                                               "Addr=%d\n", efuse_addr);
 
                                        read_efuse_byte(hw, efuse_addr, rtemp8);
                                        efuse_addr++;
@@ -308,8 +308,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
                                                break;
 
                                        RTPRINT(rtlpriv, FEEPROM,
-                                               EFUSE_READ_ALL, ("Addr=%d\n",
-                                                                efuse_addr));
+                                               EFUSE_READ_ALL,
+                                               "Addr=%d\n", efuse_addr);
 
                                        read_efuse_byte(hw, efuse_addr, rtemp8);
                                        efuse_addr++;
@@ -326,7 +326,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
                }
 
                RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
-                       ("Addr=%d\n", efuse_addr));
+                       "Addr=%d\n", efuse_addr);
                read_efuse_byte(hw, efuse_addr, rtemp8);
                if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) {
                        efuse_utilized++;
@@ -395,9 +395,8 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
                result = false;
 
        RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-                ("efuse_shadow_update_chk(): totalbytes(%#x), "
-                 "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
-                 totalbytes, hdr_num, words_need, efuse_used));
+                "efuse_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
+                totalbytes, hdr_num, words_need, efuse_used);
 
        return result;
 }
@@ -434,7 +433,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw)
        u8 word_en = 0x0F;
        u8 first_pg = false;
 
-       RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("--->\n"));
+       RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "--->\n");
 
        if (!efuse_shadow_update_chk(hw)) {
                efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
@@ -443,7 +442,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw)
                       rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
 
                RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-                        ("<---efuse out of capacity!!\n"));
+                        "<---efuse out of capacity!!\n");
                return false;
        }
        efuse_power_switch(hw, true, true);
@@ -478,12 +477,12 @@ bool efuse_shadow_update(struct ieee80211_hw *hw)
                               &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base],
                               8);
                        RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD,
-                                     ("U-efuse\n"), tmpdata, 8);
+                                     "U-efuse", tmpdata, 8);
 
                        if (!efuse_pg_packet_write(hw, (u8) offset, word_en,
                                                   tmpdata)) {
                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                        ("PG section(%#x) fail!!\n", offset));
+                                        "PG section(%#x) fail!!\n", offset);
                                break;
                        }
                }
@@ -497,7 +496,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw)
               &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
               rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
 
-       RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("<---\n"));
+       RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "<---\n");
        return true;
 }
 
@@ -634,8 +633,8 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u8 tmpidx = 0;
 
-       RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-                ("Addr = %x Data=%x\n", addr, data));
+       RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr = %x Data=%x\n",
+                addr, data);
 
        rtl_write_byte(rtlpriv,
                       rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff));
@@ -851,7 +850,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
                        }
                }
        }
-       RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n"));
+       RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,  "efuse PG_STATE_HEADER-1\n");
 }
 
 static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
@@ -916,7 +915,7 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
                }
 
                RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
-                       ("efuse PG_STATE_HEADER-2\n"));
+                       "efuse PG_STATE_HEADER-2\n");
        }
 }
 
@@ -936,7 +935,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
        if (efuse_get_current_size(hw) >=
            (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) {
                RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
-                       ("efuse_pg_packet_write error\n"));
+                       "efuse_pg_packet_write error\n");
                return false;
        }
 
@@ -948,7 +947,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
        efuse_word_enable_data_read(word_en, data, target_pkt.data);
        target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en);
 
-       RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));
+       RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,  "efuse Power ON\n");
 
        while (continual && (efuse_addr <
               (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {
@@ -956,7 +955,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
                if (write_state == PG_STATE_HEADER) {
                        badworden = 0x0F;
                        RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
-                               ("efuse PG_STATE_HEADER\n"));
+                               "efuse PG_STATE_HEADER\n");
 
                        if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
                            (efuse_data != 0xFF))
@@ -976,7 +975,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
 
                } else if (write_state == PG_STATE_DATA) {
                        RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
-                               ("efuse PG_STATE_DATA\n"));
+                               "efuse PG_STATE_DATA\n");
                        badworden =
                            efuse_word_enable_data_write(hw, efuse_addr + 1,
                                                         target_pkt.word_en,
@@ -999,14 +998,14 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
                                        result = false;
                                }
                                RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
-                                       ("efuse PG_STATE_HEADER-3\n"));
+                                       "efuse PG_STATE_HEADER-3\n");
                        }
                }
        }
 
        if (efuse_addr >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) {
                RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-                        ("efuse_addr(%#x) Out of size!!\n", efuse_addr));
+                        "efuse_addr(%#x) Out of size!!\n", efuse_addr);
        }
 
        return true;
@@ -1046,8 +1045,8 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
        u8 tmpdata[8];
 
        memset(tmpdata, 0xff, PGPKT_DATA_SIZE);
-       RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-                ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr));
+       RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "word_en = %x efuse_addr=%x\n",
+                word_en, efuse_addr);
 
        if (!(word_en & BIT(0))) {
                tmpaddr = start_addr;
index 164dabaa76159cc14690c535258d3982357e3ac4..2bdea9a8699e1cd653d85371bd54f9d23ec817e7 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 9245d882c06a3046dfb3d052456e6174d99d2a97..07dd38efe62a01580c9debe210fb2d38c8ddd50e 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
  *
  *****************************************************************************/
 
-#include <linux/export.h>
-#include "core.h"
 #include "wifi.h"
+#include "core.h"
 #include "pci.h"
 #include "base.h"
 #include "ps.h"
 #include "efuse.h"
+#include <linux/export.h>
 
 static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
        PCI_VENDOR_ID_INTEL,
@@ -170,7 +170,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
 
@@ -198,7 +198,7 @@ static bool _rtl_pci_platform_switch_device_pci_aspm(
 }
 
 /*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
-static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
+static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
 {
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@@ -207,8 +207,6 @@ static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
 
        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
                udelay(100);
-
-       return true;
 }
 
 /*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/
@@ -232,7 +230,7 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
 
        if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-                        ("PCI(Bridge) UNKNOWN.\n"));
+                        "PCI(Bridge) UNKNOWN\n");
 
                return;
        }
@@ -286,7 +284,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
 
        if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-                        ("PCI(Bridge) UNKNOWN.\n"));
+                        "PCI(Bridge) UNKNOWN\n");
                return;
        }
 
@@ -303,11 +301,10 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
                              u_pcibridge_aspmsetting);
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("PlatformEnableASPM():PciBridge busnumber[%x], "
-                 "DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n",
-                 pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum,
-                 (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
-                 u_pcibridge_aspmsetting));
+                "PlatformEnableASPM():PciBridge busnumber[%x], DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n",
+                pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum,
+                (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
+                u_pcibridge_aspmsetting);
 
        udelay(50);
 
@@ -382,9 +379,8 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev,
        pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg);
        pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                ("Link Control Register =%x\n",
-                 pcipriv->ndis_adapter.linkctrl_reg));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n",
+                pcipriv->ndis_adapter.linkctrl_reg);
 
        pci_read_config_byte(pdev, 0x98, &tmp);
        tmp |= BIT(4);
@@ -551,11 +547,10 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
                        skb_pull(skb, EM_HDR_LEN);
 
                RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,
-                        ("new ring->idx:%d, "
-                         "free: skb_queue_len:%d, free: seq:%x\n",
-                         ring->idx,
-                         skb_queue_len(&ring->queue),
-                         *(u16 *) (skb->data + 22)));
+                        "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n",
+                        ring->idx,
+                        skb_queue_len(&ring->queue),
+                        *(u16 *) (skb->data + 22));
 
                if (prio == TXCMD_QUEUE) {
                        dev_kfree_skb(skb);
@@ -593,11 +588,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
                                == 2) {
 
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
-                                       ("more desc left, wake"
-                                        "skb_queue@%d,ring->idx = %d,"
-                                        "skb_queue_len = 0x%d\n",
-                                        prio, ring->idx,
-                                        skb_queue_len(&ring->queue)));
+                                "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%d\n",
+                                prio, ring->idx,
+                                skb_queue_len(&ring->queue));
 
                        ieee80211_wake_queue(hw,
                                        skb_get_queue_mapping
@@ -657,6 +650,8 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb,
                return;
 
        uskb = dev_alloc_skb(skb->len + 128);
+       if (!uskb)
+               return;         /* exit if allocation failed */
        memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status));
        pdata = (u8 *)skb_put(uskb, skb->len);
        memcpy(pdata, skb->data, skb->len);
@@ -709,9 +704,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
 
                new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
                if (unlikely(!new_skb)) {
-                       RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
-                                DBG_DMESG,
-                                ("can't alloc skb for rx\n"));
+                       RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), DBG_DMESG,
+                                "can't alloc skb for rx\n");
                        goto done;
                }
 
@@ -796,38 +790,37 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
        /*<1> beacon related */
        if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) {
                RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                        ("beacon ok interrupt!\n"));
+                        "beacon ok interrupt!\n");
        }
 
        if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) {
                RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                        ("beacon err interrupt!\n"));
+                        "beacon err interrupt!\n");
        }
 
        if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) {
-               RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                        ("beacon interrupt!\n"));
+               RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n");
        }
 
        if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) {
                RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                        ("prepare beacon for interrupt!\n"));
+                        "prepare beacon for interrupt!\n");
                tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet);
        }
 
        /*<3> Tx related */
        if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TXFOVW]))
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("IMR_TXFOVW!\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n");
 
        if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) {
                RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                        ("Manage ok interrupt!\n"));
+                        "Manage ok interrupt!\n");
                _rtl_pci_tx_isr(hw, MGNT_QUEUE);
        }
 
        if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) {
                RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                        ("HIGH_QUEUE ok interrupt!\n"));
+                        "HIGH_QUEUE ok interrupt!\n");
                _rtl_pci_tx_isr(hw, HIGH_QUEUE);
        }
 
@@ -835,7 +828,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
                rtlpriv->link_info.num_tx_inperiod++;
 
                RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                        ("BK Tx OK interrupt!\n"));
+                        "BK Tx OK interrupt!\n");
                _rtl_pci_tx_isr(hw, BK_QUEUE);
        }
 
@@ -843,7 +836,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
                rtlpriv->link_info.num_tx_inperiod++;
 
                RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                        ("BE TX OK interrupt!\n"));
+                        "BE TX OK interrupt!\n");
                _rtl_pci_tx_isr(hw, BE_QUEUE);
        }
 
@@ -851,7 +844,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
                rtlpriv->link_info.num_tx_inperiod++;
 
                RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                        ("VI TX OK interrupt!\n"));
+                        "VI TX OK interrupt!\n");
                _rtl_pci_tx_isr(hw, VI_QUEUE);
        }
 
@@ -859,7 +852,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
                rtlpriv->link_info.num_tx_inperiod++;
 
                RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                        ("Vo TX OK interrupt!\n"));
+                        "Vo TX OK interrupt!\n");
                _rtl_pci_tx_isr(hw, VO_QUEUE);
        }
 
@@ -868,25 +861,25 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
                        rtlpriv->link_info.num_tx_inperiod++;
 
                        RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-                                       ("CMD TX OK interrupt!\n"));
+                                "CMD TX OK interrupt!\n");
                        _rtl_pci_tx_isr(hw, TXCMD_QUEUE);
                }
        }
 
        /*<2> Rx related */
        if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) {
-               RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n"));
+               RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n");
                _rtl_pci_rx_interrupt(hw);
        }
 
        if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("rx descriptor unavailable!\n"));
+                        "rx descriptor unavailable!\n");
                _rtl_pci_rx_interrupt(hw);
        }
 
        if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n");
                _rtl_pci_rx_interrupt(hw);
        }
 
@@ -1028,7 +1021,7 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
 
        if (!ring || (unsigned long)ring & 0xFF) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Cannot allocate TX ring (prio = %d)\n", prio));
+                        "Cannot allocate TX ring (prio = %d)\n", prio);
                return -ENOMEM;
        }
 
@@ -1039,8 +1032,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
        rtlpci->tx_ring[prio].entries = entries;
        skb_queue_head_init(&rtlpci->tx_ring[prio].queue);
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("queue:%d, ring_addr:%p\n", prio, ring));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n",
+                prio, ring);
 
        for (i = 0; i < entries; i++) {
                nextdescaddress = (u32) dma +
@@ -1078,7 +1071,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
                if (!rtlpci->rx_ring[rx_queue_idx].desc ||
                    (unsigned long)rtlpci->rx_ring[rx_queue_idx].desc & 0xFF) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Cannot allocate RX ring\n"));
+                                "Cannot allocate RX ring\n");
                        return -ENOMEM;
                }
 
@@ -1155,10 +1148,12 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
                ring->idx = (ring->idx + 1) % ring->entries;
        }
 
-       pci_free_consistent(rtlpci->pdev,
-                           sizeof(*ring->desc) * ring->entries,
-                           ring->desc, ring->dma);
-       ring->desc = NULL;
+       if (ring->desc) {
+               pci_free_consistent(rtlpci->pdev,
+                                   sizeof(*ring->desc) * ring->entries,
+                                   ring->desc, ring->dma);
+               ring->desc = NULL;
+       }
 }
 
 static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci)
@@ -1182,12 +1177,14 @@ static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci)
                        kfree_skb(skb);
                }
 
-               pci_free_consistent(rtlpci->pdev,
+               if (rtlpci->rx_ring[rx_queue_idx].desc) {
+                       pci_free_consistent(rtlpci->pdev,
                                    sizeof(*rtlpci->rx_ring[rx_queue_idx].
                                           desc) * rtlpci->rxringcount,
                                    rtlpci->rx_ring[rx_queue_idx].desc,
                                    rtlpci->rx_ring[rx_queue_idx].dma);
-               rtlpci->rx_ring[rx_queue_idx].desc = NULL;
+                       rtlpci->rx_ring[rx_queue_idx].desc = NULL;
+               }
        }
 }
 
@@ -1355,7 +1352,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
        u8 temp_one = 1;
 
        if (ieee80211_is_auth(fc)) {
-               RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
                rtl_ips_nic_on(hw);
        }
 
@@ -1388,10 +1385,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 
        if ((own == 1) && (hw_queue != BEACON_QUEUE)) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("No more TX desc@%d, ring->idx = %d,"
-                         "idx = %d, skb_queue_len = 0x%d\n",
-                         hw_queue, ring->idx, idx,
-                         skb_queue_len(&ring->queue)));
+                        "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n",
+                        hw_queue, ring->idx, idx,
+                        skb_queue_len(&ring->queue));
 
                spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
                return skb->len;
@@ -1426,11 +1422,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
            hw_queue != BEACON_QUEUE) {
 
                RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
-                        ("less desc left, stop skb_queue@%d, "
-                         "ring->idx = %d,"
-                         "idx = %d, skb_queue_len = 0x%d\n",
-                         hw_queue, ring->idx, idx,
-                         skb_queue_len(&ring->queue)));
+                        "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n",
+                        hw_queue, ring->idx, idx,
+                        skb_queue_len(&ring->queue));
 
                ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
        }
@@ -1497,7 +1491,7 @@ static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
        err = _rtl_pci_init_trx_ring(hw);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("tx ring initialization failed"));
+                        "tx ring initialization failed\n");
                return err;
        }
 
@@ -1519,12 +1513,12 @@ static int rtl_pci_start(struct ieee80211_hw *hw)
        err = rtlpriv->cfg->ops->hw_init(hw);
        if (err) {
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("Failed to config hardware!\n"));
+                        "Failed to config hardware!\n");
                return err;
        }
 
        rtlpriv->cfg->ops->enable_interrupt(hw);
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable_interrupt OK\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n");
 
        rtl_init_rx_config(hw);
 
@@ -1535,7 +1529,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw)
 
        rtlpci->up_first_time = false;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n");
        return 0;
 }
 
@@ -1573,6 +1567,9 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)
 
        rtlpci->driver_is_goingto_unload = true;
        rtlpriv->cfg->ops->hw_disable(hw);
+       /* some things are not needed if firmware not available */
+       if (!rtlpriv->max_fw_size)
+               return;
        rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
 
        spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
@@ -1622,20 +1619,20 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
                switch (revisionid) {
                case RTL_PCI_REVISION_ID_8192PCIE:
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                                ("8192 PCI-E is found - "
-                                 "vid/did=%x/%x\n", venderid, deviceid));
+                                "8192 PCI-E is found - vid/did=%x/%x\n",
+                                venderid, deviceid);
                        rtlhal->hw_type = HARDWARE_TYPE_RTL8192E;
                        break;
                case RTL_PCI_REVISION_ID_8192SE:
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                                ("8192SE is found - "
-                                 "vid/did=%x/%x\n", venderid, deviceid));
+                                "8192SE is found - vid/did=%x/%x\n",
+                                venderid, deviceid);
                        rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                ("Err: Unknown device - "
-                                 "vid/did=%x/%x\n", venderid, deviceid));
+                                "Err: Unknown device - vid/did=%x/%x\n",
+                                venderid, deviceid);
                        rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
                        break;
 
@@ -1646,18 +1643,18 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
                   deviceid == RTL_PCI_8188CE_DID) {
                rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("8192C PCI-E is found - "
-                         "vid/did=%x/%x\n", venderid, deviceid));
+                        "8192C PCI-E is found - vid/did=%x/%x\n",
+                        venderid, deviceid);
        } else if (deviceid == RTL_PCI_8192DE_DID ||
                   deviceid == RTL_PCI_8192DE_DID2) {
                rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("8192D PCI-E is found - "
-                         "vid/did=%x/%x\n", venderid, deviceid));
+                        "8192D PCI-E is found - vid/did=%x/%x\n",
+                        venderid, deviceid);
        } else {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("Err: Unknown device -"
-                         " vid/did=%x/%x\n", venderid, deviceid));
+                        "Err: Unknown device - vid/did=%x/%x\n",
+                        venderid, deviceid);
 
                rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;
        }
@@ -1665,19 +1662,18 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) {
                if (revisionid == 0 || revisionid == 1) {
                        if (revisionid == 0) {
-                               RT_TRACE(rtlpriv, COMP_INIT,
-                                        DBG_LOUD, ("Find 92DE MAC0.\n"));
+                               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                                        "Find 92DE MAC0\n");
                                rtlhal->interfaceindex = 0;
                        } else if (revisionid == 1) {
                                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                                       ("Find 92DE MAC1.\n"));
+                                        "Find 92DE MAC1\n");
                                rtlhal->interfaceindex = 1;
                        }
                } else {
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                               ("Unknown device - "
-                               "VendorID/DeviceID=%x/%x, Revision=%x\n",
-                               venderid, deviceid, revisionid));
+                                "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n",
+                                venderid, deviceid, revisionid);
                        rtlhal->interfaceindex = 0;
                }
        }
@@ -1693,8 +1689,8 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
                        if (bridge_pdev->vendor == pcibridge_vendors[tmp]) {
                                pcipriv->ndis_adapter.pcibridge_vendor = tmp;
                                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                                        ("Pci Bridge Vendor is found index:"
-                                        " %d\n", tmp));
+                                        "Pci Bridge Vendor is found index: %d\n",
+                                        tmp);
                                break;
                        }
                }
@@ -1723,23 +1719,21 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
        }
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                ("pcidev busnumber:devnumber:funcnumber:"
-                 "vendor:link_ctl %d:%d:%d:%x:%x\n",
-                 pcipriv->ndis_adapter.busnumber,
-                 pcipriv->ndis_adapter.devnumber,
-                 pcipriv->ndis_adapter.funcnumber,
-                 pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg));
+                "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n",
+                pcipriv->ndis_adapter.busnumber,
+                pcipriv->ndis_adapter.devnumber,
+                pcipriv->ndis_adapter.funcnumber,
+                pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg);
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                ("pci_bridge busnumber:devnumber:funcnumber:vendor:"
-                 "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
-                 pcipriv->ndis_adapter.pcibridge_busnum,
-                 pcipriv->ndis_adapter.pcibridge_devnum,
-                 pcipriv->ndis_adapter.pcibridge_funcnum,
-                 pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
-                 pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
-                 pcipriv->ndis_adapter.pcibridge_linkctrlreg,
-                 pcipriv->ndis_adapter.amd_l1_patch));
+                "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
+                pcipriv->ndis_adapter.pcibridge_busnum,
+                pcipriv->ndis_adapter.pcibridge_devnum,
+                pcipriv->ndis_adapter.pcibridge_funcnum,
+                pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
+                pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
+                pcipriv->ndis_adapter.pcibridge_linkctrlreg,
+                pcipriv->ndis_adapter.amd_l1_patch);
 
        rtl_pci_parse_configuration(pdev, hw);
 
@@ -1759,18 +1753,17 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 
        err = pci_enable_device(pdev);
        if (err) {
-               RT_ASSERT(false,
-                         ("%s : Cannot enable new PCI device\n",
-                          pci_name(pdev)));
+               RT_ASSERT(false, "%s : Cannot enable new PCI device\n",
+                         pci_name(pdev));
                return err;
        }
 
        if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
                if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
-                       RT_ASSERT(false, ("Unable to obtain 32bit DMA "
-                                         "for consistent allocations\n"));
-                       pci_disable_device(pdev);
-                       return -ENOMEM;
+                       RT_ASSERT(false,
+                                 "Unable to obtain 32bit DMA for consistent allocations\n");
+                       err = -ENOMEM;
+                       goto fail1;
                }
        }
 
@@ -1780,7 +1773,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
                                sizeof(struct rtl_priv), &rtl_ops);
        if (!hw) {
                RT_ASSERT(false,
-                         ("%s : ieee80211 alloc failed\n", pci_name(pdev)));
+                         "%s : ieee80211 alloc failed\n", pci_name(pdev));
                err = -ENOMEM;
                goto fail1;
        }
@@ -1791,6 +1784,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
        rtlpriv = hw->priv;
        pcipriv = (void *)rtlpriv->priv;
        pcipriv->dev.pdev = pdev;
+       init_completion(&rtlpriv->firmware_loading_complete);
 
        /* init cfg & intf_ops */
        rtlpriv->rtlhal.interface = INTF_PCI;
@@ -1810,8 +1804,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
        /* MEM map */
        err = pci_request_regions(pdev, KBUILD_MODNAME);
        if (err) {
-               RT_ASSERT(false, ("Can't obtain PCI resources\n"));
-               return err;
+               RT_ASSERT(false, "Can't obtain PCI resources\n");
+               goto fail1;
        }
 
        pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id);
@@ -1823,15 +1817,15 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
                        (unsigned long)pci_iomap(pdev,
                        rtlpriv->cfg->bar_id, pmem_len);
        if (rtlpriv->io.pci_mem_start == 0) {
-               RT_ASSERT(false, ("Can't map PCI mem\n"));
+               RT_ASSERT(false, "Can't map PCI mem\n");
+               err = -ENOMEM;
                goto fail2;
        }
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                ("mem mapped space: start: 0x%08lx len:%08lx "
-                 "flags:%08lx, after map:0x%08lx\n",
-                 pmem_start, pmem_len, pmem_flags,
-                 rtlpriv->io.pci_mem_start));
+                "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n",
+                pmem_start, pmem_len, pmem_flags,
+                rtlpriv->io.pci_mem_start);
 
        /* Disable Clk Request */
        pci_write_config_byte(pdev, 0x81, 0);
@@ -1841,8 +1835,10 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
        pci_write_config_byte(pdev, 0x04, 0x07);
 
        /* find adapter */
-       if (!_rtl_pci_find_adapter(pdev, hw))
+       if (!_rtl_pci_find_adapter(pdev, hw)) {
+               err = -ENODEV;
                goto fail3;
+       }
 
        /* Init IO handler */
        _rtl_pci_io_handler_init(&pdev->dev, hw);
@@ -1851,8 +1847,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
        rtlpriv->cfg->ops->read_eeprom_info(hw);
 
        if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't init_sw_vars.\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
+               err = -ENODEV;
                goto fail3;
        }
 
@@ -1865,69 +1861,55 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
        err = rtl_init_core(hw);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't allocate sw for mac80211.\n"));
+                        "Can't allocate sw for mac80211\n");
                goto fail3;
        }
 
        /* Init PCI sw */
        err = rtl_pci_init(hw, pdev);
        if (err) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Failed to init PCI.\n"));
-               goto fail3;
-       }
-
-       err = ieee80211_register_hw(hw);
-       if (err) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't register mac80211 hw.\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to init PCI\n");
                goto fail3;
-       } else {
-               rtlpriv->mac80211.mac80211_registered = 1;
        }
 
        err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("failed to create sysfs device attributes\n"));
+                        "failed to create sysfs device attributes\n");
                goto fail3;
        }
 
-       /*init rfkill */
-       rtl_init_rfkill(hw);
-
        rtlpci = rtl_pcidev(pcipriv);
        err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
                          IRQF_SHARED, KBUILD_MODNAME, hw);
        if (err) {
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("%s: failed to register IRQ handler\n",
-                         wiphy_name(hw->wiphy)));
+                        "%s: failed to register IRQ handler\n",
+                        wiphy_name(hw->wiphy));
                goto fail3;
-       } else {
-               rtlpci->irq_alloc = 1;
        }
+       rtlpci->irq_alloc = 1;
 
-       set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
        return 0;
 
 fail3:
-       pci_set_drvdata(pdev, NULL);
        rtl_deinit_core(hw);
        _rtl_pci_io_handler_release(hw);
-       ieee80211_free_hw(hw);
 
        if (rtlpriv->io.pci_mem_start != 0)
                pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
 
 fail2:
        pci_release_regions(pdev);
+       complete(&rtlpriv->firmware_loading_complete);
 
 fail1:
-
+       if (hw)
+               ieee80211_free_hw(hw);
+       pci_set_drvdata(pdev, NULL);
        pci_disable_device(pdev);
 
-       return -ENODEV;
+       return err;
 
 }
 EXPORT_SYMBOL(rtl_pci_probe);
@@ -1940,6 +1922,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
        struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
        struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
 
+       /* just in case driver is removed before firmware callback */
+       wait_for_completion(&rtlpriv->firmware_loading_complete);
        clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
 
        sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group);
index ebe0b42c0518624bb7fcd9d6c4b881c714f39732..241448fc9ed5d190a5a54097571d4f3fc6504870 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -239,7 +239,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 void rtl_pci_disconnect(struct pci_dev *pdev);
 int rtl_pci_suspend(struct device *dev);
 int rtl_pci_resume(struct device *dev);
-
 static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
        return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
index 130fdd99d57336de7ebf4475ddf783365f43a24b..15f86eaa1cd621437f1b1f6dcaff3b317c88d943 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -44,10 +44,11 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
 
        if (is_hal_stop(rtlhal))
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("Driver is already down!\n"));
+                        "Driver is already down!\n");
 
        /*<2> Enable Adapter */
-       rtlpriv->cfg->ops->hw_init(hw);
+       if (rtlpriv->cfg->ops->hw_init(hw))
+               return 1;
        RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 
        /*<3> Enable Interrupt */
@@ -120,7 +121,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
 
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
 
@@ -176,7 +177,7 @@ void rtl_ips_nic_off_wq_callback(void *data)
 
        if (mac->opmode != NL80211_IFTYPE_STATION) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("not station return\n"));
+                        "not station return\n");
                return;
        }
 
@@ -207,7 +208,7 @@ void rtl_ips_nic_off_wq_callback(void *data)
                    (mac->link_state == MAC80211_NOLINK) &&
                    !mac->act_scanning) {
                        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-                                ("IPSEnter(): Turn off RF.\n"));
+                                "IPSEnter(): Turn off RF\n");
 
                        ppsc->inactive_pwrstate = ERFOFF;
                        ppsc->in_powersavemode = true;
@@ -280,8 +281,7 @@ static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw)
 
        if (ps_timediff < 2000) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("Delay enter Fw LPS for DHCP, ARP,"
-                         " or EAPOL exchanging state.\n"));
+                        "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n");
                return false;
        }
 
@@ -328,8 +328,8 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
                bool fw_current_inps;
                if (ppsc->dot11_psmode == EACTIVE) {
                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                ("FW LPS leave ps_mode:%x\n",
-                                 FW_PS_ACTIVE_MODE));
+                                "FW LPS leave ps_mode:%x\n",
+                                FW_PS_ACTIVE_MODE);
 
                        rpwm_val = 0x0C;        /* RF on */
                        fw_pwrmode = FW_PS_ACTIVE_MODE;
@@ -347,8 +347,8 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
                } else {
                        if (rtl_get_fwlps_doze(hw)) {
                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                               ("FW LPS enter ps_mode:%x\n",
-                                                ppsc->fwctrl_psmode));
+                                        "FW LPS enter ps_mode:%x\n",
+                                        ppsc->fwctrl_psmode);
 
                                rpwm_val = 0x02;        /* RF off */
                                fw_current_inps = true;
@@ -402,7 +402,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
        if (mac->cnt_after_linked >= 2) {
                if (ppsc->dot11_psmode == EACTIVE) {
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                       ("Enter 802.11 power save mode...\n"));
+                                "Enter 802.11 power save mode...\n");
 
                        rtl_lps_set_psmode(hw, EAUTOPS);
                }
@@ -434,7 +434,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
                        }
 
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("Busy Traffic,Leave 802.11 power save..\n"));
+                                "Busy Traffic,Leave 802.11 power save..\n");
 
                        rtl_lps_set_psmode(hw, EACTIVE);
                }
@@ -518,8 +518,8 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
                queue_delayed_work(rtlpriv->works.rtl_wq,
                                &rtlpriv->works.ps_work, MSECS(5));
        } else {
-               RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, "
-                               "m_buffered: %x\n", u_buffed, m_buffed));
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+                        "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed);
        }
 }
 
@@ -607,8 +607,8 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
         * sleep  = dtim_period, that meaons, we should
         * awake before every dtim */
        RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-                ("dtim_counter:%x will sleep :%d"
-                " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv));
+                "dtim_counter:%x will sleep :%d beacon_intv\n",
+                rtlpriv->psc.dtim_counter, sleep_intv);
 
        /* we tested that 40ms is enough for sw & hw sw delay */
        queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
index 84628e6041c7120b57d238dcbe8d49ee4549758d..1357856998c21b8a252c016af2a8af17c8af954b 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 539df66dce0a9ed9252e3984c5c1c9e5b9cbe123..c66f08a0524ac6f839c7b69ae7c6d6c16884d157 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -251,7 +251,7 @@ static void *rtl_rate_alloc_sta(void *ppriv,
        rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp);
        if (!rate_priv) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Unable to allocate private rc structure\n"));
+                        "Unable to allocate private rc structure\n");
                return NULL;
        }
 
index 4afa2c20adcf29870b8d97718006f448eb3ea86e..4d61761606101faa35b0a9da503dc62a409f1a75 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 9fedb1f709191638ffd4a35bf96118d094456a92..c1608cddc5299e5150a323d0a3efb7a2f0b63de6 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -398,13 +398,11 @@ int rtl_regd_init(struct ieee80211_hw *hw,
        rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan;
 
        RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
-                (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n",
-                 rtlpriv->regd.country_code));
+                "rtl: EEPROM regdomain: 0x%0x\n", rtlpriv->regd.country_code);
 
        if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) {
                RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG,
-                        (KERN_DEBUG "rtl: EEPROM indicates invalid contry code"
-                         "world wide 13 should be used\n"));
+                        "rtl: EEPROM indicates invalid contry code, world wide 13 should be used\n");
 
                rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
        }
@@ -420,8 +418,8 @@ int rtl_regd_init(struct ieee80211_hw *hw,
        }
 
        RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
-                (KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n",
-                 rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]));
+                "rtl: Country alpha2 being used: %c%c\n",
+                rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]);
 
        _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier);
 
@@ -433,7 +431,7 @@ int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-       RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, ("\n"));
+       RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n");
 
        return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
 }
index d23118938fac57035452331e4dbab04318e5aac8..70ef2f418a44134d1fd1d810afd5f4ace4705151 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 72a98cab6f699e124ac18cb0bf0a3c4d7f778634..d8d73dbb57804559d04ea92828455ed72f76c8ee 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -246,16 +246,15 @@ static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
        rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
 
        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-                ("cnt_parity_fail = %d, cnt_rate_illegal = %d, "
-                 "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
-                 falsealm_cnt->cnt_parity_fail,
-                 falsealm_cnt->cnt_rate_illegal,
-                 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail));
+                "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
+                falsealm_cnt->cnt_parity_fail,
+                falsealm_cnt->cnt_rate_illegal,
+                falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
 
        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-                ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
-                 falsealm_cnt->cnt_ofdm_fail,
-                 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all));
+                "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
+                falsealm_cnt->cnt_ofdm_fail,
+                falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
 }
 
 static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
@@ -313,8 +312,8 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
                    dm_digtable.backoff_val;
 
        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-                ("rssi_val_min = %x backoff_val %x\n",
-                 dm_digtable.rssi_val_min, dm_digtable.backoff_val));
+                "rssi_val_min = %x backoff_val %x\n",
+                dm_digtable.rssi_val_min, dm_digtable.backoff_val);
 
        rtl92c_dm_write_dig(hw);
 }
@@ -364,10 +363,9 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
        }
 
        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-                ("curmultista_connectstate = "
-                 "%x dig_ext_port_stage %x\n",
-                 dm_digtable.curmultista_connectstate,
-                 dm_digtable.dig_ext_port_stage));
+                "curmultista_connectstate = %x dig_ext_port_stage %x\n",
+                dm_digtable.curmultista_connectstate,
+                dm_digtable.dig_ext_port_stage);
 }
 
 static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
@@ -375,10 +373,9 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-                ("presta_connectstate = %x,"
-                 " cursta_connectctate = %x\n",
-                 dm_digtable.presta_connectstate,
-                 dm_digtable.cursta_connectctate));
+                "presta_connectstate = %x, cursta_connectctate = %x\n",
+                dm_digtable.presta_connectstate,
+                dm_digtable.cursta_connectctate);
 
        if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate
            || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT
@@ -464,11 +461,11 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
                dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state;
        }
 
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-                ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n",
+                dm_digtable.cur_cck_pd_state);
 
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-                ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version)));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n",
+                IS_92C_SERIAL(rtlhal->version));
 }
 
 static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
@@ -519,10 +516,13 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
        RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-                ("cur_igvalue = 0x%x, "
-                 "pre_igvalue = 0x%x, backoff_val = %d\n",
-                 dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
-                 dm_digtable.backoff_val));
+                "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",
+                dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
+                dm_digtable.backoff_val);
+
+       dm_digtable.cur_igvalue += 2;
+       if (dm_digtable.cur_igvalue > 0x3f)
+               dm_digtable.cur_igvalue = 0x3f;
 
        if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) {
                rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
@@ -676,15 +676,14 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 
        rtlpriv->dm.txpower_trackinginit = true;
        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n"));
+                "rtl92c_dm_txpower_tracking_callback_thermalmeter\n");
 
        thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
 
        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
-                 "eeprom_thermalmeter 0x%x\n",
-                 thermalvalue, rtlpriv->dm.thermalvalue,
-                 rtlefuse->eeprom_thermalmeter));
+                "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
+                thermalvalue, rtlpriv->dm.thermalvalue,
+                rtlefuse->eeprom_thermalmeter);
 
        rtl92c_phy_ap_calibrate(hw, (thermalvalue -
                                     rtlefuse->eeprom_thermalmeter));
@@ -702,10 +701,9 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
                                ofdm_index_old[0] = (u8) i;
 
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                       ("Initial pathA ele_d reg0x%x = 0x%lx, "
-                                        "ofdm_index=0x%x\n",
+                                        "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
                                         ROFDM0_XATXIQIMBALANCE,
-                                        ele_d, ofdm_index_old[0]));
+                                        ele_d, ofdm_index_old[0]);
                                break;
                        }
                }
@@ -719,11 +717,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
                                    MASKOFDM_D)) {
 
                                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
-                                          DBG_LOUD,
-                                          ("Initial pathB ele_d reg0x%x = "
-                                          "0x%lx, ofdm_index=0x%x\n",
-                                          ROFDM0_XBTXIQIMBALANCE, ele_d,
-                                          ofdm_index_old[1]));
+                                                DBG_LOUD,
+                                                "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
+                                                ROFDM0_XBTXIQIMBALANCE, ele_d,
+                                                ofdm_index_old[1]);
                                        break;
                                }
                        }
@@ -741,11 +738,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 
                                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
                                                 DBG_LOUD,
-                                                ("Initial reg0x%x = 0x%lx, "
-                                                 "cck_index=0x%x, ch 14 %d\n",
-                                                 RCCK0_TXFILTER2, temp_cck,
-                                                 cck_index_old,
-                                                 rtlpriv->dm.cck_inch14));
+                                                "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n",
+                                                RCCK0_TXFILTER2, temp_cck,
+                                                cck_index_old,
+                                                rtlpriv->dm.cck_inch14);
                                        break;
                                }
                        } else {
@@ -757,11 +753,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 
                                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
                                                 DBG_LOUD,
-                                                ("Initial reg0x%x = 0x%lx, "
-                                                 "cck_index=0x%x, ch14 %d\n",
-                                                 RCCK0_TXFILTER2, temp_cck,
-                                                 cck_index_old,
-                                                 rtlpriv->dm.cck_inch14));
+                                                "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch14 %d\n",
+                                                RCCK0_TXFILTER2, temp_cck,
+                                                cck_index_old,
+                                                rtlpriv->dm.cck_inch14);
                                        break;
                                }
                        }
@@ -790,12 +785,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
                    (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
 
                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                       ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
-                        "eeprom_thermalmeter 0x%x delta 0x%x "
-                        "delta_lck 0x%x delta_iqk 0x%x\n",
+                        "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n",
                         thermalvalue, rtlpriv->dm.thermalvalue,
                         rtlefuse->eeprom_thermalmeter, delta, delta_lck,
-                        delta_iqk));
+                        delta_iqk);
 
                if (delta_lck > 1) {
                        rtlpriv->dm.thermalvalue_lck = thermalvalue;
@@ -815,18 +808,15 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 
                        if (is2t) {
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                        ("temp OFDM_A_index=0x%x, "
-                                         "OFDM_B_index=0x%x,"
-                                         "cck_index=0x%x\n",
-                                         rtlpriv->dm.ofdm_index[0],
-                                         rtlpriv->dm.ofdm_index[1],
-                                         rtlpriv->dm.cck_index));
+                                        "temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n",
+                                        rtlpriv->dm.ofdm_index[0],
+                                        rtlpriv->dm.ofdm_index[1],
+                                        rtlpriv->dm.cck_index);
                        } else {
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                        ("temp OFDM_A_index=0x%x,"
-                                         "cck_index=0x%x\n",
-                                         rtlpriv->dm.ofdm_index[0],
-                                         rtlpriv->dm.cck_index));
+                                        "temp OFDM_A_index=0x%x, cck_index=0x%x\n",
+                                        rtlpriv->dm.ofdm_index[0],
+                                        rtlpriv->dm.cck_index);
                        }
 
                        if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
@@ -918,16 +908,13 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 
                        if (is2t) {
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                        ("new OFDM_A_index=0x%x, "
-                                         "OFDM_B_index=0x%x,"
-                                         "cck_index=0x%x\n",
-                                         ofdm_index[0], ofdm_index[1],
-                                         cck_index));
+                                        "new OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n",
+                                        ofdm_index[0], ofdm_index[1],
+                                        cck_index);
                        } else {
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                        ("new OFDM_A_index=0x%x,"
-                                         "cck_index=0x%x\n",
-                                         ofdm_index[0], cck_index));
+                                        "new OFDM_A_index=0x%x, cck_index=0x%x\n",
+                                        ofdm_index[0], cck_index);
                        }
                }
 
@@ -1085,7 +1072,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
                        rtlpriv->dm.thermalvalue = thermalvalue;
        }
 
-       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n"));
+       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n");
 
 }
 
@@ -1098,8 +1085,8 @@ static void rtl92c_dm_initialize_txpower_tracking_thermalmeter(
        rtlpriv->dm.txpower_trackinginit = false;
 
        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                ("pMgntInfo->txpower_tracking = %d\n",
-                 rtlpriv->dm.txpower_tracking));
+                "pMgntInfo->txpower_tracking = %d\n",
+                rtlpriv->dm.txpower_tracking);
 }
 
 static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
@@ -1125,12 +1112,12 @@ static void rtl92c_dm_check_txpower_tracking_thermal_meter(
                rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK,
                              0x60);
                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                        ("Trigger 92S Thermal Meter!!\n"));
+                        "Trigger 92S Thermal Meter!!\n");
                tm_trigger = 1;
                return;
        } else {
                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                        ("Schedule TxPowerTracking direct call!!\n"));
+                        "Schedule TxPowerTracking direct call!!\n");
                rtl92c_dm_txpower_tracking_directcall(hw);
                tm_trigger = 0;
        }
@@ -1169,13 +1156,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
 
        if (is_hal_stop(rtlhal)) {
                RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
-                        ("<---- driver is going to unload\n"));
+                        "<---- driver is going to unload\n");
                return;
        }
 
        if (!rtlpriv->dm.useramask) {
                RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
-                       ("<---- driver does not control rate adaptive mask\n"));
+                        "<---- driver does not control rate adaptive mask\n");
                return;
        }
 
@@ -1210,22 +1197,26 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
                        p_ra->ratr_state = DM_RATR_STA_LOW;
 
                if (p_ra->pre_ratr_state != p_ra->ratr_state) {
+                       RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld\n",
+                                rtlpriv->dm.undecorated_smoothed_pwdb);
                        RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
-                                ("RSSI = %ld\n",
-                                 rtlpriv->dm.undecorated_smoothed_pwdb));
+                                "RSSI_LEVEL = %d\n", p_ra->ratr_state);
                        RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
-                                ("RSSI_LEVEL = %d\n", p_ra->ratr_state));
-                       RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
-                                ("PreState = %d, CurState = %d\n",
-                                 p_ra->pre_ratr_state, p_ra->ratr_state));
-
-                       rcu_read_lock();
-                       sta = ieee80211_find_sta(mac->vif, mac->bssid);
+                                "PreState = %d, CurState = %d\n",
+                                p_ra->pre_ratr_state, p_ra->ratr_state);
+
+                       /* Only the PCI card uses sta in the update rate table
+                        * callback routine */
+                       if (rtlhal->interface == INTF_PCI) {
+                               rcu_read_lock();
+                               sta = ieee80211_find_sta(mac->vif, mac->bssid);
+                       }
                        rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
                                        p_ra->ratr_state);
 
                        p_ra->pre_ratr_state = p_ra->ratr_state;
-                       rcu_read_unlock();
+                       if (rtlhal->interface == INTF_PCI)
+                               rcu_read_unlock();
                }
        }
 }
@@ -1316,8 +1307,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
        if (((mac->link_state == MAC80211_NOLINK)) &&
            (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
                dm_pstable.rssi_val_min = 0;
-               RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
-                        ("Not connected to any\n"));
+               RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n");
        }
 
        if (mac->link_state == MAC80211_LINKED) {
@@ -1325,22 +1315,22 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
                        dm_pstable.rssi_val_min =
                            rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
                        RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
-                                ("AP Client PWDB = 0x%lx\n",
-                                 dm_pstable.rssi_val_min));
+                                "AP Client PWDB = 0x%lx\n",
+                                dm_pstable.rssi_val_min);
                } else {
                        dm_pstable.rssi_val_min =
                            rtlpriv->dm.undecorated_smoothed_pwdb;
                        RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
-                                ("STA Default Port PWDB = 0x%lx\n",
-                                 dm_pstable.rssi_val_min));
+                                "STA Default Port PWDB = 0x%lx\n",
+                                dm_pstable.rssi_val_min);
                }
        } else {
                dm_pstable.rssi_val_min =
                    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 
                RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
-                        ("AP Ext Port PWDB = 0x%lx\n",
-                         dm_pstable.rssi_val_min));
+                        "AP Ext Port PWDB = 0x%lx\n",
+                        dm_pstable.rssi_val_min);
        }
 
        if (IS_92C_SERIAL(rtlhal->version))
@@ -1381,7 +1371,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
        if ((mac->link_state < MAC80211_LINKED) &&
            (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-                        ("Not connected to any\n"));
+                        "Not connected to any\n");
 
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 
@@ -1394,28 +1384,28 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
                        undecorated_smoothed_pwdb =
                            rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("AP Client PWDB = 0x%lx\n",
-                                 undecorated_smoothed_pwdb));
+                                "AP Client PWDB = 0x%lx\n",
+                                undecorated_smoothed_pwdb);
                } else {
                        undecorated_smoothed_pwdb =
                            rtlpriv->dm.undecorated_smoothed_pwdb;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("STA Default Port PWDB = 0x%lx\n",
-                                 undecorated_smoothed_pwdb));
+                                "STA Default Port PWDB = 0x%lx\n",
+                                undecorated_smoothed_pwdb);
                }
        } else {
                undecorated_smoothed_pwdb =
                    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("AP Ext Port PWDB = 0x%lx\n",
-                         undecorated_smoothed_pwdb));
+                        "AP Ext Port PWDB = 0x%lx\n",
+                        undecorated_smoothed_pwdb);
        }
 
        if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+                        "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
        } else if ((undecorated_smoothed_pwdb <
                    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
                   (undecorated_smoothed_pwdb >=
@@ -1423,18 +1413,18 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
 
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+                        "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
        } else if (undecorated_smoothed_pwdb <
                   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("TXHIGHPWRLEVEL_NORMAL\n"));
+                        "TXHIGHPWRLEVEL_NORMAL\n");
        }
 
        if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
-                         rtlphy->current_channel));
+                        "PHY_SetTxPowerLevel8192S() Channel = %d\n",
+                        rtlphy->current_channel);
                rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
        }
 
index b9736d3e9a397cad52a009df793449550cd1b490..2178e3761883f831d381b9fbe850c37800a427bd 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 931d97979b04e3bcd26dbdfa1fdfa390be48db6e..c20b3c30f62ed7bfdeef57cebef888228ec07d9f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/firmware.h>
-#include <linux/export.h>
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
 #include "../rtl8192ce/reg.h"
 #include "../rtl8192ce/def.h"
 #include "fw_common.h"
+#include <linux/export.h>
 
 static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 {
@@ -172,7 +169,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        u8 *bufferPtr = (u8 *) buffer;
 
-       RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
+       RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes\n", size);
 
        if (IS_CHIP_VER_B(version)) {
                u32 pageNums, remainSize;
@@ -186,7 +183,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
 
                if (pageNums > 4) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Page numbers should not greater then 4\n"));
+                                "Page numbers should not greater then 4\n");
                }
 
                for (page = 0; page < pageNums; page++) {
@@ -219,13 +216,12 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
 
        if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
-                         value32));
+                        "chksum report faill ! REG_MCUFWDL:0x%08x\n", value32);
                return -EIO;
        }
 
        RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
-                ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
+                "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32);
 
        value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
        value32 |= MCUFWDL_RDY;
@@ -238,9 +234,8 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
                value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
                if (value32 & WINTINI_RDY) {
                        RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
-                                ("Polling FW ready success!!"
-                                " REG_MCUFWDL:0x%08x .\n",
-                                value32));
+                                "Polling FW ready success!! REG_MCUFWDL:0x%08x\n",
+                                value32);
                        return 0;
                }
 
@@ -249,7 +244,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
        } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
 
        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
+                "Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", value32);
        return -EIO;
 }
 
@@ -262,20 +257,19 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
        u32 fwsize;
        enum version_8192c version = rtlhal->version;
 
-       if (!rtlhal->pfirmware)
+       if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
                return 1;
 
-       pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
        pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
        pfwdata = (u8 *) rtlhal->pfirmware;
        fwsize = rtlhal->fwsize;
 
        if (IS_FW_HEADER_EXIST(pfwheader)) {
                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-                        ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
+                        "Firmware Version(%d), Signature(%#x),Size(%d)\n",
                         le16_to_cpu(pfwheader->version),
                         le16_to_cpu(pfwheader->signature),
-                        (uint)sizeof(struct rtl92c_firmware_header)));
+                        (uint)sizeof(struct rtl92c_firmware_header));
 
                pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
                fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
@@ -287,10 +281,10 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
 
        if (_rtl92c_fw_free_to_go(hw)) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Firmware is not ready to run!\n"));
+                        "Firmware is not ready to run!\n");
        } else {
                RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
-                        ("Firmware is ready to run!\n"));
+                        "Firmware is ready to run!\n");
        }
 
        return 0;
@@ -328,22 +322,22 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
        unsigned long flag;
        u8 idx;
 
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
 
        while (true) {
                spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
                if (rtlhal->h2c_setinprogress) {
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("H2C set in progress! Wait to set.."
-                                 "element_id(%d).\n", element_id));
+                                "H2C set in progress! Wait to set..element_id(%d)\n",
+                                element_id);
 
                        while (rtlhal->h2c_setinprogress) {
                                spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
                                                       flag);
                                h2c_waitcounter++;
                                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                        ("Wait 100 us (%d times)...\n",
-                                         h2c_waitcounter));
+                                        "Wait 100 us (%d times)...\n",
+                                        h2c_waitcounter);
                                udelay(100);
 
                                if (h2c_waitcounter > 1000)
@@ -363,8 +357,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
                wait_writeh2c_limmit--;
                if (wait_writeh2c_limmit == 0) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Write H2C fail because no trigger "
-                                 "for FW INT!\n"));
+                                "Write H2C fail because no trigger for FW INT!\n");
                        break;
                }
 
@@ -388,7 +381,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("switch case not process\n"));
+                                "switch case not processed\n");
                        break;
                }
 
@@ -398,8 +391,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
                        wait_h2c_limmit--;
                        if (wait_h2c_limmit == 0) {
                                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                        ("Wating too long for FW read "
-                                         "clear HMEBox(%d)!\n", boxnum));
+                                        "Waiting too long for FW read clear HMEBox(%d)!\n",
+                                        boxnum);
                                break;
                        }
 
@@ -408,14 +401,14 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
                        isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
                        u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("Wating for FW read clear HMEBox(%d)!!! "
-                                 "0x1BF = %2x\n", boxnum, u1b_tmp));
+                                "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
+                                boxnum, u1b_tmp);
                }
 
                if (!isfw_read) {
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("Write H2C register BOX[%d] fail!!!!! "
-                                 "Fw do not read.\n", boxnum));
+                                "Write H2C register BOX[%d] fail!!!!! Fw do not read\n",
+                                boxnum);
                        break;
                }
 
@@ -423,8 +416,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
                memset(boxextcontent, 0, sizeof(boxextcontent));
                boxcontent[0] = element_id;
                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                        ("Write element_id box_reg(%4x) = %2x\n",
-                         box_reg, element_id));
+                        "Write element_id box_reg(%4x) = %2x\n",
+                        box_reg, element_id);
 
                switch (cmd_len) {
                case 1:
@@ -493,7 +486,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("switch case not process\n"));
+                                "switch case not processed\n");
                        break;
                }
 
@@ -504,29 +497,22 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
                        rtlhal->last_hmeboxnum = 0;
 
                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                        ("pHalData->last_hmeboxnum  = %d\n",
-                         rtlhal->last_hmeboxnum));
+                        "pHalData->last_hmeboxnum  = %d\n",
+                        rtlhal->last_hmeboxnum);
        }
 
        spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
        rtlhal->h2c_setinprogress = false;
        spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
 
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
 }
 
 void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
                         u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
 {
-       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        u32 tmp_cmdbuf[2];
 
-       if (rtlhal->fw_ready == false) {
-               RT_ASSERT(false, ("return H2C cmd because of Fw "
-                                 "download fail!!!\n"));
-               return;
-       }
-
        memset(tmp_cmdbuf, 0, 8);
        memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
        _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
@@ -547,7 +533,7 @@ void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
        while (u1b_tmp & BIT(2)) {
                delay--;
                if (delay == 0) {
-                       RT_ASSERT(false, ("8051 reset fail.\n"));
+                       RT_ASSERT(false, "8051 reset fail\n");
                        break;
                }
                udelay(50);
@@ -562,7 +548,7 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
        u8 u1_h2c_set_pwrmode[3] = {0};
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 
-       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
+       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
 
        SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
        SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
@@ -570,7 +556,7 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
                                              ppsc->reg_max_lps_awakeintvl);
 
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-                     "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
+                     "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode",
                      u1_h2c_set_pwrmode, 3);
        rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
 
@@ -780,14 +766,16 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
        totalpacketlen = TOTAL_RESERVED_PKT_LEN;
 
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
-                     "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+                     "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
                      &reserved_page_packet[0], totalpacketlen);
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-                     "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+                     "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
                      u1RsvdPageLoc, 3);
 
 
        skb = dev_alloc_skb(totalpacketlen);
+       if (!skb)
+               return;
        memcpy((u8 *) skb_put(skb, totalpacketlen),
               &reserved_page_packet, totalpacketlen);
 
@@ -798,15 +786,14 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
 
        if (dlok) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("Set RSVD page location to Fw.\n"));
+                        "Set RSVD page location to Fw\n");
                RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-                               "H2C_RSVDPAGE:\n",
-                               u1RsvdPageLoc, 3);
+                             "H2C_RSVDPAGE", u1RsvdPageLoc, 3);
                rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
                                    sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
        } else
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
+                        "Set RSVD page location to Fw FAIL!!!!!!\n");
 }
 EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt);
 
index cec5a3a1cc5338ab0f136c933b3073cbbd02dc53..780ea5b1e24c4ae37e5b281b6c9fad6492c2a773 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 605ff191aeb7f437c756aba158c3a5daa49726ce..918b1d129e77cc48e0b936b207bfcd0d861489c5 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,8 @@
  *
  *****************************************************************************/
 
-#include <linux/module.h>
 #include "../wifi.h"
+#include <linux/module.h>
 
 
 MODULE_AUTHOR("lizhaoming      <chaoming_li@realsil.com.cn>");
index 1f07558debf2b05b41bad4391b8fbccae9a19c68..cdd71f5e77ac8d0b6cfd662806baf9e8e399b6f1 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -42,16 +42,15 @@ u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 returnvalue, originalvalue, bitshift;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-                                              "bitmask(%#x)\n", regaddr,
-                                              bitmask));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
+                regaddr, bitmask);
        originalvalue = rtl_read_dword(rtlpriv, regaddr);
        bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
        returnvalue = (originalvalue & bitmask) >> bitshift;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x "
-                                              "Addr[0x%x]=0x%x\n", bitmask,
-                                              regaddr, originalvalue));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
+                bitmask, regaddr, originalvalue);
 
        return returnvalue;
 
@@ -64,9 +63,9 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 originalvalue, bitshift;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-                                              " data(%#x)\n", regaddr, bitmask,
-                                              data));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+                regaddr, bitmask, data);
 
        if (bitmask != MASKDWORD) {
                originalvalue = rtl_read_dword(rtlpriv, regaddr);
@@ -76,9 +75,9 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
 
        rtl_write_dword(rtlpriv, regaddr, data);
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-                                              " data(%#x)\n", regaddr, bitmask,
-                                              data));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+                regaddr, bitmask, data);
 
 }
 EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);
@@ -86,7 +85,7 @@ EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);
 u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
                                  enum radio_path rfpath, u32 offset)
 {
-       RT_ASSERT(false, ("deprecated!\n"));
+       RT_ASSERT(false, "deprecated!\n");
        return 0;
 
 }
@@ -96,7 +95,7 @@ void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
                                    enum radio_path rfpath, u32 offset,
                                    u32 data)
 {
-       RT_ASSERT(false, ("deprecated!\n"));
+       RT_ASSERT(false, "deprecated!\n");
 }
 EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write);
 
@@ -114,7 +113,7 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
        offset &= 0x3f;
        newoffset = offset;
        if (RT_CANNOT_IO(hw)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
                return 0xFFFFFFFF;
        }
        tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
@@ -144,9 +143,8 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
        else
                retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
                                         BLSSIREADBACKDATA);
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
-                                              rfpath, pphyreg->rflssi_readback,
-                                              retvalue));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
+                rfpath, pphyreg->rflssi_readback, retvalue);
        return retvalue;
 }
 EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read);
@@ -162,16 +160,15 @@ void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 
        if (RT_CANNOT_IO(hw)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
                return;
        }
        offset &= 0x3f;
        newoffset = offset;
        data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
        rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
-                                              rfpath, pphyreg->rf3wire_offset,
-                                              data_and_addr));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
+                rfpath, pphyreg->rf3wire_offset, data_and_addr);
 }
 EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write);
 
@@ -180,7 +177,7 @@ u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask)
        u32 i;
 
        for (i = 0; i <= 31; i++) {
-               if (((bitmask >> i) & 0x1) == 1)
+               if ((bitmask >> i) & 0x1)
                        break;
        }
        return i;
@@ -216,16 +213,16 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
        bool rtstatus;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
        rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
                                                 BASEBAND_CONFIG_PHY_REG);
        if (rtstatus != true) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
                return false;
        }
        if (rtlphy->rf_type == RF_1T2R) {
                _rtl92c_phy_bb_config_1t(hw);
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
        }
        if (rtlefuse->autoload_failflag == false) {
                rtlphy->pwrgroup_cnt = 0;
@@ -233,13 +230,13 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
                                                   BASEBAND_CONFIG_PHY_REG);
        }
        if (rtstatus != true) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
                return false;
        }
        rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
                                                 BASEBAND_CONFIG_AGC_TAB);
        if (rtstatus != true) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
                return false;
        }
        rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
@@ -256,121 +253,51 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       int index;
+
+       if (regaddr == RTXAGC_A_RATE18_06)
+               index = 0;
+       else if (regaddr == RTXAGC_A_RATE54_24)
+               index = 1;
+       else if (regaddr == RTXAGC_A_CCK1_MCS32)
+               index = 6;
+       else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00)
+               index = 7;
+       else if (regaddr == RTXAGC_A_MCS03_MCS00)
+               index = 2;
+       else if (regaddr == RTXAGC_A_MCS07_MCS04)
+               index = 3;
+       else if (regaddr == RTXAGC_A_MCS11_MCS08)
+               index = 4;
+       else if (regaddr == RTXAGC_A_MCS15_MCS12)
+               index = 5;
+       else if (regaddr == RTXAGC_B_RATE18_06)
+               index = 8;
+       else if (regaddr == RTXAGC_B_RATE54_24)
+               index = 9;
+       else if (regaddr == RTXAGC_B_CCK1_55_MCS32)
+               index = 14;
+       else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff)
+               index = 15;
+       else if (regaddr == RTXAGC_B_MCS03_MCS00)
+               index = 10;
+       else if (regaddr == RTXAGC_B_MCS07_MCS04)
+               index = 11;
+       else if (regaddr == RTXAGC_B_MCS11_MCS08)
+               index = 12;
+       else if (regaddr == RTXAGC_B_MCS15_MCS12)
+               index = 13;
+       else
+               return;
 
-       if (regaddr == RTXAGC_A_RATE18_06) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0]));
-       }
-       if (regaddr == RTXAGC_A_RATE54_24) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1]));
-       }
-       if (regaddr == RTXAGC_A_CCK1_MCS32) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6]));
-       }
-       if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7]));
-       }
-       if (regaddr == RTXAGC_A_MCS03_MCS00) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2]));
-       }
-       if (regaddr == RTXAGC_A_MCS07_MCS04) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3]));
-       }
-       if (regaddr == RTXAGC_A_MCS11_MCS08) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4]));
-       }
-       if (regaddr == RTXAGC_A_MCS15_MCS12) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5]));
-       }
-       if (regaddr == RTXAGC_B_RATE18_06) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8]));
-       }
-       if (regaddr == RTXAGC_B_RATE54_24) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]));
-       }
-       if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]));
-       }
-       if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]));
-       }
-       if (regaddr == RTXAGC_B_MCS03_MCS00) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]));
-       }
-       if (regaddr == RTXAGC_B_MCS07_MCS04) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]));
-       }
-       if (regaddr == RTXAGC_B_MCS11_MCS08) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]));
-       }
-       if (regaddr == RTXAGC_B_MCS15_MCS12) {
-               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13]));
+       rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index] = data;
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n",
+                rtlphy->pwrgroup_cnt, index,
+                rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index]);
 
+       if (index == 13)
                rtlphy->pwrgroup_cnt++;
-       }
 }
 EXPORT_SYMBOL(_rtl92c_store_pwrIndex_diffrate_offset);
 
@@ -389,12 +316,11 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
            (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                ("Default initial gain (c50=0x%x, "
-                 "c58=0x%x, c60=0x%x, c68=0x%x\n",
-                 rtlphy->default_initialgain[0],
-                 rtlphy->default_initialgain[1],
-                 rtlphy->default_initialgain[2],
-                 rtlphy->default_initialgain[3]));
+                "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
+                rtlphy->default_initialgain[0],
+                rtlphy->default_initialgain[1],
+                rtlphy->default_initialgain[2],
+                rtlphy->default_initialgain[3]);
 
        rtlphy->framesync = (u8) rtl_get_bbreg(hw,
                                               ROFDM0_RXDETECTOR3, MASKBYTE0);
@@ -402,8 +328,8 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
                                              ROFDM0_RXDETECTOR2, MASKDWORD);
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                ("Default framesync (0x%x) = 0x%x\n",
-                 ROFDM0_RXDETECTOR3, rtlphy->framesync));
+                "Default framesync (0x%x) = 0x%x\n",
+                ROFDM0_RXDETECTOR3, rtlphy->framesync);
 }
 
 void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
@@ -615,8 +541,8 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
        else
                ofdmtxpwridx = 0;
        RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
-                ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
-                 power_indbm, ccktxpwridx, ofdmtxpwridx));
+                "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
+                power_indbm, ccktxpwridx, ofdmtxpwridx);
        for (idx = 0; idx < 14; idx++) {
                for (rf_path = 0; rf_path < 2; rf_path++) {
                        rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
@@ -710,7 +636,7 @@ void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Unknown Scan Backup operation.\n"));
+                                "Unknown Scan Backup operation\n");
                        break;
                }
        }
@@ -732,7 +658,7 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
                rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw);
        } else {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("FALSE driver sleep or unload\n"));
+                        "FALSE driver sleep or unload\n");
                rtlphy->set_bwmode_inprogress = false;
                rtlphy->current_chan_bw = tmp_bw;
        }
@@ -747,7 +673,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
        u32 delay;
 
        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-                ("switch to channel%d\n", rtlphy->current_channel));
+                "switch to channel%d\n", rtlphy->current_channel);
        if (is_hal_stop(rtlhal))
                return;
        do {
@@ -765,7 +691,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
                }
                break;
        } while (true);
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 }
 EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback);
 
@@ -780,19 +706,18 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
        if (rtlphy->set_bwmode_inprogress)
                return 0;
        RT_ASSERT((rtlphy->current_channel <= 14),
-                 ("WIRELESS_MODE_G but channel>14"));
+                 "WIRELESS_MODE_G but channel>14\n");
        rtlphy->sw_chnl_inprogress = true;
        rtlphy->sw_chnl_stage = 0;
        rtlphy->sw_chnl_step = 0;
        if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
                rtl92c_phy_sw_chnl_callback(hw);
                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
-                        ("sw_chnl_inprogress false schdule workitem\n"));
+                        "sw_chnl_inprogress false schdule workitem\n");
                rtlphy->sw_chnl_inprogress = false;
        } else {
                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
-                        ("sw_chnl_inprogress false driver sleep or"
-                         " unload\n"));
+                        "sw_chnl_inprogress false driver sleep or unload\n");
                rtlphy->sw_chnl_inprogress = false;
        }
        return 1;
@@ -807,7 +732,7 @@ static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
        struct swchnlcmd *pcmd;
 
        if (cmdtable == NULL) {
-               RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+               RT_ASSERT(false, "cmdtable cannot be NULL\n");
                return false;
        }
 
@@ -853,7 +778,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
        rfdependcmdcnt = 0;
 
        RT_ASSERT((channel >= 1 && channel <= 14),
-                 ("illegal channel for Zebra: %d\n", channel));
+                 "invalid channel for Zebra: %d\n", channel);
 
        _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
                                         MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
@@ -916,7 +841,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("switch case not process\n"));
+                                "switch case not processed\n");
                        break;
                }
 
@@ -1920,23 +1845,23 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
        bool postprocessing = false;
 
        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-                ("-->IO Cmd(%#x), set_io_inprogress(%d)\n",
-                 iotype, rtlphy->set_io_inprogress));
+                "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
+                iotype, rtlphy->set_io_inprogress);
        do {
                switch (iotype) {
                case IO_CMD_RESUME_DM_BY_SCAN:
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-                                ("[IO CMD] Resume DM after scan.\n"));
+                                "[IO CMD] Resume DM after scan\n");
                        postprocessing = true;
                        break;
                case IO_CMD_PAUSE_DM_BY_SCAN:
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-                                ("[IO CMD] Pause DM before scan.\n"));
+                                "[IO CMD] Pause DM before scan\n");
                        postprocessing = true;
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("switch case not process\n"));
+                                "switch case not processed\n");
                        break;
                }
        } while (false);
@@ -1947,7 +1872,7 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
                return false;
        }
        rtl92c_phy_set_io(hw);
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
        return true;
 }
 EXPORT_SYMBOL(rtl92c_phy_set_io_cmd);
@@ -1958,8 +1883,8 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw)
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-                ("--->Cmd(%#x), set_io_inprogress(%d)\n",
-                 rtlphy->current_io_type, rtlphy->set_io_inprogress));
+                "--->Cmd(%#x), set_io_inprogress(%d)\n",
+                rtlphy->current_io_type, rtlphy->set_io_inprogress);
        switch (rtlphy->current_io_type) {
        case IO_CMD_RESUME_DM_BY_SCAN:
                dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
@@ -1973,12 +1898,12 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        rtlphy->set_io_inprogress = false;
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-                ("<---(%#x)\n", rtlphy->current_io_type));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n",
+                rtlphy->current_io_type);
 }
 EXPORT_SYMBOL(rtl92c_phy_set_io);
 
@@ -2018,7 +1943,7 @@ void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw)
                rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-                        ("Switch RF timeout !!!.\n"));
+                        "Switch RF timeout !!!\n");
                return;
        }
        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
index 9a264c0d6127da662691d0a790997b5982d838b9..cec10d696492ab4055a2982ffadb1202494eea5e 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 9fc804d89d65984dffb70b047e3ca21a151033f8..04c3aef8a4f62e178fbac155a956c64c529b97c8 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 2df33e53e15a53ac9a5b68e9ef0524e376a52361..27b3af880d96ed235e163bbfb3defa53a669f3b5 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -54,7 +54,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw)
        if ((mac->link_state < MAC80211_LINKED) &&
            (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-                        ("Not connected to any\n"));
+                        "Not connected to any\n");
 
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 
@@ -67,28 +67,28 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw)
                        undecorated_smoothed_pwdb =
                            rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("AP Client PWDB = 0x%lx\n",
-                                 undecorated_smoothed_pwdb));
+                                "AP Client PWDB = 0x%lx\n",
+                                undecorated_smoothed_pwdb);
                } else {
                        undecorated_smoothed_pwdb =
                            rtlpriv->dm.undecorated_smoothed_pwdb;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("STA Default Port PWDB = 0x%lx\n",
-                                 undecorated_smoothed_pwdb));
+                                "STA Default Port PWDB = 0x%lx\n",
+                                undecorated_smoothed_pwdb);
                }
        } else {
                undecorated_smoothed_pwdb =
                    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("AP Ext Port PWDB = 0x%lx\n",
-                         undecorated_smoothed_pwdb));
+                        "AP Ext Port PWDB = 0x%lx\n",
+                        undecorated_smoothed_pwdb);
        }
 
        if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+                        "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
        } else if ((undecorated_smoothed_pwdb <
                    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
                   (undecorated_smoothed_pwdb >=
@@ -96,18 +96,18 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw)
 
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+                        "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
        } else if (undecorated_smoothed_pwdb <
                   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("TXHIGHPWRLEVEL_NORMAL\n"));
+                        "TXHIGHPWRLEVEL_NORMAL\n");
        }
 
        if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
-                         rtlphy->current_channel));
+                        "PHY_SetTxPowerLevel8192S() Channel = %d\n",
+                        rtlphy->current_channel);
                rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
        }
 
index 07dd9552e82f559344a239ce7b46a91c3d686708..26747fa8600507042ee3f3d7cbac169431b7457c 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index a3deaefa788c1c30f630f57bdb12c6d09007d46d..48c7b5d3fc5b17e68b7fa7f5de2dd56faa60b36e 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -141,7 +141,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                }
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
 }
@@ -207,7 +207,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                        u8 e_aci;
 
                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                ("HW_VAR_SLOT_TIME %x\n", val[0]));
+                                "HW_VAR_SLOT_TIME %x\n", val[0]);
 
                        rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
 
@@ -246,8 +246,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                *val = min_spacing_to_set;
 
                                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                        ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
-                                         mac->min_space_cfg));
+                                        "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+                                        mac->min_space_cfg);
 
                                rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
                                               mac->min_space_cfg);
@@ -261,8 +261,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                        mac->min_space_cfg |= (density_to_set << 3);
 
                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
-                                 mac->min_space_cfg));
+                                "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+                                mac->min_space_cfg);
 
                        rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
                                       mac->min_space_cfg);
@@ -310,8 +310,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                }
 
                                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                        ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
-                                         factor_toset));
+                                        "Set HW_VAR_AMPDU_FACTOR: %#x\n",
+                                        factor_toset);
                        }
                        break;
                }
@@ -348,8 +348,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                        break;
                                default:
                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                                ("HW_VAR_ACM_CTRL acm set "
-                                                 "failed: eACI is %d\n", acm));
+                                                "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
+                                                acm);
                                        break;
                                }
                        } else {
@@ -365,14 +365,14 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                        break;
                                default:
                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                                ("switch case not process\n"));
+                                                "switch case not processed\n");
                                        break;
                                }
                        }
 
                        RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
-                                ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
-                                 "Write 0x%X\n", acm_ctrl));
+                                "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
+                                acm_ctrl);
                        rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
                        break;
                }
@@ -507,8 +507,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 
                }
        default:
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
-                                                       "not process\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        "switch case not processed\n");
                break;
        }
 }
@@ -530,8 +530,8 @@ static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
 
                if (count > POLLING_LLT_THRESHOLD) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Failed to polling write LLT done at "
-                                 "address %d!\n", address));
+                                "Failed to polling write LLT done at address %d!\n",
+                                address);
                        status = false;
                        break;
                }
@@ -669,18 +669,15 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)
        udelay(2);
 
        retry = 0;
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n",
-                                               rtl_read_dword(rtlpriv, 0xEC),
-                                               bytetmp));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n",
+                rtl_read_dword(rtlpriv, 0xEC), bytetmp);
 
        while ((bytetmp & BIT(0)) && retry < 1000) {
                retry++;
                udelay(50);
                bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n",
-                                                       rtl_read_dword(rtlpriv,
-                                                                      0xEC),
-                                                       bytetmp));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n",
+                        rtl_read_dword(rtlpriv, 0xEC), bytetmp);
                udelay(50);
        }
 
@@ -864,13 +861,13 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw)
        u8 sec_reg_value;
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
-                 rtlpriv->sec.pairwise_enc_algorithm,
-                 rtlpriv->sec.group_enc_algorithm));
+                "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
+                rtlpriv->sec.pairwise_enc_algorithm,
+                rtlpriv->sec.group_enc_algorithm);
 
        if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("not open "
-                                                       "hw encryption\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+                        "not open hw encryption\n");
                return;
        }
 
@@ -886,7 +883,7 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw)
        rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
 
        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                ("The SECR-value %x\n", sec_reg_value));
+                "The SECR-value %x\n", sec_reg_value);
 
        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
 
@@ -910,7 +907,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
        rtlpriv->intf_ops->disable_aspm(hw);
        rtstatus = _rtl92ce_init_mac(hw);
        if (rtstatus != true) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
                err = 1;
                return err;
        }
@@ -918,13 +915,9 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
        err = rtl92c_download_fw(hw);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("Failed to download FW. Init HW "
-                         "without FW now..\n"));
+                        "Failed to download FW. Init HW without FW now..\n");
                err = 1;
-               rtlhal->fw_ready = false;
                return err;
-       } else {
-               rtlhal->fw_ready = true;
        }
 
        rtlhal->last_hmeboxnum = 0;
@@ -968,12 +961,12 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
        tmp_u1b = efuse_read_1byte(hw, 0x1FA);
        if (!(tmp_u1b & BIT(0))) {
                rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path A\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n");
        }
 
        if (!(tmp_u1b & BIT(1)) && is92c) {
                rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05);
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path B\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path B\n");
        }
 
        if (!(tmp_u1b & BIT(4))) {
@@ -982,7 +975,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
                rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
                udelay(10);
                rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
        }
        rtl92c_dm_init(hw);
        rtlpci->being_init_adapter = false;
@@ -995,6 +988,7 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
        enum version_8192c version = VERSION_UNKNOWN;
        u32 value32;
+       const char *versionid;
 
        value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
        if (value32 & TRP_VAUX_EN) {
@@ -1007,27 +1001,25 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
 
        switch (version) {
        case VERSION_B_CHIP_92C:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Chip Version ID: VERSION_B_CHIP_92C.\n"));
+               versionid = "B_CHIP_92C";
                break;
        case VERSION_B_CHIP_88C:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Chip Version ID: VERSION_B_CHIP_88C.\n"));
+               versionid = "B_CHIP_88C";
                break;
        case VERSION_A_CHIP_92C:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Chip Version ID: VERSION_A_CHIP_92C.\n"));
+               versionid = "A_CHIP_92C";
                break;
        case VERSION_A_CHIP_88C:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Chip Version ID: VERSION_A_CHIP_88C.\n"));
+               versionid = "A_CHIP_88C";
                break;
        default:
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Chip Version ID: Unknown. Bug?\n"));
+               versionid = "Unknown. Bug?";
                break;
        }
 
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                "Chip Version ID: %s\n", versionid);
+
        switch (version & 0x3) {
        case CHIP_88C:
                rtlphy->rf_type = RF_1T1R;
@@ -1041,13 +1033,12 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
        default:
                rtlphy->rf_type = RF_1T1R;
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("ERROR RF_Type is set!!"));
+                        "ERROR RF_Type is set!!\n");
                break;
        }
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
-                 "RF_2T2R" : "RF_1T1R"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n",
+                rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R");
 
        return version;
 }
@@ -1069,8 +1060,8 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
                _rtl92ce_disable_bcn_sub_func(hw);
        } else {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("Set HW_VAR_MEDIA_STATUS: "
-                         "No such media status(%x).\n", type));
+                        "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n",
+                        type);
        }
 
        switch (type) {
@@ -1078,27 +1069,27 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
                bt_msr |= MSR_NOLINK;
                ledaction = LED_CTL_LINK;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to NO LINK!\n"));
+                        "Set Network type to NO LINK!\n");
                break;
        case NL80211_IFTYPE_ADHOC:
                bt_msr |= MSR_ADHOC;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to Ad Hoc!\n"));
+                        "Set Network type to Ad Hoc!\n");
                break;
        case NL80211_IFTYPE_STATION:
                bt_msr |= MSR_INFRA;
                ledaction = LED_CTL_LINK;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to STA!\n"));
+                        "Set Network type to STA!\n");
                break;
        case NL80211_IFTYPE_AP:
                bt_msr |= MSR_AP;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to AP!\n"));
+                        "Set Network type to AP!\n");
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Network type %d not support!\n", type));
+                        "Network type %d not supported!\n", type);
                return 1;
                break;
 
@@ -1171,7 +1162,7 @@ void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci)
                rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
                break;
        default:
-               RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+               RT_ASSERT(false, "invalid aci: %d !\n", aci);
                break;
        }
 }
@@ -1199,7 +1190,6 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
-       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        u8 u1b_tmp;
        u32 u4b_tmp;
 
@@ -1210,7 +1200,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
        rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0);
-       if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready)
+       if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7))
                rtl92c_firmware_selfreset(hw);
        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51);
        rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
@@ -1300,7 +1290,7 @@ void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw)
        u16 bcn_interval = mac->beacon_interval;
 
        RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
-                ("beacon_interval:%d\n", bcn_interval));
+                "beacon_interval:%d\n", bcn_interval);
        rtl92ce_disable_interrupt(hw);
        rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
        rtl92ce_enable_interrupt(hw);
@@ -1312,8 +1302,8 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
-       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-                ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n",
+                add_msr, rm_msr);
 
        if (add_msr)
                rtlpci->irq_mask[0] |= add_msr;
@@ -1367,25 +1357,24 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
        for (rf_path = 0; rf_path < 2; rf_path++)
                for (i = 0; i < 3; i++)
                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-                               ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
-                                i,
-                                rtlefuse->
-                                eeprom_chnlarea_txpwr_cck[rf_path][i]));
+                               "RF(%d) EEPROM CCK Area(%d) = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->
+                               eeprom_chnlarea_txpwr_cck[rf_path][i]);
        for (rf_path = 0; rf_path < 2; rf_path++)
                for (i = 0; i < 3; i++)
                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-                               ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->
-                                eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]));
+                               "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->
+                               eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]);
        for (rf_path = 0; rf_path < 2; rf_path++)
                for (i = 0; i < 3; i++)
                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-                               ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->
-                                eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path]
-                                [i]));
+                               "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->
+                               eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]);
 
        for (rf_path = 0; rf_path < 2; rf_path++) {
                for (i = 0; i < 14; i++) {
@@ -1416,11 +1405,11 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 
                for (i = 0; i < 14; i++) {
                        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                               ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
-                                "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
-                                rtlefuse->txpwrlevel_cck[rf_path][i],
-                                rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
-                                rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
+                               "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
+                               rf_path, i,
+                               rtlefuse->txpwrlevel_cck[rf_path][i],
+                               rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
+                               rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
                }
        }
 
@@ -1457,13 +1446,13 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
                        }
 
                        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                               ("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->pwrgroup_ht20[rf_path][i]));
+                               "RF-%d pwrgroup_ht20[%d] = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->pwrgroup_ht20[rf_path][i]);
                        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                               ("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->pwrgroup_ht40[rf_path][i]));
+                               "RF-%d pwrgroup_ht40[%d] = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->pwrgroup_ht40[rf_path][i]);
                }
        }
 
@@ -1502,27 +1491,27 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
+                       "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
+                       "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
+                       "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
+                       "RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
 
        if (!autoload_fail)
                rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
        else
                rtlefuse->eeprom_regulatory = 0;
        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-               ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+               "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
 
        if (!autoload_fail) {
                rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
@@ -1531,10 +1520,9 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
                rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI;
                rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI;
        }
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-               ("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
-                rtlefuse->eeprom_tssi[RF90_PATH_A],
-                rtlefuse->eeprom_tssi[RF90_PATH_B]));
+       RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
+               rtlefuse->eeprom_tssi[RF90_PATH_A],
+               rtlefuse->eeprom_tssi[RF90_PATH_B]);
 
        if (!autoload_fail)
                tempval = hwinfo[EEPROM_THERMAL_METER];
@@ -1547,7 +1535,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 
        rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-               ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
+               "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
 }
 
 static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
@@ -1567,19 +1555,19 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
                       HWSET_MAX_SIZE);
        } else if (rtlefuse->epromtype == EEPROM_93C46) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("RTL819X Not boot from eeprom, check it !!"));
+                        "RTL819X Not boot from eeprom, check it !!");
        }
 
-       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
+       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
                      hwinfo, HWSET_MAX_SIZE);
 
        eeprom_id = *((u16 *)&hwinfo[0]);
        if (eeprom_id != RTL8190_EEPROM_ID) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+                        "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
                rtlefuse->autoload_failflag = true;
        } else {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
                rtlefuse->autoload_failflag = false;
        }
 
@@ -1591,8 +1579,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
                *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
        }
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                ("%pM\n", rtlefuse->dev_addr));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);
 
        _rtl92ce_read_txpower_info_from_hwpg(hw,
                                             rtlefuse->autoload_failflag,
@@ -1608,7 +1595,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
        rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+                "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
 
        /* set channel paln to world wide 13 */
        rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
@@ -1662,7 +1649,7 @@ static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw)
                break;
        }
        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                ("RT Customized ID: 0x%02X\n", rtlhal->oem_id));
+                "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
 }
 
 void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw)
@@ -1679,22 +1666,22 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw)
        else
                rtlpriv->dm.rfpath_rxenable[0] =
                    rtlpriv->dm.rfpath_rxenable[1] = true;
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n",
-                                               rtlhal->version));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
+                rtlhal->version);
        tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
        if (tmp_u1b & BIT(4)) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
                rtlefuse->epromtype = EEPROM_93C46;
        } else {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
                rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
        }
        if (tmp_u1b & BIT(5)) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
                rtlefuse->autoload_failflag = false;
                _rtl92ce_read_adapter_info(hw);
        } else {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
        }
        _rtl92ce_hal_customized_behavior(hw);
 }
@@ -1790,8 +1777,8 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw,
 
        rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
 
-       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
-                ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+                rtl_read_dword(rtlpriv, REG_ARFR0));
 }
 
 static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
@@ -1919,16 +1906,15 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
                break;
        }
        RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
-                ("ratr_bitmap :%x\n", ratr_bitmap));
+                "ratr_bitmap :%x\n", ratr_bitmap);
        *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) |
                                     (ratr_index << 28));
        rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
-       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, "
-                                                "ratr_val:%x, %x:%x:%x:%x:%x\n",
-                                                ratr_index, ratr_bitmap,
-                                                rate_mask[0], rate_mask[1],
-                                                rate_mask[2], rate_mask[3],
-                                                rate_mask[4]));
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+                "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
+                ratr_index, ratr_bitmap,
+                rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3],
+                rate_mask[4]);
        rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
 
        if (macid != 0)
@@ -1994,7 +1980,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
 
        if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                        ("GPIOChangeRF  - HW Radio ON, RF ON\n"));
+                        "GPIOChangeRF  - HW Radio ON, RF ON\n");
 
                e_rfpowerstate_toset = ERFON;
                ppsc->hwradiooff = false;
@@ -2002,7 +1988,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
        } else if ((ppsc->hwradiooff == false)
                   && (e_rfpowerstate_toset == ERFOFF)) {
                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                        ("GPIOChangeRF  - HW Radio OFF, RF OFF\n"));
+                        "GPIOChangeRF  - HW Radio OFF, RF OFF\n");
 
                e_rfpowerstate_toset = ERFOFF;
                ppsc->hwradiooff = true;
@@ -2053,7 +2039,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
                u8 cam_offset = 0;
                u8 clear_number = 5;
 
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
 
                for (idx = 0; idx < clear_number; idx++) {
                        rtl_cam_mark_invalid(hw, cam_offset + idx);
@@ -2081,8 +2067,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
                        enc_algo = CAM_AES;
                        break;
                default:
-                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
-                                       "not process\n"));
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                                "switch case not processed\n");
                        enc_algo = CAM_TKIP;
                        break;
                }
@@ -2100,9 +2086,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
                                                                 p_macaddr);
                                        if (entry_id >=  TOTAL_CAM_ENTRY) {
                                                RT_TRACE(rtlpriv, COMP_SEC,
-                                                    DBG_EMERG,
-                                                    ("Can not find free hw"
-                                                    " security cam entry\n"));
+                                                        DBG_EMERG,
+                                                        "Can not find free hw security cam entry\n");
                                                return;
                                        }
                                } else {
@@ -2116,31 +2101,31 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
 
                if (rtlpriv->sec.key_len[key_index] == 0) {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("delete one entry, entry_id is %d\n",
-                                entry_id));
+                                "delete one entry, entry_id is %d\n",
+                                entry_id);
                        if (mac->opmode == NL80211_IFTYPE_AP)
                                rtl_cam_del_entry(hw, p_macaddr);
                        rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
                } else {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("The insert KEY length is %d\n",
-                                 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+                                "The insert KEY length is %d\n",
+                                rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("The insert KEY  is %x %x\n",
-                                 rtlpriv->sec.key_buf[0][0],
-                                 rtlpriv->sec.key_buf[0][1]));
+                                "The insert KEY is %x %x\n",
+                                rtlpriv->sec.key_buf[0][0],
+                                rtlpriv->sec.key_buf[0][1]);
 
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("add one entry\n"));
+                                "add one entry\n");
                        if (is_pairwise) {
                                RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
-                                             "Pairwiase Key content :",
+                                             "Pairwise Key content",
                                              rtlpriv->sec.pairwise_key,
                                              rtlpriv->sec.
                                              key_len[PAIRWISE_KEYIDX]);
 
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                        ("set Pairwiase key\n"));
+                                        "set Pairwise key\n");
 
                                rtl_cam_add_one_entry(hw, macaddr, key_index,
                                                      entry_id, enc_algo,
@@ -2149,7 +2134,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
                                                      key_buf[key_index]);
                        } else {
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                        ("set group key\n"));
+                                        "set group key\n");
 
                                if (mac->opmode == NL80211_IFTYPE_ADHOC) {
                                        rtl_cam_add_one_entry(hw,
index 07dbe3e340a5579c4af1c55ca805eb69dc649372..52a3aea9b3deecf8052293010ab3d95947d5cfb9 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 28a1a707d09ceb275f5266adc5c7e9d8d711181b..8283e9b27639f5bd95350fd09652ccfded1888ed 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -45,8 +45,8 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
        u8 ledcfg;
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-                ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+                REG_LEDCFG2, pled->ledpin);
 
        ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
 
@@ -62,7 +62,7 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        pled->ledon = true;
@@ -74,8 +74,8 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
        u8 ledcfg;
 
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-                ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+                REG_LEDCFG2, pled->ledpin);
 
        ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
 
@@ -97,7 +97,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        pled->ledon = false;
@@ -145,7 +145,7 @@ void rtl92ce_led_control(struct ieee80211_hw *hw,
             ledaction == LED_CTL_POWER_ON)) {
                return;
        }
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d.\n",
-                               ledaction));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n",
+                ledaction);
        _rtl92ce_sw_led_control(hw, ledaction);
 }
index 7dfccea2095b016705f60174c4f3ee7ad91ab49e..c5761066d3835118ddf9f69a5bf4130e2bef4bea 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 3b585aadabfcdae61bc7aed6b8b2694266ed1f14..c64daf25566a90b7e4bd1e8e11363e28bd1f74c0 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -47,9 +47,9 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
        u32 original_value, readback_value, bitshift;
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-                                              "rfpath(%#x), bitmask(%#x)\n",
-                                              regaddr, rfpath, bitmask));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
+                regaddr, rfpath, bitmask);
 
        spin_lock(&rtlpriv->locks.rf_lock);
 
@@ -67,9 +67,8 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
        spin_unlock(&rtlpriv->locks.rf_lock);
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-                ("regaddr(%#x), rfpath(%#x), "
-                 "bitmask(%#x), original_value(%#x)\n",
-                 regaddr, rfpath, bitmask, original_value));
+                "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
+                regaddr, rfpath, bitmask, original_value);
 
        return readback_value;
 }
@@ -121,8 +120,8 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
        u32 original_value, bitshift;
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-                ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
-                 regaddr, bitmask, data, rfpath));
+                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+                regaddr, bitmask, data, rfpath);
 
        spin_lock(&rtlpriv->locks.rf_lock);
 
@@ -153,10 +152,9 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
 
        spin_unlock(&rtlpriv->locks.rf_lock);
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-                                              "bitmask(%#x), data(%#x), "
-                                              "rfpath(%#x)\n", regaddr,
-                                              bitmask, data, rfpath));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+                regaddr, bitmask, data, rfpath);
 }
 
 static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
@@ -166,11 +164,10 @@ static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
        u32 arraylength;
        u32 *ptrarray;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
        arraylength = MAC_2T_ARRAYLENGTH;
        ptrarray = RTL8192CEMAC_2T_ARRAY;
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                ("Img:RTL8192CEMAC_2T_ARRAY\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n");
        for (i = 0; i < arraylength; i = i + 2)
                rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
        return true;
@@ -215,10 +212,9 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
                                      phy_regarray_table[i + 1]);
                        udelay(1);
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                                ("The phy_regarray_table[0] is %x"
-                                 " Rtl819XPHY_REGArray[1] is %x\n",
-                                 phy_regarray_table[i],
-                                 phy_regarray_table[i + 1]));
+                                "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
+                                phy_regarray_table[i],
+                                phy_regarray_table[i + 1]);
                }
        } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
                for (i = 0; i < agctab_arraylen; i = i + 2) {
@@ -226,10 +222,9 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
                                      agctab_array_table[i + 1]);
                        udelay(1);
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                                ("The agctab_array_table[0] is "
-                                 "%x Rtl819XPHY_REGArray[1] is %x\n",
-                                 agctab_array_table[i],
-                                 agctab_array_table[i + 1]));
+                                "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
+                                agctab_array_table[i],
+                                agctab_array_table[i + 1]);
                }
        }
        return true;
@@ -269,7 +264,7 @@ bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
        } else {
 
                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-                        ("configtype != BaseBand_Config_PHY_REG\n"));
+                        "configtype != BaseBand_Config_PHY_REG\n");
        }
        return true;
 }
@@ -291,20 +286,20 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
                radiob_arraylen = RADIOB_2TARRAYLENGTH;
                radiob_array_table = RTL8192CE_RADIOB_2TARRAY;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Radio_A:RTL8192CERADIOA_2TARRAY\n"));
+                        "Radio_A:RTL8192CERADIOA_2TARRAY\n");
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n"));
+                        "Radio_B:RTL8192CE_RADIOB_2TARRAY\n");
        } else {
                radioa_arraylen = RADIOA_1TARRAYLENGTH;
                radioa_array_table = RTL8192CE_RADIOA_1TARRAY;
                radiob_arraylen = RADIOB_1TARRAYLENGTH;
                radiob_array_table = RTL8192CE_RADIOB_1TARRAY;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n"));
+                        "Radio_A:RTL8192CE_RADIOA_1TARRAY\n");
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n"));
+                        "Radio_B:RTL8192CE_RADIOB_1TARRAY\n");
        }
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
        switch (rfpath) {
        case RF90_PATH_A:
                for (i = 0; i < radioa_arraylen; i = i + 2) {
@@ -352,11 +347,11 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
                break;
        case RF90_PATH_C:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        case RF90_PATH_D:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        return true;
@@ -371,10 +366,9 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
        u8 reg_bw_opmode;
        u8 reg_prsr_rsc;
 
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-                ("Switch to %s bandwidth\n",
-                 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
-                 "20MHz" : "40MHz"))
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
+                rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+                "20MHz" : "40MHz");
 
        if (is_hal_stop(rtlhal)) {
                rtlphy->set_bwmode_inprogress = false;
@@ -398,7 +392,7 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+                        "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
                break;
        }
 
@@ -423,12 +417,12 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+                        "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
                break;
        }
        rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
        rtlphy->set_bwmode_inprogress = false;
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 }
 
 void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
@@ -499,7 +493,7 @@ static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
                rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-                        ("Switch RF timeout !!!.\n"));
+                        "Switch RF timeout !!!\n");
                return;
        }
        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
@@ -526,7 +520,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                do {
                                        InitializeCount++;
                                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                                ("IPS Set eRf nic enable\n"));
+                                                "IPS Set eRf nic enable\n");
                                        rtstatus = rtl_ps_enable_nic(hw);
                                } while ((rtstatus != true)
                                         && (InitializeCount < 10));
@@ -534,10 +528,10 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                                  RT_RF_OFF_LEVL_HALT_NIC);
                        } else {
                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                        ("Set ERFON sleeped:%d ms\n",
-                                         jiffies_to_msecs(jiffies -
-                                                  ppsc->
-                                                  last_sleep_jiffies)));
+                                        "Set ERFON sleeped:%d ms\n",
+                                        jiffies_to_msecs(jiffies -
+                                                         ppsc->
+                                                         last_sleep_jiffies));
                                ppsc->last_awake_jiffies = jiffies;
                                rtl92ce_phy_set_rf_on(hw);
                        }
@@ -553,7 +547,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
        case ERFOFF:{
                        if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                        ("IPS Set eRf nic disable\n"));
+                                        "IPS Set eRf nic disable\n");
                                rtl_ps_disable_nic(hw);
                                RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
                        } else {
@@ -578,35 +572,33 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                        continue;
                                } else {
                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                                ("eRf Off/Sleep: %d times "
-                                                 "TcbBusyQueue[%d] =%d before "
-                                                 "doze!\n", (i + 1), queue_id,
-                                                 skb_queue_len(&ring->queue)));
+                                                "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
+                                                i + 1, queue_id,
+                                                skb_queue_len(&ring->queue));
 
                                        udelay(10);
                                        i++;
                                }
                                if (i >= MAX_DOZE_WAITING_TIMES_9x) {
                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                                ("\n ERFSLEEP: %d times "
-                                                 "TcbBusyQueue[%d] = %d !\n",
-                                                 MAX_DOZE_WAITING_TIMES_9x,
-                                                 queue_id,
-                                                 skb_queue_len(&ring->queue)));
+                                                "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
+                                                MAX_DOZE_WAITING_TIMES_9x,
+                                                queue_id,
+                                                skb_queue_len(&ring->queue));
                                        break;
                                }
                        }
                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                ("Set ERFSLEEP awaked:%d ms\n",
-                                 jiffies_to_msecs(jiffies -
-                                                  ppsc->last_awake_jiffies)));
+                                "Set ERFSLEEP awaked:%d ms\n",
+                                jiffies_to_msecs(jiffies -
+                                                 ppsc->last_awake_jiffies));
                        ppsc->last_sleep_jiffies = jiffies;
                        _rtl92ce_phy_set_rf_sleep(hw);
                        break;
                }
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                bresult = false;
                break;
        }
index be2c92adef33d293e1579a78f57c4eb56e8574de..d5e3b704f9304a596bd943cfcbebd00db6559776 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index ba5ff0411f0abce3c6e4e1e87b2e764b6182e6d0..43806d9d1e130146d217ccf89f46f47d93e4efb9 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index d3b01e6023bac8b0549a2e46c876ecd7734be3a2..69d720dd9c38e1cb73da741f89d81cce972b854d 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -56,7 +56,7 @@ void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n", bandwidth));
+                        "unknown bandwidth: %#X\n", bandwidth);
                break;
        }
 }
@@ -123,8 +123,8 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
        rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
 
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-                RTXAGC_A_CCK1_MCS32));
+               "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_A_CCK1_MCS32);
 
        tmpval = tx_agc[RF90_PATH_A] >> 8;
 
@@ -133,22 +133,22 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
 
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-                RTXAGC_B_CCK11_A_CCK2_11));
+               "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_B_CCK11_A_CCK2_11);
 
        tmpval = tx_agc[RF90_PATH_B] >> 24;
        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
 
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-                RTXAGC_B_CCK11_A_CCK2_11));
+               "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_B_CCK11_A_CCK2_11);
 
        tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
        rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
 
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-                RTXAGC_B_CCK1_55_MCS32));
+               "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_B_CCK1_55_MCS32);
 }
 
 static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
@@ -171,8 +171,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
                    (powerBase0 << 8) | powerBase0;
                *(ofdmbase + i) = powerBase0;
                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                       (" [OFDM power base index rf(%c) = 0x%x]\n",
-                        ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
+                       " [OFDM power base index rf(%c) = 0x%x]\n",
+                       i == 0 ? 'A' : 'B', *(ofdmbase + i));
        }
 
        for (i = 0; i < 2; i++) {
@@ -187,8 +187,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
                *(mcsbase + i) = powerBase1;
 
                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                       (" [MCS power base index rf(%c) = 0x%x]\n",
-                        ((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
+                       " [MCS power base index rf(%c) = 0x%x]\n",
+                       i == 0 ? 'A' : 'B', *(mcsbase + i));
        }
 }
 
@@ -215,9 +215,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                            + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
 
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("RTK better performance, "
-                                "writeVal(%c) = 0x%x\n",
-                                ((rf == 0) ? 'A' : 'B'), writeVal));
+                               "RTK better performance, writeVal(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeVal);
                        break;
                case 1:
                        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
@@ -225,9 +224,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                                            powerBase1[rf]);
 
                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                                       ("Realtek regulatory, 40MHz, "
-                                        "writeVal(%c) = 0x%x\n",
-                                        ((rf == 0) ? 'A' : 'B'), writeVal));
+                                       "Realtek regulatory, 40MHz, writeVal(%c) = 0x%x\n",
+                                       rf == 0 ? 'A' : 'B', writeVal);
                        } else {
                                if (rtlphy->pwrgroup_cnt == 1)
                                        chnlgroup = 0;
@@ -249,9 +247,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                                                              powerBase1[rf]);
 
                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                                       ("Realtek regulatory, 20MHz, "
-                                        "writeVal(%c) = 0x%x\n",
-                                        ((rf == 0) ? 'A' : 'B'), writeVal));
+                                       "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n",
+                                       rf == 0 ? 'A' : 'B', writeVal);
                        }
                        break;
                case 2:
@@ -259,27 +256,24 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                            ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
 
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("Better regulatory, "
-                                "writeVal(%c) = 0x%x\n",
-                                ((rf == 0) ? 'A' : 'B'), writeVal));
+                               "Better regulatory, writeVal(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeVal);
                        break;
                case 3:
                        chnlgroup = 0;
 
                        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                                       ("customer's limit, 40MHz "
-                                        "rf(%c) = 0x%x\n",
-                                        ((rf == 0) ? 'A' : 'B'),
-                                        rtlefuse->pwrgroup_ht40[rf][channel -
-                                                                    1]));
+                                       "customer's limit, 40MHz rf(%c) = 0x%x\n",
+                                       rf == 0 ? 'A' : 'B',
+                                       rtlefuse->pwrgroup_ht40[rf][channel -
+                                                                   1]);
                        } else {
                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                                       ("customer's limit, 20MHz "
-                                        "rf(%c) = 0x%x\n",
-                                        ((rf == 0) ? 'A' : 'B'),
-                                        rtlefuse->pwrgroup_ht20[rf][channel -
-                                                                    1]));
+                                       "customer's limit, 20MHz rf(%c) = 0x%x\n",
+                                       rf == 0 ? 'A' : 'B',
+                                       rtlefuse->pwrgroup_ht20[rf][channel -
+                                                                   1]);
                        }
                        for (i = 0; i < 4; i++) {
                                pwr_diff_limit[i] =
@@ -311,15 +305,15 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                            (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
 
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("Customer's limit rf(%c) = 0x%x\n",
-                                ((rf == 0) ? 'A' : 'B'), customer_limit));
+                               "Customer's limit rf(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', customer_limit);
 
                        writeVal = customer_limit +
                            ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
 
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("Customer, writeVal rf(%c)= 0x%x\n",
-                                ((rf == 0) ? 'A' : 'B'), writeVal));
+                               "Customer, writeVal rf(%c)= 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeVal);
                        break;
                default:
                        chnlgroup = 0;
@@ -329,9 +323,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                            + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
 
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("RTK better performance, writeVal "
-                                "rf(%c) = 0x%x\n",
-                                ((rf == 0) ? 'A' : 'B'), writeVal));
+                               "RTK better performance, writeVal rf(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeVal);
                        break;
                }
 
@@ -383,7 +376,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
                rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
 
                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                       ("Set 0x%x = %08x\n", regoffset, writeVal));
+                       "Set 0x%x = %08x\n", regoffset, writeVal);
 
                if (((get_rf_type(rtlphy) == RF_2T2R) &&
                     (regoffset == RTXAGC_A_MCS15_MCS12 ||
@@ -512,12 +505,12 @@ static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
 
                if (rtstatus != true) {
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                                ("Radio[%d] Fail!!", rfpath));
+                                "Radio[%d] Fail!!\n", rfpath);
                        return false;
                }
 
        }
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
        return rtstatus;
 }
index 39ff03685986a130b3304150bb0ab56a3ab42015..6c8d56efceae2fd8e76e8e128fea6e720241cf12 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 89ef6982ce50ea836c03975c3b39850f0b41aa5e..2c3b73366cd2e2928423c1f600d7106966bd34c4 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,9 +27,6 @@
  *
  *****************************************************************************/
 
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-
 #include "../wifi.h"
 #include "../core.h"
 #include "../pci.h"
@@ -43,6 +40,8 @@
 #include "trx.h"
 #include "led.h"
 
+#include <linux/module.h>
+
 static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw)
 {
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -92,9 +91,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
        int err;
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       const struct firmware *firmware;
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-       char *fw_name = NULL;
 
        rtl8192ce_bt_reg_init(hw);
 
@@ -159,33 +156,27 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
        if (!rtlpriv->rtlhal.pfirmware) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't alloc buffer for fw.\n"));
+                        "Can't alloc buffer for fw\n");
                return 1;
        }
 
        /* request fw */
        if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
            !IS_92C_SERIAL(rtlhal->version))
-               fw_name = "rtlwifi/rtl8192cfwU.bin";
+               rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin";
        else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
-               fw_name = "rtlwifi/rtl8192cfwU_B.bin";
-       else
-               fw_name = rtlpriv->cfg->fw_name;
-       err = request_firmware(&firmware, fw_name, rtlpriv->io.dev);
+               rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin";
+
+       rtlpriv->max_fw_size = 0x4000;
+       pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
+       err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
+                                     rtlpriv->io.dev, GFP_KERNEL, hw,
+                                     rtl_fw_cb);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Failed to request firmware!\n"));
-               return 1;
-       }
-       if (firmware->size > 0x4000) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Firmware is too big!\n"));
-               release_firmware(firmware);
+                        "Failed to request firmware!\n");
                return 1;
        }
-       memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
-       rtlpriv->rtlhal.fwsize = firmware->size;
-       release_firmware(firmware);
 
        return 0;
 }
@@ -404,7 +395,7 @@ static int __init rtl92ce_module_init(void)
 
        ret = pci_register_driver(&rtl92ce_driver);
        if (ret)
-               RT_ASSERT(false, (": No device found\n"));
+               RT_ASSERT(false, "No device found\n");
 
        return ret;
 }
index b7dc3263e433171d8bc7687cca8af063630d7a9e..d2367a5d0cf5152ff9595328eac103b4923811a2 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index ba938b91aa6f3d9d506b6f67b984f42e41797ab8..752f943a84ae10bf7f2f466bcc35078fcf0bc5dc 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 3a6e8b6aeee0987df98c0d3ee37a050c7b635532..8b79161f71be25764db207edea9634127aab340f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 4fb5ae24dee07fc08819add09b6e7793298beff8..37b13636a7786c4a66fc7397116e389e2801a90f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -725,7 +725,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
                if (ieee80211_is_data_qos(fc)) {
                        if (mac->rdg_en) {
                                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-                                        ("Enable RDG function.\n"));
+                                        "Enable RDG function\n");
                                SET_TX_DESC_RDG_ENABLE(pdesc, 1);
                                SET_TX_DESC_HTC(pdesc, 1);
                        }
@@ -763,7 +763,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
                SET_TX_DESC_BMC(pdesc, 1);
        }
 
-       RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+       RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 }
 
 void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
@@ -821,8 +821,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
        }
 
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
-                     "H2C Tx Cmd Content\n",
-                     pdesc, TX_DESC_SIZE);
+                     "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
 }
 
 void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
@@ -837,8 +836,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
                        SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR txdesc :%d"
-                                         " not process\n", desc_name));
+                       RT_ASSERT(false, "ERR txdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        } else {
@@ -857,8 +856,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
                        SET_RX_DESC_EOR(pdesc, 1);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR rxdesc :%d "
-                                         "not process\n", desc_name));
+                       RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        }
@@ -877,8 +876,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
                        ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR txdesc :%d "
-                                         "not process\n", desc_name));
+                       RT_ASSERT(false, "ERR txdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        } else {
@@ -891,8 +890,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
                        ret = GET_RX_DESC_PKT_LEN(pdesc);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR rxdesc :%d "
-                                         "not process\n", desc_name));
+                       RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        }
index c8977a50ca36de7b2d52f3abe8f55d4abd004e07..efb9ab270403321aec894da08569ca97eba6d11d 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index d097efb1e717b850a753b6c65e2101f0128330f9..f916555e6311dafef2c3821222d8d8bb54e8a916 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index f311baee668dfe6a7ff4b6ee1e47cc833a9e37eb..6fd39eaf361ee2bf5cdbcf70fc45804c6aa4e144 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -52,7 +52,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
        if ((mac->link_state < MAC80211_LINKED) &&
            (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-                        ("Not connected to any\n"));
+                        "Not connected to any\n");
 
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 
@@ -65,28 +65,28 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
                        undecorated_smoothed_pwdb =
                            rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("AP Client PWDB = 0x%lx\n",
-                                 undecorated_smoothed_pwdb));
+                                "AP Client PWDB = 0x%lx\n",
+                                undecorated_smoothed_pwdb);
                } else {
                        undecorated_smoothed_pwdb =
                            rtlpriv->dm.undecorated_smoothed_pwdb;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("STA Default Port PWDB = 0x%lx\n",
-                                 undecorated_smoothed_pwdb));
+                                "STA Default Port PWDB = 0x%lx\n",
+                                undecorated_smoothed_pwdb);
                }
        } else {
                undecorated_smoothed_pwdb =
                    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("AP Ext Port PWDB = 0x%lx\n",
-                         undecorated_smoothed_pwdb));
+                        "AP Ext Port PWDB = 0x%lx\n",
+                        undecorated_smoothed_pwdb);
        }
 
        if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+                        "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
        } else if ((undecorated_smoothed_pwdb <
                    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
                   (undecorated_smoothed_pwdb >=
@@ -94,18 +94,18 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
 
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+                        "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
        } else if (undecorated_smoothed_pwdb <
                   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("TXHIGHPWRLEVEL_NORMAL\n"));
+                        "TXHIGHPWRLEVEL_NORMAL\n");
        }
 
        if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
-                         rtlphy->current_channel));
+                        "PHY_SetTxPowerLevel8192S() Channel = %d\n",
+                        rtlphy->current_channel);
                rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
        }
 
index 7f966c666b5adbce2ced9a094fd93a1deb3c6edb..d947e7d350bbc146d7b56b1c463c9dce829b5dce 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 124cf633861c3d6f061e44af9083f95a0a12b395..0c74d4f2eeb43c86ed59f9309b3170bd3aaed7a1 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include "../wifi.h"
 #include "../efuse.h"
 #include "../base.h"
@@ -162,24 +160,24 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
        for (rf_path = 0; rf_path < 2; rf_path++)
                for (i = 0; i < 3; i++)
                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-                               ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
-                                i, rtlefuse->
-                                eeprom_chnlarea_txpwr_cck[rf_path][i]));
+                               "RF(%d) EEPROM CCK Area(%d) = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->
+                               eeprom_chnlarea_txpwr_cck[rf_path][i]);
        for (rf_path = 0; rf_path < 2; rf_path++)
                for (i = 0; i < 3; i++)
                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-                               ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->
-                                eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]));
+                               "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->
+                               eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]);
        for (rf_path = 0; rf_path < 2; rf_path++)
                for (i = 0; i < 3; i++)
                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-                               ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->
-                                eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path]
-                                [i]));
+                               "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->
+                               eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]);
        for (rf_path = 0; rf_path < 2; rf_path++) {
                for (i = 0; i < 14; i++) {
                        index = _rtl92c_get_chnl_group((u8) i);
@@ -205,11 +203,10 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
                }
                for (i = 0; i < 14; i++) {
                        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                               ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
-                                "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
-                                rtlefuse->txpwrlevel_cck[rf_path][i],
-                                rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
-                                rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
+                               "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i,
+                               rtlefuse->txpwrlevel_cck[rf_path][i],
+                               rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
+                               rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
                }
        }
        for (i = 0; i < 3; i++) {
@@ -242,13 +239,13 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
                                      & 0xf0) >> 4);
                        }
                        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                               ("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->pwrgroup_ht20[rf_path][i]));
+                               "RF-%d pwrgroup_ht20[%d] = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->pwrgroup_ht20[rf_path][i]);
                        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                               ("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->pwrgroup_ht40[rf_path][i]));
+                               "RF-%d pwrgroup_ht40[%d] = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->pwrgroup_ht40[rf_path][i]);
                }
        }
        for (i = 0; i < 14; i++) {
@@ -277,26 +274,26 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
            rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7];
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
+                       "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
+                       "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
+                       "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
+                       "RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
        if (!autoload_fail)
                rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
        else
                rtlefuse->eeprom_regulatory = 0;
        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-               ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+               "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
        if (!autoload_fail) {
                rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
                rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B];
@@ -305,9 +302,9 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
                rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI;
        }
        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-               ("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
-                rtlefuse->eeprom_tssi[RF90_PATH_A],
-                rtlefuse->eeprom_tssi[RF90_PATH_B]));
+               "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
+               rtlefuse->eeprom_tssi[RF90_PATH_A],
+               rtlefuse->eeprom_tssi[RF90_PATH_B]);
        if (!autoload_fail)
                tempval = hwinfo[EEPROM_THERMAL_METER];
        else
@@ -320,7 +317,7 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
                rtlefuse->apk_thermalmeterignore = true;
        rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-               ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
+               "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
 }
 
 static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents)
@@ -340,144 +337,8 @@ static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents)
        if (IS_HIGHT_PA(rtlefuse->board_type))
                rtlefuse->external_pa = 1;
        pr_info("Board Type %x\n", rtlefuse->board_type);
-
-#ifdef CONFIG_ANTENNA_DIVERSITY
-       /* Antenna Diversity setting. */
-       if (registry_par->antdiv_cfg == 2) /* 2: From Efuse */
-               rtl_efuse->antenna_cfg = (contents[EEPROM_RF_OPT1]&0x18)>>3;
-       else
-               rtl_efuse->antenna_cfg = registry_par->antdiv_cfg; /* 0:OFF, */
-
-       pr_info("Antenna Config %x\n", rtl_efuse->antenna_cfg);
-#endif
-}
-
-#ifdef CONFIG_BT_COEXIST
-static void _update_bt_param(_adapter *padapter)
-{
-       struct btcoexist_priv    *pbtpriv = &(padapter->halpriv.bt_coexist);
-       struct registry_priv    *registry_par = &padapter->registrypriv;
-       if (2 != registry_par->bt_iso) {
-               /* 0:Low, 1:High, 2:From Efuse */
-               pbtpriv->BT_Ant_isolation = registry_par->bt_iso;
-       }
-       if (registry_par->bt_sco == 1) {
-               /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy,
-                * 5.OtherBusy */
-               pbtpriv->BT_Service = BT_OtherAction;
-       } else if (registry_par->bt_sco == 2) {
-               pbtpriv->BT_Service = BT_SCO;
-       } else if (registry_par->bt_sco == 4) {
-               pbtpriv->BT_Service = BT_Busy;
-       } else if (registry_par->bt_sco == 5) {
-               pbtpriv->BT_Service = BT_OtherBusy;
-       } else {
-               pbtpriv->BT_Service = BT_Idle;
-       }
-       pbtpriv->BT_Ampdu = registry_par->bt_ampdu;
-       pbtpriv->bCOBT = _TRUE;
-       pbtpriv->BtEdcaUL = 0;
-       pbtpriv->BtEdcaDL = 0;
-       pbtpriv->BtRssiState = 0xff;
-       pbtpriv->bInitSet = _FALSE;
-       pbtpriv->bBTBusyTraffic = _FALSE;
-       pbtpriv->bBTTrafficModeSet = _FALSE;
-       pbtpriv->bBTNonTrafficModeSet = _FALSE;
-       pbtpriv->CurrentState = 0;
-       pbtpriv->PreviousState = 0;
-       pr_info("BT Coexistance = %s\n",
-               (pbtpriv->BT_Coexist == _TRUE) ? "enable" : "disable");
-       if (pbtpriv->BT_Coexist) {
-               if (pbtpriv->BT_Ant_Num == Ant_x2)
-                       pr_info("BlueTooth BT_Ant_Num = Antx2\n");
-               else if (pbtpriv->BT_Ant_Num == Ant_x1)
-                       pr_info("BlueTooth BT_Ant_Num = Antx1\n");
-               switch (pbtpriv->BT_CoexistType) {
-               case BT_2Wire:
-                       pr_info("BlueTooth BT_CoexistType = BT_2Wire\n");
-                       break;
-               case BT_ISSC_3Wire:
-                       pr_info("BlueTooth BT_CoexistType = BT_ISSC_3Wire\n");
-                       break;
-               case BT_Accel:
-                       pr_info("BlueTooth BT_CoexistType = BT_Accel\n");
-                       break;
-               case BT_CSR_BC4:
-                       pr_info("BlueTooth BT_CoexistType = BT_CSR_BC4\n");
-                       break;
-               case BT_CSR_BC8:
-                       pr_info("BlueTooth BT_CoexistType = BT_CSR_BC8\n");
-                       break;
-               case BT_RTL8756:
-                       pr_info("BlueTooth BT_CoexistType = BT_RTL8756\n");
-                       break;
-               default:
-                       pr_info("BlueTooth BT_CoexistType = Unknown\n");
-                       break;
-               }
-               pr_info("BlueTooth BT_Ant_isolation = %d\n",
-                       pbtpriv->BT_Ant_isolation);
-               switch (pbtpriv->BT_Service) {
-               case BT_OtherAction:
-                       pr_info("BlueTooth BT_Service = BT_OtherAction\n");
-                       break;
-               case BT_SCO:
-                       pr_info("BlueTooth BT_Service = BT_SCO\n");
-                       break;
-               case BT_Busy:
-                       pr_info("BlueTooth BT_Service = BT_Busy\n");
-                       break;
-               case BT_OtherBusy:
-                       pr_info("BlueTooth BT_Service = BT_OtherBusy\n");
-                       break;
-               default:
-                       pr_info("BlueTooth BT_Service = BT_Idle\n");
-                       break;
-               }
-               pr_info("BT_RadioSharedType = 0x%x\n",
-                       pbtpriv->BT_RadioSharedType);
-       }
 }
 
-#define GET_BT_COEXIST(priv) (&priv->bt_coexist)
-
-static void _rtl92cu_read_bluetooth_coexistInfo(struct ieee80211_hw *hw,
-                                               u8 *contents,
-                                               bool bautoloadfailed);
-{
-       HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
-       bool isNormal = IS_NORMAL_CHIP(pHalData->VersionID);
-       struct btcoexist_priv    *pbtpriv = &pHalData->bt_coexist;
-       u8      rf_opt4;
-
-       _rtw_memset(pbtpriv, 0, sizeof(struct btcoexist_priv));
-       if (AutoloadFail) {
-               pbtpriv->BT_Coexist = _FALSE;
-               pbtpriv->BT_CoexistType = BT_2Wire;
-               pbtpriv->BT_Ant_Num = Ant_x2;
-               pbtpriv->BT_Ant_isolation = 0;
-               pbtpriv->BT_RadioSharedType = BT_Radio_Shared;
-               return;
-       }
-       if (isNormal) {
-               if (pHalData->BoardType == BOARD_USB_COMBO)
-                       pbtpriv->BT_Coexist = _TRUE;
-               else
-                       pbtpriv->BT_Coexist = ((PROMContent[EEPROM_RF_OPT3] &
-                                             0x20) >> 5); /* bit[5] */
-               rf_opt4 = PROMContent[EEPROM_RF_OPT4];
-               pbtpriv->BT_CoexistType = ((rf_opt4&0xe)>>1); /* bit [3:1] */
-               pbtpriv->BT_Ant_Num = (rf_opt4&0x1); /* bit [0] */
-               pbtpriv->BT_Ant_isolation = ((rf_opt4&0x10)>>4); /* bit [4] */
-               pbtpriv->BT_RadioSharedType = ((rf_opt4&0x20)>>5); /* bit [5] */
-       } else {
-               pbtpriv->BT_Coexist = (PROMContent[EEPROM_RF_OPT4] >> 4) ?
-                                      _TRUE : _FALSE;
-       }
-       _update_bt_param(Adapter);
-}
-#endif
-
 static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -494,17 +355,17 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
                       HWSET_MAX_SIZE);
        } else if (rtlefuse->epromtype == EEPROM_93C46) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("RTL819X Not boot from eeprom, check it !!"));
+                        "RTL819X Not boot from eeprom, check it !!\n");
        }
-       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"),
+       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, "MAP",
                      hwinfo, HWSET_MAX_SIZE);
        eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0]));
        if (eeprom_id != RTL8190_EEPROM_ID) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+                        "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
                rtlefuse->autoload_failflag = true;
        } else {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
                rtlefuse->autoload_failflag = false;
        }
        if (rtlefuse->autoload_failflag)
@@ -518,16 +379,15 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
                                           rtlefuse->autoload_failflag, hwinfo);
        rtlefuse->eeprom_vid = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VID]);
        rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]);
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                (" VID = 0x%02x PID = 0x%02x\n",
-                rtlefuse->eeprom_vid, rtlefuse->eeprom_did));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, " VID = 0x%02x PID = 0x%02x\n",
+                rtlefuse->eeprom_vid, rtlefuse->eeprom_did);
        rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
        rtlefuse->eeprom_version =
                         le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]);
        rtlefuse->txpwr_fromeprom = true;
        rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n",
+                rtlefuse->eeprom_oemid);
        if (rtlhal->oem_id == RT_CID_DEFAULT) {
                switch (rtlefuse->eeprom_oemid) {
                case EEPROM_CID_DEFAULT:
@@ -554,10 +414,6 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
                }
        }
        _rtl92cu_read_board_type(hw, hwinfo);
-#ifdef CONFIG_BT_COEXIST
-       _rtl92cu_read_bluetooth_coexistInfo(hw, hwinfo,
-                                           rtlefuse->autoload_failflag);
-#endif
 }
 
 static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw)
@@ -579,8 +435,8 @@ static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw)
        default:
                break;
        }
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                ("RT Customized ID: 0x%02X\n", rtlhal->oem_id));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n",
+                rtlhal->oem_id);
 }
 
 void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw)
@@ -596,11 +452,11 @@ void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw)
        tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
        rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ?
                               EEPROM_93C46 : EEPROM_BOOT_EFUSE;
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n",
-                (tmp_u1b & BOOT_FROM_EEPROM) ? "EERROM" : "EFUSE"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from %s\n",
+                tmp_u1b & BOOT_FROM_EEPROM ? "EERROM" : "EFUSE");
        rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true;
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n",
-                (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload %s\n",
+                tmp_u1b & EEPROM_EN ? "OK!!" : "ERR!!");
        _rtl92cu_read_adapter_info(hw);
        _rtl92cu_hal_customized_behavior(hw);
        return;
@@ -618,13 +474,12 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw)
        do {
                if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) {
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                                ("Autoload Done!\n"));
+                                "Autoload Done!\n");
                        break;
                }
                if (pollingCount++ > 100) {
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                                ("Failed to polling REG_APS_FSMCO[PFM_ALDN]"
-                                " done!\n"));
+                                "Failed to polling REG_APS_FSMCO[PFM_ALDN] done!\n");
                        return -ENODEV;
                }
        } while (true);
@@ -639,8 +494,8 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw)
                value8 |= LDV12_EN;
                rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8);
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        (" power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",
-                        value8));
+                        " power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x\n",
+                        value8);
                udelay(100);
                value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL);
                value8 &= ~ISO_MD2PP;
@@ -658,8 +513,7 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw)
                }
                if (pollingCount++ > 100) {
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                                ("Failed to polling REG_APS_FSMCO[APFM_ONMAC]"
-                                " done!\n"));
+                                "Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n");
                        return -ENODEV;
                }
        } while (true);
@@ -877,8 +731,8 @@ static void _rtl92cu_init_chipN_three_out_ep_priority(struct ieee80211_hw *hw,
                hiQ     = QUEUE_HIGH;
        }
        _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                ("Tx queue select :0x%02x..\n", queue_sel));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n",
+                queue_sel);
 }
 
 static void _rtl92cu_init_chipN_queue_priority(struct ieee80211_hw *hw,
@@ -937,8 +791,8 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw,
                break;
        }
        rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele);
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                ("Tx queue select :0x%02x..\n", hq_sele));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n",
+                hq_sele);
 }
 
 static void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw,
@@ -998,7 +852,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw)
 
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                       ("Failed to init power on!\n"));
+                        "Failed to init power on!\n");
                return err;
        }
        if (!wmm_enable) {
@@ -1010,7 +864,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw)
        }
        if (false == rtl92c_init_llt_table(hw, boundary)) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                       ("Failed to init LLT Table!\n"));
+                        "Failed to init LLT Table!\n");
                return -EINVAL;
        }
        _rtl92cu_init_queue_reserved_page(hw, wmm_enable, out_ep_nums,
@@ -1043,12 +897,12 @@ void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw)
        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
-                 rtlpriv->sec.pairwise_enc_algorithm,
-                 rtlpriv->sec.group_enc_algorithm));
+                "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
+                rtlpriv->sec.pairwise_enc_algorithm,
+                rtlpriv->sec.group_enc_algorithm);
        if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                        ("not open sw encryption\n"));
+                        "not open sw encryption\n");
                return;
        }
        sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable;
@@ -1059,8 +913,8 @@ void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw)
        if (IS_NORMAL_CHIP(rtlhal->version))
                sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
        rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
-       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                ("The SECR-value %x\n", sec_reg_value));
+       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n",
+                sec_reg_value);
        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
 }
 
@@ -1111,34 +965,6 @@ static void _InitPABias(struct ieee80211_hw *hw)
        }
 }
 
-static void _InitAntenna_Selection(struct ieee80211_hw *hw)
-{
-#ifdef CONFIG_ANTENNA_DIVERSITY
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-       struct rtl_phy *rtlphy = &(rtlpriv->phy);
-
-       if (pHalData->AntDivCfg == 0)
-               return;
-
-       if (rtlphy->rf_type == RF_1T1R) {
-               rtl_write_dword(rtlpriv, REG_LEDCFG0,
-                               rtl_read_dword(rtlpriv,
-                               REG_LEDCFG0)|BIT(23));
-               rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
-               if (rtl_get_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300) ==
-                   Antenna_A)
-                       pHalData->CurAntenna = Antenna_A;
-               else
-                       pHalData->CurAntenna = Antenna_B;
-       }
-#endif
-}
-
-static void _dump_registers(struct ieee80211_hw *hw)
-{
-}
-
 static void _update_mac_setting(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1163,18 +989,15 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
        rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU;
        err = _rtl92cu_init_mac(hw);
        if (err) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("init mac failed!\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n");
                return err;
        }
        err = rtl92c_download_fw(hw);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("Failed to download FW. Init HW without FW now..\n"));
+                        "Failed to download FW. Init HW without FW now..\n");
                err = 1;
-               rtlhal->fw_ready = false;
                return err;
-       } else {
-               rtlhal->fw_ready = true;
        }
        rtlhal->last_hmeboxnum = 0; /* h2c */
        _rtl92cu_phy_param_tab_init(hw);
@@ -1209,10 +1032,8 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
        }
        _rtl92cu_hw_configure(hw);
        _InitPABias(hw);
-       _InitAntenna_Selection(hw);
        _update_mac_setting(hw);
        rtl92c_dm_init(hw);
-       _dump_registers(hw);
        return err;
 }
 
@@ -1270,24 +1091,21 @@ static void  _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM)
                if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) {
                        /* reset MCU ready status */
                        rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
-                       if (rtlhal->fw_ready) {
-                               /* 8051 reset by self */
-                               rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20);
-                               while ((retry_cnts++ < 100) &&
-                                      (FEN_CPUEN & rtl_read_word(rtlpriv,
-                                      REG_SYS_FUNC_EN))) {
-                                       udelay(50);
-                               }
-                               if (retry_cnts >= 100) {
-                                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                               ("#####=> 8051 reset failed!.."
-                                               ".......................\n"););
-                                       /* if 8051 reset fail, reset MAC. */
-                                       rtl_write_byte(rtlpriv,
-                                                      REG_SYS_FUNC_EN + 1,
-                                                      0x50);
-                                       udelay(100);
-                               }
+                       /* 8051 reset by self */
+                       rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20);
+                       while ((retry_cnts++ < 100) &&
+                              (FEN_CPUEN & rtl_read_word(rtlpriv,
+                              REG_SYS_FUNC_EN))) {
+                               udelay(50);
+                       }
+                       if (retry_cnts >= 100) {
+                               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                                        "#####=> 8051 reset failed!.........................\n");
+                               /* if 8051 reset fail, reset MAC. */
+                               rtl_write_byte(rtlpriv,
+                                              REG_SYS_FUNC_EN + 1,
+                                              0x50);
+                               udelay(100);
                        }
                }
                /* Reset MAC and Enable 8051 */
@@ -1495,35 +1313,36 @@ static int _rtl92cu_set_media_status(struct ieee80211_hw *hw,
                _rtl92cu_resume_tx_beacon(hw);
                _rtl92cu_disable_bcn_sub_func(hw);
        } else {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("Set HW_VAR_MEDIA_"
-                        "STATUS:No such media status(%x).\n", type));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                        "Set HW_VAR_MEDIA_STATUS:No such media status(%x)\n",
+                        type);
        }
        switch (type) {
        case NL80211_IFTYPE_UNSPECIFIED:
                bt_msr |= MSR_NOLINK;
                ledaction = LED_CTL_LINK;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to NO LINK!\n"));
+                        "Set Network type to NO LINK!\n");
                break;
        case NL80211_IFTYPE_ADHOC:
                bt_msr |= MSR_ADHOC;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to Ad Hoc!\n"));
+                        "Set Network type to Ad Hoc!\n");
                break;
        case NL80211_IFTYPE_STATION:
                bt_msr |= MSR_INFRA;
                ledaction = LED_CTL_LINK;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to STA!\n"));
+                        "Set Network type to STA!\n");
                break;
        case NL80211_IFTYPE_AP:
                bt_msr |= MSR_AP;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to AP!\n"));
+                        "Set Network type to AP!\n");
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Network type %d not support!\n", type));
+                        "Network type %d not supported!\n", type);
                goto error_out;
        }
        rtl_write_byte(rtlpriv, (MSR), bt_msr);
@@ -1684,8 +1503,8 @@ void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw)
        value32 |= TSFRST;
        rtl_write_dword(rtlpriv, REG_TCR, value32);
        RT_TRACE(rtlpriv, COMP_INIT|COMP_BEACON, DBG_LOUD,
-                ("SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n",
-                value32));
+                "SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n",
+                value32);
        /* TODO: Modify later (Find the right parameters)
         * NOTE: Fix test chip's bug (about contention windows's randomness) */
        if ((mac->opmode == NL80211_IFTYPE_ADHOC) ||
@@ -1702,8 +1521,8 @@ void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw)
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        u16 bcn_interval = mac->beacon_interval;
 
-       RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
-                ("beacon_interval:%d\n", bcn_interval));
+       RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n",
+                bcn_interval);
        rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
 }
 
@@ -1767,7 +1586,7 @@ void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
 }
@@ -1827,8 +1646,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                        rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
                        rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]);
                        rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]);
-                       RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                ("HW_VAR_SIFS\n"));
+                       RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, "HW_VAR_SIFS\n");
                        break;
                }
        case HW_VAR_SLOT_TIME:{
@@ -1837,7 +1655,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 
                        rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                ("HW_VAR_SLOT_TIME %x\n", val[0]));
+                                "HW_VAR_SLOT_TIME %x\n", val[0]);
                        if (QOS_MODE) {
                                for (e_aci = 0; e_aci < AC_MAX; e_aci++)
                                        rtlpriv->cfg->ops->set_hw_reg(hw,
@@ -1901,8 +1719,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                                     min_spacing_to_set);
                                *val = min_spacing_to_set;
                                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                       ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
-                                       mac->min_space_cfg));
+                                        "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+                                        mac->min_space_cfg);
                                rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
                                               mac->min_space_cfg);
                        }
@@ -1916,8 +1734,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                        mac->min_space_cfg &= 0x07;
                        mac->min_space_cfg |= (density_to_set << 3);
                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
-                                 mac->min_space_cfg));
+                                "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+                                mac->min_space_cfg);
                        rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
                                       mac->min_space_cfg);
                        break;
@@ -1950,8 +1768,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                                       p_regtoset[index]);
                                }
                                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                        ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
-                                         factor_toset));
+                                        "Set HW_VAR_AMPDU_FACTOR: %#x\n",
+                                        factor_toset);
                        }
                        break;
                }
@@ -1969,8 +1787,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                         AC_PARAM_ECW_MAX_OFFSET);
                        u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET;
                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                ("queue:%x, ac_param:%x\n", e_aci,
-                                 u4b_ac_param));
+                                "queue:%x, ac_param:%x\n",
+                                e_aci, u4b_ac_param);
                        switch (e_aci) {
                        case AC1_BK:
                                rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM,
@@ -1989,8 +1807,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                                u4b_ac_param);
                                break;
                        default:
-                               RT_ASSERT(false, ("SetHwReg8185(): invalid"
-                                         " aci: %d !\n", e_aci));
+                               RT_ASSERT(false,
+                                         "SetHwReg8185(): invalid aci: %d !\n",
+                                         e_aci);
                                break;
                        }
                        if (rtlusb->acm_method != eAcmWay2_SW)
@@ -2020,8 +1839,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                        break;
                                default:
                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                                ("HW_VAR_ACM_CTRL acm set "
-                                                 "failed: eACI is %d\n", acm));
+                                                "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
+                                                acm);
                                        break;
                                }
                        } else {
@@ -2037,13 +1856,13 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                        break;
                                default:
                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                                ("switch case not process\n"));
+                                                "switch case not processed\n");
                                        break;
                                }
                        }
                        RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
-                                ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
-                                 "Write 0x%X\n", acm_ctrl));
+                                "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
+                                acm_ctrl);
                        rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
                        break;
                }
@@ -2051,7 +1870,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                        rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]);
                        mac->rx_conf = ((u32 *) (val))[0];
                        RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG,
-                                ("### Set RCR(0x%08x) ###\n", mac->rx_conf));
+                                "### Set RCR(0x%08x) ###\n", mac->rx_conf);
                        break;
                }
        case HW_VAR_RETRY_LIMIT:{
@@ -2060,8 +1879,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                        rtl_write_word(rtlpriv, REG_RL,
                                       retry_limit << RETRY_LIMIT_SHORT_SHIFT |
                                       retry_limit << RETRY_LIMIT_LONG_SHIFT);
-                       RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG, ("Set HW_VAR_R"
-                                "ETRY_LIMIT(0x%08x)\n", retry_limit));
+                       RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG,
+                                "Set HW_VAR_RETRY_LIMIT(0x%08x)\n",
+                                retry_limit);
                        break;
                }
        case HW_VAR_DUAL_TSF_RST:
@@ -2165,8 +1985,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val);
                break;
        default:
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
-                                                       "not process\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        "switch case not processed\n");
                break;
        }
 }
@@ -2239,8 +2059,8 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
                               (shortgi_rate << 4) | (shortgi_rate);
        }
        rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
-       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("%x\n", rtl_read_dword(rtlpriv,
-                REG_ARFR0)));
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+                rtl_read_dword(rtlpriv, REG_ARFR0));
 }
 
 void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
@@ -2344,17 +2164,16 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
                        ratr_bitmap &= 0x0f0ff0ff;
                break;
        }
-       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("ratr_bitmap :%x\n",
-                ratr_bitmap));
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n",
+                ratr_bitmap);
        *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) |
                                      ratr_index << 28);
        rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
-       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, "
-                                               "ratr_val:%x, %x:%x:%x:%x:%x\n",
-                                               ratr_index, ratr_bitmap,
-                                               rate_mask[0], rate_mask[1],
-                                               rate_mask[2], rate_mask[3],
-                                               rate_mask[4]));
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+                "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
+                ratr_index, ratr_bitmap,
+                rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3],
+                rate_mask[4]);
        rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
 }
 
@@ -2404,7 +2223,7 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
                        e_rfpowerstate_toset = (u1tmp & BIT(7)) ?
                                               ERFOFF : ERFON;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-                                ("pwrdown, 0x5c(BIT7)=%02x\n", u1tmp));
+                                "pwrdown, 0x5c(BIT7)=%02x\n", u1tmp);
                } else {
                        rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG,
                                       rtl_read_byte(rtlpriv,
@@ -2413,27 +2232,26 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
                        e_rfpowerstate_toset  = (u1tmp & BIT(3)) ?
                                                 ERFON : ERFOFF;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-                               ("GPIO_IN=%02x\n", u1tmp));
+                                "GPIO_IN=%02x\n", u1tmp);
                }
-               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("N-SS RF =%x\n",
-                        e_rfpowerstate_toset));
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "N-SS RF =%x\n",
+                        e_rfpowerstate_toset);
        }
        if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
-               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF  - HW "
-                        "Radio ON, RF ON\n"));
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                        "GPIOChangeRF  - HW Radio ON, RF ON\n");
                ppsc->hwradiooff = false;
                actuallyset = true;
        } else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset  ==
                    ERFOFF)) {
-               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF  - HW"
-                        " Radio OFF\n"));
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                        "GPIOChangeRF  - HW Radio OFF\n");
                ppsc->hwradiooff = true;
                actuallyset = true;
        } else {
-               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD ,
-                        ("pHalData->bHwRadioOff and eRfPowerStateToSet do not"
-                        " match: pHalData->bHwRadioOff %x, eRfPowerStateToSet "
-                        "%x\n", ppsc->hwradiooff, e_rfpowerstate_toset));
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                        "pHalData->bHwRadioOff and eRfPowerStateToSet do not match: pHalData->bHwRadioOff %x, eRfPowerStateToSet %x\n",
+                        ppsc->hwradiooff, e_rfpowerstate_toset);
        }
        if (actuallyset) {
                ppsc->hwradiooff = true;
index 32f85cba106ae7f2491e84a5caebf208208a0c53..f41a3aa4a26f3a90003a4aa0781e6fb041ef61cd 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 2ff9d8314e7b318fe3d9be9bc6f8c695422d26da..75a2deb23af101a7c2dacf92e4e3f803cd03aed7 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -47,8 +47,8 @@ void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
        u8 ledcfg;
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-                ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+                REG_LEDCFG2, pled->ledpin);
        ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
        switch (pled->ledpin) {
        case LED_PIN_GPIO0:
@@ -62,7 +62,7 @@ void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        pled->ledon = true;
@@ -74,8 +74,8 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
        struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
        u8 ledcfg;
 
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-                ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+                REG_LEDCFG2, pled->ledpin);
        ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
        switch (pled->ledpin) {
        case LED_PIN_GPIO0:
@@ -95,7 +95,7 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        pled->ledon = false;
@@ -136,7 +136,6 @@ void rtl92cu_led_control(struct ieee80211_hw *hw,
             ledaction == LED_CTL_POWER_ON)) {
                return;
        }
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
-                               ledaction));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction);
        _rtl92cu_sw_led_control(hw, ledaction);
 }
index decaee4d1eb1c459dc984a98993bda51bffc7a62..0f372278b7af84e4d310ecc7fb2a608f127c4385 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 9e0c8fcdf90fb60c1fb9370e3fe0c36d563f3da7..025bdc2eba44868d0f84caeed607b45c82fccee9 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
  *
 ****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-
 #include "../wifi.h"
 #include "../pci.h"
 #include "../usb.h"
@@ -44,6 +40,8 @@
 #include "mac.h"
 #include "trx.h"
 
+#include <linux/module.h>
+
 /* macro to shorten lines */
 
 #define LINK_Q ui_link_quality
@@ -57,6 +55,7 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw)
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
        enum version_8192c chip_version = VERSION_UNKNOWN;
+       const char *versionid;
        u32 value32;
 
        value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
@@ -84,88 +83,69 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw)
                }
        }
        rtlhal->version  = (enum version_8192c)chip_version;
-       pr_info("rtl8192cu: Chip version 0x%x\n", chip_version);
+       pr_info("Chip version 0x%x\n", chip_version);
        switch (rtlhal->version) {
        case VERSION_NORMAL_TSMC_CHIP_92C_1T2R:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                ("Chip Version ID: VERSION_B_CHIP_92C.\n"));
+               versionid = "NORMAL_B_CHIP_92C";
                break;
        case VERSION_NORMAL_TSMC_CHIP_92C:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C.\n"));
+               versionid = "NORMAL_TSMC_CHIP_92C";
                break;
        case VERSION_NORMAL_TSMC_CHIP_88C:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C.\n"));
+               versionid = "NORMAL_TSMC_CHIP_88C";
                break;
        case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_i"
-                       "92C_1T2R_A_CUT.\n"));
+               versionid = "NORMAL_UMC_CHIP_i92C_1T2R_A_CUT";
                break;
        case VERSION_NORMAL_UMC_CHIP_92C_A_CUT:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_"
-                       "92C_A_CUT.\n"));
+               versionid = "NORMAL_UMC_CHIP_92C_A_CUT";
                break;
        case VERSION_NORMAL_UMC_CHIP_88C_A_CUT:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
-                       "_88C_A_CUT.\n"));
+               versionid = "NORMAL_UMC_CHIP_88C_A_CUT";
                break;
        case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
-                       "_92C_1T2R_B_CUT.\n"));
+               versionid = "NORMAL_UMC_CHIP_92C_1T2R_B_CUT";
                break;
        case VERSION_NORMAL_UMC_CHIP_92C_B_CUT:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
-                       "_92C_B_CUT.\n"));
+               versionid = "NORMAL_UMC_CHIP_92C_B_CUT";
                break;
        case VERSION_NORMAL_UMC_CHIP_88C_B_CUT:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
-                       "_88C_B_CUT.\n"));
+               versionid = "NORMAL_UMC_CHIP_88C_B_CUT";
                break;
        case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_NORMA_UMC_CHIP"
-                       "_8723_1T1R_A_CUT.\n"));
+               versionid = "NORMAL_UMC_CHIP_8723_1T1R_A_CUT";
                break;
        case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_NORMA_UMC_CHIP"
-                       "_8723_1T1R_B_CUT.\n"));
+               versionid = "NORMAL_UMC_CHIP_8723_1T1R_B_CUT";
                break;
        case VERSION_TEST_CHIP_92C:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_TEST_CHIP_92C.\n"));
+               versionid = "TEST_CHIP_92C";
                break;
        case VERSION_TEST_CHIP_88C:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: VERSION_TEST_CHIP_88C.\n"));
+               versionid = "TEST_CHIP_88C";
                break;
        default:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                       ("Chip Version ID: ???????????????.\n"));
+               versionid = "UNKNOWN";
                break;
        }
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                "Chip Version ID: %s\n", versionid);
+
        if (IS_92C_SERIAL(rtlhal->version))
                rtlphy->rf_type =
                         (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R;
        else
                rtlphy->rf_type = RF_1T1R;
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
-                 "RF_2T2R" : "RF_1T1R"));
+                "Chip RF Type: %s\n",
+                rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R");
        if (get_rf_type(rtlphy) == RF_1T1R)
                rtlpriv->dm.rfpath_rxenable[0] = true;
        else
                rtlpriv->dm.rfpath_rxenable[0] =
                    rtlpriv->dm.rfpath_rxenable[1] = true;
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n",
-                                               rtlhal->version));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
+                rtlhal->version);
 }
 
 /**
@@ -192,9 +172,8 @@ bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
                        break;
                if (count > POLLING_LLT_THRESHOLD) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Failed to polling write LLT done at"
-                                " address %d! _LLT_OP_VALUE(%x)\n",
-                                address, _LLT_OP_VALUE(value)));
+                                "Failed to polling write LLT done at address %d! _LLT_OP_VALUE(%x)\n",
+                                address, _LLT_OP_VALUE(value));
                        status = false;
                        break;
                }
@@ -272,7 +251,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
                u8 cam_offset = 0;
                u8 clear_number = 5;
 
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
                for (idx = 0; idx < clear_number; idx++) {
                        rtl_cam_mark_invalid(hw, cam_offset + idx);
                        rtl_cam_empty_entry(hw, cam_offset + idx);
@@ -298,7 +277,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                               ("iillegal switch case\n"));
+                                "illegal switch case\n");
                        enc_algo = CAM_TKIP;
                        break;
                }
@@ -317,26 +296,26 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
                }
                if (rtlpriv->sec.key_len[key_index] == 0) {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("delete one entry\n"));
+                                "delete one entry\n");
                        rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
                } else {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("The insert KEY length is %d\n",
-                                 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+                                "The insert KEY length is %d\n",
+                                rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("The insert KEY  is %x %x\n",
-                                 rtlpriv->sec.key_buf[0][0],
-                                 rtlpriv->sec.key_buf[0][1]));
+                                "The insert KEY is %x %x\n",
+                                rtlpriv->sec.key_buf[0][0],
+                                rtlpriv->sec.key_buf[0][1]);
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("add one entry\n"));
+                                "add one entry\n");
                        if (is_pairwise) {
                                RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
-                                             "Pairwiase Key content :",
+                                             "Pairwise Key content",
                                              rtlpriv->sec.pairwise_key,
                                              rtlpriv->sec.
                                              key_len[PAIRWISE_KEYIDX]);
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                        ("set Pairwiase key\n"));
+                                        "set Pairwise key\n");
 
                                rtl_cam_add_one_entry(hw, macaddr, key_index,
                                                entry_id, enc_algo,
@@ -345,7 +324,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
                                                key_buf[key_index]);
                        } else {
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                        ("set group key\n"));
+                                        "set group key\n");
                                if (mac->opmode == NL80211_IFTYPE_ADHOC) {
                                        rtl_cam_add_one_entry(hw,
                                                rtlefuse->dev_addr,
@@ -421,8 +400,8 @@ void rtl92c_set_qos(struct ieee80211_hw *hw, int aci)
            AC_PARAM_ECW_MAX_OFFSET;
        u4b_ac_param |= (u32) le16_to_cpu(mac->ac[aci].tx_op) <<
                         AC_PARAM_TXOP_OFFSET;
-       RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD,
-                ("queue:%x, ac_param:%x\n", aci, u4b_ac_param));
+       RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, "queue:%x, ac_param:%x\n",
+                aci, u4b_ac_param);
        switch (aci) {
        case AC1_BK:
                rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param);
@@ -437,7 +416,7 @@ void rtl92c_set_qos(struct ieee80211_hw *hw, int aci)
                rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param);
                break;
        default:
-               RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+               RT_ASSERT(false, "invalid aci: %d !\n", aci);
                break;
        }
 }
@@ -453,14 +432,14 @@ void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr)
        for (i = 0 ; i < ETH_ALEN ; i++)
                rtl_write_byte(rtlpriv, (REG_MACID + i), *(addr+i));
 
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("MAC Address: %02X-%02X-%02X-"
-               "%02X-%02X-%02X\n",
-               rtl_read_byte(rtlpriv, REG_MACID),
-               rtl_read_byte(rtlpriv, REG_MACID+1),
-               rtl_read_byte(rtlpriv, REG_MACID+2),
-               rtl_read_byte(rtlpriv, REG_MACID+3),
-               rtl_read_byte(rtlpriv, REG_MACID+4),
-               rtl_read_byte(rtlpriv, REG_MACID+5)));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+                "MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n",
+                rtl_read_byte(rtlpriv, REG_MACID),
+                rtl_read_byte(rtlpriv, REG_MACID+1),
+                rtl_read_byte(rtlpriv, REG_MACID+2),
+                rtl_read_byte(rtlpriv, REG_MACID+3),
+                rtl_read_byte(rtlpriv, REG_MACID+4),
+                rtl_read_byte(rtlpriv, REG_MACID+5));
 }
 
 void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size)
@@ -478,26 +457,26 @@ int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
        case NL80211_IFTYPE_UNSPECIFIED:
                value = NT_NO_LINK;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                       ("Set Network type to NO LINK!\n"));
+                        "Set Network type to NO LINK!\n");
                break;
        case NL80211_IFTYPE_ADHOC:
                value = NT_LINK_AD_HOC;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                       ("Set Network type to Ad Hoc!\n"));
+                        "Set Network type to Ad Hoc!\n");
                break;
        case NL80211_IFTYPE_STATION:
                value = NT_LINK_AP;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                       ("Set Network type to STA!\n"));
+                        "Set Network type to STA!\n");
                break;
        case NL80211_IFTYPE_AP:
                value = NT_AS_AP;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                       ("Set Network type to AP!\n"));
+                        "Set Network type to AP!\n");
                break;
        default:
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                       ("Network type %d not support!\n", type));
+                        "Network type %d not supported!\n", type);
                return -EOPNOTSUPP;
        }
        rtl_write_byte(rtlpriv, (REG_CR + 2), value);
index 626d88e88e26b70c598d902c01747d8341a18965..bf53652e4eddb3428c5e80850c0a3aa59e4346f3 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index e49cf2244c7568af1958a57608804a61763cd23d..8ac3bcca4d4193dbe9f8dd8e1dc011643e34b274 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -44,9 +44,9 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
        u32 original_value, readback_value, bitshift;
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-                                              "rfpath(%#x), bitmask(%#x)\n",
-                                              regaddr, rfpath, bitmask));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
+                regaddr, rfpath, bitmask);
        if (rtlphy->rf_mode != RF_OP_BY_FW) {
                original_value = _rtl92c_phy_rf_serial_read(hw,
                                                            rfpath, regaddr);
@@ -57,9 +57,8 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
        bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
        readback_value = (original_value & bitmask) >> bitshift;
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-                ("regaddr(%#x), rfpath(%#x), "
-                 "bitmask(%#x), original_value(%#x)\n",
-                 regaddr, rfpath, bitmask, original_value));
+                "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
+                regaddr, rfpath, bitmask, original_value);
        return readback_value;
 }
 
@@ -72,8 +71,8 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
        u32 original_value, bitshift;
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-                ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
-                 regaddr, bitmask, data, rfpath));
+                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+                regaddr, bitmask, data, rfpath);
        if (rtlphy->rf_mode != RF_OP_BY_FW) {
                if (bitmask != RFREG_OFFSET_MASK) {
                        original_value = _rtl92c_phy_rf_serial_read(hw,
@@ -97,9 +96,9 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
                }
                _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
        }
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-                                              "bitmask(%#x), data(%#x), rfpath(%#x)\n",
-                                              regaddr, bitmask, data, rfpath));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+                regaddr, bitmask, data, rfpath);
 }
 
 bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw)
@@ -152,11 +151,10 @@ bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
        u32 arraylength;
        u32 *ptrarray;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
        arraylength =  rtlphy->hwparam_tables[MAC_REG].length ;
        ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata;
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                ("Img:RTL8192CEMAC_2T_ARRAY\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n");
        for (i = 0; i < arraylength; i = i + 2)
                rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
        return true;
@@ -202,10 +200,9 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
                                      phy_regarray_table[i + 1]);
                        udelay(1);
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                                ("The phy_regarray_table[0] is %x"
-                                 " Rtl819XPHY_REGArray[1] is %x\n",
-                                 phy_regarray_table[i],
-                                 phy_regarray_table[i + 1]));
+                                "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
+                                phy_regarray_table[i],
+                                phy_regarray_table[i + 1]);
                }
        } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
                for (i = 0; i < agctab_arraylen; i = i + 2) {
@@ -213,10 +210,9 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
                                      agctab_array_table[i + 1]);
                        udelay(1);
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                                ("The agctab_array_table[0] is "
-                                 "%x Rtl819XPHY_REGArray[1] is %x\n",
-                                 agctab_array_table[i],
-                                 agctab_array_table[i + 1]));
+                                "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
+                                agctab_array_table[i],
+                                agctab_array_table[i + 1]);
                }
        }
        return true;
@@ -255,7 +251,7 @@ bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
                }
        } else {
                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-                        ("configtype != BaseBand_Config_PHY_REG\n"));
+                        "configtype != BaseBand_Config_PHY_REG\n");
        }
        return true;
 }
@@ -277,20 +273,20 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
                radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length;
                radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Radio_A:RTL8192CERADIOA_2TARRAY\n"));
+                        "Radio_A:RTL8192CERADIOA_2TARRAY\n");
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n"));
+                        "Radio_B:RTL8192CE_RADIOB_2TARRAY\n");
        } else {
                radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length;
                radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata;
                radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length;
                radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n"));
+                        "Radio_A:RTL8192CE_RADIOA_1TARRAY\n");
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n"));
+                        "Radio_B:RTL8192CE_RADIOB_1TARRAY\n");
        }
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
        switch (rfpath) {
        case RF90_PATH_A:
                for (i = 0; i < radioa_arraylen; i = i + 2) {
@@ -338,11 +334,11 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
                break;
        case RF90_PATH_C:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        case RF90_PATH_D:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        return true;
@@ -357,10 +353,9 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
        u8 reg_bw_opmode;
        u8 reg_prsr_rsc;
 
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-                ("Switch to %s bandwidth\n",
-                 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
-                 "20MHz" : "40MHz"))
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
+                rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+                "20MHz" : "40MHz");
        if (is_hal_stop(rtlhal)) {
                rtlphy->set_bwmode_inprogress = false;
                return;
@@ -381,7 +376,7 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+                        "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
                break;
        }
        switch (rtlphy->current_chan_bw) {
@@ -403,12 +398,12 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+                        "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
                break;
        }
        rtl92cu_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
        rtlphy->set_bwmode_inprogress = false;
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 }
 
 void rtl92cu_bb_block_on(struct ieee80211_hw *hw)
@@ -480,7 +475,7 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
                        do {
                                InitializeCount++;
                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                        ("IPS Set eRf nic enable\n"));
+                                        "IPS Set eRf nic enable\n");
                                rtstatus = rtl_ps_enable_nic(hw);
                        } while ((rtstatus != true)
                                 && (InitializeCount < 10));
@@ -488,10 +483,9 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                          RT_RF_OFF_LEVL_HALT_NIC);
                } else {
                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                ("Set ERFON sleeped:%d ms\n",
-                                 jiffies_to_msecs(jiffies -
-                                                  ppsc->
-                                                  last_sleep_jiffies)));
+                                "Set ERFON sleeped:%d ms\n",
+                                jiffies_to_msecs(jiffies -
+                                                 ppsc->last_sleep_jiffies));
                        ppsc->last_awake_jiffies = jiffies;
                        rtl92ce_phy_set_rf_on(hw);
                }
@@ -513,27 +507,25 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                continue;
                        } else {
                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                        ("eRf Off/Sleep: %d times "
-                                         "TcbBusyQueue[%d] "
-                                         "=%d before doze!\n", (i + 1),
-                                         queue_id,
-                                         skb_queue_len(&ring->queue)));
+                                        "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
+                                        i + 1,
+                                        queue_id,
+                                        skb_queue_len(&ring->queue));
                                udelay(10);
                                i++;
                        }
                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                        ("\nERFOFF: %d times "
-                                         "TcbBusyQueue[%d] = %d !\n",
-                                         MAX_DOZE_WAITING_TIMES_9x,
-                                         queue_id,
-                                         skb_queue_len(&ring->queue)));
+                                        "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
+                                        MAX_DOZE_WAITING_TIMES_9x,
+                                        queue_id,
+                                        skb_queue_len(&ring->queue));
                                break;
                        }
                }
                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                ("IPS Set eRf nic disable\n"));
+                                "IPS Set eRf nic disable\n");
                        rtl_ps_disable_nic(hw);
                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
                } else {
@@ -557,33 +549,30 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                continue;
                        } else {
                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                        ("eRf Off/Sleep: %d times "
-                                         "TcbBusyQueue[%d] =%d before "
-                                         "doze!\n", (i + 1), queue_id,
-                                         skb_queue_len(&ring->queue)));
+                                        "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
+                                        i + 1, queue_id,
+                                        skb_queue_len(&ring->queue));
                                udelay(10);
                                i++;
                        }
                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                        ("\n ERFSLEEP: %d times "
-                                         "TcbBusyQueue[%d] = %d !\n",
-                                         MAX_DOZE_WAITING_TIMES_9x,
-                                         queue_id,
-                                         skb_queue_len(&ring->queue)));
+                                        "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
+                                        MAX_DOZE_WAITING_TIMES_9x,
+                                        queue_id,
+                                        skb_queue_len(&ring->queue));
                                break;
                        }
                }
                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                        ("Set ERFSLEEP awaked:%d ms\n",
-                         jiffies_to_msecs(jiffies -
-                                          ppsc->last_awake_jiffies)));
+                        "Set ERFSLEEP awaked:%d ms\n",
+                        jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
                ppsc->last_sleep_jiffies = jiffies;
                _rtl92c_phy_set_rf_sleep(hw);
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                bresult = false;
                break;
        }
index ff81a61729d7bb1a353c9d05556363e205a21bf4..42b0686604833d87310e9d1d21295585ecc0b9c7 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 7f1be614c998ffead947a309e76c2913fdb8d91b..8b81465c629b9abfae5f337d709c9f45d3d99317 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 1e851aae58db913ebd49cc34878b24ab7d45937d..780c0d98a836122cc74ef535af017de717a48534 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -56,7 +56,7 @@ void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n", bandwidth));
+                        "unknown bandwidth: %#X\n", bandwidth);
                break;
        }
 }
@@ -140,26 +140,26 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
        rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
 
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-                RTXAGC_A_CCK1_MCS32));
+               "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_A_CCK1_MCS32);
 
        tmpval = tx_agc[RF90_PATH_A] >> 8;
        if (mac->mode == WIRELESS_MODE_B)
                tmpval = tmpval & 0xff00ffff;
        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-                RTXAGC_B_CCK11_A_CCK2_11));
+               "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_B_CCK11_A_CCK2_11);
        tmpval = tx_agc[RF90_PATH_B] >> 24;
        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-                RTXAGC_B_CCK11_A_CCK2_11));
+               "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_B_CCK11_A_CCK2_11);
        tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
        rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-                RTXAGC_B_CCK1_55_MCS32));
+               "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_B_CCK1_55_MCS32);
 }
 
 static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
@@ -181,8 +181,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
                    (powerBase0 << 8) | powerBase0;
                *(ofdmbase + i) = powerBase0;
                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                       (" [OFDM power base index rf(%c) = 0x%x]\n",
-                        ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
+                       " [OFDM power base index rf(%c) = 0x%x]\n",
+                       i == 0 ? 'A' : 'B', *(ofdmbase + i));
        }
        for (i = 0; i < 2; i++) {
                if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
@@ -194,8 +194,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
                    (powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
                *(mcsbase + i) = powerBase1;
                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                       (" [MCS power base index rf(%c) = 0x%x]\n",
-                        ((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
+                       " [MCS power base index rf(%c) = 0x%x]\n",
+                       i == 0 ? 'A' : 'B', *(mcsbase + i));
        }
 }
 
@@ -219,8 +219,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                            [chnlgroup][index + (rf ? 8 : 0)]
                            + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("RTK better performance,writeVal(%c) = 0x%x\n",
-                               ((rf == 0) ? 'A' : 'B'), writeVal));
+                               "RTK better performance,writeVal(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeVal);
                        break;
                case 1:
                        if (rtlphy->pwrgroup_cnt == 1)
@@ -244,32 +244,31 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                                        ((index < 2) ? powerBase0[rf] :
                                        powerBase1[rf]);
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("Realtek regulatory, 20MHz, "
-                               "writeVal(%c) = 0x%x\n",
-                               ((rf == 0) ? 'A' : 'B'), writeVal));
+                               "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeVal);
                        break;
                case 2:
                        writeVal = ((index < 2) ? powerBase0[rf] :
                                   powerBase1[rf]);
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("Better regulatory,writeVal(%c) = 0x%x\n",
-                                ((rf == 0) ? 'A' : 'B'), writeVal));
+                               "Better regulatory,writeVal(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeVal);
                        break;
                case 3:
                        chnlgroup = 0;
                        if (rtlphy->current_chan_bw ==
                            HT_CHANNEL_WIDTH_20_40) {
                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                                       ("customer's limit, 40MHzrf(%c) = "
-                                       "0x%x\n", ((rf == 0) ? 'A' : 'B'),
+                                       "customer's limit, 40MHzrf(%c) = 0x%x\n",
+                                       rf == 0 ? 'A' : 'B',
                                        rtlefuse->pwrgroup_ht40[rf]
-                                       [channel - 1]));
+                                       [channel - 1]);
                        } else {
                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                                       ("customer's limit, 20MHz rf(%c) = "
-                                       "0x%x\n", ((rf == 0) ? 'A' : 'B'),
+                                       "customer's limit, 20MHz rf(%c) = 0x%x\n",
+                                       rf == 0 ? 'A' : 'B',
                                        rtlefuse->pwrgroup_ht20[rf]
-                                       [channel - 1]));
+                                       [channel - 1]);
                        }
                        for (i = 0; i < 4; i++) {
                                pwr_diff_limit[i] =
@@ -297,22 +296,22 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                            (pwr_diff_limit[2] << 16) |
                            (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("Customer's limit rf(%c) = 0x%x\n",
-                                ((rf == 0) ? 'A' : 'B'), customer_limit));
+                               "Customer's limit rf(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', customer_limit);
                        writeVal = customer_limit + ((index < 2) ?
                                   powerBase0[rf] : powerBase1[rf]);
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("Customer, writeVal rf(%c)= 0x%x\n",
-                                ((rf == 0) ? 'A' : 'B'), writeVal));
+                               "Customer, writeVal rf(%c)= 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeVal);
                        break;
                default:
                        chnlgroup = 0;
                        writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
                                   [index + (rf ? 8 : 0)] + ((index < 2) ?
                                   powerBase0[rf] : powerBase1[rf]);
-                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better "
-                               "performance, writeValrf(%c) = 0x%x\n",
-                               ((rf == 0) ? 'A' : 'B'), writeVal));
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               "RTK better performance, writeValrf(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeVal);
                        break;
                }
                if (rtlpriv->dm.dynamic_txhighpower_lvl ==
@@ -365,7 +364,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
                        regoffset = regoffset_b[index];
                rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                       ("Set 0x%x = %08x\n", regoffset, writeVal));
+                       "Set 0x%x = %08x\n", regoffset, writeVal);
                if (((get_rf_type(rtlphy) == RF_2T2R) &&
                     (regoffset == RTXAGC_A_MCS15_MCS12 ||
                      regoffset == RTXAGC_B_MCS15_MCS12)) ||
@@ -482,11 +481,11 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
                }
                if (rtstatus != true) {
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                                ("Radio[%d] Fail!!", rfpath));
+                                "Radio[%d] Fail!!", rfpath);
                        goto phy_rf_cfg_fail;
                }
        }
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
        return rtstatus;
 phy_rf_cfg_fail:
        return rtstatus;
index 500a2094b6bbe496078b6c73c2ca9164b26a3390..090fd33a158db1635c14d3ea323a5363f7c82169 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 6d2ca773bbc7d9b6a9db6e28a91d2562c23ea37a..82c85286ab2e25852eb7e45f878fc7b783e07f97 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -41,7 +41,6 @@
 #include "trx.h"
 #include "led.h"
 #include "hw.h"
-#include <linux/vmalloc.h>
 #include <linux/module.h>
 
 MODULE_AUTHOR("Georgia         <georgia@realtek.com>");
@@ -54,7 +53,6 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
 static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
-       const struct firmware *firmware;
        int err;
 
        rtlpriv->dm.dm_initialgain_enable = true;
@@ -62,29 +60,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->dm.disable_framebursting = false;
        rtlpriv->dm.thermalvalue = 0;
        rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
-       rtlpriv->rtlhal.pfirmware = vmalloc(0x4000);
+
+       /* for firmware buf */
+       rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
        if (!rtlpriv->rtlhal.pfirmware) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't alloc buffer for fw.\n"));
+                        "Can't alloc buffer for fw\n");
                return 1;
        }
-       /* request fw */
-       err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
-                       rtlpriv->io.dev);
-       if (err) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Failed to request firmware!\n"));
-               return 1;
-       }
-       if (firmware->size > 0x4000) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Firmware is too big!\n"));
-               release_firmware(firmware);
-               return 1;
-       }
-       memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
-       rtlpriv->rtlhal.fwsize = firmware->size;
-       release_firmware(firmware);
+
+       pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name);
+       rtlpriv->max_fw_size = 0x4000;
+       err = request_firmware_nowait(THIS_MODULE, 1,
+                                     rtlpriv->cfg->fw_name, rtlpriv->io.dev,
+                                     GFP_KERNEL, hw, rtl_fw_cb);
+
 
        return 0;
 }
index 43b1177924ab70073636cc93700865a0be26c3ef..a1310abd0d54605e6bbd1a1cc9f9200bc3ecbe43 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index d57ef5e88a9eb8db066b1a68905166f207946637..966be519edb89b8780778ad0145e4ece80c6621a 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index c3d5cd826cfaebfaf10e60bdda68c75e67d2ea78..4b020e9e30b1eb8a2f559b41c5906e10276c5e9a 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index b3cc7b9499927d3db75af87c0d1d2ebcd66e8b3b..21bc827c5fa60fe207e9c8883fa1d889b46b4db6 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -108,7 +108,7 @@ static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB,
 
        if (bwificfg) { /* for WMM */
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("USB Chip-B & WMM Setting.....\n"));
+                        "USB Chip-B & WMM Setting.....\n");
                ep_map->ep_mapping[RTL_TXQ_BE]  = 2;
                ep_map->ep_mapping[RTL_TXQ_BK]  = 3;
                ep_map->ep_mapping[RTL_TXQ_VI]  = 3;
@@ -118,7 +118,7 @@ static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB,
                ep_map->ep_mapping[RTL_TXQ_HI]  = 2;
        } else { /* typical setting */
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("USB typical Setting.....\n"));
+                        "USB typical Setting.....\n");
                ep_map->ep_mapping[RTL_TXQ_BE]  = 3;
                ep_map->ep_mapping[RTL_TXQ_BK]  = 3;
                ep_map->ep_mapping[RTL_TXQ_VI]  = 2;
@@ -135,7 +135,7 @@ static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool  bwificfg,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        if (bwificfg) { /* for WMM */
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("USB 3EP Setting for WMM.....\n"));
+                        "USB 3EP Setting for WMM.....\n");
                ep_map->ep_mapping[RTL_TXQ_BE]  = 5;
                ep_map->ep_mapping[RTL_TXQ_BK]  = 3;
                ep_map->ep_mapping[RTL_TXQ_VI]  = 3;
@@ -145,7 +145,7 @@ static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool  bwificfg,
                ep_map->ep_mapping[RTL_TXQ_HI]  = 2;
        } else { /* typical setting */
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("USB 3EP Setting for typical.....\n"));
+                        "USB 3EP Setting for typical.....\n");
                ep_map->ep_mapping[RTL_TXQ_BE]  = 5;
                ep_map->ep_mapping[RTL_TXQ_BK]  = 5;
                ep_map->ep_mapping[RTL_TXQ_VI]  = 3;
@@ -244,8 +244,8 @@ u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index)
                break;
        default:
                hw_queue_index = RTL_TXQ_BE;
-               RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n",
-                         mac80211_queue_index));
+               RT_ASSERT(false, "QSLT_BE queue, skb_queue:%d\n",
+                         mac80211_queue_index);
                break;
        }
 out:
@@ -270,23 +270,23 @@ static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw,
        case 0: /* VO */
                qsel = QSLT_VO;
                RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
-                        ("VO queue, set qsel = 0x%x\n", QSLT_VO));
+                        "VO queue, set qsel = 0x%x\n", QSLT_VO);
                break;
        case 1: /* VI */
                qsel = QSLT_VI;
                RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
-                        ("VI queue, set qsel = 0x%x\n", QSLT_VI));
+                        "VI queue, set qsel = 0x%x\n", QSLT_VI);
                break;
        case 3: /* BK */
                qsel = QSLT_BK;
                RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
-                        ("BK queue, set qsel = 0x%x\n", QSLT_BK));
+                        "BK queue, set qsel = 0x%x\n", QSLT_BK);
                break;
        case 2: /* BE */
        default:
                qsel = QSLT_BE;
                RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
-                        ("BE queue, set qsel = 0x%x\n", QSLT_BE));
+                        "BE queue, set qsel = 0x%x\n", QSLT_BE);
                break;
        }
 out:
@@ -422,17 +422,17 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
        bv = ieee80211_is_probe_resp(fc);
        if (bv)
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("Got probe response frame.\n"));
+                        "Got probe response frame\n");
        if (ieee80211_is_beacon(fc))
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("Got beacon frame.\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got beacon frame\n");
        if (ieee80211_is_data(fc))
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Got data frame.\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got data frame\n");
        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                ("Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:"
-                "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1],
-                (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4],
-                (u32)hdr->addr1[5]));
+                "Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\n",
+                fc,
+                (u32)hdr->addr1[0], (u32)hdr->addr1[1],
+                (u32)hdr->addr1[2], (u32)hdr->addr1[3],
+                (u32)hdr->addr1[4], (u32)hdr->addr1[5]);
        memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
        ieee80211_rx_irqsafe(hw, skb);
 }
@@ -594,7 +594,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
        if (ieee80211_is_data_qos(fc)) {
                if (mac->rdg_en) {
                        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-                                ("Enable RDG function.\n"));
+                                "Enable RDG function\n");
                        SET_TX_DESC_RDG_ENABLE(txdesc, 1);
                        SET_TX_DESC_HTC(txdesc, 1);
                }
@@ -620,7 +620,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
                SET_TX_DESC_BMC(txdesc, 1);
        _rtl_fill_usb_tx_desc(txdesc);
        _rtl_tx_desc_checksum(txdesc);
-       RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, (" %s ==>\n", __func__));
+       RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n");
 }
 
 void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
@@ -677,7 +677,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
                SET_TX_DESC_HWSEQ_EN(pdesc, 1);
                SET_TX_DESC_PKT_ID(pdesc, 8);
        }
-       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n",
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content",
                      pdesc, RTL_TX_DESC_SIZE);
 }
 
index 53de5f66e2424803a6d9424fb4d301439a8d7155..332b06e78b00d8e9fb849e03709fcb0b412849b0 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 946304771748fab0781c65991b33882f982c6d70..eafdf76ed64db95c42972e7fb725ad4b7a4f3a18 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 3cd0736fe8e17230b52d2f0727be33af59c5ddf7..9fda1af44b383f219cdf4ed45ebaf5019c81db6f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -246,23 +246,21 @@ static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
                rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
                rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
        }
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Fast_Fsync_fail = %x, "
-                "Cnt_SB_Search_fail = %x\n",
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                "Cnt_Fast_Fsync_fail = %x, Cnt_SB_Search_fail = %x\n",
                 falsealm_cnt->cnt_fast_fsync_fail,
-                falsealm_cnt->cnt_sb_search_fail));
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Parity_Fail = %x, "
-                "Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, "
-                "Cnt_Mcs_fail = %x\n",
+                falsealm_cnt->cnt_sb_search_fail);
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                "Cnt_Parity_Fail = %x, Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, Cnt_Mcs_fail = %x\n",
                 falsealm_cnt->cnt_parity_fail,
                 falsealm_cnt->cnt_rate_illegal,
                 falsealm_cnt->cnt_crc8_fail,
-                falsealm_cnt->cnt_mcs_fail));
+                falsealm_cnt->cnt_mcs_fail);
        RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-                ("Cnt_Ofdm_fail = %x, " "Cnt_Cck_fail = %x, "
-                "Cnt_all = %x\n",
+                "Cnt_Ofdm_fail = %x, Cnt_Cck_fail = %x, Cnt_all = %x\n",
                 falsealm_cnt->cnt_ofdm_fail,
                 falsealm_cnt->cnt_cck_fail,
-                falsealm_cnt->cnt_all));
+                falsealm_cnt->cnt_all);
 }
 
 static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw)
@@ -275,7 +273,7 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw)
            (rtlpriv->dm.UNDEC_SM_PWDB == 0)) {
                de_digtable.min_undecorated_pwdb_for_dm = 0;
                RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
-                        ("Not connected to any\n"));
+                        "Not connected to any\n");
        }
        if (mac->link_state >= MAC80211_LINKED) {
                if (mac->opmode == NL80211_IFTYPE_AP ||
@@ -283,25 +281,25 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw)
                        de_digtable.min_undecorated_pwdb_for_dm =
                            rtlpriv->dm.UNDEC_SM_PWDB;
                        RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
-                                ("AP Client PWDB = 0x%lx\n",
-                                 rtlpriv->dm.UNDEC_SM_PWDB));
+                                "AP Client PWDB = 0x%lx\n",
+                                rtlpriv->dm.UNDEC_SM_PWDB);
                } else {
                        de_digtable.min_undecorated_pwdb_for_dm =
                            rtlpriv->dm.undecorated_smoothed_pwdb;
                        RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
-                                ("STA Default Port PWDB = 0x%x\n",
-                                 de_digtable.min_undecorated_pwdb_for_dm));
+                                "STA Default Port PWDB = 0x%x\n",
+                                de_digtable.min_undecorated_pwdb_for_dm);
                }
        } else {
                de_digtable.min_undecorated_pwdb_for_dm =
                    rtlpriv->dm.UNDEC_SM_PWDB;
                RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
-                        ("AP Ext Port or disconnet PWDB = 0x%x\n",
-                         de_digtable.min_undecorated_pwdb_for_dm));
+                        "AP Ext Port or disconnect PWDB = 0x%x\n",
+                        de_digtable.min_undecorated_pwdb_for_dm);
        }
 
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n",
-                       de_digtable.min_undecorated_pwdb_for_dm));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
+                de_digtable.min_undecorated_pwdb_for_dm);
 }
 
 static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
@@ -340,14 +338,14 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
                }
                de_digtable.pre_cck_pd_state = de_digtable.cur_cck_pd_state;
        }
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CurSTAConnectState=%s\n",
-                (de_digtable.cursta_connectctate == DIG_STA_CONNECT ?
-                "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT")));
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CCKPDStage=%s\n",
-                (de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ?
-                "Low RSSI " : "High RSSI ")));
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("is92d single phy =%x\n",
-                IS_92D_SINGLEPHY(rtlpriv->rtlhal.version)));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n",
+                de_digtable.cursta_connectctate == DIG_STA_CONNECT ?
+                "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT");
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n",
+                de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ?
+                "Low RSSI " : "High RSSI ");
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "is92d single phy =%x\n",
+                IS_92D_SINGLEPHY(rtlpriv->rtlhal.version));
 
 }
 
@@ -355,12 +353,12 @@ void rtl92d_dm_write_dig(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("cur_igvalue = 0x%x, "
-                "pre_igvalue = 0x%x, backoff_val = %d\n",
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",
                 de_digtable.cur_igvalue, de_digtable.pre_igvalue,
-                de_digtable.backoff_val));
+                de_digtable.backoff_val);
        if (de_digtable.dig_enable_flag == false) {
-               RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("DIG is disabled\n"));
+               RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n");
                de_digtable.pre_igvalue = 0x17;
                return;
        }
@@ -377,22 +375,21 @@ static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv)
 {
        if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) &&
            (rtlpriv->mac80211.vendor == PEER_CISCO)) {
-               RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-                        ("IOT_PEER = CISCO\n"));
+               RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n");
                if (de_digtable.last_min_undecorated_pwdb_for_dm >= 50
                    && de_digtable.min_undecorated_pwdb_for_dm < 50) {
                        rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00);
                        RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-                                ("Early Mode Off\n"));
+                                "Early Mode Off\n");
                } else if (de_digtable.last_min_undecorated_pwdb_for_dm <= 55 &&
                           de_digtable.min_undecorated_pwdb_for_dm > 55) {
                        rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
                        RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-                                ("Early Mode On\n"));
+                                "Early Mode On\n");
                }
        } else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) {
                rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
-               RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Early Mode On\n"));
+               RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode On\n");
        }
 }
 
@@ -402,7 +399,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
        u8 value_igi = de_digtable.cur_igvalue;
        struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
 
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("==>\n"));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n");
        if (rtlpriv->rtlhal.earlymode_enable) {
                rtl92d_early_mode_enabled(rtlpriv);
                de_digtable.last_min_undecorated_pwdb_for_dm =
@@ -421,7 +418,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
        /* Not STA mode return tmp */
        if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
                return;
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("progress\n"));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n");
        /* Decide the current status and if modify initial gain or not */
        if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
                de_digtable.cursta_connectctate = DIG_STA_CONNECT;
@@ -438,16 +435,16 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
        else if (falsealm_cnt->cnt_all >= DM_DIG_FA_TH2)
                value_igi += 2;
        RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-                ("dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n",
-                de_digtable.large_fa_hit, de_digtable.forbidden_igi));
+                "dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n",
+                de_digtable.large_fa_hit, de_digtable.forbidden_igi);
        RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-                ("dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n",
-                de_digtable.recover_cnt, de_digtable.rx_gain_range_min));
+                "dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n",
+                de_digtable.recover_cnt, de_digtable.rx_gain_range_min);
 
        /* deal with abnorally large false alarm */
        if (falsealm_cnt->cnt_all > 10000) {
                RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-                        ("dm_DIG(): Abnornally false alarm case.\n"));
+                        "dm_DIG(): Abnormally false alarm case\n");
 
                de_digtable.large_fa_hit++;
                if (de_digtable.forbidden_igi < de_digtable.cur_igvalue) {
@@ -486,11 +483,11 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
                }
        }
        RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-                ("dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n",
-                 de_digtable.large_fa_hit, de_digtable.forbidden_igi));
+                "dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n",
+                de_digtable.large_fa_hit, de_digtable.forbidden_igi);
        RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-                ("dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n",
-                 de_digtable.recover_cnt, de_digtable.rx_gain_range_min));
+                "dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n",
+                de_digtable.recover_cnt, de_digtable.rx_gain_range_min);
 
        if (value_igi > DM_DIG_MAX)
                value_igi = DM_DIG_MAX;
@@ -500,7 +497,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
        rtl92d_dm_write_dig(hw);
        if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G)
                rtl92d_dm_cck_packet_detection_thresh(hw);
-       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("<<==\n"));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "<<==\n");
 }
 
 static void rtl92d_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
@@ -528,7 +525,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
        if ((mac->link_state < MAC80211_LINKED) &&
            (rtlpriv->dm.UNDEC_SM_PWDB == 0)) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-                        ("Not connected to any\n"));
+                        "Not connected to any\n");
                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
                rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
                return;
@@ -538,40 +535,40 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
                        undecorated_smoothed_pwdb =
                            rtlpriv->dm.UNDEC_SM_PWDB;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("IBSS Client PWDB = 0x%lx\n",
-                                 undecorated_smoothed_pwdb));
+                                "IBSS Client PWDB = 0x%lx\n",
+                                undecorated_smoothed_pwdb);
                } else {
                        undecorated_smoothed_pwdb =
                            rtlpriv->dm.undecorated_smoothed_pwdb;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("STA Default Port PWDB = 0x%lx\n",
-                                 undecorated_smoothed_pwdb));
+                                "STA Default Port PWDB = 0x%lx\n",
+                                undecorated_smoothed_pwdb);
                }
        } else {
                undecorated_smoothed_pwdb =
                    rtlpriv->dm.UNDEC_SM_PWDB;
 
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("AP Ext Port PWDB = 0x%lx\n",
-                         undecorated_smoothed_pwdb));
+                        "AP Ext Port PWDB = 0x%lx\n",
+                        undecorated_smoothed_pwdb);
        }
        if (rtlhal->current_bandtype == BAND_ON_5G) {
                if (undecorated_smoothed_pwdb >= 0x33) {
                        rtlpriv->dm.dynamic_txhighpower_lvl =
                                                 TXHIGHPWRLEVEL_LEVEL2;
                        RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD,
-                                ("5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"));
+                                "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n");
                } else if ((undecorated_smoothed_pwdb < 0x33)
                           && (undecorated_smoothed_pwdb >= 0x2b)) {
                        rtlpriv->dm.dynamic_txhighpower_lvl =
                                                 TXHIGHPWRLEVEL_LEVEL1;
                        RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD,
-                                ("5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"));
+                                "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n");
                } else if (undecorated_smoothed_pwdb < 0x2b) {
                        rtlpriv->dm.dynamic_txhighpower_lvl =
                                                 TXHIGHPWRLEVEL_NORMAL;
                        RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD,
-                                ("5G:TxHighPwrLevel_Normal\n"));
+                                "5G:TxHighPwrLevel_Normal\n");
                }
        } else {
                if (undecorated_smoothed_pwdb >=
@@ -579,7 +576,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
                        rtlpriv->dm.dynamic_txhighpower_lvl =
                                                 TXHIGHPWRLEVEL_LEVEL2;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+                                "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
                } else
                    if ((undecorated_smoothed_pwdb <
                         (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3))
@@ -589,19 +586,19 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
                        rtlpriv->dm.dynamic_txhighpower_lvl =
                                                 TXHIGHPWRLEVEL_LEVEL1;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+                                "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
                } else if (undecorated_smoothed_pwdb <
                           (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
                        rtlpriv->dm.dynamic_txhighpower_lvl =
                                                 TXHIGHPWRLEVEL_NORMAL;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("TXHIGHPWRLEVEL_NORMAL\n"));
+                                "TXHIGHPWRLEVEL_NORMAL\n");
                }
        }
        if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
-                         rtlphy->current_channel));
+                        "PHY_SetTxPowerLevel8192S() Channel = %d\n",
+                        rtlphy->current_channel);
                rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel);
        }
        rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
@@ -717,7 +714,7 @@ static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw)
        u4tmp = (index_mapping[(rtlpriv->efuse.eeprom_thermalmeter -
                                rtlpriv->dm.thermalvalue_rxgain)]) << 12;
        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                ("===> Rx Gain %x\n", u4tmp));
+                "===> Rx Gain %x\n", u4tmp);
        for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++)
                rtl_set_rfreg(hw, i, 0x3C, BRFREGOFFSETMASK,
                              (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp);
@@ -741,27 +738,22 @@ static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg,
                        if (!memcmp((void *)&temp_cck,
                            (void *)&cckswing_table_ch14[i][2], 4)) {
                                *cck_index_old = (u8) i;
-                               RT_TRACE(rtlpriv,
-                                        COMP_POWER_TRACKING,
-                                        DBG_LOUD,
-                                        ("Initial reg0x%x = 0x%lx, "
-                                         "cck_index=0x%x, ch 14 %d\n",
-                                         RCCK0_TXFILTER2,
-                                         temp_cck, *cck_index_old,
-                                         rtlpriv->dm.cck_inch14));
+                               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                        "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n",
+                                        RCCK0_TXFILTER2, temp_cck,
+                                        *cck_index_old,
+                                        rtlpriv->dm.cck_inch14);
                                break;
                        }
                } else {
                        if (!memcmp((void *) &temp_cck,
                            &cckswing_table_ch1ch13[i][2], 4)) {
                                *cck_index_old = (u8) i;
-                               RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
-                                        DBG_LOUD,
-                                        ("Initial reg0x%x = 0x%lx, "
-                                        "cck_index = 0x%x, ch14 %d\n",
-                                        RCCK0_TXFILTER2,
-                                        temp_cck, *cck_index_old,
-                                        rtlpriv->dm.cck_inch14));
+                               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                        "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
+                                        RCCK0_TXFILTER2, temp_cck,
+                                        *cck_index_old,
+                                        rtlpriv->dm.cck_inch14);
                                break;
                        }
                }
@@ -884,12 +876,12 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
        };
 
        rtlpriv->dm.txpower_trackinginit = true;
-       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("\n"));
+       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "\n");
        thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xf800);
        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
-                "eeprom_thermalmeter 0x%x\n", thermalvalue,
-                rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter));
+                "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
+                thermalvalue,
+                rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter);
        rtl92d_phy_ap_calibrate(hw, (thermalvalue -
                                     rtlefuse->eeprom_thermalmeter));
        if (is2t)
@@ -904,10 +896,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
                                ofdm_index_old[0] = (u8) i;
 
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                        ("Initial pathA ele_d reg0x%x = 0x%lx,"
-                                        " ofdm_index=0x%x\n",
+                                        "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
                                         ROFDM0_XATxIQIMBALANCE,
-                                        ele_d, ofdm_index_old[0]));
+                                        ele_d, ofdm_index_old[0]);
                                break;
                        }
                }
@@ -920,11 +911,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
                                        ofdm_index_old[1] = (u8) i;
                                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
                                                 DBG_LOUD,
-                                                ("Initial pathB ele_d reg "
-                                                "0x%x = 0x%lx, ofdm_index "
-                                                "= 0x%x\n",
+                                                "Initial pathB ele_d reg 0x%x = 0x%lx, ofdm_index = 0x%x\n",
                                                 ROFDM0_XBTxIQIMBALANCE, ele_d,
-                                                ofdm_index_old[1]));
+                                                ofdm_index_old[1]);
                                        break;
                                }
                        }
@@ -952,7 +941,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
                                rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
                        rtlpriv->dm.cck_index = cck_index_old;
                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                ("reload ofdm index for band switch\n"));
+                                "reload ofdm index for band switch\n");
                }
                rtlpriv->dm.thermalvalue_avg
                            [rtlpriv->dm.thermalvalue_avg_index] = thermalvalue;
@@ -995,12 +984,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
                        (thermalvalue - rtlpriv->dm.thermalvalue_rxgain) :
                        (rtlpriv->dm.thermalvalue_rxgain - thermalvalue);
                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                        ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x"
-                         " eeprom_thermalmeter 0x%x delta 0x%x "
-                         "delta_lck 0x%x delta_iqk 0x%x\n",
-                         thermalvalue, rtlpriv->dm.thermalvalue,
-                         rtlefuse->eeprom_thermalmeter, delta, delta_lck,
-                         delta_iqk));
+                        "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n",
+                        thermalvalue, rtlpriv->dm.thermalvalue,
+                        rtlefuse->eeprom_thermalmeter, delta, delta_lck,
+                        delta_iqk);
                if ((delta_lck > rtlefuse->delta_lck) &&
                    (rtlefuse->delta_lck != 0)) {
                        rtlpriv->dm.thermalvalue_lck = thermalvalue;
@@ -1036,17 +1023,15 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
                        }
                        if (is2t) {
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                        ("temp OFDM_A_index=0x%x, OFDM_B_index"
-                                        " = 0x%x,cck_index=0x%x\n",
-                                         rtlpriv->dm.ofdm_index[0],
-                                         rtlpriv->dm.ofdm_index[1],
-                                         rtlpriv->dm.cck_index));
+                                        "temp OFDM_A_index=0x%x, OFDM_B_index = 0x%x,cck_index=0x%x\n",
+                                        rtlpriv->dm.ofdm_index[0],
+                                        rtlpriv->dm.ofdm_index[1],
+                                        rtlpriv->dm.cck_index);
                        } else {
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                        ("temp OFDM_A_index=0x%x,cck_index = "
-                                        "0x%x\n",
-                                         rtlpriv->dm.ofdm_index[0],
-                                                       rtlpriv->dm.cck_index));
+                                        "temp OFDM_A_index=0x%x,cck_index = 0x%x\n",
+                                        rtlpriv->dm.ofdm_index[0],
+                                        rtlpriv->dm.cck_index);
                        }
                        for (i = 0; i < rf; i++) {
                                if (ofdm_index[i] > OFDM_TABLE_SIZE_92D - 1)
@@ -1070,15 +1055,13 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
                        }
                        if (is2t) {
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                        ("new OFDM_A_index=0x%x, OFDM_B_index "
-                                        "= 0x%x, cck_index=0x%x\n",
+                                        "new OFDM_A_index=0x%x, OFDM_B_index = 0x%x, cck_index=0x%x\n",
                                         ofdm_index[0], ofdm_index[1],
-                                        cck_index));
+                                        cck_index);
                        } else {
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                        ("new OFDM_A_index=0x%x,cck_index = "
-                                        "0x%x\n",
-                                         ofdm_index[0], cck_index));
+                                        "new OFDM_A_index=0x%x,cck_index = 0x%x\n",
+                                        ofdm_index[0], cck_index);
                        }
                        ele_d = (ofdmswing_table[(u8) ofdm_index[0]] &
                                                 0xFFC00000) >> 22;
@@ -1124,12 +1107,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
                        }
 
                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                ("TxPwrTracking for interface %d path A: X ="
-                                " 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = "
-                                "0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = "
-                                "0x%lx\n", rtlhal->interfaceindex,
+                                "TxPwrTracking for interface %d path A: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = 0x%lx\n",
+                                rtlhal->interfaceindex,
                                 val_x, val_y, ele_a, ele_c, ele_d,
-                                val_x, val_y));
+                                val_x, val_y);
 
                        if (rtlhal->current_bandtype == BAND_ON_2_4G) {
                                /* Adjust CCK according to IQK result */
@@ -1232,20 +1213,16 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
                                                      BIT(28), 0x00);
                                }
                                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                        ("TxPwrTracking path B: X = 0x%lx, "
-                                        "Y = 0x%lx ele_A = 0x%lx ele_C = 0x"
-                                        "%lx ele_D = 0x%lx 0xeb4 = 0x%lx "
-                                        "0xebc = 0x%lx\n",
-                                         val_x, val_y, ele_a, ele_c,
-                                         ele_d, val_x, val_y));
+                                        "TxPwrTracking path B: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xeb4 = 0x%lx 0xebc = 0x%lx\n",
+                                        val_x, val_y, ele_a, ele_c,
+                                        ele_d, val_x, val_y);
                        }
                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                                ("TxPwrTracking 0xc80 = 0x%x, 0xc94 = "
-                                "0x%x RF 0x24 = 0x%x\n",
+                                "TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n",
                                 rtl_get_bbreg(hw, 0xc80, BMASKDWORD),
                                 rtl_get_bbreg(hw, 0xc94, BMASKDWORD),
                                 rtl_get_rfreg(hw, RF90_PATH_A, 0x24,
-                                BRFREGOFFSETMASK)));
+                                              BRFREGOFFSETMASK));
                }
                if ((delta_iqk > rtlefuse->delta_iqk) &&
                    (rtlefuse->delta_iqk != 0)) {
@@ -1262,7 +1239,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
                        rtlpriv->dm.thermalvalue = thermalvalue;
        }
 
-       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n"));
+       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n");
 }
 
 static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
@@ -1273,8 +1250,8 @@ static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
        rtlpriv->dm.txpower_trackinginit = false;
        rtlpriv->dm.txpower_track_control = true;
        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                ("pMgntInfo->txpower_tracking = %d\n",
-                rtlpriv->dm.txpower_tracking));
+                "pMgntInfo->txpower_tracking = %d\n",
+                rtlpriv->dm.txpower_tracking);
 }
 
 void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw)
@@ -1289,12 +1266,12 @@ void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw)
                rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) |
                              BIT(16), 0x03);
                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                        ("Trigger 92S Thermal Meter!!\n"));
+                        "Trigger 92S Thermal Meter!!\n");
                tm_trigger = 1;
                return;
        } else {
                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                        ("Schedule TxPowerTracking direct call!!\n"));
+                        "Schedule TxPowerTracking direct call!!\n");
                rtl92d_dm_txpower_tracking_callback_thermalmeter(hw);
                tm_trigger = 0;
        }
index 69354657f0f5d7d64d537abe4f40ec2f2043b88d..91030ec8ac3e9e2eef67ea9913ffb8e9a3d5e8d9 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 82f060bdbc0b7fa8b22b14b96c8b478c977758ee..f548a8d0068d22d672bf505a9e9f071f1171560e 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -124,14 +124,14 @@ static void _rtl92d_write_fw(struct ieee80211_hw *hw,
        u32 pagenums, remainSize;
        u32 page, offset;
 
-       RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
+       RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
                _rtl92d_fill_dummy(bufferPtr, &size);
        pagenums = size / FW_8192D_PAGE_SIZE;
        remainSize = size % FW_8192D_PAGE_SIZE;
        if (pagenums > 8) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Page numbers should not greater then 8\n"));
+                        "Page numbers should not greater then 8\n");
        }
        for (page = 0; page < pagenums; page++) {
                offset = page * FW_8192D_PAGE_SIZE;
@@ -158,12 +158,12 @@ static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
                 (!(value32 & FWDL_ChkSum_rpt)));
        if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
-                        value32));
+                        "chksum report faill ! REG_MCUFWDL:0x%08x\n",
+                        value32);
                return -EIO;
        }
        RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
-                ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
+                "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32);
        value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
        value32 |= MCUFWDL_RDY;
        rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
@@ -186,9 +186,9 @@ void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
                udelay(50);
                u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
        }
-       RT_ASSERT((delay > 0), ("8051 reset failed!\n"));
+       RT_ASSERT((delay > 0), "8051 reset failed!\n");
        RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-                ("=====> 8051 reset success (%d) .\n", delay));
+                "=====> 8051 reset success (%d)\n", delay);
 }
 
 static int _rtl92d_fw_init(struct ieee80211_hw *hw)
@@ -197,7 +197,7 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        u32 counter;
 
-       RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, ("FW already have download\n"));
+       RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n");
        /* polling for FW ready */
        counter = 0;
        do {
@@ -205,10 +205,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
                        if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
                            MAC0_READY) {
                                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-                                        ("Polling FW ready success!! "
-                                        "REG_MCUFWDL: 0x%x .\n",
+                                        "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
                                         rtl_read_byte(rtlpriv,
-                                        FW_MAC0_READY)));
+                                                      FW_MAC0_READY));
                                return 0;
                        }
                        udelay(5);
@@ -216,10 +215,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
                        if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
                            MAC1_READY) {
                                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-                                        ("Polling FW ready success!! "
-                                        "REG_MCUFWDL: 0x%x .\n",
+                                        "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
                                         rtl_read_byte(rtlpriv,
-                                                      FW_MAC1_READY)));
+                                                      FW_MAC1_READY));
                                return 0;
                        }
                        udelay(5);
@@ -228,18 +226,16 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
 
        if (rtlhal->interfaceindex == 0) {
                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-                        ("Polling FW ready fail!! MAC0 FW init not ready: "
-                        "0x%x .\n",
-                        rtl_read_byte(rtlpriv, FW_MAC0_READY)));
+                        "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n",
+                        rtl_read_byte(rtlpriv, FW_MAC0_READY));
        } else {
                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-                        ("Polling FW ready fail!! MAC1 FW init not ready: "
-                        "0x%x .\n",
-                        rtl_read_byte(rtlpriv, FW_MAC1_READY)));
+                        "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n",
+                        rtl_read_byte(rtlpriv, FW_MAC1_READY));
        }
        RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-                ("Polling FW ready fail!! REG_MCUFWDL:0x%08ul .\n",
-                rtl_read_dword(rtlpriv, REG_MCUFWDL)));
+                "Polling FW ready fail!! REG_MCUFWDL:0x%08ul\n",
+                rtl_read_dword(rtlpriv, REG_MCUFWDL));
        return -1;
 }
 
@@ -257,20 +253,20 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
        bool fw_downloaded = false, fwdl_in_process = false;
        unsigned long flags;
 
-       if (!rtlhal->pfirmware)
+       if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
                return 1;
        fwsize = rtlhal->fwsize;
        pfwheader = (u8 *) rtlhal->pfirmware;
        pfwdata = (u8 *) rtlhal->pfirmware;
        rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
        rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, (" FirmwareVersion(%d),"
-                "FirmwareSubVersion(%d), Signature(%#x)\n",
-                rtlhal->fw_version,    rtlhal->fw_subversion,
-                GET_FIRMWARE_HDR_SIGNATURE(pfwheader)));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",
+                rtlhal->fw_version, rtlhal->fw_subversion,
+                GET_FIRMWARE_HDR_SIGNATURE(pfwheader));
        if (IS_FW_HEADER_EXIST(pfwheader)) {
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        ("Shift 32 bytes for FW header!!\n"));
+                        "Shift 32 bytes for FW header!!\n");
                pfwdata = pfwdata + 32;
                fwsize = fwsize - 32;
        }
@@ -302,8 +298,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
                                break;
                        else
                                RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-                                        ("Wait for another mac "
-                                        "download fw\n"));
+                                        "Wait for another mac download fw\n");
                }
                spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
                value = rtl_read_byte(rtlpriv, 0x1f);
@@ -337,11 +332,10 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
        spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("fw is not ready to run!\n"));
+                        "fw is not ready to run!\n");
                goto exit;
        } else {
-               RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
-                        ("fw is ready to run!\n"));
+               RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "fw is ready to run!\n");
        }
 exit:
        err = _rtl92d_fw_init(hw);
@@ -381,24 +375,24 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
 
        if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                        ("Return as RF is off!!!\n"));
+                        "Return as RF is off!!!\n");
                return;
        }
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
        while (true) {
                spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
                if (rtlhal->h2c_setinprogress) {
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("H2C set in progress! Wait to set.."
-                                "element_id(%d).\n", element_id));
+                                "H2C set in progress! Wait to set..element_id(%d)\n",
+                                element_id);
 
                        while (rtlhal->h2c_setinprogress) {
                                spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
                                                       flag);
                                h2c_waitcounter++;
                                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                        ("Wait 100 us (%d times)...\n",
-                                        h2c_waitcounter));
+                                        "Wait 100 us (%d times)...\n",
+                                        h2c_waitcounter);
                                udelay(100);
 
                                if (h2c_waitcounter > 1000)
@@ -418,8 +412,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
                wait_writeh2c_limmit--;
                if (wait_writeh2c_limmit == 0) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Write H2C fail because no trigger "
-                                "for FW INT!\n"));
+                                "Write H2C fail because no trigger for FW INT!\n");
                        break;
                }
                boxnum = rtlhal->last_hmeboxnum;
@@ -442,7 +435,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("switch case not process\n"));
+                                "switch case not processed\n");
                        break;
                }
                isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
@@ -450,29 +443,29 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
                        wait_h2c_limmit--;
                        if (wait_h2c_limmit == 0) {
                                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                        ("Wating too long for FW read "
-                                        "clear HMEBox(%d)!\n", boxnum));
+                                        "Waiting too long for FW read clear HMEBox(%d)!\n",
+                                        boxnum);
                                break;
                        }
                        udelay(10);
                        isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
                        u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("Wating for FW read clear HMEBox(%d)!!! "
-                                "0x1BF = %2x\n", boxnum, u1b_tmp));
+                                "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
+                                boxnum, u1b_tmp);
                }
                if (!isfw_read) {
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("Write H2C register BOX[%d] fail!!!!! "
-                                "Fw do not read.\n", boxnum));
+                                "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
+                                boxnum);
                        break;
                }
                memset(boxcontent, 0, sizeof(boxcontent));
                memset(boxextcontent, 0, sizeof(boxextcontent));
                boxcontent[0] = element_id;
                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                        ("Write element_id box_reg(%4x) = %2x\n",
-                        box_reg, element_id));
+                        "Write element_id box_reg(%4x) = %2x\n",
+                        box_reg, element_id);
                switch (cmd_len) {
                case 1:
                        boxcontent[0] &= ~(BIT(7));
@@ -519,7 +512,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                               ("switch case not process\n"));
+                                "switch case not processed\n");
                        break;
                }
                bwrite_sucess = true;
@@ -527,26 +520,20 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
                if (rtlhal->last_hmeboxnum == 4)
                        rtlhal->last_hmeboxnum = 0;
                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                        ("pHalData->last_hmeboxnum  = %d\n",
-                         rtlhal->last_hmeboxnum));
+                        "pHalData->last_hmeboxnum  = %d\n",
+                        rtlhal->last_hmeboxnum);
        }
        spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
        rtlhal->h2c_setinprogress = false;
        spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
 }
 
 void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
                         u8 element_id, u32 cmd_len, u8 *cmdbuffer)
 {
-       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        u32 tmp_cmdbuf[2];
 
-       if (rtlhal->fw_ready == false) {
-               RT_ASSERT(false, ("return H2C cmd because of Fw "
-                                 "download fail!!!\n"));
-               return;
-       }
        memset(tmp_cmdbuf, 0, 8);
        memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
        _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
@@ -559,13 +546,13 @@ void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
        u8 u1_h2c_set_pwrmode[3] = { 0 };
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 
-       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
+       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
        SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
        SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
        SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
                                              ppsc->reg_max_lps_awakeintvl);
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-                     "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
+                     "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode",
                      u1_h2c_set_pwrmode, 3);
        rtl92d_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
 }
@@ -757,28 +744,32 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
        SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
        totalpacketlen = TOTAL_RESERVED_PKT_LEN;
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
-                     "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+                     "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
                      &reserved_page_packet[0], totalpacketlen);
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-                     "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+                     "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
                      u1RsvdPageLoc, 3);
        skb = dev_alloc_skb(totalpacketlen);
-       memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet,
-               totalpacketlen);
-       rtstatus = _rtl92d_cmd_send_packet(hw, skb);
+       if (!skb) {
+               dlok = false;
+       } else {
+               memcpy((u8 *) skb_put(skb, totalpacketlen),
+                       &reserved_page_packet, totalpacketlen);
+               rtstatus = _rtl92d_cmd_send_packet(hw, skb);
 
-       if (rtstatus)
-               dlok = true;
+               if (rtstatus)
+                       dlok = true;
+       }
        if (dlok) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                       ("Set RSVD page location to Fw.\n"));
+                        "Set RSVD page location to Fw\n");
                RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-                             "H2C_RSVDPAGE:\n", u1RsvdPageLoc, 3);
+                             "H2C_RSVDPAGE", u1RsvdPageLoc, 3);
                rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
                        sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
        } else
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                       ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
+                        "Set RSVD page location to Fw FAIL!!!!!!\n");
 }
 
 void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
index 0c4d489eaa487ca572a21a085bf77c5a01052acb..1ffacdda734c96222ff59370dd917a3d73cb28e3 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 9d89d7ccdafb7fa389499ae5d9d6df1be75ddc0b..7d877125db29e12da4b12cad901f2f8bc641c331 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -166,7 +166,7 @@ void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
 }
@@ -230,7 +230,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                u8 e_aci;
 
                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                        ("HW_VAR_SLOT_TIME %x\n", val[0]));
+                        "HW_VAR_SLOT_TIME %x\n", val[0]);
                rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
                for (e_aci = 0; e_aci < AC_MAX; e_aci++)
                        rtlpriv->cfg->ops->set_hw_reg(hw,
@@ -261,8 +261,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                              min_spacing_to_set);
                        *val = min_spacing_to_set;
                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
-                                mac->min_space_cfg));
+                                "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+                                mac->min_space_cfg);
                        rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
                                       mac->min_space_cfg);
                }
@@ -275,8 +275,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg;
                mac->min_space_cfg |= (density_to_set << 3);
                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                        ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
-                        mac->min_space_cfg));
+                        "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+                        mac->min_space_cfg);
                rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
                               mac->min_space_cfg);
                break;
@@ -310,8 +310,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                        }
                        rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, regtoSet);
                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
-                                factor_toset));
+                                "Set HW_VAR_AMPDU_FACTOR: %#x\n",
+                                factor_toset);
                }
                break;
        }
@@ -344,8 +344,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                break;
                        default:
                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                        ("HW_VAR_ACM_CTRL acm set "
-                                        "failed: eACI is %d\n", acm));
+                                        "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
+                                        acm);
                                break;
                        }
                } else {
@@ -361,13 +361,13 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                break;
                        default:
                                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                        ("switch case not process\n"));
+                                        "switch case not processed\n");
                                break;
                        }
                }
                RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
-                        ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
-                        "Write 0x%X\n", acm_ctrl));
+                        "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
+                        acm_ctrl);
                rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
                break;
        }
@@ -502,7 +502,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
        }
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
 }
@@ -522,8 +522,8 @@ static bool _rtl92de_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
                        break;
                if (count > POLLING_LLT_THRESHOLD) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Failed to polling write LLT done at "
-                                 "address %d!\n", address));
+                                "Failed to polling write LLT done at address %d!\n",
+                                address);
                        status = false;
                        break;
                }
@@ -879,12 +879,12 @@ void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw)
        u8 sec_reg_value;
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
-                 rtlpriv->sec.pairwise_enc_algorithm,
-                 rtlpriv->sec.group_enc_algorithm));
+                "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
+                rtlpriv->sec.pairwise_enc_algorithm,
+                rtlpriv->sec.group_enc_algorithm);
        if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                        ("not open hw encryption\n"));
+                        "not open hw encryption\n");
                return;
        }
        sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE;
@@ -895,7 +895,7 @@ void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw)
        sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
        rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                ("The SECR-value %x\n", sec_reg_value));
+                "The SECR-value %x\n", sec_reg_value);
        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
 }
 
@@ -921,7 +921,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)
        /* rtlpriv->intf_ops->disable_aspm(hw); */
        rtstatus = _rtl92de_init_mac(hw);
        if (rtstatus != true) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
                err = 1;
                spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags);
                return err;
@@ -930,12 +930,8 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)
        spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("Failed to download FW. Init HW "
-                        "without FW..\n"));
-               rtlhal->fw_ready = false;
+                        "Failed to download FW. Init HW without FW..\n");
                return 1;
-       } else {
-               rtlhal->fw_ready = true;
        }
        rtlhal->last_hmeboxnum = 0;
        rtlpriv->psc.fw_current_inpsmode = false;
@@ -946,7 +942,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)
 
        if (rtlhal->earlymode_enable) {
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        ("EarlyMode Enabled!!!\n"));
+                        "EarlyMode Enabled!!!\n");
 
                tmp_u1b = rtl_read_byte(rtlpriv, 0x4d0);
                tmp_u1b = tmp_u1b | 0x1f;
@@ -1064,10 +1060,10 @@ static enum version_8192d _rtl92de_read_chip_version(struct ieee80211_hw *hw)
        value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
        if (!(value32 & 0x000f0000)) {
                version = VERSION_TEST_CHIP_92D_SINGLEPHY;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("TEST CHIP!!!\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "TEST CHIP!!!\n");
        } else {
                version = VERSION_NORMAL_CHIP_92D_SINGLEPHY;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Normal CHIP!!!\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Normal CHIP!!!\n");
        }
        return version;
 }
@@ -1092,8 +1088,8 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw,
                _rtl92de_disable_bcn_sub_func(hw);
        } else {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("Set HW_VAR_MEDIA_STATUS: No such media "
-                        "status(%x).\n", type));
+                        "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n",
+                        type);
        }
        bcnfunc_enable = rtl_read_byte(rtlpriv, REG_BCN_CTRL);
        switch (type) {
@@ -1102,30 +1098,30 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw,
                ledaction = LED_CTL_LINK;
                bcnfunc_enable &= 0xF7;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to NO LINK!\n"));
+                        "Set Network type to NO LINK!\n");
                break;
        case NL80211_IFTYPE_ADHOC:
                bt_msr |= MSR_ADHOC;
                bcnfunc_enable |= 0x08;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to Ad Hoc!\n"));
+                        "Set Network type to Ad Hoc!\n");
                break;
        case NL80211_IFTYPE_STATION:
                bt_msr |= MSR_INFRA;
                ledaction = LED_CTL_LINK;
                bcnfunc_enable &= 0xF7;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to STA!\n"));
+                        "Set Network type to STA!\n");
                break;
        case NL80211_IFTYPE_AP:
                bt_msr |= MSR_AP;
                bcnfunc_enable |= 0x08;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to AP!\n"));
+                        "Set Network type to AP!\n");
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Network type %d not support!\n", type));
+                        "Network type %d not supported!\n", type);
                return 1;
                break;
 
@@ -1189,7 +1185,7 @@ void rtl92d_linked_set_reg(struct ieee80211_hw *hw)
        indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
        if (!rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done) {
                RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG,
-                               ("Do IQK for channel:%d.\n", channel));
+                        "Do IQK for channel:%d\n", channel);
                rtl92d_phy_iq_calibrate(hw);
        }
 }
@@ -1214,7 +1210,7 @@ void rtl92de_set_qos(struct ieee80211_hw *hw, int aci)
                rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
                break;
        default:
-               RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+               RT_ASSERT(false, "invalid aci: %d !\n", aci);
                break;
        }
 }
@@ -1305,8 +1301,8 @@ static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw)
        rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10);
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("In PowerOff,reg0x%x=%X\n", REG_SPS0_CTRL,
-                 rtl_read_byte(rtlpriv, REG_SPS0_CTRL)));
+                "In PowerOff,reg0x%x=%X\n",
+                REG_SPS0_CTRL, rtl_read_byte(rtlpriv, REG_SPS0_CTRL));
        /* r.   Note: for PCIe interface, PON will not turn */
        /* off m-bias and BandGap in PCIe suspend mode.  */
 
@@ -1319,7 +1315,7 @@ static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw)
                spin_unlock_irqrestore(&globalmutex_power, flags);
        }
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<=======\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<=======\n");
 }
 
 void rtl92de_card_disable(struct ieee80211_hw *hw)
@@ -1377,7 +1373,7 @@ void rtl92de_card_disable(struct ieee80211_hw *hw)
        rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xff);
        udelay(50);
        rtl_write_byte(rtlpriv, REG_CR, 0x0);
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==> Do power off.......\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==> Do power off.......\n");
        if (rtl92d_phy_check_poweroff(hw))
                _rtl92de_poweroff_adapter(hw);
        return;
@@ -1425,7 +1421,7 @@ void rtl92de_set_beacon_interval(struct ieee80211_hw *hw)
        u16 bcn_interval = mac->beacon_interval;
 
        RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
-                ("beacon_interval:%d\n", bcn_interval));
+                "beacon_interval:%d\n", bcn_interval);
        /* rtl92de_disable_interrupt(hw); */
        rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
        /* rtl92de_enable_interrupt(hw); */
@@ -1437,8 +1433,8 @@ void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
-       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-                ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n",
+                add_msr, rm_msr);
        if (add_msr)
                rtlpci->irq_mask[0] |= add_msr;
        if (rm_msr)
@@ -1615,9 +1611,9 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw,
                        rtlefuse->internal_pa_5g[1] =
                                !((hwinfo[EEPROM_TSSI_B_5G] & BIT(6)) >> 6);
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                                ("Is D cut,Internal PA0 %d Internal PA1 %d\n",
+                                "Is D cut,Internal PA0 %d Internal PA1 %d\n",
                                 rtlefuse->internal_pa_5g[0],
-                                rtlefuse->internal_pa_5g[1]))
+                                rtlefuse->internal_pa_5g[1]);
                }
                rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6];
                rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7];
@@ -1667,14 +1663,14 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw,
        if (rtlefuse->eeprom_c9 == 0xFF)
                rtlefuse->eeprom_c9 = 0x00;
        RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-                ("EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+                "EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
        RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-                ("ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
+                "ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
        RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-                ("CrystalCap = 0x%x\n", rtlefuse->crystalcap));
+                "CrystalCap = 0x%x\n", rtlefuse->crystalcap);
        RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-                ("Delta_IQK = 0x%x Delta_LCK = 0x%x\n", rtlefuse->delta_iqk,
-                rtlefuse->delta_lck));
+                "Delta_IQK = 0x%x Delta_LCK = 0x%x\n",
+                rtlefuse->delta_iqk, rtlefuse->delta_lck);
 
        for (rfPath = 0; rfPath < RF6052_MAX_PATH; rfPath++) {
                for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
@@ -1710,11 +1706,11 @@ static void _rtl92de_read_macphymode_from_prom(struct ieee80211_hw *hw,
        if (macphy_crvalue & BIT(3)) {
                rtlhal->macphymode = SINGLEMAC_SINGLEPHY;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        ("MacPhyMode SINGLEMAC_SINGLEPHY\n"));
+                        "MacPhyMode SINGLEMAC_SINGLEPHY\n");
        } else {
                rtlhal->macphymode = DUALMAC_DUALPHY;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        ("MacPhyMode DUALMAC_DUALPHY\n"));
+                        "MacPhyMode DUALMAC_DUALPHY\n");
        }
 }
 
@@ -1741,15 +1737,15 @@ static void _rtl92de_efuse_update_chip_version(struct ieee80211_hw *hw)
        switch (chipvalue) {
        case 0xAA55:
                chipver |= CHIP_92D_C_CUT;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("C-CUT!!!\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "C-CUT!!!\n");
                break;
        case 0x9966:
                chipver |= CHIP_92D_D_CUT;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("D-CUT!!!\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n");
                break;
        default:
                chipver |= CHIP_92D_D_CUT;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("Unkown CUT!\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unkown CUT!\n");
                break;
        }
        rtlpriv->rtlhal.version = chipver;
@@ -1775,23 +1771,23 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
                       HWSET_MAX_SIZE);
        } else if (rtlefuse->epromtype == EEPROM_93C46) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("RTL819X Not boot from eeprom, check it !!"));
+                        "RTL819X Not boot from eeprom, check it !!\n");
        }
-       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
+       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
                      hwinfo, HWSET_MAX_SIZE);
 
        eeprom_id = *((u16 *)&hwinfo[0]);
        if (eeprom_id != RTL8190_EEPROM_ID) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+                        "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
                rtlefuse->autoload_failflag = true;
        } else {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
                rtlefuse->autoload_failflag = false;
        }
        if (rtlefuse->autoload_failflag) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("RTL819X Not boot from eeprom, check it !!"));
+                        "RTL819X Not boot from eeprom, check it !!\n");
                return;
        }
        rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
@@ -1802,16 +1798,15 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
        rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
        rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
        rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROMId = 0x%4x\n", eeprom_id);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("EEPROMId = 0x%4x\n", eeprom_id));
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid));
+                "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did));
+                "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid));
+                "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid));
+                "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
 
        /* Read Permanent MAC address */
        if (rtlhal->interfaceindex == 0) {
@@ -1827,8 +1822,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
        }
        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR,
                                      rtlefuse->dev_addr);
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                ("%pM\n", rtlefuse->dev_addr));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);
        _rtl92de_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo);
 
        /* Read Channel Plan */
@@ -1849,7 +1843,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
        rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
        rtlefuse->txpwr_fromeprom = true;
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+                "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
 }
 
 void rtl92de_read_eeprom_info(struct ieee80211_hw *hw)
@@ -1863,19 +1857,19 @@ void rtl92de_read_eeprom_info(struct ieee80211_hw *hw)
        tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
        rtlefuse->autoload_status = tmp_u1b;
        if (tmp_u1b & BIT(4)) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
                rtlefuse->epromtype = EEPROM_93C46;
        } else {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
                rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
        }
        if (tmp_u1b & BIT(5)) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
 
                rtlefuse->autoload_failflag = false;
                _rtl92de_read_adapter_info(hw);
        } else {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
        }
        return;
 }
@@ -1958,8 +1952,8 @@ static void rtl92de_update_hal_rate_table(struct ieee80211_hw *hw,
                    (shortgi_rate << 4) | (shortgi_rate);
        }
        rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
-       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
-                ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+                rtl_read_dword(rtlpriv, REG_ARFR0));
 }
 
 static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw,
@@ -2092,8 +2086,8 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw,
        value[0] = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28);
        value[1] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
        RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
-                ("ratr_bitmap :%x value0:%x value1:%x\n",
-                 ratr_bitmap, value[0], value[1]));
+                "ratr_bitmap :%x value0:%x value1:%x\n",
+                ratr_bitmap, value[0], value[1]);
        rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, 5, (u8 *) value);
        if (macid != 0)
                sta_entry->ratr_index = ratr_index;
@@ -2153,14 +2147,14 @@ bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
        e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF;
        if (ppsc->hwradiooff && (e_rfpowerstate_toset == ERFON)) {
                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                        ("GPIOChangeRF  - HW Radio ON, RF ON\n"));
+                        "GPIOChangeRF  - HW Radio ON, RF ON\n");
                e_rfpowerstate_toset = ERFON;
                ppsc->hwradiooff = false;
                actuallyset = true;
        } else if ((ppsc->hwradiooff == false)
                && (e_rfpowerstate_toset == ERFOFF)) {
                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                        ("GPIOChangeRF  - HW Radio OFF, RF OFF\n"));
+                        "GPIOChangeRF  - HW Radio OFF, RF OFF\n");
                e_rfpowerstate_toset = ERFOFF;
                ppsc->hwradiooff = true;
                actuallyset = true;
@@ -2204,7 +2198,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
                u8 idx;
                u8 cam_offset = 0;
                u8 clear_number = 5;
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
                for (idx = 0; idx < clear_number; idx++) {
                        rtl_cam_mark_invalid(hw, cam_offset + idx);
                        rtl_cam_empty_entry(hw, cam_offset + idx);
@@ -2230,8 +2224,8 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
                        enc_algo = CAM_AES;
                        break;
                default:
-                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
-                                               "not process\n"));
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                                "switch case not processed\n");
                        enc_algo = CAM_TKIP;
                        break;
                }
@@ -2248,9 +2242,8 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
                                                                 p_macaddr);
                                        if (entry_id >=  TOTAL_CAM_ENTRY) {
                                                RT_TRACE(rtlpriv, COMP_SEC,
-                                                        DBG_EMERG, ("Can not "
-                                                        "find free hw security"
-                                                        " cam entry\n"));
+                                                        DBG_EMERG,
+                                                        "Can not find free hw security cam entry\n");
                                                return;
                                        }
                                } else {
@@ -2262,29 +2255,29 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
                }
                if (rtlpriv->sec.key_len[key_index] == 0) {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("delete one entry, entry_id is %d\n",
-                                entry_id));
+                                "delete one entry, entry_id is %d\n",
+                                entry_id);
                        if (mac->opmode == NL80211_IFTYPE_AP)
                                rtl_cam_del_entry(hw, p_macaddr);
                        rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
                } else {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("The insert KEY length is %d\n",
-                                 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+                                "The insert KEY length is %d\n",
+                                rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("The insert KEY  is %x %x\n",
-                                 rtlpriv->sec.key_buf[0][0],
-                                 rtlpriv->sec.key_buf[0][1]));
+                                "The insert KEY is %x %x\n",
+                                rtlpriv->sec.key_buf[0][0],
+                                rtlpriv->sec.key_buf[0][1]);
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("add one entry\n"));
+                                "add one entry\n");
                        if (is_pairwise) {
                                RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
-                                             "Pairwiase Key content :",
+                                             "Pairwise Key content",
                                              rtlpriv->sec.pairwise_key,
                                              rtlpriv->
                                              sec.key_len[PAIRWISE_KEYIDX]);
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                        ("set Pairwiase key\n"));
+                                        "set Pairwise key\n");
                                rtl_cam_add_one_entry(hw, macaddr, key_index,
                                                      entry_id, enc_algo,
                                                      CAM_CONFIG_NO_USEDK,
@@ -2292,7 +2285,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
                                                      sec.key_buf[key_index]);
                        } else {
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                        ("set group key\n"));
+                                        "set group key\n");
                                if (mac->opmode == NL80211_IFTYPE_ADHOC) {
                                        rtl_cam_add_one_entry(hw,
                                                rtlefuse->dev_addr,
index ad44ffa520e619aa5f99556d51eca3d5e4b0e241..7c9f7a2f1e427d2bac52cfacdea38c949f390a2e 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index f1552f4df65805aea48848d402c6d71e2188395a..76a57ae4af3eb77a24a44d17f44c38da106e2312 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -45,8 +45,8 @@ void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
        u8 ledcfg;
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-                ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+                REG_LEDCFG2, pled->ledpin);
 
        switch (pled->ledpin) {
        case LED_PIN_GPIO0:
@@ -71,7 +71,7 @@ void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        pled->ledon = true;
@@ -83,8 +83,8 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
        u8 ledcfg;
 
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-                ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+                REG_LEDCFG2, pled->ledpin);
 
        ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
 
@@ -106,7 +106,7 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        pled->ledon = false;
@@ -153,7 +153,7 @@ void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
             ledaction == LED_CTL_POWER_ON)) {
                return;
        }
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", ledaction));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction);
 
        _rtl92ce_sw_led_control(hw, ledaction);
 }
index 57f4a3c583d43c83ebc50702e9e773ee9ac5f827..a29df30c30255414bfa522ce61ebe469cfc9fae0 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 0883349e1c8371f9828deee3bb78ac04ccf0c4d9..96dc71746eaab9c3f2a2fd2380b0efcfe3d5c711 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -204,8 +204,8 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
        u32 returnvalue, originalvalue, bitshift;
        u8 dbi_direct;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-               "bitmask(%#x)\n", regaddr, bitmask));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
+                regaddr, bitmask);
        if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) {
                /* mac1 use phy0 read radio_b. */
                /* mac0 use phy1 read radio_b. */
@@ -220,8 +220,9 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
        }
        bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
        returnvalue = (originalvalue & bitmask) >> bitshift;
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x "
-               "Addr[0x%x]=0x%x\n", bitmask, regaddr, originalvalue));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
+                bitmask, regaddr, originalvalue);
        return returnvalue;
 }
 
@@ -233,8 +234,9 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
        u8 dbi_direct = 0;
        u32 originalvalue, bitshift;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-               " data(%#x)\n", regaddr, bitmask, data));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+                regaddr, bitmask, data);
        if (rtlhal->during_mac1init_radioa)
                dbi_direct = BIT(3);
        else if (rtlhal->during_mac0init_radiob)
@@ -255,8 +257,9 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
                rtl92de_write_dword_dbi(hw, (u16) regaddr, data, dbi_direct);
        else
                rtl_write_dword(rtlpriv, regaddr, data);
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-                " data(%#x)\n", regaddr, bitmask, data));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+                regaddr, bitmask, data);
 }
 
 static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw,
@@ -300,8 +303,8 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw,
        else
                retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
                        BLSSIREADBACKDATA);
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x] = 0x%x\n",
-                rfpath, pphyreg->rflssi_readback, retvalue));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n",
+                rfpath, pphyreg->rflssi_readback, retvalue);
        return retvalue;
 }
 
@@ -319,8 +322,8 @@ static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw,
        /* T65 RF */
        data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
        rtl_set_bbreg(hw, pphyreg->rf3wire_offset, BMASKDWORD, data_and_addr);
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
-               rfpath, pphyreg->rf3wire_offset, data_and_addr));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
+                rfpath, pphyreg->rf3wire_offset, data_and_addr);
 }
 
 u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw,
@@ -330,17 +333,17 @@ u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw,
        u32 original_value, readback_value, bitshift;
        unsigned long flags;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-               "rfpath(%#x), bitmask(%#x)\n",
-               regaddr, rfpath, bitmask));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
+                regaddr, rfpath, bitmask);
        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
        original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr);
        bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
        readback_value = (original_value & bitmask) >> bitshift;
        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
-               "bitmask(%#x), original_value(%#x)\n",
-               regaddr, rfpath, bitmask, original_value));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
+                regaddr, rfpath, bitmask, original_value);
        return readback_value;
 }
 
@@ -353,8 +356,8 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
        unsigned long flags;
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-               ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
-               regaddr, bitmask, data, rfpath));
+                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+                regaddr, bitmask, data, rfpath);
        if (bitmask == 0)
                return;
        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
@@ -369,9 +372,9 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
                _rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data);
        }
        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-               "bitmask(%#x), data(%#x), rfpath(%#x)\n",
-               regaddr, bitmask, data, rfpath));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+                regaddr, bitmask, data, rfpath);
 }
 
 bool rtl92d_phy_mac_config(struct ieee80211_hw *hw)
@@ -381,10 +384,10 @@ bool rtl92d_phy_mac_config(struct ieee80211_hw *hw)
        u32 arraylength;
        u32 *ptrarray;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
        arraylength = MAC_2T_ARRAYLENGTH;
        ptrarray = rtl8192de_mac_2tarray;
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Img:Rtl819XMAC_Array\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:Rtl819XMAC_Array\n");
        for (i = 0; i < arraylength; i = i + 2)
                rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
        if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) {
@@ -561,25 +564,25 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
                agctab_arraylen = AGCTAB_ARRAYLENGTH;
                agctab_array_table = rtl8192de_agctab_array;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        (" ===> phy:MAC0, Rtl819XAGCTAB_Array\n"));
+                        " ===> phy:MAC0, Rtl819XAGCTAB_Array\n");
        } else {
                if (rtlhal->current_bandtype == BAND_ON_2_4G) {
                        agctab_arraylen = AGCTAB_2G_ARRAYLENGTH;
                        agctab_array_table = rtl8192de_agctab_2garray;
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                                (" ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n"));
+                                " ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n");
                } else {
                        agctab_5garraylen = AGCTAB_5G_ARRAYLENGTH;
                        agctab_5garray_table = rtl8192de_agctab_5garray;
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                                (" ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n"));
+                                " ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n");
 
                }
        }
        phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH;
        phy_regarray_table = rtl8192de_phy_reg_2tarray;
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                (" ===> phy:Rtl819XPHY_REG_Array_PG\n"));
+                " ===> phy:Rtl819XPHY_REG_Array_PG\n");
        if (configtype == BASEBAND_CONFIG_PHY_REG) {
                for (i = 0; i < phy_reg_arraylen; i = i + 2) {
                        if (phy_regarray_table[i] == 0xfe)
@@ -598,10 +601,9 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
                                      phy_regarray_table[i + 1]);
                        udelay(1);
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                                ("The phy_regarray_table[0] is %x"
-                                 " Rtl819XPHY_REGArray[1] is %x\n",
-                                 phy_regarray_table[i],
-                                 phy_regarray_table[i + 1]));
+                                "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
+                                phy_regarray_table[i],
+                                phy_regarray_table[i + 1]);
                }
        } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
                if (rtlhal->interfaceindex == 0) {
@@ -613,15 +615,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
                                 * setting. */
                                udelay(1);
                                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                                        ("The Rtl819XAGCTAB_Array_"
-                                        "Table[0] is %ul "
-                                        "Rtl819XPHY_REGArray[1] is %ul\n",
+                                        "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n",
                                         agctab_array_table[i],
-                                        agctab_array_table[i + 1]));
+                                        agctab_array_table[i + 1]);
                        }
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                                ("Normal Chip, MAC0, load "
-                                "Rtl819XAGCTAB_Array\n"));
+                                "Normal Chip, MAC0, load Rtl819XAGCTAB_Array\n");
                } else {
                        if (rtlhal->current_bandtype == BAND_ON_2_4G) {
                                for (i = 0; i < agctab_arraylen; i = i + 2) {
@@ -632,14 +631,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
                                         * setting. */
                                        udelay(1);
                                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                                                ("The Rtl819XAGCTAB_Array_"
-                                                "Table[0] is %ul Rtl819XPHY_"
-                                                "REGArray[1] is %ul\n",
+                                                "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n",
                                                 agctab_array_table[i],
-                                                agctab_array_table[i + 1]));
+                                                agctab_array_table[i + 1]);
                                }
                                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                                        ("Load Rtl819XAGCTAB_2GArray\n"));
+                                        "Load Rtl819XAGCTAB_2GArray\n");
                        } else {
                                for (i = 0; i < agctab_5garraylen; i = i + 2) {
                                        rtl_set_bbreg(hw,
@@ -650,14 +647,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
                                         * setting. */
                                        udelay(1);
                                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                                                ("The Rtl819XAGCTAB_5GArray_"
-                                                "Table[0] is %ul Rtl819XPHY_"
-                                                "REGArray[1] is %ul\n",
+                                                "The Rtl819XAGCTAB_5GArray_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n",
                                                 agctab_5garray_table[i],
-                                                agctab_5garray_table[i + 1]));
+                                                agctab_5garray_table[i + 1]);
                                }
                                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                                       ("Load Rtl819XAGCTAB_5GArray\n"));
+                                        "Load Rtl819XAGCTAB_5GArray\n");
                        }
                }
        }
@@ -670,152 +665,51 @@ static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       int index;
+
+       if (regaddr == RTXAGC_A_RATE18_06)
+               index = 0;
+       else if (regaddr == RTXAGC_A_RATE54_24)
+               index = 1;
+       else if (regaddr == RTXAGC_A_CCK1_MCS32)
+               index = 6;
+       else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00)
+               index = 7;
+       else if (regaddr == RTXAGC_A_MCS03_MCS00)
+               index = 2;
+       else if (regaddr == RTXAGC_A_MCS07_MCS04)
+               index = 3;
+       else if (regaddr == RTXAGC_A_MCS11_MCS08)
+               index = 4;
+       else if (regaddr == RTXAGC_A_MCS15_MCS12)
+               index = 5;
+       else if (regaddr == RTXAGC_B_RATE18_06)
+               index = 8;
+       else if (regaddr == RTXAGC_B_RATE54_24)
+               index = 9;
+       else if (regaddr == RTXAGC_B_CCK1_55_MCS32)
+               index = 14;
+       else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff)
+               index = 15;
+       else if (regaddr == RTXAGC_B_MCS03_MCS00)
+               index = 10;
+       else if (regaddr == RTXAGC_B_MCS07_MCS04)
+               index = 11;
+       else if (regaddr == RTXAGC_B_MCS11_MCS08)
+               index = 12;
+       else if (regaddr == RTXAGC_B_MCS15_MCS12)
+               index = 13;
+       else
+               return;
 
-       if (regaddr == RTXAGC_A_RATE18_06) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][0]));
-       }
-       if (regaddr == RTXAGC_A_RATE54_24) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][1]));
-       }
-       if (regaddr == RTXAGC_A_CCK1_MCS32) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][6]));
-       }
-       if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][7]));
-       }
-       if (regaddr == RTXAGC_A_MCS03_MCS00) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][2]));
-       }
-       if (regaddr == RTXAGC_A_MCS07_MCS04) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][3]));
-       }
-       if (regaddr == RTXAGC_A_MCS11_MCS08) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][4]));
-       }
-       if (regaddr == RTXAGC_A_MCS15_MCS12) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][5]));
-       }
-       if (regaddr == RTXAGC_B_RATE18_06) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][8]));
-       }
-       if (regaddr == RTXAGC_B_RATE54_24) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][9]));
-       }
-       if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][14]));
-       }
-       if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][15]));
-       }
-       if (regaddr == RTXAGC_B_MCS03_MCS00) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][10]));
-       }
-       if (regaddr == RTXAGC_B_MCS07_MCS04) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n",
-                        rtlphy->pwrgroup_cnt,
-                        rtlphy->mcs_txpwrlevel_origoffset
-                        [rtlphy->pwrgroup_cnt][11]));
-       }
-       if (regaddr == RTXAGC_B_MCS11_MCS08) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset
-                                       [rtlphy->pwrgroup_cnt][12]));
-       }
-       if (regaddr == RTXAGC_B_MCS15_MCS12) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
-                                                                        data;
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n",
-                         rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset
-                                       [rtlphy->pwrgroup_cnt][13]));
+       rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data;
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%ulx\n",
+                rtlphy->pwrgroup_cnt, index,
+                rtlphy->mcs_txpwrlevel_origoffset
+                [rtlphy->pwrgroup_cnt][index]);
+       if (index == 13)
                rtlphy->pwrgroup_cnt++;
-       }
 }
 
 static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
@@ -849,7 +743,7 @@ static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
                }
        } else {
                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-                        ("configtype != BaseBand_Config_PHY_REG\n"));
+                        "configtype != BaseBand_Config_PHY_REG\n");
        }
        return true;
 }
@@ -861,17 +755,17 @@ static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw)
        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
        bool rtstatus = true;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
        rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw,
                BASEBAND_CONFIG_PHY_REG);
        if (rtstatus != true) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
                return false;
        }
 
        /* if (rtlphy->rf_type == RF_1T2R) {
         *      _rtl92c_phy_bb_config_1t(hw);
-        *     RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n"));
+        *     RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
         *} */
 
        if (rtlefuse->autoload_failflag == false) {
@@ -880,13 +774,13 @@ static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw)
                        BASEBAND_CONFIG_PHY_REG);
        }
        if (rtstatus != true) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
                return false;
        }
        rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw,
                BASEBAND_CONFIG_AGC_TAB);
        if (rtstatus != true) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
                return false;
        }
        rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
@@ -951,19 +845,17 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
                radiob_array_table = rtl8192de_radiob_2t_int_paarray;
        }
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("PHY_ConfigRFWithHeaderFile() "
-                "Radio_A:Rtl819XRadioA_1TArray\n"));
+                "PHY_ConfigRFWithHeaderFile() Radio_A:Rtl819XRadioA_1TArray\n");
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("PHY_ConfigRFWithHeaderFile() "
-                "Radio_B:Rtl819XRadioB_1TArray\n"));
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
+                "PHY_ConfigRFWithHeaderFile() Radio_B:Rtl819XRadioB_1TArray\n");
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
 
        /* this only happens when DMDP, mac0 start on 2.4G,
         * mac1 start on 5G, mac 0 has to set phy0&phy1
         * pathA or mac1 has to set phy0&phy1 pathA */
        if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) {
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        (" ===> althougth Path A, we load radiob.txt\n"));
+                        " ===> althougth Path A, we load radiob.txt\n");
                radioa_arraylen = radiob_arraylen;
                radioa_array_table = radiob_array_table;
        }
@@ -1022,11 +914,11 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
                break;
        case RF90_PATH_C:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        case RF90_PATH_D:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        return true;
@@ -1046,19 +938,18 @@ void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
        rtlphy->default_initialgain[3] =
            (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                ("Default initial gain (c50=0x%x, "
-                 "c58=0x%x, c60=0x%x, c68=0x%x\n",
-                 rtlphy->default_initialgain[0],
-                 rtlphy->default_initialgain[1],
-                 rtlphy->default_initialgain[2],
-                 rtlphy->default_initialgain[3]));
+                "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
+                rtlphy->default_initialgain[0],
+                rtlphy->default_initialgain[1],
+                rtlphy->default_initialgain[2],
+                rtlphy->default_initialgain[3]);
        rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
                                              BMASKBYTE0);
        rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
                                              BMASKDWORD);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                ("Default framesync (0x%x) = 0x%x\n",
-                 ROFDM0_RXDETECTOR3, rtlphy->framesync));
+                "Default framesync (0x%x) = 0x%x\n",
+                ROFDM0_RXDETECTOR3, rtlphy->framesync);
 }
 
 static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
@@ -1172,7 +1063,7 @@ void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Unknown Scan Backup operation.\n"));
+                                "Unknown Scan Backup operation\n");
                        break;
                }
        }
@@ -1193,14 +1084,13 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
                return;
        if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("FALSE driver sleep or unload\n"));
+                        "FALSE driver sleep or unload\n");
                return;
        }
        rtlphy->set_bwmode_inprogress = true;
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-                ("Switch to %s bandwidth\n",
-                 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
-                 "20MHz" : "40MHz"));
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
+                rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+                "20MHz" : "40MHz");
        reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
        reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
        switch (rtlphy->current_chan_bw) {
@@ -1218,7 +1108,7 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+                        "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
                break;
        }
        switch (rtlphy->current_chan_bw) {
@@ -1250,13 +1140,13 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+                        "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
                break;
 
        }
        rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
        rtlphy->set_bwmode_inprogress = false;
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 }
 
 static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw)
@@ -1273,7 +1163,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        u8 value8;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n");
        rtlhal->bandset = band;
        rtlhal->current_bandtype = band;
        if (IS_92D_SINGLEPHY(rtlhal->version))
@@ -1283,13 +1173,13 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
        /* reconfig BB/RF according to wireless mode */
        if (rtlhal->current_bandtype == BAND_ON_2_4G) {
                /* BB & RF Config */
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>2.4G\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>2.4G\n");
                if (rtlhal->interfaceindex == 1)
                        _rtl92d_phy_config_bb_with_headerfile(hw,
                                BASEBAND_CONFIG_AGC_TAB);
        } else {
                /* 5G band */
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>5G\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>5G\n");
                if (rtlhal->interfaceindex == 1)
                        _rtl92d_phy_config_bb_with_headerfile(hw,
                                BASEBAND_CONFIG_AGC_TAB);
@@ -1317,7 +1207,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
                        0 ? REG_MAC0 : REG_MAC1), value8);
        }
        mdelay(1);
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==Switch Band OK.\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==Switch Band OK\n");
 }
 
 static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
@@ -1329,9 +1219,9 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
        u8 group, i;
        unsigned long flag = 0;
 
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>path %d\n", rfpath));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>path %d\n", rfpath);
        if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n");
                rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0);
                rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
                /* fc area 0xd2c */
@@ -1353,14 +1243,13 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
        } else {
                /* G band. */
                RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
-                        ("Load RF IMR parameters for G band. IMR already "
-                        "setting %d\n",
-                         rtlpriv->rtlhal.load_imrandiqk_setting_for2g));
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n"));
+                        "Load RF IMR parameters for G band. IMR already setting %d\n",
+                        rtlpriv->rtlhal.load_imrandiqk_setting_for2g);
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n");
                if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) {
                        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
-                               ("Load RF IMR parameters "
-                               "for G band. %d\n", rfpath));
+                                "Load RF IMR parameters for G band. %d\n",
+                                rfpath);
                        rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
                        rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0);
                        rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
@@ -1378,7 +1267,7 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
                        rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
                }
        }
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
 }
 
 static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw,
@@ -1388,7 +1277,7 @@ static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw,
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n"));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
        /*----Store original RFENV control type----*/
        switch (rfpath) {
        case RF90_PATH_A:
@@ -1414,7 +1303,7 @@ static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw,
        /*Set 0 to 12 bits for 8255 */
        rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
        udelay(1);
-       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n"));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
 }
 
 static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
@@ -1424,7 +1313,7 @@ static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("=====>\n"));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "=====>\n");
        /*----Restore RFENV control type----*/ ;
        switch (rfpath) {
        case RF90_PATH_A:
@@ -1437,7 +1326,7 @@ static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
                              *pu4_regval);
                break;
        }
-       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<=====\n"));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<=====\n");
 }
 
 static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
@@ -1451,13 +1340,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
        bool need_pwr_down = false, internal_pa = false;
        u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2;
 
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>\n"));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>\n");
        /* config path A for 5G */
        if (rtlhal->current_bandtype == BAND_ON_5G) {
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n");
                u4tmp = curveindex_5g[channel - 1];
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 1 set RF-A, 5G, "
-                       "0x28 = 0x%x !!\n", u4tmp));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp);
                for (i = 0; i < RF_CHNL_NUM_5G; i++) {
                        if (channel == rf_chnl_5g[i] && channel <= 140)
                                index = 0;
@@ -1503,12 +1392,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
                                              rf_reg_pram_c_5g[index][i]);
                        }
                        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-                               ("offset 0x%x value 0x%x "
-                               "path %d index %d readback 0x%x\n",
-                               rf_reg_for_c_cut_5g[i],
-                               rf_reg_pram_c_5g[index][i], path,
-                               index, rtl_get_rfreg(hw, (enum radio_path)path,
-                               rf_reg_for_c_cut_5g[i], BRFREGOFFSETMASK)));
+                                "offset 0x%x value 0x%x path %d index %d readback 0x%x\n",
+                                rf_reg_for_c_cut_5g[i],
+                                rf_reg_pram_c_5g[index][i],
+                                path, index,
+                                rtl_get_rfreg(hw, (enum radio_path)path,
+                                              rf_reg_for_c_cut_5g[i],
+                                              BRFREGOFFSETMASK));
                }
                if (need_pwr_down)
                        _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
@@ -1541,11 +1431,10 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
                                                BRFREGOFFSETMASK,
                                                rf_pram_c_5g_int_pa[index][i]);
                                        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
-                                                ("offset 0x%x value 0x%x "
-                                                "path %d index %d\n",
+                                                "offset 0x%x value 0x%x path %d index %d\n",
                                                 rf_for_c_cut_5g_internal_pa[i],
                                                 rf_pram_c_5g_int_pa[index][i],
-                                                rfpath, index));
+                                                rfpath, index);
                                }
                        } else {
                                rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B,
@@ -1553,10 +1442,10 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
                        }
                }
        } else if (rtlhal->current_bandtype == BAND_ON_2_4G) {
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n");
                u4tmp = curveindex_2g[channel - 1];
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 3 set RF-B, 2G, "
-                       "0x28 = 0x%x !!\n", u4tmp));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp);
                if (channel == 1 || channel == 2 || channel == 4 || channel == 9
                    || channel == 10 || channel == 11 || channel == 12)
                        index = 0;
@@ -1590,18 +1479,17 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
                                              rf_reg_param_for_c_cut_2g
                                              [index][i]);
                        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-                               ("offset 0x%x value 0x%x mak 0x%x path %d "
-                               "index %d readback 0x%x\n",
-                               rf_reg_for_c_cut_2g[i],
-                               rf_reg_param_for_c_cut_2g[index][i],
-                               rf_reg_mask_for_c_cut_2g[i], path, index,
-                               rtl_get_rfreg(hw, (enum radio_path)path,
-                               rf_reg_for_c_cut_2g[i],
-                               BRFREGOFFSETMASK)));
+                                "offset 0x%x value 0x%x mak 0x%x path %d index %d readback 0x%x\n",
+                                rf_reg_for_c_cut_2g[i],
+                                rf_reg_param_for_c_cut_2g[index][i],
+                                rf_reg_mask_for_c_cut_2g[i], path, index,
+                                rtl_get_rfreg(hw, (enum radio_path)path,
+                                              rf_reg_for_c_cut_2g[i],
+                                              BRFREGOFFSETMASK));
                }
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
-                       rf_syn_g4_for_c_cut_2g | (u4tmp << 11)));
+                       "cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
+                       rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
 
                rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4,
                              BRFREGOFFSETMASK,
@@ -1611,7 +1499,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
                if (rtlhal->during_mac0init_radiob)
                        rtl92d_phy_powerdown_anotherphy(hw, true);
        }
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
 }
 
 u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl)
@@ -1648,9 +1536,9 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
        u32 regeac, rege94, rege9c, regea4;
        u8 result = 0;
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK!\n");
        /* path-A IQK setting */
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n");
        if (rtlhal->interfaceindex == 0) {
                rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f);
                rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f);
@@ -1668,26 +1556,26 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
                rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206);
        }
        /* LO calibration setting */
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n");
        rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
        /* One shot, path A LOK & IQK */
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "One shot, path A LOK & IQK!\n");
        rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000);
        rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
        /* delay x ms */
        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-               ("Delay %d ms for One shot, path A LOK & IQK.\n",
-               IQK_DELAY_TIME));
+               "Delay %d ms for One shot, path A LOK & IQK\n",
+               IQK_DELAY_TIME);
        mdelay(IQK_DELAY_TIME);
        /* Check failed */
        regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
        rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD);
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe94 = 0x%x\n", rege94);
        rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD);
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe9c = 0x%x\n", rege9c);
        regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD);
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xea4 = 0x%x\n", regea4);
        if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) &&
            (((rege9c & 0x03FF0000) >> 16) != 0x42))
                result |= 0x01;
@@ -1698,7 +1586,7 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
            (((regeac & 0x03FF0000) >> 16) != 0x36))
                result |= 0x02;
        else
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A Rx IQK fail!!\n"));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A Rx IQK fail!!\n");
        return result;
 }
 
@@ -1719,9 +1607,9 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
                TxOKBit = BIT(31);
                RxOKBit = BIT(30);
        }
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK!\n");
        /* path-A IQK setting */
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n");
        rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f);
        rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f);
        rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307);
@@ -1734,7 +1622,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
                rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000);
        }
        /* LO calibration setting */
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n");
        rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
        /* path-A PA on */
        rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60);
@@ -1742,29 +1630,29 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
        for (i = 0; i < retrycount; i++) {
                /* One shot, path A LOK & IQK */
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("One shot, path A LOK & IQK!\n"));
+                       "One shot, path A LOK & IQK!\n");
                rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000);
                rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
                /* delay x ms */
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("Delay %d ms for One shot, path A LOK & IQK.\n",
-                       IQK_DELAY_TIME));
+                       "Delay %d ms for One shot, path A LOK & IQK.\n",
+                       IQK_DELAY_TIME);
                mdelay(IQK_DELAY_TIME * 10);
                /* Check failed */
                regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
                rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe94 = 0x%x\n", rege94);
                rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe9c = 0x%x\n", rege9c);
                regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xea4 = 0x%x\n", regea4);
                if (!(regeac & TxOKBit) &&
                     (((rege94 & 0x03FF0000) >> 16) != 0x142)) {
                        result |= 0x01;
                } else { /* if Tx not OK, ignore Rx */
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("Path A Tx IQK fail!!\n"));
+                               "Path A Tx IQK fail!!\n");
                        continue;
                }
 
@@ -1775,7 +1663,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
                        break;
                } else {
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("Path A Rx IQK fail!!\n"));
+                               "Path A Rx IQK fail!!\n");
                }
        }
        /* path A PA off */
@@ -1793,27 +1681,26 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw)
        u32 regeac, regeb4, regebc, regec4, regecc;
        u8 result = 0;
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path B IQK!\n");
        /* One shot, path B LOK & IQK */
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "One shot, path A LOK & IQK!\n");
        rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002);
        rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000);
        /* delay x ms  */
        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-               ("Delay %d ms for One shot, path B LOK & IQK.\n",
-               IQK_DELAY_TIME));
+               "Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME);
        mdelay(IQK_DELAY_TIME);
        /* Check failed */
        regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
        regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD);
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeb4 = 0x%x\n", regeb4);
        regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD);
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xebc = 0x%x\n", regebc);
        regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD);
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xec4 = 0x%x\n", regec4);
        regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD);
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xecc = 0x%x\n", regecc);
        if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) &&
            (((regebc & 0x03FF0000) >> 16) != 0x42))
                result |= 0x01;
@@ -1823,7 +1710,7 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw)
            (((regecc & 0x03FF0000) >> 16) != 0x36))
                result |= 0x02;
        else
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B Rx IQK fail!!\n"));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path B Rx IQK fail!!\n");
        return result;
 }
 
@@ -1837,9 +1724,9 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
        u8 i;
        u8 retrycount = 2;
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path B IQK!\n");
        /* path-A IQK setting */
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n");
        rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f);
        rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f);
        rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000);
@@ -1852,7 +1739,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
        rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960);
 
        /* LO calibration setting */
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n");
        rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
 
        /* path-B PA on */
@@ -1862,26 +1749,26 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
        for (i = 0; i < retrycount; i++) {
                /* One shot, path B LOK & IQK */
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("One shot, path A LOK & IQK!\n"));
+                       "One shot, path A LOK & IQK!\n");
                rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000);
                rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
 
                /* delay x ms */
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("Delay %d ms for One shot, path B LOK & IQK.\n", 10));
+                       "Delay %d ms for One shot, path B LOK & IQK.\n", 10);
                mdelay(IQK_DELAY_TIME * 10);
 
                /* Check failed */
                regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
                regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeb4 = 0x%x\n", regeb4);
                regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xebc = 0x%x\n", regebc);
                regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xec4 = 0x%x\n", regec4);
                regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xecc = 0x%x\n", regecc);
                if (!(regeac & BIT(31)) &&
                    (((regeb4 & 0x03FF0000) >> 16) != 0x142))
                        result |= 0x01;
@@ -1893,7 +1780,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
                        break;
                } else {
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("Path B Rx IQK fail!!\n"));
+                               "Path B Rx IQK fail!!\n");
                }
        }
 
@@ -1912,7 +1799,7 @@ static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 i;
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save ADDA parameters.\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Save ADDA parameters.\n");
        for (i = 0; i < regnum; i++)
                adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD);
 }
@@ -1923,7 +1810,7 @@ static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 i;
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save MAC parameters.\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Save MAC parameters.\n");
        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
                macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
        macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
@@ -1937,7 +1824,7 @@ static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw,
        u32 i;
 
        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-               ("Reload ADDA power saving parameters !\n"));
+               "Reload ADDA power saving parameters !\n");
        for (i = 0; i < regnum; i++)
                rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]);
 }
@@ -1948,7 +1835,7 @@ static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 i;
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Reload MAC parameters !\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Reload MAC parameters !\n");
        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
                rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
        rtl_write_byte(rtlpriv, macreg[i], macbackup[i]);
@@ -1961,7 +1848,7 @@ static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw,
        u32 pathon;
        u32 i;
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ADDA ON.\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "ADDA ON.\n");
        pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4;
        if (patha_on)
                pathon = rtlpriv->rtlhal.interfaceindex == 0 ?
@@ -1976,7 +1863,7 @@ static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 i;
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("MAC settings for Calibration.\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "MAC settings for Calibration.\n");
        rtl_write_byte(rtlpriv, macreg[0], 0x3F);
 
        for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
@@ -1988,7 +1875,7 @@ static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw,
 static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A standby mode!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A standby mode!\n");
 
        rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0);
        rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000);
@@ -2001,7 +1888,7 @@ static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode)
        u32 mode;
 
        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-               ("BB Switch to %s mode!\n", (pi_mode ? "PI" : "SI")));
+               "BB Switch to %s mode!\n", pi_mode ? "PI" : "SI");
        mode = pi_mode ? 0x01000100 : 0x01000000;
        rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode);
        rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode);
@@ -2033,12 +1920,12 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
        const u32 retrycount = 2;
        u32 bbvalue;
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 2.4G :Start!!!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK for 2.4G :Start!!!\n");
        if (t == 0) {
                bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue));
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n",
-                       (is2t ? "2T2R" : "1T1R")));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "==>0x%08x\n", bbvalue);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
+                       is2t ? "2T2R" : "1T1R");
 
                /*  Save ADDA parameters, turn Path A ADDA on */
                _rtl92d_phy_save_adda_registers(hw, adda_reg,
@@ -2076,7 +1963,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
        if (is2t)
                rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000);
        /* IQ calibration setting */
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK setting!\n");
        rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
        rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00);
        rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800);
@@ -2084,7 +1971,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
                patha_ok = _rtl92d_phy_patha_iqk(hw, is2t);
                if (patha_ok == 0x03) {
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("Path A IQK Success!!\n"));
+                               "Path A IQK Success!!\n");
                        result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
                                        0x3FF0000) >> 16;
                        result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
@@ -2097,7 +1984,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
                } else if (i == (retrycount - 1) && patha_ok == 0x01) {
                        /* Tx IQK OK */
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("Path A IQK Only  Tx Success!!\n"));
+                               "Path A IQK Only  Tx Success!!\n");
 
                        result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
                                        0x3FF0000) >> 16;
@@ -2106,7 +1993,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
                }
        }
        if (0x00 == patha_ok)
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK failed!!\n"));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK failed!!\n");
        if (is2t) {
                _rtl92d_phy_patha_standby(hw);
                /* Turn Path B ADDA on */
@@ -2115,7 +2002,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
                        pathb_ok = _rtl92d_phy_pathb_iqk(hw);
                        if (pathb_ok == 0x03) {
                                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                                       ("Path B IQK Success!!\n"));
+                                       "Path B IQK Success!!\n");
                                result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
                                               BMASKDWORD) & 0x3FF0000) >> 16;
                                result[t][5] = (rtl_get_bbreg(hw, 0xebc,
@@ -2128,7 +2015,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
                        } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
                                /* Tx IQK OK */
                                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                                       ("Path B Only Tx IQK Success!!\n"));
+                                       "Path B Only Tx IQK Success!!\n");
                                result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
                                               BMASKDWORD) & 0x3FF0000) >> 16;
                                result[t][5] = (rtl_get_bbreg(hw, 0xebc,
@@ -2137,12 +2024,12 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
                }
                if (0x00 == pathb_ok)
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("Path B IQK failed!!\n"));
+                               "Path B IQK failed!!\n");
        }
 
        /* Back to BB mode, load original value */
        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-               ("IQK:Back to BB mode, load original value!\n"));
+               "IQK:Back to BB mode, load original value!\n");
 
        rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0);
        if (t != 0) {
@@ -2167,7 +2054,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
                rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00);
                rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00);
        }
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "<==\n");
 }
 
 static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
@@ -2199,13 +2086,13 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
        /* Note: IQ calibration must be performed after loading
         * PHY_REG.txt , and radio_a, radio_b.txt */
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 5G NORMAL:Start!!!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK for 5G NORMAL:Start!!!\n");
        mdelay(IQK_DELAY_TIME * 20);
        if (t == 0) {
                bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue));
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n",
-                       (is2t ? "2T2R" : "1T1R")));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "==>0x%08x\n", bbvalue);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
+                       is2t ? "2T2R" : "1T1R");
                /* Save ADDA parameters, turn Path A ADDA on */
                _rtl92d_phy_save_adda_registers(hw, adda_reg,
                                                rtlphy->adda_backup,
@@ -2242,13 +2129,13 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
        if (is2t)
                rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000);
        /* IQ calibration setting  */
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK setting!\n");
        rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
        rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00);
        rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800);
        patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t);
        if (patha_ok == 0x03) {
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Success!!\n"));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK Success!!\n");
                result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
                                0x3FF0000) >> 16;
                result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
@@ -2259,14 +2146,14 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
                                0x3FF0000) >> 16;
        } else if (patha_ok == 0x01) {  /* Tx IQK OK */
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("Path A IQK Only  Tx Success!!\n"));
+                       "Path A IQK Only  Tx Success!!\n");
 
                result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
                                0x3FF0000) >> 16;
                result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
                                0x3FF0000) >> 16;
        } else {
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Fail!!\n"));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK Fail!!\n");
        }
        if (is2t) {
                /* _rtl92d_phy_patha_standby(hw); */
@@ -2275,7 +2162,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
                pathb_ok = _rtl92d_phy_pathb_iqk_5g_normal(hw);
                if (pathb_ok == 0x03) {
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("Path B IQK Success!!\n"));
+                               "Path B IQK Success!!\n");
                        result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) &
                             0x3FF0000) >> 16;
                        result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) &
@@ -2286,20 +2173,20 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
                             0x3FF0000) >> 16;
                } else if (pathb_ok == 0x01) { /* Tx IQK OK */
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("Path B Only Tx IQK Success!!\n"));
+                               "Path B Only Tx IQK Success!!\n");
                        result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) &
                             0x3FF0000) >> 16;
                        result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) &
                             0x3FF0000) >> 16;
                } else {
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("Path B IQK failed!!\n"));
+                               "Path B IQK failed!!\n");
                }
        }
 
        /* Back to BB mode, load original value */
        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-               ("IQK:Back to BB mode, load original value!\n"));
+               "IQK:Back to BB mode, load original value!\n");
        rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0);
        if (t != 0) {
                if (is2t)
@@ -2321,7 +2208,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
                                                  rtlphy->adda_backup,
                                                  IQK_ADDA_REG_NUM);
        }
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "<==\n");
 }
 
 static bool _rtl92d_phy_simularity_compare(struct ieee80211_hw *hw,
@@ -2395,8 +2282,7 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
            rtlhal->macphymode == DUALMAC_DUALPHY;
 
        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-               ("Path A IQ Calibration %s !\n",
-               (iqk_ok) ? "Success" : "Failed"));
+               "Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed");
        if (final_candidate == 0xFF) {
                return;
        } else if (iqk_ok) {
@@ -2406,8 +2292,9 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
                if ((val_x & 0x00000200) != 0)
                        val_x = val_x | 0xFFFFFC00;
                tx0_a = (val_x * oldval_0) >> 8;
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx0_a = 0x%x,"
-                       " oldval_0 0x%x\n",     val_x, tx0_a, oldval_0));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       "X = 0x%x, tx0_a = 0x%x, oldval_0 0x%x\n",
+                       val_x, tx0_a, oldval_0);
                rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x3FF, tx0_a);
                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
                              ((val_x * oldval_0 >> 7) & 0x1));
@@ -2419,8 +2306,9 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
                        rtlhal->current_bandtype == BAND_ON_5G)
                        val_y += 3;
                tx0_c = (val_y * oldval_0) >> 8;
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx0_c = 0x%lx\n",
-                       val_y, tx0_c));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       "Y = 0x%lx, tx0_c = 0x%lx\n",
+                       val_y, tx0_c);
                rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000,
                              ((tx0_c & 0x3C0) >> 6));
                rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x003F0000,
@@ -2428,11 +2316,11 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
                if (is2t)
                        rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26),
                                      ((val_y * oldval_0 >> 7) & 0x1));
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xC80 = 0x%x\n",
-                        rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
-                                      BMASKDWORD)));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n",
+                       rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
+                                     BMASKDWORD));
                if (txonly) {
-                       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("only Tx OK\n"));
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "only Tx OK\n");
                        return;
                }
                reg = result[final_candidate][2];
@@ -2452,8 +2340,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
        u32 oldval_1, val_x, tx1_a, reg;
        long val_y, tx1_c;
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQ Calibration %s !\n",
-                (iqk_ok) ? "Success" : "Failed"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQ Calibration %s !\n",
+               iqk_ok ? "Success" : "Failed");
        if (final_candidate == 0xFF) {
                return;
        } else if (iqk_ok) {
@@ -2463,8 +2351,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
                if ((val_x & 0x00000200) != 0)
                        val_x = val_x | 0xFFFFFC00;
                tx1_a = (val_x * oldval_1) >> 8;
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx1_a = 0x%x\n",
-                       val_x, tx1_a));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x, tx1_a = 0x%x\n",
+                       val_x, tx1_a);
                rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x3FF, tx1_a);
                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),
                              ((val_x * oldval_1 >> 7) & 0x1));
@@ -2474,8 +2362,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
                if (rtlhal->current_bandtype == BAND_ON_5G)
                        val_y += 3;
                tx1_c = (val_y * oldval_1) >> 8;
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx1_c = 0x%lx\n",
-                       val_y, tx1_c));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%lx, tx1_c = 0x%lx\n",
+                       val_y, tx1_c);
                rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000,
                              ((tx1_c & 0x3C0) >> 6));
                rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x003F0000,
@@ -2507,7 +2395,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
        unsigned long flag = 0;
 
        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-               ("IQK:Start!!!channel %d\n", rtlphy->current_channel));
+               "IQK:Start!!!channel %d\n", rtlphy->current_channel);
        for (i = 0; i < 8; i++) {
                result[0][i] = 0;
                result[1][i] = 0;
@@ -2521,7 +2409,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
        is23simular = false;
        is13simular = false;
        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-               ("IQK !!!currentband %d\n", rtlhal->current_bandtype));
+               "IQK !!!currentband %d\n", rtlhal->current_bandtype);
        rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
        for (i = 0; i < 3; i++) {
                if (rtlhal->current_bandtype == BAND_ON_5G) {
@@ -2573,10 +2461,9 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
                regec4 = result[i][6];
                regecc = result[i][7];
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx "
-                       "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ",
+                       "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n",
                        rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
-                       regecc));
+                       regecc);
        }
        if (final_candidate != 0xff) {
                rtlphy->reg_e94 = rege94 = result[final_candidate][0];
@@ -2588,12 +2475,11 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
                regec4 = result[final_candidate][6];
                regecc = result[final_candidate][7];
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("IQK: final_candidate is %x\n", final_candidate));
+                       "IQK: final_candidate is %x\n", final_candidate);
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx "
-                       "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ",
+                       "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n",
                        rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
-                       regecc));
+                       regecc);
                patha_ok = pathb_ok = true;
        } else {
                rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; /* X default value */
@@ -2618,7 +2504,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
                        true;
 
                RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD,
-                        ("\nIQK OK indexforchannel %d.\n", indexforchannel));
+                        "IQK OK indexforchannel %d\n", indexforchannel);
        }
 }
 
@@ -2629,17 +2515,17 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
        struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
        u8 indexforchannel;
 
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("channel %d\n", channel));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "channel %d\n", channel);
        /*------Do IQK for normal chip and test chip 5G band------- */
        indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-               ("indexforchannel %d done %d\n", indexforchannel,
-               rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n",
+                indexforchannel,
+                rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done);
        if (0 && !rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done &&
                rtlphy->need_iqk) {
                /* Re Do IQK. */
                RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD,
-                        ("Do IQK Matrix reg for channel:%d....\n", channel));
+                        "Do IQK Matrix reg for channel:%d....\n", channel);
                rtl92d_phy_iq_calibrate(hw);
        } else {
                /* Just load the value. */
@@ -2647,8 +2533,8 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
                if (((!rtlhal->load_imrandiqk_setting_for2g) &&
                    indexforchannel == 0) || indexforchannel > 0) {
                        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
-                                ("Just Read IQK Matrix reg for channel:%d"
-                                "....\n", channel));
+                                "Just Read IQK Matrix reg for channel:%d....\n",
+                                channel);
                        if ((rtlphy->iqk_matrix_regsetting[indexforchannel].
                             value[0] != NULL)
                                /*&&(regea4 != 0) */)
@@ -2672,7 +2558,7 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
                }
        }
        rtlphy->need_iqk = false;
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
 }
 
 static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2)
@@ -2727,8 +2613,8 @@ static void _rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw,
                        }
                }
                smallest_abs_val = 0xffffffff;
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("curveindex[%d] = %x\n", i,
-                       curveindex[i]));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, "curveindex[%d] = %x\n",
+                       i, curveindex[i]);
        }
 }
 
@@ -2743,14 +2629,14 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
        u32 u4tmp = 0, u4regvalue = 0;
        bool bneed_powerdown_radio = false;
 
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("path %d\n", erfpath));
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("band type = %d\n",
-               rtlpriv->rtlhal.current_bandtype));
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("channel = %d\n", channel));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, "band type = %d\n",
+               rtlpriv->rtlhal.current_bandtype);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "channel = %d\n", channel);
        if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */
                u4tmp = curveindex_5g[channel-1];
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("ver 1 set RF-A, 5G,   0x28 = 0x%ulx !!\n", u4tmp));
+                       "ver 1 set RF-A, 5G,    0x28 = 0x%ulx !!\n", u4tmp);
                if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
                        rtlpriv->rtlhal.interfaceindex == 1) {
                        bneed_powerdown_radio =
@@ -2769,7 +2655,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
        } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) {
                u4tmp = curveindex_2g[channel-1];
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp));
+                       "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp);
                if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
                        rtlpriv->rtlhal.interfaceindex == 0) {
                        bneed_powerdown_radio =
@@ -2781,14 +2667,14 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
                }
                rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n",
-                       rtl_get_rfreg(hw,  erfpath, RF_SYN_G4, 0x3f800)));
+                       "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n",
+                       rtl_get_rfreg(hw,  erfpath, RF_SYN_G4, 0x3f800));
                if (bneed_powerdown_radio)
                        _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
                if (rtlpriv->rtlhal.during_mac0init_radiob)
                        rtl92d_phy_powerdown_anotherphy(hw, true);
        }
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
 }
 
 static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
@@ -2836,20 +2722,20 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
                                              RF_SYN_G6, BRFREGOFFSETMASK);
                }
                RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                       ("PHY_LCK finish delay for %d ms=2\n", timecount));
+                       "PHY_LCK finish delay for %d ms=2\n", timecount);
                u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK);
                if (index == 0 && rtlhal->interfaceindex == 0) {
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("path-A / 5G LCK\n"));
+                               "path-A / 5G LCK\n");
                } else {
                        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-                               ("path-B / 2.4G LCK\n"));
+                               "path-B / 2.4G LCK\n");
                }
                memset(&curvecount_val[0], 0, CV_CURVE_CNT * 2);
                /* Set LC calibration off */
                rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW,
                              0x08000, 0x0);
-               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("set RF 0x18[15] = 0\n"));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,  "set RF 0x18[15] = 0\n");
                /* save Curve-counting number */
                for (i = 0; i < CV_CURVE_CNT; i++) {
                        u32 readval = 0, readval2 = 0;
@@ -2899,7 +2785,7 @@ static void _rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("cosa PHY_LCK ver=2\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "cosa PHY_LCK ver=2\n");
        _rtl92d_phy_lc_calibrate_sw(hw, is2t);
 }
 
@@ -2917,8 +2803,8 @@ void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw)
 
        rtlphy->lck_inprogress = true;
        RTPRINT(rtlpriv, FINIT, INIT_IQK,
-               ("LCK:Start!!! currentband %x delay %d ms\n",
-                rtlhal->current_bandtype, timecount));
+               "LCK:Start!!! currentband %x delay %d ms\n",
+               rtlhal->current_bandtype, timecount);
        if (IS_92D_SINGLEPHY(rtlhal->version)) {
                _rtl92d_phy_lc_calibrate(hw, true);
        } else {
@@ -2926,7 +2812,7 @@ void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw)
                _rtl92d_phy_lc_calibrate(hw, false);
        }
        rtlphy->lck_inprogress = false;
-       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LCK:Finish!!!\n"));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LCK:Finish!!!\n");
 }
 
 void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
@@ -2941,7 +2827,7 @@ static bool _rtl92d_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
        struct swchnlcmd *pcmd;
 
        if (cmdtable == NULL) {
-               RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+               RT_ASSERT(false, "cmdtable cannot be NULL\n");
                return false;
        }
        if (cmdtableidx >= cmdtablesz)
@@ -2962,10 +2848,10 @@ void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw)
        u8 i;
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                       ("settings regs %d default regs %d\n",
-                       (int)(sizeof(rtlphy->iqk_matrix_regsetting) /
-                       sizeof(struct iqk_matrix_regs)),
-                       IQK_MATRIX_REG_NUM));
+                "settings regs %d default regs %d\n",
+                (int)(sizeof(rtlphy->iqk_matrix_regsetting) /
+                      sizeof(struct iqk_matrix_regs)),
+                IQK_MATRIX_REG_NUM);
        /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */
        for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
                rtlphy->iqk_matrix_regsetting[i].value[0][0] = 0x100;
@@ -3084,7 +2970,7 @@ static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("switch case not process\n"));
+                                "switch case not processed\n");
                        break;
                }
                break;
@@ -3111,7 +2997,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
 
        if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
-                        ("sw_chnl_inprogress false driver sleep or unload\n"));
+                        "sw_chnl_inprogress false driver sleep or unload\n");
                return 0;
        }
        while (rtlphy->lck_inprogress && timecount < timeout) {
@@ -3133,19 +3019,18 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
                 * 5G and 2.4G band. */
                if (channel <= 14)
                        return 0;
-               RT_ASSERT((channel > 14), ("5G but channel<=14"));
+               RT_ASSERT((channel > 14), "5G but channel<=14\n");
                break;
        case BAND_ON_2_4G:
                /* Get first channel error when change between
                 * 5G and 2.4G band. */
                if (channel > 14)
                        return 0;
-               RT_ASSERT((channel <= 14), ("2G but channel>14"));
+               RT_ASSERT((channel <= 14), "2G but channel>14\n");
                break;
        default:
-               RT_ASSERT(false,
-                         ("Invalid WirelessMode(%#x)!!\n",
-                          rtlpriv->mac80211.mode));
+               RT_ASSERT(false, "Invalid WirelessMode(%#x)!!\n",
+                         rtlpriv->mac80211.mode);
                break;
        }
        rtlphy->sw_chnl_inprogress = true;
@@ -3154,7 +3039,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
        rtlphy->sw_chnl_stage = 0;
        rtlphy->sw_chnl_step = 0;
        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-                ("switch to channel%d\n", rtlphy->current_channel));
+                "switch to channel%d\n", rtlphy->current_channel);
 
        do {
                if (!rtlphy->sw_chnl_inprogress)
@@ -3171,7 +3056,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
                }
                break;
        } while (true);
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
        rtlphy->sw_chnl_inprogress = false;
        return 1;
 }
@@ -3182,8 +3067,8 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw)
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-                ("--->Cmd(%#x), set_io_inprogress(%d)\n",
-                rtlphy->current_io_type, rtlphy->set_io_inprogress));
+                "--->Cmd(%#x), set_io_inprogress(%d)\n",
+                rtlphy->current_io_type, rtlphy->set_io_inprogress);
        switch (rtlphy->current_io_type) {
        case IO_CMD_RESUME_DM_BY_SCAN:
                de_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
@@ -3197,12 +3082,12 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        rtlphy->set_io_inprogress = false;
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-                ("<---(%#x)\n", rtlphy->current_io_type));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n",
+                rtlphy->current_io_type);
 }
 
 bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
@@ -3212,23 +3097,23 @@ bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
        bool postprocessing = false;
 
        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-                ("-->IO Cmd(%#x), set_io_inprogress(%d)\n",
-                iotype, rtlphy->set_io_inprogress));
+                "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
+                iotype, rtlphy->set_io_inprogress);
        do {
                switch (iotype) {
                case IO_CMD_RESUME_DM_BY_SCAN:
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-                                ("[IO CMD] Resume DM after scan.\n"));
+                                "[IO CMD] Resume DM after scan\n");
                        postprocessing = true;
                        break;
                case IO_CMD_PAUSE_DM_BY_SCAN:
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-                                ("[IO CMD] Pause DM before scan.\n"));
+                                "[IO CMD] Pause DM before scan\n");
                        postprocessing = true;
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("switch case not process\n"));
+                                "switch case not processed\n");
                        break;
                }
        } while (false);
@@ -3239,7 +3124,7 @@ bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
                return false;
        }
        rtl92d_phy_set_io(hw);
-       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype));
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
        return true;
 }
 
@@ -3297,7 +3182,7 @@ static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw)
                rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                       ("Fail !!! Switch RF timeout.\n"));
+                        "Fail !!! Switch RF timeout\n");
                return;
        }
        /* e.   For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */
@@ -3332,7 +3217,7 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
                        do {
                                InitializeCount++;
                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                        ("IPS Set eRf nic enable\n"));
+                                        "IPS Set eRf nic enable\n");
                                rtstatus = rtl_ps_enable_nic(hw);
                        } while ((rtstatus != true) &&
                                 (InitializeCount < 10));
@@ -3341,11 +3226,10 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                          RT_RF_OFF_LEVL_HALT_NIC);
                } else {
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-                                ("awake, sleeped:%d ms state_"
-                                "inap:%x\n",
+                                "awake, sleeped:%d ms state_inap:%x\n",
                                 jiffies_to_msecs(jiffies -
-                                ppsc->last_sleep_jiffies),
-                                rtlpriv->psc.state_inap));
+                                                 ppsc->last_sleep_jiffies),
+                                rtlpriv->psc.state_inap);
                        ppsc->last_awake_jiffies = jiffies;
                        _rtl92d_phy_set_rfon(hw);
                }
@@ -3360,7 +3244,7 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
        case ERFOFF:
                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                ("IPS Set eRf nic disable\n"));
+                                "IPS Set eRf nic disable\n");
                        rtl_ps_disable_nic(hw);
                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
                } else {
@@ -3385,41 +3269,40 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                continue;
                        } else if (rtlpci->pdev->current_state != PCI_D0) {
                                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                        ("eRf Off/Sleep: %d times TcbBusyQueu"
-                                        "e[%d] !=0 but lower power state!\n",
-                                        (i + 1), queue_id));
+                                        "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n",
+                                        i + 1, queue_id);
                                break;
                        } else {
                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                        ("eRf Off/Sleep: %d times TcbBusyQueu"
-                                        "e[%d] =%d "
-                                        "before doze!\n", (i + 1), queue_id,
-                                         skb_queue_len(&ring->queue)));
+                                        "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
+                                        i + 1, queue_id,
+                                        skb_queue_len(&ring->queue));
                                udelay(10);
                                i++;
                        }
 
                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                        ("\nERFOFF: %d times TcbBusyQueue[%d] "
-                                        "= %d !\n",
-                                         MAX_DOZE_WAITING_TIMES_9x, queue_id,
-                                         skb_queue_len(&ring->queue)));
+                                        "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
+                                        MAX_DOZE_WAITING_TIMES_9x, queue_id,
+                                        skb_queue_len(&ring->queue));
                                break;
                        }
                }
                RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-                        ("Set rfsleep awaked:%d ms\n",
-                        jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)));
-               RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("sleep awaked:%d ms "
-                        "state_inap:%x\n", jiffies_to_msecs(jiffies -
-                        ppsc->last_awake_jiffies), rtlpriv->psc.state_inap));
+                        "Set rfsleep awaked:%d ms\n",
+                        jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+                        "sleep awaked:%d ms state_inap:%x\n",
+                        jiffies_to_msecs(jiffies -
+                                         ppsc->last_awake_jiffies),
+                        rtlpriv->psc.state_inap);
                ppsc->last_sleep_jiffies = jiffies;
                _rtl92d_phy_set_rfsleep(hw);
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                bresult = false;
                break;
        }
@@ -3437,17 +3320,17 @@ void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw)
        switch (rtlhal->macphymode) {
        case DUALMAC_DUALPHY:
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        ("MacPhyMode: DUALMAC_DUALPHY\n"));
+                        "MacPhyMode: DUALMAC_DUALPHY\n");
                rtl_write_byte(rtlpriv, offset, 0xF3);
                break;
        case SINGLEMAC_SINGLEPHY:
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        ("MacPhyMode: SINGLEMAC_SINGLEPHY\n"));
+                        "MacPhyMode: SINGLEMAC_SINGLEPHY\n");
                rtl_write_byte(rtlpriv, offset, 0xF4);
                break;
        case DUALMAC_SINGLEPHY:
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        ("MacPhyMode: DUALMAC_SINGLEPHY\n"));
+                        "MacPhyMode: DUALMAC_SINGLEPHY\n");
                rtl_write_byte(rtlpriv, offset, 0xF1);
                break;
        }
@@ -3578,7 +3461,7 @@ void rtl92d_phy_set_poweron(struct ieee80211_hw *hw)
                        }
                }
                if (i == 200)
-                       RT_ASSERT(false, ("Another mac power off over time\n"));
+                       RT_ASSERT(false, "Another mac power off over time\n");
        }
 }
 
@@ -3615,7 +3498,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
        u8 rfpath, i;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n");
        /* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */
        if (rtlhal->current_bandtype == BAND_ON_2_4G) {
                /* r_select_5G for path_A/B,0x878 */
@@ -3764,7 +3647,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
                } else {
                        rtl92d_phy_enable_anotherphy(hw, false);
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                                ("MAC1 use DBI to update 0x888"));
+                                "MAC1 use DBI to update 0x888\n");
                        /* 0x888 */
                        rtl92de_write_dword_dbi(hw, RFPGA0_ADDALLOCKEN,
                                                rtl92de_read_dword_dbi(hw,
@@ -3789,9 +3672,9 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
                        BRFREGOFFSETMASK);
        }
        for (i = 0; i < 2; i++)
-               RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("RF 0x18 = 0x%x\n",
-                         rtlphy->rfreg_chnlval[i]));
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==\n"));
+               RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n",
+                        rtlphy->rfreg_chnlval[i]);
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==\n");
 
 }
 
index a52c824b41e32e1d09cc29d451339316cd53dfe2..f074952bf25c53c3fcd6dbf6ae22f0a1f8de9316 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 131acc306fcc07ea2d1eec4bb32193f83a74eefd..9bc4623310784f6ebb60be727043670ba2bb05c7 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index db27cebaac2c80052a0479992c88ebfa25017896..ff34d2dd39b894cd50eafea97af01121bb6a1521 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -50,8 +50,8 @@ void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
                                      BIT(11), 0x01);
 
                        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
-                                ("20M RF 0x18 = 0x%x\n",
-                                rtlphy->rfreg_chnlval[rfpath]));
+                                "20M RF 0x18 = 0x%x\n",
+                                rtlphy->rfreg_chnlval[rfpath]);
                }
 
                break;
@@ -62,13 +62,13 @@ void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
                        rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11),
                                      0x00);
                        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
-                                ("40M RF 0x18 = 0x%x\n",
-                                rtlphy->rfreg_chnlval[rfpath]));
+                                "40M RF 0x18 = 0x%x\n",
+                                rtlphy->rfreg_chnlval[rfpath]);
                }
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n", bandwidth));
+                        "unknown bandwidth: %#X\n", bandwidth);
                break;
        }
 }
@@ -127,23 +127,23 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
        tmpval = tx_agc[RF90_PATH_A] & 0xff;
        rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, BMASKBYTE1, tmpval);
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-               RTXAGC_A_CCK1_MCS32));
+               "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_A_CCK1_MCS32);
        tmpval = tx_agc[RF90_PATH_A] >> 8;
        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-               RTXAGC_B_CCK11_A_CCK2_11));
+               "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_B_CCK11_A_CCK2_11);
        tmpval = tx_agc[RF90_PATH_B] >> 24;
        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, BMASKBYTE0, tmpval);
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-               RTXAGC_B_CCK11_A_CCK2_11));
+               "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_B_CCK11_A_CCK2_11);
        tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
        rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-               ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-               RTXAGC_B_CCK1_55_MCS32));
+               "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
+               tmpval, RTXAGC_B_CCK1_55_MCS32);
 }
 
 static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
@@ -165,8 +165,8 @@ static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
                    (powerbase0 << 8) | powerbase0;
                *(ofdmbase + i) = powerbase0;
                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                       (" [OFDM power base index rf(%c) = 0x%x]\n",
-                       ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
+                       " [OFDM power base index rf(%c) = 0x%x]\n",
+                       i == 0 ? 'A' : 'B', *(ofdmbase + i));
        }
 
        for (i = 0; i < 2; i++) {
@@ -179,8 +179,8 @@ static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
                             (powerbase1 << 8) | powerbase1;
                *(mcsbase + i) = powerbase1;
                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                       (" [MCS power base index rf(%c) = 0x%x]\n",
-                       ((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
+                       " [MCS power base index rf(%c) = 0x%x]\n",
+                       i == 0 ? 'A' : 'B', *(mcsbase + i));
        }
 }
 
@@ -232,9 +232,9 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                                        (rf ? 8 : 0)] + ((index < 2) ?
                                        powerbase0[rf] :
                                        powerbase1[rf]);
-                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better "
-                               "performance, writeval(%c) = 0x%x\n",
-                               ((rf == 0) ? 'A' : 'B'), writeval));
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               "RTK better performance, writeval(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeval);
                        break;
                case 1:
                        if (rtlphy->pwrgroup_cnt == 1)
@@ -253,33 +253,31 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                                                powerbase0[rf] :
                                                powerbase1[rf]);
                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                                       ("Realtek regulatory, "
-                                       "20MHz, writeval(%c) = 0x%x\n",
-                                       ((rf == 0) ? 'A' : 'B'),
-                                       writeval));
+                                       "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n",
+                                       rf == 0 ? 'A' : 'B', writeval);
                        }
                        break;
                case 2:
                        writeval = ((index < 2) ? powerbase0[rf] :
                                   powerbase1[rf]);
-                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("Better regulatory, "
-                               "writeval(%c) = 0x%x\n",
-                               ((rf == 0) ? 'A' : 'B'), writeval));
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               "Better regulatory, writeval(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeval);
                        break;
                case 3:
                        chnlgroup = 0;
                        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                                       ("customer's limit, 40MHz rf(%c) = "
-                                       "0x%x\n", ((rf == 0) ? 'A' : 'B'),
+                                       "customer's limit, 40MHz rf(%c) = 0x%x\n",
+                                       rf == 0 ? 'A' : 'B',
                                        rtlefuse->pwrgroup_ht40[rf]
-                                       [channel - 1]));
+                                       [channel - 1]);
                        } else {
                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                                       ("customer's limit, 20MHz rf(%c) = "
-                                       "0x%x\n", ((rf == 0) ? 'A' : 'B'),
+                                       "customer's limit, 20MHz rf(%c) = 0x%x\n",
+                                       rf == 0 ? 'A' : 'B',
                                        rtlefuse->pwrgroup_ht20[rf]
-                                       [channel - 1]));
+                                       [channel - 1]);
                        }
                        for (i = 0; i < 4; i++) {
                                pwr_diff_limit[i] =
@@ -308,13 +306,13 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                                         (pwr_diff_limit[1] << 8) |
                                         (pwr_diff_limit[0]);
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("Customer's limit rf(%c) = 0x%x\n",
-                               ((rf == 0) ? 'A' : 'B'), customer_limit));
+                               "Customer's limit rf(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', customer_limit);
                        writeval = customer_limit + ((index < 2) ?
                                   powerbase0[rf] : powerbase1[rf]);
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("Customer, writeval rf(%c)= 0x%x\n",
-                               ((rf == 0) ? 'A' : 'B'), writeval));
+                               "Customer, writeval rf(%c)= 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeval);
                        break;
                default:
                        chnlgroup = 0;
@@ -323,9 +321,8 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
                                   (rf ? 8 : 0)] + ((index < 2) ?
                                   powerbase0[rf] : powerbase1[rf]);
                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                               ("RTK better performance, writeval "
-                               "rf(%c) = 0x%x\n",
-                               ((rf == 0) ? 'A' : 'B'), writeval));
+                               "RTK better performance, writeval rf(%c) = 0x%x\n",
+                               rf == 0 ? 'A' : 'B', writeval);
                        break;
                }
                *(p_outwriteval + rf) = writeval;
@@ -367,7 +364,7 @@ static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
                        regoffset = regoffset_b[index];
                rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval);
                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-                       ("Set 0x%x = %08x\n", regoffset, writeval));
+                       "Set 0x%x = %08x\n", regoffset, writeval);
                if (((get_rf_type(rtlphy) == RF_2T2R) &&
                    (regoffset == RTXAGC_A_MCS15_MCS12 ||
                    regoffset == RTXAGC_B_MCS15_MCS12)) ||
@@ -423,11 +420,11 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
 
        rtlhal->during_mac0init_radiob = false;
        rtlhal->during_mac1init_radioa = false;
-       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("===>\n"));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "===>\n");
        /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */
        u1btmp = rtl_read_byte(rtlpriv, mac_reg);
        if (!(u1btmp & mac_on_bit)) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable BB & RF\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n");
                /* Enable BB and RF power */
                rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL,
                        rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) |
@@ -437,7 +434,7 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
                 * and radio_b.txt has been load. */
                bresult = false;
        }
-       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<===\n"));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<===\n");
        return bresult;
 
 }
@@ -453,17 +450,17 @@ void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0)
 
        rtlhal->during_mac0init_radiob = false;
        rtlhal->during_mac1init_radioa = false;
-       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n"));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
        /* check MAC0 enable or not again now, if
         * enabled, not power down radio A. */
        u1btmp = rtl_read_byte(rtlpriv, mac_reg);
        if (!(u1btmp & mac_on_bit)) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("power down\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n");
                /* power down RF radio A according to YuNan's advice. */
                rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER,
                                        0x00000000, direct);
        }
-       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n"));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
 }
 
 bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
@@ -606,7 +603,7 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
                }
                if (rtstatus != true) {
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                               ("Radio[%d] Fail!!", rfpath));
+                                "Radio[%d] Fail!!", rfpath);
                        goto phy_rf_cfg_fail;
                }
 
@@ -620,7 +617,7 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
                rtl92d_phy_powerdown_anotherphy(hw, false);
        else if (need_pwrdown_radiob)
                rtl92d_phy_powerdown_anotherphy(hw, true);
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
        return rtstatus;
 
 phy_rf_cfg_fail:
index 74b9cfc39a83ba9bfca24d39bf5d7317de170e23..0fe1a48593e8b90dd797335efed9fd9e38598ef6 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 7911c9c870859ab11c5e03e3bb7cdede5eb0bb54..4898c502974db606bf725ed0664318f0655ab7f8 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-
 #include "../wifi.h"
 #include "../core.h"
 #include "../pci.h"
@@ -44,6 +39,8 @@
 #include "trx.h"
 #include "led.h"
 
+#include <linux/module.h>
+
 static void rtl92d_init_aspm_vars(struct ieee80211_hw *hw)
 {
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -94,7 +91,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
        u8 tid;
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       const struct firmware *firmware;
        static int header_print;
 
        rtlpriv->dm.dm_initialgain_enable = true;
@@ -154,9 +150,9 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
        rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
        if (!rtlpriv->psc.inactiveps)
-               pr_info("rtl8192ce: Power Save off (module option)\n");
+               pr_info("Power Save off (module option)\n");
        if (!rtlpriv->psc.fwctrl_lps)
-               pr_info("rtl8192ce: FW Power Save off (module option)\n");
+               pr_info("FW Power Save off (module option)\n");
        rtlpriv->psc.reg_fwctrl_lps = 3;
        rtlpriv->psc.reg_max_lps_awakeintvl = 5;
        /* for ASPM, you can close aspm through
@@ -170,41 +166,38 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
        else if (rtlpriv->psc.reg_fwctrl_lps == 3)
                rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
 
+       /* for early mode */
+       rtlpriv->rtlhal.earlymode_enable = true;
+       for (tid = 0; tid < 8; tid++)
+               skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
+
+       /* Only load firmware for first MAC */
+       if (header_print)
+               return 0;
+
        /* for firmware buf */
        rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
        if (!rtlpriv->rtlhal.pfirmware) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't alloc buffer for fw.\n"));
+                        "Can't alloc buffer for fw\n");
                return 1;
        }
 
-       if (!header_print) {
-               pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
-               pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
-               header_print++;
-       }
+       rtlpriv->max_fw_size = 0x8000;
+       pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
+       pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
+       header_print++;
+
        /* request fw */
-       err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
-                              rtlpriv->io.dev);
+       err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
+                                     rtlpriv->io.dev, GFP_KERNEL, hw,
+                                     rtl_fw_cb);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Failed to request firmware!\n"));
-               return 1;
-       }
-       if (firmware->size > 0x8000) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Firmware is too big!\n"));
-               release_firmware(firmware);
+                        "Failed to request firmware!\n");
                return 1;
        }
-       memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
-       rtlpriv->rtlhal.fwsize = firmware->size;
-       release_firmware(firmware);
 
-       /* for early mode */
-       rtlpriv->rtlhal.earlymode_enable = true;
-       for (tid = 0; tid < 8; tid++)
-               skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
        return 0;
 }
 
@@ -424,7 +417,7 @@ static int __init rtl92de_module_init(void)
 
        ret = pci_register_driver(&rtl92de_driver);
        if (ret)
-               RT_ASSERT(false, (": No device found\n"));
+               RT_ASSERT(false, "No device found\n");
        return ret;
 }
 
index c95e47de13461ed2269629dd71acac312319547a..0e6035b8fd86faec14d07dd64f22b0acd4037356 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index bad7f9449ecf597f6f3aae0635d5219260d675dd..8ea6f528dfa6d72c4b460ce8bcf60b8555cd8c3e 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 93f30ca62d8fcfd9d37938f02657f1f8d992e8a9..8b724a86117a5f1130d0d7e83fe87e466182676f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 3637c0c3352513b2dab6a6c964feb61b0f2085ad..a7f6126e2f861f970c0e0f1c63a27021b649be36 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -602,8 +602,8 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
                                           EM_HDR_LEN);
                        if (ptcb_desc->empkt_num) {
                                RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD,
-                                        ("Insert 8 byte.pTcb->EMPktNum:%d\n",
-                                         ptcb_desc->empkt_num));
+                                        "Insert 8 byte.pTcb->EMPktNum:%d\n",
+                                        ptcb_desc->empkt_num);
                                _rtl92de_insert_emcontent(ptcb_desc,
                                                          (u8 *)(skb->data));
                        }
@@ -700,7 +700,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
                if (ieee80211_is_data_qos(fc)) {
                        if (mac->rdg_en) {
                                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-                                       ("Enable RDG function.\n"));
+                                        "Enable RDG function\n");
                                SET_TX_DESC_RDG_ENABLE(pdesc, 1);
                                SET_TX_DESC_HTC(pdesc, 1);
                        }
@@ -726,7 +726,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
                SET_TX_DESC_PKT_ID(pdesc, 8);
        }
        SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
-       RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+       RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 }
 
 void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
@@ -776,7 +776,7 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
        }
 
        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
-                     "H2C Tx Cmd Content\n", pdesc, TX_DESC_SIZE);
+                     "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
        wmb();
        SET_TX_DESC_OWN(pdesc, 1);
 }
@@ -793,8 +793,8 @@ void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
                        SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR txdesc :%d"
-                                         " not process\n", desc_name));
+                       RT_ASSERT(false, "ERR txdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        } else {
@@ -813,8 +813,8 @@ void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
                        SET_RX_DESC_EOR(pdesc, 1);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR rxdesc :%d "
-                                         "not process\n", desc_name));
+                       RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        }
@@ -833,8 +833,8 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name)
                        ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR txdesc :%d "
-                                         "not process\n", desc_name));
+                       RT_ASSERT(false, "ERR txdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        } else {
@@ -847,8 +847,8 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name)
                        ret = GET_RX_DESC_PKT_LEN(pdesc);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR rxdesc :%d "
-                                         "not process\n", desc_name));
+                       RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        }
index 4d55d0b6816dca21b1b4322b46be14f1e87cf7b7..0dc736c2723b827661f973a8a9999fbd1e8f366f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index c6c044816d39e585a4cf9e0625675aaf1a1d7574..d1b0a1e1497181220146ce9eb82e7a321252ac07 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 4203a8531ca0b0569774ad0b72e53c2af07a9d36..fbabae17259e6e6f6e021d754c6a36094f3e2ac2 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -170,9 +170,9 @@ static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
        thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
 
        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-                ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
-                 "eeprom_thermalmeter 0x%x\n", thermalvalue,
-                 rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter));
+                "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n",
+                thermalvalue,
+                rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter);
 
        if (thermalvalue) {
                rtlpriv->dm.thermalvalue = thermalvalue;
@@ -282,11 +282,11 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
                }
 
                if (ra->pre_ratr_state != ra->ratr_state) {
-                       RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, ("RSSI = %ld "
-                               "RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
-                               rtlpriv->dm.undecorated_smoothed_pwdb,
-                               ra->ratr_state,
-                               ra->pre_ratr_state, ra->ratr_state));
+                       RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
+                                "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
+                                rtlpriv->dm.undecorated_smoothed_pwdb,
+                                ra->ratr_state,
+                                ra->pre_ratr_state, ra->ratr_state);
 
                        rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
                                                           ra->ratr_state);
@@ -586,7 +586,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
        if ((mac->link_state < MAC80211_LINKED) &&
            (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-                        ("Not connected to any\n"));
+                        "Not connected to any\n");
 
                rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
 
@@ -599,22 +599,22 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
                        undecorated_smoothed_pwdb =
                            rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("AP Client PWDB = 0x%lx\n",
-                                 undecorated_smoothed_pwdb));
+                                "AP Client PWDB = 0x%lx\n",
+                                undecorated_smoothed_pwdb);
                } else {
                        undecorated_smoothed_pwdb =
                            rtlpriv->dm.undecorated_smoothed_pwdb;
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("STA Default Port PWDB = 0x%lx\n",
-                                 undecorated_smoothed_pwdb));
+                                "STA Default Port PWDB = 0x%lx\n",
+                                undecorated_smoothed_pwdb);
                }
        } else {
                undecorated_smoothed_pwdb =
                    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("AP Ext Port PWDB = 0x%lx\n",
-                         undecorated_smoothed_pwdb));
+                        "AP Ext Port PWDB = 0x%lx\n",
+                        undecorated_smoothed_pwdb);
        }
 
        txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2;
index 9051a556acc4f0ded17763cc7a6247f346f5c7ca..e1b19a64176584731f018ff6c926588872d44c7b 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 3fda6b1dcf465ee3fcda52a5807d78dedb50c760..0d8bf565700881e22e1b5a0c3c652ad9c1366834 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -66,7 +66,7 @@ static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw)
                cpustatus = rtl_read_byte(rtlpriv, TCR);
                if (cpustatus & IMEM_RDY) {
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                               ("IMEM Ready after CPU has refilled.\n"));
+                                "IMEM Ready after CPU has refilled\n");
                        break;
                }
 
@@ -120,9 +120,8 @@ static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw)
                return 0x22;
                break;
        default:
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                        ("Unknown RF type(%x)\n",
-                        rtlphy->rf_type));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unknown RF type(%x)\n",
+                        rtlphy->rf_type);
                break;
        }
        return 0x22;
@@ -177,7 +176,7 @@ static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw,
 
        if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                       ("Size over FIRMWARE_CODE_SIZE!\n"));
+                        "Size over FIRMWARE_CODE_SIZE!\n");
 
                return false;
        }
@@ -231,8 +230,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
        short pollingcnt = 1000;
        bool rtstatus = true;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("LoadStaus(%d)\n",
-                loadfw_status));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                "LoadStaus(%d)\n", loadfw_status);
 
        firmware->fwstatus = (enum fw_status)loadfw_status;
 
@@ -248,8 +247,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 
                if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("FW_STATUS_LOAD_IMEM"
-                                " FAIL CPU, Status=%x\r\n", cpustatus));
+                                "FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\n",
+                                cpustatus);
                        goto status_check_fail;
                }
                break;
@@ -266,8 +265,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 
                if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("FW_STATUS_LOAD_EMEM"
-                                " FAIL CPU, Status=%x\r\n", cpustatus));
+                                "FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\n",
+                                cpustatus);
                        goto status_check_fail;
                }
 
@@ -275,7 +274,7 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
                rtstatus = _rtl92s_firmware_enable_cpu(hw);
                if (rtstatus != true) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Enable CPU fail!\n"));
+                                "Enable CPU fail!\n");
                        goto status_check_fail;
                }
                break;
@@ -291,14 +290,14 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 
                if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Polling  DMEM code done"
-                                " fail ! cpustatus(%#x)\n", cpustatus));
+                                "Polling DMEM code done fail ! cpustatus(%#x)\n",
+                                cpustatus);
                        goto status_check_fail;
                }
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        ("DMEM code download success,"
-                       " cpustatus(%#x)\n", cpustatus));
+                        "DMEM code download success, cpustatus(%#x)\n",
+                        cpustatus);
 
                /* Prevent Delay too much and being scheduled out */
                /* Polling Load Firmware ready */
@@ -311,14 +310,14 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
                } while (pollingcnt--);
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        ("Polling Load Firmware ready,"
-                       " cpustatus(%x)\n",     cpustatus));
+                        "Polling Load Firmware ready, cpustatus(%x)\n",
+                        cpustatus);
 
                if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) ||
                    (pollingcnt <= 0)) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Polling Load Firmware"
-                               " ready fail ! cpustatus(%x)\n", cpustatus));
+                                "Polling Load Firmware ready fail ! cpustatus(%x)\n",
+                                cpustatus);
                        goto status_check_fail;
                }
 
@@ -332,7 +331,7 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
                                RCR_APP_ICV | RCR_APP_MIC));
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                        ("Current RCR settings(%#x)\n", tmpu4b));
+                        "Current RCR settings(%#x)\n", tmpu4b);
 
                /* Set to normal mode. */
                rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL);
@@ -340,14 +339,15 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 
        default:
                RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                        ("Unknown status check!\n"));
+                        "Unknown status check!\n");
                rtstatus = false;
                break;
        }
 
 status_check_fail:
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("loadfw_status(%d), "
-                "rtstatus(%x)\n", loadfw_status, rtstatus));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                "loadfw_status(%d), rtstatus(%x)\n",
+                loadfw_status, rtstatus);
        return rtstatus;
 }
 
@@ -364,7 +364,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
        u8 fwstatus = FW_STATUS_INIT;
        bool rtstatus = true;
 
-       if (!rtlhal->pfirmware)
+       if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
                return 1;
 
        firmware = (struct rt_firmware *)rtlhal->pfirmware;
@@ -378,17 +378,17 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
        firmware->firmwareversion =  byte(pfwheader->version, 0);
        firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("signature:%x, version:"
-                "%x, size:%x,"
-                "imemsize:%x, sram size:%x\n", pfwheader->signature,
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                "signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n",
+                pfwheader->signature,
                 pfwheader->version, pfwheader->dmem_size,
-                pfwheader->img_imem_size, pfwheader->img_sram_size));
+                pfwheader->img_imem_size, pfwheader->img_sram_size);
 
        /* 2. Retrieve IMEM image. */
        if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size >
            sizeof(firmware->fw_imem))) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                       ("memory for data image is less than IMEM required\n"));
+                        "memory for data image is less than IMEM required\n");
                goto fail;
        } else {
                puc_mappedfile += fwhdr_size;
@@ -401,7 +401,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
        /* 3. Retriecve EMEM image. */
        if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                       ("memory for data image is less than EMEM required\n"));
+                        "memory for data image is less than EMEM required\n");
                goto fail;
        } else {
                puc_mappedfile += firmware->fw_imem_len;
@@ -436,7 +436,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                       ("Unexpected Download step!!\n"));
+                                "Unexpected Download step!!\n");
                        goto fail;
                        break;
                }
@@ -446,14 +446,14 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
                                ul_filelength);
 
                if (rtstatus != true) {
-                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n"));
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fail!\n");
                        goto fail;
                }
 
                /* <3> Check whether load FW process is ready */
                rtstatus = _rtl92s_firmware_checkready(hw, fwstatus);
                if (rtstatus != true) {
-                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n"));
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fail!\n");
                        goto fail;
                }
 
index 74cc503efe8a8474eed867f84b44ed3d7e7f4d66..b4afff62643763f15db2f954d5abc6f1f59e3e3f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -30,6 +30,7 @@
 #define __REALTEK_FIRMWARE92S_H__
 
 #define RTL8190_MAX_FIRMWARE_CODE_SIZE         64000
+#define RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE     90000
 #define RTL8190_CPU_START_OFFSET               0x80
 /* Firmware Local buffer size. 64k */
 #define        MAX_FIRMWARE_CODE_SIZE                  0xFF00
@@ -217,7 +218,7 @@ struct rt_firmware {
        u8 fw_emem[RTL8190_MAX_FIRMWARE_CODE_SIZE];
        u32 fw_imem_len;
        u32 fw_emem_len;
-       u8 sz_fw_tmpbuffer[164000];
+       u8 sz_fw_tmpbuffer[RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE];
        u32 sz_fw_tmpbufferlen;
        u16 cmdpacket_fragthresold;
 };
index c474486e391157d1d2be8c4ff40c4ca82db91ce1..22098c2f38f13682056cfa541d86a932ebb6bbf4 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include "../wifi.h"
 #include "../efuse.h"
 #include "../base.h"
@@ -80,8 +78,8 @@ void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                        break;
                }
        default: {
-                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("switch case not process\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        "switch case not processed\n");
                        break;
                }
        }
@@ -140,7 +138,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                        u8 e_aci;
 
                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                ("HW_VAR_SLOT_TIME %x\n", val[0]));
+                                "HW_VAR_SLOT_TIME %x\n", val[0]);
 
                        rtl_write_byte(rtlpriv, SLOT_TIME, val[0]);
 
@@ -185,8 +183,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                *val = min_spacing_to_set;
 
                                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                        ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
-                                         mac->min_space_cfg));
+                                        "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+                                        mac->min_space_cfg);
 
                                rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
                                               mac->min_space_cfg);
@@ -201,8 +199,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                        mac->min_space_cfg |= (density_to_set << 3);
 
                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
-                                 mac->min_space_cfg));
+                                "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+                                mac->min_space_cfg);
 
                        rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
                                       mac->min_space_cfg);
@@ -244,8 +242,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset);
 
                                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-                                        ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
-                                         factor_toset));
+                                        "Set HW_VAR_AMPDU_FACTOR: %#x\n",
+                                        factor_toset);
                        }
                        break;
                }
@@ -282,8 +280,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                        break;
                                default:
                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                                ("HW_VAR_ACM_CTRL acm set "
-                                                 "failed: eACI is %d\n", acm));
+                                                "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
+                                                acm);
                                        break;
                                }
                        } else {
@@ -299,13 +297,13 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                                        break;
                                default:
                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                                ("switch case not process\n"));
+                                                "switch case not processed\n");
                                        break;
                                }
                        }
 
                        RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
-                                ("HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl));
+                                "HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl);
                        rtl_write_byte(rtlpriv, AcmHwCtrl, acm_ctrl);
                        break;
                }
@@ -404,7 +402,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
                }
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
 
@@ -415,14 +413,14 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u8 sec_reg_value = 0x0;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("PairwiseEncAlgorithm = %d "
-                "GroupEncAlgorithm = %d\n",
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
                 rtlpriv->sec.pairwise_enc_algorithm,
-                rtlpriv->sec.group_enc_algorithm));
+                rtlpriv->sec.group_enc_algorithm);
 
        if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                        ("not open hw encryption\n"));
+                        "not open hw encryption\n");
                return;
        }
 
@@ -433,8 +431,8 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw)
                sec_reg_value |= SCR_RXUSEDK;
        }
 
-       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("The SECR-value %x\n",
-                       sec_reg_value));
+       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n",
+                sec_reg_value);
 
        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
 
@@ -718,8 +716,8 @@ static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw)
 
        if (pollingcnt <= 0) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Polling TXDMA_INIT_VALUE "
-                        "timeout!! Current TCR(%#x)\n", tmpu1b));
+                        "Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n",
+                        tmpu1b);
                tmpu1b = rtl_read_byte(rtlpriv, CMDR);
                rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN));
                udelay(2);
@@ -870,10 +868,10 @@ static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw)
 
                /* Change Program timing */
                rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72);
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("EFUSE CONFIG OK\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "EFUSE CONFIG OK\n");
        }
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n");
 
 }
 
@@ -951,12 +949,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
        rtstatus = rtl92s_download_fw(hw);
        if (!rtstatus) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("Failed to download FW. "
-                        "Init HW without FW now.., Please copy FW into"
-                        "/lib/firmware/rtlwifi\n"));
-               rtlhal->fw_ready = false;
-       } else {
-               rtlhal->fw_ready = true;
+                        "Failed to download FW. Init HW without FW now... "
+                        "Please copy FW into /lib/firmware/rtlwifi\n");
+               return 1;
        }
 
        /* After FW download, we have to reset MAC register */
@@ -968,7 +963,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
 
        /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */
        if (rtl92s_phy_mac_config(hw) != true) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("MAC Config failed\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "MAC Config failed\n");
                return rtstatus;
        }
 
@@ -978,7 +973,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
 
        /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */
        if (rtl92s_phy_bb_config(hw) != true) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("BB Config failed\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "BB Config failed\n");
                return rtstatus;
        }
 
@@ -1014,7 +1009,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
                rtl_write_byte(rtlpriv, RF_CTRL, 0x07);
 
        if (rtl92s_phy_rf_config(hw) != true) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("RF Config failed\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n");
                return rtstatus;
        }
 
@@ -1129,26 +1124,26 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
        case NL80211_IFTYPE_UNSPECIFIED:
                bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT);
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to NO LINK!\n"));
+                        "Set Network type to NO LINK!\n");
                break;
        case NL80211_IFTYPE_ADHOC:
                bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT);
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to Ad Hoc!\n"));
+                        "Set Network type to Ad Hoc!\n");
                break;
        case NL80211_IFTYPE_STATION:
                bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT);
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to STA!\n"));
+                        "Set Network type to STA!\n");
                break;
        case NL80211_IFTYPE_AP:
                bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT);
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-                        ("Set Network type to AP!\n"));
+                        "Set Network type to AP!\n");
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Network type %d not support!\n", type));
+                        "Network type %d not supported!\n", type);
                return 1;
                break;
 
@@ -1202,7 +1197,7 @@ void rtl92se_set_qos(struct ieee80211_hw *hw, int aci)
                rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222);
                break;
        default:
-               RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+               RT_ASSERT(false, "invalid aci: %d !\n", aci);
                break;
        }
 }
@@ -1219,9 +1214,14 @@ void rtl92se_enable_interrupt(struct ieee80211_hw *hw)
 
 void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
 {
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_priv *rtlpriv;
+       struct rtl_pci *rtlpci;
 
+       rtlpriv = rtl_priv(hw);
+       /* if firmware not available, no interrupts */
+       if (!rtlpriv || !rtlpriv->max_fw_size)
+               return;
+       rtlpci = rtl_pcidev(rtl_pcipriv(hw));
        rtl_write_dword(rtlpriv, INTA_MASK, 0);
        rtl_write_dword(rtlpriv, INTA_MASK + 4, 0);
 
@@ -1583,8 +1583,8 @@ void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
-       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-                ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n",
+                add_msr, rm_msr);
 
        if (add_msr)
                rtlpci->irq_mask[0] |= add_msr;
@@ -1627,7 +1627,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 
        if (rtlefuse->epromtype == EEPROM_93C46) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("RTL819X Not boot from eeprom, check it !!"));
+                        "RTL819X Not boot from eeprom, check it !!\n");
        } else if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
                rtl_efuse_shadow_map_update(hw);
 
@@ -1636,16 +1636,16 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
                        HWSET_MAX_SIZE_92S);
        }
 
-       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
+       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
                      hwinfo, HWSET_MAX_SIZE_92S);
 
        eeprom_id = *((u16 *)&hwinfo[0]);
        if (eeprom_id != RTL8190_EEPROM_ID) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                        ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+                        "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
                rtlefuse->autoload_failflag = true;
        } else {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
                rtlefuse->autoload_failflag = false;
        }
 
@@ -1663,15 +1663,15 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
        rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                       ("EEPROMId = 0x%4x\n", eeprom_id));
+                "EEPROMId = 0x%4x\n", eeprom_id);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                       ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid));
+                "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                       ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did));
+                "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                       ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid));
+                "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                       ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid));
+                "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
 
        for (i = 0; i < 6; i += 2) {
                usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
@@ -1681,8 +1681,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
        for (i = 0; i < 6; i++)
                rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                ("%pM\n", rtlefuse->dev_addr));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);
 
        /* Get Tx Power Level by Channel */
        /* Read Tx power of Channel 1 ~ 14 from EEPROM. */
@@ -1707,23 +1706,24 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
        for (rf_path = 0; rf_path < 2; rf_path++)
                for (i = 0; i < 3; i++)
                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-                               ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
-                               i, rtlefuse->eeprom_chnlarea_txpwr_cck
-                                       [rf_path][i]));
+                               "RF(%d) EEPROM CCK Area(%d) = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->eeprom_chnlarea_txpwr_cck
+                               [rf_path][i]);
        for (rf_path = 0; rf_path < 2; rf_path++)
                for (i = 0; i < 3; i++)
                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-                               ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
-                                               [rf_path][i]));
+                               "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
+                               [rf_path][i]);
        for (rf_path = 0; rf_path < 2; rf_path++)
                for (i = 0; i < 3; i++)
                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-                               ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif
-                                       [rf_path][i]));
+                               "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif
+                               [rf_path][i]);
 
        for (rf_path = 0; rf_path < 2; rf_path++) {
 
@@ -1754,11 +1754,11 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 
                for (i = 0; i < 14; i++) {
                        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                               ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
-                                "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
-                                rtlefuse->txpwrlevel_cck[rf_path][i],
-                                rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
-                                rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
+                               "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
+                               rf_path, i,
+                               rtlefuse->txpwrlevel_cck[rf_path][i],
+                               rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
+                               rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
                }
        }
 
@@ -1791,13 +1791,13 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
                                0xf0) >> 4);
 
                        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                               ("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->pwrgroup_ht20[rf_path][i]));
+                               "RF-%d pwrgroup_ht20[%d] = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->pwrgroup_ht20[rf_path][i]);
                        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                               ("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
-                                rf_path, i,
-                                rtlefuse->pwrgroup_ht40[rf_path][i]));
+                               "RF-%d pwrgroup_ht40[%d] = 0x%x\n",
+                               rf_path, i,
+                               rtlefuse->pwrgroup_ht40[rf_path][i]);
                        }
        }
 
@@ -1852,27 +1852,27 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
                                 (hwinfo[EEPROM_REGULATORY] & 0x1);
        }
        RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-               ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+               "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
 
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
+                       "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
+                       "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
+                       "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
        for (i = 0; i < 14; i++)
                RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-                       ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
-                        rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
+                       "RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
+                       i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
 
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPwrSafetyFlag = %d\n",
-               rtlefuse->txpwr_safetyflag));
+       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+               "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag);
 
        /* Read RF-indication and Tx Power gain
         * index diff of legacy to HT OFDM rate. */
@@ -1881,8 +1881,8 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
        rtlefuse->legacy_httxpowerdiff =
                rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0];
 
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPowerDiff = %#x\n",
-               rtlefuse->eeprom_txpowerdiff));
+       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+               "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff);
 
        /* Get TSSI value for each path. */
        usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A];
@@ -1890,16 +1890,16 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
        usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B];
        rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff);
 
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
-                rtlefuse->eeprom_tssi[RF90_PATH_A],
-                rtlefuse->eeprom_tssi[RF90_PATH_B]));
+       RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
+               rtlefuse->eeprom_tssi[RF90_PATH_A],
+               rtlefuse->eeprom_tssi[RF90_PATH_B]);
 
        /* Read antenna tx power offset of B/C/D to A  from EEPROM */
        /* and read ThermalMeter from EEPROM */
        tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER];
        rtlefuse->eeprom_thermalmeter = tempval;
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("thermalmeter = 0x%x\n",
-               rtlefuse->eeprom_thermalmeter));
+       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+               "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
 
        /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */
        rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f);
@@ -1915,8 +1915,8 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
        /* Version ID, Channel plan */
        rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
        rtlefuse->txpwr_fromeprom = true;
-       RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("EEPROM ChannelPlan = 0x%4x\n",
-               rtlefuse->eeprom_channelplan));
+       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+               "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan);
 
        /* Read Customer ID or Board Type!!! */
        tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE];
@@ -1937,14 +1937,14 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
                if (!(tempval & BIT(0))) {
                        rtlefuse->b1x1_recvcombine = true;
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                               ("RF_TYPE=1T2R but only 1SS\n"));
+                                "RF_TYPE=1T2R but only 1SS\n");
                }
        }
        rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine;
        rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID];
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("EEPROM Customer ID: 0x%2x",
-                       rtlefuse->eeprom_oemid));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x",
+                rtlefuse->eeprom_oemid);
 
        /* set channel paln to world wide 13 */
        rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
@@ -1959,19 +1959,19 @@ void rtl92se_read_eeprom_info(struct ieee80211_hw *hw)
        tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD);
 
        if (tmp_u1b & BIT(4)) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
                rtlefuse->epromtype = EEPROM_93C46;
        } else {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
                rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
        }
 
        if (tmp_u1b & BIT(5)) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
                rtlefuse->autoload_failflag = false;
                _rtl92se_read_adapter_info(hw);
        } else {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
                rtlefuse->autoload_failflag = true;
        }
 }
@@ -2071,8 +2071,8 @@ static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw,
        else
                rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG);
 
-       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
-                ("%x\n", rtl_read_dword(rtlpriv, ARFR0)));
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+                rtl_read_dword(rtlpriv, ARFR0));
 }
 
 static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
@@ -2224,8 +2224,8 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
 
        mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf);
 
-       RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, ("mask = %x, bitmap = %x\n",
-                       mask, ratr_bitmap));
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, "mask = %x, bitmap = %x\n",
+                mask, ratr_bitmap);
        rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap);
        rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8)));
 
@@ -2301,14 +2301,14 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
 
        if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) {
                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                        ("RFKILL-HW Radio ON, RF ON\n"));
+                        "RFKILL-HW Radio ON, RF ON\n");
 
                rfpwr_toset = ERFON;
                ppsc->hwradiooff = false;
                actuallyset = true;
        } else if ((ppsc->hwradiooff == false) && (rfpwr_toset == ERFOFF)) {
-               RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                        ("RFKILL-HW Radio OFF, RF OFF\n"));
+               RT_TRACE(rtlpriv, COMP_RF,
+                        DBG_DMESG, "RFKILL-HW Radio OFF, RF OFF\n");
 
                rfpwr_toset = ERFOFF;
                ppsc->hwradiooff = true;
@@ -2372,7 +2372,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
                u8 cam_offset = 0;
                u8 clear_number = 5;
 
-               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
 
                for (idx = 0; idx < clear_number; idx++) {
                        rtl_cam_mark_invalid(hw, cam_offset + idx);
@@ -2401,7 +2401,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                       ("switch case not process\n"));
+                                "switch case not processed\n");
                        enc_algo = CAM_TKIP;
                        break;
                }
@@ -2419,9 +2419,8 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
                                                                 p_macaddr);
                                        if (entry_id >=  TOTAL_CAM_ENTRY) {
                                                RT_TRACE(rtlpriv,
-                                                  COMP_SEC, DBG_EMERG,
-                                                  ("Can not find free hw"
-                                                  " security cam entry\n"));
+                                                        COMP_SEC, DBG_EMERG,
+                                                        "Can not find free hw security cam entry\n");
                                                return;
                                        }
                                } else {
@@ -2435,30 +2434,31 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
 
                if (rtlpriv->sec.key_len[key_index] == 0) {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("delete one entry, entry_id is %d\n",
-                                entry_id));
+                                "delete one entry, entry_id is %d\n",
+                                entry_id);
                        if (mac->opmode == NL80211_IFTYPE_AP)
                                rtl_cam_del_entry(hw, p_macaddr);
                        rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
                } else {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("The insert KEY length is %d\n",
-                                 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+                                "The insert KEY length is %d\n",
+                                rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-                                ("The insert KEY  is %x %x\n",
-                                 rtlpriv->sec.key_buf[0][0],
-                                 rtlpriv->sec.key_buf[0][1]));
+                                "The insert KEY is %x %x\n",
+                                rtlpriv->sec.key_buf[0][0],
+                                rtlpriv->sec.key_buf[0][1]);
 
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                ("add one entry\n"));
+                                "add one entry\n");
                        if (is_pairwise) {
                                RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
-                                     "Pairwiase Key content :",
-                                      rtlpriv->sec.pairwise_key,
-                                      rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
+                                             "Pairwise Key content",
+                                             rtlpriv->sec.pairwise_key,
+                                             rtlpriv->sec.
+                                             key_len[PAIRWISE_KEYIDX]);
 
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                        ("set Pairwiase key\n"));
+                                        "set Pairwise key\n");
 
                                rtl_cam_add_one_entry(hw, macaddr, key_index,
                                        entry_id, enc_algo,
@@ -2466,7 +2466,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
                                        rtlpriv->sec.key_buf[key_index]);
                        } else {
                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                                        ("set group key\n"));
+                                        "set group key\n");
 
                                if (mac->opmode == NL80211_IFTYPE_ADHOC) {
                                        rtl_cam_add_one_entry(hw,
index 6160a9bfe98a563e168f5e6c37b518c1fb55b4c9..1886c2644a26104d37c99e38709c2dc9a58c8350 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index e3fe7c90ebf4ea661c0c0a52b75d258f01dfd981..44949b5cbb872e9ccbdc3416486b1d45d214c094 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -52,8 +52,8 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
        u8 ledcfg;
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-                ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+                LEDCFG, pled->ledpin);
 
        ledcfg = rtl_read_byte(rtlpriv, LEDCFG);
 
@@ -68,7 +68,7 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        pled->ledon = true;
@@ -76,12 +76,15 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 
 void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
 {
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_priv *rtlpriv;
        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
        u8 ledcfg;
 
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-                ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
+       rtlpriv = rtl_priv(hw);
+       if (!rtlpriv || rtlpriv->max_fw_size)
+               return;
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+                LEDCFG, pled->ledpin);
 
        ledcfg = rtl_read_byte(rtlpriv, LEDCFG);
 
@@ -101,7 +104,7 @@ void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                break;
        }
        pled->ledon = false;
@@ -141,8 +144,7 @@ void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
            ledaction == LED_CTL_POWER_ON)) {
                return;
        }
-       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
-                ledaction));
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction);
 
        _rtl92se_sw_led_control(hw, ledaction);
 }
index 8cce3870af3c88fabf0f5d9ded8a15023e3e2d42..2182dbeb5f32b56b8b2e64824f19159d4a63ce32 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index f10ac1ad9087e594747d9e4c71b29863fe623da8..6d5bbd0e4d3855c44315179052adfd8f7325f6e8 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include "../wifi.h"
 #include "../pci.h"
 #include "../ps.h"
@@ -58,16 +56,15 @@ u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 returnvalue = 0, originalvalue, bitshift;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n",
-                       regaddr, bitmask));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
+                regaddr, bitmask);
 
        originalvalue = rtl_read_dword(rtlpriv, regaddr);
        bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
        returnvalue = (originalvalue & bitmask) >> bitshift;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-                ("BBR MASK=0x%x Addr[0x%x]=0x%x\n",
-                bitmask, regaddr, originalvalue));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
+                bitmask, regaddr, originalvalue);
 
        return returnvalue;
 
@@ -79,8 +76,9 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 originalvalue, bitshift;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-                       " data(%#x)\n", regaddr, bitmask, data));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+                regaddr, bitmask, data);
 
        if (bitmask != MASKDWORD) {
                originalvalue = rtl_read_dword(rtlpriv, regaddr);
@@ -90,8 +88,9 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
 
        rtl_write_dword(rtlpriv, regaddr, data);
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-                       " data(%#x)\n", regaddr, bitmask, data));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+                regaddr, bitmask, data);
 
 }
 
@@ -149,8 +148,8 @@ static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw,
        retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
                                 BLSSI_READBACK_DATA);
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
-                rfpath, pphyreg->rflssi_readback, retvalue));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
+                rfpath, pphyreg->rflssi_readback, retvalue);
 
        return retvalue;
 
@@ -172,8 +171,8 @@ static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw,
        data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
        rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
-                rfpath, pphyreg->rf3wire_offset, data_and_addr));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
+                rfpath, pphyreg->rf3wire_offset, data_and_addr);
 }
 
 
@@ -183,8 +182,9 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 original_value, readback_value, bitshift;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
-                "bitmask(%#x)\n", regaddr, rfpath, bitmask));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
+                regaddr, rfpath, bitmask);
 
        spin_lock(&rtlpriv->locks.rf_lock);
 
@@ -195,9 +195,9 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 
        spin_unlock(&rtlpriv->locks.rf_lock);
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
-                "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath,
-                bitmask, original_value));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
+                regaddr, rfpath, bitmask, original_value);
 
        return readback_value;
 }
@@ -212,8 +212,9 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
        if (!((rtlphy->rf_pathmap >> rfpath) & 0x1))
                return;
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-                " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+                regaddr, bitmask, data, rfpath);
 
        spin_lock(&rtlpriv->locks.rf_lock);
 
@@ -228,8 +229,9 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 
        spin_unlock(&rtlpriv->locks.rf_lock);
 
-       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), "
-                "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+                regaddr, bitmask, data, rfpath);
 
 }
 
@@ -249,7 +251,7 @@ void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw,
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("Unknown operation.\n"));
+                                "Unknown operation\n");
                        break;
                }
        }
@@ -264,9 +266,9 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        u8 reg_bw_opmode;
 
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n",
-                 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
-                 "20MHz" : "40MHz"));
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
+                rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+                "20MHz" : "40MHz");
 
        if (rtlphy->set_bwmode_inprogress)
                return;
@@ -290,8 +292,7 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n",
-                        rtlphy->current_chan_bw));
+                        "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
                break;
        }
 
@@ -316,13 +317,13 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+                        "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
                break;
        }
 
        rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
        rtlphy->set_bwmode_inprogress = false;
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 }
 
 static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
@@ -332,7 +333,7 @@ static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
        struct swchnlcmd *pcmd;
 
        if (cmdtable == NULL) {
-               RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+               RT_ASSERT(false, "cmdtable cannot be NULL\n");
                return false;
        }
 
@@ -377,7 +378,7 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
        rfdependcmdcnt = 0;
 
        RT_ASSERT((channel >= 1 && channel <= 14),
-                 ("illegal channel for Zebra: %d\n", channel));
+                 "invalid channel for Zebra: %d\n", channel);
 
        _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
                                         MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
@@ -438,7 +439,7 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
                        break;
                default:
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                ("switch case not process\n"));
+                                "switch case not processed\n");
                        break;
                }
 
@@ -458,9 +459,8 @@ u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
        u32 delay;
        bool ret;
 
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-                ("switch to channel%d\n",
-                rtlphy->current_channel));
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n",
+                rtlphy->current_channel);
 
        if (rtlphy->sw_chnl_inprogress)
                return 0;
@@ -496,7 +496,7 @@ u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
 
        rtlphy->sw_chnl_inprogress = false;
 
-       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 
        return 1;
 }
@@ -556,7 +556,7 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                do {
                                        InitializeCount++;
                                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                                ("IPS Set eRf nic enable\n"));
+                                                "IPS Set eRf nic enable\n");
                                        rtstatus = rtl_ps_enable_nic(hw);
                                } while ((rtstatus != true) &&
                                         (InitializeCount < 10));
@@ -565,11 +565,11 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                                  RT_RF_OFF_LEVL_HALT_NIC);
                        } else {
                                RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-                                        ("awake, sleeped:%d ms "
-                                       "state_inap:%x\n",
-                                       jiffies_to_msecs(jiffies -
-                                       ppsc->last_sleep_jiffies),
-                                       rtlpriv->psc.state_inap));
+                                        "awake, sleeped:%d ms state_inap:%x\n",
+                                        jiffies_to_msecs(jiffies -
+                                                         ppsc->
+                                                         last_sleep_jiffies),
+                                        rtlpriv->psc.state_inap);
                                ppsc->last_awake_jiffies = jiffies;
                                rtl_write_word(rtlpriv, CMDR, 0x37FC);
                                rtl_write_byte(rtlpriv, TXPAUSE, 0x00);
@@ -587,7 +587,7 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
        case ERFOFF:{
                        if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-                                        ("IPS Set eRf nic disable\n"));
+                                        "IPS Set eRf nic disable\n");
                                rtl_ps_disable_nic(hw);
                                RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
                        } else {
@@ -613,11 +613,9 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                        continue;
                                } else {
                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                                ("eRf Off/Sleep: "
-                                                "%d times TcbBusyQueue[%d] = "
-                                                "%d before doze!\n",
-                                                (i + 1), queue_id,
-                                                skb_queue_len(&ring->queue)));
+                                                "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n",
+                                                i + 1, queue_id,
+                                                skb_queue_len(&ring->queue));
 
                                        udelay(10);
                                        i++;
@@ -625,31 +623,30 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
 
                                if (i >= MAX_DOZE_WAITING_TIMES_9x) {
                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-                                                ("\nERFOFF: %d times"
-                                                "TcbBusyQueue[%d] = %d !\n",
+                                                "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
                                                 MAX_DOZE_WAITING_TIMES_9x,
                                                 queue_id,
-                                                skb_queue_len(&ring->queue)));
+                                                skb_queue_len(&ring->queue));
                                        break;
                                }
                        }
 
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-                                ("Set ERFSLEEP awaked:%d ms\n",
+                                "Set ERFSLEEP awaked:%d ms\n",
                                 jiffies_to_msecs(jiffies -
-                                ppsc->last_awake_jiffies)));
+                                                 ppsc->last_awake_jiffies));
 
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-                                ("sleep awaked:%d ms "
-                               "state_inap:%x\n", jiffies_to_msecs(jiffies -
-                               ppsc->last_awake_jiffies),
-                               rtlpriv->psc.state_inap));
+                                "sleep awaked:%d ms state_inap:%x\n",
+                                jiffies_to_msecs(jiffies -
+                                                 ppsc->last_awake_jiffies),
+                                rtlpriv->psc.state_inap);
                        ppsc->last_sleep_jiffies = jiffies;
                        _rtl92se_phy_set_rf_sleep(hw);
            break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("switch case not process\n"));
+                        "switch case not processed\n");
                bresult = false;
                break;
        }
@@ -681,30 +678,28 @@ static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       int index;
 
        if (reg_addr == RTXAGC_RATE18_06)
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
-                                                                        data;
-       if (reg_addr == RTXAGC_RATE54_24)
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
-                                                                        data;
-       if (reg_addr == RTXAGC_CCK_MCS32)
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
-                                                                        data;
-       if (reg_addr == RTXAGC_MCS03_MCS00)
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
-                                                                        data;
-       if (reg_addr == RTXAGC_MCS07_MCS04)
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
-                                                                        data;
-       if (reg_addr == RTXAGC_MCS11_MCS08)
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
-                                                                        data;
-       if (reg_addr == RTXAGC_MCS15_MCS12) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
-                                                                        data;
+               index = 0;
+       else if (reg_addr == RTXAGC_RATE54_24)
+               index = 1;
+       else if (reg_addr == RTXAGC_CCK_MCS32)
+               index = 6;
+       else if (reg_addr == RTXAGC_MCS03_MCS00)
+               index = 2;
+       else if (reg_addr == RTXAGC_MCS07_MCS04)
+               index = 3;
+       else if (reg_addr == RTXAGC_MCS11_MCS08)
+               index = 4;
+       else if (reg_addr == RTXAGC_MCS15_MCS12)
+               index = 5;
+       else
+               return;
+
+       rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data;
+       if (index == 5)
                rtlphy->pwrgroup_cnt++;
-       }
 }
 
 static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw)
@@ -995,7 +990,7 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
 
        if (rtstatus != true) {
                RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                        ("Write BB Reg Fail!!"));
+                        "Write BB Reg Fail!!\n");
                goto phy_BB8190_Config_ParaFile_Fail;
        }
 
@@ -1009,8 +1004,7 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
        }
        if (rtstatus != true) {
                RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                        ("_rtl92s_phy_bb_config_parafile(): "
-                        "BB_PG Reg Fail!!"));
+                        "_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n");
                goto phy_BB8190_Config_ParaFile_Fail;
        }
 
@@ -1053,7 +1047,7 @@ u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
                radio_b_tblen = RADIOB_ARRAYLENGTH;
        }
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
        rtstatus = true;
 
        switch (rfpath) {
@@ -1175,11 +1169,11 @@ bool rtl92s_phy_bb_config(struct ieee80211_hw *hw)
            (rtlphy->rf_type == RF_2T2R && rf_num != 2) ||
            (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) {
                RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                        ("RF_Type(%x) does not match "
-                        "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num));
+                        "RF_Type(%x) does not match RF_Num(%x)!!\n",
+                        rtlphy->rf_type, rf_num);
                RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                        ("path1 0x%x, path2 0x%x, pathmap "
-                         "0x%x\n", path1, path2, pathmap));
+                        "path1 0x%x, path2 0x%x, pathmap 0x%x\n",
+                        path1, path2, pathmap);
        }
 
        return rtstatus;
@@ -1214,20 +1208,20 @@ void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
                        ROFDM0_XCAGCCORE1, MASKBYTE0);
        rtlphy->default_initialgain[3] = rtl_get_bbreg(hw,
                        ROFDM0_XDAGCCORE1, MASKBYTE0);
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain "
-                "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
                 rtlphy->default_initialgain[0],
                 rtlphy->default_initialgain[1],
                 rtlphy->default_initialgain[2],
-                rtlphy->default_initialgain[3]));
+                rtlphy->default_initialgain[3]);
 
        /* read framesync */
        rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
        rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
                                              MASKDWORD);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-                ("Default framesync (0x%x) = 0x%x\n",
-                ROFDM0_RXDETECTOR3, rtlphy->framesync));
+                "Default framesync (0x%x) = 0x%x\n",
+                ROFDM0_RXDETECTOR3, rtlphy->framesync);
 
 }
 
@@ -1287,10 +1281,9 @@ void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8  channel)
                        &ofdmpowerLevel[0]);
 
        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                       ("Channel-%d, cckPowerLevel (A / B) = "
-                       "0x%x / 0x%x,   ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
-                       channel, cckpowerlevel[0], cckpowerlevel[1],
-                       ofdmpowerLevel[0], ofdmpowerLevel[1]));
+                "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
+                channel, cckpowerlevel[0], cckpowerlevel[1],
+                ofdmpowerLevel[0], ofdmpowerLevel[1]);
 
        _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0],
                        &ofdmpowerLevel[0]);
@@ -1316,7 +1309,7 @@ void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw)
        } while (--pollingcnt);
 
        if (pollingcnt == 0)
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Set FW Cmd fail!!\n");
 }
 
 
@@ -1345,20 +1338,17 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
 
        switch (rtlhal->current_fwcmd_io) {
        case FW_CMD_RA_RESET:
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-                        ("FW_CMD_RA_RESET\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n");
                rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
                rtl92s_phy_chk_fwcmd_iodone(hw);
                break;
        case FW_CMD_RA_ACTIVE:
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-                        ("FW_CMD_RA_ACTIVE\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n");
                rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
                rtl92s_phy_chk_fwcmd_iodone(hw);
                break;
        case FW_CMD_RA_REFRESH_N:
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-                        ("FW_CMD_RA_REFRESH_N\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n");
                input = FW_RA_REFRESH;
                rtl_write_dword(rtlpriv, WFM5, input);
                rtl92s_phy_chk_fwcmd_iodone(hw);
@@ -1367,7 +1357,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
                break;
        case FW_CMD_RA_REFRESH_BG:
                RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-                        ("FW_CMD_RA_REFRESH_BG\n"));
+                        "FW_CMD_RA_REFRESH_BG\n");
                rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
                rtl92s_phy_chk_fwcmd_iodone(hw);
                rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
@@ -1375,21 +1365,20 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
                break;
        case FW_CMD_RA_REFRESH_N_COMB:
                RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-                        ("FW_CMD_RA_REFRESH_N_COMB\n"));
+                        "FW_CMD_RA_REFRESH_N_COMB\n");
                input = FW_RA_IOT_N_COMB;
                rtl_write_dword(rtlpriv, WFM5, input);
                rtl92s_phy_chk_fwcmd_iodone(hw);
                break;
        case FW_CMD_RA_REFRESH_BG_COMB:
                RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-                        ("FW_CMD_RA_REFRESH_BG_COMB\n"));
+                        "FW_CMD_RA_REFRESH_BG_COMB\n");
                input = FW_RA_IOT_BG_COMB;
                rtl_write_dword(rtlpriv, WFM5, input);
                rtl92s_phy_chk_fwcmd_iodone(hw);
                break;
        case FW_CMD_IQK_ENABLE:
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-                        ("FW_CMD_IQK_ENABLE\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n");
                rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
                rtl92s_phy_chk_fwcmd_iodone(hw);
                break;
@@ -1424,8 +1413,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
                rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
                break;
        case FW_CMD_LPS_ENTER:
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-                        ("FW_CMD_LPS_ENTER\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n");
                current_aid = rtlpriv->mac80211.assoc_id;
                rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
                                ((current_aid | 0xc000) << 8)));
@@ -1434,20 +1422,18 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
                 * turbo mode until driver leave LPS */
                break;
        case FW_CMD_LPS_LEAVE:
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-                        ("FW_CMD_LPS_LEAVE\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n");
                rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
                rtl92s_phy_chk_fwcmd_iodone(hw);
                break;
        case FW_CMD_ADD_A2_ENTRY:
-               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-                        ("FW_CMD_ADD_A2_ENTRY\n"));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n");
                rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
                rtl92s_phy_chk_fwcmd_iodone(hw);
                break;
        case FW_CMD_CTRL_DM_BY_DRIVER:
                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                        ("FW_CMD_CTRL_DM_BY_DRIVER\n"));
+                        "FW_CMD_CTRL_DM_BY_DRIVER\n");
                rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
                rtl92s_phy_chk_fwcmd_iodone(hw);
                break;
@@ -1472,8 +1458,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
        bool bPostProcessing = false;
 
        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                       ("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
-                       fw_cmdio, rtlhal->set_fwcmd_inprogress));
+                "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
+                fw_cmdio, rtlhal->set_fwcmd_inprogress);
 
        do {
                /* We re-map to combined FW CMD ones if firmware version */
@@ -1501,7 +1487,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
                 * DM map table in the future. */
                switch (fw_cmdio) {
                case FW_CMD_RA_INIT:
-                       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n"));
+                       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n");
                        fw_cmdmap |= FW_RA_INIT_CTL;
                        FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
                        /* Clear control flag to sync with FW. */
@@ -1509,7 +1495,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
                        break;
                case FW_CMD_DIG_DISABLE:
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("Set DIG disable!!\n"));
+                                "Set DIG disable!!\n");
                        fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
                        FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
                        break;
@@ -1517,14 +1503,14 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
                case FW_CMD_DIG_RESUME:
                        if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
                                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                       ("Set DIG enable or resume!!\n"));
+                                        "Set DIG enable or resume!!\n");
                                fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
                                FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
                        }
                        break;
                case FW_CMD_DIG_HALT:
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("Set DIG halt!!\n"));
+                                "Set DIG halt!!\n");
                        fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
                        FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
                        break;
@@ -1540,9 +1526,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
                                     (rtlefuse->thermalmeter[0] << 16));
 
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("Set TxPwr tracking!! "
-                                "FwCmdMap(%#x), FwParam(%#x)\n",
-                                fw_cmdmap, fw_param));
+                                "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n",
+                                fw_cmdmap, fw_param);
 
                        FW_CMD_PARA_SET(rtlpriv, fw_param);
                        FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
@@ -1563,9 +1548,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
                        fw_param &= FW_RA_PARAM_CLR;
 
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("[FW CMD] [New Version] "
-                                "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), "
-                                "FwParam(%#x)\n", fw_cmdmap, fw_param));
+                                "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n",
+                                fw_cmdmap, fw_param);
 
                        FW_CMD_PARA_SET(rtlpriv, fw_param);
                        FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
@@ -1652,7 +1636,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
                        break;
                case FW_CMD_PAPE_CONTROL:
                        RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-                                ("[FW CMD] Set PAPE Control\n"));
+                                "[FW CMD] Set PAPE Control\n");
                        fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
 
                        FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
index 37e504af6446215a9cfe15a1ea7dc09b0bbdab12..ac0387770630dfedb9dc7d682b898d2d2e78690c 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 11f125c030ce0f923dab24d1b0a55dcfec64f2b2..84d1181795b8aeba6ff9d3d0d0245f75e596933f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 0ad50fe44aa288f3783f9d4b966ea4fbb08296ed..ad51906124db25195de7dd8b39716067f219bcd2 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include "../wifi.h"
 #include "reg.h"
 #include "def.h"
@@ -123,13 +121,13 @@ static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel,
        }
 
        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
-               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx "
-                       "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
-                       p_final_pwridx[1]));
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                        "40MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n",
+                        p_final_pwridx[0], p_final_pwridx[1]);
        } else {
-               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx "
-                       "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
-                        p_final_pwridx[1]));
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                        "20MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n",
+                        p_final_pwridx[0], p_final_pwridx[1]);
        }
 }
 
@@ -153,9 +151,8 @@ static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw,
                        ant_pwr_diff = -8;
 
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("Antenna Diff from RF-B "
-                       "to RF-A = %d (0x%x)\n", ant_pwr_diff,
-                        ant_pwr_diff & 0xf));
+                        "Antenna Diff from RF-B to RF-A = %d (0x%x)\n",
+                        ant_pwr_diff, ant_pwr_diff & 0xf);
 
                ant_pwr_diff &= 0xf;
        }
@@ -172,9 +169,8 @@ static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw,
        rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC),
                      u4reg_val);
 
-       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                ("Write BCD-Diff(0x%x) = 0x%x\n",
-                RFPGA0_TXGAINSTAGE, u4reg_val));
+       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Write BCD-Diff(0x%x) = 0x%x\n",
+                RFPGA0_TXGAINSTAGE, u4reg_val);
 }
 
 static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
@@ -201,8 +197,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
                                ((index < 2) ? pwrbase0 : pwrbase1);
 
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("RTK better performance, "
-                        "writeval = 0x%x\n", writeval));
+                        "RTK better performance, writeval = 0x%x\n", writeval);
                break;
        case 1:
                /* Realtek regulatory increase power diff defined
@@ -211,8 +206,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
                        writeval = ((index < 2) ? pwrbase0 : pwrbase1);
 
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("Realtek regulatory, "
-                                "40MHz, writeval = 0x%x\n", writeval));
+                                "Realtek regulatory, 40MHz, writeval = 0x%x\n",
+                                writeval);
                } else {
                        if (rtlphy->pwrgroup_cnt == 1)
                                chnlgroup = 0;
@@ -234,16 +229,15 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
                                        pwrbase0 : pwrbase1);
 
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                                ("Realtek regulatory, "
-                                "20MHz, writeval = 0x%x\n", writeval));
+                                "Realtek regulatory, 20MHz, writeval = 0x%x\n",
+                                writeval);
                }
                break;
        case 2:
                /* Better regulatory don't increase any power diff */
                writeval = ((index < 2) ? pwrbase0 : pwrbase1);
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("Better regulatory, "
-                        "writeval = 0x%x\n", writeval));
+                        "Better regulatory, writeval = 0x%x\n", writeval);
                break;
        case 3:
                /* Customer defined power diff. increase power diff
@@ -252,14 +246,14 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
 
                if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                               ("customer's limit, 40MHz = 0x%x\n",
-                               rtlefuse->pwrgroup_ht40
-                               [RF90_PATH_A][chnl - 1]));
+                                "customer's limit, 40MHz = 0x%x\n",
+                                rtlefuse->pwrgroup_ht40
+                                [RF90_PATH_A][chnl - 1]);
                } else {
                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                               ("customer's limit, 20MHz = 0x%x\n",
-                               rtlefuse->pwrgroup_ht20
-                               [RF90_PATH_A][chnl - 1]));
+                                "customer's limit, 20MHz = 0x%x\n",
+                                rtlefuse->pwrgroup_ht20
+                                [RF90_PATH_A][chnl - 1]);
                }
 
                for (i = 0; i < 4; i++) {
@@ -293,22 +287,19 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
                                (pwrdiff_limit[1] << 8) |
                                (pwrdiff_limit[0]);
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("Customer's limit = 0x%x\n",
-                        customer_limit));
+                        "Customer's limit = 0x%x\n", customer_limit);
 
                writeval = customer_limit + ((index < 2) ?
                                             pwrbase0 : pwrbase1);
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("Customer, writeval = "
-                        "0x%x\n", writeval));
+                        "Customer, writeval = 0x%x\n", writeval);
                break;
        default:
                chnlgroup = 0;
                writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] +
                                ((index < 2) ? pwrbase0 : pwrbase1);
                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-                        ("RTK better performance, "
-                        "writeval = 0x%x\n", writeval));
+                        "RTK better performance, writeval = 0x%x\n", writeval);
                break;
        }
 
@@ -541,8 +532,7 @@ void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("unknown bandwidth: %#X\n",
-                        bandwidth));
+                        "unknown bandwidth: %#X\n", bandwidth);
                break;
        }
 }
index 3843baa1a87411213385d43a43504718f21b290d..8a29eb94ab174dbfef5a2cac60c1f61f2a206437 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 78723cf59491264706b636be638d68eb5585818f..345d752137fa00e5725415a54b39e444a35acf4c 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-
 #include "../wifi.h"
 #include "../core.h"
 #include "../pci.h"
+#include "../base.h"
+#include "../pci.h"
 #include "reg.h"
 #include "def.h"
 #include "phy.h"
@@ -45,6 +42,8 @@
 #include "trx.h"
 #include "led.h"
 
+#include <linux/module.h>
+
 static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
 {
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -89,12 +88,54 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
        rtlpci->const_support_pciaspm = 2;
 }
 
+static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
+{
+       struct ieee80211_hw *hw = context;
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+       struct rt_firmware *pfirmware = NULL;
+       int err;
+
+       RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+                        "Firmware callback routine entered!\n");
+       complete(&rtlpriv->firmware_loading_complete);
+       if (!firmware) {
+               pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
+               rtlpriv->max_fw_size = 0;
+               return;
+       }
+       if (firmware->size > rtlpriv->max_fw_size) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        "Firmware is too big!\n");
+               rtlpriv->max_fw_size = 0;
+               release_firmware(firmware);
+               return;
+       }
+       pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
+       memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
+       pfirmware->sz_fw_tmpbufferlen = firmware->size;
+       release_firmware(firmware);
+
+       err = ieee80211_register_hw(hw);
+       if (err) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        "Can't register mac80211 hw\n");
+               return;
+       } else {
+               rtlpriv->mac80211.mac80211_registered = 1;
+       }
+       rtlpci->irq_alloc = 1;
+       set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+
+       /*init rfkill */
+       rtl_init_rfkill(hw);
+}
+
 static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       const struct firmware *firmware;
-       struct rt_firmware *pfirmware = NULL;
        int err = 0;
        u16 earlyrxthreshold = 7;
 
@@ -168,9 +209,9 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
        rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
        if (!rtlpriv->psc.inactiveps)
-               pr_info("rtl8192ce: Power Save off (module option)\n");
+               pr_info("Power Save off (module option)\n");
        if (!rtlpriv->psc.fwctrl_lps)
-               pr_info("rtl8192ce: FW Power Save off (module option)\n");
+               pr_info("FW Power Save off (module option)\n");
        rtlpriv->psc.reg_fwctrl_lps = 3;
        rtlpriv->psc.reg_max_lps_awakeintvl = 5;
        /* for ASPM, you can close aspm through
@@ -188,31 +229,23 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware));
        if (!rtlpriv->rtlhal.pfirmware) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't alloc buffer for fw.\n"));
+                        "Can't alloc buffer for fw\n");
                return 1;
        }
 
+       rtlpriv->max_fw_size = RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE;
+
        pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n"
                "Loading firmware %s\n", rtlpriv->cfg->fw_name);
        /* request fw */
-       err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
-                       rtlpriv->io.dev);
+       err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
+                                     rtlpriv->io.dev, GFP_KERNEL, hw,
+                                     rtl92se_fw_cb);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Failed to request firmware!\n"));
+                        "Failed to request firmware!\n");
                return 1;
        }
-       if (firmware->size > sizeof(struct rt_firmware)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Firmware is too big!\n"));
-               release_firmware(firmware);
-               return 1;
-       }
-
-       pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
-       memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
-       pfirmware->sz_fw_tmpbufferlen = firmware->size;
-       release_firmware(firmware);
 
        return err;
 }
@@ -426,7 +459,7 @@ static int __init rtl92se_module_init(void)
 
        ret = pci_register_driver(&rtl92se_driver);
        if (ret)
-               RT_ASSERT(false, (": No device found\n"));
+               RT_ASSERT(false, "No device found\n");
 
        return ret;
 }
index fc4eb285a0acad21204676126974e6e41fc78574..2eb88862ebe462e701ea4c33ccad756e7be190b8 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 154185b3969d3bbeabea010ac270086fd04a0f96..f1a73f75127eb0dc76086976a9357faf02636412 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index b4ed6d951ebb3de99387be537d5f41770d311f31..2feb73b71a4f6d1e560c7a06a487839dcd1ae6a9 100644 (file)
@@ -1,5 +1,5 @@
 /******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Realtek Corporation. All rights reserved.
  *
  * This program is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
index fbebe3ea0a22b95cedd432b0ca663d871915112c..2fd3d13b7ced311fd1607f5c4bc437cdc98029f5 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -756,7 +756,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
        /* DOWRD 8 */
        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
 
-       RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+       RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 }
 
 void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
@@ -823,8 +823,8 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
                        SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR txdesc :%d not process\n",
-                                 desc_name));
+                       RT_ASSERT(false, "ERR txdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        } else {
@@ -843,8 +843,8 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
                        SET_RX_STATUS_DESC_EOR(pdesc, 1);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
-                                 desc_name));
+                       RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        }
@@ -863,8 +863,8 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
                        ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR txdesc :%d not process\n",
-                                 desc_name));
+                       RT_ASSERT(false, "ERR txdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        } else {
@@ -876,8 +876,8 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
                        ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
                        break;
                default:
-                       RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
-                                 desc_name));
+                       RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+                                 desc_name);
                        break;
                }
        }
index 05862c51b861a1ce4be8f8a48d1030b927a41bec..011e7b0695f24f0a00bdd322a82e961cb69faa28 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index e956fa71d040756952868e423d497b8a329aff2b..2e1e352864bb88ad33489402aee1f19ef2aa4154 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2011  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/usb.h>
-#include <linux/export.h>
-#include "core.h"
 #include "wifi.h"
+#include "core.h"
 #include "usb.h"
 #include "base.h"
 #include "ps.h"
 #include "rtl8192c/fw_common.h"
+#include <linux/export.h>
 
 #define        REALTEK_USB_VENQT_READ                  0xC0
 #define        REALTEK_USB_VENQT_WRITE                 0x40
@@ -276,14 +273,14 @@ static int _rtl_usb_init_tx(struct ieee80211_hw *hw)
                                                    ? USB_HIGH_SPEED_BULK_SIZE
                                                    : USB_FULL_SPEED_BULK_SIZE;
 
-       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("USB Max Bulk-out Size=%d\n",
-                rtlusb->max_bulk_out_size));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n",
+                rtlusb->max_bulk_out_size);
 
        for (i = 0; i < __RTL_TXQ_NUM; i++) {
                u32 ep_num = rtlusb->ep_map.ep_mapping[i];
                if (!ep_num) {
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                                ("Invalid endpoint map setting!\n"));
+                                "Invalid endpoint map setting!\n");
                        return -EINVAL;
                }
        }
@@ -345,13 +342,18 @@ static int _rtl_usb_init(struct ieee80211_hw *hw)
                        rtlusb->out_ep_nums++;
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                        ("USB EP(0x%02x), MaxPacketSize=%d ,Interval=%d.\n",
+                        "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n",
                         pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize,
-                        pep_desc->bInterval));
+                        pep_desc->bInterval);
+       }
+       if (rtlusb->in_ep_nums <  rtlpriv->cfg->usb_interface_cfg->in_ep_num) {
+               pr_err("Too few input end points found\n");
+               return -EINVAL;
+       }
+       if (rtlusb->out_ep_nums == 0) {
+               pr_err("No output end points found\n");
+               return -EINVAL;
        }
-       if (rtlusb->in_ep_nums <  rtlpriv->cfg->usb_interface_cfg->in_ep_num)
-               return -EINVAL ;
-
        /* usb endpoint mapping */
        err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw);
        rtlusb->usb_mq_to_hwq =  rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq;
@@ -360,7 +362,7 @@ static int _rtl_usb_init(struct ieee80211_hw *hw)
        return err;
 }
 
-static int _rtl_usb_init_sw(struct ieee80211_hw *hw)
+static void rtl_usb_init_sw(struct ieee80211_hw *hw)
 {
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@@ -395,7 +397,6 @@ static int _rtl_usb_init_sw(struct ieee80211_hw *hw)
        /* HIMR_EX - turn all on */
        rtlusb->irq_mask[1] = 0xFFFFFFFF;
        rtlusb->disableHWSM =  true;
-       return 0;
 }
 
 #define __RADIO_TAP_SIZE_RSV   32
@@ -414,7 +415,7 @@ static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw,
                               gfp_mask);
        if (!skb) {
                RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-                        ("Failed to __dev_alloc_skb!!\n"))
+                        "Failed to __dev_alloc_skb!!\n");
                return ERR_PTR(-ENOMEM);
        }
 
@@ -520,12 +521,14 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,
                        u8 *pdata;
 
                        uskb = dev_alloc_skb(skb->len + 128);
-                       memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
-                              sizeof(rx_status));
-                       pdata = (u8 *)skb_put(uskb, skb->len);
-                       memcpy(pdata, skb->data, skb->len);
+                       if (uskb) {     /* drop packet on allocation failure */
+                               memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
+                                      sizeof(rx_status));
+                               pdata = (u8 *)skb_put(uskb, skb->len);
+                               memcpy(pdata, skb->data, skb->len);
+                               ieee80211_rx_irqsafe(hw, uskb);
+                       }
                        dev_kfree_skb_any(skb);
-                       ieee80211_rx_irqsafe(hw, uskb);
                } else {
                        dev_kfree_skb_any(skb);
                }
@@ -575,7 +578,7 @@ static void _rtl_rx_completed(struct urb *_urb)
                        if (IS_ERR(_skb)) {
                                err = PTR_ERR(_skb);
                                RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-                                       ("Can't allocate skb for bulk IN!\n"));
+                                        "Can't allocate skb for bulk IN!\n");
                                return;
                        }
                        skb = _skb;
@@ -632,14 +635,14 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw)
                urb = usb_alloc_urb(0, GFP_KERNEL);
                if (!urb) {
                        RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-                                ("Failed to alloc URB!!\n"))
+                                "Failed to alloc URB!!\n");
                        goto err_out;
                }
 
                skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL);
                if (IS_ERR(skb)) {
                        RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-                                ("Failed to prep_rx_urb!!\n"))
+                                "Failed to prep_rx_urb!!\n");
                        err = PTR_ERR(skb);
                        goto err_out;
                }
@@ -665,15 +668,17 @@ static int rtl_usb_start(struct ieee80211_hw *hw)
        struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
 
        err = rtlpriv->cfg->ops->hw_init(hw);
-       rtl_init_rx_config(hw);
+       if (!err) {
+               rtl_init_rx_config(hw);
 
-       /* Enable software */
-       SET_USB_START(rtlusb);
-       /* should after adapter start and interrupt enable. */
-       set_hal_start(rtlhal);
+               /* Enable software */
+               SET_USB_START(rtlusb);
+               /* should after adapter start and interrupt enable. */
+               set_hal_start(rtlhal);
 
-       /* Start bulk IN */
-       _rtl_usb_receive(hw);
+               /* Start bulk IN */
+               _rtl_usb_receive(hw);
+       }
 
        return err;
 }
@@ -745,7 +750,7 @@ static void _rtl_submit_tx_urb(struct ieee80211_hw *hw, struct urb *_urb)
                struct sk_buff *skb;
 
                RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-                        ("Failed to submit urb.\n"));
+                        "Failed to submit urb\n");
                usb_unanchor_urb(_urb);
                skb = (struct sk_buff *)_urb->context;
                kfree_skb(skb);
@@ -768,7 +773,7 @@ static int _usb_tx_post(struct ieee80211_hw *hw, struct urb *urb,
 
        if (urb->status) {
                RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-                        ("Urb has error status 0x%X\n", urb->status));
+                        "Urb has error status 0x%X\n", urb->status);
                goto out;
        }
        /*  TODO:       statistics */
@@ -805,7 +810,7 @@ static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw,
        _urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!_urb) {
                RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-                        ("Can't allocate URB for bulk out!\n"));
+                        "Can't allocate URB for bulk out!\n");
                kfree_skb(skb);
                return NULL;
        }
@@ -830,7 +835,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
        WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl);
        if (unlikely(IS_USB_STOP(rtlusb))) {
                RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-                        ("USB device is stopping...\n"));
+                        "USB device is stopping...\n");
                kfree_skb(skb);
                return;
        }
@@ -840,7 +845,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
        _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num);
        if (unlikely(!_urb)) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't allocate urb. Drop skb!\n"));
+                        "Can't allocate urb. Drop skb!\n");
                return;
        }
        urb_list = &rtlusb->tx_pending[ep_num];
@@ -865,7 +870,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,
 
        memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
        if (ieee80211_is_auth(fc)) {
-               RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
                rtl_ips_nic_on(hw);
        }
 
@@ -946,10 +951,11 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
        hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) +
                                sizeof(struct rtl_usb_priv), &rtl_ops);
        if (!hw) {
-               RT_ASSERT(false, ("%s : ieee80211 alloc failed\n", __func__));
+               RT_ASSERT(false, "ieee80211 alloc failed\n");
                return -ENOMEM;
        }
        rtlpriv = hw->priv;
+       init_completion(&rtlpriv->firmware_loading_complete);
        SET_IEEE80211_DEV(hw, &intf->dev);
        udev = interface_to_usbdev(intf);
        usb_get_dev(udev);
@@ -969,39 +975,28 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
        /*like read eeprom and so on */
        rtlpriv->cfg->ops->read_eeprom_info(hw);
        if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't init_sw_vars.\n"));
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
                goto error_out;
        }
        rtlpriv->cfg->ops->init_sw_leds(hw);
        err = _rtl_usb_init(hw);
-       err = _rtl_usb_init_sw(hw);
+       if (err)
+               goto error_out;
+       rtl_usb_init_sw(hw);
        /* Init mac80211 sw */
        err = rtl_init_core(hw);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't allocate sw for mac80211.\n"));
+                        "Can't allocate sw for mac80211\n");
                goto error_out;
        }
 
-       /*init rfkill */
-       /* rtl_init_rfkill(hw); */
-
-       err = ieee80211_register_hw(hw);
-       if (err) {
-               RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-                        ("Can't register mac80211 hw.\n"));
-               goto error_out;
-       } else {
-               rtlpriv->mac80211.mac80211_registered = 1;
-       }
-       set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
        return 0;
 error_out:
        rtl_deinit_core(hw);
        _rtl_usb_io_handler_release(hw);
-       ieee80211_free_hw(hw);
        usb_put_dev(udev);
+       complete(&rtlpriv->firmware_loading_complete);
        return -ENODEV;
 }
 EXPORT_SYMBOL(rtl_usb_probe);
@@ -1015,6 +1010,9 @@ void rtl_usb_disconnect(struct usb_interface *intf)
 
        if (unlikely(!rtlpriv))
                return;
+
+       /* just in case driver is removed before firmware callback */
+       wait_for_completion(&rtlpriv->firmware_loading_complete);
        /*ieee80211_unregister_hw will call ops_stop */
        if (rtlmac->mac80211_registered == 1) {
                ieee80211_unregister_hw(hw);
index d2a63fb3e1e60ca61598dfdf73aea13b4da3f002..43846b329153195fbe123b884d84e365483aa97e 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2011  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -28,7 +28,6 @@
 #ifndef __RTL_USB_H__
 #define __RTL_USB_H__
 
-#include <linux/usb.h>
 #include <linux/skbuff.h>
 
 #define RTL_RX_DESC_SIZE               24
index cdaf1429fa0b30b6322f31d21f48f5216e51f7d3..b591614c3b9bb79c7b6e00ec6fe48cb8b06c480b 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
 #ifndef __RTL_WIFI_H__
 #define __RTL_WIFI_H__
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/usb.h>
 #include <net/mac80211.h>
+#include <linux/completion.h>
 #include "debug.h"
 
 #define RF_CHANGE_BY_INIT                      0
@@ -1045,7 +1048,6 @@ struct rtl_hal {
        u16 fw_subversion;
        bool h2c_setinprogress;
        u8 last_hmeboxnum;
-       bool fw_ready;
        /*Reserve page start offset except beacon in TxQ. */
        u8 fw_rsvdpage_startoffset;
        u8 h2c_txcmd_seq;
@@ -1591,6 +1593,7 @@ struct rtl_debug {
 };
 
 struct rtl_priv {
+       struct completion firmware_loading_complete;
        struct rtl_locks locks;
        struct rtl_works works;
        struct rtl_mac mac80211;
@@ -1612,6 +1615,7 @@ struct rtl_priv {
        struct rtl_rate_priv *rate_priv;
 
        struct rtl_debug dbg;
+       int max_fw_size;
 
        /*
         *hal_cfg : for diff cards
index 58b4f935a3f634f89157e32389e90cbf29898310..a5c6328b5f725bd3e92e8292df48328f219b08f2 100644 (file)
@@ -6,3 +6,5 @@ wl1251_sdio-objs        += sdio.o
 obj-$(CONFIG_WL1251)           += wl1251.o
 obj-$(CONFIG_WL1251_SPI)       += wl1251_spi.o
 obj-$(CONFIG_WL1251_SDIO)      += wl1251_sdio.o
+
+ccflags-y += -D__CHECK_ENDIAN__
index d729daf8e8411f9de8ccdb388af37346e1a9a4da..a2e5241382da3ddab3fd71920863a9cca12ea4d3 100644 (file)
@@ -464,8 +464,6 @@ static int wl1251_boot_upload_nvs(struct wl1251 *wl)
                val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
                       | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
 
-               val = cpu_to_le32(val);
-
                wl1251_debug(DEBUG_BOOT,
                             "nvs write table 0x%x: 0x%x",
                             nvs_start, val);
index c545e9d5f512a34f2cc8a61e847f829dc74d73bc..d382877c34cc179c35cb7b0f65a8efa42c2ed341 100644 (file)
 
 static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
 {
-       u32 response;
-
-       wl->if_ops->read(wl, addr, &response, sizeof(u32));
+       wl->if_ops->read(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32));
 
-       return response;
+       return le32_to_cpu(wl->buffer_32);
 }
 
 static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
 {
-       wl->if_ops->write(wl, addr, &val, sizeof(u32));
+       wl->buffer_32 = cpu_to_le32(val);
+       wl->if_ops->write(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32));
 }
 
 static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr)
index ba3268ea81fe57563c9f0f95a293773c21f68ffe..41302c7b1ad0089480a495a26dac4da2552eecf2 100644 (file)
@@ -514,6 +514,9 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw,
        struct wl1251 *wl = hw->priv;
        int ret = 0;
 
+       vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
+                            IEEE80211_VIF_SUPPORTS_CQM_RSSI;
+
        wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
                     vif->type, vif->addr);
 
@@ -1338,9 +1341,7 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
 
        wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
                IEEE80211_HW_SUPPORTS_PS |
-               IEEE80211_HW_BEACON_FILTER |
-               IEEE80211_HW_SUPPORTS_UAPSD |
-               IEEE80211_HW_SUPPORTS_CQM_RSSI;
+               IEEE80211_HW_SUPPORTS_UAPSD;
 
        wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
                                         BIT(NL80211_IFTYPE_ADHOC);
index a77f1bbbed0ad063aae085ff857c4cc7abadd717..9d8f5816c6f91628d609ecd0090c438133c5b115 100644 (file)
@@ -380,7 +380,7 @@ struct wl1251 {
        struct wl1251_stats stats;
        struct wl1251_debugfs debugfs;
 
-       u32 buffer_32;
+       __le32 buffer_32;
        u32 buffer_cmd;
        u8 buffer_busyword[WL1251_BUSY_WORD_LEN];
        struct wl1251_rx_descriptor *rx_descriptor;
index fe67262ba19f7997b16c37b9a42395c25890e6ec..98f289c907a97db3f1ef619d391545478af0a7cb 100644 (file)
@@ -11,3 +11,5 @@ obj-$(CONFIG_WL12XX_SDIO)             += wl12xx_sdio.o
 
 # small builtin driver bit
 obj-$(CONFIG_WL12XX_PLATFORM_DATA)     += wl12xx_platform_data.o
+
+ccflags-y += -D__CHECK_ENDIAN__
index 7537c401a4487174a0d50680b1d84e68c3e16675..bc96db0683a5ce99d9fe58d3480813a529675e1a 100644 (file)
 #include "reg.h"
 #include "ps.h"
 
-int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif)
+int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                                 u8 wake_up_event, u8 listen_interval)
 {
        struct acx_wake_up_condition *wake_up;
        int ret;
 
-       wl1271_debug(DEBUG_ACX, "acx wake up conditions");
+       wl1271_debug(DEBUG_ACX, "acx wake up conditions (wake_up_event %d listen_interval %d)",
+                    wake_up_event, listen_interval);
 
        wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
        if (!wake_up) {
@@ -48,8 +50,8 @@ int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif)
        }
 
        wake_up->role_id = wlvif->role_id;
-       wake_up->wake_up_event = wl->conf.conn.wake_up_event;
-       wake_up->listen_interval = wl->conf.conn.listen_interval;
+       wake_up->wake_up_event = wake_up_event;
+       wake_up->listen_interval = listen_interval;
 
        ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
                                   wake_up, sizeof(*wake_up));
@@ -1459,9 +1461,10 @@ out:
        return ret;
 }
 
-int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
+int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                       u64 *mactime)
 {
-       struct wl1271_acx_fw_tsf_information *tsf_info;
+       struct wl12xx_acx_fw_tsf_information *tsf_info;
        int ret;
 
        tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
@@ -1470,6 +1473,8 @@ int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
                goto out;
        }
 
+       tsf_info->role_id = wlvif->role_id;
+
        ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO,
                                     tsf_info, sizeof(*tsf_info));
        if (ret < 0) {
index 69892b40c2dfc850cd44b434a155c5ce81da4c6c..a28fc044034c8e194a4e8bf82649a88a6231d4d0 100644 (file)
@@ -995,15 +995,17 @@ struct wl1271_acx_ba_receiver_setup {
        u8 padding[2];
 } __packed;
 
-struct wl1271_acx_fw_tsf_information {
+struct wl12xx_acx_fw_tsf_information {
        struct acx_header header;
 
+       u8 role_id;
+       u8 padding1[3];
        __le32 current_tsf_high;
        __le32 current_tsf_low;
        __le32 last_bttt_high;
        __le32 last_tbtt_low;
        u8 last_dtim_count;
-       u8 padding[3];
+       u8 padding2[3];
 } __packed;
 
 struct wl1271_acx_ps_rx_streaming {
@@ -1151,79 +1153,81 @@ struct wl12xx_acx_config_hangover {
 } __packed;
 
 enum {
-       ACX_WAKE_UP_CONDITIONS      = 0x0002,
-       ACX_MEM_CFG                 = 0x0003,
-       ACX_SLOT                    = 0x0004,
-       ACX_AC_CFG                  = 0x0007,
-       ACX_MEM_MAP                 = 0x0008,
-       ACX_AID                     = 0x000A,
-       ACX_MEDIUM_USAGE            = 0x000F,
-       ACX_TX_QUEUE_CFG            = 0x0011, /* FIXME: only used by wl1251 */
-       ACX_STATISTICS              = 0x0013, /* Debug API */
-       ACX_PWR_CONSUMPTION_STATISTICS = 0x0014,
-       ACX_FEATURE_CFG             = 0x0015,
-       ACX_TID_CFG                 = 0x001A,
-       ACX_PS_RX_STREAMING         = 0x001B,
-       ACX_BEACON_FILTER_OPT       = 0x001F,
-       ACX_NOISE_HIST              = 0x0021,
-       ACX_HDK_VERSION             = 0x0022, /* ??? */
-       ACX_PD_THRESHOLD            = 0x0023,
-       ACX_TX_CONFIG_OPT           = 0x0024,
-       ACX_CCA_THRESHOLD           = 0x0025,
-       ACX_EVENT_MBOX_MASK         = 0x0026,
-       ACX_CONN_MONIT_PARAMS       = 0x002D,
-       ACX_BCN_DTIM_OPTIONS        = 0x0031,
-       ACX_SG_ENABLE               = 0x0032,
-       ACX_SG_CFG                  = 0x0033,
-       ACX_FM_COEX_CFG             = 0x0034,
-       ACX_BEACON_FILTER_TABLE     = 0x0038,
-       ACX_ARP_IP_FILTER           = 0x0039,
-       ACX_ROAMING_STATISTICS_TBL  = 0x003B,
-       ACX_RATE_POLICY             = 0x003D,
-       ACX_CTS_PROTECTION          = 0x003E,
-       ACX_SLEEP_AUTH              = 0x003F,
-       ACX_PREAMBLE_TYPE           = 0x0040,
-       ACX_ERROR_CNT               = 0x0041,
-       ACX_IBSS_FILTER             = 0x0044,
-       ACX_SERVICE_PERIOD_TIMEOUT  = 0x0045,
-       ACX_TSF_INFO                = 0x0046,
-       ACX_CONFIG_PS_WMM           = 0x0049,
-       ACX_ENABLE_RX_DATA_FILTER   = 0x004A,
-       ACX_SET_RX_DATA_FILTER      = 0x004B,
-       ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
-       ACX_RX_CONFIG_OPT           = 0x004E,
-       ACX_FRAG_CFG                = 0x004F,
-       ACX_BET_ENABLE              = 0x0050,
-       ACX_RSSI_SNR_TRIGGER        = 0x0051,
-       ACX_RSSI_SNR_WEIGHTS        = 0x0052,
-       ACX_KEEP_ALIVE_MODE         = 0x0053,
-       ACX_SET_KEEP_ALIVE_CONFIG   = 0x0054,
-       ACX_BA_SESSION_INIT_POLICY  = 0x0055,
-       ACX_BA_SESSION_RX_SETUP     = 0x0056,
-       ACX_PEER_HT_CAP             = 0x0057,
-       ACX_HT_BSS_OPERATION        = 0x0058,
-       ACX_COEX_ACTIVITY           = 0x0059,
-       ACX_BURST_MODE              = 0x005C,
-       ACX_SET_RATE_MGMT_PARAMS    = 0x005D,
-       ACX_SET_RATE_ADAPT_PARAMS   = 0x0060,
-       ACX_SET_DCO_ITRIM_PARAMS    = 0x0061,
-       ACX_GEN_FW_CMD              = 0x0070,
-       ACX_HOST_IF_CFG_BITMAP      = 0x0071,
-       ACX_MAX_TX_FAILURE          = 0x0072,
-       ACX_UPDATE_INCONNECTION_STA_LIST = 0x0073,
-       DOT11_RX_MSDU_LIFE_TIME     = 0x1004,
-       DOT11_CUR_TX_PWR            = 0x100D,
-       DOT11_RX_DOT11_MODE         = 0x1012,
-       DOT11_RTS_THRESHOLD         = 0x1013,
-       DOT11_GROUP_ADDRESS_TBL     = 0x1014,
-       ACX_PM_CONFIG               = 0x1016,
-       ACX_CONFIG_PS               = 0x1017,
-       ACX_CONFIG_HANGOVER         = 0x1018,
+       ACX_WAKE_UP_CONDITIONS           = 0x0000,
+       ACX_MEM_CFG                      = 0x0001,
+       ACX_SLOT                         = 0x0002,
+       ACX_AC_CFG                       = 0x0003,
+       ACX_MEM_MAP                      = 0x0004,
+       ACX_AID                          = 0x0005,
+       ACX_MEDIUM_USAGE                 = 0x0006,
+       ACX_STATISTICS                   = 0x0007,
+       ACX_PWR_CONSUMPTION_STATISTICS   = 0x0008,
+       ACX_TID_CFG                      = 0x0009,
+       ACX_PS_RX_STREAMING              = 0x000A,
+       ACX_BEACON_FILTER_OPT            = 0x000B,
+       ACX_NOISE_HIST                   = 0x000C,
+       ACX_HDK_VERSION                  = 0x000D,
+       ACX_PD_THRESHOLD                 = 0x000E,
+       ACX_TX_CONFIG_OPT                = 0x000F,
+       ACX_CCA_THRESHOLD                = 0x0010,
+       ACX_EVENT_MBOX_MASK              = 0x0011,
+       ACX_CONN_MONIT_PARAMS            = 0x0012,
+       ACX_DISABLE_BROADCASTS           = 0x0013,
+       ACX_BCN_DTIM_OPTIONS             = 0x0014,
+       ACX_SG_ENABLE                    = 0x0015,
+       ACX_SG_CFG                       = 0x0016,
+       ACX_FM_COEX_CFG                  = 0x0017,
+       ACX_BEACON_FILTER_TABLE          = 0x0018,
+       ACX_ARP_IP_FILTER                = 0x0019,
+       ACX_ROAMING_STATISTICS_TBL       = 0x001A,
+       ACX_RATE_POLICY                  = 0x001B,
+       ACX_CTS_PROTECTION               = 0x001C,
+       ACX_SLEEP_AUTH                   = 0x001D,
+       ACX_PREAMBLE_TYPE                = 0x001E,
+       ACX_ERROR_CNT                    = 0x001F,
+       ACX_IBSS_FILTER                  = 0x0020,
+       ACX_SERVICE_PERIOD_TIMEOUT       = 0x0021,
+       ACX_TSF_INFO                     = 0x0022,
+       ACX_CONFIG_PS_WMM                = 0x0023,
+       ACX_ENABLE_RX_DATA_FILTER        = 0x0024,
+       ACX_SET_RX_DATA_FILTER           = 0x0025,
+       ACX_GET_DATA_FILTER_STATISTICS   = 0x0026,
+       ACX_RX_CONFIG_OPT                = 0x0027,
+       ACX_FRAG_CFG                     = 0x0028,
+       ACX_BET_ENABLE                   = 0x0029,
+       ACX_RSSI_SNR_TRIGGER             = 0x002A,
+       ACX_RSSI_SNR_WEIGHTS             = 0x002B,
+       ACX_KEEP_ALIVE_MODE              = 0x002C,
+       ACX_SET_KEEP_ALIVE_CONFIG        = 0x002D,
+       ACX_BA_SESSION_INIT_POLICY       = 0x002E,
+       ACX_BA_SESSION_RX_SETUP          = 0x002F,
+       ACX_PEER_HT_CAP                  = 0x0030,
+       ACX_HT_BSS_OPERATION             = 0x0031,
+       ACX_COEX_ACTIVITY                = 0x0032,
+       ACX_BURST_MODE                   = 0x0033,
+       ACX_SET_RATE_MGMT_PARAMS         = 0x0034,
+       ACX_GET_RATE_MGMT_PARAMS         = 0x0035,
+       ACX_SET_RATE_ADAPT_PARAMS        = 0x0036,
+       ACX_SET_DCO_ITRIM_PARAMS         = 0x0037,
+       ACX_GEN_FW_CMD                   = 0x0038,
+       ACX_HOST_IF_CFG_BITMAP           = 0x0039,
+       ACX_MAX_TX_FAILURE               = 0x003A,
+       ACX_UPDATE_INCONNECTION_STA_LIST = 0x003B,
+       DOT11_RX_MSDU_LIFE_TIME          = 0x003C,
+       DOT11_CUR_TX_PWR                 = 0x003D,
+       DOT11_RTS_THRESHOLD              = 0x003E,
+       DOT11_GROUP_ADDRESS_TBL          = 0x003F,
+       ACX_PM_CONFIG                    = 0x0040,
+       ACX_CONFIG_PS                    = 0x0041,
+       ACX_CONFIG_HANGOVER              = 0x0042,
+       ACX_FEATURE_CFG                  = 0x0043,
+       ACX_PROTECTION_CFG               = 0x0044,
 };
 
 
 int wl1271_acx_wake_up_conditions(struct wl1271 *wl,
-                                 struct wl12xx_vif *wlvif);
+                                 struct wl12xx_vif *wlvif,
+                                 u8 wake_up_event, u8 listen_interval);
 int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
 int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                        int power);
@@ -1296,7 +1300,8 @@ int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl,
                                       struct wl12xx_vif *wlvif);
 int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
                                       u16 ssn, bool enable, u8 peer_hlid);
-int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
+int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                       u64 *mactime);
 int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                               bool enable);
 int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif);
index 8f9cf5a816ea494601acb5cd4c55112530cd02f2..954101d03f068300e4ed731a8f8cbfa420af166d 100644 (file)
 #include "event.h"
 #include "rx.h"
 
-static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
-       [PART_DOWN] = {
-               .mem = {
-                       .start = 0x00000000,
-                       .size  = 0x000177c0
-               },
-               .reg = {
-                       .start = REGISTERS_BASE,
-                       .size  = 0x00008800
-               },
-               .mem2 = {
-                       .start = 0x00000000,
-                       .size  = 0x00000000
-               },
-               .mem3 = {
-                       .start = 0x00000000,
-                       .size  = 0x00000000
-               },
-       },
-
-       [PART_WORK] = {
-               .mem = {
-                       .start = 0x00040000,
-                       .size  = 0x00014fc0
-               },
-               .reg = {
-                       .start = REGISTERS_BASE,
-                       .size  = 0x0000a000
-               },
-               .mem2 = {
-                       .start = 0x003004f8,
-                       .size  = 0x00000004
-               },
-               .mem3 = {
-                       .start = 0x00040404,
-                       .size  = 0x00000000
-               },
-       },
-
-       [PART_DRPW] = {
-               .mem = {
-                       .start = 0x00040000,
-                       .size  = 0x00014fc0
-               },
-               .reg = {
-                       .start = DRPW_BASE,
-                       .size  = 0x00006000
-               },
-               .mem2 = {
-                       .start = 0x00000000,
-                       .size  = 0x00000000
-               },
-               .mem3 = {
-                       .start = 0x00000000,
-                       .size  = 0x00000000
-               }
-       }
-};
-
 static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
 {
        u32 cpu_ctrl;
@@ -181,13 +122,13 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
                return -ENOMEM;
        }
 
-       memcpy(&partition, &part_table[PART_DOWN], sizeof(partition));
+       memcpy(&partition, &wl12xx_part_table[PART_DOWN], sizeof(partition));
        partition.mem.start = dest;
        wl1271_set_partition(wl, &partition);
 
        /* 10.1 set partition limit and chunk num */
        chunk_num = 0;
-       partition_limit = part_table[PART_DOWN].mem.size;
+       partition_limit = wl12xx_part_table[PART_DOWN].mem.size;
 
        while (chunk_num < fw_data_len / CHUNK_SIZE) {
                /* 10.2 update partition, if needed */
@@ -195,7 +136,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
                if (addr > partition_limit) {
                        addr = dest + chunk_num * CHUNK_SIZE;
                        partition_limit = chunk_num * CHUNK_SIZE +
-                               part_table[PART_DOWN].mem.size;
+                               wl12xx_part_table[PART_DOWN].mem.size;
                        partition.mem.start = addr;
                        wl1271_set_partition(wl, &partition);
                }
@@ -317,12 +258,12 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
        }
 
        /* update current MAC address to NVS */
-       nvs_ptr[11] = wl->mac_addr[0];
-       nvs_ptr[10] = wl->mac_addr[1];
-       nvs_ptr[6] = wl->mac_addr[2];
-       nvs_ptr[5] = wl->mac_addr[3];
-       nvs_ptr[4] = wl->mac_addr[4];
-       nvs_ptr[3] = wl->mac_addr[5];
+       nvs_ptr[11] = wl->addresses[0].addr[0];
+       nvs_ptr[10] = wl->addresses[0].addr[1];
+       nvs_ptr[6] = wl->addresses[0].addr[2];
+       nvs_ptr[5] = wl->addresses[0].addr[3];
+       nvs_ptr[4] = wl->addresses[0].addr[4];
+       nvs_ptr[3] = wl->addresses[0].addr[5];
 
        /*
         * Layout before the actual NVS tables:
@@ -383,7 +324,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
        nvs_len -= nvs_ptr - (u8 *)wl->nvs;
 
        /* Now we must set the partition correctly */
-       wl1271_set_partition(wl, &part_table[PART_WORK]);
+       wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
 
        /* Copy the NVS tables to a new block to ensure alignment */
        nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
@@ -492,7 +433,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
        wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
 
        /* set the working partition to its "running" mode offset */
-       wl1271_set_partition(wl, &part_table[PART_WORK]);
+       wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
 
        wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
                     wl->cmd_box_addr, wl->event_box_addr);
@@ -507,8 +448,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
        /* unmask required mbox events  */
        wl->event_mask = BSS_LOSE_EVENT_ID |
                SCAN_COMPLETE_EVENT_ID |
-               PS_REPORT_EVENT_ID |
-               DISCONNECT_EVENT_COMPLETE_ID |
+               ROLE_STOP_COMPLETE_EVENT_ID |
                RSSI_SNR_TRIGGER_0_EVENT_ID |
                PSPOLL_DELIVERY_FAILURE_EVENT_ID |
                SOFT_GEMINI_SENSE_EVENT_ID |
@@ -547,19 +487,6 @@ static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
        return 0;
 }
 
-static void wl1271_boot_hw_version(struct wl1271 *wl)
-{
-       u32 fuse;
-
-       if (wl->chip.id == CHIP_ID_1283_PG20)
-               fuse = wl1271_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1);
-       else
-               fuse = wl1271_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);
-       fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET;
-
-       wl->hw_pg_ver = (s8)fuse;
-}
-
 static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
 {
        u16 spare_reg;
@@ -698,7 +625,7 @@ static int wl127x_boot_clk(struct wl1271 *wl)
        u32 pause;
        u32 clk;
 
-       if (((wl->hw_pg_ver & PG_MAJOR_VER_MASK) >> PG_MAJOR_VER_OFFSET) < 3)
+       if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
                wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
 
        if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
@@ -753,8 +680,6 @@ int wl1271_load_firmware(struct wl1271 *wl)
        u32 tmp, clk;
        int selected_clock = -1;
 
-       wl1271_boot_hw_version(wl);
-
        if (wl->chip.id == CHIP_ID_1283_PG20) {
                ret = wl128x_boot_clk(wl, &selected_clock);
                if (ret < 0)
@@ -769,7 +694,7 @@ int wl1271_load_firmware(struct wl1271 *wl)
        wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
        udelay(500);
 
-       wl1271_set_partition(wl, &part_table[PART_DRPW]);
+       wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]);
 
        /* Read-modify-write DRPW_SCRATCH_START register (see next state)
           to be used by DRPw FW. The RTRIM value will be added by the FW
@@ -788,7 +713,7 @@ int wl1271_load_firmware(struct wl1271 *wl)
 
        wl1271_write32(wl, DRPW_SCRATCH_START, clk);
 
-       wl1271_set_partition(wl, &part_table[PART_WORK]);
+       wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
 
        /* Disable interrupts */
        wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
index 06dad9380fa7f427e5318d5f5e0e191a5c00f1cb..c3adc09f403dd1319fe99303d1a75357d21a9127 100644 (file)
@@ -55,16 +55,6 @@ struct wl1271_static_data {
 #define OCP_REG_CLK_POLARITY 0x0cb2
 #define OCP_REG_CLK_PULL     0x0cb4
 
-#define WL127X_REG_FUSE_DATA_2_1    0x050a
-#define WL128X_REG_FUSE_DATA_2_1    0x2152
-#define PG_VER_MASK          0x3c
-#define PG_VER_OFFSET        2
-
-#define PG_MAJOR_VER_MASK    0x3
-#define PG_MAJOR_VER_OFFSET  0x0
-#define PG_MINOR_VER_MASK    0xc
-#define PG_MINOR_VER_OFFSET  0x2
-
 #define CMD_MBOX_ADDRESS     0x407B4
 
 #define POLARITY_LOW         BIT(1)
index 25990bd38be633d57bc17ae13573875f3cce4a7a..3414fc11e9ba71da93eb4723d252bac693871899 100644 (file)
@@ -459,23 +459,39 @@ out:
 
 int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
 {
+       unsigned long flags;
        u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS);
        if (link >= WL12XX_MAX_LINKS)
                return -EBUSY;
 
+       /* these bits are used by op_tx */
+       spin_lock_irqsave(&wl->wl_lock, flags);
        __set_bit(link, wl->links_map);
        __set_bit(link, wlvif->links_map);
+       spin_unlock_irqrestore(&wl->wl_lock, flags);
        *hlid = link;
        return 0;
 }
 
 void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
 {
+       unsigned long flags;
+
        if (*hlid == WL12XX_INVALID_LINK_ID)
                return;
 
+       /* these bits are used by op_tx */
+       spin_lock_irqsave(&wl->wl_lock, flags);
        __clear_bit(*hlid, wl->links_map);
        __clear_bit(*hlid, wlvif->links_map);
+       spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+       /*
+        * At this point op_tx() will not add more packets to the queues. We
+        * can purge them.
+        */
+       wl1271_tx_reset_link_queues(wl, *hlid);
+
        *hlid = WL12XX_INVALID_LINK_ID;
 }
 
@@ -515,7 +531,7 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
                        goto out_free;
        }
        cmd->device.hlid = wlvif->dev_hlid;
-       cmd->device.session = wlvif->session_counter;
+       cmd->device.session = wl12xx_get_new_session_id(wl, wlvif);
 
        wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d",
                     cmd->role_id, cmd->device.hlid, cmd->device.session);
@@ -566,7 +582,7 @@ static int wl12xx_cmd_role_stop_dev(struct wl1271 *wl,
                goto out_free;
        }
 
-       ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID);
+       ret = wl1271_cmd_wait_for_event(wl, ROLE_STOP_COMPLETE_EVENT_ID);
        if (ret < 0) {
                wl1271_error("cmd role stop dev event completion error");
                goto out_free;
@@ -715,6 +731,8 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
        cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int);
        cmd->ap.dtim_interval = bss_conf->dtim_period;
        cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
+       /* FIXME: Change when adding DFS */
+       cmd->ap.reset_tsf = 1;  /* By default reset AP TSF */
        cmd->channel = wlvif->channel;
 
        if (!bss_conf->hidden_ssid) {
@@ -994,7 +1012,7 @@ out:
 }
 
 int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-                      u8 ps_mode)
+                      u8 ps_mode, u16 auto_ps_timeout)
 {
        struct wl1271_cmd_ps_params *ps_params = NULL;
        int ret = 0;
@@ -1009,6 +1027,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 
        ps_params->role_id = wlvif->role_id;
        ps_params->ps_mode = ps_mode;
+       ps_params->auto_ps_timeout = auto_ps_timeout;
 
        ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
                              sizeof(*ps_params), 0);
@@ -1022,13 +1041,15 @@ out:
        return ret;
 }
 
-int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
-                           void *buf, size_t buf_len, int index, u32 rates)
+int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
+                           u16 template_id, void *buf, size_t buf_len,
+                           int index, u32 rates)
 {
        struct wl1271_cmd_template_set *cmd;
        int ret = 0;
 
-       wl1271_debug(DEBUG_CMD, "cmd template_set %d", template_id);
+       wl1271_debug(DEBUG_CMD, "cmd template_set %d (role %d)",
+                    template_id, role_id);
 
        WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE);
        buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE);
@@ -1039,6 +1060,8 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
                goto out;
        }
 
+       /* during initialization wlvif is NULL */
+       cmd->role_id = role_id;
        cmd->len = cpu_to_le16(buf_len);
        cmd->template_type = template_id;
        cmd->enabled_rates = cpu_to_le32(rates);
@@ -1082,7 +1105,8 @@ int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif)
                ptr = skb->data;
        }
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                     CMD_TEMPL_NULL_DATA, ptr, size, 0,
                                      wlvif->basic_rate);
 
 out:
@@ -1105,7 +1129,7 @@ int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
        if (!skb)
                goto out;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_KLV,
                                      skb->data, skb->len,
                                      CMD_TEMPL_KLV_IDX_NULL_DATA,
                                      wlvif->basic_rate);
@@ -1130,7 +1154,8 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
        if (!skb)
                goto out;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                     CMD_TEMPL_PS_POLL, skb->data,
                                      skb->len, 0, wlvif->basic_rate_set);
 
 out:
@@ -1138,9 +1163,10 @@ out:
        return ret;
 }
 
-int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                              u8 role_id, u8 band,
                               const u8 *ssid, size_t ssid_len,
-                              const u8 *ie, size_t ie_len, u8 band)
+                              const u8 *ie, size_t ie_len)
 {
        struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
        struct sk_buff *skb;
@@ -1158,10 +1184,12 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 
        rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
        if (band == IEEE80211_BAND_2GHZ)
-               ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
+               ret = wl1271_cmd_template_set(wl, role_id,
+                                             CMD_TEMPL_CFG_PROBE_REQ_2_4,
                                              skb->data, skb->len, 0, rate);
        else
-               ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+               ret = wl1271_cmd_template_set(wl, role_id,
+                                             CMD_TEMPL_CFG_PROBE_REQ_5,
                                              skb->data, skb->len, 0, rate);
 
 out:
@@ -1186,10 +1214,12 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
 
        rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[wlvif->band]);
        if (wlvif->band == IEEE80211_BAND_2GHZ)
-               ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
+               ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                             CMD_TEMPL_CFG_PROBE_REQ_2_4,
                                              skb->data, skb->len, 0, rate);
        else
-               ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+               ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                             CMD_TEMPL_CFG_PROBE_REQ_5,
                                              skb->data, skb->len, 0, rate);
 
        if (ret < 0)
@@ -1199,32 +1229,34 @@ out:
        return skb;
 }
 
-int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-                            __be32 ip_addr)
+int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 {
-       int ret;
+       int ret, extra;
+       u16 fc;
        struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
-       struct wl12xx_arp_rsp_template tmpl;
+       struct sk_buff *skb;
+       struct wl12xx_arp_rsp_template *tmpl;
        struct ieee80211_hdr_3addr *hdr;
        struct arphdr *arp_hdr;
 
-       memset(&tmpl, 0, sizeof(tmpl));
+       skb = dev_alloc_skb(sizeof(*hdr) + sizeof(__le16) + sizeof(*tmpl) +
+                           WL1271_EXTRA_SPACE_MAX);
+       if (!skb) {
+               wl1271_error("failed to allocate buffer for arp rsp template");
+               return -ENOMEM;
+       }
 
-       /* mac80211 header */
-       hdr = &tmpl.hdr;
-       hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
-                                        IEEE80211_STYPE_DATA |
-                                        IEEE80211_FCTL_TODS);
-       memcpy(hdr->addr1, vif->bss_conf.bssid, ETH_ALEN);
-       memcpy(hdr->addr2, vif->addr, ETH_ALEN);
-       memset(hdr->addr3, 0xff, ETH_ALEN);
+       skb_reserve(skb, sizeof(*hdr) + WL1271_EXTRA_SPACE_MAX);
+
+       tmpl = (struct wl12xx_arp_rsp_template *)skb_put(skb, sizeof(*tmpl));
+       memset(tmpl, 0, sizeof(tmpl));
 
        /* llc layer */
-       memcpy(tmpl.llc_hdr, rfc1042_header, sizeof(rfc1042_header));
-       tmpl.llc_type = cpu_to_be16(ETH_P_ARP);
+       memcpy(tmpl->llc_hdr, rfc1042_header, sizeof(rfc1042_header));
+       tmpl->llc_type = cpu_to_be16(ETH_P_ARP);
 
        /* arp header */
-       arp_hdr = &tmpl.arp_hdr;
+       arp_hdr = &tmpl->arp_hdr;
        arp_hdr->ar_hrd = cpu_to_be16(ARPHRD_ETHER);
        arp_hdr->ar_pro = cpu_to_be16(ETH_P_IP);
        arp_hdr->ar_hln = ETH_ALEN;
@@ -1232,13 +1264,59 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif,
        arp_hdr->ar_op = cpu_to_be16(ARPOP_REPLY);
 
        /* arp payload */
-       memcpy(tmpl.sender_hw, vif->addr, ETH_ALEN);
-       tmpl.sender_ip = ip_addr;
+       memcpy(tmpl->sender_hw, vif->addr, ETH_ALEN);
+       tmpl->sender_ip = wlvif->ip_addr;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP,
-                                     &tmpl, sizeof(tmpl), 0,
-                                     wlvif->basic_rate);
+       /* encryption space */
+       switch (wlvif->encryption_type) {
+       case KEY_TKIP:
+               extra = WL1271_EXTRA_SPACE_TKIP;
+               break;
+       case KEY_AES:
+               extra = WL1271_EXTRA_SPACE_AES;
+               break;
+       case KEY_NONE:
+       case KEY_WEP:
+       case KEY_GEM:
+               extra = 0;
+               break;
+       default:
+               wl1271_warning("Unknown encryption type: %d",
+                              wlvif->encryption_type);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (extra) {
+               u8 *space = skb_push(skb, extra);
+               memset(space, 0, extra);
+       }
+
+       /* QoS header - BE */
+       if (wlvif->sta.qos)
+               memset(skb_push(skb, sizeof(__le16)), 0, sizeof(__le16));
 
+       /* mac80211 header */
+       hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, sizeof(*hdr));
+       memset(hdr, 0, sizeof(hdr));
+       fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS;
+       if (wlvif->sta.qos)
+               fc |= IEEE80211_STYPE_QOS_DATA;
+       else
+               fc |= IEEE80211_STYPE_DATA;
+       if (wlvif->encryption_type != KEY_NONE)
+               fc |= IEEE80211_FCTL_PROTECTED;
+
+       hdr->frame_control = cpu_to_le16(fc);
+       memcpy(hdr->addr1, vif->bss_conf.bssid, ETH_ALEN);
+       memcpy(hdr->addr2, vif->addr, ETH_ALEN);
+       memset(hdr->addr3, 0xff, ETH_ALEN);
+
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_ARP_RSP,
+                                     skb->data, skb->len, 0,
+                                     wlvif->basic_rate);
+out:
+       dev_kfree_skb(skb);
        return ret;
 }
 
@@ -1260,7 +1338,8 @@ int wl1271_build_qos_null_data(struct wl1271 *wl, struct ieee80211_vif *vif)
        /* FIXME: not sure what priority to use here */
        template.qos_ctrl = cpu_to_le16(0);
 
-       return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
+       return wl1271_cmd_template_set(wl, wlvif->role_id,
+                                      CMD_TEMPL_QOS_NULL_DATA, &template,
                                       sizeof(template), 0,
                                       wlvif->basic_rate);
 }
@@ -1739,11 +1818,20 @@ int wl12xx_croc(struct wl1271 *wl, u8 role_id)
                goto out;
 
        __clear_bit(role_id, wl->roc_map);
+
+       /*
+        * Rearm the tx watchdog when removing the last ROC. This prevents
+        * recoveries due to just finished ROCs - when Tx hasn't yet had
+        * a chance to get out.
+        */
+       if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES)
+               wl12xx_rearm_tx_watchdog_locked(wl);
 out:
        return ret;
 }
 
 int wl12xx_cmd_channel_switch(struct wl1271 *wl,
+                             struct wl12xx_vif *wlvif,
                              struct ieee80211_channel_switch *ch_switch)
 {
        struct wl12xx_cmd_channel_switch *cmd;
@@ -1757,10 +1845,13 @@ int wl12xx_cmd_channel_switch(struct wl1271 *wl,
                goto out;
        }
 
+       cmd->role_id = wlvif->role_id;
        cmd->channel = ch_switch->channel->hw_value;
        cmd->switch_time = ch_switch->count;
-       cmd->tx_suspend = ch_switch->block_tx;
-       cmd->flush = 0; /* this value is ignored by the FW */
+       cmd->stop_tx = ch_switch->block_tx;
+
+       /* FIXME: control from mac80211 in the future */
+       cmd->post_switch_tx_disable = 0;  /* Enable TX on the target channel */
 
        ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
        if (ret < 0) {
index 3f7d0b93c24d76c2853fc17ce43580646904e283..de217d92516b4efede360f4c1f187b156b76a294 100644 (file)
@@ -51,22 +51,23 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
 int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
 int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
 int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-                      u8 ps_mode);
+                      u8 ps_mode, u16 auto_ps_timeout);
 int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
                           size_t len);
-int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
-                           void *buf, size_t buf_len, int index, u32 rates);
+int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
+                           u16 template_id, void *buf, size_t buf_len,
+                           int index, u32 rates);
 int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif);
 int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                             u16 aid);
-int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                              u8 role_id, u8 band,
                               const u8 *ssid, size_t ssid_len,
-                              const u8 *ie, size_t ie_len, u8 band);
+                              const u8 *ie, size_t ie_len);
 struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
                                              struct wl12xx_vif *wlvif,
                                              struct sk_buff *skb);
-int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-                            __be32 ip_addr);
+int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif);
 int wl1271_build_qos_null_data(struct wl1271 *wl, struct ieee80211_vif *vif);
 int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
                                   struct wl12xx_vif *wlvif);
@@ -89,6 +90,7 @@ int wl12xx_cmd_config_fwlog(struct wl1271 *wl);
 int wl12xx_cmd_start_fwlog(struct wl1271 *wl);
 int wl12xx_cmd_stop_fwlog(struct wl1271 *wl);
 int wl12xx_cmd_channel_switch(struct wl1271 *wl,
+                             struct wl12xx_vif *wlvif,
                              struct ieee80211_channel_switch *ch_switch);
 int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl);
 int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif,
@@ -96,62 +98,65 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid);
 
 enum wl1271_commands {
-       CMD_INTERROGATE     = 1,    /*use this to read information elements*/
-       CMD_CONFIGURE       = 2,    /*use this to write information elements*/
-       CMD_ENABLE_RX       = 3,
-       CMD_ENABLE_TX       = 4,
-       CMD_DISABLE_RX      = 5,
-       CMD_DISABLE_TX      = 6,
-       CMD_SCAN            = 8,
-       CMD_STOP_SCAN       = 9,
-       CMD_SET_KEYS        = 12,
-       CMD_READ_MEMORY     = 13,
-       CMD_WRITE_MEMORY    = 14,
-       CMD_SET_TEMPLATE    = 19,
-       CMD_TEST            = 23,
-       CMD_NOISE_HIST      = 28,
-       CMD_QUIET_ELEMENT_SET_STATE  = 29,
-       CMD_SET_BCN_MODE    = 33,
-       CMD_MEASUREMENT      = 34,
-       CMD_STOP_MEASUREMENT = 35,
-       CMD_SET_PS_MODE      = 37,
-       CMD_CHANNEL_SWITCH   = 38,
-       CMD_STOP_CHANNEL_SWICTH = 39,
-       CMD_AP_DISCOVERY     = 40,
-       CMD_STOP_AP_DISCOVERY = 41,
-       CMD_HEALTH_CHECK     = 45,
-       CMD_DEBUG            = 46,
-       CMD_TRIGGER_SCAN_TO  = 47,
-       CMD_CONNECTION_SCAN_CFG      = 48,
-       CMD_CONNECTION_SCAN_SSID_CFG = 49,
-       CMD_START_PERIODIC_SCAN      = 50,
-       CMD_STOP_PERIODIC_SCAN       = 51,
-       CMD_SET_PEER_STATE           = 52,
-       CMD_REMAIN_ON_CHANNEL        = 53,
-       CMD_CANCEL_REMAIN_ON_CHANNEL = 54,
-
-       CMD_CONFIG_FWLOGGER          = 55,
-       CMD_START_FWLOGGER           = 56,
-       CMD_STOP_FWLOGGER            = 57,
-
-       /* AP commands */
-       CMD_ADD_PEER                 = 62,
-       CMD_REMOVE_PEER              = 63,
+       CMD_INTERROGATE = 1, /* use this to read information elements */
+       CMD_CONFIGURE   = 2, /* use this to write information elements */
+       CMD_ENABLE_RX   = 3,
+       CMD_ENABLE_TX   = 4,
+       CMD_DISABLE_RX  = 5,
+       CMD_DISABLE_TX  = 6,
+       CMD_SCAN        = 7,
+       CMD_STOP_SCAN   = 8,
+       CMD_SET_KEYS    = 9,
+       CMD_READ_MEMORY = 10,
+       CMD_WRITE_MEMORY        = 11,
+       CMD_SET_TEMPLATE        = 12,
+       CMD_TEST                = 13,
+       CMD_NOISE_HIST          = 14,
+       CMD_QUIET_ELEMENT_SET_STATE = 15,
+       CMD_SET_BCN_MODE        = 16,
+
+       CMD_MEASUREMENT         = 17,
+       CMD_STOP_MEASUREMENT    = 18,
+       CMD_SET_PS_MODE         = 19,
+       CMD_CHANNEL_SWITCH      = 20,
+       CMD_STOP_CHANNEL_SWICTH = 21,
+       CMD_AP_DISCOVERY        = 22,
+       CMD_STOP_AP_DISCOVERY   = 23,
+       CMD_HEALTH_CHECK        = 24,
+       CMD_DEBUG               = 25,
+       CMD_TRIGGER_SCAN_TO     = 26,
+       CMD_CONNECTION_SCAN_CFG = 27,
+       CMD_CONNECTION_SCAN_SSID_CFG    = 28,
+       CMD_START_PERIODIC_SCAN = 29,
+       CMD_STOP_PERIODIC_SCAN  = 30,
+       CMD_SET_PEER_STATE      = 31,
+       CMD_REMAIN_ON_CHANNEL   = 32,
+       CMD_CANCEL_REMAIN_ON_CHANNEL    = 33,
+       CMD_CONFIG_FWLOGGER             = 34,
+       CMD_START_FWLOGGER                      = 35,
+       CMD_STOP_FWLOGGER                       = 36,
+
+       /* Access point commands */
+       CMD_ADD_PEER            = 37,
+       CMD_REMOVE_PEER         = 38,
 
        /* Role API */
-       CMD_ROLE_ENABLE              = 70,
-       CMD_ROLE_DISABLE             = 71,
-       CMD_ROLE_START               = 72,
-       CMD_ROLE_STOP                = 73,
+       CMD_ROLE_ENABLE         = 39,
+       CMD_ROLE_DISABLE        = 40,
+       CMD_ROLE_START          = 41,
+       CMD_ROLE_STOP           = 42,
 
-       /* WIFI Direct */
-       CMD_WFD_START_DISCOVERY      = 80,
-       CMD_WFD_STOP_DISCOVERY       = 81,
-       CMD_WFD_ATTRIBUTE_CONFIG     = 82,
+       /* DFS */
+       CMD_START_RADAR_DETECTION       = 43,
+       CMD_STOP_RADAR_DETECTION        = 44,
 
-       CMD_NOP                      = 100,
+       /* WIFI Direct */
+       CMD_WFD_START_DISCOVERY = 45,
+       CMD_WFD_STOP_DISCOVERY  = 46,
+       CMD_WFD_ATTRIBUTE_CONFIG        = 47,
+       CMD_NOP                 = 48,
+       CMD_LAST_COMMAND,
 
-       NUM_COMMANDS,
        MAX_COMMAND_ID = 0xFFFF,
 };
 
@@ -191,7 +196,7 @@ enum cmd_templ {
 /* unit ms */
 #define WL1271_COMMAND_TIMEOUT     2000
 #define WL1271_CMD_TEMPL_DFLT_SIZE 252
-#define WL1271_CMD_TEMPL_MAX_SIZE  548
+#define WL1271_CMD_TEMPL_MAX_SIZE  512
 #define WL1271_EVENT_TIMEOUT       750
 
 struct wl1271_cmd_header {
@@ -339,7 +344,9 @@ struct wl12xx_cmd_role_start {
                        u8 ssid_len;
                        u8 ssid[IEEE80211_MAX_SSID_LEN];
 
-                       u8 padding_1[5];
+                       u8 reset_tsf;
+
+                       u8 padding_1[4];
                } __packed ap;
        };
 } __packed;
@@ -364,14 +371,18 @@ struct cmd_enabledisable_path {
 struct wl1271_cmd_template_set {
        struct wl1271_cmd_header header;
 
-       __le16 len;
+       u8 role_id;
        u8 template_type;
+       __le16 len;
        u8 index;  /* relevant only for KLV_TEMPLATE type */
+       u8 padding[3];
+
        __le32 enabled_rates;
        u8 short_retry_limit;
        u8 long_retry_limit;
        u8 aflags;
        u8 reserved;
+
        u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE];
 } __packed;
 
@@ -388,6 +399,7 @@ struct wl1271_tim {
 } __packed;
 
 enum wl1271_cmd_ps_mode {
+       STATION_AUTO_PS_MODE,   /* Dynamic Power Save */
        STATION_ACTIVE_MODE,
        STATION_POWER_SAVE_MODE
 };
@@ -397,7 +409,7 @@ struct wl1271_cmd_ps_params {
 
        u8 role_id;
        u8 ps_mode; /* STATION_* */
-       u8 padding[2];
+       u16 auto_ps_timeout;
 } __packed;
 
 /* HW encryption keys */
@@ -695,14 +707,18 @@ struct wl12xx_cmd_stop_fwlog {
 struct wl12xx_cmd_channel_switch {
        struct wl1271_cmd_header header;
 
+       u8 role_id;
+
        /* The new serving channel */
        u8 channel;
        /* Relative time of the serving channel switch in TBTT units */
        u8 switch_time;
-       /* 1: Suspend TX till switch time; 0: Do not suspend TX */
-       u8 tx_suspend;
-       /* 1: Flush TX at switch time; 0: Do not flush */
-       u8 flush;
+       /* Stop the role TX, should expect it after radar detection */
+       u8 stop_tx;
+       /* The target channel tx status 1-stopped 0-open*/
+       u8 post_switch_tx_disable;
+
+       u8 padding[3];
 } __packed;
 
 struct wl12xx_cmd_stop_channel_switch {
index 1bcfb017058d19da42682bdb817488575d8be6d1..3e581e19424c85f68afc272e7ec33ba458f1baf3 100644 (file)
@@ -66,7 +66,8 @@ enum {
 };
 
 enum {
-       CONF_HW_RXTX_RATE_MCS7 = 0,
+       CONF_HW_RXTX_RATE_MCS7_SGI = 0,
+       CONF_HW_RXTX_RATE_MCS7,
        CONF_HW_RXTX_RATE_MCS6,
        CONF_HW_RXTX_RATE_MCS5,
        CONF_HW_RXTX_RATE_MCS4,
@@ -91,6 +92,10 @@ enum {
        CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff
 };
 
+/* Rates between and including these are MCS rates */
+#define CONF_HW_RXTX_RATE_MCS_MIN CONF_HW_RXTX_RATE_MCS7_SGI
+#define CONF_HW_RXTX_RATE_MCS_MAX CONF_HW_RXTX_RATE_MCS0
+
 enum {
        CONF_SG_DISABLE = 0,
        CONF_SG_PROTECTIVE,
@@ -312,6 +317,10 @@ enum {
        CONF_AP_BT_ACL_VAL_BT_SERVE_TIME,
        CONF_AP_BT_ACL_VAL_WL_SERVE_TIME,
 
+       /* CTS Diluting params */
+       CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH,
+       CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER,
+
        CONF_SG_TEMP_PARAM_1,
        CONF_SG_TEMP_PARAM_2,
        CONF_SG_TEMP_PARAM_3,
@@ -681,6 +690,9 @@ struct conf_tx_settings {
         */
        u8 tmpl_short_retry_limit;
        u8 tmpl_long_retry_limit;
+
+       /* Time in ms for Tx watchdog timer to expire */
+       u32 tx_watchdog_timeout;
 };
 
 enum {
@@ -809,6 +821,19 @@ struct conf_conn_settings {
         */
        u8 listen_interval;
 
+       /*
+        * Firmware wakeup conditions during suspend
+        * Range: CONF_WAKE_UP_EVENT_*
+        */
+       u8 suspend_wake_up_event;
+
+       /*
+        * Listen interval during suspend.
+        * Currently will be in DTIMs (1-10)
+        *
+        */
+       u8 suspend_listen_interval;
+
        /*
         * Enable or disable the beacon filtering.
         *
@@ -867,13 +892,6 @@ struct conf_conn_settings {
         */
        u8 ps_poll_threshold;
 
-       /*
-        * PS Poll failure recovery ACTIVE period length
-        *
-        * Range: u32 (ms)
-        */
-       u32 ps_poll_recovery_period;
-
        /*
         * Configuration of signal average weights.
         */
@@ -921,6 +939,18 @@ struct conf_conn_settings {
         */
        u8 psm_entry_nullfunc_retries;
 
+       /*
+        * Specifies the dynamic PS timeout in ms that will be used
+        * by the FW when in AUTO_PS mode
+        */
+       u16 dynamic_ps_timeout;
+
+       /*
+        * Specifies whether dynamic PS should be disabled and PSM forced.
+        * This is required for certain WiFi certification tests.
+        */
+       u8 forced_ps;
+
        /*
         *
         * Specifies the interval of the connection keep-alive null-func
@@ -1055,6 +1085,14 @@ struct conf_scan_settings {
         */
        u16 num_probe_reqs;
 
+       /*
+        * Scan trigger (split scan) timeout. The FW will split the scan
+        * operation into slices of the given time and allow the FW to schedule
+        * other tasks in between.
+        *
+        * Range: u32 Microsecs
+        */
+       u32 split_scan_timeout;
 };
 
 struct conf_sched_scan_settings {
index b85fd8c41e8f04065535b34eee0a3777190b8599..ec0fdc25b28027c58a39d711fc846c25b356eaee 100644 (file)
@@ -51,6 +51,7 @@ enum {
        DEBUG_FILTERS   = BIT(15),
        DEBUG_ADHOC     = BIT(16),
        DEBUG_AP        = BIT(17),
+       DEBUG_PROBE     = BIT(18),
        DEBUG_MASTER    = (DEBUG_ADHOC | DEBUG_AP),
        DEBUG_ALL       = ~0,
 };
index 15eb3a9c30ca11907ea92ef4aaf3ce794c91ea0c..e1cf727659650a90f9ae43f8636003409404eb00 100644 (file)
@@ -113,7 +113,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl)
        if (ret < 0)
                goto out;
 
-       if (wl->state == WL1271_STATE_ON &&
+       if (wl->state == WL1271_STATE_ON && !wl->plt &&
            time_after(jiffies, wl->stats.fw_stats_update +
                       msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
                wl1271_acx_statistics(wl, wl->stats.fw_stats);
@@ -312,6 +312,181 @@ static const struct file_operations start_recovery_ops = {
        .llseek = default_llseek,
 };
 
+static ssize_t dynamic_ps_timeout_read(struct file *file, char __user *user_buf,
+                         size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+
+       return wl1271_format_buffer(user_buf, count,
+                                   ppos, "%d\n",
+                                   wl->conf.conn.dynamic_ps_timeout);
+}
+
+static ssize_t dynamic_ps_timeout_write(struct file *file,
+                                   const char __user *user_buf,
+                                   size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+       struct wl12xx_vif *wlvif;
+       unsigned long value;
+       int ret;
+
+       ret = kstrtoul_from_user(user_buf, count, 10, &value);
+       if (ret < 0) {
+               wl1271_warning("illegal value in dynamic_ps");
+               return -EINVAL;
+       }
+
+       if (value < 1 || value > 65535) {
+               wl1271_warning("dyanmic_ps_timeout is not in valid range");
+               return -ERANGE;
+       }
+
+       mutex_lock(&wl->mutex);
+
+       wl->conf.conn.dynamic_ps_timeout = value;
+
+       if (wl->state == WL1271_STATE_OFF)
+               goto out;
+
+       ret = wl1271_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       /* In case we're already in PSM, trigger it again to set new timeout
+        * immediately without waiting for re-association
+        */
+
+       wl12xx_for_each_wlvif_sta(wl, wlvif) {
+               if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags))
+                       wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE);
+       }
+
+       wl1271_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+       return count;
+}
+
+static const struct file_operations dynamic_ps_timeout_ops = {
+       .read = dynamic_ps_timeout_read,
+       .write = dynamic_ps_timeout_write,
+       .open = wl1271_open_file_generic,
+       .llseek = default_llseek,
+};
+
+static ssize_t forced_ps_read(struct file *file, char __user *user_buf,
+                         size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+
+       return wl1271_format_buffer(user_buf, count,
+                                   ppos, "%d\n",
+                                   wl->conf.conn.forced_ps);
+}
+
+static ssize_t forced_ps_write(struct file *file,
+                                   const char __user *user_buf,
+                                   size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+       struct wl12xx_vif *wlvif;
+       unsigned long value;
+       int ret, ps_mode;
+
+       ret = kstrtoul_from_user(user_buf, count, 10, &value);
+       if (ret < 0) {
+               wl1271_warning("illegal value in forced_ps");
+               return -EINVAL;
+       }
+
+       if (value != 1 && value != 0) {
+               wl1271_warning("forced_ps should be either 0 or 1");
+               return -ERANGE;
+       }
+
+       mutex_lock(&wl->mutex);
+
+       if (wl->conf.conn.forced_ps == value)
+               goto out;
+
+       wl->conf.conn.forced_ps = value;
+
+       if (wl->state == WL1271_STATE_OFF)
+               goto out;
+
+       ret = wl1271_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       /* In case we're already in PSM, trigger it again to switch mode
+        * immediately without waiting for re-association
+        */
+
+       ps_mode = value ? STATION_POWER_SAVE_MODE : STATION_AUTO_PS_MODE;
+
+       wl12xx_for_each_wlvif_sta(wl, wlvif) {
+               if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags))
+                       wl1271_ps_set_mode(wl, wlvif, ps_mode);
+       }
+
+       wl1271_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+       return count;
+}
+
+static const struct file_operations forced_ps_ops = {
+       .read = forced_ps_read,
+       .write = forced_ps_write,
+       .open = wl1271_open_file_generic,
+       .llseek = default_llseek,
+};
+
+static ssize_t split_scan_timeout_read(struct file *file, char __user *user_buf,
+                         size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+
+       return wl1271_format_buffer(user_buf, count,
+                                   ppos, "%d\n",
+                                   wl->conf.scan.split_scan_timeout / 1000);
+}
+
+static ssize_t split_scan_timeout_write(struct file *file,
+                                   const char __user *user_buf,
+                                   size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+       unsigned long value;
+       int ret;
+
+       ret = kstrtoul_from_user(user_buf, count, 10, &value);
+       if (ret < 0) {
+               wl1271_warning("illegal value in split_scan_timeout");
+               return -EINVAL;
+       }
+
+       if (value == 0)
+               wl1271_info("split scan will be disabled");
+
+       mutex_lock(&wl->mutex);
+
+       wl->conf.scan.split_scan_timeout = value * 1000;
+
+       mutex_unlock(&wl->mutex);
+       return count;
+}
+
+static const struct file_operations split_scan_timeout_ops = {
+       .read = split_scan_timeout_read,
+       .write = split_scan_timeout_write,
+       .open = wl1271_open_file_generic,
+       .llseek = default_llseek,
+};
+
 static ssize_t driver_state_read(struct file *file, char __user *user_buf,
                                 size_t count, loff_t *ppos)
 {
@@ -446,6 +621,7 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
                        VIF_STATE_PRINT_INT(sta.basic_rate_idx);
                        VIF_STATE_PRINT_INT(sta.ap_rate_idx);
                        VIF_STATE_PRINT_INT(sta.p2p_rate_idx);
+                       VIF_STATE_PRINT_INT(sta.qos);
                } else {
                        VIF_STATE_PRINT_INT(ap.global_hlid);
                        VIF_STATE_PRINT_INT(ap.bcast_hlid);
@@ -471,7 +647,6 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
                VIF_STATE_PRINT_INT(default_key);
                VIF_STATE_PRINT_INT(aid);
                VIF_STATE_PRINT_INT(session_counter);
-               VIF_STATE_PRINT_INT(ps_poll_failures);
                VIF_STATE_PRINT_INT(psm_entry_retry);
                VIF_STATE_PRINT_INT(power_level);
                VIF_STATE_PRINT_INT(rssi_thold);
@@ -562,6 +737,64 @@ static const struct file_operations dtim_interval_ops = {
        .llseek = default_llseek,
 };
 
+
+
+static ssize_t suspend_dtim_interval_read(struct file *file,
+                                         char __user *user_buf,
+                                         size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+       u8 value;
+
+       if (wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_DTIM ||
+           wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM)
+               value = wl->conf.conn.suspend_listen_interval;
+       else
+               value = 0;
+
+       return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
+}
+
+static ssize_t suspend_dtim_interval_write(struct file *file,
+                                          const char __user *user_buf,
+                                          size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+       unsigned long value;
+       int ret;
+
+       ret = kstrtoul_from_user(user_buf, count, 10, &value);
+       if (ret < 0) {
+               wl1271_warning("illegal value for suspend_dtim_interval");
+               return -EINVAL;
+       }
+
+       if (value < 1 || value > 10) {
+               wl1271_warning("suspend_dtim value is not in valid range");
+               return -ERANGE;
+       }
+
+       mutex_lock(&wl->mutex);
+
+       wl->conf.conn.suspend_listen_interval = value;
+       /* for some reason there are different event types for 1 and >1 */
+       if (value == 1)
+               wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_DTIM;
+       else
+               wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM;
+
+       mutex_unlock(&wl->mutex);
+       return count;
+}
+
+
+static const struct file_operations suspend_dtim_interval_ops = {
+       .read = suspend_dtim_interval_read,
+       .write = suspend_dtim_interval_write,
+       .open = wl1271_open_file_generic,
+       .llseek = default_llseek,
+};
+
 static ssize_t beacon_interval_read(struct file *file, char __user *user_buf,
                                    size_t count, loff_t *ppos)
 {
@@ -886,8 +1119,12 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
        DEBUGFS_ADD(driver_state, rootdir);
        DEBUGFS_ADD(vifs_state, rootdir);
        DEBUGFS_ADD(dtim_interval, rootdir);
+       DEBUGFS_ADD(suspend_dtim_interval, rootdir);
        DEBUGFS_ADD(beacon_interval, rootdir);
        DEBUGFS_ADD(beacon_filtering, rootdir);
+       DEBUGFS_ADD(dynamic_ps_timeout, rootdir);
+       DEBUGFS_ADD(forced_ps, rootdir);
+       DEBUGFS_ADD(split_scan_timeout, rootdir);
 
        streaming = debugfs_create_dir("rx_streaming", rootdir);
        if (!streaming || IS_ERR(streaming))
index d3280df68f5dee8de32537c22e6200f53fa69e60..c953717f38ebab69ed3acdbd117563925916a139 100644 (file)
 #include "scan.h"
 #include "wl12xx_80211.h"
 
-void wl1271_pspoll_work(struct work_struct *work)
-{
-       struct ieee80211_vif *vif;
-       struct wl12xx_vif *wlvif;
-       struct delayed_work *dwork;
-       struct wl1271 *wl;
-       int ret;
-
-       dwork = container_of(work, struct delayed_work, work);
-       wlvif = container_of(dwork, struct wl12xx_vif, pspoll_work);
-       vif = container_of((void *)wlvif, struct ieee80211_vif, drv_priv);
-       wl = wlvif->wl;
-
-       wl1271_debug(DEBUG_EVENT, "pspoll work");
-
-       mutex_lock(&wl->mutex);
-
-       if (unlikely(wl->state == WL1271_STATE_OFF))
-               goto out;
-
-       if (!test_and_clear_bit(WLVIF_FLAG_PSPOLL_FAILURE, &wlvif->flags))
-               goto out;
-
-       if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
-               goto out;
-
-       /*
-        * if we end up here, then we were in powersave when the pspoll
-        * delivery failure occurred, and no-one changed state since, so
-        * we should go back to powersave.
-        */
-       ret = wl1271_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out;
-
-       wl1271_ps_set_mode(wl, wlvif, STATION_POWER_SAVE_MODE,
-                          wlvif->basic_rate, true);
-
-       wl1271_ps_elp_sleep(wl);
-out:
-       mutex_unlock(&wl->mutex);
-};
-
-static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl,
-                                             struct wl12xx_vif *wlvif)
-{
-       int delay = wl->conf.conn.ps_poll_recovery_period;
-       int ret;
-
-       wlvif->ps_poll_failures++;
-       if (wlvif->ps_poll_failures == 1)
-               wl1271_info("AP with dysfunctional ps-poll, "
-                           "trying to work around it.");
-
-       /* force active mode receive data from the AP */
-       if (test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {
-               ret = wl1271_ps_set_mode(wl, wlvif, STATION_ACTIVE_MODE,
-                                        wlvif->basic_rate, true);
-               if (ret < 0)
-                       return;
-               set_bit(WLVIF_FLAG_PSPOLL_FAILURE, &wlvif->flags);
-               ieee80211_queue_delayed_work(wl->hw, &wlvif->pspoll_work,
-                                            msecs_to_jiffies(delay));
-       }
-
-       /*
-        * If already in active mode, lets we should be getting data from
-        * the AP right away. If we enter PSM too fast after this, and data
-        * remains on the AP, we will get another event like this, and we'll
-        * go into active once more.
-        */
-}
-
-static int wl1271_event_ps_report(struct wl1271 *wl,
-                                 struct wl12xx_vif *wlvif,
-                                 struct event_mailbox *mbox,
-                                 bool *beacon_loss)
-{
-       int ret = 0;
-       u32 total_retries = wl->conf.conn.psm_entry_retries;
-
-       wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);
-
-       switch (mbox->ps_status) {
-       case EVENT_ENTER_POWER_SAVE_FAIL:
-               wl1271_debug(DEBUG_PSM, "PSM entry failed");
-
-               if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {
-                       /* remain in active mode */
-                       wlvif->psm_entry_retry = 0;
-                       break;
-               }
-
-               if (wlvif->psm_entry_retry < total_retries) {
-                       wlvif->psm_entry_retry++;
-                       ret = wl1271_ps_set_mode(wl, wlvif,
-                                                STATION_POWER_SAVE_MODE,
-                                                wlvif->basic_rate, true);
-               } else {
-                       wl1271_info("No ack to nullfunc from AP.");
-                       wlvif->psm_entry_retry = 0;
-                       *beacon_loss = true;
-               }
-               break;
-       case EVENT_ENTER_POWER_SAVE_SUCCESS:
-               wlvif->psm_entry_retry = 0;
-
-               /*
-                * BET has only a minor effect in 5GHz and masks
-                * channel switch IEs, so we only enable BET on 2.4GHz
-               */
-               if (wlvif->band == IEEE80211_BAND_2GHZ)
-                       /* enable beacon early termination */
-                       ret = wl1271_acx_bet_enable(wl, wlvif, true);
-
-               if (wlvif->ps_compl) {
-                       complete(wlvif->ps_compl);
-                       wlvif->ps_compl = NULL;
-               }
-               break;
-       default:
-               break;
-       }
-
-       return ret;
-}
-
 static void wl1271_event_rssi_trigger(struct wl1271 *wl,
                                      struct wl12xx_vif *wlvif,
                                      struct event_mailbox *mbox)
@@ -205,21 +78,13 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl,
                                               u8 enable)
 {
-       struct ieee80211_vif *vif;
        struct wl12xx_vif *wlvif;
 
        if (enable) {
-               /* disable dynamic PS when requested by the firmware */
-               wl12xx_for_each_wlvif_sta(wl, wlvif) {
-                       vif = wl12xx_wlvif_to_vif(wlvif);
-                       ieee80211_disable_dyn_ps(vif);
-               }
                set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
        } else {
                clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
                wl12xx_for_each_wlvif_sta(wl, wlvif) {
-                       vif = wl12xx_wlvif_to_vif(wlvif);
-                       ieee80211_enable_dyn_ps(vif);
                        wl1271_recalc_rx_streaming(wl, wlvif);
                }
        }
@@ -237,7 +102,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
 {
        struct ieee80211_vif *vif;
        struct wl12xx_vif *wlvif;
-       int ret;
        u32 vector;
        bool beacon_loss = false;
        bool disconnect_sta = false;
@@ -293,21 +157,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
                beacon_loss = true;
        }
 
-       if (vector & PS_REPORT_EVENT_ID) {
-               wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
-               wl12xx_for_each_wlvif_sta(wl, wlvif) {
-                       ret = wl1271_event_ps_report(wl, wlvif,
-                                                    mbox, &beacon_loss);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-
-       if (vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID)
-               wl12xx_for_each_wlvif_sta(wl, wlvif) {
-                       wl1271_event_pspoll_delivery_fail(wl, wlvif);
-               }
-
        if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
                /* TODO: check actual multi-role support */
                wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT");
@@ -344,7 +193,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
 
                /* TODO: configure only the relevant vif */
                wl12xx_for_each_wlvif_sta(wl, wlvif) {
-                       struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
                        bool success;
 
                        if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS,
@@ -352,6 +200,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
                                continue;
 
                        success = mbox->channel_switch_status ? false : true;
+                       vif = wl12xx_wlvif_to_vif(wlvif);
+
                        ieee80211_chswitch_done(vif, success);
                }
        }
index 1d878ba47bf47b1dc85e9af485963a610ff92e59..057d193d3525c39adce0b26e4ac170b8688c08bc 100644 (file)
@@ -51,10 +51,10 @@ enum {
        SCAN_COMPLETE_EVENT_ID                   = BIT(10),
        WFD_DISCOVERY_COMPLETE_EVENT_ID          = BIT(11),
        AP_DISCOVERY_COMPLETE_EVENT_ID           = BIT(12),
-       PS_REPORT_EVENT_ID                       = BIT(13),
+       RESERVED1                                = BIT(13),
        PSPOLL_DELIVERY_FAILURE_EVENT_ID         = BIT(14),
-       DISCONNECT_EVENT_COMPLETE_ID             = BIT(15),
-       /* BIT(16) is reserved */
+       ROLE_STOP_COMPLETE_EVENT_ID              = BIT(15),
+       RADAR_DETECTED_EVENT_ID                  = BIT(16),
        CHANNEL_SWITCH_COMPLETE_EVENT_ID         = BIT(17),
        BSS_LOSE_EVENT_ID                        = BIT(18),
        REGAINED_BSS_EVENT_ID                    = BIT(19),
@@ -94,9 +94,9 @@ struct event_mailbox {
        u8 soft_gemini_sense_info;
        u8 soft_gemini_protective_info;
        s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
-       u8 channel_switch_status;
+       u8 change_auto_mode_timeout;
        u8 scheduled_scan_status;
-       u8 ps_status;
+       u8 reserved4;
        /* tuned channel (roc) */
        u8 roc_channel;
 
@@ -119,17 +119,21 @@ struct event_mailbox {
        u8 rx_ba_allowed;
        u8 reserved_6[2];
 
+       /* Channel switch results */
+
+       u8 channel_switch_role_id;
+       u8 channel_switch_status;
+       u8 reserved_7[2];
+
        u8 ps_poll_delivery_failure_role_ids;
        u8 stopped_role_ids;
        u8 started_role_ids;
-       u8 change_auto_mode_timeout;
 
-       u8 reserved_7[12];
+       u8 reserved_8[9];
 } __packed;
 
 int wl1271_event_unmask(struct wl1271 *wl);
 void wl1271_event_mbox_config(struct wl1271 *wl);
 int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
-void wl1271_pspoll_work(struct work_struct *work);
 
 #endif
index ca7ee59e4505b297c104197bfde176e34336458b..203fbebf09eb472e8fa49a9178264181c0b15b3b 100644 (file)
 int wl1271_init_templates_config(struct wl1271 *wl)
 {
        int ret, i;
+       size_t max_size;
 
        /* send empty templates for fw memory reservation */
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
-                                     WL1271_CMD_TEMPL_DFLT_SIZE,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
+                                     WL1271_CMD_TEMPL_MAX_SIZE,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
-                                     NULL, WL1271_CMD_TEMPL_DFLT_SIZE, 0,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_CFG_PROBE_REQ_5,
+                                     NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0,
                                      WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_NULL_DATA, NULL,
                                      sizeof(struct wl12xx_null_data_template),
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_PS_POLL, NULL,
                                      sizeof(struct wl12xx_ps_poll_template),
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_QOS_NULL_DATA, NULL,
                                      sizeof
                                      (struct ieee80211_qos_hdr),
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_PROBE_RESPONSE, NULL,
                                      WL1271_CMD_TEMPL_DFLT_SIZE,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_BEACON, NULL,
                                      WL1271_CMD_TEMPL_DFLT_SIZE,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL,
-                                     sizeof
-                                     (struct wl12xx_arp_rsp_template),
+       max_size = sizeof(struct wl12xx_arp_rsp_template) +
+                  WL1271_EXTRA_SPACE_MAX;
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_ARP_RSP, NULL,
+                                     max_size,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
@@ -93,19 +103,22 @@ int wl1271_init_templates_config(struct wl1271 *wl)
         * Put very large empty placeholders for all templates. These
         * reserve memory for later.
         */
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
                                      WL1271_CMD_TEMPL_MAX_SIZE,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_BEACON, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_AP_BEACON, NULL,
                                      WL1271_CMD_TEMPL_MAX_SIZE,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_DEAUTH_AP, NULL,
                                      sizeof
                                      (struct wl12xx_disconn_template),
                                      0, WL1271_RATE_AUTOMATIC);
@@ -113,7 +126,8 @@ int wl1271_init_templates_config(struct wl1271 *wl)
                return ret;
 
        for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
-               ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
+               ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                             CMD_TEMPL_KLV, NULL,
                                              sizeof(struct ieee80211_qos_hdr),
                                              i, WL1271_RATE_AUTOMATIC);
                if (ret < 0)
@@ -140,7 +154,8 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl,
                                             IEEE80211_STYPE_DEAUTH);
 
        rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                     CMD_TEMPL_DEAUTH_AP,
                                      tmpl, sizeof(*tmpl), 0, rate);
 
 out:
@@ -172,7 +187,8 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl,
        memcpy(nullfunc->addr3, vif->addr, ETH_ALEN);
 
        rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                     CMD_TEMPL_NULL_DATA, nullfunc,
                                      sizeof(*nullfunc), 0, rate);
 
 out:
@@ -204,7 +220,8 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl,
        memcpy(qosnull->addr3, vif->addr, ETH_ALEN);
 
        rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                     CMD_TEMPL_QOS_NULL_DATA, qosnull,
                                      sizeof(*qosnull), 0, rate);
 
 out:
index 079ad380e8ff7902ea2359d8e99a203e19941b81..c574a3b31e3127e514d74ab7d09a3e8e9664f15f 100644 (file)
 #define OCP_STATUS_REQ_FAILED 0x20000
 #define OCP_STATUS_RESP_ERROR 0x30000
 
+struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN] = {
+       [PART_DOWN] = {
+               .mem = {
+                       .start = 0x00000000,
+                       .size  = 0x000177c0
+               },
+               .reg = {
+                       .start = REGISTERS_BASE,
+                       .size  = 0x00008800
+               },
+               .mem2 = {
+                       .start = 0x00000000,
+                       .size  = 0x00000000
+               },
+               .mem3 = {
+                       .start = 0x00000000,
+                       .size  = 0x00000000
+               },
+       },
+
+       [PART_WORK] = {
+               .mem = {
+                       .start = 0x00040000,
+                       .size  = 0x00014fc0
+               },
+               .reg = {
+                       .start = REGISTERS_BASE,
+                       .size  = 0x0000a000
+               },
+               .mem2 = {
+                       .start = 0x003004f8,
+                       .size  = 0x00000004
+               },
+               .mem3 = {
+                       .start = 0x00040404,
+                       .size  = 0x00000000
+               },
+       },
+
+       [PART_DRPW] = {
+               .mem = {
+                       .start = 0x00040000,
+                       .size  = 0x00014fc0
+               },
+               .reg = {
+                       .start = DRPW_BASE,
+                       .size  = 0x00006000
+               },
+               .mem2 = {
+                       .start = 0x00000000,
+                       .size  = 0x00000000
+               },
+               .mem3 = {
+                       .start = 0x00000000,
+                       .size  = 0x00000000
+               }
+       }
+};
+
 bool wl1271_set_block_size(struct wl1271 *wl)
 {
        if (wl->if_ops->set_block_size) {
index d398cbcea98677ae4b2c952b3077ed7d10c8920d..4fb3dab8c3b2124516ccac22ef9f71d82a9a50e2 100644 (file)
@@ -43,6 +43,8 @@
 
 #define HW_ACCESS_PRAM_MAX_RANGE       0x3c000
 
+extern struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN];
+
 struct wl1271;
 
 void wl1271_disable_interrupts(struct wl1271 *wl);
index d5f55a149de5e43216ad46c7ebf0d4825e9d0628..39002363611e19460473f9bca60504c4475db640 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * This file is part of wl1271
  *
@@ -115,6 +116,9 @@ static struct conf_drv_settings default_conf = {
                        [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
                        [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
                        [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
+                       /* CTS Diluting params */
+                       [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
+                       [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
                },
                .state = CONF_SG_PROTECTIVE,
        },
@@ -213,10 +217,13 @@ static struct conf_drv_settings default_conf = {
                .basic_rate_5                = CONF_HW_BIT_RATE_6MBPS,
                .tmpl_short_retry_limit      = 10,
                .tmpl_long_retry_limit       = 10,
+               .tx_watchdog_timeout         = 5000,
        },
        .conn = {
                .wake_up_event               = CONF_WAKE_UP_EVENT_DTIM,
                .listen_interval             = 1,
+               .suspend_wake_up_event       = CONF_WAKE_UP_EVENT_N_DTIM,
+               .suspend_listen_interval     = 3,
                .bcn_filt_mode               = CONF_BCN_FILT_MODE_ENABLED,
                .bcn_filt_ie_count           = 2,
                .bcn_filt_ie = {
@@ -235,12 +242,13 @@ static struct conf_drv_settings default_conf = {
                .broadcast_timeout           = 20000,
                .rx_broadcast_in_ps          = 1,
                .ps_poll_threshold           = 10,
-               .ps_poll_recovery_period     = 700,
                .bet_enable                  = CONF_BET_MODE_ENABLE,
                .bet_max_consecutive         = 50,
                .psm_entry_retries           = 8,
                .psm_exit_retries            = 16,
                .psm_entry_nullfunc_retries  = 3,
+               .dynamic_ps_timeout          = 200,
+               .forced_ps                   = false,
                .keep_alive_interval         = 55000,
                .max_listen_interval         = 20,
        },
@@ -265,6 +273,7 @@ static struct conf_drv_settings default_conf = {
                .min_dwell_time_passive       = 100000,
                .max_dwell_time_passive       = 100000,
                .num_probe_reqs               = 2,
+               .split_scan_timeout           = 50000,
        },
        .sched_scan = {
                /* sched_scan requires dwell times in TU instead of TU/1000 */
@@ -384,15 +393,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
 static void wl1271_op_stop(struct ieee80211_hw *hw);
 static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif);
 
-static DEFINE_MUTEX(wl_list_mutex);
-static LIST_HEAD(wl_list);
-
-static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-                                 unsigned char operstate)
+static int wl12xx_set_authorized(struct wl1271 *wl,
+                                struct wl12xx_vif *wlvif)
 {
        int ret;
 
-       if (operstate != IF_OPER_UP)
+       if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
+               return -EINVAL;
+
+       if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
                return 0;
 
        if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags))
@@ -407,76 +416,6 @@ static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
        wl1271_info("Association completed.");
        return 0;
 }
-static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
-                            void *arg)
-{
-       struct net_device *dev = arg;
-       struct wireless_dev *wdev;
-       struct wiphy *wiphy;
-       struct ieee80211_hw *hw;
-       struct wl1271 *wl;
-       struct wl1271 *wl_temp;
-       struct wl12xx_vif *wlvif;
-       int ret = 0;
-
-       /* Check that this notification is for us. */
-       if (what != NETDEV_CHANGE)
-               return NOTIFY_DONE;
-
-       wdev = dev->ieee80211_ptr;
-       if (wdev == NULL)
-               return NOTIFY_DONE;
-
-       wiphy = wdev->wiphy;
-       if (wiphy == NULL)
-               return NOTIFY_DONE;
-
-       hw = wiphy_priv(wiphy);
-       if (hw == NULL)
-               return NOTIFY_DONE;
-
-       wl_temp = hw->priv;
-       mutex_lock(&wl_list_mutex);
-       list_for_each_entry(wl, &wl_list, list) {
-               if (wl == wl_temp)
-                       break;
-       }
-       mutex_unlock(&wl_list_mutex);
-       if (wl != wl_temp)
-               return NOTIFY_DONE;
-
-       mutex_lock(&wl->mutex);
-
-       if (wl->state == WL1271_STATE_OFF)
-               goto out;
-
-       if (dev->operstate != IF_OPER_UP)
-               goto out;
-       /*
-        * The correct behavior should be just getting the appropriate wlvif
-        * from the given dev, but currently we don't have a mac80211
-        * interface for it.
-        */
-       wl12xx_for_each_wlvif_sta(wl, wlvif) {
-               struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
-
-               if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
-                       continue;
-
-               ret = wl1271_ps_elp_wakeup(wl);
-               if (ret < 0)
-                       goto out;
-
-               wl1271_check_operstate(wl, wlvif,
-                                      ieee80211_get_operstate(vif));
-
-               wl1271_ps_elp_sleep(wl);
-       }
-out:
-       mutex_unlock(&wl->mutex);
-
-       return NOTIFY_OK;
-}
 
 static int wl1271_reg_notify(struct wiphy *wiphy,
                             struct regulatory_request *request)
@@ -615,6 +554,80 @@ static void wl1271_rx_streaming_timer(unsigned long data)
        ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work);
 }
 
+/* wl->mutex must be taken */
+void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl)
+{
+       /* if the watchdog is not armed, don't do anything */
+       if (wl->tx_allocated_blocks == 0)
+               return;
+
+       cancel_delayed_work(&wl->tx_watchdog_work);
+       ieee80211_queue_delayed_work(wl->hw, &wl->tx_watchdog_work,
+               msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout));
+}
+
+static void wl12xx_tx_watchdog_work(struct work_struct *work)
+{
+       struct delayed_work *dwork;
+       struct wl1271 *wl;
+
+       dwork = container_of(work, struct delayed_work, work);
+       wl = container_of(dwork, struct wl1271, tx_watchdog_work);
+
+       mutex_lock(&wl->mutex);
+
+       if (unlikely(wl->state == WL1271_STATE_OFF))
+               goto out;
+
+       /* Tx went out in the meantime - everything is ok */
+       if (unlikely(wl->tx_allocated_blocks == 0))
+               goto out;
+
+       /*
+        * if a ROC is in progress, we might not have any Tx for a long
+        * time (e.g. pending Tx on the non-ROC channels)
+        */
+       if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) {
+               wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to ROC",
+                            wl->conf.tx.tx_watchdog_timeout);
+               wl12xx_rearm_tx_watchdog_locked(wl);
+               goto out;
+       }
+
+       /*
+        * if a scan is in progress, we might not have any Tx for a long
+        * time
+        */
+       if (wl->scan.state != WL1271_SCAN_STATE_IDLE) {
+               wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to scan",
+                            wl->conf.tx.tx_watchdog_timeout);
+               wl12xx_rearm_tx_watchdog_locked(wl);
+               goto out;
+       }
+
+       /*
+       * AP might cache a frame for a long time for a sleeping station,
+       * so rearm the timer if there's an AP interface with stations. If
+       * Tx is genuinely stuck we will most hopefully discover it when all
+       * stations are removed due to inactivity.
+       */
+       if (wl->active_sta_count) {
+               wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms. AP has "
+                            " %d stations",
+                             wl->conf.tx.tx_watchdog_timeout,
+                             wl->active_sta_count);
+               wl12xx_rearm_tx_watchdog_locked(wl);
+               goto out;
+       }
+
+       wl1271_error("Tx stuck (in FW) for %d ms. Starting recovery",
+                    wl->conf.tx.tx_watchdog_timeout);
+       wl12xx_queue_recovery_work(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+}
+
 static void wl1271_conf_init(struct wl1271 *wl)
 {
 
@@ -672,8 +685,6 @@ static int wl1271_plt_init(struct wl1271 *wl)
                if (ret < 0)
                        return ret;
        }
-       if (ret < 0)
-               return ret;
 
        /* Chip-specific initializations */
        ret = wl1271_chip_specific_init(wl);
@@ -809,6 +820,18 @@ static void wl12xx_fw_status(struct wl1271 *wl,
 
        wl->tx_allocated_blocks -= freed_blocks;
 
+       /*
+        * If the FW freed some blocks:
+        * If we still have allocated blocks - re-arm the timer, Tx is
+        * not stuck. Otherwise, cancel the timer (no Tx currently).
+        */
+       if (freed_blocks) {
+               if (wl->tx_allocated_blocks)
+                       wl12xx_rearm_tx_watchdog_locked(wl);
+               else
+                       cancel_delayed_work(&wl->tx_watchdog_work);
+       }
+
        avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks;
 
        /*
@@ -985,16 +1008,70 @@ out:
        return IRQ_HANDLED;
 }
 
-static int wl1271_fetch_firmware(struct wl1271 *wl)
+struct vif_counter_data {
+       u8 counter;
+
+       struct ieee80211_vif *cur_vif;
+       bool cur_vif_running;
+};
+
+static void wl12xx_vif_count_iter(void *data, u8 *mac,
+                                 struct ieee80211_vif *vif)
+{
+       struct vif_counter_data *counter = data;
+
+       counter->counter++;
+       if (counter->cur_vif == vif)
+               counter->cur_vif_running = true;
+}
+
+/* caller must not hold wl->mutex, as it might deadlock */
+static void wl12xx_get_vif_count(struct ieee80211_hw *hw,
+                              struct ieee80211_vif *cur_vif,
+                              struct vif_counter_data *data)
+{
+       memset(data, 0, sizeof(*data));
+       data->cur_vif = cur_vif;
+
+       ieee80211_iterate_active_interfaces(hw,
+                                           wl12xx_vif_count_iter, data);
+}
+
+static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
 {
        const struct firmware *fw;
        const char *fw_name;
+       enum wl12xx_fw_type fw_type;
        int ret;
 
-       if (wl->chip.id == CHIP_ID_1283_PG20)
-               fw_name = WL128X_FW_NAME;
-       else
-               fw_name = WL127X_FW_NAME;
+       if (plt) {
+               fw_type = WL12XX_FW_TYPE_PLT;
+               if (wl->chip.id == CHIP_ID_1283_PG20)
+                       fw_name = WL128X_PLT_FW_NAME;
+               else
+                       fw_name = WL127X_PLT_FW_NAME;
+       } else {
+               /*
+                * we can't call wl12xx_get_vif_count() here because
+                * wl->mutex is taken, so use the cached last_vif_count value
+                */
+               if (wl->last_vif_count > 1) {
+                       fw_type = WL12XX_FW_TYPE_MULTI;
+                       if (wl->chip.id == CHIP_ID_1283_PG20)
+                               fw_name = WL128X_FW_NAME_MULTI;
+                       else
+                               fw_name = WL127X_FW_NAME_MULTI;
+               } else {
+                       fw_type = WL12XX_FW_TYPE_NORMAL;
+                       if (wl->chip.id == CHIP_ID_1283_PG20)
+                               fw_name = WL128X_FW_NAME_SINGLE;
+                       else
+                               fw_name = WL127X_FW_NAME_SINGLE;
+               }
+       }
+
+       if (wl->fw_type == fw_type)
+               return 0;
 
        wl1271_debug(DEBUG_BOOT, "booting firmware %s", fw_name);
 
@@ -1013,6 +1090,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
        }
 
        vfree(wl->fw);
+       wl->fw_type = WL12XX_FW_TYPE_NONE;
        wl->fw_len = fw->size;
        wl->fw = vmalloc(wl->fw_len);
 
@@ -1024,7 +1102,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
 
        memcpy(wl->fw, fw->data, wl->fw_len);
        ret = 0;
-
+       wl->fw_type = fw_type;
 out:
        release_firmware(fw);
 
@@ -1152,7 +1230,7 @@ static void wl1271_recovery_work(struct work_struct *work)
 
        mutex_lock(&wl->mutex);
 
-       if (wl->state != WL1271_STATE_ON)
+       if (wl->state != WL1271_STATE_ON || wl->plt)
                goto out_unlock;
 
        /* Avoid a recursive recovery */
@@ -1163,7 +1241,8 @@ static void wl1271_recovery_work(struct work_struct *work)
        wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
                    wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4));
 
-       BUG_ON(bug_on_recovery);
+       BUG_ON(bug_on_recovery &&
+              !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
 
        /*
         * Advance security sequence number to overcome potential progress
@@ -1232,10 +1311,9 @@ static int wl1271_setup(struct wl1271 *wl)
        return 0;
 }
 
-static int wl1271_chip_wakeup(struct wl1271 *wl)
+static int wl12xx_set_power_on(struct wl1271 *wl)
 {
-       struct wl1271_partition_set partition;
-       int ret = 0;
+       int ret;
 
        msleep(WL1271_PRE_POWER_ON_SLEEP);
        ret = wl1271_power_on(wl);
@@ -1245,20 +1323,22 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
        wl1271_io_reset(wl);
        wl1271_io_init(wl);
 
-       /* We don't need a real memory partition here, because we only want
-        * to use the registers at this point. */
-       memset(&partition, 0, sizeof(partition));
-       partition.reg.start = REGISTERS_BASE;
-       partition.reg.size = REGISTERS_DOWN_SIZE;
-       wl1271_set_partition(wl, &partition);
+       wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]);
 
        /* ELP module wake up */
        wl1271_fw_wakeup(wl);
 
-       /* whal_FwCtrl_BootSm() */
+out:
+       return ret;
+}
+
+static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
+{
+       int ret = 0;
 
-       /* 0. read chip id from CHIP_ID */
-       wl->chip.id = wl1271_read32(wl, CHIP_ID_B);
+       ret = wl12xx_set_power_on(wl);
+       if (ret < 0)
+               goto out;
 
        /*
         * For wl127x based devices we could use the default block
@@ -1307,11 +1387,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
                goto out;
        }
 
-       if (wl->fw == NULL) {
-               ret = wl1271_fetch_firmware(wl);
-               if (ret < 0)
-                       goto out;
-       }
+       ret = wl12xx_fetch_firmware(wl, plt);
+       if (ret < 0)
+               goto out;
 
        /* No NVS from netlink, try to get it from the filesystem */
        if (wl->nvs == NULL) {
@@ -1343,7 +1421,7 @@ int wl1271_plt_start(struct wl1271 *wl)
 
        while (retries) {
                retries--;
-               ret = wl1271_chip_wakeup(wl);
+               ret = wl12xx_chip_wakeup(wl, true);
                if (ret < 0)
                        goto power_off;
 
@@ -1355,7 +1433,8 @@ int wl1271_plt_start(struct wl1271 *wl)
                if (ret < 0)
                        goto irq_disable;
 
-               wl->state = WL1271_STATE_PLT;
+               wl->plt = true;
+               wl->state = WL1271_STATE_ON;
                wl1271_notice("firmware booted in PLT mode (%s)",
                              wl->chip.fw_ver_str);
 
@@ -1391,41 +1470,52 @@ out:
        return ret;
 }
 
-static int __wl1271_plt_stop(struct wl1271 *wl)
+int wl1271_plt_stop(struct wl1271 *wl)
 {
        int ret = 0;
 
        wl1271_notice("power down");
 
-       if (wl->state != WL1271_STATE_PLT) {
+       /*
+        * Interrupts must be disabled before setting the state to OFF.
+        * Otherwise, the interrupt handler might be called and exit without
+        * reading the interrupt status.
+        */
+       wl1271_disable_interrupts(wl);
+       mutex_lock(&wl->mutex);
+       if (!wl->plt) {
+               mutex_unlock(&wl->mutex);
+
+               /*
+                * This will not necessarily enable interrupts as interrupts
+                * may have been disabled when op_stop was called. It will,
+                * however, balance the above call to disable_interrupts().
+                */
+               wl1271_enable_interrupts(wl);
+
                wl1271_error("cannot power down because not in PLT "
                             "state: %d", wl->state);
                ret = -EBUSY;
                goto out;
        }
 
-       wl1271_power_off(wl);
-
-       wl->state = WL1271_STATE_OFF;
-       wl->rx_counter = 0;
-
        mutex_unlock(&wl->mutex);
-       wl1271_disable_interrupts(wl);
+
        wl1271_flush_deferred_work(wl);
        cancel_work_sync(&wl->netstack_work);
        cancel_work_sync(&wl->recovery_work);
-       mutex_lock(&wl->mutex);
-out:
-       return ret;
-}
-
-int wl1271_plt_stop(struct wl1271 *wl)
-{
-       int ret;
+       cancel_delayed_work_sync(&wl->elp_work);
+       cancel_delayed_work_sync(&wl->tx_watchdog_work);
 
        mutex_lock(&wl->mutex);
-       ret = __wl1271_plt_stop(wl);
+       wl1271_power_off(wl);
+       wl->flags = 0;
+       wl->state = WL1271_STATE_OFF;
+       wl->plt = false;
+       wl->rx_counter = 0;
        mutex_unlock(&wl->mutex);
+
+out:
        return ret;
 }
 
@@ -1457,7 +1547,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
                goto out;
        }
 
-       wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q);
+       wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d len %d",
+                    hlid, q, skb->len);
        skb_queue_tail(&wl->links[hlid].tx_queue[q], skb);
 
        wl->tx_queue_count[q]++;
@@ -1555,10 +1646,6 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
 }
 
 
-static struct notifier_block wl1271_dev_notifier = {
-       .notifier_call = wl1271_dev_notify,
-};
-
 #ifdef CONFIG_PM
 static int wl1271_configure_suspend_sta(struct wl1271 *wl,
                                        struct wl12xx_vif *wlvif)
@@ -1574,38 +1661,16 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
        if (ret < 0)
                goto out_unlock;
 
-       /* enter psm if needed*/
-       if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {
-               DECLARE_COMPLETION_ONSTACK(compl);
-
-               wlvif->ps_compl = &compl;
-               ret = wl1271_ps_set_mode(wl, wlvif, STATION_POWER_SAVE_MODE,
-                                  wlvif->basic_rate, true);
-               if (ret < 0)
-                       goto out_sleep;
-
-               /* we must unlock here so we will be able to get events */
-               wl1271_ps_elp_sleep(wl);
-               mutex_unlock(&wl->mutex);
+       ret = wl1271_acx_wake_up_conditions(wl, wlvif,
+                                   wl->conf.conn.suspend_wake_up_event,
+                                   wl->conf.conn.suspend_listen_interval);
 
-               ret = wait_for_completion_timeout(
-                       &compl, msecs_to_jiffies(WL1271_PS_COMPLETE_TIMEOUT));
+       if (ret < 0)
+               wl1271_error("suspend: set wake up conditions failed: %d", ret);
 
-               mutex_lock(&wl->mutex);
-               if (ret <= 0) {
-                       wl1271_warning("couldn't enter ps mode!");
-                       ret = -EBUSY;
-                       goto out_cleanup;
-               }
 
-               ret = wl1271_ps_elp_wakeup(wl);
-               if (ret < 0)
-                       goto out_cleanup;
-       }
-out_sleep:
        wl1271_ps_elp_sleep(wl);
-out_cleanup:
-       wlvif->ps_compl = NULL;
+
 out_unlock:
        mutex_unlock(&wl->mutex);
        return ret;
@@ -1648,11 +1713,11 @@ static int wl1271_configure_suspend(struct wl1271 *wl,
 static void wl1271_configure_resume(struct wl1271 *wl,
                                    struct wl12xx_vif *wlvif)
 {
-       int ret;
-       bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
+       int ret = 0;
        bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
+       bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
 
-       if (!is_sta && !is_ap)
+       if ((!is_ap) && (!is_sta))
                return;
 
        mutex_lock(&wl->mutex);
@@ -1661,12 +1726,16 @@ static void wl1271_configure_resume(struct wl1271 *wl,
                goto out;
 
        if (is_sta) {
-               /* exit psm if it wasn't configured */
-               if (!test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags))
-                       wl1271_ps_set_mode(wl, wlvif, STATION_ACTIVE_MODE,
-                                          wlvif->basic_rate, true);
+               ret = wl1271_acx_wake_up_conditions(wl, wlvif,
+                                   wl->conf.conn.wake_up_event,
+                                   wl->conf.conn.listen_interval);
+
+               if (ret < 0)
+                       wl1271_error("resume: wake up conditions failed: %d",
+                                    ret);
+
        } else if (is_ap) {
-               wl1271_acx_beacon_filter_opt(wl, wlvif, false);
+               ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
        }
 
        wl1271_ps_elp_sleep(wl);
@@ -1684,6 +1753,8 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
        wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
        WARN_ON(!wow || !wow->any);
 
+       wl1271_tx_flush(wl);
+
        wl->wow_enabled = true;
        wl12xx_for_each_wlvif(wl, wlvif) {
                ret = wl1271_configure_suspend(wl, wlvif);
@@ -1709,9 +1780,6 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
 
        wl1271_enable_interrupts(wl);
        flush_work(&wl->tx_work);
-       wl12xx_for_each_wlvif(wl, wlvif) {
-               flush_delayed_work(&wlvif->pspoll_work);
-       }
        flush_delayed_work(&wl->elp_work);
 
        return 0;
@@ -1778,11 +1846,25 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
 
        wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
 
+       /*
+        * Interrupts must be disabled before setting the state to OFF.
+        * Otherwise, the interrupt handler might be called and exit without
+        * reading the interrupt status.
+        */
+       wl1271_disable_interrupts(wl);
        mutex_lock(&wl->mutex);
        if (wl->state == WL1271_STATE_OFF) {
                mutex_unlock(&wl->mutex);
+
+               /*
+                * This will not necessarily enable interrupts as interrupts
+                * may have been disabled when op_stop was called. It will,
+                * however, balance the above call to disable_interrupts().
+                */
+               wl1271_enable_interrupts(wl);
                return;
        }
+
        /*
         * this must be before the cancel_work calls below, so that the work
         * functions don't perform further work.
@@ -1790,16 +1872,12 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
        wl->state = WL1271_STATE_OFF;
        mutex_unlock(&wl->mutex);
 
-       mutex_lock(&wl_list_mutex);
-       list_del(&wl->list);
-       mutex_unlock(&wl_list_mutex);
-
-       wl1271_disable_interrupts(wl);
        wl1271_flush_deferred_work(wl);
        cancel_delayed_work_sync(&wl->scan_complete_work);
        cancel_work_sync(&wl->netstack_work);
        cancel_work_sync(&wl->tx_work);
        cancel_delayed_work_sync(&wl->elp_work);
+       cancel_delayed_work_sync(&wl->tx_watchdog_work);
 
        /* let's notify MAC80211 about the remaining pending TX frames */
        wl12xx_tx_reset(wl, true);
@@ -1969,7 +2047,6 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
                  wl1271_rx_streaming_enable_work);
        INIT_WORK(&wlvif->rx_streaming_disable_work,
                  wl1271_rx_streaming_disable_work);
-       INIT_DELAYED_WORK(&wlvif->pspoll_work, wl1271_pspoll_work);
        INIT_LIST_HEAD(&wlvif->list);
 
        setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer,
@@ -1986,7 +2063,7 @@ static bool wl12xx_init_fw(struct wl1271 *wl)
 
        while (retries) {
                retries--;
-               ret = wl1271_chip_wakeup(wl);
+               ret = wl12xx_chip_wakeup(wl, false);
                if (ret < 0)
                        goto power_off;
 
@@ -2051,30 +2128,77 @@ static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif)
        return wlvif->dev_hlid != WL12XX_INVALID_LINK_ID;
 }
 
+/*
+ * Check whether a fw switch (i.e. moving from one loaded
+ * fw to another) is needed. This function is also responsible
+ * for updating wl->last_vif_count, so it must be called before
+ * loading a non-plt fw (so the correct fw (single-role/multi-role)
+ * will be used).
+ */
+static bool wl12xx_need_fw_change(struct wl1271 *wl,
+                                 struct vif_counter_data vif_counter_data,
+                                 bool add)
+{
+       enum wl12xx_fw_type current_fw = wl->fw_type;
+       u8 vif_count = vif_counter_data.counter;
+
+       if (test_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags))
+               return false;
+
+       /* increase the vif count if this is a new vif */
+       if (add && !vif_counter_data.cur_vif_running)
+               vif_count++;
+
+       wl->last_vif_count = vif_count;
+
+       /* no need for fw change if the device is OFF */
+       if (wl->state == WL1271_STATE_OFF)
+               return false;
+
+       if (vif_count > 1 && current_fw == WL12XX_FW_TYPE_NORMAL)
+               return true;
+       if (vif_count <= 1 && current_fw == WL12XX_FW_TYPE_MULTI)
+               return true;
+
+       return false;
+}
+
+/*
+ * Enter "forced psm". Make sure the sta is in psm against the ap,
+ * to make the fw switch a bit more disconnection-persistent.
+ */
+static void wl12xx_force_active_psm(struct wl1271 *wl)
+{
+       struct wl12xx_vif *wlvif;
+
+       wl12xx_for_each_wlvif_sta(wl, wlvif) {
+               wl1271_ps_set_mode(wl, wlvif, STATION_POWER_SAVE_MODE);
+       }
+}
+
 static int wl1271_op_add_interface(struct ieee80211_hw *hw,
                                   struct ieee80211_vif *vif)
 {
        struct wl1271 *wl = hw->priv;
        struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
+       struct vif_counter_data vif_count;
        int ret = 0;
        u8 role_type;
        bool booted = false;
 
+       vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
+                            IEEE80211_VIF_SUPPORTS_CQM_RSSI;
+
        wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
                     ieee80211_vif_type_p2p(vif), vif->addr);
 
+       wl12xx_get_vif_count(hw, vif, &vif_count);
+
        mutex_lock(&wl->mutex);
        ret = wl1271_ps_elp_wakeup(wl);
        if (ret < 0)
                goto out_unlock;
 
-       if (wl->vif) {
-               wl1271_debug(DEBUG_MAC80211,
-                            "multiple vifs are not supported yet");
-               ret = -EBUSY;
-               goto out;
-       }
-
        /*
         * in some very corner case HW recovery scenarios its possible to
         * get here before __wl1271_op_remove_interface is complete, so
@@ -2086,6 +2210,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
                goto out;
        }
 
+
        ret = wl12xx_init_vif_data(wl, vif);
        if (ret < 0)
                goto out;
@@ -2097,6 +2222,14 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
                goto out;
        }
 
+       if (wl12xx_need_fw_change(wl, vif_count, true)) {
+               wl12xx_force_active_psm(wl);
+               set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
+               mutex_unlock(&wl->mutex);
+               wl1271_recovery_work(&wl->recovery_work);
+               return 0;
+       }
+
        /*
         * TODO: after the nvs issue will be solved, move this block
         * to start(), and make sure here the driver is ON.
@@ -2106,7 +2239,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
                 * we still need this in order to configure the fw
                 * while uploading the nvs
                 */
-               memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
+               memcpy(wl->addresses[0].addr, vif->addr, ETH_ALEN);
 
                booted = wl12xx_init_fw(wl);
                if (!booted) {
@@ -2139,7 +2272,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
        if (ret < 0)
                goto out;
 
-       wl->vif = vif;
        list_add(&wlvif->list, &wl->wlvif_list);
        set_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags);
 
@@ -2152,11 +2284,6 @@ out:
 out_unlock:
        mutex_unlock(&wl->mutex);
 
-       mutex_lock(&wl_list_mutex);
-       if (!ret)
-               list_add(&wl->list, &wl_list);
-       mutex_unlock(&wl_list_mutex);
-
        return ret;
 }
 
@@ -2172,20 +2299,20 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
        if (!test_and_clear_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
                return;
 
-       wl->vif = NULL;
-
        /* because of hardware recovery, we may get here twice */
        if (wl->state != WL1271_STATE_ON)
                return;
 
        wl1271_info("down");
 
-       /* enable dyn ps just in case (if left on due to fw crash etc) */
-       if (wlvif->bss_type == BSS_TYPE_STA_BSS)
-               ieee80211_enable_dyn_ps(vif);
-
        if (wl->scan.state != WL1271_SCAN_STATE_IDLE &&
            wl->scan_vif == vif) {
+               /*
+                * Rearm the tx watchdog just before idling scan. This
+                * prevents just-finished scans from triggering the watchdog
+                */
+               wl12xx_rearm_tx_watchdog_locked(wl);
+
                wl->scan.state = WL1271_SCAN_STATE_IDLE;
                memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
                wl->scan_vif = NULL;
@@ -2250,10 +2377,10 @@ deinit:
                wl->sta_count--;
 
        mutex_unlock(&wl->mutex);
+
        del_timer_sync(&wlvif->rx_streaming_timer);
        cancel_work_sync(&wlvif->rx_streaming_enable_work);
        cancel_work_sync(&wlvif->rx_streaming_disable_work);
-       cancel_delayed_work_sync(&wlvif->pspoll_work);
 
        mutex_lock(&wl->mutex);
 }
@@ -2264,7 +2391,10 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
        struct wl1271 *wl = hw->priv;
        struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
        struct wl12xx_vif *iter;
+       struct vif_counter_data vif_count;
+       bool cancel_recovery = true;
 
+       wl12xx_get_vif_count(hw, vif, &vif_count);
        mutex_lock(&wl->mutex);
 
        if (wl->state == WL1271_STATE_OFF ||
@@ -2283,20 +2413,34 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
                break;
        }
        WARN_ON(iter != wlvif);
+       if (wl12xx_need_fw_change(wl, vif_count, false)) {
+               wl12xx_force_active_psm(wl);
+               set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
+               wl12xx_queue_recovery_work(wl);
+               cancel_recovery = false;
+       }
 out:
        mutex_unlock(&wl->mutex);
-       cancel_work_sync(&wl->recovery_work);
+       if (cancel_recovery)
+               cancel_work_sync(&wl->recovery_work);
 }
 
 static int wl12xx_op_change_interface(struct ieee80211_hw *hw,
                                      struct ieee80211_vif *vif,
                                      enum nl80211_iftype new_type, bool p2p)
 {
+       struct wl1271 *wl = hw->priv;
+       int ret;
+
+       set_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags);
        wl1271_op_remove_interface(hw, vif);
 
-       vif->type = ieee80211_iftype_p2p(new_type, p2p);
+       vif->type = new_type;
        vif->p2p = p2p;
-       return wl1271_op_add_interface(hw, vif);
+       ret = wl1271_op_add_interface(hw, vif);
+
+       clear_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags);
+       return ret;
 }
 
 static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif,
@@ -2317,6 +2461,9 @@ static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif,
        if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
                wl1271_info("JOIN while associated.");
 
+       /* clear encryption type */
+       wlvif->encryption_type = KEY_NONE;
+
        if (set_assoc)
                set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags);
 
@@ -2467,71 +2614,61 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                                wl1271_warning("rate policy for channel "
                                               "failed %d", ret);
 
-                       if (test_bit(WLVIF_FLAG_STA_ASSOCIATED,
-                                    &wlvif->flags)) {
-                               if (wl12xx_dev_role_started(wlvif)) {
-                                       /* roaming */
-                                       ret = wl12xx_croc(wl,
-                                                         wlvif->dev_role_id);
-                                       if (ret < 0)
-                                               return ret;
-                               }
-                               ret = wl1271_join(wl, wlvif, false);
+                       /*
+                        * change the ROC channel. do it only if we are
+                        * not idle. otherwise, CROC will be called
+                        * anyway.
+                        */
+                       if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED,
+                                     &wlvif->flags) &&
+                           wl12xx_dev_role_started(wlvif) &&
+                           !(conf->flags & IEEE80211_CONF_IDLE)) {
+                               ret = wl12xx_stop_dev(wl, wlvif);
                                if (ret < 0)
-                                       wl1271_warning("cmd join on channel "
-                                                      "failed %d", ret);
-                       } else {
-                               /*
-                                * change the ROC channel. do it only if we are
-                                * not idle. otherwise, CROC will be called
-                                * anyway.
-                                */
-                               if (wl12xx_dev_role_started(wlvif) &&
-                                   !(conf->flags & IEEE80211_CONF_IDLE)) {
-                                       ret = wl12xx_stop_dev(wl, wlvif);
-                                       if (ret < 0)
-                                               return ret;
+                                       return ret;
 
-                                       ret = wl12xx_start_dev(wl, wlvif);
-                                       if (ret < 0)
-                                               return ret;
-                               }
+                               ret = wl12xx_start_dev(wl, wlvif);
+                               if (ret < 0)
+                                       return ret;
                        }
                }
        }
 
-       /*
-        * if mac80211 changes the PSM mode, make sure the mode is not
-        * incorrectly changed after the pspoll failure active window.
-        */
-       if (changed & IEEE80211_CONF_CHANGE_PS)
-               clear_bit(WLVIF_FLAG_PSPOLL_FAILURE, &wlvif->flags);
+       if ((changed & IEEE80211_CONF_CHANGE_PS) && !is_ap) {
 
-       if (conf->flags & IEEE80211_CONF_PS &&
-           !test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags)) {
-               set_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags);
+               if ((conf->flags & IEEE80211_CONF_PS) &&
+                   test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
+                   !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
 
-               /*
-                * We enter PSM only if we're already associated.
-                * If we're not, we'll enter it when joining an SSID,
-                * through the bss_info_changed() hook.
-                */
-               if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
-                       wl1271_debug(DEBUG_PSM, "psm enabled");
-                       ret = wl1271_ps_set_mode(wl, wlvif,
-                                                STATION_POWER_SAVE_MODE,
-                                                wlvif->basic_rate, true);
-               }
-       } else if (!(conf->flags & IEEE80211_CONF_PS) &&
-                  test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags)) {
-               wl1271_debug(DEBUG_PSM, "psm disabled");
+                       int ps_mode;
+                       char *ps_mode_str;
+
+                       if (wl->conf.conn.forced_ps) {
+                               ps_mode = STATION_POWER_SAVE_MODE;
+                               ps_mode_str = "forced";
+                       } else {
+                               ps_mode = STATION_AUTO_PS_MODE;
+                               ps_mode_str = "auto";
+                       }
+
+                       wl1271_debug(DEBUG_PSM, "%s ps enabled", ps_mode_str);
+
+                       ret = wl1271_ps_set_mode(wl, wlvif, ps_mode);
 
-               clear_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags);
+                       if (ret < 0)
+                               wl1271_warning("enter %s ps failed %d",
+                                              ps_mode_str, ret);
+
+               } else if (!(conf->flags & IEEE80211_CONF_PS) &&
+                          test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
+
+                       wl1271_debug(DEBUG_PSM, "auto ps disabled");
 
-               if (test_bit(WLVIF_FLAG_PSM, &wlvif->flags))
                        ret = wl1271_ps_set_mode(wl, wlvif,
-                                                STATION_ACTIVE_MODE,
-                                                wlvif->basic_rate, true);
+                                                STATION_ACTIVE_MODE);
+                       if (ret < 0)
+                               wl1271_warning("exit auto ps failed %d", ret);
+               }
        }
 
        if (conf->power_level != wlvif->power_level) {
@@ -2971,6 +3108,21 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                        wl1271_error("Could not add or replace key");
                        goto out_sleep;
                }
+
+               /*
+                * reconfiguring arp response if the unicast (or common)
+                * encryption key type was changed
+                */
+               if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
+                   (sta || key_type == KEY_WEP) &&
+                   wlvif->encryption_type != key_type) {
+                       wlvif->encryption_type = key_type;
+                       ret = wl1271_cmd_build_arp_rsp(wl, wlvif);
+                       if (ret < 0) {
+                               wl1271_warning("build arp rsp failed: %d", ret);
+                               goto out_sleep;
+                       }
+               }
                break;
 
        case DISABLE_KEY:
@@ -3004,8 +3156,6 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
                             struct cfg80211_scan_request *req)
 {
        struct wl1271 *wl = hw->priv;
-       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
-
        int ret;
        u8 *ssid = NULL;
        size_t len = 0;
@@ -3033,17 +3183,13 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
        if (ret < 0)
                goto out;
 
-       if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
-           test_bit(wlvif->role_id, wl->roc_map)) {
+       /* fail if there is any role in ROC */
+       if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) {
                /* don't allow scanning right now */
                ret = -EBUSY;
                goto out_sleep;
        }
 
-       /* cancel ROC before scanning */
-       if (wl12xx_dev_role_started(wlvif))
-               wl12xx_stop_dev(wl, wlvif);
-
        ret = wl1271_scan(hw->priv, vif, ssid, len, req);
 out_sleep:
        wl1271_ps_elp_sleep(wl);
@@ -3078,6 +3224,13 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
                if (ret < 0)
                        goto out_sleep;
        }
+
+       /*
+        * Rearm the tx watchdog just before idling scan. This
+        * prevents just-finished scans from triggering the watchdog
+        */
+       wl12xx_rearm_tx_watchdog_locked(wl);
+
        wl->scan.state = WL1271_SCAN_STATE_IDLE;
        memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
        wl->scan_vif = NULL;
@@ -3105,6 +3258,11 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
 
        mutex_lock(&wl->mutex);
 
+       if (wl->state == WL1271_STATE_OFF) {
+               ret = -EAGAIN;
+               goto out;
+       }
+
        ret = wl1271_ps_elp_wakeup(wl);
        if (ret < 0)
                goto out;
@@ -3136,6 +3294,9 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
 
        mutex_lock(&wl->mutex);
 
+       if (wl->state == WL1271_STATE_OFF)
+               goto out;
+
        ret = wl1271_ps_elp_wakeup(wl);
        if (ret < 0)
                goto out;
@@ -3263,6 +3424,7 @@ static void wl12xx_remove_vendor_ie(struct sk_buff *skb,
 static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates,
                                         struct ieee80211_vif *vif)
 {
+       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
        struct sk_buff *skb;
        int ret;
 
@@ -3270,7 +3432,7 @@ static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates,
        if (!skb)
                return -EOPNOTSUPP;
 
-       ret = wl1271_cmd_template_set(wl,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
                                      CMD_TEMPL_AP_PROBE_RESPONSE,
                                      skb->data,
                                      skb->len, 0,
@@ -3294,7 +3456,7 @@ static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl,
 
        /* no need to change probe response if the SSID is set correctly */
        if (wlvif->ssid_len > 0)
-               return wl1271_cmd_template_set(wl,
+               return wl1271_cmd_template_set(wl, wlvif->role_id,
                                               CMD_TEMPL_AP_PROBE_RESPONSE,
                                               probe_rsp_data,
                                               probe_rsp_len, 0,
@@ -3331,7 +3493,7 @@ static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl,
               ptr, probe_rsp_len - (ptr - probe_rsp_data));
        templ_len += probe_rsp_len - (ptr - probe_rsp_data);
 
-       return wl1271_cmd_template_set(wl,
+       return wl1271_cmd_template_set(wl, wlvif->role_id,
                                       CMD_TEMPL_AP_PROBE_RESPONSE,
                                       probe_rsp_templ,
                                       templ_len, 0,
@@ -3428,7 +3590,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
                min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
                tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
                                  CMD_TEMPL_BEACON;
-               ret = wl1271_cmd_template_set(wl, tmpl_id,
+               ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id,
                                              beacon->data,
                                              beacon->len, 0,
                                              min_rate);
@@ -3467,7 +3629,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
                                                beacon->len,
                                                min_rate);
                else
-                       ret = wl1271_cmd_template_set(wl,
+                       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
                                                CMD_TEMPL_PROBE_RESPONSE,
                                                beacon->data,
                                                beacon->len, 0,
@@ -3592,10 +3754,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
                        ibss_joined = true;
                } else {
                        if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED,
-                                              &wlvif->flags)) {
+                                              &wlvif->flags))
                                wl1271_unjoin(wl, wlvif);
-                               wl12xx_start_dev(wl, wlvif);
-                       }
                }
        }
 
@@ -3613,7 +3773,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
                do_join = true;
        }
 
-       if (changed & BSS_CHANGED_IDLE) {
+       if (changed & BSS_CHANGED_IDLE && !is_ibss) {
                ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle);
                if (ret < 0)
                        wl1271_warning("idle mode change failed %d", ret);
@@ -3631,7 +3791,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
                wlvif->rssi_thold = bss_conf->cqm_rssi_thold;
        }
 
-       if (changed & BSS_CHANGED_BSSID)
+       if (changed & BSS_CHANGED_BSSID &&
+           (is_ibss || bss_conf->assoc))
                if (!is_zero_ether_addr(bss_conf->bssid)) {
                        ret = wl12xx_cmd_build_null_data(wl, wlvif);
                        if (ret < 0)
@@ -3668,10 +3829,9 @@ sta_not_found:
                        u32 rates;
                        int ieoffset;
                        wlvif->aid = bss_conf->aid;
+                       wlvif->beacon_int = bss_conf->beacon_int;
                        set_assoc = true;
 
-                       wlvif->ps_poll_failures = 0;
-
                        /*
                         * use basic rates from AP, and determine lowest rate
                         * to use with control frames.
@@ -3731,9 +3891,6 @@ sta_not_found:
                        dev_kfree_skb(wlvif->probereq);
                        wlvif->probereq = NULL;
 
-                       /* re-enable dynamic ps - just in case */
-                       ieee80211_enable_dyn_ps(vif);
-
                        /* revert back to minimum rates for the current band */
                        wl1271_set_band_rate(wl, wlvif);
                        wlvif->basic_rate =
@@ -3753,7 +3910,6 @@ sta_not_found:
 
                        /* restore the bssid filter and go to dummy bssid */
                        if (was_assoc) {
-                               u32 conf_flags = wl->hw->conf.flags;
                                /*
                                 * we might have to disable roc, if there was
                                 * no IF_OPER_UP notification.
@@ -3776,7 +3932,7 @@ sta_not_found:
                                }
 
                                wl1271_unjoin(wl, wlvif);
-                               if (!(conf_flags & IEEE80211_CONF_IDLE))
+                               if (!bss_conf->idle)
                                        wl12xx_start_dev(wl, wlvif);
                        }
                }
@@ -3807,34 +3963,6 @@ sta_not_found:
        if (ret < 0)
                goto out;
 
-       if (changed & BSS_CHANGED_ARP_FILTER) {
-               __be32 addr = bss_conf->arp_addr_list[0];
-               WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS);
-
-               if (bss_conf->arp_addr_cnt == 1 &&
-                   bss_conf->arp_filter_enabled) {
-                       /*
-                        * The template should have been configured only upon
-                        * association. however, it seems that the correct ip
-                        * isn't being set (when sending), so we have to
-                        * reconfigure the template upon every ip change.
-                        */
-                       ret = wl1271_cmd_build_arp_rsp(wl, wlvif, addr);
-                       if (ret < 0) {
-                               wl1271_warning("build arp rsp failed: %d", ret);
-                               goto out;
-                       }
-
-                       ret = wl1271_acx_arp_ip_filter(wl, wlvif,
-                               ACX_ARP_FILTER_ARP_FILTERING,
-                               addr);
-               } else
-                       ret = wl1271_acx_arp_ip_filter(wl, wlvif, 0, addr);
-
-               if (ret < 0)
-                       goto out;
-       }
-
        if (do_join) {
                ret = wl1271_join(wl, wlvif, set_assoc);
                if (ret < 0) {
@@ -3848,8 +3976,8 @@ sta_not_found:
                        if (ret < 0)
                                goto out;
 
-                       wl1271_check_operstate(wl, wlvif,
-                                              ieee80211_get_operstate(vif));
+                       if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags))
+                               wl12xx_set_authorized(wl, wlvif);
                }
                /*
                 * stop device role if started (we might already be in
@@ -3860,19 +3988,6 @@ sta_not_found:
                        if (ret < 0)
                                goto out;
                }
-
-               /* If we want to go in PSM but we're not there yet */
-               if (test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags) &&
-                   !test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {
-                       enum wl1271_cmd_ps_mode mode;
-
-                       mode = STATION_POWER_SAVE_MODE;
-                       ret = wl1271_ps_set_mode(wl, wlvif, mode,
-                                                wlvif->basic_rate,
-                                                true);
-                       if (ret < 0)
-                               goto out;
-               }
        }
 
        /* Handle new association with HT. Do this after join. */
@@ -3914,6 +4029,41 @@ sta_not_found:
                }
        }
 
+       /* Handle arp filtering. Done after join. */
+       if ((changed & BSS_CHANGED_ARP_FILTER) ||
+           (!is_ibss && (changed & BSS_CHANGED_QOS))) {
+               __be32 addr = bss_conf->arp_addr_list[0];
+               wlvif->sta.qos = bss_conf->qos;
+               WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS);
+
+               if (bss_conf->arp_addr_cnt == 1 &&
+                   bss_conf->arp_filter_enabled) {
+                       wlvif->ip_addr = addr;
+                       /*
+                        * The template should have been configured only upon
+                        * association. however, it seems that the correct ip
+                        * isn't being set (when sending), so we have to
+                        * reconfigure the template upon every ip change.
+                        */
+                       ret = wl1271_cmd_build_arp_rsp(wl, wlvif);
+                       if (ret < 0) {
+                               wl1271_warning("build arp rsp failed: %d", ret);
+                               goto out;
+                       }
+
+                       ret = wl1271_acx_arp_ip_filter(wl, wlvif,
+                               (ACX_ARP_FILTER_ARP_FILTERING |
+                                ACX_ARP_FILTER_AUTO_ARP),
+                               addr);
+               } else {
+                       wlvif->ip_addr = 0;
+                       ret = wl1271_acx_arp_ip_filter(wl, wlvif, 0, addr);
+               }
+
+               if (ret < 0)
+                       goto out;
+       }
+
 out:
        return;
 }
@@ -4009,6 +4159,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
 {
 
        struct wl1271 *wl = hw->priv;
+       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
        u64 mactime = ULLONG_MAX;
        int ret;
 
@@ -4023,7 +4174,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
        if (ret < 0)
                goto out;
 
-       ret = wl1271_acx_tsf_info(wl, &mactime);
+       ret = wl12xx_acx_tsf_info(wl, wlvif, &mactime);
        if (ret < 0)
                goto out_sleep;
 
@@ -4085,107 +4236,155 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
        clear_bit(hlid, wlvif->ap.sta_hlid_map);
        memset(wl->links[hlid].addr, 0, ETH_ALEN);
        wl->links[hlid].ba_bitmap = 0;
-       wl1271_tx_reset_link_queues(wl, hlid);
        __clear_bit(hlid, &wl->ap_ps_map);
        __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
        wl12xx_free_link(wl, wlvif, &hlid);
        wl->active_sta_count--;
+
+       /*
+        * rearm the tx watchdog when the last STA is freed - give the FW a
+        * chance to return STA-buffered packets before complaining.
+        */
+       if (wl->active_sta_count == 0)
+               wl12xx_rearm_tx_watchdog_locked(wl);
 }
 
-static int wl1271_op_sta_add(struct ieee80211_hw *hw,
-                            struct ieee80211_vif *vif,
-                            struct ieee80211_sta *sta)
+static int wl12xx_sta_add(struct wl1271 *wl,
+                         struct wl12xx_vif *wlvif,
+                         struct ieee80211_sta *sta)
 {
-       struct wl1271 *wl = hw->priv;
-       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
        struct wl1271_station *wl_sta;
        int ret = 0;
        u8 hlid;
 
-       mutex_lock(&wl->mutex);
-
-       if (unlikely(wl->state == WL1271_STATE_OFF))
-               goto out;
-
-       if (wlvif->bss_type != BSS_TYPE_AP_BSS)
-               goto out;
-
        wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid);
 
        ret = wl1271_allocate_sta(wl, wlvif, sta);
        if (ret < 0)
-               goto out;
+               return ret;
 
        wl_sta = (struct wl1271_station *)sta->drv_priv;
        hlid = wl_sta->hlid;
 
-       ret = wl1271_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out_free_sta;
-
        ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid);
        if (ret < 0)
-               goto out_sleep;
+               wl1271_free_sta(wl, wlvif, hlid);
 
-       ret = wl12xx_cmd_set_peer_state(wl, hlid);
-       if (ret < 0)
-               goto out_sleep;
+       return ret;
+}
 
-       ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, hlid);
-       if (ret < 0)
-               goto out_sleep;
+static int wl12xx_sta_remove(struct wl1271 *wl,
+                            struct wl12xx_vif *wlvif,
+                            struct ieee80211_sta *sta)
+{
+       struct wl1271_station *wl_sta;
+       int ret = 0, id;
 
-out_sleep:
-       wl1271_ps_elp_sleep(wl);
+       wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid);
+
+       wl_sta = (struct wl1271_station *)sta->drv_priv;
+       id = wl_sta->hlid;
+       if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map)))
+               return -EINVAL;
 
-out_free_sta:
+       ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid);
        if (ret < 0)
-               wl1271_free_sta(wl, wlvif, hlid);
+               return ret;
 
-out:
-       mutex_unlock(&wl->mutex);
+       wl1271_free_sta(wl, wlvif, wl_sta->hlid);
        return ret;
 }
 
-static int wl1271_op_sta_remove(struct ieee80211_hw *hw,
-                               struct ieee80211_vif *vif,
-                               struct ieee80211_sta *sta)
+static int wl12xx_update_sta_state(struct wl1271 *wl,
+                                  struct wl12xx_vif *wlvif,
+                                  struct ieee80211_sta *sta,
+                                  enum ieee80211_sta_state old_state,
+                                  enum ieee80211_sta_state new_state)
 {
-       struct wl1271 *wl = hw->priv;
-       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
        struct wl1271_station *wl_sta;
-       int ret = 0, id;
+       u8 hlid;
+       bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
+       bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
+       int ret;
 
-       mutex_lock(&wl->mutex);
+       wl_sta = (struct wl1271_station *)sta->drv_priv;
+       hlid = wl_sta->hlid;
 
-       if (unlikely(wl->state == WL1271_STATE_OFF))
-               goto out;
+       /* Add station (AP mode) */
+       if (is_ap &&
+           old_state == IEEE80211_STA_NOTEXIST &&
+           new_state == IEEE80211_STA_NONE)
+               return wl12xx_sta_add(wl, wlvif, sta);
+
+       /* Remove station (AP mode) */
+       if (is_ap &&
+           old_state == IEEE80211_STA_NONE &&
+           new_state == IEEE80211_STA_NOTEXIST) {
+               /* must not fail */
+               wl12xx_sta_remove(wl, wlvif, sta);
+               return 0;
+       }
 
-       if (wlvif->bss_type != BSS_TYPE_AP_BSS)
-               goto out;
+       /* Authorize station (AP mode) */
+       if (is_ap &&
+           new_state == IEEE80211_STA_AUTHORIZED) {
+               ret = wl12xx_cmd_set_peer_state(wl, hlid);
+               if (ret < 0)
+                       return ret;
 
-       wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid);
+               ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true,
+                                                    hlid);
+               return ret;
+       }
 
-       wl_sta = (struct wl1271_station *)sta->drv_priv;
-       id = wl_sta->hlid;
-       if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map)))
+       /* Authorize station */
+       if (is_sta &&
+           new_state == IEEE80211_STA_AUTHORIZED) {
+               set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
+               return wl12xx_set_authorized(wl, wlvif);
+       }
+
+       if (is_sta &&
+           old_state == IEEE80211_STA_AUTHORIZED &&
+           new_state == IEEE80211_STA_ASSOC) {
+               clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
+               return 0;
+       }
+
+       return 0;
+}
+
+static int wl12xx_op_sta_state(struct ieee80211_hw *hw,
+                              struct ieee80211_vif *vif,
+                              struct ieee80211_sta *sta,
+                              enum ieee80211_sta_state old_state,
+                              enum ieee80211_sta_state new_state)
+{
+       struct wl1271 *wl = hw->priv;
+       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
+       int ret;
+
+       wl1271_debug(DEBUG_MAC80211, "mac80211 sta %d state=%d->%d",
+                    sta->aid, old_state, new_state);
+
+       mutex_lock(&wl->mutex);
+
+       if (unlikely(wl->state == WL1271_STATE_OFF)) {
+               ret = -EBUSY;
                goto out;
+       }
 
        ret = wl1271_ps_elp_wakeup(wl);
        if (ret < 0)
                goto out;
 
-       ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid);
-       if (ret < 0)
-               goto out_sleep;
+       ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state);
 
-       wl1271_free_sta(wl, wlvif, wl_sta->hlid);
-
-out_sleep:
        wl1271_ps_elp_sleep(wl);
-
 out:
        mutex_unlock(&wl->mutex);
+       if (new_state < old_state)
+               return 0;
        return ret;
 }
 
@@ -4354,6 +4553,8 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
 
        wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch");
 
+       wl1271_tx_flush(wl);
+
        mutex_lock(&wl->mutex);
 
        if (unlikely(wl->state == WL1271_STATE_OFF)) {
@@ -4370,7 +4571,7 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
 
        /* TODO: change mac80211 to pass vif as param */
        wl12xx_for_each_wlvif_sta(wl, wlvif) {
-               ret = wl12xx_cmd_channel_switch(wl, ch_switch);
+               ret = wl12xx_cmd_channel_switch(wl, wlvif, ch_switch);
 
                if (!ret)
                        set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
@@ -4464,6 +4665,7 @@ static struct ieee80211_channel wl1271_channels[] = {
 /* mapping to indexes for wl1271_rates */
 static const u8 wl1271_rate_to_idx_2ghz[] = {
        /* MCS rates are used only with 11n */
+       7,                            /* CONF_HW_RXTX_RATE_MCS7_SGI */
        7,                            /* CONF_HW_RXTX_RATE_MCS7 */
        6,                            /* CONF_HW_RXTX_RATE_MCS6 */
        5,                            /* CONF_HW_RXTX_RATE_MCS5 */
@@ -4585,6 +4787,7 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = {
 /* mapping to indexes for wl1271_rates_5ghz */
 static const u8 wl1271_rate_to_idx_5ghz[] = {
        /* MCS rates are used only with 11n */
+       7,                            /* CONF_HW_RXTX_RATE_MCS7_SGI */
        7,                            /* CONF_HW_RXTX_RATE_MCS7 */
        6,                            /* CONF_HW_RXTX_RATE_MCS6 */
        5,                            /* CONF_HW_RXTX_RATE_MCS5 */
@@ -4650,8 +4853,7 @@ static const struct ieee80211_ops wl1271_ops = {
        .conf_tx = wl1271_op_conf_tx,
        .get_tsf = wl1271_op_get_tsf,
        .get_survey = wl1271_op_get_survey,
-       .sta_add = wl1271_op_sta_add,
-       .sta_remove = wl1271_op_sta_remove,
+       .sta_state = wl12xx_op_sta_state,
        .ampdu_action = wl1271_op_ampdu_action,
        .tx_frames_pending = wl1271_tx_frames_pending,
        .set_bitrate_mask = wl12xx_set_bitrate_mask,
@@ -4825,13 +5027,120 @@ static struct bin_attribute fwlog_attr = {
        .read = wl1271_sysfs_read_fwlog,
 };
 
+static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
+{
+       bool supported = false;
+       u8 major, minor;
+
+       if (wl->chip.id == CHIP_ID_1283_PG20) {
+               major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
+               minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
+
+               /* in wl128x we have the MAC address if the PG is >= (2, 1) */
+               if (major > 2 || (major == 2 && minor >= 1))
+                       supported = true;
+       } else {
+               major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
+               minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
+
+               /* in wl127x we have the MAC address if the PG is >= (3, 1) */
+               if (major == 3 && minor >= 1)
+                       supported = true;
+       }
+
+       wl1271_debug(DEBUG_PROBE,
+                    "PG Ver major = %d minor = %d, MAC %s present",
+                    major, minor, supported ? "is" : "is not");
+
+       return supported;
+}
+
+static void wl12xx_derive_mac_addresses(struct wl1271 *wl,
+                                       u32 oui, u32 nic, int n)
+{
+       int i;
+
+       wl1271_debug(DEBUG_PROBE, "base address: oui %06x nic %06x, n %d",
+                    oui, nic, n);
+
+       if (nic + n - 1 > 0xffffff)
+               wl1271_warning("NIC part of the MAC address wraps around!");
+
+       for (i = 0; i < n; i++) {
+               wl->addresses[i].addr[0] = (u8)(oui >> 16);
+               wl->addresses[i].addr[1] = (u8)(oui >> 8);
+               wl->addresses[i].addr[2] = (u8) oui;
+               wl->addresses[i].addr[3] = (u8)(nic >> 16);
+               wl->addresses[i].addr[4] = (u8)(nic >> 8);
+               wl->addresses[i].addr[5] = (u8) nic;
+               nic++;
+       }
+
+       wl->hw->wiphy->n_addresses = n;
+       wl->hw->wiphy->addresses = wl->addresses;
+}
+
+static void wl12xx_get_fuse_mac(struct wl1271 *wl)
+{
+       u32 mac1, mac2;
+
+       wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]);
+
+       mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1);
+       mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2);
+
+       /* these are the two parts of the BD_ADDR */
+       wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
+               ((mac1 & 0xff000000) >> 24);
+       wl->fuse_nic_addr = mac1 & 0xffffff;
+
+       wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]);
+}
+
+static int wl12xx_get_hw_info(struct wl1271 *wl)
+{
+       int ret;
+       u32 die_info;
+
+       ret = wl12xx_set_power_on(wl);
+       if (ret < 0)
+               goto out;
+
+       wl->chip.id = wl1271_read32(wl, CHIP_ID_B);
+
+       if (wl->chip.id == CHIP_ID_1283_PG20)
+               die_info = wl1271_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1);
+       else
+               die_info = wl1271_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);
+
+       wl->hw_pg_ver = (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET;
+
+       if (!wl12xx_mac_in_fuse(wl)) {
+               wl->fuse_oui_addr = 0;
+               wl->fuse_nic_addr = 0;
+       } else {
+               wl12xx_get_fuse_mac(wl);
+       }
+
+       wl1271_power_off(wl);
+out:
+       return ret;
+}
+
 static int wl1271_register_hw(struct wl1271 *wl)
 {
        int ret;
+       u32 oui_addr = 0, nic_addr = 0;
 
        if (wl->mac80211_registered)
                return 0;
 
+       ret = wl12xx_get_hw_info(wl);
+       if (ret < 0) {
+               wl1271_error("couldn't get hw info");
+               goto out;
+       }
+
        ret = wl1271_fetch_nvs(wl);
        if (ret == 0) {
                /* NOTE: The wl->nvs->nvs element must be first, in
@@ -4840,39 +5149,42 @@ static int wl1271_register_hw(struct wl1271 *wl)
                 */
                u8 *nvs_ptr = (u8 *)wl->nvs;
 
-               wl->mac_addr[0] = nvs_ptr[11];
-               wl->mac_addr[1] = nvs_ptr[10];
-               wl->mac_addr[2] = nvs_ptr[6];
-               wl->mac_addr[3] = nvs_ptr[5];
-               wl->mac_addr[4] = nvs_ptr[4];
-               wl->mac_addr[5] = nvs_ptr[3];
+               oui_addr =
+                       (nvs_ptr[11] << 16) + (nvs_ptr[10] << 8) + nvs_ptr[6];
+               nic_addr =
+                       (nvs_ptr[5] << 16) + (nvs_ptr[4] << 8) + nvs_ptr[3];
        }
 
-       SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+       /* if the MAC address is zeroed in the NVS derive from fuse */
+       if (oui_addr == 0 && nic_addr == 0) {
+               oui_addr = wl->fuse_oui_addr;
+               /* fuse has the BD_ADDR, the WLAN addresses are the next two */
+               nic_addr = wl->fuse_nic_addr + 1;
+       }
+
+       wl12xx_derive_mac_addresses(wl, oui_addr, nic_addr, 2);
 
        ret = ieee80211_register_hw(wl->hw);
        if (ret < 0) {
                wl1271_error("unable to register mac80211 hw: %d", ret);
-               return ret;
+               goto out;
        }
 
        wl->mac80211_registered = true;
 
        wl1271_debugfs_init(wl);
 
-       register_netdevice_notifier(&wl1271_dev_notifier);
-
        wl1271_notice("loaded");
 
-       return 0;
+out:
+       return ret;
 }
 
 static void wl1271_unregister_hw(struct wl1271 *wl)
 {
-       if (wl->state == WL1271_STATE_PLT)
-               __wl1271_plt_stop(wl);
+       if (wl->plt)
+               wl1271_plt_stop(wl);
 
-       unregister_netdevice_notifier(&wl1271_dev_notifier);
        ieee80211_unregister_hw(wl->hw);
        wl->mac80211_registered = false;
 
@@ -4889,7 +5201,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
        };
 
        /* The tx descriptor buffer and the TKIP space. */
-       wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE +
+       wl->hw->extra_tx_headroom = WL1271_EXTRA_SPACE_TKIP +
                sizeof(struct wl1271_tx_hw_descr);
 
        /* unit us */
@@ -4898,17 +5210,17 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
        wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
 
        wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
-               IEEE80211_HW_BEACON_FILTER |
                IEEE80211_HW_SUPPORTS_PS |
+               IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
                IEEE80211_HW_SUPPORTS_UAPSD |
                IEEE80211_HW_HAS_RATE_CONTROL |
                IEEE80211_HW_CONNECTION_MONITOR |
-               IEEE80211_HW_SUPPORTS_CQM_RSSI |
                IEEE80211_HW_REPORTS_TX_ACK_STATUS |
                IEEE80211_HW_SPECTRUM_MGMT |
                IEEE80211_HW_AP_LINK_PS |
                IEEE80211_HW_AMPDU_AGGREGATION |
-               IEEE80211_HW_TX_AMPDU_SETUP_IN_HW;
+               IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
+               IEEE80211_HW_SCAN_WHILE_IDLE;
 
        wl->hw->wiphy->cipher_suites = cipher_suites;
        wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
@@ -4924,10 +5236,10 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
         * should be the maximum length possible for a template, without
         * the IEEE80211 header of the template
         */
-       wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE -
+       wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
                        sizeof(struct ieee80211_header);
 
-       wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE -
+       wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
                sizeof(struct ieee80211_header);
 
        wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
@@ -4993,7 +5305,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
        wl = hw->priv;
        memset(wl, 0, sizeof(*wl));
 
-       INIT_LIST_HEAD(&wl->list);
        INIT_LIST_HEAD(&wl->wlvif_list);
 
        wl->hw = hw;
@@ -5010,6 +5321,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
        INIT_WORK(&wl->tx_work, wl1271_tx_work);
        INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
        INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
+       INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work);
 
        wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
        if (!wl->freezable_wq) {
@@ -5021,7 +5333,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
        wl->rx_counter = 0;
        wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
        wl->band = IEEE80211_BAND_2GHZ;
-       wl->vif = NULL;
        wl->flags = 0;
        wl->sg_enabled = true;
        wl->hw_pg_ver = -1;
@@ -5046,6 +5357,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
        spin_lock_init(&wl->wl_lock);
 
        wl->state = WL1271_STATE_OFF;
+       wl->fw_type = WL12XX_FW_TYPE_NONE;
        mutex_init(&wl->mutex);
 
        /* Apply default driver configuration. */
@@ -5113,6 +5425,7 @@ static int wl1271_free_hw(struct wl1271 *wl)
 
        vfree(wl->fw);
        wl->fw = NULL;
+       wl->fw_type = WL12XX_FW_TYPE_NONE;
        kfree(wl->nvs);
        wl->nvs = NULL;
 
@@ -5299,7 +5612,7 @@ module_param_named(debug_level, wl12xx_debug_level, uint, S_IRUSR | S_IWUSR);
 MODULE_PARM_DESC(debug_level, "wl12xx debugging level");
 
 module_param_named(fwlog, fwlog_param, charp, 0);
-MODULE_PARM_DESC(keymap,
+MODULE_PARM_DESC(fwlog,
                 "FW logger options: continuous, ondemand, dbgpins or disable");
 
 module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR);
index a2bdacdd7e1dd742ae9398ef70c1d2eb1c8037d2..78f598b4f97b977cbc747a0bd93b0877bc900ff0 100644 (file)
@@ -56,7 +56,7 @@ void wl1271_elp_work(struct work_struct *work)
                if (wlvif->bss_type == BSS_TYPE_AP_BSS)
                        goto out;
 
-               if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) &&
+               if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
                    test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
                        goto out;
        }
@@ -69,8 +69,6 @@ out:
        mutex_unlock(&wl->mutex);
 }
 
-#define ELP_ENTRY_DELAY  5
-
 /* Routines to toggle sleep mode while in ELP */
 void wl1271_ps_elp_sleep(struct wl1271 *wl)
 {
@@ -84,13 +82,13 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
                if (wlvif->bss_type == BSS_TYPE_AP_BSS)
                        return;
 
-               if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) &&
+               if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
                    test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
                        return;
        }
 
        ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
-                                    msecs_to_jiffies(ELP_ENTRY_DELAY));
+               msecs_to_jiffies(wl->conf.conn.dynamic_ps_timeout));
 }
 
 int wl1271_ps_elp_wakeup(struct wl1271 *wl)
@@ -160,28 +158,39 @@ out:
 }
 
 int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-                      enum wl1271_cmd_ps_mode mode, u32 rates, bool send)
+                      enum wl1271_cmd_ps_mode mode)
 {
        int ret;
+       u16 timeout = wl->conf.conn.dynamic_ps_timeout;
 
        switch (mode) {
+       case STATION_AUTO_PS_MODE:
        case STATION_POWER_SAVE_MODE:
-               wl1271_debug(DEBUG_PSM, "entering psm");
+               wl1271_debug(DEBUG_PSM, "entering psm (mode=%d,timeout=%u)",
+                            mode, timeout);
 
-               ret = wl1271_acx_wake_up_conditions(wl, wlvif);
+               ret = wl1271_acx_wake_up_conditions(wl, wlvif,
+                                           wl->conf.conn.wake_up_event,
+                                           wl->conf.conn.listen_interval);
                if (ret < 0) {
                        wl1271_error("couldn't set wake up conditions");
                        return ret;
                }
 
-               ret = wl1271_cmd_ps_mode(wl, wlvif, STATION_POWER_SAVE_MODE);
+               ret = wl1271_cmd_ps_mode(wl, wlvif, mode, timeout);
                if (ret < 0)
                        return ret;
 
-               set_bit(WLVIF_FLAG_PSM, &wlvif->flags);
+               set_bit(WLVIF_FLAG_IN_PS, &wlvif->flags);
+
+               /* enable beacon early termination. Not relevant for 5GHz */
+               if (wlvif->band == IEEE80211_BAND_2GHZ) {
+                       ret = wl1271_acx_bet_enable(wl, wlvif, true);
+                       if (ret < 0)
+                               return ret;
+               }
                break;
        case STATION_ACTIVE_MODE:
-       default:
                wl1271_debug(DEBUG_PSM, "leaving psm");
 
                /* disable beacon early termination */
@@ -191,12 +200,15 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                                return ret;
                }
 
-               ret = wl1271_cmd_ps_mode(wl, wlvif, STATION_ACTIVE_MODE);
+               ret = wl1271_cmd_ps_mode(wl, wlvif, mode, 0);
                if (ret < 0)
                        return ret;
 
-               clear_bit(WLVIF_FLAG_PSM, &wlvif->flags);
+               clear_bit(WLVIF_FLAG_IN_PS, &wlvif->flags);
                break;
+       default:
+               wl1271_warning("trying to set ps to unsupported mode %d", mode);
+               ret = -EINVAL;
        }
 
        return ret;
index a12052f02026fba0a943258913cb7ad099254f75..5f19d4fbbf27e88345dd7d4fb406d1ad37e2bf0b 100644 (file)
@@ -28,7 +28,7 @@
 #include "acx.h"
 
 int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-                      enum wl1271_cmd_ps_mode mode, u32 rates, bool send);
+                      enum wl1271_cmd_ps_mode mode);
 void wl1271_ps_elp_sleep(struct wl1271 *wl);
 int wl1271_ps_elp_wakeup(struct wl1271 *wl);
 void wl1271_elp_work(struct work_struct *work);
index df34d5977b98581a2e4b321665a9d0de0dc00398..340db324bc26016933b68afe8abb031d2302513d 100644 (file)
@@ -525,4 +525,31 @@ b12-b0 - Supported Rate indicator bits as defined below.
  */
 #define INTR_TRIG_TX_PROC1 BIT(18)
 
+#define WL127X_REG_FUSE_DATA_2_1       0x050a
+#define WL128X_REG_FUSE_DATA_2_1       0x2152
+#define PG_VER_MASK                    0x3c
+#define PG_VER_OFFSET                  2
+
+#define WL127X_PG_MAJOR_VER_MASK       0x3
+#define WL127X_PG_MAJOR_VER_OFFSET     0x0
+#define WL127X_PG_MINOR_VER_MASK       0xc
+#define WL127X_PG_MINOR_VER_OFFSET     0x2
+
+#define WL128X_PG_MAJOR_VER_MASK       0xc
+#define WL128X_PG_MAJOR_VER_OFFSET     0x2
+#define WL128X_PG_MINOR_VER_MASK       0x3
+#define WL128X_PG_MINOR_VER_OFFSET     0x0
+
+#define WL127X_PG_GET_MAJOR(pg_ver) ((pg_ver & WL127X_PG_MAJOR_VER_MASK) >> \
+                                    WL127X_PG_MAJOR_VER_OFFSET)
+#define WL127X_PG_GET_MINOR(pg_ver) ((pg_ver & WL127X_PG_MINOR_VER_MASK) >> \
+                                    WL127X_PG_MINOR_VER_OFFSET)
+#define WL128X_PG_GET_MAJOR(pg_ver) ((pg_ver & WL128X_PG_MAJOR_VER_MASK) >> \
+                                    WL128X_PG_MAJOR_VER_OFFSET)
+#define WL128X_PG_GET_MINOR(pg_ver) ((pg_ver & WL128X_PG_MINOR_VER_MASK) >> \
+                                    WL128X_PG_MINOR_VER_OFFSET)
+
+#define WL12XX_REG_FUSE_BD_ADDR_1      0x00310eb4
+#define WL12XX_REG_FUSE_BD_ADDR_2      0x00310eb8
+
 #endif
index 4fbd2a722ffabf28eb4f3c383490b2060c1535dc..cfa6071704c591d3be1100b469a140302da95489 100644 (file)
@@ -113,7 +113,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
         * In PLT mode we seem to get frames and mac80211 warns about them,
         * workaround this by not retrieving them at all.
         */
-       if (unlikely(wl->state == WL1271_STATE_PLT))
+       if (unlikely(wl->plt))
                return -EINVAL;
 
        /* the data read starts with the descriptor */
index e24111ececc5c64ba40cf87133b1193b93b0aaa5..fcba055ef196a050023796152d66cafb550c68e2 100644 (file)
@@ -38,7 +38,6 @@ void wl1271_scan_complete_work(struct work_struct *work)
        struct ieee80211_vif *vif;
        struct wl12xx_vif *wlvif;
        int ret;
-       bool is_sta, is_ibss;
 
        dwork = container_of(work, struct delayed_work, work);
        wl = container_of(dwork, struct wl1271, scan_complete_work);
@@ -56,6 +55,12 @@ void wl1271_scan_complete_work(struct work_struct *work)
        vif = wl->scan_vif;
        wlvif = wl12xx_vif_to_data(vif);
 
+       /*
+        * Rearm the tx watchdog just before idling scan. This
+        * prevents just-finished scans from triggering the watchdog
+        */
+       wl12xx_rearm_tx_watchdog_locked(wl);
+
        wl->scan.state = WL1271_SCAN_STATE_IDLE;
        memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
        wl->scan.req = NULL;
@@ -70,15 +75,6 @@ void wl1271_scan_complete_work(struct work_struct *work)
                wl1271_cmd_build_ap_probe_req(wl, wlvif, wlvif->probereq);
        }
 
-       /* return to ROC if needed */
-       is_sta = (wlvif->bss_type == BSS_TYPE_STA_BSS);
-       is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
-       if (((is_sta && !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) ||
-            (is_ibss && !test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags))) &&
-           !test_bit(wlvif->dev_role_id, wl->roc_map)) {
-               /* restore remain on channel */
-               wl12xx_start_dev(wl, wlvif);
-       }
        wl1271_ps_elp_sleep(wl);
 
        if (wl->scan.failed) {
@@ -182,14 +178,23 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
                goto out;
        }
 
+       if (wl->conf.scan.split_scan_timeout)
+               scan_options |= WL1271_SCAN_OPT_SPLIT_SCAN;
+
        if (passive)
                scan_options |= WL1271_SCAN_OPT_PASSIVE;
 
-       if (WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID)) {
+       if (wlvif->bss_type == BSS_TYPE_AP_BSS ||
+           test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+               cmd->params.role_id = wlvif->role_id;
+       else
+               cmd->params.role_id = wlvif->dev_role_id;
+
+       if (WARN_ON(cmd->params.role_id == WL12XX_INVALID_ROLE_ID)) {
                ret = -EINVAL;
                goto out;
        }
-       cmd->params.role_id = wlvif->role_id;
+
        cmd->params.scan_options = cpu_to_le16(scan_options);
 
        cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req,
@@ -202,7 +207,7 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
 
        cmd->params.tx_rate = cpu_to_le32(basic_rate);
        cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs;
-       cmd->params.tid_trigger = 0;
+       cmd->params.tid_trigger = CONF_TX_AC_ANY_TID;
        cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
 
        if (band == IEEE80211_BAND_2GHZ)
@@ -217,16 +222,17 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
 
        memcpy(cmd->addr, vif->addr, ETH_ALEN);
 
-       ret = wl1271_cmd_build_probe_req(wl, wlvif, wl->scan.ssid,
-                                        wl->scan.ssid_len, wl->scan.req->ie,
-                                        wl->scan.req->ie_len, band);
+       ret = wl12xx_cmd_build_probe_req(wl, wlvif,
+                                        cmd->params.role_id, band,
+                                        wl->scan.ssid, wl->scan.ssid_len,
+                                        wl->scan.req->ie,
+                                        wl->scan.req->ie_len);
        if (ret < 0) {
                wl1271_error("PROBE request template failed");
                goto out;
        }
 
-       /* disable the timeout */
-       trigger->timeout = 0;
+       trigger->timeout = cpu_to_le32(wl->conf.scan.split_scan_timeout);
        ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
                              sizeof(*trigger), 0);
        if (ret < 0) {
@@ -658,11 +664,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
        }
 
        if (!force_passive && cfg->active[0]) {
-               ret = wl1271_cmd_build_probe_req(wl, wlvif, req->ssids[0].ssid,
+               u8 band = IEEE80211_BAND_2GHZ;
+               ret = wl12xx_cmd_build_probe_req(wl, wlvif,
+                                                wlvif->dev_role_id, band,
+                                                req->ssids[0].ssid,
                                                 req->ssids[0].ssid_len,
-                                                ies->ie[IEEE80211_BAND_2GHZ],
-                                                ies->len[IEEE80211_BAND_2GHZ],
-                                                IEEE80211_BAND_2GHZ);
+                                                ies->ie[band],
+                                                ies->len[band]);
                if (ret < 0) {
                        wl1271_error("2.4GHz PROBE request template failed");
                        goto out;
@@ -670,11 +678,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
        }
 
        if (!force_passive && cfg->active[1]) {
-               ret = wl1271_cmd_build_probe_req(wl, wlvif, req->ssids[0].ssid,
+               u8 band = IEEE80211_BAND_5GHZ;
+               ret = wl12xx_cmd_build_probe_req(wl, wlvif,
+                                                wlvif->dev_role_id, band,
+                                                req->ssids[0].ssid,
                                                 req->ssids[0].ssid_len,
-                                                ies->ie[IEEE80211_BAND_5GHZ],
-                                                ies->len[IEEE80211_BAND_5GHZ],
-                                                IEEE80211_BAND_5GHZ);
+                                                ies->ie[band],
+                                                ies->len[band]);
                if (ret < 0) {
                        wl1271_error("5GHz PROBE request template failed");
                        goto out;
index a7ed43dc08c9e89217bc4430ca8b5b2b3ce2607a..96ff457a3a0bee224996788195d9fcdb49bdb31b 100644 (file)
@@ -48,7 +48,7 @@ void wl1271_scan_sched_scan_results(struct wl1271 *wl);
 #define WL1271_SCAN_CURRENT_TX_PWR     0
 #define WL1271_SCAN_OPT_ACTIVE         0
 #define WL1271_SCAN_OPT_PASSIVE               1
-#define WL1271_SCAN_OPT_TRIGGERED_SCAN 2
+#define WL1271_SCAN_OPT_SPLIT_SCAN     2
 #define WL1271_SCAN_OPT_PRIORITY_HIGH  4
 /* scan even if we fail to enter psm */
 #define WL1271_SCAN_OPT_FORCE          8
index 468a50553fac8f345e689432f82cd075d9413828..4b3c32774baee1978a45bb5ee95d62f0840a041c 100644 (file)
@@ -74,6 +74,8 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf,
        struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
        struct sdio_func *func = dev_to_sdio_func(glue->dev);
 
+       sdio_claim_host(func);
+
        if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
                ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
                dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n",
@@ -88,6 +90,8 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf,
                        addr, len);
        }
 
+       sdio_release_host(func);
+
        if (ret)
                dev_err(child->parent, "sdio read failed (%d)\n", ret);
 }
@@ -99,6 +103,8 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf,
        struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
        struct sdio_func *func = dev_to_sdio_func(glue->dev);
 
+       sdio_claim_host(func);
+
        if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
                sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
                dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n",
@@ -113,6 +119,8 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf,
                        ret = sdio_memcpy_toio(func, addr, buf, len);
        }
 
+       sdio_release_host(func);
+
        if (ret)
                dev_err(child->parent, "sdio write failed (%d)\n", ret);
 }
@@ -136,6 +144,7 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue)
 
        sdio_claim_host(func);
        sdio_enable_func(func);
+       sdio_release_host(func);
 
 out:
        return ret;
@@ -146,6 +155,7 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue)
        int ret;
        struct sdio_func *func = dev_to_sdio_func(glue->dev);
 
+       sdio_claim_host(func);
        sdio_disable_func(func);
        sdio_release_host(func);
 
@@ -314,9 +324,6 @@ static int wl1271_suspend(struct device *dev)
                        dev_err(dev, "error while trying to keep power\n");
                        goto out;
                }
-
-               /* release host */
-               sdio_release_host(func);
        }
 out:
        return ret;
@@ -324,15 +331,7 @@ out:
 
 static int wl1271_resume(struct device *dev)
 {
-       struct sdio_func *func = dev_to_sdio_func(dev);
-       struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
-       struct wl1271 *wl = platform_get_drvdata(glue->core);
-
        dev_dbg(dev, "wl1271 resume\n");
-       if (wl->wow_enabled) {
-               /* claim back host */
-               sdio_claim_host(func);
-       }
 
        return 0;
 }
@@ -371,5 +370,9 @@ module_exit(wl1271_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
-MODULE_FIRMWARE(WL127X_FW_NAME);
-MODULE_FIRMWARE(WL128X_FW_NAME);
+MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
+MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
+MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
+MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
+MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
+MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
index 92caa7ce6053efc1c36227553b03b05e61844cbe..2fc18a8dcce8329436805a38d0582578325a8368 100644 (file)
@@ -433,6 +433,10 @@ module_exit(wl1271_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
-MODULE_FIRMWARE(WL127X_FW_NAME);
-MODULE_FIRMWARE(WL128X_FW_NAME);
+MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
+MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
+MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
+MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
+MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
+MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
 MODULE_ALIAS("spi:wl1271");
index 25093c0cb0edf654ad04f603e3c1b7eb47603a1b..1e93bb9c0246cfa02e44f6160851909b422b14ec 100644 (file)
@@ -30,6 +30,7 @@
 #include "acx.h"
 #include "reg.h"
 #include "ps.h"
+#include "io.h"
 
 #define WL1271_TM_MAX_DATA_LENGTH 1024
 
@@ -41,6 +42,7 @@ enum wl1271_tm_commands {
        WL1271_TM_CMD_NVS_PUSH,         /* Not in use. Keep to not break ABI */
        WL1271_TM_CMD_SET_PLT_MODE,
        WL1271_TM_CMD_RECOVER,
+       WL1271_TM_CMD_GET_MAC,
 
        __WL1271_TM_CMD_AFTER_LAST
 };
@@ -264,6 +266,52 @@ static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[])
        return 0;
 }
 
+static int wl12xx_tm_cmd_get_mac(struct wl1271 *wl, struct nlattr *tb[])
+{
+       struct sk_buff *skb;
+       u8 mac_addr[ETH_ALEN];
+       int ret = 0;
+
+       mutex_lock(&wl->mutex);
+
+       if (!wl->plt) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (wl->fuse_oui_addr == 0 && wl->fuse_nic_addr == 0) {
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+
+       mac_addr[0] = (u8)(wl->fuse_oui_addr >> 16);
+       mac_addr[1] = (u8)(wl->fuse_oui_addr >> 8);
+       mac_addr[2] = (u8) wl->fuse_oui_addr;
+       mac_addr[3] = (u8)(wl->fuse_nic_addr >> 16);
+       mac_addr[4] = (u8)(wl->fuse_nic_addr >> 8);
+       mac_addr[5] = (u8) wl->fuse_nic_addr;
+
+       skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, ETH_ALEN);
+       if (!skb) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       NLA_PUT(skb, WL1271_TM_ATTR_DATA, ETH_ALEN, mac_addr);
+       ret = cfg80211_testmode_reply(skb);
+       if (ret < 0)
+               goto out;
+
+out:
+       mutex_unlock(&wl->mutex);
+       return ret;
+
+nla_put_failure:
+       kfree_skb(skb);
+       ret = -EMSGSIZE;
+       goto out;
+}
+
 int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
 {
        struct wl1271 *wl = hw->priv;
@@ -288,6 +336,8 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
                return wl1271_tm_cmd_set_plt_mode(wl, tb);
        case WL1271_TM_CMD_RECOVER:
                return wl1271_tm_cmd_recover(wl, tb);
+       case WL1271_TM_CMD_GET_MAC:
+               return wl12xx_tm_cmd_get_mac(wl, tb);
        default:
                return -EOPNOTSUPP;
        }
index 4508ccd78328017b173215fbfec69ea3a6c5c413..43ae49143d68bf47a4fa98c25f15b5d3b20cd3a9 100644 (file)
@@ -77,35 +77,6 @@ static void wl1271_free_tx_id(struct wl1271 *wl, int id)
        }
 }
 
-static int wl1271_tx_update_filters(struct wl1271 *wl,
-                                   struct wl12xx_vif *wlvif,
-                                   struct sk_buff *skb)
-{
-       struct ieee80211_hdr *hdr;
-       int ret;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-
-       /*
-        * stop bssid-based filtering before transmitting authentication
-        * requests. this way the hw will never drop authentication
-        * responses coming from BSSIDs it isn't familiar with (e.g. on
-        * roaming)
-        */
-       if (!ieee80211_is_auth(hdr->frame_control))
-               return 0;
-
-       if (wlvif->dev_hlid != WL12XX_INVALID_LINK_ID)
-               goto out;
-
-       wl1271_debug(DEBUG_CMD, "starting device role for roaming");
-       ret = wl12xx_start_dev(wl, wlvif);
-       if (ret < 0)
-               goto out;
-out:
-       return 0;
-}
-
 static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
                                                 struct sk_buff *skb)
 {
@@ -187,8 +158,6 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
        if (wlvif->bss_type == BSS_TYPE_AP_BSS)
                return wl12xx_tx_get_hlid_ap(wl, wlvif, skb);
 
-       wl1271_tx_update_filters(wl, wlvif, skb);
-
        if ((test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
             test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags)) &&
            !ieee80211_is_auth(hdr->frame_control) &&
@@ -257,6 +226,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                wl->tx_blocks_available -= total_blocks;
                wl->tx_allocated_blocks += total_blocks;
 
+               /* If the FW was empty before, arm the Tx watchdog */
+               if (wl->tx_allocated_blocks == total_blocks)
+                       wl12xx_rearm_tx_watchdog_locked(wl);
+
                ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
                wl->tx_allocated_pkts[ac]++;
 
@@ -286,16 +259,20 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
        int aligned_len, ac, rate_idx;
        s64 hosttime;
        u16 tx_attr = 0;
+       __le16 frame_control;
+       struct ieee80211_hdr *hdr;
+       u8 *frame_start;
        bool is_dummy;
 
        desc = (struct wl1271_tx_hw_descr *) skb->data;
+       frame_start = (u8 *)(desc + 1);
+       hdr = (struct ieee80211_hdr *)(frame_start + extra);
+       frame_control = hdr->frame_control;
 
        /* relocate space for security header */
        if (extra) {
-               void *framestart = skb->data + sizeof(*desc);
-               u16 fc = *(u16 *)(framestart + extra);
-               int hdrlen = ieee80211_hdrlen(cpu_to_le16(fc));
-               memmove(framestart, framestart + extra, hdrlen);
+               int hdrlen = ieee80211_hdrlen(frame_control);
+               memmove(frame_start, hdr, hdrlen);
        }
 
        /* configure packet life time */
@@ -384,6 +361,11 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                             desc->wl127x_mem.total_mem_blocks);
        }
 
+       /* for WEP shared auth - no fw encryption is needed */
+       if (ieee80211_is_auth(frame_control) &&
+           ieee80211_has_protected(frame_control))
+               tx_attr |= TX_HW_ATTR_HOST_ENCRYPT;
+
        desc->tx_attr = cpu_to_le16(tx_attr);
 }
 
@@ -408,7 +390,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 
        if (info->control.hw_key &&
            info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
-               extra = WL1271_TKIP_IV_SPACE;
+               extra = WL1271_EXTRA_SPACE_TKIP;
 
        if (info->control.hw_key) {
                bool is_wep;
@@ -549,6 +531,7 @@ static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl,
        if (skb) {
                int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
                spin_lock_irqsave(&wl->wl_lock, flags);
+               WARN_ON_ONCE(wl->tx_queue_count[q] <= 0);
                wl->tx_queue_count[q]--;
                spin_unlock_irqrestore(&wl->wl_lock, flags);
        }
@@ -593,6 +576,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
        struct wl12xx_vif *wlvif = wl->last_wlvif;
        struct sk_buff *skb = NULL;
 
+       /* continue from last wlvif (round robin) */
        if (wlvif) {
                wl12xx_for_each_wlvif_continue(wl, wlvif) {
                        skb = wl12xx_vif_skb_dequeue(wl, wlvif);
@@ -603,7 +587,11 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
                }
        }
 
-       /* do another pass */
+       /* dequeue from the system HLID before the restarting wlvif list */
+       if (!skb)
+               skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]);
+
+       /* do a new pass over the wlvif list */
        if (!skb) {
                wl12xx_for_each_wlvif(wl, wlvif) {
                        skb = wl12xx_vif_skb_dequeue(wl, wlvif);
@@ -611,12 +599,16 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
                                wl->last_wlvif = wlvif;
                                break;
                        }
+
+                       /*
+                        * No need to continue after last_wlvif. The previous
+                        * pass should have found it.
+                        */
+                       if (wlvif == wl->last_wlvif)
+                               break;
                }
        }
 
-       if (!skb)
-               skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]);
-
        if (!skb &&
            test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
                int q;
@@ -624,6 +616,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
                skb = wl->dummy_packet;
                q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
                spin_lock_irqsave(&wl->wl_lock, flags);
+               WARN_ON_ONCE(wl->tx_queue_count[q] <= 0);
                wl->tx_queue_count[q]--;
                spin_unlock_irqrestore(&wl->wl_lock, flags);
        }
@@ -795,6 +788,18 @@ out:
        mutex_unlock(&wl->mutex);
 }
 
+static u8 wl1271_tx_get_rate_flags(u8 rate_class_index)
+{
+       u8 flags = 0;
+
+       if (rate_class_index >= CONF_HW_RXTX_RATE_MCS_MIN &&
+           rate_class_index <= CONF_HW_RXTX_RATE_MCS_MAX)
+               flags |= IEEE80211_TX_RC_MCS;
+       if (rate_class_index == CONF_HW_RXTX_RATE_MCS7_SGI)
+               flags |= IEEE80211_TX_RC_SHORT_GI;
+       return flags;
+}
+
 static void wl1271_tx_complete_packet(struct wl1271 *wl,
                                      struct wl1271_tx_hw_res_descr *result)
 {
@@ -804,6 +809,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
        struct sk_buff *skb;
        int id = result->id;
        int rate = -1;
+       u8 rate_flags = 0;
        u8 retries = 0;
 
        /* check for id legality */
@@ -830,6 +836,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
                        info->flags |= IEEE80211_TX_STAT_ACK;
                rate = wl1271_rate_to_idx(result->rate_class_index,
                                          wlvif->band);
+               rate_flags = wl1271_tx_get_rate_flags(result->rate_class_index);
                retries = result->ack_failures;
        } else if (result->status == TX_RETRY_EXCEEDED) {
                wl->stats.excessive_retries++;
@@ -838,7 +845,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
 
        info->status.rates[0].idx = rate;
        info->status.rates[0].count = retries;
-       info->status.rates[0].flags = 0;
+       info->status.rates[0].flags = rate_flags;
        info->status.ack_signal = -1;
 
        wl->stats.retry_count += result->ack_failures;
@@ -869,8 +876,9 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
        if (info->control.hw_key &&
            info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
                int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-               memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, hdrlen);
-               skb_pull(skb, WL1271_TKIP_IV_SPACE);
+               memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data,
+                       hdrlen);
+               skb_pull(skb, WL1271_EXTRA_SPACE_TKIP);
        }
 
        wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
@@ -966,7 +974,6 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
                else
                        wlvif->sta.ba_rx_bitmap = 0;
 
-               wl1271_tx_reset_link_queues(wl, i);
                wl->links[i].allocated_pkts = 0;
                wl->links[i].prev_freed_pkts = 0;
        }
@@ -980,8 +987,14 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
        struct sk_buff *skb;
        struct ieee80211_tx_info *info;
 
-       for (i = 0; i < NUM_TX_QUEUES; i++)
-               wl->tx_queue_count[i] = 0;
+       /* only reset the queues if something bad happened */
+       if (WARN_ON_ONCE(wl1271_tx_total_queue_count(wl) != 0)) {
+               for (i = 0; i < WL12XX_MAX_LINKS; i++)
+                       wl1271_tx_reset_link_queues(wl, i);
+
+               for (i = 0; i < NUM_TX_QUEUES; i++)
+                       wl->tx_queue_count[i] = 0;
+       }
 
        wl->stopped_queues_map = 0;
 
@@ -1012,9 +1025,9 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
                            info->control.hw_key->cipher ==
                            WLAN_CIPHER_SUITE_TKIP) {
                                int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-                               memmove(skb->data + WL1271_TKIP_IV_SPACE,
+                               memmove(skb->data + WL1271_EXTRA_SPACE_TKIP,
                                        skb->data, hdrlen);
-                               skb_pull(skb, WL1271_TKIP_IV_SPACE);
+                               skb_pull(skb, WL1271_EXTRA_SPACE_TKIP);
                        }
 
                        info->status.rates[0].idx = -1;
@@ -1031,6 +1044,7 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
 void wl1271_tx_flush(struct wl1271 *wl)
 {
        unsigned long timeout;
+       int i;
        timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT);
 
        while (!time_after(jiffies, timeout)) {
@@ -1048,6 +1062,12 @@ void wl1271_tx_flush(struct wl1271 *wl)
        }
 
        wl1271_warning("Unable to flush all TX buffers, timed out.");
+
+       /* forcibly flush all Tx buffers on our queues */
+       mutex_lock(&wl->mutex);
+       for (i = 0; i < WL12XX_MAX_LINKS; i++)
+               wl1271_tx_reset_link_queues(wl, i);
+       mutex_unlock(&wl->mutex);
 }
 
 u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set)
index 2dbb24e6d541a8c9dbff30efd9144f922217fb92..5cf8c32d40d14e1915a6e65eaa2e980b35ecaef3 100644 (file)
@@ -39,6 +39,7 @@
 #define TX_HW_ATTR_LAST_WORD_PAD         (BIT(10) | BIT(11))
 #define TX_HW_ATTR_TX_CMPLT_REQ          BIT(12)
 #define TX_HW_ATTR_TX_DUMMY_REQ          BIT(13)
+#define TX_HW_ATTR_HOST_ENCRYPT          BIT(14)
 
 #define TX_HW_ATTR_OFST_SAVE_RETRIES     0
 #define TX_HW_ATTR_OFST_HEADER_PAD       1
@@ -51,7 +52,9 @@
 #define TX_HW_RESULT_QUEUE_LEN_MASK      0xf
 
 #define WL1271_TX_ALIGN_TO 4
-#define WL1271_TKIP_IV_SPACE 4
+#define WL1271_EXTRA_SPACE_TKIP 4
+#define WL1271_EXTRA_SPACE_AES  8
+#define WL1271_EXTRA_SPACE_MAX  8
 
 /* Used for management frames and dummy packets */
 #define WL1271_TID_MGMT 7
@@ -224,5 +227,6 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids);
 
 /* from main.c */
 void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
+void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl);
 
 #endif
index b2b09cd0202256c4a623c65f6870160f5fa106b9..749a15a75d384c763b5bf68a06b038a3961e2af0 100644 (file)
 #include "conf.h"
 #include "ini.h"
 
-#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-3.bin"
-#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-3.bin"
+#define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-4-mr.bin"
+#define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-4-sr.bin"
+
+#define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-4-mr.bin"
+#define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
+
+#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
+#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
 
 /*
  * wl127x and wl128x are using the same NVS file name. However, the
 enum wl1271_state {
        WL1271_STATE_OFF,
        WL1271_STATE_ON,
-       WL1271_STATE_PLT,
+};
+
+enum wl12xx_fw_type {
+       WL12XX_FW_TYPE_NONE,
+       WL12XX_FW_TYPE_NORMAL,
+       WL12XX_FW_TYPE_MULTI,
+       WL12XX_FW_TYPE_PLT,
 };
 
 enum wl1271_partition_type {
@@ -247,15 +259,17 @@ enum wl12xx_flags {
        WL1271_FLAG_PENDING_WORK,
        WL1271_FLAG_SOFT_GEMINI,
        WL1271_FLAG_RECOVERY_IN_PROGRESS,
+       WL1271_FLAG_VIF_CHANGE_IN_PROGRESS,
+       WL1271_FLAG_INTENDED_FW_RECOVERY,
 };
 
 enum wl12xx_vif_flags {
        WLVIF_FLAG_INITIALIZED,
        WLVIF_FLAG_STA_ASSOCIATED,
+       WLVIF_FLAG_STA_AUTHORIZED,
        WLVIF_FLAG_IBSS_JOINED,
        WLVIF_FLAG_AP_STARTED,
-       WLVIF_FLAG_PSM,
-       WLVIF_FLAG_PSM_REQUESTED,
+       WLVIF_FLAG_IN_PS,
        WLVIF_FLAG_STA_STATE_SENT,
        WLVIF_FLAG_RX_STREAMING_STARTED,
        WLVIF_FLAG_PSPOLL_FAILURE,
@@ -295,6 +309,9 @@ struct wl1271 {
        spinlock_t wl_lock;
 
        enum wl1271_state state;
+       enum wl12xx_fw_type fw_type;
+       bool plt;
+       u8 last_vif_count;
        struct mutex mutex;
 
        unsigned long flags;
@@ -313,7 +330,12 @@ struct wl1271 {
 
        s8 hw_pg_ver;
 
-       u8 mac_addr[ETH_ALEN];
+       /* address read from the fuse ROM */
+       u32 fuse_oui_addr;
+       u32 fuse_nic_addr;
+
+       /* we have up to 2 MAC addresses */
+       struct mac_address addresses[2];
        int channel;
        u8 system_hlid;
 
@@ -425,8 +447,6 @@ struct wl1271 {
        struct wl12xx_fw_status *fw_status;
        struct wl1271_tx_hw_res_if *tx_res_if;
 
-       struct ieee80211_vif *vif;
-
        /* Current chipset configuration */
        struct conf_drv_settings conf;
 
@@ -434,8 +454,6 @@ struct wl1271 {
 
        bool enable_11a;
 
-       struct list_head list;
-
        /* Most recently reported noise in dBm */
        s8 noise;
 
@@ -477,6 +495,9 @@ struct wl1271 {
 
        /* last wlvif we transmitted from */
        struct wl12xx_vif *last_wlvif;
+
+       /* work to fire when Tx is stuck */
+       struct delayed_work tx_watchdog_work;
 };
 
 struct wl1271_station {
@@ -503,6 +524,8 @@ struct wl12xx_vif {
                        u8 basic_rate_idx;
                        u8 ap_rate_idx;
                        u8 p2p_rate_idx;
+
+                       bool qos;
                } sta;
                struct {
                        u8 global_hlid;
@@ -560,12 +583,6 @@ struct wl12xx_vif {
        /* Session counter for the chipset */
        int session_counter;
 
-       struct completion *ps_compl;
-       struct delayed_work pspoll_work;
-
-       /* counter for ps-poll delivery failures */
-       int ps_poll_failures;
-
        /* retry counter for PSM entries */
        u8 psm_entry_retry;
 
@@ -575,6 +592,10 @@ struct wl12xx_vif {
        int rssi_thold;
        int last_rssi_event;
 
+       /* save the current encryption type for auto-arp config */
+       u8 encryption_type;
+       __be32 ip_addr;
+
        /* RX BA constraint value */
        bool ba_support;
        bool ba_allowed;
index 8f0ffaf62309f8208a1bd6299cf3fd1c66c29e45..22b0bc98d7b5baeb05aec26a180dc060f9712a6d 100644 (file)
@@ -117,7 +117,7 @@ struct wl12xx_ps_poll_template {
 } __packed;
 
 struct wl12xx_arp_rsp_template {
-       struct ieee80211_hdr_3addr hdr;
+       /* not including ieee80211 header */
 
        u8 llc_hdr[sizeof(rfc1042_header)];
        __be16 llc_type;
index 98a574a4a465004728792a293551ae867f450d6c..9fcde36d5013d9435d0070e2eadd4c36f5dc21aa 100644 (file)
@@ -306,9 +306,19 @@ int zd_op_start(struct ieee80211_hw *hw)
        r = set_mc_hash(mac);
        if (r)
                goto disable_int;
+
+       /* Wait after setting the multicast hash table and powering on
+        * the radio otherwise interface bring up will fail. This matches
+        * what the vendor driver did.
+        */
+       msleep(10);
+
        r = zd_chip_switch_radio_on(chip);
-       if (r < 0)
+       if (r < 0) {
+               dev_err(zd_chip_dev(chip),
+                       "%s: failed to set radio on\n", __func__);
                goto disable_int;
+       }
        r = zd_chip_enable_rxtx(chip);
        if (r < 0)
                goto disable_radio;
index 06c3642e5bdb0f1525c6bde54bf2c73058e1b26e..1f74a77d040df4c5b9b93589cf786c4deea12c4d 100644 (file)
@@ -28,6 +28,8 @@
  */
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/types.h>
+#include <linux/firmware.h>
 #include <linux/nfc.h>
 #include <net/nfc/nci.h>
 #include <net/nfc/nci_core.h>
 #define NFCWILINK_OFFSET_LEN_IN_HDR    1
 #define NFCWILINK_LEN_SIZE             2
 #define NFCWILINK_REGISTER_TIMEOUT     8000    /* 8 sec */
+#define NFCWILINK_CMD_TIMEOUT          5000    /* 5 sec */
+
+#define BTS_FILE_NAME_MAX_SIZE         40
+#define BTS_FILE_HDR_MAGIC             0x42535442
+#define BTS_FILE_CMD_MAX_LEN           0xff
+#define BTS_FILE_ACTION_TYPE_SEND_CMD  1
+
+#define NCI_VS_NFCC_INFO_CMD_GID       0x2f
+#define NCI_VS_NFCC_INFO_CMD_OID       0x12
+#define NCI_VS_NFCC_INFO_RSP_GID       0x4f
+#define NCI_VS_NFCC_INFO_RSP_OID       0x12
 
 struct nfcwilink_hdr {
-       u8 chnl;
-       u8 opcode;
-       u16 len;
+       __u8 chnl;
+       __u8 opcode;
+       __le16 len;
+} __packed;
+
+struct nci_vs_nfcc_info_cmd {
+       __u8 gid;
+       __u8 oid;
+       __u8 plen;
+} __packed;
+
+struct nci_vs_nfcc_info_rsp {
+       __u8 gid;
+       __u8 oid;
+       __u8 plen;
+       __u8 status;
+       __u8 hw_id;
+       __u8 sw_ver_x;
+       __u8 sw_ver_z;
+       __u8 patch_id;
+} __packed;
+
+struct bts_file_hdr {
+       __le32 magic;
+       __le32 ver;
+       __u8 rfu[24];
+       __u8 actions[0];
+} __packed;
+
+struct bts_file_action {
+       __le16 type;
+       __le16 len;
+       __u8 data[0];
 } __packed;
 
 struct nfcwilink {
@@ -54,14 +97,241 @@ struct nfcwilink {
 
        char                            st_register_cb_status;
        long                            (*st_write) (struct sk_buff *);
-       struct completion               st_register_completed;
+
+       struct completion               completed;
+
+       struct nci_vs_nfcc_info_rsp     nfcc_info;
 };
 
 /* NFCWILINK driver flags */
 enum {
        NFCWILINK_RUNNING,
+       NFCWILINK_FW_DOWNLOAD,
 };
 
+static int nfcwilink_send(struct sk_buff *skb);
+
+static inline struct sk_buff *nfcwilink_skb_alloc(unsigned int len, gfp_t how)
+{
+       struct sk_buff *skb;
+
+       skb = alloc_skb(len + NFCWILINK_HDR_LEN, how);
+       if (skb)
+               skb_reserve(skb, NFCWILINK_HDR_LEN);
+
+       return skb;
+}
+
+static void nfcwilink_fw_download_receive(struct nfcwilink *drv,
+                                               struct sk_buff *skb)
+{
+       struct nci_vs_nfcc_info_rsp *rsp = (void *)skb->data;
+
+       /* Detect NCI_VS_NFCC_INFO_RSP and store the result */
+       if ((skb->len > 3) && (rsp->gid == NCI_VS_NFCC_INFO_RSP_GID) &&
+               (rsp->oid == NCI_VS_NFCC_INFO_RSP_OID)) {
+               memcpy(&drv->nfcc_info, rsp,
+                       sizeof(struct nci_vs_nfcc_info_rsp));
+       }
+
+       kfree_skb(skb);
+
+       complete(&drv->completed);
+}
+
+static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name)
+{
+       struct nci_vs_nfcc_info_cmd *cmd;
+       struct sk_buff *skb;
+       unsigned long comp_ret;
+       int rc;
+
+       nfc_dev_dbg(&drv->pdev->dev, "get_bts_file_name entry");
+
+       skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd),
+                                       GFP_KERNEL);
+       if (!skb) {
+               nfc_dev_err(&drv->pdev->dev,
+                               "no memory for nci_vs_nfcc_info_cmd");
+               return -ENOMEM;
+       }
+
+       skb->dev = (void *)drv->ndev;
+
+       cmd = (struct nci_vs_nfcc_info_cmd *)
+                       skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd));
+       cmd->gid = NCI_VS_NFCC_INFO_CMD_GID;
+       cmd->oid = NCI_VS_NFCC_INFO_CMD_OID;
+       cmd->plen = 0;
+
+       drv->nfcc_info.plen = 0;
+
+       rc = nfcwilink_send(skb);
+       if (rc)
+               return rc;
+
+       comp_ret = wait_for_completion_timeout(&drv->completed,
+                               msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT));
+       nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld",
+                       comp_ret);
+       if (comp_ret == 0) {
+               nfc_dev_err(&drv->pdev->dev,
+                               "timeout on wait_for_completion_timeout");
+               return -ETIMEDOUT;
+       }
+
+       nfc_dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d",
+                       drv->nfcc_info.plen,
+                       drv->nfcc_info.status);
+
+       if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) {
+               nfc_dev_err(&drv->pdev->dev,
+                               "invalid nci_vs_nfcc_info_rsp");
+               return -EINVAL;
+       }
+
+       snprintf(file_name, BTS_FILE_NAME_MAX_SIZE,
+                       "TINfcInit_%d.%d.%d.%d.bts",
+                       drv->nfcc_info.hw_id,
+                       drv->nfcc_info.sw_ver_x,
+                       drv->nfcc_info.sw_ver_z,
+                       drv->nfcc_info.patch_id);
+
+       nfc_dev_info(&drv->pdev->dev, "nfcwilink FW file name: %s", file_name);
+
+       return 0;
+}
+
+static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len)
+{
+       struct nfcwilink_hdr *hdr = (struct nfcwilink_hdr *)data;
+       struct sk_buff *skb;
+       unsigned long comp_ret;
+       int rc;
+
+       nfc_dev_dbg(&drv->pdev->dev, "send_bts_cmd entry");
+
+       /* verify valid cmd for the NFC channel */
+       if ((len <= sizeof(struct nfcwilink_hdr)) ||
+               (len > BTS_FILE_CMD_MAX_LEN) ||
+               (hdr->chnl != NFCWILINK_CHNL) ||
+               (hdr->opcode != NFCWILINK_OPCODE)) {
+               nfc_dev_err(&drv->pdev->dev,
+                       "ignoring invalid bts cmd, len %d, chnl %d, opcode %d",
+                       len, hdr->chnl, hdr->opcode);
+               return 0;
+       }
+
+       /* remove the ST header */
+       len -= sizeof(struct nfcwilink_hdr);
+       data += sizeof(struct nfcwilink_hdr);
+
+       skb = nfcwilink_skb_alloc(len, GFP_KERNEL);
+       if (!skb) {
+               nfc_dev_err(&drv->pdev->dev, "no memory for bts cmd");
+               return -ENOMEM;
+       }
+
+       skb->dev = (void *)drv->ndev;
+
+       memcpy(skb_put(skb, len), data, len);
+
+       rc = nfcwilink_send(skb);
+       if (rc)
+               return rc;
+
+       comp_ret = wait_for_completion_timeout(&drv->completed,
+                               msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT));
+       nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld",
+                       comp_ret);
+       if (comp_ret == 0) {
+               nfc_dev_err(&drv->pdev->dev,
+                               "timeout on wait_for_completion_timeout");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+static int nfcwilink_download_fw(struct nfcwilink *drv)
+{
+       unsigned char file_name[BTS_FILE_NAME_MAX_SIZE];
+       const struct firmware *fw;
+       __u16 action_type, action_len;
+       __u8 *ptr;
+       int len, rc;
+
+       nfc_dev_dbg(&drv->pdev->dev, "download_fw entry");
+
+       set_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags);
+
+       rc = nfcwilink_get_bts_file_name(drv, file_name);
+       if (rc)
+               goto exit;
+
+       rc = request_firmware(&fw, file_name, &drv->pdev->dev);
+       if (rc) {
+               nfc_dev_err(&drv->pdev->dev, "request_firmware failed %d", rc);
+
+               /* if the file is not found, don't exit with failure */
+               if (rc == -ENOENT)
+                       rc = 0;
+
+               goto exit;
+       }
+
+       len = fw->size;
+       ptr = (__u8 *)fw->data;
+
+       if ((len == 0) || (ptr == NULL)) {
+               nfc_dev_dbg(&drv->pdev->dev,
+                               "request_firmware returned size %d", len);
+               goto release_fw;
+       }
+
+       if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) !=
+                       BTS_FILE_HDR_MAGIC) {
+               nfc_dev_err(&drv->pdev->dev, "wrong bts magic number");
+               rc = -EINVAL;
+               goto release_fw;
+       }
+
+       /* remove the BTS header */
+       len -= sizeof(struct bts_file_hdr);
+       ptr += sizeof(struct bts_file_hdr);
+
+       while (len > 0) {
+               action_type =
+                       __le16_to_cpu(((struct bts_file_action *)ptr)->type);
+               action_len =
+                       __le16_to_cpu(((struct bts_file_action *)ptr)->len);
+
+               nfc_dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d",
+                               action_type, action_len);
+
+               switch (action_type) {
+               case BTS_FILE_ACTION_TYPE_SEND_CMD:
+                       rc = nfcwilink_send_bts_cmd(drv,
+                                       ((struct bts_file_action *)ptr)->data,
+                                       action_len);
+                       if (rc)
+                               goto release_fw;
+                       break;
+               }
+
+               /* advance to the next action */
+               len -= (sizeof(struct bts_file_action) + action_len);
+               ptr += (sizeof(struct bts_file_action) + action_len);
+       }
+
+release_fw:
+       release_firmware(fw);
+
+exit:
+       clear_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags);
+       return rc;
+}
+
 /* Called by ST when registration is complete */
 static void nfcwilink_register_complete(void *priv_data, char data)
 {
@@ -73,7 +343,7 @@ static void nfcwilink_register_complete(void *priv_data, char data)
        drv->st_register_cb_status = data;
 
        /* complete the wait in nfc_st_open() */
-       complete(&drv->st_register_completed);
+       complete(&drv->completed);
 }
 
 /* Called by ST when receive data is available */
@@ -96,6 +366,11 @@ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb)
        (apart for the chnl byte, which is not received in the hdr) */
        skb_pull(skb, (NFCWILINK_HDR_LEN-1));
 
+       if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) {
+               nfcwilink_fw_download_receive(drv, skb);
+               return 0;
+       }
+
        skb->dev = (void *) drv->ndev;
 
        /* Forward skb to NCI core layer */
@@ -136,14 +411,14 @@ static int nfcwilink_open(struct nci_dev *ndev)
 
        nfcwilink_proto.priv_data = drv;
 
-       init_completion(&drv->st_register_completed);
+       init_completion(&drv->completed);
        drv->st_register_cb_status = -EINPROGRESS;
 
        rc = st_register(&nfcwilink_proto);
        if (rc < 0) {
                if (rc == -EINPROGRESS) {
                        comp_ret = wait_for_completion_timeout(
-                       &drv->st_register_completed,
+                       &drv->completed,
                        msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT));
 
                        nfc_dev_dbg(&drv->pdev->dev,
@@ -171,6 +446,12 @@ static int nfcwilink_open(struct nci_dev *ndev)
        BUG_ON(nfcwilink_proto.write == NULL);
        drv->st_write = nfcwilink_proto.write;
 
+       if (nfcwilink_download_fw(drv)) {
+               nfc_dev_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d",
+                               rc);
+               /* open should succeed, even if the FW download failed */
+       }
+
        goto exit;
 
 clear_exit:
@@ -208,11 +489,13 @@ static int nfcwilink_send(struct sk_buff *skb)
 
        nfc_dev_dbg(&drv->pdev->dev, "send entry, len %d", skb->len);
 
-       if (!test_bit(NFCWILINK_RUNNING, &drv->flags))
-               return -EBUSY;
+       if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) {
+               kfree_skb(skb);
+               return -EINVAL;
+       }
 
        /* add the ST hdr to the start of the buffer */
-       hdr.len = skb->len;
+       hdr.len = cpu_to_le16(skb->len);
        memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN);
 
        /* Insert skb to shared transport layer's transmit queue.
@@ -239,7 +522,7 @@ static int nfcwilink_probe(struct platform_device *pdev)
 {
        static struct nfcwilink *drv;
        int rc;
-       u32 protocols;
+       __u32 protocols;
 
        nfc_dev_dbg(&pdev->dev, "probe entry");
 
index 1a1500bc845233dc1537ea2b05c35379c33907e5..cb6204f783002dc3ddcc79adebcc79fa61cc4392 100644 (file)
@@ -736,6 +736,8 @@ static int pn533_target_found_type_a(struct nfc_target *nfc_tgt, u8 *tgt_data,
 
        nfc_tgt->sens_res = be16_to_cpu(tgt_type_a->sens_res);
        nfc_tgt->sel_res = tgt_type_a->sel_res;
+       nfc_tgt->nfcid1_len = tgt_type_a->nfcid_len;
+       memcpy(nfc_tgt->nfcid1, tgt_type_a->nfcid_data, nfc_tgt->nfcid1_len);
 
        return 0;
 }
@@ -781,6 +783,9 @@ static int pn533_target_found_felica(struct nfc_target *nfc_tgt, u8 *tgt_data,
        else
                nfc_tgt->supported_protocols = NFC_PROTO_FELICA_MASK;
 
+       memcpy(nfc_tgt->sensf_res, &tgt_felica->opcode, 9);
+       nfc_tgt->sensf_res_len = 9;
+
        return 0;
 }
 
@@ -823,6 +828,8 @@ static int pn533_target_found_jewel(struct nfc_target *nfc_tgt, u8 *tgt_data,
 
        nfc_tgt->supported_protocols = NFC_PROTO_JEWEL_MASK;
        nfc_tgt->sens_res = be16_to_cpu(tgt_jewel->sens_res);
+       nfc_tgt->nfcid1_len = 4;
+       memcpy(nfc_tgt->nfcid1, tgt_jewel->jewelid, nfc_tgt->nfcid1_len);
 
        return 0;
 }
@@ -902,6 +909,8 @@ static int pn533_target_found(struct pn533 *dev,
        if (resp->tg != 1)
                return -EPROTO;
 
+       memset(&nfc_tgt, 0, sizeof(struct nfc_target));
+
        target_data_len = resp_len - sizeof(struct pn533_poll_response);
 
        switch (dev->poll_mod_curr) {
@@ -1307,6 +1316,8 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
                nfc_dev_dbg(&dev->interface->dev, "Creating new target");
 
                nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
+               nfc_target.nfcid1_len = 10;
+               memcpy(nfc_target.nfcid1, resp->nfcid3t, nfc_target.nfcid1_len);
                rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1);
                if (rc)
                        return 0;
@@ -1329,21 +1340,15 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
 }
 
 static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx,
-                                               u8 comm_mode, u8 rf_mode)
+                            u8 comm_mode, u8* gb, size_t gb_len)
 {
        struct pn533 *dev = nfc_get_drvdata(nfc_dev);
        struct pn533_cmd_jump_dep *cmd;
-       u8 cmd_len, local_gt_len, *local_gt;
+       u8 cmd_len;
        int rc;
 
        nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
 
-       if (rf_mode == NFC_RF_TARGET) {
-               nfc_dev_err(&dev->interface->dev, "Target mode not supported");
-               return -EOPNOTSUPP;
-       }
-
-
        if (dev->poll_mod_count) {
                nfc_dev_err(&dev->interface->dev,
                                "Cannot bring the DEP link up while polling");
@@ -1356,11 +1361,7 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx,
                return -EBUSY;
        }
 
-       local_gt = nfc_get_local_general_bytes(dev->nfc_dev, &local_gt_len);
-       if (local_gt_len > NFC_MAX_GT_LEN)
-               return -EINVAL;
-
-       cmd_len = sizeof(struct pn533_cmd_jump_dep) + local_gt_len;
+       cmd_len = sizeof(struct pn533_cmd_jump_dep) + gb_len;
        cmd = kzalloc(cmd_len, GFP_KERNEL);
        if (cmd == NULL)
                return -ENOMEM;
@@ -1369,9 +1370,9 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx,
 
        cmd->active = !comm_mode;
        cmd->baud = 0;
-       if (local_gt != NULL) {
+       if (gb != NULL && gb_len > 0) {
                cmd->next = 4; /* We have some Gi */
-               memcpy(cmd->gt, local_gt, local_gt_len);
+               memcpy(cmd->gt, gb, gb_len);
        } else {
                cmd->next = 0;
        }
index e5a2e0e9bc19bbf586c49cc06b49f35cb16c5a88..b58fef780ea063827f6bf5d66aa10547f17c9edf 100644 (file)
@@ -13,6 +13,9 @@
 #include <linux/ssb/ssb_driver_chipcommon.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
+#endif
 
 #include "ssb_private.h"
 
@@ -92,10 +95,6 @@ static void ssb_pmu0_pllinit_r0(struct ssb_chipcommon *cc,
        u32 pmuctl, tmp, pllctl;
        unsigned int i;
 
-       if ((bus->chip_id == 0x5354) && !crystalfreq) {
-               /* The 5354 crystal freq is 25MHz */
-               crystalfreq = 25000;
-       }
        if (crystalfreq)
                e = pmu0_plltab_find_entry(crystalfreq);
        if (!e)
@@ -321,7 +320,11 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc)
        u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */
 
        if (bus->bustype == SSB_BUSTYPE_SSB) {
-               /* TODO: The user may override the crystal frequency. */
+#ifdef CONFIG_BCM47XX
+               char buf[20];
+               if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0)
+                       crystalfreq = simple_strtoul(buf, NULL, 0);
+#endif
        }
 
        switch (bus->chip_id) {
@@ -330,7 +333,11 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc)
                ssb_pmu1_pllinit_r0(cc, crystalfreq);
                break;
        case 0x4328:
+               ssb_pmu0_pllinit_r0(cc, crystalfreq);
+               break;
        case 0x5354:
+               if (crystalfreq == 0)
+                       crystalfreq = 25000;
                ssb_pmu0_pllinit_r0(cc, crystalfreq);
                break;
        case 0x4322:
@@ -607,3 +614,34 @@ void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
 
 EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
 EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
+
+u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc)
+{
+       struct ssb_bus *bus = cc->dev->bus;
+
+       switch (bus->chip_id) {
+       case 0x5354:
+               /* 5354 chip uses a non programmable PLL of frequency 240MHz */
+               return 240000000;
+       default:
+               ssb_printk(KERN_ERR PFX
+                          "ERROR: PMU cpu clock unknown for device %04X\n",
+                          bus->chip_id);
+               return 0;
+       }
+}
+
+u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
+{
+       struct ssb_bus *bus = cc->dev->bus;
+
+       switch (bus->chip_id) {
+       case 0x5354:
+               return 120000000;
+       default:
+               ssb_printk(KERN_ERR PFX
+                          "ERROR: PMU controlclock unknown for device %04X\n",
+                          bus->chip_id);
+               return 0;
+       }
+}
index ced501568594837a7852350a8449a997cb03033c..7e2ddc042f5bff19954bc4d61200a36bf6523609 100644 (file)
@@ -208,6 +208,9 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
        struct ssb_bus *bus = mcore->dev->bus;
        u32 pll_type, n, m, rate = 0;
 
+       if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
+               return ssb_pmu_get_cpu_clock(&bus->chipco);
+
        if (bus->extif.dev) {
                ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
        } else if (bus->chipco.dev) {
index bb6317fb925ce922908e0053e9acc740cc7fe541..2a0a1b99e0e48046563827aaf4a014e3e2cf095d 100644 (file)
@@ -1094,6 +1094,9 @@ u32 ssb_clockspeed(struct ssb_bus *bus)
        u32 plltype;
        u32 clkctl_n, clkctl_m;
 
+       if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
+               return ssb_pmu_get_controlclock(&bus->chipco);
+
        if (ssb_extif_available(&bus->extif))
                ssb_extif_get_clockcontrol(&bus->extif, &plltype,
                                           &clkctl_n, &clkctl_m);
index 973223f5de8ebbeee690da524d0cf94c2593ce85..ed4124469a3a34493088db68b725c081620ab81d 100644 (file)
@@ -331,7 +331,6 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
 {
        int i;
        u16 v;
-       s8 gain;
        u16 loc[3];
 
        if (out->revision == 3)                 /* rev 3 moved MAC */
@@ -390,20 +389,12 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
                SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
 
        /* Extract the antenna gain values. */
-       gain = r123_extract_antgain(out->revision, in,
-                                   SSB_SPROM1_AGAIN_BG,
-                                   SSB_SPROM1_AGAIN_BG_SHIFT);
-       out->antenna_gain.ghz24.a0 = gain;
-       out->antenna_gain.ghz24.a1 = gain;
-       out->antenna_gain.ghz24.a2 = gain;
-       out->antenna_gain.ghz24.a3 = gain;
-       gain = r123_extract_antgain(out->revision, in,
-                                   SSB_SPROM1_AGAIN_A,
-                                   SSB_SPROM1_AGAIN_A_SHIFT);
-       out->antenna_gain.ghz5.a0 = gain;
-       out->antenna_gain.ghz5.a1 = gain;
-       out->antenna_gain.ghz5.a2 = gain;
-       out->antenna_gain.ghz5.a3 = gain;
+       out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
+                                                   SSB_SPROM1_AGAIN_BG,
+                                                   SSB_SPROM1_AGAIN_BG_SHIFT);
+       out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
+                                                   SSB_SPROM1_AGAIN_A,
+                                                   SSB_SPROM1_AGAIN_A_SHIFT);
 }
 
 /* Revs 4 5 and 8 have partially shared layout */
@@ -504,16 +495,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
        }
 
        /* Extract the antenna gain values. */
-       SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
+       SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
             SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
-       SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
+       SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
             SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
-       SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
+       SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
             SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
-       SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
+       SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
             SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
-       memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
-              sizeof(out->antenna_gain.ghz5));
 
        sprom_extract_r458(out, in);
 
@@ -523,7 +512,13 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
 static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
 {
        int i;
-       u16 v;
+       u16 v, o;
+       u16 pwr_info_offset[] = {
+               SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
+               SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
+       };
+       BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
+                       ARRAY_SIZE(out->core_pwr_info));
 
        /* extract the MAC address */
        for (i = 0; i < 3; i++) {
@@ -596,16 +591,46 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
        SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
 
        /* Extract the antenna gain values. */
-       SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
+       SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
             SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
-       SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01,
+       SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
             SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
-       SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23,
+       SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
             SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
-       SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23,
+       SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
             SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
-       memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
-              sizeof(out->antenna_gain.ghz5));
+
+       /* Extract cores power info info */
+       for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
+               o = pwr_info_offset[i];
+               SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
+                       SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
+               SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
+                       SSB_SPROM8_2G_MAXP, 0);
+
+               SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
+               SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
+               SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
+
+               SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
+                       SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
+               SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
+                       SSB_SPROM8_5G_MAXP, 0);
+               SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
+                       SSB_SPROM8_5GH_MAXP, 0);
+               SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
+                       SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
+
+               SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
+               SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
+       }
 
        /* Extract FEM info */
        SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
index c821c6b2a6a0b778da37a7994ad1ad2d57335428..fbafed5b729bdcf6ae57889c3c9d4f05ca0509c5 100644 (file)
@@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
        case SSB_PCMCIA_CIS_ANTGAIN:
                GOTO_ERROR_ON(tuple->TupleDataLen != 2,
                        "antg tpl size");
-               sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
+               sprom->antenna_gain.a0 = tuple->TupleData[1];
+               sprom->antenna_gain.a1 = tuple->TupleData[1];
+               sprom->antenna_gain.a2 = tuple->TupleData[1];
+               sprom->antenna_gain.a3 = tuple->TupleData[1];
                break;
        case SSB_PCMCIA_CIS_BFLAGS:
                GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
index 3e844874631f84badb6faead992d6391253d9348..266c7c5c86dcba7dcb6c70965534bea331f1b153 100644 (file)
@@ -318,6 +318,9 @@ int ssb_bus_scan(struct ssb_bus *bus,
                        bus->chip_package = 0;
                }
        }
+       ssb_printk(KERN_INFO PFX "Found chip with id 0x%04X, rev 0x%02X and "
+                  "package 0x%02X\n", bus->chip_id, bus->chip_rev,
+                  bus->chip_package);
        if (!bus->nr_devices)
                bus->nr_devices = chipid_to_nrcores(bus->chip_id);
        if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
index 63fd709038caed0d7bbb70121159f27028bd0b41..b2d36f7736c537ef5ba6ec65d6144f965b75f971 100644 (file)
@@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_bus *bus,
                        case SSB_SDIO_CIS_ANTGAIN:
                                GOTO_ERROR_ON(tuple->size != 2,
                                              "antg tpl size");
-                               sprom->antenna_gain.ghz24.a0 = tuple->data[1];
-                               sprom->antenna_gain.ghz24.a1 = tuple->data[1];
-                               sprom->antenna_gain.ghz24.a2 = tuple->data[1];
-                               sprom->antenna_gain.ghz24.a3 = tuple->data[1];
-                               sprom->antenna_gain.ghz5.a0 = tuple->data[1];
-                               sprom->antenna_gain.ghz5.a1 = tuple->data[1];
-                               sprom->antenna_gain.ghz5.a2 = tuple->data[1];
-                               sprom->antenna_gain.ghz5.a3 = tuple->data[1];
+                               sprom->antenna_gain.a0 = tuple->data[1];
+                               sprom->antenna_gain.a1 = tuple->data[1];
+                               sprom->antenna_gain.a2 = tuple->data[1];
+                               sprom->antenna_gain.a3 = tuple->data[1];
                                break;
                        case SSB_SDIO_CIS_BFLAGS:
                                GOTO_ERROR_ON((tuple->size != 3) &&
index 77653014db0b8f997a61dec98a26933cacb874d1..a305550b4b65ecce6c5e6e925c63c36667edd3b0 100644 (file)
@@ -207,4 +207,8 @@ static inline void b43_pci_ssb_bridge_exit(void)
 }
 #endif /* CONFIG_SSB_B43_PCI_BRIDGE */
 
+/* driver_chipcommon_pmu.c */
+extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
+extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
+
 #endif /* LINUX_SSB_PRIVATE_H_ */
index 83c209f39493adf3ef4ae659c2cc46b3770c2948..5af9a075498f144fa3c6ea6d86744201a65428b7 100644 (file)
@@ -136,6 +136,7 @@ struct bcma_device {
        bool dev_registered;
 
        u8 core_index;
+       u8 core_unit;
 
        u32 addr;
        u32 wrap;
@@ -175,6 +176,12 @@ int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
 
 extern void bcma_driver_unregister(struct bcma_driver *drv);
 
+/* Set a fallback SPROM.
+ * See kdoc at the function definition for complete documentation. */
+extern int bcma_arch_register_fallback_sprom(
+               int (*sprom_callback)(struct bcma_bus *bus,
+               struct ssb_sprom *out));
+
 struct bcma_bus {
        /* The MMIO area. */
        void __iomem *mmio;
@@ -195,6 +202,7 @@ struct bcma_bus {
        struct list_head cores;
        u8 nr_cores;
        u8 init_done:1;
+       u8 num;
 
        struct bcma_drv_cc drv_cc;
        struct bcma_drv_pci drv_pci;
@@ -282,6 +290,7 @@ static inline void bcma_maskset16(struct bcma_device *cc,
        bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
 }
 
+extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
 extern bool bcma_core_is_enabled(struct bcma_device *core);
 extern void bcma_core_disable(struct bcma_device *core, u32 flags);
 extern int bcma_core_enable(struct bcma_device *core, u32 flags);
index a33086a7530bc708e9b903723cd80a8967d429e7..8bbfe31fbac864db2fa60e9edeef149097d3a32e 100644 (file)
@@ -56,6 +56,9 @@
 #define         BCMA_CC_OTPS_HW_PROTECT        0x00000001
 #define         BCMA_CC_OTPS_SW_PROTECT        0x00000002
 #define         BCMA_CC_OTPS_CID_PROTECT       0x00000004
+#define  BCMA_CC_OTPS_GU_PROG_IND      0x00000F00      /* General Use programmed indication */
+#define  BCMA_CC_OTPS_GU_PROG_IND_SHIFT        8
+#define  BCMA_CC_OTPS_GU_PROG_HW       0x00000100      /* HW region programmed */
 #define BCMA_CC_OTPC                   0x0014          /* OTP control */
 #define         BCMA_CC_OTPC_RECWAIT           0xFF000000
 #define         BCMA_CC_OTPC_PROGWAIT          0x00FFFF00
@@ -72,6 +75,8 @@
 #define         BCMA_CC_OTPP_READ              0x40000000
 #define         BCMA_CC_OTPP_START             0x80000000
 #define         BCMA_CC_OTPP_BUSY              0x80000000
+#define BCMA_CC_OTPL                   0x001C          /* OTP layout */
+#define  BCMA_CC_OTPL_GURGN_OFFSET     0x00000FFF      /* offset of general use region */
 #define BCMA_CC_IRQSTAT                        0x0020
 #define BCMA_CC_IRQMASK                        0x0024
 #define         BCMA_CC_IRQ_GPIO               0x00000001      /* gpio intr */
 #define         BCMA_CC_IRQ_WDRESET            0x80000000      /* watchdog reset occurred */
 #define BCMA_CC_CHIPCTL                        0x0028          /* Rev >= 11 only */
 #define BCMA_CC_CHIPSTAT               0x002C          /* Rev >= 11 only */
+#define  BCMA_CC_CHIPST_4313_SPROM_PRESENT     1
+#define  BCMA_CC_CHIPST_4313_OTP_PRESENT       2
+#define  BCMA_CC_CHIPST_4331_SPROM_PRESENT     2
+#define  BCMA_CC_CHIPST_4331_OTP_PRESENT       4
 #define BCMA_CC_JCMD                   0x0030          /* Rev >= 10 only */
 #define  BCMA_CC_JCMD_START            0x80000000
 #define  BCMA_CC_JCMD_BUSY             0x80000000
 #define BCMA_CC_FLASH_CFG              0x0128
 #define  BCMA_CC_FLASH_CFG_DS          0x0010  /* Data size, 0=8bit, 1=16bit */
 #define BCMA_CC_FLASH_WAITCNT          0x012C
+#define BCMA_CC_SROM_CONTROL           0x0190
+#define  BCMA_CC_SROM_CONTROL_START    0x80000000
+#define  BCMA_CC_SROM_CONTROL_BUSY     0x80000000
+#define  BCMA_CC_SROM_CONTROL_OPCODE   0x60000000
+#define  BCMA_CC_SROM_CONTROL_OP_READ  0x00000000
+#define  BCMA_CC_SROM_CONTROL_OP_WRITE 0x20000000
+#define  BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
+#define  BCMA_CC_SROM_CONTROL_OP_WREN  0x60000000
+#define  BCMA_CC_SROM_CONTROL_OTPSEL   0x00000010
+#define  BCMA_CC_SROM_CONTROL_LOCK     0x00000008
+#define  BCMA_CC_SROM_CONTROL_SIZE_MASK        0x00000006
+#define  BCMA_CC_SROM_CONTROL_SIZE_1K  0x00000000
+#define  BCMA_CC_SROM_CONTROL_SIZE_4K  0x00000002
+#define  BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004
+#define  BCMA_CC_SROM_CONTROL_SIZE_SHIFT       1
+#define  BCMA_CC_SROM_CONTROL_PRESENT  0x00000001
 /* 0x1E0 is defined as shared BCMA_CLKCTLST */
 #define BCMA_CC_HW_WORKAROUND          0x01E4 /* Hardware workaround (rev >= 20) */
 #define BCMA_CC_UART0_DATA             0x0300
 #define BCMA_CC_PLLCTL_ADDR            0x0660
 #define BCMA_CC_PLLCTL_DATA            0x0664
 #define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
-#define BCMA_CC_SPROM_PCIE6            0x0830 /* SPROM beginning on PCIe rev >= 6 */
 
 /* Divider allocation in 4716/47162/5356 */
 #define BCMA_CC_PMU5_MAINPLL_CPU       1
index 3871b668caf91a507268954dab35282afaedb735..46c71e27d31f2c1fc25118195aa3e1fc75496cd5 100644 (file)
@@ -53,6 +53,35 @@ struct pci_dev;
 #define  BCMA_CORE_PCI_SBTOPCI1_MASK           0xFC000000
 #define BCMA_CORE_PCI_SBTOPCI2                 0x0108  /* Backplane to PCI translation 2 (sbtopci2) */
 #define  BCMA_CORE_PCI_SBTOPCI2_MASK           0xC0000000
+#define BCMA_CORE_PCI_CONFIG_ADDR              0x0120  /* pcie config space access */
+#define BCMA_CORE_PCI_CONFIG_DATA              0x0124  /* pcie config space access */
+#define BCMA_CORE_PCI_MDIO_CONTROL             0x0128  /* controls the mdio access */
+#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK    0x7f    /* clock to be used on MDIO */
+#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL     0x2
+#define  BCMA_CORE_PCI_MDIOCTL_PREAM_EN                0x80    /* Enable preamble sequnce */
+#define  BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE     0x100   /* Tranaction complete */
+#define BCMA_CORE_PCI_MDIO_DATA                        0x012c  /* Data to the mdio access */
+#define  BCMA_CORE_PCI_MDIODATA_MASK           0x0000ffff /* data 2 bytes */
+#define  BCMA_CORE_PCI_MDIODATA_TA             0x00020000 /* Turnaround */
+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD        18      /* Regaddr shift (rev < 10) */
+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD       0x003c0000 /* Regaddr Mask (rev < 10) */
+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD        22      /* Physmedia devaddr shift (rev < 10) */
+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD       0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF    18      /* Regaddr shift */
+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK   0x007c0000 /* Regaddr Mask */
+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF    23      /* Physmedia devaddr shift */
+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK   0x0f800000 /* Physmedia devaddr Mask */
+#define  BCMA_CORE_PCI_MDIODATA_WRITE          0x10000000 /* write Transaction */
+#define  BCMA_CORE_PCI_MDIODATA_READ           0x20000000 /* Read Transaction */
+#define  BCMA_CORE_PCI_MDIODATA_START          0x40000000 /* start of Transaction */
+#define  BCMA_CORE_PCI_MDIODATA_DEV_ADDR       0x0     /* dev address for serdes */
+#define  BCMA_CORE_PCI_MDIODATA_BLK_ADDR       0x1F    /* blk address for serdes */
+#define  BCMA_CORE_PCI_MDIODATA_DEV_PLL                0x1d    /* SERDES PLL Dev */
+#define  BCMA_CORE_PCI_MDIODATA_DEV_TX         0x1e    /* SERDES TX Dev */
+#define  BCMA_CORE_PCI_MDIODATA_DEV_RX         0x1f    /* SERDES RX Dev */
+#define BCMA_CORE_PCI_PCIEIND_ADDR             0x0130  /* indirect access to the internal register */
+#define BCMA_CORE_PCI_PCIEIND_DATA             0x0134  /* Data to/from the internal regsiter */
+#define BCMA_CORE_PCI_CLKREQENCTRL             0x0138  /*  >= rev 6, Clkreq rdma control */
 #define BCMA_CORE_PCI_PCICFG0                  0x0400  /* PCI config space 0 (rev >= 8) */
 #define BCMA_CORE_PCI_PCICFG1                  0x0500  /* PCI config space 1 (rev >= 8) */
 #define BCMA_CORE_PCI_PCICFG2                  0x0600  /* PCI config space 2 (rev >= 8) */
@@ -72,20 +101,114 @@ struct pci_dev;
 #define  BCMA_CORE_PCI_SBTOPCI_RC_READL                0x00000010 /* Memory read line */
 #define  BCMA_CORE_PCI_SBTOPCI_RC_READM                0x00000020 /* Memory read multiple */
 
+/* PCIE protocol PHY diagnostic registers */
+#define BCMA_CORE_PCI_PLP_MODEREG              0x200   /* Mode */
+#define BCMA_CORE_PCI_PLP_STATUSREG            0x204   /* Status */
+#define  BCMA_CORE_PCI_PLP_POLARITYINV_STAT    0x10    /* Status reg PCIE_PLP_STATUSREG */
+#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG         0x208   /* LTSSM control */
+#define BCMA_CORE_PCI_PLP_LTLINKNUMREG         0x20c   /* Link Training Link number */
+#define BCMA_CORE_PCI_PLP_LTLANENUMREG         0x210   /* Link Training Lane number */
+#define BCMA_CORE_PCI_PLP_LTNFTSREG            0x214   /* Link Training N_FTS */
+#define BCMA_CORE_PCI_PLP_ATTNREG              0x218   /* Attention */
+#define BCMA_CORE_PCI_PLP_ATTNMASKREG          0x21C   /* Attention Mask */
+#define BCMA_CORE_PCI_PLP_RXERRCTR             0x220   /* Rx Error */
+#define BCMA_CORE_PCI_PLP_RXFRMERRCTR          0x224   /* Rx Framing Error */
+#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG       0x228   /* Rx Error threshold */
+#define BCMA_CORE_PCI_PLP_TESTCTRLREG          0x22C   /* Test Control reg */
+#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG    0x230   /* SERDES Control Override */
+#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG                0x234   /* Timing param override */
+#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG                0x238   /* RXTX State Machine Diag */
+#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG         0x23C   /* LTSSM State Machine Diag */
+
+/* PCIE protocol DLLP diagnostic registers */
+#define BCMA_CORE_PCI_DLLP_LCREG               0x100   /* Link Control */
+#define BCMA_CORE_PCI_DLLP_LSREG               0x104   /* Link Status */
+#define BCMA_CORE_PCI_DLLP_LAREG               0x108   /* Link Attention */
+#define  BCMA_CORE_PCI_DLLP_LSREG_LINKUP       (1 << 16)
+#define BCMA_CORE_PCI_DLLP_LAMASKREG           0x10C   /* Link Attention Mask */
+#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG     0x110   /* Next Tx Seq Num */
+#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG    0x114   /* Acked Tx Seq Num */
+#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG   0x118   /* Purged Tx Seq Num */
+#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG         0x11C   /* Rx Sequence Number */
+#define BCMA_CORE_PCI_DLLP_LRREG               0x120   /* Link Replay */
+#define BCMA_CORE_PCI_DLLP_LACKTOREG           0x124   /* Link Ack Timeout */
+#define BCMA_CORE_PCI_DLLP_PMTHRESHREG         0x128   /* Power Management Threshold */
+#define BCMA_CORE_PCI_DLLP_RTRYWPREG           0x12C   /* Retry buffer write ptr */
+#define BCMA_CORE_PCI_DLLP_RTRYRPREG           0x130   /* Retry buffer Read ptr */
+#define BCMA_CORE_PCI_DLLP_RTRYPPREG           0x134   /* Retry buffer Purged ptr */
+#define BCMA_CORE_PCI_DLLP_RTRRWREG            0x138   /* Retry buffer Read/Write */
+#define BCMA_CORE_PCI_DLLP_ECTHRESHREG         0x13C   /* Error Count Threshold */
+#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG                0x140   /* TLP Error Counter */
+#define BCMA_CORE_PCI_DLLP_ERRCTRREG           0x144   /* Error Counter */
+#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG         0x148   /* NAK Received Counter */
+#define BCMA_CORE_PCI_DLLP_TESTREG             0x14C   /* Test */
+#define BCMA_CORE_PCI_DLLP_PKTBIST             0x150   /* Packet BIST */
+#define BCMA_CORE_PCI_DLLP_PCIE11              0x154   /* DLLP PCIE 1.1 reg */
+
+/* SERDES RX registers */
+#define BCMA_CORE_PCI_SERDES_RX_CTRL           1       /* Rx cntrl */
+#define  BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE    0x80    /* rxpolarity_force */
+#define  BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY 0x40    /* rxpolarity_value */
+#define BCMA_CORE_PCI_SERDES_RX_TIMER1         2       /* Rx Timer1 */
+#define BCMA_CORE_PCI_SERDES_RX_CDR            6       /* CDR */
+#define BCMA_CORE_PCI_SERDES_RX_CDRBW          7       /* CDR BW */
+
+/* SERDES PLL registers */
+#define BCMA_CORE_PCI_SERDES_PLL_CTRL          1       /* PLL control reg */
+#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN      0x4000  /* bit 14 is FREQDET on */
+
 /* PCIcore specific boardflags */
 #define BCMA_CORE_PCI_BFL_NOPCI                        0x00000400 /* Board leaves PCI floating */
 
+/* PCIE Config space accessing MACROS */
+#define BCMA_CORE_PCI_CFG_BUS_SHIFT            24      /* Bus shift */
+#define BCMA_CORE_PCI_CFG_SLOT_SHIFT           19      /* Slot/Device shift */
+#define BCMA_CORE_PCI_CFG_FUN_SHIFT            16      /* Function shift */
+#define BCMA_CORE_PCI_CFG_OFF_SHIFT            0       /* Register shift */
+
+#define BCMA_CORE_PCI_CFG_BUS_MASK             0xff    /* Bus mask */
+#define BCMA_CORE_PCI_CFG_SLOT_MASK            0x1f    /* Slot/Device mask */
+#define BCMA_CORE_PCI_CFG_FUN_MASK             7       /* Function mask */
+#define BCMA_CORE_PCI_CFG_OFF_MASK             0xfff   /* Register mask */
+
+/* PCIE Root Capability Register bits (Host mode only) */
+#define BCMA_CORE_PCI_RC_CRS_VISIBILITY                0x0001
+
+struct bcma_drv_pci;
+
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
+struct bcma_drv_pci_host {
+       struct bcma_drv_pci *pdev;
+
+       u32 host_cfg_addr;
+       spinlock_t cfgspace_lock;
+
+       struct pci_controller pci_controller;
+       struct pci_ops pci_ops;
+       struct resource mem_resource;
+       struct resource io_resource;
+};
+#endif
+
 struct bcma_drv_pci {
        struct bcma_device *core;
        u8 setup_done:1;
+       u8 hostmode:1;
+
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
+       struct bcma_drv_pci_host *host_controller;
+#endif
 };
 
 /* Register access */
 #define pcicore_read32(pc, offset)             bcma_read32((pc)->core, offset)
 #define pcicore_write32(pc, offset, val)       bcma_write32((pc)->core, offset, val)
 
-extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
+extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
 extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
                                 struct bcma_device *core, bool enable);
 
+extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
+extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
+
 #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
index 9faae2ae02e8c34abecffc6bcb86f2d0c0fcb72b..5a71d57196404780ab587458ac1826343fd74c1c 100644 (file)
 #define  BCMA_PCI_GPIO_XTAL            0x40    /* PCI config space GPIO 14 for Xtal powerup */
 #define  BCMA_PCI_GPIO_PLL             0x80    /* PCI config space GPIO 15 for PLL powerdown */
 
+/* SiliconBackplane Address Map.
+ * All regions may not exist on all chips.
+ */
+#define BCMA_SOC_SDRAM_BASE            0x00000000U     /* Physical SDRAM */
+#define BCMA_SOC_PCI_MEM               0x08000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
+#define BCMA_SOC_PCI_MEM_SZ            (64 * 1024 * 1024)
+#define BCMA_SOC_PCI_CFG               0x0c000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
+#define BCMA_SOC_SDRAM_SWAPPED         0x10000000U     /* Byteswapped Physical SDRAM */
+#define BCMA_SOC_SDRAM_R2              0x80000000U     /* Region 2 for sdram (512 MB) */
+
+
+#define BCMA_SOC_PCI_DMA               0x40000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
+#define BCMA_SOC_PCI_DMA2              0x80000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
+#define BCMA_SOC_PCI_DMA_SZ            0x40000000U     /* Client Mode sb2pcitranslation2 size in bytes */
+#define BCMA_SOC_PCIE_DMA_L32          0x00000000U     /* PCIE Client Mode sb2pcitranslation2
+                                                        * (2 ZettaBytes), low 32 bits
+                                                        */
+#define BCMA_SOC_PCIE_DMA_H32          0x80000000U     /* PCIE Client Mode sb2pcitranslation2
+                                                        * (2 ZettaBytes), high 32 bits
+                                                        */
+
+#define BCMA_SOC_PCI1_MEM              0x40000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
+#define BCMA_SOC_PCI1_CFG              0x44000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
+#define BCMA_SOC_PCIE1_DMA_H32         0xc0000000U     /* PCIE Client Mode sb2pcitranslation2
+                                                        * (2 ZettaBytes), high 32 bits
+                                                        */
+
 #endif /* LINUX_BCMA_REGS_H_ */
index 01d4e5d60325bd58f51c12876a25e2bfc13550d9..39c1fcf089c0a99ec654d4c5fb190eda696dd665 100644 (file)
@@ -89,6 +89,8 @@ enum nfc_commands {
  * @NFC_ATTR_TARGET_SEL_RES: NFC-A targets extra information (useful if the
  *     target is not NFC-Forum compliant)
  * @NFC_ATTR_TARGET_NFCID1: NFC-A targets identifier, max 10 bytes
+ * @NFC_ATTR_TARGET_SENSB_RES: NFC-B targets extra information, max 12 bytes
+ * @NFC_ATTR_TARGET_SENSF_RES: NFC-F targets extra information, max 18 bytes
  * @NFC_ATTR_COMM_MODE: Passive or active mode
  * @NFC_ATTR_RF_MODE: Initiator or target
  */
@@ -101,14 +103,20 @@ enum nfc_attrs {
        NFC_ATTR_TARGET_SENS_RES,
        NFC_ATTR_TARGET_SEL_RES,
        NFC_ATTR_TARGET_NFCID1,
+       NFC_ATTR_TARGET_SENSB_RES,
+       NFC_ATTR_TARGET_SENSF_RES,
        NFC_ATTR_COMM_MODE,
        NFC_ATTR_RF_MODE,
+       NFC_ATTR_DEVICE_POWERED,
 /* private: internal use only */
        __NFC_ATTR_AFTER_LAST
 };
 #define NFC_ATTR_MAX (__NFC_ATTR_AFTER_LAST - 1)
 
 #define NFC_DEVICE_NAME_MAXSIZE 8
+#define NFC_NFCID1_MAXSIZE 10
+#define NFC_SENSB_RES_MAXSIZE 12
+#define NFC_SENSF_RES_MAXSIZE 18
 
 /* NFC protocols */
 #define NFC_PROTO_JEWEL                1
index 0f5ff37398206d0cb30f866244879be020b99ed5..c37d67add090b0cc45cd9555ee886e5ff7d7f091 100644 (file)
  * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
  *     or %NL80211_ATTR_MAC.
  *
- * @NL80211_CMD_GET_BEACON: retrieve beacon information (returned in a
- *     %NL80222_CMD_NEW_BEACON message)
- * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface
- *     using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD,
- *     %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL attributes.
- *     Following attributes are provided for drivers that generate full Beacon
- *     and Probe Response frames internally: %NL80211_ATTR_SSID,
+ * @NL80211_CMD_GET_BEACON: (not used)
+ * @NL80211_CMD_SET_BEACON: change the beacon on an access point interface
+ *     using the %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL
+ *     attributes. For drivers that generate the beacon and probe responses
+ *     internally, the following attributes must be provided: %NL80211_ATTR_IE,
+ *     %NL80211_ATTR_IE_PROBE_RESP and %NL80211_ATTR_IE_ASSOC_RESP.
+ * @NL80211_CMD_START_AP: Start AP operation on an AP interface, parameters
+ *     are like for %NL80211_CMD_SET_BEACON, and additionally parameters that
+ *     do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL,
+ *     %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID,
  *     %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE,
  *     %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
  *     %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
- *     %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_IE, %NL80211_ATTR_IE_PROBE_RESP,
- *     %NL80211_ATTR_IE_ASSOC_RESP.
- * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface,
- *     parameters are like for %NL80211_CMD_SET_BEACON.
- * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it
+ *     %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
+ * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
+ * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
+ * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
  *
  * @NL80211_CMD_GET_STATION: Get station attributes for station identified by
  *     %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
@@ -565,8 +567,10 @@ enum nl80211_commands {
 
        NL80211_CMD_GET_BEACON,
        NL80211_CMD_SET_BEACON,
-       NL80211_CMD_NEW_BEACON,
-       NL80211_CMD_DEL_BEACON,
+       NL80211_CMD_START_AP,
+       NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP,
+       NL80211_CMD_STOP_AP,
+       NL80211_CMD_DEL_BEACON = NL80211_CMD_STOP_AP,
 
        NL80211_CMD_GET_STATION,
        NL80211_CMD_SET_STATION,
@@ -1193,6 +1197,16 @@ enum nl80211_commands {
  * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of
  *      up to 16 TIDs.
  *
+ * @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be
+ *     used by the drivers which has MLME in firmware and does not have support
+ *     to report per station tx/rx activity to free up the staion entry from
+ *     the list. This needs to be used when the driver advertises the
+ *     capability to timeout the stations.
+ *
+ * @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int);
+ *     this attribute is (depending on the driver capabilities) added to
+ *     received frames indicated with %NL80211_CMD_FRAME.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1438,6 +1452,10 @@ enum nl80211_attrs {
 
        NL80211_ATTR_NOACK_MAP,
 
+       NL80211_ATTR_INACTIVITY_TIMEOUT,
+
+       NL80211_ATTR_RX_SIGNAL_DBM,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -1475,6 +1493,7 @@ enum nl80211_attrs {
 #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
 
 #define NL80211_MAX_SUPP_RATES                 32
+#define NL80211_MAX_SUPP_HT_RATES              77
 #define NL80211_MAX_SUPP_REG_RULES             32
 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY      0
 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY    16
@@ -2104,6 +2123,13 @@ enum nl80211_mntr_flags {
  * TUs) during which a mesh STA can send only one Action frame containing a
  * PERR element.
  *
+ * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding
+ * or forwarding entity (default is TRUE - forwarding entity)
+ *
+ * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the
+ * threshold for average signal strength of candidate station to establish
+ * a peer link.
+ *
  * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
  *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -2128,6 +2154,8 @@ enum nl80211_meshconf_params {
        NL80211_MESHCONF_HWMP_RANN_INTERVAL,
        NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
        NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
+       NL80211_MESHCONF_FORWARDING,
+       NL80211_MESHCONF_RSSI_THRESHOLD,
 
        /* keep last */
        __NL80211_MESHCONF_ATTR_AFTER_LAST,
@@ -2401,12 +2429,15 @@ enum nl80211_key_attributes {
  *     in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with
  *     1 = 500 kbps) but without the IE length restriction (at most
  *     %NL80211_MAX_SUPP_RATES in a single array).
+ * @NL80211_TXRATE_MCS: HT (MCS) rates allowed for TX rate selection
+ *     in an array of MCS numbers.
  * @__NL80211_TXRATE_AFTER_LAST: internal
  * @NL80211_TXRATE_MAX: highest TX rate attribute
  */
 enum nl80211_tx_rate_attributes {
        __NL80211_TXRATE_INVALID,
        NL80211_TXRATE_LEGACY,
+       NL80211_TXRATE_MCS,
 
        /* keep last */
        __NL80211_TXRATE_AFTER_LAST,
@@ -2792,10 +2823,13 @@ enum nl80211_ap_sme_features {
  *     TX status to the socket error queue when requested with the
  *     socket option.
  * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates.
+ * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up
+ *     the connected inactive stations in AP mode.
  */
 enum nl80211_feature_flags {
        NL80211_FEATURE_SK_TX_STATUS    = 1 << 0,
        NL80211_FEATURE_HT_IBSS         = 1 << 1,
+       NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2,
 };
 
 /**
index dcf35b0f303aabef3698b0f7b06d4568748b87fb..d2768318002519510971a60a156ff32591f6790c 100644 (file)
@@ -16,6 +16,12 @@ struct pcmcia_device;
 struct ssb_bus;
 struct ssb_driver;
 
+struct ssb_sprom_core_pwr_info {
+       u8 itssi_2g, itssi_5g;
+       u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh;
+       u16 pa_2g[4], pa_5gl[4], pa_5g[4], pa_5gh[4];
+};
+
 struct ssb_sprom {
        u8 revision;
        u8 il0mac[6];           /* MAC address for 802.11b/g */
@@ -26,9 +32,12 @@ struct ssb_sprom {
        u8 et0mdcport;          /* MDIO for enet0 */
        u8 et1mdcport;          /* MDIO for enet1 */
        u16 board_rev;          /* Board revision number from SPROM. */
+       u16 board_num;          /* Board number from SPROM. */
+       u16 board_type;         /* Board type from SPROM. */
        u8 country_code;        /* Country Code */
-       u16 leddc_on_time;      /* LED Powersave Duty Cycle On Count */
-       u16 leddc_off_time;     /* LED Powersave Duty Cycle Off Count */
+       char alpha2[2];         /* Country Code as two chars like EU or US */
+       u8 leddc_on_time;       /* LED Powersave Duty Cycle On Count */
+       u8 leddc_off_time;      /* LED Powersave Duty Cycle Off Count */
        u8 ant_available_a;     /* 2GHz antenna available bits (up to 4) */
        u8 ant_available_bg;    /* 5GHz antenna available bits (up to 4) */
        u16 pa0b0;
@@ -47,10 +56,10 @@ struct ssb_sprom {
        u8 gpio1;               /* GPIO pin 1 */
        u8 gpio2;               /* GPIO pin 2 */
        u8 gpio3;               /* GPIO pin 3 */
-       u16 maxpwr_bg;          /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
-       u16 maxpwr_al;          /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
-       u16 maxpwr_a;           /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
-       u16 maxpwr_ah;          /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
+       u8 maxpwr_bg;           /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
+       u8 maxpwr_al;           /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
+       u8 maxpwr_a;            /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
+       u8 maxpwr_ah;           /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
        u8 itssi_a;             /* Idle TSSI Target for A-PHY */
        u8 itssi_bg;            /* Idle TSSI Target for B/G-PHY */
        u8 tri2g;               /* 2.4GHz TX isolation */
@@ -61,8 +70,8 @@ struct ssb_sprom {
        u8 txpid5gl[4];         /* 4.9 - 5.1GHz TX power index */
        u8 txpid5g[4];          /* 5.1 - 5.5GHz TX power index */
        u8 txpid5gh[4];         /* 5.5 - ...GHz TX power index */
-       u8 rxpo2g;              /* 2GHz RX power offset */
-       u8 rxpo5g;              /* 5GHz RX power offset */
+       s8 rxpo2g;              /* 2GHz RX power offset */
+       s8 rxpo5g;              /* 5GHz RX power offset */
        u8 rssisav2g;           /* 2GHz RSSI params */
        u8 rssismc2g;
        u8 rssismf2g;
@@ -82,16 +91,13 @@ struct ssb_sprom {
        u16 boardflags2_hi;     /* Board flags (bits 48-63) */
        /* TODO store board flags in a single u64 */
 
+       struct ssb_sprom_core_pwr_info core_pwr_info[4];
+
        /* Antenna gain values for up to 4 antennas
         * on each band. Values in dBm/4 (Q5.2). Negative gain means the
         * loss in the connectors is bigger than the gain. */
        struct {
-               struct {
-                       s8 a0, a1, a2, a3;
-               } ghz24;        /* 2.4GHz band */
-               struct {
-                       s8 a0, a1, a2, a3;
-               } ghz5;         /* 5GHz band */
+               s8 a0, a1, a2, a3;
        } antenna_gain;
 
        struct {
@@ -103,7 +109,79 @@ struct ssb_sprom {
                } ghz5;
        } fem;
 
-       /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
+       u16 mcs2gpo[8];
+       u16 mcs5gpo[8];
+       u16 mcs5glpo[8];
+       u16 mcs5ghpo[8];
+       u8 opo;
+
+       u8 rxgainerr2ga[3];
+       u8 rxgainerr5gla[3];
+       u8 rxgainerr5gma[3];
+       u8 rxgainerr5gha[3];
+       u8 rxgainerr5gua[3];
+
+       u8 noiselvl2ga[3];
+       u8 noiselvl5gla[3];
+       u8 noiselvl5gma[3];
+       u8 noiselvl5gha[3];
+       u8 noiselvl5gua[3];
+
+       u8 regrev;
+       u8 txchain;
+       u8 rxchain;
+       u8 antswitch;
+       u16 cddpo;
+       u16 stbcpo;
+       u16 bw40po;
+       u16 bwduppo;
+
+       u8 tempthresh;
+       u8 tempoffset;
+       u16 rawtempsense;
+       u8 measpower;
+       u8 tempsense_slope;
+       u8 tempcorrx;
+       u8 tempsense_option;
+       u8 freqoffset_corr;
+       u8 iqcal_swp_dis;
+       u8 hw_iqcal_en;
+       u8 elna2g;
+       u8 elna5g;
+       u8 phycal_tempdelta;
+       u8 temps_period;
+       u8 temps_hysteresis;
+       u8 measpower1;
+       u8 measpower2;
+       u8 pcieingress_war;
+
+       /* power per rate from sromrev 9 */
+       u16 cckbw202gpo;
+       u16 cckbw20ul2gpo;
+       u32 legofdmbw202gpo;
+       u32 legofdmbw20ul2gpo;
+       u32 legofdmbw205glpo;
+       u32 legofdmbw20ul5glpo;
+       u32 legofdmbw205gmpo;
+       u32 legofdmbw20ul5gmpo;
+       u32 legofdmbw205ghpo;
+       u32 legofdmbw20ul5ghpo;
+       u32 mcsbw202gpo;
+       u32 mcsbw20ul2gpo;
+       u32 mcsbw402gpo;
+       u32 mcsbw205glpo;
+       u32 mcsbw20ul5glpo;
+       u32 mcsbw405glpo;
+       u32 mcsbw205gmpo;
+       u32 mcsbw20ul5gmpo;
+       u32 mcsbw405gmpo;
+       u32 mcsbw205ghpo;
+       u32 mcsbw20ul5ghpo;
+       u32 mcsbw405ghpo;
+       u16 mcs32po;
+       u16 legofdm40duppo;
+       u8 sar2g;
+       u8 sar5g;
 };
 
 /* Information about the PCB the circuitry is soldered on. */
index c814ae6eeb2292df3cb8080b0a10bf04726418fd..40b1ef8595ee9518bda1325765e01a0b3bc355e8 100644 (file)
 #define SSB_SPROM8_TS_SLP_OPT_CORRX    0x00B6
 #define SSB_SPROM8_FOC_HWIQ_IQSWP      0x00B8
 #define SSB_SPROM8_PHYCAL_TEMPDELTA    0x00BA
+
+/* There are 4 blocks with power info sharing the same layout */
+#define SSB_SROM8_PWR_INFO_CORE0       0x00C0
+#define SSB_SROM8_PWR_INFO_CORE1       0x00E0
+#define SSB_SROM8_PWR_INFO_CORE2       0x0100
+#define SSB_SROM8_PWR_INFO_CORE3       0x0120
+
+#define SSB_SROM8_2G_MAXP_ITSSI                0x00
+#define  SSB_SPROM8_2G_MAXP            0x00FF
+#define  SSB_SPROM8_2G_ITSSI           0xFF00
+#define  SSB_SPROM8_2G_ITSSI_SHIFT     8
+#define SSB_SROM8_2G_PA_0              0x02    /* 2GHz power amp settings */
+#define SSB_SROM8_2G_PA_1              0x04
+#define SSB_SROM8_2G_PA_2              0x06
+#define SSB_SROM8_5G_MAXP_ITSSI                0x08    /* 5GHz ITSSI and 5.3GHz Max Power */
+#define  SSB_SPROM8_5G_MAXP            0x00FF
+#define  SSB_SPROM8_5G_ITSSI           0xFF00
+#define  SSB_SPROM8_5G_ITSSI_SHIFT     8
+#define SSB_SPROM8_5GHL_MAXP           0x0A    /* 5.2GHz and 5.8GHz Max Power */
+#define  SSB_SPROM8_5GH_MAXP           0x00FF
+#define  SSB_SPROM8_5GL_MAXP           0xFF00
+#define  SSB_SPROM8_5GL_MAXP_SHIFT     8
+#define SSB_SROM8_5G_PA_0              0x0C    /* 5.3GHz power amp settings */
+#define SSB_SROM8_5G_PA_1              0x0E
+#define SSB_SROM8_5G_PA_2              0x10
+#define SSB_SROM8_5GL_PA_0             0x12    /* 5.2GHz power amp settings */
+#define SSB_SROM8_5GL_PA_1             0x14
+#define SSB_SROM8_5GL_PA_2             0x16
+#define SSB_SROM8_5GH_PA_0             0x18    /* 5.8GHz power amp settings */
+#define SSB_SROM8_5GH_PA_1             0x1A
+#define SSB_SROM8_5GH_PA_2             0x1C
+
+/* TODO: Make it deprecated */
 #define SSB_SPROM8_MAXP_BG             0x00C0  /* Max Power 2GHz in path 1 */
 #define  SSB_SPROM8_MAXP_BG_MASK       0x00FF  /* Mask for Max Power 2GHz */
 #define  SSB_SPROM8_ITSSI_BG           0xFF00  /* Mask for path 1 itssi_bg */
 #define SSB_SPROM8_PA1HIB0             0x00D8  /* 5.8GHz power amp settings */
 #define SSB_SPROM8_PA1HIB1             0x00DA
 #define SSB_SPROM8_PA1HIB2             0x00DC
+
 #define SSB_SPROM8_CCK2GPO             0x0140  /* CCK power offset */
 #define SSB_SPROM8_OFDM2GPO            0x0142  /* 2.4GHz OFDM power offset */
 #define SSB_SPROM8_OFDM5GPO            0x0146  /* 5.3GHz OFDM power offset */
index abaad6ed9b83e7b65da14b7a30ae3a175f2992b4..4a82ca0bb0b209a12c65a83b42138098e6572ad1 100644 (file)
@@ -256,4 +256,6 @@ void l2cap_exit(void);
 int sco_init(void);
 void sco_exit(void);
 
+void bt_sock_reclassify_lock(struct sock *sk, int proto);
+
 #endif /* __BLUETOOTH_H */
index ea9231f4935feba9ebd791e4d12287cc24284fd6..453893b3120ef6b81d024047a420802dedcb9247 100644 (file)
@@ -540,7 +540,7 @@ void hci_conn_put_device(struct hci_conn *conn);
 static inline void hci_conn_hold(struct hci_conn *conn)
 {
        atomic_inc(&conn->refcnt);
-       cancel_delayed_work_sync(&conn->disc_work);
+       cancel_delayed_work(&conn->disc_work);
 }
 
 static inline void hci_conn_put(struct hci_conn *conn)
@@ -559,9 +559,9 @@ static inline void hci_conn_put(struct hci_conn *conn)
                } else {
                        timeo = msecs_to_jiffies(10);
                }
-               cancel_delayed_work_sync(&conn->disc_work);
+               cancel_delayed_work(&conn->disc_work);
                queue_delayed_work(conn->hdev->workqueue,
-                                       &conn->disc_work, jiffies + timeo);
+                                       &conn->disc_work, timeo);
        }
 }
 
index 68f5891506925f3101389b2afed34900231291c2..b1664ed884e68c461088217b9d97915e519592f0 100644 (file)
@@ -611,7 +611,7 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
 {
        BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
 
-       if (!__cancel_delayed_work(work))
+       if (!cancel_delayed_work(work))
                l2cap_chan_hold(chan);
        schedule_delayed_work(work, timeout);
 }
@@ -619,20 +619,20 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
 static inline void l2cap_clear_timer(struct l2cap_chan *chan,
                                        struct delayed_work *work)
 {
-       if (__cancel_delayed_work(work))
+       if (cancel_delayed_work(work))
                l2cap_chan_put(chan);
 }
 
 #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
 #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
 #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
-               L2CAP_DEFAULT_RETRANS_TO);
+               msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
 #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
 #define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
-               L2CAP_DEFAULT_MONITOR_TO);
+               msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
 #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
 #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
-               L2CAP_DEFAULT_ACK_TO);
+               msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
 #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
 
 static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
@@ -834,7 +834,7 @@ int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid);
 struct l2cap_chan *l2cap_chan_create(struct sock *sk);
 void l2cap_chan_close(struct l2cap_chan *chan, int reason);
 void l2cap_chan_destroy(struct l2cap_chan *chan);
-inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
                                                                bdaddr_t *dst);
 int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
                                                                u32 priority);
index a067d30ce73e88fa86dce220e3f2002cac5be878..57c9fddc2acf41514a067622e33cf418d3b3d9a6 100644 (file)
@@ -120,6 +120,7 @@ enum ieee80211_channel_flags {
  * @band: band this channel belongs to.
  * @max_antenna_gain: maximum antenna gain in dBi
  * @max_power: maximum transmission power (in dBm)
+ * @max_reg_power: maximum regulatory transmission power (in dBm)
  * @beacon_found: helper to regulatory code to indicate when a beacon
  *     has been found on this channel. Use regulatory_hint_found_beacon()
  *     to enable this, this is useful only on 5 GHz band.
@@ -133,6 +134,7 @@ struct ieee80211_channel {
        u32 flags;
        int max_antenna_gain;
        int max_power;
+       int max_reg_power;
        bool beacon_found;
        u32 orig_flags;
        int orig_mag, orig_mpwr;
@@ -364,25 +366,13 @@ struct cfg80211_crypto_settings {
 };
 
 /**
- * struct beacon_parameters - beacon parameters
- *
- * Used to configure the beacon for an interface.
- *
+ * struct cfg80211_beacon_data - beacon data
  * @head: head portion of beacon (before TIM IE)
  *     or %NULL if not changed
  * @tail: tail portion of beacon (after TIM IE)
  *     or %NULL if not changed
- * @interval: beacon interval or zero if not changed
- * @dtim_period: DTIM period or zero if not changed
  * @head_len: length of @head
  * @tail_len: length of @tail
- * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from
- *     user space)
- * @ssid_len: length of @ssid
- * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames
- * @crypto: crypto settings
- * @privacy: the BSS uses privacy
- * @auth_type: Authentication type (algorithm)
  * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL
  * @beacon_ies_len: length of beacon_ies in octets
  * @proberesp_ies: extra information element(s) to add into Probe Response
@@ -394,24 +384,48 @@ struct cfg80211_crypto_settings {
  * @probe_resp_len: length of probe response template (@probe_resp)
  * @probe_resp: probe response template (AP mode only)
  */
-struct beacon_parameters {
-       u8 *head, *tail;
-       int interval, dtim_period;
-       int head_len, tail_len;
+struct cfg80211_beacon_data {
+       const u8 *head, *tail;
+       const u8 *beacon_ies;
+       const u8 *proberesp_ies;
+       const u8 *assocresp_ies;
+       const u8 *probe_resp;
+
+       size_t head_len, tail_len;
+       size_t beacon_ies_len;
+       size_t proberesp_ies_len;
+       size_t assocresp_ies_len;
+       size_t probe_resp_len;
+};
+
+/**
+ * struct cfg80211_ap_settings - AP configuration
+ *
+ * Used to configure an AP interface.
+ *
+ * @beacon: beacon data
+ * @beacon_interval: beacon interval
+ * @dtim_period: DTIM period
+ * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from
+ *     user space)
+ * @ssid_len: length of @ssid
+ * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames
+ * @crypto: crypto settings
+ * @privacy: the BSS uses privacy
+ * @auth_type: Authentication type (algorithm)
+ * @inactivity_timeout: time in seconds to determine station's inactivity.
+ */
+struct cfg80211_ap_settings {
+       struct cfg80211_beacon_data beacon;
+
+       int beacon_interval, dtim_period;
        const u8 *ssid;
        size_t ssid_len;
        enum nl80211_hidden_ssid hidden_ssid;
        struct cfg80211_crypto_settings crypto;
        bool privacy;
        enum nl80211_auth_type auth_type;
-       const u8 *beacon_ies;
-       size_t beacon_ies_len;
-       const u8 *proberesp_ies;
-       size_t proberesp_ies_len;
-       const u8 *assocresp_ies;
-       size_t assocresp_ies_len;
-       int probe_resp_len;
-       u8 *probe_resp;
+       int inactivity_timeout;
 };
 
 /**
@@ -796,6 +810,8 @@ struct mesh_config {
         * mesh gate, but not necessarily using the gate announcement protocol.
         * Still keeping the same nomenclature to be in sync with the spec. */
        bool  dot11MeshGateAnnouncementProtocol;
+       bool dot11MeshForwarding;
+       s32 rssi_threshold;
 };
 
 /**
@@ -1036,10 +1052,6 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
  * @key_len: length of WEP key for shared key authentication
  * @key_idx: index of WEP key for shared key authentication
  * @key: WEP key for shared key authentication
- * @local_state_change: This is a request for a local state only, i.e., no
- *     Authentication frame is to be transmitted and authentication state is
- *     to be changed without having to wait for a response from the peer STA
- *     (AP).
  */
 struct cfg80211_auth_request {
        struct cfg80211_bss *bss;
@@ -1048,7 +1060,6 @@ struct cfg80211_auth_request {
        enum nl80211_auth_type auth_type;
        const u8 *key;
        u8 key_len, key_idx;
-       bool local_state_change;
 };
 
 /**
@@ -1065,7 +1076,11 @@ enum cfg80211_assoc_req_flags {
  *
  * This structure provides information needed to complete IEEE 802.11
  * (re)association.
- * @bss: The BSS to associate with.
+ * @bss: The BSS to associate with. If the call is successful the driver
+ *     is given a reference that it must release, normally via a call to
+ *     cfg80211_send_rx_assoc(), or, if association timed out, with a
+ *     call to cfg80211_put_bss() (in addition to calling
+ *     cfg80211_send_assoc_timeout())
  * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
  * @ie_len: Length of ie buffer in octets
  * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
@@ -1093,19 +1108,16 @@ struct cfg80211_assoc_request {
  * This structure provides information needed to complete IEEE 802.11
  * deauthentication.
  *
- * @bss: the BSS to deauthenticate from
+ * @bssid: the BSSID of the BSS to deauthenticate from
  * @ie: Extra IEs to add to Deauthentication frame or %NULL
  * @ie_len: Length of ie buffer in octets
  * @reason_code: The reason code for the deauthentication
- * @local_state_change: This is a request for a local state only, i.e., no
- *     Deauthentication frame is to be transmitted.
  */
 struct cfg80211_deauth_request {
-       struct cfg80211_bss *bss;
+       const u8 *bssid;
        const u8 *ie;
        size_t ie_len;
        u16 reason_code;
-       bool local_state_change;
 };
 
 /**
@@ -1148,6 +1160,10 @@ struct cfg80211_disassoc_request {
  * @beacon_interval: beacon interval to use
  * @privacy: this is a protected network, keys will be configured
  *     after joining
+ * @control_port: whether user space controls IEEE 802.1X port, i.e.,
+ *     sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
+ *     required to assume that the port is unauthorized until authorized by
+ *     user space. Otherwise, port is marked authorized by default.
  * @basic_rates: bitmap of basic rates to use when creating the IBSS
  * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
  */
@@ -1162,6 +1178,7 @@ struct cfg80211_ibss_params {
        u32 basic_rates;
        bool channel_fixed;
        bool privacy;
+       bool control_port;
        int mcast_rate[IEEE80211_NUM_BANDS];
 };
 
@@ -1229,8 +1246,7 @@ enum wiphy_params_flags {
 struct cfg80211_bitrate_mask {
        struct {
                u32 legacy;
-               /* TODO: add support for masking MCS rates; e.g.: */
-               /* u8 mcs[IEEE80211_HT_MCS_MASK_LEN]; */
+               u8 mcs[IEEE80211_HT_MCS_MASK_LEN];
        } control[IEEE80211_NUM_BANDS];
 };
 /**
@@ -1343,12 +1359,10 @@ struct cfg80211_gtk_rekey_data {
  *
  * @set_rekey_data: give the data necessary for GTK rekeying to the driver
  *
- * @add_beacon: Add a beacon with given parameters, @head, @interval
- *     and @dtim_period will be valid, @tail is optional.
- * @set_beacon: Change the beacon parameters for an access point mode
- *     interface. This should reject the call when no beacon has been
- *     configured.
- * @del_beacon: Remove beacon configuration and stop sending the beacon.
+ * @start_ap: Start acting in AP mode defined by the parameters.
+ * @change_beacon: Change the beacon parameters for an access point mode
+ *     interface. This should reject the call when AP mode wasn't started.
+ * @stop_ap: Stop being an AP, including stopping beaconing.
  *
  * @add_station: Add a new station.
  * @del_station: Remove a station; @mac may be NULL to remove all stations.
@@ -1515,11 +1529,11 @@ struct cfg80211_ops {
                                        struct net_device *netdev,
                                        u8 key_index);
 
-       int     (*add_beacon)(struct wiphy *wiphy, struct net_device *dev,
-                             struct beacon_parameters *info);
-       int     (*set_beacon)(struct wiphy *wiphy, struct net_device *dev,
-                             struct beacon_parameters *info);
-       int     (*del_beacon)(struct wiphy *wiphy, struct net_device *dev);
+       int     (*start_ap)(struct wiphy *wiphy, struct net_device *dev,
+                           struct cfg80211_ap_settings *settings);
+       int     (*change_beacon)(struct wiphy *wiphy, struct net_device *dev,
+                                struct cfg80211_beacon_data *info);
+       int     (*stop_ap)(struct wiphy *wiphy, struct net_device *dev);
 
 
        int     (*add_station)(struct wiphy *wiphy, struct net_device *dev,
@@ -1574,11 +1588,9 @@ struct cfg80211_ops {
        int     (*assoc)(struct wiphy *wiphy, struct net_device *dev,
                         struct cfg80211_assoc_request *req);
        int     (*deauth)(struct wiphy *wiphy, struct net_device *dev,
-                         struct cfg80211_deauth_request *req,
-                         void *cookie);
+                         struct cfg80211_deauth_request *req);
        int     (*disassoc)(struct wiphy *wiphy, struct net_device *dev,
-                           struct cfg80211_disassoc_request *req,
-                           void *cookie);
+                           struct cfg80211_disassoc_request *req);
 
        int     (*connect)(struct wiphy *wiphy, struct net_device *dev,
                           struct cfg80211_connect_params *sme);
@@ -2204,8 +2216,6 @@ struct cfg80211_conn;
 struct cfg80211_internal_bss;
 struct cfg80211_cached_keys;
 
-#define MAX_AUTH_BSSES         4
-
 /**
  * struct wireless_dev - wireless per-netdev state
  *
@@ -2269,8 +2279,6 @@ struct wireless_dev {
        struct list_head event_list;
        spinlock_t event_lock;
 
-       struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES];
-       struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];
        struct cfg80211_internal_bss *current_bss; /* associated / joined */
        struct ieee80211_channel *channel;
 
@@ -2725,6 +2733,20 @@ struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
                                       struct ieee80211_channel *channel,
                                       const u8 *meshid, size_t meshidlen,
                                       const u8 *meshcfg);
+/**
+ * cfg80211_ref_bss - reference BSS struct
+ * @bss: the BSS struct to reference
+ *
+ * Increments the refcount of the given BSS struct.
+ */
+void cfg80211_ref_bss(struct cfg80211_bss *bss);
+
+/**
+ * cfg80211_put_bss - unref BSS struct
+ * @bss: the BSS struct
+ *
+ * Decrements the refcount of the given BSS struct.
+ */
 void cfg80211_put_bss(struct cfg80211_bss *bss);
 
 /**
@@ -2761,21 +2783,11 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
  */
 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
 
-/**
- * __cfg80211_auth_canceled - notify cfg80211 that authentication was canceled
- * @dev: network device
- * @addr: The MAC address of the device with which the authentication timed out
- *
- * When a pending authentication had no action yet, the driver may decide
- * to not send a deauth frame, but in that case must calls this function
- * to tell cfg80211 about this decision. It is only valid to call this
- * function within the deauth() callback.
- */
-void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr);
-
 /**
  * cfg80211_send_rx_assoc - notification of processed association
  * @dev: network device
+ * @bss: the BSS struct association was requested for, the struct reference
+ *     is owned by cfg80211 after this call
  * @buf: (re)association response frame (header + body)
  * @len: length of the frame data
  *
@@ -2784,7 +2796,8 @@ void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr);
  * function or cfg80211_send_assoc_timeout() to indicate the result of
  * cfg80211_ops::assoc() call. This function may sleep.
  */
-void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);
+void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
+                           const u8 *buf, size_t len);
 
 /**
  * cfg80211_send_assoc_timeout - notification of timed out association
@@ -3176,6 +3189,7 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp);
  * cfg80211_rx_mgmt - notification of received, unprocessed management frame
  * @dev: network device
  * @freq: Frequency on which the frame was received in MHz
+ * @sig_dbm: signal strength in mBm, or 0 if unknown
  * @buf: Management frame (header + body)
  * @len: length of the frame data
  * @gfp: context flags
@@ -3188,8 +3202,8 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp);
  * This function is called whenever an Action frame is received for a station
  * mode interface, but is not processed in kernel.
  */
-bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
-                     size_t len, gfp_t gfp);
+bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_dbm,
+                     const u8 *buf, size_t len, gfp_t gfp);
 
 /**
  * cfg80211_mgmt_tx_status - notification of TX status for management frame
@@ -3302,6 +3316,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
  * @frame: the frame
  * @len: length of the frame
  * @freq: frequency the frame was received on
+ * @sig_dbm: signal strength in mBm, or 0 if unknown
  * @gfp: allocation flags
  *
  * Use this function to report to userspace when a beacon was
@@ -3310,7 +3325,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
  */
 void cfg80211_report_obss_beacon(struct wiphy *wiphy,
                                 const u8 *frame, size_t len,
-                                int freq, gfp_t gfp);
+                                int freq, int sig_dbm, gfp_t gfp);
 
 /*
  * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used
@@ -3322,6 +3337,14 @@ int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
                                 struct ieee80211_channel *chan,
                                 enum nl80211_channel_type channel_type);
 
+/*
+ * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units)
+ * @rate: given rate_info to calculate bitrate from
+ *
+ * return 0 if MCS index >= 32
+ */
+u16 cfg80211_calculate_bitrate(struct rate_info *rate);
+
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
 /* wiphy_printk helpers, similar to dev_printk */
index d49928ba5d09fa379fd5db91ea173cfe08d57475..f7917f765cbcaf48fb9e7b6298efe7bec965415d 100644 (file)
@@ -341,9 +341,9 @@ struct ieee80211_bss_conf {
  *     used to indicate that a frame was already retried due to PS
  * @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211,
  *     used to indicate frame should not be encrypted
- * @IEEE80211_TX_CTL_POLL_RESPONSE: This frame is a response to a poll
- *     frame (PS-Poll or uAPSD) and should be sent although the station
- *     is in powersave mode.
+ * @IEEE80211_TX_CTL_NO_PS_BUFFER: This frame is a response to a poll
+ *     frame (PS-Poll or uAPSD) or a non-bufferable MMPDU and must
+ *     be sent although the station is in powersave mode.
  * @IEEE80211_TX_CTL_MORE_FRAMES: More frames will be passed to the
  *     transmit function after the current frame, this can be used
  *     by drivers to kick the DMA queue only if unset or when the
@@ -399,7 +399,7 @@ enum mac80211_tx_control_flags {
        IEEE80211_TX_INTFL_NEED_TXPROCESSING    = BIT(14),
        IEEE80211_TX_INTFL_RETRIED              = BIT(15),
        IEEE80211_TX_INTFL_DONT_ENCRYPT         = BIT(16),
-       IEEE80211_TX_CTL_POLL_RESPONSE          = BIT(17),
+       IEEE80211_TX_CTL_NO_PS_BUFFER           = BIT(17),
        IEEE80211_TX_CTL_MORE_FRAMES            = BIT(18),
        IEEE80211_TX_INTFL_RETRANSMISSION       = BIT(19),
        /* hole at 20, use later */
@@ -425,7 +425,7 @@ enum mac80211_tx_control_flags {
        IEEE80211_TX_CTL_SEND_AFTER_DTIM | IEEE80211_TX_CTL_AMPDU |           \
        IEEE80211_TX_STAT_TX_FILTERED | IEEE80211_TX_STAT_ACK |               \
        IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_STAT_AMPDU_NO_BACK |           \
-       IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_POLL_RESPONSE |   \
+       IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_NO_PS_BUFFER |    \
        IEEE80211_TX_CTL_MORE_FRAMES | IEEE80211_TX_CTL_LDPC |                \
        IEEE80211_TX_CTL_STBC | IEEE80211_TX_STATUS_EOSP)
 
@@ -659,6 +659,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
  * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
  * @RX_FLAG_40MHZ: HT40 (40 MHz) was used
  * @RX_FLAG_SHORT_GI: Short guard interval was used
+ * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present.
+ *     Valid only for data frames (mainly A-MPDU)
  */
 enum mac80211_rx_flags {
        RX_FLAG_MMIC_ERROR      = 1<<0,
@@ -672,6 +674,7 @@ enum mac80211_rx_flags {
        RX_FLAG_HT              = 1<<9,
        RX_FLAG_40MHZ           = 1<<10,
        RX_FLAG_SHORT_GI        = 1<<11,
+       RX_FLAG_NO_SIGNAL_VAL   = 1<<12,
 };
 
 /**
@@ -851,6 +854,21 @@ struct ieee80211_channel_switch {
        u8 count;
 };
 
+/**
+ * enum ieee80211_vif_flags - virtual interface flags
+ *
+ * @IEEE80211_VIF_BEACON_FILTER: the device performs beacon filtering
+ *     on this virtual interface to avoid unnecessary CPU wakeups
+ * @IEEE80211_VIF_SUPPORTS_CQM_RSSI: the device can do connection quality
+ *     monitoring on this virtual interface -- i.e. it can monitor
+ *     connection quality related parameters, such as the RSSI level and
+ *     provide notifications if configured trigger levels are reached.
+ */
+enum ieee80211_vif_flags {
+       IEEE80211_VIF_BEACON_FILTER             = BIT(0),
+       IEEE80211_VIF_SUPPORTS_CQM_RSSI         = BIT(1),
+};
+
 /**
  * struct ieee80211_vif - per-interface data
  *
@@ -863,6 +881,10 @@ struct ieee80211_channel_switch {
  * @addr: address of this interface
  * @p2p: indicates whether this AP or STA interface is a p2p
  *     interface, i.e. a GO or p2p-sta respectively
+ * @driver_flags: flags/capabilities the driver has for this interface,
+ *     these need to be set (or cleared) when the interface is added
+ *     or, if supported by the driver, the interface type is changed
+ *     at runtime, mac80211 will never touch this field
  * @drv_priv: data area for driver use, will always be aligned to
  *     sizeof(void *).
  */
@@ -871,6 +893,7 @@ struct ieee80211_vif {
        struct ieee80211_bss_conf bss_conf;
        u8 addr[ETH_ALEN];
        bool p2p;
+       u32 driver_flags;
        /* must be last */
        u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
 };
@@ -961,6 +984,25 @@ enum set_key_cmd {
        SET_KEY, DISABLE_KEY,
 };
 
+/**
+ * enum ieee80211_sta_state - station state
+ *
+ * @IEEE80211_STA_NOTEXIST: station doesn't exist at all,
+ *     this is a special state for add/remove transitions
+ * @IEEE80211_STA_NONE: station exists without special state
+ * @IEEE80211_STA_AUTH: station is authenticated
+ * @IEEE80211_STA_ASSOC: station is associated
+ * @IEEE80211_STA_AUTHORIZED: station is authorized (802.1X)
+ */
+enum ieee80211_sta_state {
+       /* NOTE: These need to be ordered correctly! */
+       IEEE80211_STA_NOTEXIST,
+       IEEE80211_STA_NONE,
+       IEEE80211_STA_AUTH,
+       IEEE80211_STA_ASSOC,
+       IEEE80211_STA_AUTHORIZED,
+};
+
 /**
  * struct ieee80211_sta - station table entry
  *
@@ -1079,10 +1121,6 @@ enum sta_notify_cmd {
  * @IEEE80211_HW_MFP_CAPABLE:
  *     Hardware supports management frame protection (MFP, IEEE 802.11w).
  *
- * @IEEE80211_HW_BEACON_FILTER:
- *     Hardware supports dropping of irrelevant beacon frames to
- *     avoid waking up cpu.
- *
  * @IEEE80211_HW_SUPPORTS_STATIC_SMPS:
  *     Hardware supports static spatial multiplexing powersave,
  *     ie. can turn off all but one chain even on HT connections
@@ -1108,11 +1146,6 @@ enum sta_notify_cmd {
  *      When this flag is set, signaling beacon-loss will cause an immediate
  *      change to disassociated state.
  *
- * @IEEE80211_HW_SUPPORTS_CQM_RSSI:
- *     Hardware can do connection quality monitoring - i.e. it can monitor
- *     connection quality related parameters, such as the RSSI level and
- *     provide notifications if configured trigger levels are reached.
- *
  * @IEEE80211_HW_NEED_DTIM_PERIOD:
  *     This device needs to know the DTIM period for the BSS before
  *     associating.
@@ -1134,6 +1167,10 @@ enum sta_notify_cmd {
  * @IEEE80211_HW_TX_AMPDU_SETUP_IN_HW: The device handles TX A-MPDU session
  *     setup strictly in HW. mac80211 should not attempt to do this in
  *     software.
+ *
+ * @IEEE80211_HW_SCAN_WHILE_IDLE: The device can do hw scan while
+ *     being idle (i.e. mac80211 doesn't have to go idle-off during the
+ *     the scan).
  */
 enum ieee80211_hw_flags {
        IEEE80211_HW_HAS_RATE_CONTROL                   = 1<<0,
@@ -1150,16 +1187,17 @@ enum ieee80211_hw_flags {
        IEEE80211_HW_PS_NULLFUNC_STACK                  = 1<<11,
        IEEE80211_HW_SUPPORTS_DYNAMIC_PS                = 1<<12,
        IEEE80211_HW_MFP_CAPABLE                        = 1<<13,
-       IEEE80211_HW_BEACON_FILTER                      = 1<<14,
+       /* reuse bit 14 */
        IEEE80211_HW_SUPPORTS_STATIC_SMPS               = 1<<15,
        IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS              = 1<<16,
        IEEE80211_HW_SUPPORTS_UAPSD                     = 1<<17,
        IEEE80211_HW_REPORTS_TX_ACK_STATUS              = 1<<18,
        IEEE80211_HW_CONNECTION_MONITOR                 = 1<<19,
-       IEEE80211_HW_SUPPORTS_CQM_RSSI                  = 1<<20,
+       /* reuse bit 20 */
        IEEE80211_HW_SUPPORTS_PER_STA_GTK               = 1<<21,
        IEEE80211_HW_AP_LINK_PS                         = 1<<22,
        IEEE80211_HW_TX_AMPDU_SETUP_IN_HW               = 1<<23,
+       IEEE80211_HW_SCAN_WHILE_IDLE                    = 1<<24,
 };
 
 /**
@@ -1446,8 +1484,8 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
  * way the host will only receive beacons where some relevant information
  * (for example ERP protection or WMM settings) have changed.
  *
- * Beacon filter support is advertised with the %IEEE80211_HW_BEACON_FILTER
- * hardware capability. The driver needs to enable beacon filter support
+ * Beacon filter support is advertised with the %IEEE80211_VIF_BEACON_FILTER
+ * interface capability. The driver needs to enable beacon filter support
  * whenever power save is enabled, that is %IEEE80211_CONF_PS is set. When
  * power save is enabled, the stack will not check for beacon loss and the
  * driver needs to notify about loss of beacons with ieee80211_beacon_loss().
@@ -1599,7 +1637,7 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
  * the station sends a PS-Poll or a uAPSD trigger frame, mac80211
  * will inform the driver of this with the @allow_buffered_frames
  * callback; this callback is optional. mac80211 will then transmit
- * the frames as usual and set the %IEEE80211_TX_CTL_POLL_RESPONSE
+ * the frames as usual and set the %IEEE80211_TX_CTL_NO_PS_BUFFER
  * on each frame. The last frame in the service period (or the only
  * response to a PS-Poll) also has %IEEE80211_TX_STATUS_EOSP set to
  * indicate that it ends the service period; as this frame must have
@@ -1607,6 +1645,9 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
  * When TX status is reported for this frame, the service period is
  * marked has having ended and a new one can be started by the peer.
  *
+ * Additionally, non-bufferable MMPDUs can also be transmitted by
+ * mac80211 with the %IEEE80211_TX_CTL_NO_PS_BUFFER set in them.
+ *
  * Another race condition can happen on some devices like iwlwifi
  * when there are frames queued for the station and it wakes up
  * or polls; the frames that are already queued could end up being
@@ -1963,6 +2004,13 @@ enum ieee80211_frame_release_type {
  *     in AP mode, this callback will not be called when the flag
  *     %IEEE80211_HW_AP_LINK_PS is set. Must be atomic.
  *
+ * @sta_state: Notifies low level driver about state transition of a
+ *     station (which can be the AP, a client, IBSS/WDS/mesh peer etc.)
+ *     This callback is mutually exclusive with @sta_add/@sta_remove.
+ *     It must not fail for down transitions but may fail for transitions
+ *     up the list of states.
+ *     The callback can sleep.
+ *
  * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
  *     bursting) for a hardware TX queue.
  *     Returns a negative error code on failure.
@@ -2098,7 +2146,7 @@ enum ieee80211_frame_release_type {
  * @allow_buffered_frames: Prepare device to allow the given number of frames
  *     to go out to the given station. The frames will be sent by mac80211
  *     via the usual TX path after this call. The TX information for frames
- *     released will also have the %IEEE80211_TX_CTL_POLL_RESPONSE flag set
+ *     released will also have the %IEEE80211_TX_CTL_NO_PS_BUFFER flag set
  *     and the last one will also have %IEEE80211_TX_STATUS_EOSP set. In case
  *     frames from multiple TIDs are released and the driver might reorder
  *     them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag
@@ -2182,6 +2230,10 @@ struct ieee80211_ops {
                          struct ieee80211_sta *sta);
        void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        enum sta_notify_cmd, struct ieee80211_sta *sta);
+       int (*sta_state)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                        struct ieee80211_sta *sta,
+                        enum ieee80211_sta_state old_state,
+                        enum ieee80211_sta_state new_state);
        int (*conf_tx)(struct ieee80211_hw *hw,
                       struct ieee80211_vif *vif, u16 queue,
                       const struct ieee80211_tx_queue_params *params);
@@ -3316,7 +3368,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
  *
  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
  *
- * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER and
+ * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER and
  * %IEEE80211_CONF_PS is set, the driver needs to inform whenever the
  * hardware is not receiving beacons with this function.
  */
@@ -3327,7 +3379,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif);
  *
  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
  *
- * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER, and
+ * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER, and
  * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver
  * needs to inform if the connection to the AP has been lost.
  *
@@ -3397,7 +3449,7 @@ void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif);
  * @rssi_event: the RSSI trigger event type
  * @gfp: context flags
  *
- * When the %IEEE80211_HW_SUPPORTS_CQM_RSSI is set, and a connection quality
+ * When the %IEEE80211_VIF_SUPPORTS_CQM_RSSI is set, and a connection quality
  * monitoring is configured with an rssi threshold, the driver will inform
  * whenever the rssi level reaches the threshold.
  */
@@ -3516,6 +3568,8 @@ enum rate_control_changed {
  * @hw: The hardware the algorithm is invoked for.
  * @sband: The band this frame is being transmitted on.
  * @bss_conf: the current BSS configuration
+ * @skb: the skb that will be transmitted, the control information in it needs
+ *     to be filled in
  * @reported_rate: The rate control algorithm can fill this in to indicate
  *     which rate should be reported to userspace as the current rate and
  *     used for rate calculations in the mesh network.
@@ -3523,12 +3577,11 @@ enum rate_control_changed {
  *     RTS threshold
  * @short_preamble: whether mac80211 will request short-preamble transmission
  *     if the selected rate supports it
- * @max_rate_idx: user-requested maximum rate (not MCS for now)
+ * @max_rate_idx: user-requested maximum (legacy) rate
  *     (deprecated; this will be removed once drivers get updated to use
  *     rate_idx_mask)
- * @rate_idx_mask: user-requested rate mask (not MCS for now)
- * @skb: the skb that will be transmitted, the control information in it needs
- *     to be filled in
+ * @rate_idx_mask: user-requested (legacy) rate mask
+ * @rate_idx_mcs_mask: user-requested MCS rate mask
  * @bss: whether this frame is sent out in AP or IBSS mode
  */
 struct ieee80211_tx_rate_control {
@@ -3540,6 +3593,7 @@ struct ieee80211_tx_rate_control {
        bool rts, short_preamble;
        u8 max_rate_idx;
        u32 rate_idx_mask;
+       u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
        bool bss;
 };
 
index 2be95e2626c0a364f7c7a8858503971be5428aff..276094b91d7ced880477730fd487f162cf5b4a6e 100644 (file)
 #define NCI_DISC_MAP_MODE_POLL                                 0x01
 #define NCI_DISC_MAP_MODE_LISTEN                               0x02
 
+/* NCI Discover Notification Type */
+#define NCI_DISCOVER_NTF_TYPE_LAST                             0x00
+#define NCI_DISCOVER_NTF_TYPE_LAST_NFCC                                0x01
+#define NCI_DISCOVER_NTF_TYPE_MORE                             0x02
+
 /* NCI Deactivation Type */
 #define NCI_DEACTIVATE_TYPE_IDLE_MODE                          0x00
 #define NCI_DEACTIVATE_TYPE_SLEEP_MODE                         0x01
@@ -207,6 +212,13 @@ struct nci_rf_disc_cmd {
        struct disc_config              disc_configs[NCI_MAX_NUM_RF_CONFIGS];
 } __packed;
 
+#define NCI_OP_RF_DISCOVER_SELECT_CMD  nci_opcode_pack(NCI_GID_RF_MGMT, 0x04)
+struct nci_rf_discover_select_cmd {
+       __u8    rf_discovery_id;
+       __u8    rf_protocol;
+       __u8    rf_interface;
+} __packed;
+
 #define NCI_OP_RF_DEACTIVATE_CMD       nci_opcode_pack(NCI_GID_RF_MGMT, 0x06)
 struct nci_rf_deactivate_cmd {
        __u8    type;
@@ -244,6 +256,8 @@ struct nci_core_init_rsp_2 {
 
 #define NCI_OP_RF_DISCOVER_RSP         nci_opcode_pack(NCI_GID_RF_MGMT, 0x03)
 
+#define NCI_OP_RF_DISCOVER_SELECT_RSP  nci_opcode_pack(NCI_GID_RF_MGMT, 0x04)
+
 #define NCI_OP_RF_DEACTIVATE_RSP       nci_opcode_pack(NCI_GID_RF_MGMT, 0x06)
 
 /* --------------------------- */
@@ -260,13 +274,15 @@ struct nci_core_conn_credit_ntf {
        struct conn_credit_entry        conn_entries[NCI_MAX_NUM_CONN];
 } __packed;
 
+#define NCI_OP_CORE_GENERIC_ERROR_NTF  nci_opcode_pack(NCI_GID_CORE, 0x07)
+
 #define NCI_OP_CORE_INTF_ERROR_NTF     nci_opcode_pack(NCI_GID_CORE, 0x08)
 struct nci_core_intf_error_ntf {
        __u8    status;
        __u8    conn_id;
 } __packed;
 
-#define NCI_OP_RF_INTF_ACTIVATED_NTF   nci_opcode_pack(NCI_GID_RF_MGMT, 0x05)
+#define NCI_OP_RF_DISCOVER_NTF         nci_opcode_pack(NCI_GID_RF_MGMT, 0x03)
 struct rf_tech_specific_params_nfca_poll {
        __u16   sens_res;
        __u8    nfcid1_len;     /* 0, 4, 7, or 10 Bytes */
@@ -275,11 +291,43 @@ struct rf_tech_specific_params_nfca_poll {
        __u8    sel_res;
 } __packed;
 
+struct rf_tech_specific_params_nfcb_poll {
+       __u8    sensb_res_len;
+       __u8    sensb_res[12];  /* 11 or 12 Bytes */
+} __packed;
+
+struct rf_tech_specific_params_nfcf_poll {
+       __u8    bit_rate;
+       __u8    sensf_res_len;
+       __u8    sensf_res[18];  /* 16 or 18 Bytes */
+} __packed;
+
+struct nci_rf_discover_ntf {
+       __u8    rf_discovery_id;
+       __u8    rf_protocol;
+       __u8    rf_tech_and_mode;
+       __u8    rf_tech_specific_params_len;
+
+       union {
+               struct rf_tech_specific_params_nfca_poll nfca_poll;
+               struct rf_tech_specific_params_nfcb_poll nfcb_poll;
+               struct rf_tech_specific_params_nfcf_poll nfcf_poll;
+       } rf_tech_specific_params;
+
+       __u8    ntf_type;
+} __packed;
+
+#define NCI_OP_RF_INTF_ACTIVATED_NTF   nci_opcode_pack(NCI_GID_RF_MGMT, 0x05)
 struct activation_params_nfca_poll_iso_dep {
        __u8    rats_res_len;
        __u8    rats_res[20];
 };
 
+struct activation_params_nfcb_poll_iso_dep {
+       __u8    attrib_res_len;
+       __u8    attrib_res[50];
+};
+
 struct nci_rf_intf_activated_ntf {
        __u8    rf_discovery_id;
        __u8    rf_interface;
@@ -291,6 +339,8 @@ struct nci_rf_intf_activated_ntf {
 
        union {
                struct rf_tech_specific_params_nfca_poll nfca_poll;
+               struct rf_tech_specific_params_nfcb_poll nfcb_poll;
+               struct rf_tech_specific_params_nfcf_poll nfcf_poll;
        } rf_tech_specific_params;
 
        __u8    data_exch_rf_tech_and_mode;
@@ -300,6 +350,7 @@ struct nci_rf_intf_activated_ntf {
 
        union {
                struct activation_params_nfca_poll_iso_dep nfca_poll_iso_dep;
+               struct activation_params_nfcb_poll_iso_dep nfcb_poll_iso_dep;
        } activation_params;
 
 } __packed;
index bccd89e9d4c2702851895f4ce9f1ff14729f2ed5..feba74027ff8bc18674c68625f8f6e5a9cd6562f 100644 (file)
 #include <net/nfc/nfc.h>
 #include <net/nfc/nci.h>
 
-/* NCI device state */
-enum {
+/* NCI device flags */
+enum nci_flag {
        NCI_INIT,
        NCI_UP,
+       NCI_DATA_EXCHANGE,
+       NCI_DATA_EXCHANGE_TO,
+};
+
+/* NCI device states */
+enum nci_state {
+       NCI_IDLE,
        NCI_DISCOVERY,
+       NCI_W4_ALL_DISCOVERIES,
+       NCI_W4_HOST_SELECT,
        NCI_POLL_ACTIVE,
-       NCI_DATA_EXCHANGE,
 };
 
 /* NCI timeouts */
 #define NCI_RESET_TIMEOUT                      5000
 #define NCI_INIT_TIMEOUT                       5000
 #define NCI_RF_DISC_TIMEOUT                    5000
-#define NCI_RF_DEACTIVATE_TIMEOUT              5000
+#define NCI_RF_DISC_SELECT_TIMEOUT             5000
+#define NCI_RF_DEACTIVATE_TIMEOUT              30000
 #define NCI_CMD_TIMEOUT                                5000
+#define NCI_DATA_TIMEOUT                       700
 
 struct nci_dev;
 
@@ -59,6 +69,7 @@ struct nci_ops {
 };
 
 #define NCI_MAX_SUPPORTED_RF_INTERFACES                4
+#define NCI_MAX_DISCOVERED_TARGETS             10
 
 /* NCI Core structures */
 struct nci_dev {
@@ -68,12 +79,14 @@ struct nci_dev {
        int                     tx_headroom;
        int                     tx_tailroom;
 
+       atomic_t                state;
        unsigned long           flags;
 
        atomic_t                cmd_cnt;
        atomic_t                credits_cnt;
 
        struct timer_list       cmd_timer;
+       struct timer_list       data_timer;
 
        struct workqueue_struct *cmd_wq;
        struct work_struct      cmd_work;
@@ -96,9 +109,11 @@ struct nci_dev {
        void                    *driver_data;
 
        __u32                   poll_prots;
-       __u32                   target_available_prots;
        __u32                   target_active_prot;
 
+       struct nfc_target       targets[NCI_MAX_DISCOVERED_TARGETS];
+       int                     n_targets;
+
        /* received during NCI_OP_CORE_RESET_RSP */
        __u8                    nci_ver;
 
@@ -126,17 +141,17 @@ struct nci_dev {
 
 /* ----- NCI Devices ----- */
 struct nci_dev *nci_allocate_device(struct nci_ops *ops,
-                               __u32 supported_protocols,
-                               int tx_headroom,
-                               int tx_tailroom);
+                                   __u32 supported_protocols,
+                                   int tx_headroom,
+                                   int tx_tailroom);
 void nci_free_device(struct nci_dev *ndev);
 int nci_register_device(struct nci_dev *ndev);
 void nci_unregister_device(struct nci_dev *ndev);
 int nci_recv_frame(struct sk_buff *skb);
 
 static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev,
-                                               unsigned int len,
-                                               gfp_t how)
+                                           unsigned int len,
+                                           gfp_t how)
 {
        struct sk_buff *skb;
 
@@ -169,6 +184,7 @@ int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload);
 int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb);
 void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,
                                int err);
+void nci_clear_target_list(struct nci_dev *ndev);
 
 /* ----- NCI requests ----- */
 #define NCI_REQ_DONE           0
index 8696b773a6951c881cd202738a6cfbbcc7919714..bac070bf3514188c589b1769484abacfa8470ca1 100644 (file)
@@ -24,6 +24,7 @@
 #ifndef __NET_NFC_H
 #define __NET_NFC_H
 
+#include <linux/nfc.h>
 #include <linux/device.h>
 #include <linux/skbuff.h>
 
@@ -52,20 +53,19 @@ struct nfc_ops {
        int (*dev_down)(struct nfc_dev *dev);
        int (*start_poll)(struct nfc_dev *dev, u32 protocols);
        void (*stop_poll)(struct nfc_dev *dev);
-       int (*dep_link_up)(struct nfc_dev *dev, int target_idx,
-                               u8 comm_mode, u8 rf_mode);
+       int (*dep_link_up)(struct nfc_dev *dev, int target_idx, u8 comm_mode,
+                          u8 *gb, size_t gb_len);
        int (*dep_link_down)(struct nfc_dev *dev);
        int (*activate_target)(struct nfc_dev *dev, u32 target_idx,
-                                                       u32 protocol);
+                              u32 protocol);
        void (*deactivate_target)(struct nfc_dev *dev, u32 target_idx);
        int (*data_exchange)(struct nfc_dev *dev, u32 target_idx,
-                               struct sk_buff *skb, data_exchange_cb_t cb,
-                                                       void *cb_context);
+                            struct sk_buff *skb, data_exchange_cb_t cb,
+                            void *cb_context);
 };
 
 #define NFC_TARGET_IDX_ANY -1
 #define NFC_MAX_GT_LEN 48
-#define NFC_MAX_NFCID1_LEN 10
 
 struct nfc_target {
        u32 idx;
@@ -73,7 +73,11 @@ struct nfc_target {
        u16 sens_res;
        u8 sel_res;
        u8 nfcid1_len;
-       u8 nfcid1[NFC_MAX_NFCID1_LEN];
+       u8 nfcid1[NFC_NFCID1_MAXSIZE];
+       u8 sensb_res_len;
+       u8 sensb_res[NFC_SENSB_RES_MAXSIZE];
+       u8 sensf_res_len;
+       u8 sensf_res[NFC_SENSF_RES_MAXSIZE];
 };
 
 struct nfc_genl_data {
@@ -83,7 +87,6 @@ struct nfc_genl_data {
 
 struct nfc_dev {
        unsigned idx;
-       unsigned target_idx;
        struct nfc_target *targets;
        int n_targets;
        int targets_generation;
@@ -107,9 +110,9 @@ struct nfc_dev {
 extern struct class nfc_class;
 
 struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
-                                       u32 supported_protocols,
-                                       int tx_headroom,
-                                       int tx_tailroom);
+                                   u32 supported_protocols,
+                                   int tx_headroom,
+                                   int tx_tailroom);
 
 /**
  * nfc_free_device - free nfc device
@@ -132,7 +135,7 @@ void nfc_unregister_device(struct nfc_dev *dev);
  * @dev: The parent device
  */
 static inline void nfc_set_parent_dev(struct nfc_dev *nfc_dev,
-                                       struct device *dev)
+                                     struct device *dev)
 {
        nfc_dev->dev.parent = dev;
 }
@@ -169,17 +172,15 @@ static inline const char *nfc_device_name(struct nfc_dev *dev)
 }
 
 struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk,
-                                       unsigned int flags, unsigned int size,
-                                       unsigned int *err);
+                                  unsigned int flags, unsigned int size,
+                                  unsigned int *err);
 struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp);
 
 int nfc_set_remote_general_bytes(struct nfc_dev *dev,
-                                       u8 *gt, u8 gt_len);
+                                u8 *gt, u8 gt_len);
 
-u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *gt_len);
-
-int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets,
-                                                       int ntargets);
+int nfc_targets_found(struct nfc_dev *dev,
+                     struct nfc_target *targets, int ntargets);
 
 int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx,
                       u8 comm_mode, u8 rf_mode);
index ef92864ac6258b32ec600ad5791e19d399d0965b..72eb187a5f605f9835d71c2de9f980e1e52d6a4e 100644 (file)
@@ -71,19 +71,16 @@ static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
        "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
 };
 
-static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
+void bt_sock_reclassify_lock(struct sock *sk, int proto)
 {
-       struct sock *sk = sock->sk;
-
-       if (!sk)
-               return;
-
+       BUG_ON(!sk);
        BUG_ON(sock_owned_by_user(sk));
 
        sock_lock_init_class_and_name(sk,
                        bt_slock_key_strings[proto], &bt_slock_key[proto],
                                bt_key_strings[proto], &bt_lock_key[proto]);
 }
+EXPORT_SYMBOL(bt_sock_reclassify_lock);
 
 int bt_sock_register(int proto, const struct net_proto_family *ops)
 {
@@ -145,7 +142,8 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto,
 
        if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
                err = bt_proto[proto]->create(net, sock, proto, kern);
-               bt_sock_reclassify_lock(sock, proto);
+               if (!err)
+                       bt_sock_reclassify_lock(sock->sk, proto);
                module_put(bt_proto[proto]->owner);
        }
 
index 3db432473ad5214efc902f5bbaa36f631114defa..07bc69ed9498c276e272d9215a3189b0df7beb30 100644 (file)
@@ -635,6 +635,10 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 
        if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
                struct hci_cp_auth_requested cp;
+
+               /* encrypt must be pending if auth is also pending */
+               set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+
                cp.handle = cpu_to_le16(conn->handle);
                hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
                                                        sizeof(cp), &cp);
index 9de93714213a1be51542af9f8ff94cc6f3ac9fea..5aeb62491198b193b26e7b5e2c46a90b089bf848 100644 (file)
@@ -640,7 +640,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
        /* Reset device */
        skb_queue_purge(&hdev->cmd_q);
        atomic_set(&hdev->cmd_cnt, 1);
-       if (!test_bit(HCI_RAW, &hdev->flags)) {
+       if (!test_bit(HCI_RAW, &hdev->flags) &&
+                               test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
                set_bit(HCI_INIT, &hdev->flags);
                __hci_request(hdev, hci_reset_req, 0,
                                        msecs_to_jiffies(250));
index faf0b11ac1d3610805e6d049f4a2e2221c35053a..32d338c30e65a034460652579112fb6c9b61f806 100644 (file)
@@ -1018,10 +1018,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
        hci_chan_del(conn->hchan);
 
        if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
-               __cancel_delayed_work(&conn->info_timer);
+               cancel_delayed_work_sync(&conn->info_timer);
 
        if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) {
-               __cancel_delayed_work(&conn->security_timer);
+               cancel_delayed_work_sync(&conn->security_timer);
                smp_chan_destroy(conn);
        }
 
@@ -1120,7 +1120,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr
        return c1;
 }
 
-inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
 {
        struct sock *sk = chan->sk;
        bdaddr_t *src = &bt_sk(sk)->src;
@@ -2574,7 +2574,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
 
        if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
                                        cmd->ident == conn->info_ident) {
-               __cancel_delayed_work(&conn->info_timer);
+               cancel_delayed_work(&conn->info_timer);
 
                conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
                conn->info_ident = 0;
@@ -2970,7 +2970,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
        default:
                sk->sk_err = ECONNRESET;
-               __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
+               __set_chan_timer(chan,
+                               msecs_to_jiffies(L2CAP_DISC_REJ_TIMEOUT));
                l2cap_send_disconn_req(conn, chan, ECONNRESET);
                goto done;
        }
@@ -3120,7 +3121,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
                        conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
                return 0;
 
-       __cancel_delayed_work(&conn->info_timer);
+       cancel_delayed_work(&conn->info_timer);
 
        if (result != L2CAP_IR_SUCCESS) {
                conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
@@ -4478,7 +4479,8 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
        if (encrypt == 0x00) {
                if (chan->sec_level == BT_SECURITY_MEDIUM) {
                        __clear_chan_timer(chan);
-                       __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
+                       __set_chan_timer(chan,
+                                       msecs_to_jiffies(L2CAP_ENC_TIMEOUT));
                } else if (chan->sec_level == BT_SECURITY_HIGH)
                        l2cap_chan_close(chan, ECONNREFUSED);
        } else {
@@ -4499,7 +4501,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 
        if (hcon->type == LE_LINK) {
                smp_distribute_keys(conn, 0);
-               __cancel_delayed_work(&conn->security_timer);
+               cancel_delayed_work(&conn->security_timer);
        }
 
        rcu_read_lock();
@@ -4546,7 +4548,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                                        L2CAP_CONN_REQ, sizeof(req), &req);
                        } else {
                                __clear_chan_timer(chan);
-                               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
+                               __set_chan_timer(chan,
+                                       msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
                        }
                } else if (chan->state == BT_CONNECT2) {
                        struct l2cap_conn_rsp rsp;
@@ -4566,7 +4569,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                                }
                        } else {
                                l2cap_state_change(chan, BT_DISCONN);
-                               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
+                               __set_chan_timer(chan,
+                                       msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
                                res = L2CAP_CR_SEC_BLOCK;
                                stat = L2CAP_CS_NO_INFO;
                        }
index c61d967012b2008547767dd69cec91be0f97d30d..401d9428ae4c824f6dbe2871d77bb6742ba4688c 100644 (file)
@@ -849,6 +849,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data)
        if (!sk)
                return NULL;
 
+       bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
+
        l2cap_sock_init(sk, parent);
 
        return l2cap_pi(sk)->chan;
@@ -1002,7 +1004,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
        INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
 
        sk->sk_destruct = l2cap_sock_destruct;
-       sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
+       sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
 
        sock_reset_flag(sk, SOCK_ZAPPED);
 
index 501649bf5596d0373d6b6dd3be791dd1345ad33e..8a602388f1e73c185aa24499e9ff636c9358fcee 100644 (file)
@@ -1164,12 +1164,18 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
                        break;
 
                case BT_DISCONN:
-                       /* When socket is closed and we are not RFCOMM
-                        * initiator rfcomm_process_rx already calls
-                        * rfcomm_session_put() */
-                       if (s->sock->sk->sk_state != BT_CLOSED)
-                               if (list_empty(&s->dlcs))
-                                       rfcomm_session_put(s);
+                       /* rfcomm_session_put is called later so don't do
+                        * anything here otherwise we will mess up the session
+                        * reference counter:
+                        *
+                        * (a) when we are the initiator dlc_unlink will drive
+                        * the reference counter to 0 (there is no initial put
+                        * after session_add)
+                        *
+                        * (b) when we are not the initiator rfcomm_rx_process
+                        * will explicitly call put to balance the initial hold
+                        * done after session add.
+                        */
                        break;
                }
        }
index f066678faeee838efae16243111a1bb51f47c8f3..22169c3f148254c52b991caf64b7c0284a54d7f6 100644 (file)
@@ -956,6 +956,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
        if (!sk)
                goto done;
 
+       bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM);
+
        rfcomm_sock_init(sk, parent);
        bacpy(&bt_sk(sk)->src, &src);
        bacpy(&bt_sk(sk)->dst, &dst);
index d540c3b160f37fde53c1cbdc867291849b0d08fa..1be7a454aa77b6c6de370d44c84f2ccdb64ee53a 100644 (file)
@@ -9,7 +9,7 @@ mac80211-y := \
        scan.o offchannel.o \
        ht.o agg-tx.o agg-rx.o \
        ibss.o \
-       mlme.o work.o \
+       work.o \
        iface.o \
        rate.o \
        michael.o \
@@ -25,7 +25,7 @@ mac80211-y := \
        wme.o \
        event.o \
        chan.o \
-       driver-trace.o
+       driver-trace.o mlme.o
 
 mac80211-$(CONFIG_MAC80211_LEDS) += led.o
 mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
index 296620d6ca0c0c2388f05ffaffd9c5d832eb3cbd..677d65929780ad147a531657f30ee26f6b52ae82 100644 (file)
@@ -336,6 +336,20 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in
                rate->mcs = idx;
 }
 
+void sta_set_rate_info_tx(struct sta_info *sta,
+                         const struct ieee80211_tx_rate *rate,
+                         struct rate_info *rinfo)
+{
+       rinfo->flags = 0;
+       if (rate->flags & IEEE80211_TX_RC_MCS)
+               rinfo->flags |= RATE_INFO_FLAGS_MCS;
+       if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+               rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+       if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
+               rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
+       rate_idx_to_bitrate(rinfo, sta, rate->idx);
+}
+
 static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 {
        struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -378,14 +392,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
                sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
        }
 
-       sinfo->txrate.flags = 0;
-       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
-       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
-       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
-       rate_idx_to_bitrate(&sinfo->txrate, sta, sta->last_tx_rate.idx);
+       sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
 
        sinfo->rxrate.flags = 0;
        if (sta->last_rx_rate_flag & RX_FLAG_HT)
@@ -489,27 +496,13 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
        return ret;
 }
 
-static void ieee80211_config_ap_ssid(struct ieee80211_sub_if_data *sdata,
-                                    struct beacon_parameters *params)
-{
-       struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
-
-       bss_conf->ssid_len = params->ssid_len;
-
-       if (params->ssid_len)
-               memcpy(bss_conf->ssid, params->ssid, params->ssid_len);
-
-       bss_conf->hidden_ssid =
-               (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
-}
-
 static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
-                                   u8 *resp, size_t resp_len)
+                                   const u8 *resp, size_t resp_len)
 {
        struct sk_buff *new, *old;
 
        if (!resp || !resp_len)
-               return -EINVAL;
+               return 1;
 
        old = rtnl_dereference(sdata->u.ap.probe_resp);
 
@@ -520,50 +513,28 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
        memcpy(skb_put(new, resp_len), resp, resp_len);
 
        rcu_assign_pointer(sdata->u.ap.probe_resp, new);
-       synchronize_rcu();
-
-       if (old)
+       if (old) {
+               /* TODO: use call_rcu() */
+               synchronize_rcu();
                dev_kfree_skb(old);
+       }
 
        return 0;
 }
 
-/*
- * This handles both adding a beacon and setting new beacon info
- */
-static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
-                                  struct beacon_parameters *params)
+static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
+                                  struct cfg80211_beacon_data *params)
 {
        struct beacon_data *new, *old;
        int new_head_len, new_tail_len;
-       int size;
-       int err = -EINVAL;
-       u32 changed = 0;
+       int size, err;
+       u32 changed = BSS_CHANGED_BEACON;
 
        old = rtnl_dereference(sdata->u.ap.beacon);
 
-       /* head must not be zero-length */
-       if (params->head && !params->head_len)
-               return -EINVAL;
-
-       /*
-        * This is a kludge. beacon interval should really be part
-        * of the beacon information.
-        */
-       if (params->interval &&
-           (sdata->vif.bss_conf.beacon_int != params->interval)) {
-               sdata->vif.bss_conf.beacon_int = params->interval;
-               ieee80211_bss_info_change_notify(sdata,
-                                                BSS_CHANGED_BEACON_INT);
-       }
-
        /* Need to have a beacon head if we don't have one yet */
        if (!params->head && !old)
-               return err;
-
-       /* sorry, no way to start beaconing without dtim period */
-       if (!params->dtim_period && !old)
-               return err;
+               return -EINVAL;
 
        /* new or old head? */
        if (params->head)
@@ -586,12 +557,6 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
 
        /* start filling the new info now */
 
-       /* new or old dtim period? */
-       if (params->dtim_period)
-               new->dtim_period = params->dtim_period;
-       else
-               new->dtim_period = old->dtim_period;
-
        /*
         * pointers go into the block we allocated,
         * memory is | beacon_data | head | tail |
@@ -614,46 +579,37 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
                if (old)
                        memcpy(new->tail, old->tail, new_tail_len);
 
-       sdata->vif.bss_conf.dtim_period = new->dtim_period;
-
-       rcu_assign_pointer(sdata->u.ap.beacon, new);
-
-       synchronize_rcu();
-
-       kfree(old);
-
        err = ieee80211_set_probe_resp(sdata, params->probe_resp,
                                       params->probe_resp_len);
-       if (!err)
+       if (err < 0)
+               return err;
+       if (err == 0)
                changed |= BSS_CHANGED_AP_PROBE_RESP;
 
-       ieee80211_config_ap_ssid(sdata, params);
-       changed |= BSS_CHANGED_BEACON_ENABLED |
-                  BSS_CHANGED_BEACON |
-                  BSS_CHANGED_SSID;
+       rcu_assign_pointer(sdata->u.ap.beacon, new);
 
-       ieee80211_bss_info_change_notify(sdata, changed);
-       return 0;
+       if (old)
+               kfree_rcu(old, rcu_head);
+
+       return changed;
 }
 
-static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
-                               struct beacon_parameters *params)
+static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
+                             struct cfg80211_ap_settings *params)
 {
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct beacon_data *old;
        struct ieee80211_sub_if_data *vlan;
-       int ret;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       u32 changed = BSS_CHANGED_BEACON_INT |
+                     BSS_CHANGED_BEACON_ENABLED |
+                     BSS_CHANGED_BEACON |
+                     BSS_CHANGED_SSID;
+       int err;
 
        old = rtnl_dereference(sdata->u.ap.beacon);
        if (old)
                return -EALREADY;
 
-       ret = ieee80211_config_beacon(sdata, params);
-       if (ret)
-               return ret;
-
        /*
         * Apply control port protocol, this allows us to
         * not encrypt dynamic WEP control frames.
@@ -667,14 +623,32 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
                        params->crypto.control_port_no_encrypt;
        }
 
+       sdata->vif.bss_conf.beacon_int = params->beacon_interval;
+       sdata->vif.bss_conf.dtim_period = params->dtim_period;
+
+       sdata->vif.bss_conf.ssid_len = params->ssid_len;
+       if (params->ssid_len)
+               memcpy(sdata->vif.bss_conf.ssid, params->ssid,
+                      params->ssid_len);
+       sdata->vif.bss_conf.hidden_ssid =
+               (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
+
+       err = ieee80211_assign_beacon(sdata, &params->beacon);
+       if (err < 0)
+               return err;
+       changed |= err;
+
+       ieee80211_bss_info_change_notify(sdata, changed);
+
        return 0;
 }
 
-static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
-                               struct beacon_parameters *params)
+static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
+                                  struct cfg80211_beacon_data *params)
 {
        struct ieee80211_sub_if_data *sdata;
        struct beacon_data *old;
+       int err;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
@@ -682,10 +656,14 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
        if (!old)
                return -ENOENT;
 
-       return ieee80211_config_beacon(sdata, params);
+       err = ieee80211_assign_beacon(sdata, params);
+       if (err < 0)
+               return err;
+       ieee80211_bss_info_change_notify(sdata, err);
+       return 0;
 }
 
-static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
+static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
 {
        struct ieee80211_sub_if_data *sdata;
        struct beacon_data *old;
@@ -697,10 +675,11 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
                return -ENOENT;
 
        RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
-       synchronize_rcu();
-       kfree(old);
+
+       kfree_rcu(old, rcu_head);
 
        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
+
        return 0;
 }
 
@@ -776,12 +755,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
 
                if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED) &&
                    !test_sta_flag(sta, WLAN_STA_AUTH)) {
-                       ret = sta_info_move_state_checked(sta,
-                                       IEEE80211_STA_AUTH);
+                       ret = sta_info_move_state(sta, IEEE80211_STA_AUTH);
                        if (ret)
                                return ret;
-                       ret = sta_info_move_state_checked(sta,
-                                       IEEE80211_STA_ASSOC);
+                       ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
                        if (ret)
                                return ret;
                }
@@ -789,11 +766,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
 
        if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
                if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
-                       ret = sta_info_move_state_checked(sta,
-                                       IEEE80211_STA_AUTHORIZED);
+                       ret = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
                else if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
-                       ret = sta_info_move_state_checked(sta,
-                                       IEEE80211_STA_ASSOC);
+                       ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
                if (ret)
                        return ret;
        }
@@ -805,12 +780,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
 
                if (!(set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) &&
                    test_sta_flag(sta, WLAN_STA_AUTH)) {
-                       ret = sta_info_move_state_checked(sta,
-                                       IEEE80211_STA_AUTH);
+                       ret = sta_info_move_state(sta, IEEE80211_STA_AUTH);
                        if (ret)
                                return ret;
-                       ret = sta_info_move_state_checked(sta,
-                                       IEEE80211_STA_NONE);
+                       ret = sta_info_move_state(sta, IEEE80211_STA_NONE);
                        if (ret)
                                return ret;
                }
@@ -944,8 +917,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        if (!sta)
                return -ENOMEM;
 
-       sta_info_move_state(sta, IEEE80211_STA_AUTH);
-       sta_info_move_state(sta, IEEE80211_STA_ASSOC);
+       sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+       sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
 
        err = sta_apply_parameters(local, sta, params);
        if (err) {
@@ -1001,6 +974,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
        struct ieee80211_local *local = wiphy_priv(wiphy);
        struct sta_info *sta;
        struct ieee80211_sub_if_data *vlansdata;
+       int err;
 
        mutex_lock(&local->sta_mtx);
 
@@ -1040,7 +1014,11 @@ static int ieee80211_change_station(struct wiphy *wiphy,
                ieee80211_send_layer2_update(sta);
        }
 
-       sta_apply_parameters(local, sta, params);
+       err = sta_apply_parameters(local, sta, params);
+       if (err) {
+               mutex_unlock(&local->sta_mtx);
+               return err;
+       }
 
        if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && params->supported_rates)
                rate_control_rate_init(sta);
@@ -1341,6 +1319,16 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
                conf->dot11MeshHWMPRannInterval =
                        nconf->dot11MeshHWMPRannInterval;
        }
+       if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
+               conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
+       if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
+               /* our RSSI threshold implementation is supported only for
+                * devices that report signal in dBm.
+                */
+               if (!(sdata->local->hw.flags & IEEE80211_HW_SIGNAL_DBM))
+                       return -ENOTSUPP;
+               conf->rssi_threshold = nconf->rssi_threshold;
+       }
        return 0;
 }
 
@@ -1622,19 +1610,15 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
 }
 
 static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
-                           struct cfg80211_deauth_request *req,
-                           void *cookie)
+                           struct cfg80211_deauth_request *req)
 {
-       return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev),
-                                   req, cookie);
+       return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev), req);
 }
 
 static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
-                             struct cfg80211_disassoc_request *req,
-                             void *cookie)
+                             struct cfg80211_disassoc_request *req)
 {
-       return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev),
-                                     req, cookie);
+       return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
 }
 
 static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
@@ -1868,7 +1852,6 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
                                         s32 rssi_thold, u32 rssi_hyst)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_vif *vif = &sdata->vif;
        struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 
@@ -1879,14 +1862,9 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
        bss_conf->cqm_rssi_thold = rssi_thold;
        bss_conf->cqm_rssi_hyst = rssi_hyst;
 
-       if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
-               if (sdata->vif.type != NL80211_IFTYPE_STATION)
-                       return -EOPNOTSUPP;
-               return 0;
-       }
-
        /* tell the driver upon association, unless already associated */
-       if (sdata->u.mgd.associated)
+       if (sdata->u.mgd.associated &&
+           sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)
                ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
 
        return 0;
@@ -1907,8 +1885,11 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
                        return ret;
        }
 
-       for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+       for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
                sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
+               memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
+                      sizeof(mask->control[i].mcs));
+       }
 
        return 0;
 }
@@ -2030,7 +2011,7 @@ ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb)
        if (wk->offchan_tx.wait && !wk->offchan_tx.status)
                cfg80211_mgmt_tx_status(wk->sdata->dev,
                                        (unsigned long) wk->offchan_tx.frame,
-                                       wk->ie, wk->ie_len, false, GFP_KERNEL);
+                                       wk->data, wk->data_len, false, GFP_KERNEL);
 
        return WORK_DONE_DESTROY;
 }
@@ -2181,8 +2162,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
        wk->done = ieee80211_offchan_tx_done;
        wk->offchan_tx.frame = skb;
        wk->offchan_tx.wait = wait;
-       wk->ie_len = len;
-       memcpy(wk->ie, buf, len);
+       wk->data_len = len;
+       memcpy(wk->data, buf, len);
 
        ieee80211_add_work(wk);
        return 0;
@@ -2701,9 +2682,9 @@ struct cfg80211_ops mac80211_config_ops = {
        .get_key = ieee80211_get_key,
        .set_default_key = ieee80211_config_default_key,
        .set_default_mgmt_key = ieee80211_config_default_mgmt_key,
-       .add_beacon = ieee80211_add_beacon,
-       .set_beacon = ieee80211_set_beacon,
-       .del_beacon = ieee80211_del_beacon,
+       .start_ap = ieee80211_start_ap,
+       .change_beacon = ieee80211_change_beacon,
+       .stop_ap = ieee80211_stop_ap,
        .add_station = ieee80211_add_station,
        .del_station = ieee80211_del_station,
        .change_station = ieee80211_change_station,
index 889c3e93e0f4a9df2a1a2007799f2a2f13e8a496..d1f7abddb182e1fe1f780af0d19e1948ca3c70e6 100644 (file)
@@ -20,23 +20,29 @@ __ieee80211_get_channel_mode(struct ieee80211_local *local,
                if (!ieee80211_sdata_running(sdata))
                        continue;
 
-               if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+               switch (sdata->vif.type) {
+               case NL80211_IFTYPE_MONITOR:
                        continue;
-
-               if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-                   !sdata->u.mgd.associated)
-                       continue;
-
-               if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+               case NL80211_IFTYPE_STATION:
+                       if (!sdata->u.mgd.associated)
+                               continue;
+                       break;
+               case NL80211_IFTYPE_ADHOC:
                        if (!sdata->u.ibss.ssid_len)
                                continue;
                        if (!sdata->u.ibss.fixed_channel)
                                return CHAN_MODE_HOPPING;
-               }
-
-               if (sdata->vif.type == NL80211_IFTYPE_AP &&
-                   !sdata->u.ap.beacon)
+                       break;
+               case NL80211_IFTYPE_AP_VLAN:
+                       /* will also have _AP interface */
                        continue;
+               case NL80211_IFTYPE_AP:
+                       if (!sdata->u.ap.beacon)
+                               continue;
+                       break;
+               default:
+                       break;
+               }
 
                return CHAN_MODE_FIXED;
        }
index 90baea53e7c56572df7562d201237fed48ef49e9..483e96ed95c10b4f62b8c847db07dbc3d9f1ab8a 100644 (file)
@@ -247,8 +247,6 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf,
                sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n");
        if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE)
                sf += snprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n");
-       if (local->hw.flags & IEEE80211_HW_BEACON_FILTER)
-               sf += snprintf(buf + sf, mxln - sf, "BEACON_FILTER\n");
        if (local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS)
                sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_STATIC_SMPS\n");
        if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
@@ -259,14 +257,14 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf,
                sf += snprintf(buf + sf, mxln - sf, "REPORTS_TX_ACK_STATUS\n");
        if (local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
                sf += snprintf(buf + sf, mxln - sf, "CONNECTION_MONITOR\n");
-       if (local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)
-               sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_CQM_RSSI\n");
        if (local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK)
                sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n");
        if (local->hw.flags & IEEE80211_HW_AP_LINK_PS)
                sf += snprintf(buf + sf, mxln - sf, "AP_LINK_PS\n");
        if (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)
                sf += snprintf(buf + sf, mxln - sf, "TX_AMPDU_SETUP_IN_HW\n");
+       if (local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)
+               sf += snprintf(buf + sf, mxln - sf, "SCAN_WHILE_IDLE\n");
 
        rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
        kfree(buf);
index 176c08ffb13c50e5f5fa8c212175a8367f09bb97..f6de8a65f4020e70d7a630608eea166f6ef6b430 100644 (file)
@@ -87,6 +87,21 @@ static ssize_t ieee80211_if_fmt_##name(                                      \
 #define IEEE80211_IF_FMT_SIZE(name, field)                             \
                IEEE80211_IF_FMT(name, field, "%zd\n")
 
+#define IEEE80211_IF_FMT_HEXARRAY(name, field)                         \
+static ssize_t ieee80211_if_fmt_##name(                                        \
+       const struct ieee80211_sub_if_data *sdata,                      \
+       char *buf, int buflen)                                          \
+{                                                                      \
+       char *p = buf;                                                  \
+       int i;                                                          \
+       for (i = 0; i < sizeof(sdata->field); i++) {                    \
+               p += scnprintf(p, buflen + buf - p, "%.2x ",            \
+                                sdata->field[i]);                      \
+       }                                                               \
+       p += scnprintf(p, buflen + buf - p, "\n");                      \
+       return p - buf;                                                 \
+}
+
 #define IEEE80211_IF_FMT_ATOMIC(name, field)                           \
 static ssize_t ieee80211_if_fmt_##name(                                        \
        const struct ieee80211_sub_if_data *sdata,                      \
@@ -148,6 +163,11 @@ IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[IEEE80211_BAND_2GHZ],
                  HEX);
 IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
                  HEX);
+IEEE80211_IF_FILE(rc_rateidx_mcs_mask_2ghz,
+                 rc_rateidx_mcs_mask[IEEE80211_BAND_2GHZ], HEXARRAY);
+IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
+                 rc_rateidx_mcs_mask[IEEE80211_BAND_5GHZ], HEXARRAY);
+
 IEEE80211_IF_FILE(flags, flags, HEX);
 IEEE80211_IF_FILE(state, state, LHEX);
 IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC);
@@ -422,6 +442,8 @@ IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
                u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
 IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
                u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
+IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
+IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC);
 #endif
 
 
@@ -441,6 +463,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
        DEBUGFS_ADD(channel_type);
        DEBUGFS_ADD(rc_rateidx_mask_2ghz);
        DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+       DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+       DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 
        DEBUGFS_ADD(bssid);
        DEBUGFS_ADD(aid);
@@ -458,6 +482,8 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
        DEBUGFS_ADD(channel_type);
        DEBUGFS_ADD(rc_rateidx_mask_2ghz);
        DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+       DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+       DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 
        DEBUGFS_ADD(num_sta_authorized);
        DEBUGFS_ADD(num_sta_ps);
@@ -468,6 +494,12 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
 
 static void add_ibss_files(struct ieee80211_sub_if_data *sdata)
 {
+       DEBUGFS_ADD(channel_type);
+       DEBUGFS_ADD(rc_rateidx_mask_2ghz);
+       DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+       DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+       DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
+
        DEBUGFS_ADD_MODE(tsf, 0600);
 }
 
@@ -479,6 +511,8 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata)
        DEBUGFS_ADD(channel_type);
        DEBUGFS_ADD(rc_rateidx_mask_2ghz);
        DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+       DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+       DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 
        DEBUGFS_ADD(peer);
 }
@@ -491,6 +525,8 @@ static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
        DEBUGFS_ADD(channel_type);
        DEBUGFS_ADD(rc_rateidx_mask_2ghz);
        DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+       DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+       DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 }
 
 static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
@@ -502,11 +538,15 @@ static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
 
 #ifdef CONFIG_MAC80211_MESH
 
+static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
+{
+       DEBUGFS_ADD_MODE(tsf, 0600);
+}
+
 static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
 {
        struct dentry *dir = debugfs_create_dir("mesh_stats",
                                                sdata->debugfs.dir);
-
 #define MESHSTATS_ADD(name)\
        debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);
 
@@ -546,6 +586,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
        MESHPARAMS_ADD(dot11MeshHWMPRootMode);
        MESHPARAMS_ADD(dot11MeshHWMPRannInterval);
        MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
+       MESHPARAMS_ADD(rssi_threshold);
 #undef MESHPARAMS_ADD
 }
 #endif
@@ -558,6 +599,7 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_MESH_POINT:
 #ifdef CONFIG_MAC80211_MESH
+               add_mesh_files(sdata);
                add_mesh_stats(sdata);
                add_mesh_config(sdata);
 #endif
index 2406b3e7393fb042d8ec82b417c7e985a0801fa2..6d45804d09bc0a26ef9025c8751355ffebd13b8f 100644 (file)
@@ -63,14 +63,15 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
        test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
 
        int res = scnprintf(buf, sizeof(buf),
-                           "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+                           "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                            TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
                            TEST(PS_DRIVER), TEST(AUTHORIZED),
                            TEST(SHORT_PREAMBLE),
                            TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
                            TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
                            TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
-                           TEST(TDLS_PEER_AUTH));
+                           TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
+                           TEST(INSERTED), TEST(RATE_CONTROL));
 #undef TEST
        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 }
index e8960ae3986126aadd0b4254909d7b9b45fd07c9..70dfb6415c20cef5a138fb4bc453292a9d783535 100644 (file)
@@ -253,6 +253,7 @@ static inline int drv_set_key(struct ieee80211_local *local,
 
        might_sleep();
 
+       sdata = get_bss_sdata(sdata);
        check_sdata_in_driver(sdata);
 
        trace_drv_set_key(local, cmd, sdata, sta, key);
@@ -272,6 +273,7 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local,
        if (sta)
                ista = &sta->sta;
 
+       sdata = get_bss_sdata(sdata);
        check_sdata_in_driver(sdata);
 
        trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
@@ -476,6 +478,37 @@ static inline void drv_sta_remove(struct ieee80211_local *local,
        trace_drv_return_void(local);
 }
 
+static inline __must_check
+int drv_sta_state(struct ieee80211_local *local,
+                 struct ieee80211_sub_if_data *sdata,
+                 struct sta_info *sta,
+                 enum ieee80211_sta_state old_state,
+                 enum ieee80211_sta_state new_state)
+{
+       int ret = 0;
+
+       might_sleep();
+
+       sdata = get_bss_sdata(sdata);
+       check_sdata_in_driver(sdata);
+
+       trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
+       if (local->ops->sta_state) {
+               ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
+                                           old_state, new_state);
+       } else if (old_state == IEEE80211_STA_AUTH &&
+                  new_state == IEEE80211_STA_ASSOC) {
+               ret = drv_sta_add(local, sdata, &sta->sta);
+               if (ret == 0)
+                       sta->uploaded = true;
+       } else if (old_state == IEEE80211_STA_ASSOC &&
+                  new_state == IEEE80211_STA_AUTH) {
+               drv_sta_remove(local, sdata, &sta->sta);
+       }
+       trace_drv_return_int(local, ret);
+       return ret;
+}
+
 static inline int drv_conf_tx(struct ieee80211_local *local,
                              struct ieee80211_sub_if_data *sdata, u16 queue,
                              const struct ieee80211_tx_queue_params *params)
index 6e9df8fd8fb8c7d04e2d834232152a0377952823..384e2f08c187051f3bfb647adb66204a6c2153e0 100644 (file)
@@ -635,6 +635,38 @@ TRACE_EVENT(drv_sta_notify,
        )
 );
 
+TRACE_EVENT(drv_sta_state,
+       TP_PROTO(struct ieee80211_local *local,
+                struct ieee80211_sub_if_data *sdata,
+                struct ieee80211_sta *sta,
+                enum ieee80211_sta_state old_state,
+                enum ieee80211_sta_state new_state),
+
+       TP_ARGS(local, sdata, sta, old_state, new_state),
+
+       TP_STRUCT__entry(
+               LOCAL_ENTRY
+               VIF_ENTRY
+               STA_ENTRY
+               __field(u32, old_state)
+               __field(u32, new_state)
+       ),
+
+       TP_fast_assign(
+               LOCAL_ASSIGN;
+               VIF_ASSIGN;
+               STA_ASSIGN;
+               __entry->old_state = old_state;
+               __entry->new_state = new_state;
+       ),
+
+       TP_printk(
+               LOCAL_PR_FMT  VIF_PR_FMT  STA_PR_FMT " state: %d->%d",
+               LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG,
+               __entry->old_state, __entry->new_state
+       )
+);
+
 TRACE_EVENT(drv_sta_add,
        TP_PROTO(struct ieee80211_local *local,
                 struct ieee80211_sub_if_data *sdata,
index a4643969a13b22524a7f90f0304c18d917f025be..33fd8d9f714ec05db8aeba88d0bb5c6bf97e8fd0 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 #include <net/mac80211.h>
-#include <asm/unaligned.h>
 
 #include "ieee80211_i.h"
 #include "driver-ops.h"
 #define IEEE80211_IBSS_MAX_STA_ENTRIES 128
 
 
-static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
-                                       struct ieee80211_mgmt *mgmt,
-                                       size_t len)
-{
-       u16 auth_alg, auth_transaction;
-
-       lockdep_assert_held(&sdata->u.ibss.mtx);
-
-       if (len < 24 + 6)
-               return;
-
-       auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
-       auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
-
-       /*
-        * IEEE 802.11 standard does not require authentication in IBSS
-        * networks and most implementations do not seem to use it.
-        * However, try to reply to authentication attempts if someone
-        * has actually implemented this.
-        */
-       if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1)
-               ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0,
-                                   sdata->u.ibss.bssid, NULL, 0, 0);
-}
-
 static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                                      const u8 *bssid, const int beacon_int,
                                      struct ieee80211_channel *chan,
@@ -92,7 +66,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        skb_reset_tail_pointer(skb);
        skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
 
-       if (memcmp(ifibss->bssid, bssid, ETH_ALEN))
+       if (compare_ether_addr(ifibss->bssid, bssid))
                sta_info_flush(sdata->local, sdata);
 
        /* if merging, indicate to driver that we leave the old IBSS */
@@ -276,7 +250,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                                  cbss->tsf);
 }
 
-static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
+static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
+                                                 bool auth)
        __acquires(RCU)
 {
        struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -290,22 +265,34 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
                    addr, sdata->name);
 #endif
 
-       sta_info_move_state(sta, IEEE80211_STA_AUTH);
-       sta_info_move_state(sta, IEEE80211_STA_ASSOC);
-       sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
+       sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+       sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
+       /* authorize the station only if the network is not RSN protected. If
+        * not wait for the userspace to authorize it */
+       if (!sta->sdata->u.ibss.control_port)
+               sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
 
        rate_control_rate_init(sta);
 
        /* If it fails, maybe we raced another insertion? */
        if (sta_info_insert_rcu(sta))
                return sta_info_get(sdata, addr);
+       if (auth) {
+#ifdef CONFIG_MAC80211_IBSS_DEBUG
+               printk(KERN_DEBUG "TX Auth SA=%pM DA=%pM BSSID=%pM"
+                      "(auth_transaction=1)\n", sdata->vif.addr,
+                      sdata->u.ibss.bssid, addr);
+#endif
+               ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0,
+                                   addr, sdata->u.ibss.bssid, NULL, 0, 0);
+       }
        return sta;
 }
 
 static struct sta_info *
 ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
                       const u8 *bssid, const u8 *addr,
-                      u32 supp_rates)
+                      u32 supp_rates, bool auth)
        __acquires(RCU)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
@@ -347,7 +334,42 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
        sta->sta.supp_rates[band] = supp_rates |
                        ieee80211_mandatory_rates(local, band);
 
-       return ieee80211_ibss_finish_sta(sta);
+       return ieee80211_ibss_finish_sta(sta, auth);
+}
+
+static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
+                                       struct ieee80211_mgmt *mgmt,
+                                       size_t len)
+{
+       u16 auth_alg, auth_transaction;
+
+       lockdep_assert_held(&sdata->u.ibss.mtx);
+
+       if (len < 24 + 6)
+               return;
+
+       auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
+       auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
+
+       if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
+               return;
+#ifdef CONFIG_MAC80211_IBSS_DEBUG
+       printk(KERN_DEBUG "%s: RX Auth SA=%pM DA=%pM BSSID=%pM."
+              "(auth_transaction=%d)\n",
+              sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction);
+#endif
+       sta_info_destroy_addr(sdata, mgmt->sa);
+       ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
+       rcu_read_unlock();
+
+       /*
+        * IEEE 802.11 standard does not require authentication in IBSS
+        * networks and most implementations do not seem to use it.
+        * However, try to reply to authentication attempts if someone
+        * has actually implemented this.
+        */
+       ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0,
+                           mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0);
 }
 
 static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -381,7 +403,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                return;
 
        if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
-           memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) {
+           compare_ether_addr(mgmt->bssid, sdata->u.ibss.bssid) == 0) {
 
                rcu_read_lock();
                sta = sta_info_get(sdata, mgmt->sa);
@@ -412,7 +434,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                        } else {
                                rcu_read_unlock();
                                sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
-                                               mgmt->sa, supp_rates);
+                                               mgmt->sa, supp_rates, true);
                        }
                }
 
@@ -486,7 +508,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                goto put_bss;
 
        /* same BSSID */
-       if (memcmp(cbss->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0)
+       if (compare_ether_addr(cbss->bssid, sdata->u.ibss.bssid) == 0)
                goto put_bss;
 
        if (rx_status->flag & RX_FLAG_MACTIME_MPDU) {
@@ -540,7 +562,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                ieee80211_sta_join_ibss(sdata, bss);
                supp_rates = ieee80211_sta_get_rates(local, elems, band);
                ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
-                                      supp_rates);
+                                      supp_rates, true);
                rcu_read_unlock();
        }
 
@@ -643,8 +665,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
               "IBSS networks with same SSID (merge)\n", sdata->name);
 
        ieee80211_request_internal_scan(sdata,
-                       ifibss->ssid, ifibss->ssid_len,
-                       ifibss->fixed_channel ? ifibss->channel : NULL);
+                       ifibss->ssid, ifibss->ssid_len, NULL);
 }
 
 static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -810,8 +831,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
        if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da))
                return;
 
-       if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 &&
-           memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
+       if (compare_ether_addr(mgmt->bssid, ifibss->bssid) != 0 &&
+           !is_broadcast_ether_addr(mgmt->bssid))
                return;
 
        end = ((u8 *) mgmt) + len;
@@ -855,9 +876,6 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
        size_t baselen;
        struct ieee802_11_elems elems;
 
-       if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
-               return; /* ignore ProbeResp to foreign address */
-
        baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
        if (baselen > len)
                return;
@@ -945,7 +963,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
                list_del(&sta->list);
                spin_unlock_bh(&ifibss->incomplete_lock);
 
-               ieee80211_ibss_finish_sta(sta);
+               ieee80211_ibss_finish_sta(sta, true);
                rcu_read_unlock();
                spin_lock_bh(&ifibss->incomplete_lock);
        }
@@ -1059,6 +1077,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
                sdata->u.ibss.fixed_bssid = false;
 
        sdata->u.ibss.privacy = params->privacy;
+       sdata->u.ibss.control_port = params->control_port;
        sdata->u.ibss.basic_rates = params->basic_rates;
        memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
               sizeof(params->mcast_rate));
index 2f0642d9e154672da4959bfe4c3e3d828fc3cdac..796b13bfc9532c1adcb5199934980c255443dbe0 100644 (file)
@@ -105,6 +105,44 @@ struct ieee80211_bss {
         */
        bool has_erp_value;
        u8 erp_value;
+
+       /* Keep track of the corruption of the last beacon/probe response. */
+       u8 corrupt_data;
+
+       /* Keep track of what bits of information we have valid info for. */
+       u8 valid_data;
+};
+
+/**
+ * enum ieee80211_corrupt_data_flags - BSS data corruption flags
+ * @IEEE80211_BSS_CORRUPT_BEACON: last beacon frame received was corrupted
+ * @IEEE80211_BSS_CORRUPT_PROBE_RESP: last probe response received was corrupted
+ *
+ * These are bss flags that are attached to a bss in the
+ * @corrupt_data field of &struct ieee80211_bss.
+ */
+enum ieee80211_bss_corrupt_data_flags {
+       IEEE80211_BSS_CORRUPT_BEACON            = BIT(0),
+       IEEE80211_BSS_CORRUPT_PROBE_RESP        = BIT(1)
+};
+
+/**
+ * enum ieee80211_valid_data_flags - BSS valid data flags
+ * @IEEE80211_BSS_VALID_DTIM: DTIM data was gathered from non-corrupt IE
+ * @IEEE80211_BSS_VALID_WMM: WMM/UAPSD data was gathered from non-corrupt IE
+ * @IEEE80211_BSS_VALID_RATES: Supported rates were gathered from non-corrupt IE
+ * @IEEE80211_BSS_VALID_ERP: ERP flag was gathered from non-corrupt IE
+ *
+ * These are bss flags that are attached to a bss in the
+ * @valid_data field of &struct ieee80211_bss.  They show which parts
+ * of the data structure were recieved as a result of an un-corrupted
+ * beacon/probe response.
+ */
+enum ieee80211_bss_valid_data_flags {
+       IEEE80211_BSS_VALID_DTIM                = BIT(0),
+       IEEE80211_BSS_VALID_WMM                 = BIT(1),
+       IEEE80211_BSS_VALID_RATES               = BIT(2),
+       IEEE80211_BSS_VALID_ERP                 = BIT(3)
 };
 
 static inline u8 *bss_mesh_cfg(struct ieee80211_bss *bss)
@@ -228,7 +266,7 @@ struct ieee80211_rx_data {
 struct beacon_data {
        u8 *head, *tail;
        int head_len, tail_len;
-       int dtim_period;
+       struct rcu_head rcu_head;
 };
 
 struct ieee80211_if_ap {
@@ -280,10 +318,6 @@ struct mesh_preq_queue {
 
 enum ieee80211_work_type {
        IEEE80211_WORK_ABORT,
-       IEEE80211_WORK_DIRECT_PROBE,
-       IEEE80211_WORK_AUTH,
-       IEEE80211_WORK_ASSOC_BEACON_WAIT,
-       IEEE80211_WORK_ASSOC,
        IEEE80211_WORK_REMAIN_ON_CHANNEL,
        IEEE80211_WORK_OFFCHANNEL_TX,
 };
@@ -316,35 +350,9 @@ struct ieee80211_work {
        unsigned long timeout;
        enum ieee80211_work_type type;
 
-       u8 filter_ta[ETH_ALEN];
-
        bool started;
 
        union {
-               struct {
-                       int tries;
-                       u16 algorithm, transaction;
-                       u8 ssid[IEEE80211_MAX_SSID_LEN];
-                       u8 ssid_len;
-                       u8 key[WLAN_KEY_LEN_WEP104];
-                       u8 key_len, key_idx;
-                       bool privacy;
-                       bool synced;
-               } probe_auth;
-               struct {
-                       struct cfg80211_bss *bss;
-                       const u8 *supp_rates;
-                       const u8 *ht_information_ie;
-                       enum ieee80211_smps_mode smps;
-                       int tries;
-                       u16 capability;
-                       u8 prev_bssid[ETH_ALEN];
-                       u8 ssid[IEEE80211_MAX_SSID_LEN];
-                       u8 ssid_len;
-                       u8 supp_rates_len;
-                       bool wmm_used, use_11n, uapsd_used;
-                       bool synced;
-               } assoc;
                struct {
                        u32 duration;
                } remain;
@@ -355,9 +363,8 @@ struct ieee80211_work {
                } offchan_tx;
        };
 
-       int ie_len;
-       /* must be last */
-       u8 ie[0];
+       size_t data_len;
+       u8 data[];
 };
 
 /* flags used in struct ieee80211_if_managed.flags */
@@ -373,6 +380,43 @@ enum ieee80211_sta_flags {
        IEEE80211_STA_RESET_SIGNAL_AVE  = BIT(9),
 };
 
+struct ieee80211_mgd_auth_data {
+       struct cfg80211_bss *bss;
+       unsigned long timeout;
+       int tries;
+       u16 algorithm, expected_transaction;
+
+       u8 key[WLAN_KEY_LEN_WEP104];
+       u8 key_len, key_idx;
+       bool synced;
+       bool done;
+
+       size_t ie_len;
+       u8 ie[];
+};
+
+struct ieee80211_mgd_assoc_data {
+       struct cfg80211_bss *bss;
+       const u8 *supp_rates;
+       const u8 *ht_information_ie;
+
+       unsigned long timeout;
+       int tries;
+
+       u16 capability;
+       u8 prev_bssid[ETH_ALEN];
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
+       u8 ssid_len;
+       u8 supp_rates_len;
+       bool wmm_used, uapsd_used;
+       bool have_beacon;
+       bool sent_assoc;
+       bool synced;
+
+       size_t ie_len;
+       u8 ie[];
+};
+
 struct ieee80211_if_managed {
        struct timer_list timer;
        struct timer_list conn_mon_timer;
@@ -389,6 +433,8 @@ struct ieee80211_if_managed {
 
        struct mutex mtx;
        struct cfg80211_bss *associated;
+       struct ieee80211_mgd_auth_data *auth_data;
+       struct ieee80211_mgd_assoc_data *assoc_data;
 
        u8 bssid[ETH_ALEN];
 
@@ -470,7 +516,9 @@ struct ieee80211_if_ibss {
        bool fixed_channel;
        bool privacy;
 
-       u8 bssid[ETH_ALEN];
+       bool control_port;
+
+       u8 bssid[ETH_ALEN] __aligned(2);
        u8 ssid[IEEE80211_MAX_SSID_LEN];
        u8 ssid_len, ie_len;
        u8 *ie;
@@ -646,6 +694,7 @@ struct ieee80211_sub_if_data {
 
        /* bitmap of allowed (non-MCS) rate indexes for rate control */
        u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
+       u8  rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
 
        union {
                struct ieee80211_if_ap ap;
@@ -769,7 +818,6 @@ struct ieee80211_local {
        struct list_head work_list;
        struct timer_list work_timer;
        struct work_struct work_work;
-       struct sk_buff_head work_skb_queue;
 
        /*
         * private workqueue to mac80211. mac80211 makes this accessible
@@ -1110,6 +1158,9 @@ struct ieee802_11_elems {
        u8 quiet_elem_len;
        u8 num_of_quiet_elem;   /* can be more the one */
        u8 timeout_int_len;
+
+       /* whether a parse error occurred while retrieving these elements */
+       bool parse_error;
 };
 
 static inline struct ieee80211_local *hw_to_local(
@@ -1118,12 +1169,6 @@ static inline struct ieee80211_local *hw_to_local(
        return container_of(hw, struct ieee80211_local, hw);
 }
 
-static inline struct ieee80211_hw *local_to_hw(
-       struct ieee80211_local *local)
-{
-       return &local->hw;
-}
-
 
 static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
 {
@@ -1146,11 +1191,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
 int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
                        struct cfg80211_assoc_request *req);
 int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
-                        struct cfg80211_deauth_request *req,
-                        void *cookie);
+                        struct cfg80211_deauth_request *req);
 int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
-                          struct cfg80211_disassoc_request *req,
-                          void *cookie);
+                          struct cfg80211_disassoc_request *req);
 void ieee80211_send_pspoll(struct ieee80211_local *local,
                           struct ieee80211_sub_if_data *sdata);
 void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
@@ -1168,6 +1211,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
                                  struct sk_buff *skb);
 void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata);
 void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
+void ieee80211_mgd_teardown(struct ieee80211_sub_if_data *sdata);
 
 /* IBSS code */
 void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
@@ -1345,7 +1389,8 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
 void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
                                     struct ieee80211_hdr *hdr, const u8 *tsc,
                                     gfp_t gfp);
-void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
+void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
+                              bool bss_notify);
 void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
 
 void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
@@ -1396,7 +1441,7 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
                         u16 transaction, u16 auth_alg,
                         u8 *extra, size_t extra_len, const u8 *bssid,
-                        const u8 *key, u8 key_len, u8 key_idx);
+                        const u8 *da, const u8 *key, u8 key_len, u8 key_idx);
 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
                             const u8 *ie, size_t ie_len,
                             enum ieee80211_band band, u32 rate_mask,
@@ -1436,8 +1481,6 @@ void ieee80211_work_init(struct ieee80211_local *local);
 void ieee80211_add_work(struct ieee80211_work *wk);
 void free_work(struct ieee80211_work *wk);
 void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata);
-ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
-                                          struct sk_buff *skb);
 int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
                                   struct ieee80211_channel *chan,
                                   enum nl80211_channel_type channel_type,
index 01a21c2f6ab37df336f5f69c55f33de4e0a698f3..401c01f0731e996e5c22435f0066b53c97529559 100644 (file)
@@ -304,7 +304,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
                 * need to initialise the hardware if the hardware
                 * doesn't start up with sane defaults
                 */
-               ieee80211_set_wmm_default(sdata);
+               ieee80211_set_wmm_default(sdata, true);
        }
 
        set_bit(SDATA_STATE_RUNNING, &sdata->state);
@@ -318,9 +318,9 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
                        goto err_del_interface;
                }
 
-               sta_info_move_state(sta, IEEE80211_STA_AUTH);
-               sta_info_move_state(sta, IEEE80211_STA_ASSOC);
-               sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
+               sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+               sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
+               sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
 
                res = sta_info_insert(sta);
                if (res) {
@@ -644,6 +644,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
 
        if (ieee80211_vif_is_mesh(&sdata->vif))
                mesh_rmc_free(sdata);
+       else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+               ieee80211_mgd_teardown(sdata);
 
        flushed = sta_info_flush(local, sdata);
        WARN_ON(flushed);
@@ -1181,6 +1183,13 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
                sband = local->hw.wiphy->bands[i];
                sdata->rc_rateidx_mask[i] =
                        sband ? (1 << sband->n_bitrates) - 1 : 0;
+               if (sband)
+                       memcpy(sdata->rc_rateidx_mcs_mask[i],
+                              sband->ht_cap.mcs.rx_mask,
+                              sizeof(sdata->rc_rateidx_mcs_mask[i]));
+               else
+                       memset(sdata->rc_rateidx_mcs_mask[i], 0,
+                              sizeof(sdata->rc_rateidx_mcs_mask[i]));
        }
 
        /* setup type-dependent data */
@@ -1303,7 +1312,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
 
                /* do not count disabled managed interfaces */
                if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-                   !sdata->u.mgd.associated) {
+                   !sdata->u.mgd.associated &&
+                   !sdata->u.mgd.auth_data &&
+                   !sdata->u.mgd.assoc_data) {
                        sdata->vif.bss_conf.idle = true;
                        continue;
                }
@@ -1323,7 +1334,8 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
                wk->sdata->vif.bss_conf.idle = false;
        }
 
-       if (local->scan_sdata) {
+       if (local->scan_sdata &&
+           !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) {
                scanning = true;
                local->scan_sdata->vif.bss_conf.idle = false;
        }
@@ -1332,6 +1344,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
                hw_roc = true;
 
        list_for_each_entry(sdata, &local->interfaces, list) {
+               if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+                   sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+                       continue;
                if (sdata->old_idle == sdata->vif.bss_conf.idle)
                        continue;
                if (!ieee80211_sdata_running(sdata))
index 87a89741432dce811cdb31168036788146f5721b..5bb600d93d77b4cf2ec9c0196c002b7ab46538df 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/export.h>
 #include <net/mac80211.h>
+#include <asm/unaligned.h>
 #include "ieee80211_i.h"
 #include "driver-ops.h"
 #include "debugfs_key.h"
@@ -54,14 +55,6 @@ static void assert_key_lock(struct ieee80211_local *local)
        lockdep_assert_held(&local->key_mtx);
 }
 
-static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
-{
-       if (key->sta)
-               return &key->sta->sta;
-
-       return NULL;
-}
-
 static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
 {
        /*
@@ -95,7 +88,7 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
 static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 {
        struct ieee80211_sub_if_data *sdata;
-       struct ieee80211_sta *sta;
+       struct sta_info *sta;
        int ret;
 
        might_sleep();
@@ -105,7 +98,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 
        assert_key_lock(key->local);
 
-       sta = get_sta_for_key(key);
+       sta = key->sta;
 
        /*
         * If this is a per-STA GTK, check if it
@@ -115,6 +108,9 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
            !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
                goto out_unsupported;
 
+       if (sta && !sta->uploaded)
+               goto out_unsupported;
+
        sdata = key->sdata;
        if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
                /*
@@ -123,12 +119,10 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
                 */
                if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE))
                        goto out_unsupported;
-               sdata = container_of(sdata->bss,
-                                    struct ieee80211_sub_if_data,
-                                    u.ap);
        }
 
-       ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
+       ret = drv_set_key(key->local, SET_KEY, sdata,
+                         sta ? &sta->sta : NULL, &key->conf);
 
        if (!ret) {
                key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
@@ -147,7 +141,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
        if (ret != -ENOSPC && ret != -EOPNOTSUPP)
                wiphy_err(key->local->hw.wiphy,
                          "failed to set key (%d, %pM) to hardware (%d)\n",
-                         key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
+                         key->conf.keyidx,
+                         sta ? sta->sta.addr : bcast_addr, ret);
 
  out_unsupported:
        switch (key->conf.cipher) {
@@ -166,7 +161,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
 {
        struct ieee80211_sub_if_data *sdata;
-       struct ieee80211_sta *sta;
+       struct sta_info *sta;
        int ret;
 
        might_sleep();
@@ -179,7 +174,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
        if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
                return;
 
-       sta = get_sta_for_key(key);
+       sta = key->sta;
        sdata = key->sdata;
 
        if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
@@ -187,18 +182,14 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
              (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
                increment_tailroom_need_count(sdata);
 
-       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-               sdata = container_of(sdata->bss,
-                                    struct ieee80211_sub_if_data,
-                                    u.ap);
-
        ret = drv_set_key(key->local, DISABLE_KEY, sdata,
-                         sta, &key->conf);
+                         sta ? &sta->sta : NULL, &key->conf);
 
        if (ret)
                wiphy_err(key->local->hw.wiphy,
                          "failed to remove key (%d, %pM) from hardware (%d)\n",
-                         key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
+                         key->conf.keyidx,
+                         sta ? sta->sta.addr : bcast_addr, ret);
 
        key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
 }
index b142bd4c239096f51fbf0e79e9b507a2bf35d1d0..36fa8051296c80fab82c37f206a46d5892592435 100644 (file)
@@ -155,7 +155,8 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
                power = chan->max_power;
        else
                power = local->power_constr_level ?
-                       (chan->max_power - local->power_constr_level) :
+                       min(chan->max_power,
+                               (chan->max_reg_power  - local->power_constr_level)) :
                        chan->max_power;
 
        if (local->user_power_level >= 0)
@@ -198,15 +199,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
                return;
 
        if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-               /*
-                * While not associated, claim a BSSID of all-zeroes
-                * so that drivers don't do any weird things with the
-                * BSSID at that time.
-                */
-               if (sdata->vif.bss_conf.assoc)
-                       sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
-               else
-                       sdata->vif.bss_conf.bssid = zero;
+               sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
        } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
                sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
        else if (sdata->vif.type == NL80211_IFTYPE_AP)
@@ -293,11 +286,11 @@ static void ieee80211_tasklet_handler(unsigned long data)
                        /* Clear skb->pkt_type in order to not confuse kernel
                         * netstack. */
                        skb->pkt_type = 0;
-                       ieee80211_rx(local_to_hw(local), skb);
+                       ieee80211_rx(&local->hw, skb);
                        break;
                case IEEE80211_TX_STATUS_MSG:
                        skb->pkt_type = 0;
-                       ieee80211_tx_status(local_to_hw(local), skb);
+                       ieee80211_tx_status(&local->hw, skb);
                        break;
                case IEEE80211_EOSP_MSG:
                        eosp_data = (void *)skb->cb;
@@ -534,6 +527,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        int priv_size, i;
        struct wiphy *wiphy;
 
+       if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove)))
+               return NULL;
+
        /* Ensure 32-byte alignment of our private data and hw private data.
         * We use the wiphy priv data for both our ieee80211_local and for
         * the driver's private data
@@ -672,7 +668,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 
        ieee80211_hw_roc_setup(local);
 
-       return local_to_hw(local);
+       return &local->hw;
 }
 EXPORT_SYMBOL(ieee80211_alloc_hw);
 
@@ -701,6 +697,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
            )
                return -EINVAL;
 
+       if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan)
+               return -EINVAL;
+
        if (hw->max_report_rates == 0)
                hw->max_report_rates = hw->max_rates;
 
index c707c8bf6d2cbc1ee8e5e54b8d9776d59e5229a4..e5fbb7cf356250ce75968d8102d4dd87430ef551 100644 (file)
@@ -204,7 +204,7 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
                        kmem_cache_free(rm_cache, p);
                        --entries;
                } else if ((seqnum == p->seqnum) &&
-                          (memcmp(sa, p->sa, ETH_ALEN) == 0))
+                          (compare_ether_addr(sa, p->sa) == 0))
                        return -1;
        }
 
index bd14bd26a2b64eec5321bb218e2cd407e60b2ada..8d53b71378e3865cb38376ad35195be8c8193e41 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/types.h>
 #include <linux/jhash.h>
-#include <asm/unaligned.h>
 #include "ieee80211_i.h"
 
 
@@ -86,6 +85,8 @@ enum mesh_deferred_task_flags {
  * @state_lock: mesh path state lock used to protect changes to the
  * mpath itself.  No need to take this lock when adding or removing
  * an mpath to a hash bucket on a path table.
+ * @rann_snd_addr: the RANN sender address
+ * @is_root: the destination station of this path is a root node
  * @is_gate: the destination station of this path is a mesh gate
  *
  *
@@ -110,6 +111,8 @@ struct mesh_path {
        u8 discovery_retries;
        enum mesh_path_flags flags;
        spinlock_t state_lock;
+       u8 rann_snd_addr[ETH_ALEN];
+       bool is_root;
        bool is_gate;
 };
 
index 54df1b2bafd2882454bc71b3a018161f0f83e5e3..1c6f3d02aebf5a4f19630f604aae94cda6810247 100644 (file)
@@ -8,6 +8,8 @@
  */
 
 #include <linux/slab.h>
+#include <linux/etherdevice.h>
+#include <asm/unaligned.h>
 #include "wme.h"
 #include "mesh.h"
 
@@ -322,6 +324,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
                                   struct sta_info *sta)
 {
        struct ieee80211_supported_band *sband;
+       struct rate_info rinfo;
        /* This should be adjusted for each device */
        int device_constant = 1 << ARITH_SHIFT;
        int test_frame_len = TEST_FRAME_LEN << ARITH_SHIFT;
@@ -335,7 +338,9 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
        if (sta->fail_avg >= 100)
                return MAX_METRIC;
 
-       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+       sta_set_rate_info_tx(sta, &sta->last_tx_rate, &rinfo);
+       rate = cfg80211_calculate_bitrate(&rinfo);
+       if (WARN_ON(!rate))
                return MAX_METRIC;
 
        err = (sta->fail_avg << ARITH_SHIFT) / 100;
@@ -343,7 +348,6 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
        /* bitrate is in units of 100 Kbps, while we need rate in units of
         * 1Mbps. This will be corrected on tx_time computation.
         */
-       rate = sband->bitrates[sta->last_tx_rate.idx].bitrate;
        tx_time = (device_constant + 10 * test_frame_len / rate);
        estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err));
        result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ;
@@ -418,7 +422,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
                new_metric = MAX_METRIC;
        exp_time = TU_TO_EXP_TIME(orig_lifetime);
 
-       if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) {
+       if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) {
                /* This MP is the originator, we are not interested in this
                 * frame, except for updating transmitter's path info.
                 */
@@ -468,7 +472,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
 
        /* Update and check transmitter routing info */
        ta = mgmt->sa;
-       if (memcmp(orig_addr, ta, ETH_ALEN) == 0)
+       if (compare_ether_addr(orig_addr, ta) == 0)
                fresh_info = false;
        else {
                fresh_info = true;
@@ -512,8 +516,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
                                    u8 *preq_elem, u32 metric)
 {
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-       struct mesh_path *mpath;
+       struct mesh_path *mpath = NULL;
        u8 *target_addr, *orig_addr;
+       const u8 *da;
        u8 target_flags, ttl;
        u32 orig_sn, target_sn, lifetime;
        bool reply = false;
@@ -528,7 +533,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
 
        mhwmp_dbg("received PREQ from %pM", orig_addr);
 
-       if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) {
+       if (compare_ether_addr(target_addr, sdata->vif.addr) == 0) {
                mhwmp_dbg("PREQ is for us");
                forward = false;
                reply = true;
@@ -575,7 +580,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
                        ifmsh->mshstats.dropped_frames_ttl++;
        }
 
-       if (forward) {
+       if (forward && ifmsh->mshcfg.dot11MeshForwarding) {
                u32 preq_id;
                u8 hopcount, flags;
 
@@ -590,9 +595,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
                flags = PREQ_IE_FLAGS(preq_elem);
                preq_id = PREQ_IE_PREQ_ID(preq_elem);
                hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
+               da = (mpath && mpath->is_root) ?
+                       mpath->rann_snd_addr : broadcast_addr;
                mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
                                cpu_to_le32(orig_sn), target_flags, target_addr,
-                               cpu_to_le32(target_sn), broadcast_addr,
+                               cpu_to_le32(target_sn), da,
                                hopcount, ttl, cpu_to_le32(lifetime),
                                cpu_to_le32(metric), cpu_to_le32(preq_id),
                                sdata);
@@ -614,6 +621,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
                                    struct ieee80211_mgmt *mgmt,
                                    u8 *prep_elem, u32 metric)
 {
+       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
        struct mesh_path *mpath;
        u8 *target_addr, *orig_addr;
        u8 ttl, hopcount, flags;
@@ -623,10 +631,13 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
        mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem));
 
        orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
-       if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
+       if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0)
                /* destination, no forwarding required */
                return;
 
+       if (!ifmsh->mshcfg.dot11MeshForwarding)
+               return;
+
        ttl = PREP_IE_TTL(prep_elem);
        if (ttl <= 1) {
                sdata->u.mesh.mshstats.dropped_frames_ttl++;
@@ -693,21 +704,26 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
        rcu_read_lock();
        mpath = mesh_path_lookup(target_addr, sdata);
        if (mpath) {
+               struct sta_info *sta;
+
                spin_lock_bh(&mpath->state_lock);
+               sta = next_hop_deref_protected(mpath);
                if (mpath->flags & MESH_PATH_ACTIVE &&
-                   memcmp(ta, next_hop_deref_protected(mpath)->sta.addr,
-                                                       ETH_ALEN) == 0 &&
+                   compare_ether_addr(ta, sta->sta.addr) == 0 &&
                    (!(mpath->flags & MESH_PATH_SN_VALID) ||
                    SN_GT(target_sn, mpath->sn))) {
                        mpath->flags &= ~MESH_PATH_ACTIVE;
                        mpath->sn = target_sn;
                        spin_unlock_bh(&mpath->state_lock);
+                       if (!ifmsh->mshcfg.dot11MeshForwarding)
+                               goto endperr;
                        mesh_path_error_tx(ttl, target_addr, cpu_to_le32(target_sn),
                                           cpu_to_le16(target_rcode),
                                           broadcast_addr, sdata);
                } else
                        spin_unlock_bh(&mpath->state_lock);
        }
+endperr:
        rcu_read_unlock();
 }
 
@@ -738,11 +754,11 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
        metric = rann->rann_metric;
 
        /*  Ignore our own RANNs */
-       if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
+       if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0)
                return;
 
-       mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr,
-                       root_is_gate);
+       mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)",
+                       orig_addr, mgmt->sa, root_is_gate);
 
        rcu_read_lock();
        mpath = mesh_path_lookup(orig_addr, sdata);
@@ -764,7 +780,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
                mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
        }
 
-       if (mpath->sn < orig_sn) {
+       if (mpath->sn < orig_sn && ifmsh->mshcfg.dot11MeshForwarding) {
                mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
                                       cpu_to_le32(orig_sn),
                                       0, NULL, 0, broadcast_addr,
@@ -773,6 +789,11 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
                                       0, sdata);
                mpath->sn = orig_sn;
        }
+
+       /* Using individually addressed PREQ for root node */
+       memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
+       mpath->is_root = true;
+
        if (root_is_gate)
                mesh_path_add_gate(mpath);
 
@@ -908,6 +929,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
        struct mesh_preq_queue *preq_node;
        struct mesh_path *mpath;
        u8 ttl, target_flags;
+       const u8 *da;
        u32 lifetime;
 
        spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
@@ -970,9 +992,10 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
                target_flags = MP_F_RF;
 
        spin_unlock_bh(&mpath->state_lock);
+       da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr;
        mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr,
                        cpu_to_le32(ifmsh->sn), target_flags, mpath->dst,
-                       cpu_to_le32(mpath->sn), broadcast_addr, 0,
+                       cpu_to_le32(mpath->sn), da, 0,
                        ttl, cpu_to_le32(lifetime), 0,
                        cpu_to_le32(ifmsh->preq_id++), sdata);
        mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
@@ -1063,7 +1086,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
        if (time_after(jiffies,
                       mpath->exp_time -
                       msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
-           !memcmp(sdata->vif.addr, hdr->addr4, ETH_ALEN) &&
+           !compare_ether_addr(sdata->vif.addr, hdr->addr4) &&
            !(mpath->flags & MESH_PATH_RESOLVING) &&
            !(mpath->flags & MESH_PATH_FIXED))
                mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
index edf167e3b8f391d65784bc56f3a3f43fc07b9169..be1361b5f7ada32953a080a573bb6574d0fe9ac9 100644 (file)
@@ -336,7 +336,7 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath,
 }
 
 
-static struct mesh_path *path_lookup(struct mesh_table *tbl, u8 *dst,
+static struct mesh_path *mpath_lookup(struct mesh_table *tbl, u8 *dst,
                                          struct ieee80211_sub_if_data *sdata)
 {
        struct mesh_path *mpath;
@@ -348,7 +348,7 @@ static struct mesh_path *path_lookup(struct mesh_table *tbl, u8 *dst,
        hlist_for_each_entry_rcu(node, n, bucket, list) {
                mpath = node->mpath;
                if (mpath->sdata == sdata &&
-                               memcmp(dst, mpath->dst, ETH_ALEN) == 0) {
+                               compare_ether_addr(dst, mpath->dst) == 0) {
                        if (MPATH_EXPIRED(mpath)) {
                                spin_lock_bh(&mpath->state_lock);
                                mpath->flags &= ~MESH_PATH_ACTIVE;
@@ -371,12 +371,12 @@ static struct mesh_path *path_lookup(struct mesh_table *tbl, u8 *dst,
  */
 struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
 {
-       return path_lookup(rcu_dereference(mesh_paths), dst, sdata);
+       return mpath_lookup(rcu_dereference(mesh_paths), dst, sdata);
 }
 
 struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
 {
-       return path_lookup(rcu_dereference(mpp_paths), dst, sdata);
+       return mpath_lookup(rcu_dereference(mpp_paths), dst, sdata);
 }
 
 
@@ -523,7 +523,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
        int err = 0;
        u32 hash_idx;
 
-       if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0)
+       if (compare_ether_addr(dst, sdata->vif.addr) == 0)
                /* never add ourselves as neighbours */
                return -ENOTSUPP;
 
@@ -559,12 +559,13 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
        hash_idx = mesh_table_hash(dst, sdata, tbl);
        bucket = &tbl->hash_buckets[hash_idx];
 
-       spin_lock_bh(&tbl->hashwlock[hash_idx]);
+       spin_lock(&tbl->hashwlock[hash_idx]);
 
        err = -EEXIST;
        hlist_for_each_entry(node, n, bucket, list) {
                mpath = node->mpath;
-               if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0)
+               if (mpath->sdata == sdata &&
+                   compare_ether_addr(dst, mpath->dst) == 0)
                        goto err_exists;
        }
 
@@ -575,7 +576,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
 
        mesh_paths_generation++;
 
-       spin_unlock_bh(&tbl->hashwlock[hash_idx]);
+       spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
        if (grow) {
                set_bit(MESH_WORK_GROW_MPATH_TABLE,  &ifmsh->wrkq_flags);
@@ -584,7 +585,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
        return 0;
 
 err_exists:
-       spin_unlock_bh(&tbl->hashwlock[hash_idx]);
+       spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
        kfree(new_node);
 err_node_alloc:
@@ -655,7 +656,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
        int err = 0;
        u32 hash_idx;
 
-       if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0)
+       if (compare_ether_addr(dst, sdata->vif.addr) == 0)
                /* never add ourselves as neighbours */
                return -ENOTSUPP;
 
@@ -687,12 +688,13 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
        hash_idx = mesh_table_hash(dst, sdata, tbl);
        bucket = &tbl->hash_buckets[hash_idx];
 
-       spin_lock_bh(&tbl->hashwlock[hash_idx]);
+       spin_lock(&tbl->hashwlock[hash_idx]);
 
        err = -EEXIST;
        hlist_for_each_entry(node, n, bucket, list) {
                mpath = node->mpath;
-               if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0)
+               if (mpath->sdata == sdata &&
+                   compare_ether_addr(dst, mpath->dst) == 0)
                        goto err_exists;
        }
 
@@ -701,7 +703,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
            tbl->mean_chain_len * (tbl->hash_mask + 1))
                grow = 1;
 
-       spin_unlock_bh(&tbl->hashwlock[hash_idx]);
+       spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
        if (grow) {
                set_bit(MESH_WORK_GROW_MPP_TABLE,  &ifmsh->wrkq_flags);
@@ -710,7 +712,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
        return 0;
 
 err_exists:
-       spin_unlock_bh(&tbl->hashwlock[hash_idx]);
+       spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
        kfree(new_node);
 err_node_alloc:
@@ -809,9 +811,9 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
        for_each_mesh_entry(tbl, p, node, i) {
                mpath = node->mpath;
                if (rcu_dereference(mpath->next_hop) == sta) {
-                       spin_lock_bh(&tbl->hashwlock[i]);
+                       spin_lock(&tbl->hashwlock[i]);
                        __mesh_path_del(tbl, node);
-                       spin_unlock_bh(&tbl->hashwlock[i]);
+                       spin_unlock(&tbl->hashwlock[i]);
                }
        }
        read_unlock_bh(&pathtbl_resize_lock);
@@ -882,11 +884,11 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
        hash_idx = mesh_table_hash(addr, sdata, tbl);
        bucket = &tbl->hash_buckets[hash_idx];
 
-       spin_lock_bh(&tbl->hashwlock[hash_idx]);
+       spin_lock(&tbl->hashwlock[hash_idx]);
        hlist_for_each_entry(node, n, bucket, list) {
                mpath = node->mpath;
                if (mpath->sdata == sdata &&
-                   memcmp(addr, mpath->dst, ETH_ALEN) == 0) {
+                   compare_ether_addr(addr, mpath->dst) == 0) {
                        __mesh_path_del(tbl, node);
                        goto enddel;
                }
@@ -895,7 +897,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
        err = -ENXIO;
 enddel:
        mesh_paths_generation++;
-       spin_unlock_bh(&tbl->hashwlock[hash_idx]);
+       spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
        return err;
 }
index a17251730b9e603097ca8763f3301452168444a7..4e53c4cbca9e5248f26254a261796ffdd5236681 100644 (file)
 #define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
 #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
 
+/* We only need a valid sta if user configured a minimum rssi_threshold. */
+#define rssi_threshold_check(sta, sdata) \
+               (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
+               (sta && (s8) -ewma_read(&sta->avg_signal) > \
+               sdata->u.mesh.mshcfg.rssi_threshold))
+
 enum plink_event {
        PLINK_UNDEFINED,
        OPN_ACPT,
@@ -96,9 +102,9 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
        if (!sta)
                return NULL;
 
-       sta_info_move_state(sta, IEEE80211_STA_AUTH);
-       sta_info_move_state(sta, IEEE80211_STA_ASSOC);
-       sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
+       sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+       sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
+       sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
 
        set_sta_flag(sta, WLAN_STA_WME);
 
@@ -301,7 +307,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
        if (mesh_peer_accepts_plinks(elems) &&
                        sta->plink_state == NL80211_PLINK_LISTEN &&
                        sdata->u.mesh.accepting_plinks &&
-                       sdata->u.mesh.mshcfg.auto_open_plinks)
+                       sdata->u.mesh.mshcfg.auto_open_plinks &&
+                       rssi_threshold_check(sta, sdata))
                mesh_plink_open(sta);
 
        rcu_read_unlock();
@@ -531,6 +538,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                return;
        }
 
+       if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
+           !rssi_threshold_check(sta, sdata)) {
+               mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n",
+                       mgmt->sa);
+               rcu_read_unlock();
+               return;
+       }
+
        if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
                mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
                rcu_read_unlock();
index 295be92f7c7747238ae1ae9204982db8fd264d77..c08924aeac0017de011a3c305fcedf9faa4f8796 100644 (file)
 #include "rate.h"
 #include "led.h"
 
+#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
+#define IEEE80211_AUTH_MAX_TRIES 3
+#define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5)
+#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
+#define IEEE80211_ASSOC_MAX_TRIES 3
+
 static int max_nullfunc_tries = 2;
 module_param(max_nullfunc_tries, int, 0644);
 MODULE_PARM_DESC(max_nullfunc_tries,
@@ -82,6 +88,8 @@ MODULE_PARM_DESC(probe_wait_ms,
 #define TMR_RUNNING_TIMER      0
 #define TMR_RUNNING_CHANSW     1
 
+#define DEAUTH_DISASSOC_LEN    (24 /* hdr */ + 2 /* reason */)
+
 /*
  * All cfg80211 functions have to be called outside a locked
  * section so that they can acquire a lock themselves... This
@@ -97,6 +105,15 @@ enum rx_mgmt_action {
 
        /* caller must call cfg80211_send_disassoc() */
        RX_MGMT_CFG80211_DISASSOC,
+
+       /* caller must call cfg80211_send_rx_auth() */
+       RX_MGMT_CFG80211_RX_AUTH,
+
+       /* caller must call cfg80211_send_rx_assoc() */
+       RX_MGMT_CFG80211_RX_ASSOC,
+
+       /* caller must call cfg80211_send_assoc_timeout() */
+       RX_MGMT_CFG80211_ASSOC_TIMEOUT,
 };
 
 /* utils */
@@ -115,8 +132,7 @@ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
  * has happened -- the work that runs from this timer will
  * do that.
  */
-static void run_again(struct ieee80211_if_managed *ifmgd,
-                            unsigned long timeout)
+static void run_again(struct ieee80211_if_managed *ifmgd, unsigned long timeout)
 {
        ASSERT_MGD_MTX(ifmgd);
 
@@ -127,7 +143,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd,
 
 void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
 {
-       if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
+       if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
                return;
 
        mod_timer(&sdata->u.mgd.bcn_mon_timer,
@@ -284,48 +300,356 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
 
 /* frame sending functions */
 
-static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
-                                          const u8 *bssid, u16 stype, u16 reason,
-                                          void *cookie, bool send_frame)
+static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
+                                     struct ieee80211_supported_band *sband,
+                                     u32 *rates)
+{
+       int i, j, count;
+       *rates = 0;
+       count = 0;
+       for (i = 0; i < supp_rates_len; i++) {
+               int rate = (supp_rates[i] & 0x7F) * 5;
+
+               for (j = 0; j < sband->n_bitrates; j++)
+                       if (sband->bitrates[j].bitrate == rate) {
+                               *rates |= BIT(j);
+                               count++;
+                               break;
+                       }
+       }
+
+       return count;
+}
+
+static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
+                               struct sk_buff *skb, const u8 *ht_info_ie,
+                               struct ieee80211_supported_band *sband,
+                               struct ieee80211_channel *channel,
+                               enum ieee80211_smps_mode smps)
+{
+       struct ieee80211_ht_info *ht_info;
+       u8 *pos;
+       u32 flags = channel->flags;
+       u16 cap;
+       struct ieee80211_sta_ht_cap ht_cap;
+
+       BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
+
+       if (!sband->ht_cap.ht_supported)
+               return;
+
+       if (!ht_info_ie)
+               return;
+
+       if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
+               return;
+
+       memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
+       ieee80211_apply_htcap_overrides(sdata, &ht_cap);
+
+       ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
+
+       /* determine capability flags */
+       cap = ht_cap.cap;
+
+       switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+               if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
+                       cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+                       cap &= ~IEEE80211_HT_CAP_SGI_40;
+               }
+               break;
+       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+               if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
+                       cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+                       cap &= ~IEEE80211_HT_CAP_SGI_40;
+               }
+               break;
+       }
+
+       /* set SM PS mode properly */
+       cap &= ~IEEE80211_HT_CAP_SM_PS;
+       switch (smps) {
+       case IEEE80211_SMPS_AUTOMATIC:
+       case IEEE80211_SMPS_NUM_MODES:
+               WARN_ON(1);
+       case IEEE80211_SMPS_OFF:
+               cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
+                       IEEE80211_HT_CAP_SM_PS_SHIFT;
+               break;
+       case IEEE80211_SMPS_STATIC:
+               cap |= WLAN_HT_CAP_SM_PS_STATIC <<
+                       IEEE80211_HT_CAP_SM_PS_SHIFT;
+               break;
+       case IEEE80211_SMPS_DYNAMIC:
+               cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
+                       IEEE80211_HT_CAP_SM_PS_SHIFT;
+               break;
+       }
+
+       /* reserve and fill IE */
+       pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
+       ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
+}
+
+static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
+       u8 *pos, qos_info;
+       size_t offset = 0, noffset;
+       int i, count, rates_len, supp_rates_len;
+       u16 capab;
+       struct ieee80211_supported_band *sband;
+       u32 rates = 0;
+       struct ieee80211_bss *bss = (void *)assoc_data->bss->priv;
+
+       lockdep_assert_held(&ifmgd->mtx);
+
+       sband = local->hw.wiphy->bands[local->oper_channel->band];
 
-       skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
+       if (assoc_data->supp_rates_len) {
+               /*
+                * Get all rates supported by the device and the AP as
+                * some APs don't like getting a superset of their rates
+                * in the association request (e.g. D-Link DAP 1353 in
+                * b-only mode)...
+                */
+               rates_len = ieee80211_compatible_rates(assoc_data->supp_rates,
+                                                      assoc_data->supp_rates_len,
+                                                      sband, &rates);
+       } else {
+               /*
+                * In case AP not provide any supported rates information
+                * before association, we send information element(s) with
+                * all rates that we support.
+                */
+               rates = ~0;
+               rates_len = sband->n_bitrates;
+       }
+
+       skb = alloc_skb(local->hw.extra_tx_headroom +
+                       sizeof(*mgmt) + /* bit too much but doesn't matter */
+                       2 + assoc_data->ssid_len + /* SSID */
+                       4 + rates_len + /* (extended) rates */
+                       4 + /* power capability */
+                       2 + 2 * sband->n_channels + /* supported channels */
+                       2 + sizeof(struct ieee80211_ht_cap) + /* HT */
+                       assoc_data->ie_len + /* extra IEs */
+                       9, /* WMM */
+                       GFP_KERNEL);
        if (!skb)
                return;
 
        skb_reserve(skb, local->hw.extra_tx_headroom);
 
+       capab = WLAN_CAPABILITY_ESS;
+
+       if (sband->band == IEEE80211_BAND_2GHZ) {
+               if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
+                       capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
+               if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
+                       capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+       }
+
+       if (assoc_data->capability & WLAN_CAPABILITY_PRIVACY)
+               capab |= WLAN_CAPABILITY_PRIVACY;
+
+       if ((assoc_data->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
+           (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
+               capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
+
        mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
        memset(mgmt, 0, 24);
+       memcpy(mgmt->da, assoc_data->bss->bssid, ETH_ALEN);
+       memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+       memcpy(mgmt->bssid, assoc_data->bss->bssid, ETH_ALEN);
+
+       if (!is_zero_ether_addr(assoc_data->prev_bssid)) {
+               skb_put(skb, 10);
+               mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+                                                 IEEE80211_STYPE_REASSOC_REQ);
+               mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
+               mgmt->u.reassoc_req.listen_interval =
+                               cpu_to_le16(local->hw.conf.listen_interval);
+               memcpy(mgmt->u.reassoc_req.current_ap, assoc_data->prev_bssid,
+                      ETH_ALEN);
+       } else {
+               skb_put(skb, 4);
+               mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+                                                 IEEE80211_STYPE_ASSOC_REQ);
+               mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
+               mgmt->u.assoc_req.listen_interval =
+                               cpu_to_le16(local->hw.conf.listen_interval);
+       }
+
+       /* SSID */
+       pos = skb_put(skb, 2 + assoc_data->ssid_len);
+       *pos++ = WLAN_EID_SSID;
+       *pos++ = assoc_data->ssid_len;
+       memcpy(pos, assoc_data->ssid, assoc_data->ssid_len);
+
+       /* add all rates which were marked to be used above */
+       supp_rates_len = rates_len;
+       if (supp_rates_len > 8)
+               supp_rates_len = 8;
+
+       pos = skb_put(skb, supp_rates_len + 2);
+       *pos++ = WLAN_EID_SUPP_RATES;
+       *pos++ = supp_rates_len;
+
+       count = 0;
+       for (i = 0; i < sband->n_bitrates; i++) {
+               if (BIT(i) & rates) {
+                       int rate = sband->bitrates[i].bitrate;
+                       *pos++ = (u8) (rate / 5);
+                       if (++count == 8)
+                               break;
+               }
+       }
+
+       if (rates_len > count) {
+               pos = skb_put(skb, rates_len - count + 2);
+               *pos++ = WLAN_EID_EXT_SUPP_RATES;
+               *pos++ = rates_len - count;
+
+               for (i++; i < sband->n_bitrates; i++) {
+                       if (BIT(i) & rates) {
+                               int rate = sband->bitrates[i].bitrate;
+                               *pos++ = (u8) (rate / 5);
+                       }
+               }
+       }
+
+       if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
+               /* 1. power capabilities */
+               pos = skb_put(skb, 4);
+               *pos++ = WLAN_EID_PWR_CAPABILITY;
+               *pos++ = 2;
+               *pos++ = 0; /* min tx power */
+               *pos++ = local->oper_channel->max_power; /* max tx power */
+
+               /* 2. supported channels */
+               /* TODO: get this in reg domain format */
+               pos = skb_put(skb, 2 * sband->n_channels + 2);
+               *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
+               *pos++ = 2 * sband->n_channels;
+               for (i = 0; i < sband->n_channels; i++) {
+                       *pos++ = ieee80211_frequency_to_channel(
+                                       sband->channels[i].center_freq);
+                       *pos++ = 1; /* one channel in the subband*/
+               }
+       }
+
+       /* if present, add any custom IEs that go before HT */
+       if (assoc_data->ie_len && assoc_data->ie) {
+               static const u8 before_ht[] = {
+                       WLAN_EID_SSID,
+                       WLAN_EID_SUPP_RATES,
+                       WLAN_EID_EXT_SUPP_RATES,
+                       WLAN_EID_PWR_CAPABILITY,
+                       WLAN_EID_SUPPORTED_CHANNELS,
+                       WLAN_EID_RSN,
+                       WLAN_EID_QOS_CAPA,
+                       WLAN_EID_RRM_ENABLED_CAPABILITIES,
+                       WLAN_EID_MOBILITY_DOMAIN,
+                       WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
+               };
+               noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len,
+                                            before_ht, ARRAY_SIZE(before_ht),
+                                            offset);
+               pos = skb_put(skb, noffset - offset);
+               memcpy(pos, assoc_data->ie + offset, noffset - offset);
+               offset = noffset;
+       }
+
+       if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N) &&
+           bss->wmm_used && local->hw.queues >= 4)
+               ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie,
+                                   sband, local->oper_channel, ifmgd->ap_smps);
+
+       /* if present, add any custom non-vendor IEs that go after HT */
+       if (assoc_data->ie_len && assoc_data->ie) {
+               noffset = ieee80211_ie_split_vendor(assoc_data->ie,
+                                                   assoc_data->ie_len,
+                                                   offset);
+               pos = skb_put(skb, noffset - offset);
+               memcpy(pos, assoc_data->ie + offset, noffset - offset);
+               offset = noffset;
+       }
+
+       if (assoc_data->wmm_used && local->hw.queues >= 4) {
+               if (assoc_data->uapsd_used) {
+                       qos_info = local->uapsd_queues;
+                       qos_info |= (local->uapsd_max_sp_len <<
+                                    IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
+               } else {
+                       qos_info = 0;
+               }
+
+               pos = skb_put(skb, 9);
+               *pos++ = WLAN_EID_VENDOR_SPECIFIC;
+               *pos++ = 7; /* len */
+               *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
+               *pos++ = 0x50;
+               *pos++ = 0xf2;
+               *pos++ = 2; /* WME */
+               *pos++ = 0; /* WME info */
+               *pos++ = 1; /* WME ver */
+               *pos++ = qos_info;
+       }
+
+       /* add any remaining custom (i.e. vendor specific here) IEs */
+       if (assoc_data->ie_len && assoc_data->ie) {
+               noffset = assoc_data->ie_len;
+               pos = skb_put(skb, noffset - offset);
+               memcpy(pos, assoc_data->ie + offset, noffset - offset);
+       }
+
+       IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+       ieee80211_tx_skb(sdata, skb);
+}
+
+static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
+                                          const u8 *bssid, u16 stype,
+                                          u16 reason, bool send_frame,
+                                          u8 *frame_buf)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       struct sk_buff *skb;
+       struct ieee80211_mgmt *mgmt = (void *)frame_buf;
+
+       /* build frame */
+       mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
+       mgmt->duration = 0; /* initialize only */
+       mgmt->seq_ctrl = 0; /* initialize only */
        memcpy(mgmt->da, bssid, ETH_ALEN);
        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
        memcpy(mgmt->bssid, bssid, ETH_ALEN);
-       mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
-       skb_put(skb, 2);
        /* u.deauth.reason_code == u.disassoc.reason_code */
        mgmt->u.deauth.reason_code = cpu_to_le16(reason);
 
-       if (stype == IEEE80211_STYPE_DEAUTH)
-               if (cookie)
-                       __cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
-               else
-                       cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
-       else
-               if (cookie)
-                       __cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
-               else
-                       cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
-       if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
-               IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+       if (send_frame) {
+               skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+                                   DEAUTH_DISASSOC_LEN);
+               if (!skb)
+                       return;
 
-       if (send_frame)
+               skb_reserve(skb, local->hw.extra_tx_headroom);
+
+               /* copy in frame */
+               memcpy(skb_put(skb, DEAUTH_DISASSOC_LEN),
+                      mgmt, DEAUTH_DISASSOC_LEN);
+
+               if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
+                       IEEE80211_SKB_CB(skb)->flags |=
+                               IEEE80211_TX_INTFL_DONT_ENCRYPT;
                ieee80211_tx_skb(sdata, skb);
-       else
-               kfree_skb(skb);
+       }
 }
 
 void ieee80211_send_pspoll(struct ieee80211_local *local,
@@ -547,7 +871,7 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
        if (pwr_constr_elem_len != 1)
                return;
 
-       if ((*pwr_constr_elem <= conf->channel->max_power) &&
+       if ((*pwr_constr_elem <= conf->channel->max_reg_power) &&
            (*pwr_constr_elem != sdata->local->power_constr_level)) {
                sdata->local->power_constr_level = *pwr_constr_elem;
                ieee80211_hw_config(sdata->local, 0);
@@ -953,7 +1277,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
 
        /* enable WMM or activate new settings */
        sdata->vif.bss_conf.qos = true;
-       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
 }
 
 static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
@@ -1043,7 +1366,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
        bss_info_changed |= BSS_CHANGED_BSSID;
 
        /* Tell the driver to monitor connection quality (if supported) */
-       if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) &&
+       if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI &&
            bss_conf->cqm_rssi_thold)
                bss_info_changed |= BSS_CHANGED_CQM;
 
@@ -1065,7 +1388,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
 }
 
 static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
-                                  bool remove_sta, bool tx)
+                                  u16 stype, u16 reason, bool tx,
+                                  u8 *frame_buf)
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_local *local = sdata->local;
@@ -1075,6 +1399,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 
        ASSERT_MGD_MTX(ifmgd);
 
+       if (WARN_ON_ONCE(tx && !frame_buf))
+               return;
+
        if (WARN_ON(!ifmgd->associated))
                return;
 
@@ -1108,14 +1435,25 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        }
        mutex_unlock(&local->sta_mtx);
 
+       /* deauthenticate/disassociate now */
+       if (tx || frame_buf)
+               ieee80211_send_deauth_disassoc(sdata, bssid, stype, reason,
+                                              tx, frame_buf);
+
+       /* flush out frame */
+       if (tx)
+               drv_flush(local, false);
+
+       /* remove AP and TDLS peers */
+       sta_info_flush(local, sdata);
+
+       /* finally reset all BSS / config parameters */
        changed |= ieee80211_reset_erp_info(sdata);
 
        ieee80211_led_assoc(local, 0);
        changed |= BSS_CHANGED_ASSOC;
        sdata->vif.bss_conf.assoc = false;
 
-       ieee80211_set_wmm_default(sdata);
-
        /* channel(_type) changes are handled by ieee80211_hw_config */
        WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
 
@@ -1143,13 +1481,15 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
                changed |= BSS_CHANGED_ARP_FILTER;
        }
 
+       sdata->vif.bss_conf.qos = false;
+       changed |= BSS_CHANGED_QOS;
+
        /* The BSSID (not really interesting) and HT changed */
        changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
        ieee80211_bss_info_change_notify(sdata, changed);
 
-       /* remove AP and TDLS peers */
-       if (remove_sta)
-               sta_info_flush(local, sdata);
+       /* disassociated - set to defaults now */
+       ieee80211_set_wmm_default(sdata, false);
 
        del_timer_sync(&sdata->u.mgd.conn_mon_timer);
        del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
@@ -1347,6 +1687,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_local *local = sdata->local;
        u8 bssid[ETH_ALEN];
+       u8 frame_buf[DEAUTH_DISASSOC_LEN];
 
        mutex_lock(&ifmgd->mtx);
        if (!ifmgd->associated) {
@@ -1359,17 +1700,16 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
        printk(KERN_DEBUG "%s: Connection to AP %pM lost.\n",
               sdata->name, bssid);
 
-       ieee80211_set_disassoc(sdata, true, true);
+       ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
+                              WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
+                              false, frame_buf);
        mutex_unlock(&ifmgd->mtx);
 
        /*
         * must be outside lock due to cfg80211,
         * but that's not a problem.
         */
-       ieee80211_send_deauth_disassoc(sdata, bssid,
-                                      IEEE80211_STYPE_DEAUTH,
-                                      WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
-                                      NULL, true);
+       cfg80211_send_deauth(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
 
        mutex_lock(&local->mtx);
        ieee80211_recalc_idle(local);
@@ -1423,6 +1763,135 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif)
 EXPORT_SYMBOL(ieee80211_connection_loss);
 
 
+static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
+                                       bool assoc)
+{
+       struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
+
+       lockdep_assert_held(&sdata->u.mgd.mtx);
+
+       if (auth_data->synced)
+               drv_finish_tx_sync(sdata->local, sdata,
+                                  auth_data->bss->bssid,
+                                  IEEE80211_TX_SYNC_AUTH);
+
+       if (!assoc) {
+               sta_info_destroy_addr(sdata, auth_data->bss->bssid);
+
+               memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
+               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
+       }
+
+       cfg80211_put_bss(auth_data->bss);
+       kfree(auth_data);
+       sdata->u.mgd.auth_data = NULL;
+}
+
+static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
+                                    struct ieee80211_mgmt *mgmt, size_t len)
+{
+       struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
+       u8 *pos;
+       struct ieee802_11_elems elems;
+
+       pos = mgmt->u.auth.variable;
+       ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
+       if (!elems.challenge)
+               return;
+       auth_data->expected_transaction = 4;
+       ieee80211_send_auth(sdata, 3, auth_data->algorithm,
+                           elems.challenge - 2, elems.challenge_len + 2,
+                           auth_data->bss->bssid, auth_data->bss->bssid,
+                           auth_data->key, auth_data->key_len,
+                           auth_data->key_idx);
+}
+
+static enum rx_mgmt_action __must_check
+ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
+                      struct ieee80211_mgmt *mgmt, size_t len)
+{
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       u8 bssid[ETH_ALEN];
+       u16 auth_alg, auth_transaction, status_code;
+       struct sta_info *sta;
+
+       lockdep_assert_held(&ifmgd->mtx);
+
+       if (len < 24 + 6)
+               return RX_MGMT_NONE;
+
+       if (!ifmgd->auth_data || ifmgd->auth_data->done)
+               return RX_MGMT_NONE;
+
+       memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
+
+       if (compare_ether_addr(bssid, mgmt->bssid))
+               return RX_MGMT_NONE;
+
+       auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
+       auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
+       status_code = le16_to_cpu(mgmt->u.auth.status_code);
+
+       if (auth_alg != ifmgd->auth_data->algorithm ||
+           auth_transaction != ifmgd->auth_data->expected_transaction)
+               return RX_MGMT_NONE;
+
+       if (status_code != WLAN_STATUS_SUCCESS) {
+               printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
+                      sdata->name, mgmt->sa, status_code);
+               goto out;
+       }
+
+       switch (ifmgd->auth_data->algorithm) {
+       case WLAN_AUTH_OPEN:
+       case WLAN_AUTH_LEAP:
+       case WLAN_AUTH_FT:
+               break;
+       case WLAN_AUTH_SHARED_KEY:
+               if (ifmgd->auth_data->expected_transaction != 4) {
+                       ieee80211_auth_challenge(sdata, mgmt, len);
+                       /* need another frame */
+                       return RX_MGMT_NONE;
+               }
+               break;
+       default:
+               WARN_ONCE(1, "invalid auth alg %d",
+                         ifmgd->auth_data->algorithm);
+               return RX_MGMT_NONE;
+       }
+
+       printk(KERN_DEBUG "%s: authenticated\n", sdata->name);
+ out:
+       if (ifmgd->auth_data->synced)
+               drv_finish_tx_sync(sdata->local, sdata, bssid,
+                                  IEEE80211_TX_SYNC_AUTH);
+       ifmgd->auth_data->synced = false;
+       ifmgd->auth_data->done = true;
+       ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
+       run_again(ifmgd, ifmgd->auth_data->timeout);
+
+       /* move station state to auth */
+       mutex_lock(&sdata->local->sta_mtx);
+       sta = sta_info_get(sdata, bssid);
+       if (!sta) {
+               WARN_ONCE(1, "%s: STA %pM not found", sdata->name, bssid);
+               goto out_err;
+       }
+       if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
+               printk(KERN_DEBUG "%s: failed moving %pM to auth\n",
+                      sdata->name, bssid);
+               goto out_err;
+       }
+       mutex_unlock(&sdata->local->sta_mtx);
+
+       return RX_MGMT_CFG80211_RX_AUTH;
+ out_err:
+       mutex_unlock(&sdata->local->sta_mtx);
+       /* ignore frame -- wait for timeout */
+       return RX_MGMT_NONE;
+}
+
+
 static enum rx_mgmt_action __must_check
 ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
                         struct ieee80211_mgmt *mgmt, size_t len)
@@ -1431,10 +1900,14 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
        const u8 *bssid = NULL;
        u16 reason_code;
 
+       lockdep_assert_held(&ifmgd->mtx);
+
        if (len < 24 + 2)
                return RX_MGMT_NONE;
 
-       ASSERT_MGD_MTX(ifmgd);
+       if (!ifmgd->associated ||
+           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
+               return RX_MGMT_NONE;
 
        bssid = ifmgd->associated->bssid;
 
@@ -1443,7 +1916,8 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
        printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
                        sdata->name, bssid, reason_code);
 
-       ieee80211_set_disassoc(sdata, true, false);
+       ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
+
        mutex_lock(&sdata->local->mtx);
        ieee80211_recalc_idle(sdata->local);
        mutex_unlock(&sdata->local->mtx);
@@ -1459,15 +1933,13 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        u16 reason_code;
 
-       if (len < 24 + 2)
-               return RX_MGMT_NONE;
-
-       ASSERT_MGD_MTX(ifmgd);
+       lockdep_assert_held(&ifmgd->mtx);
 
-       if (WARN_ON(!ifmgd->associated))
+       if (len < 24 + 2)
                return RX_MGMT_NONE;
 
-       if (WARN_ON(memcmp(ifmgd->associated->bssid, mgmt->sa, ETH_ALEN)))
+       if (!ifmgd->associated ||
+           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
                return RX_MGMT_NONE;
 
        reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
@@ -1475,10 +1947,12 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
        printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
                        sdata->name, mgmt->sa, reason_code);
 
-       ieee80211_set_disassoc(sdata, true, false);
+       ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
+
        mutex_lock(&sdata->local->mtx);
        ieee80211_recalc_idle(sdata->local);
        mutex_unlock(&sdata->local->mtx);
+
        return RX_MGMT_CFG80211_DISASSOC;
 }
 
@@ -1524,15 +1998,37 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
        }
 }
 
-static bool ieee80211_assoc_success(struct ieee80211_work *wk,
+static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
+                                        bool assoc)
+{
+       struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
+
+       lockdep_assert_held(&sdata->u.mgd.mtx);
+
+       if (assoc_data->synced)
+               drv_finish_tx_sync(sdata->local, sdata,
+                                  assoc_data->bss->bssid,
+                                  IEEE80211_TX_SYNC_ASSOC);
+
+       if (!assoc) {
+               sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
+
+               memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
+               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
+       }
+
+       kfree(assoc_data);
+       sdata->u.mgd.assoc_data = NULL;
+}
+
+static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
+                                   struct cfg80211_bss *cbss,
                                    struct ieee80211_mgmt *mgmt, size_t len)
 {
-       struct ieee80211_sub_if_data *sdata = wk->sdata;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_supported_band *sband;
        struct sta_info *sta;
-       struct cfg80211_bss *cbss = wk->assoc.bss;
        u8 *pos;
        u32 rates, basic_rates;
        u16 capab_info, aid;
@@ -1581,20 +2077,15 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
         * station info was already allocated and inserted before
         * the association and should be available to us
         */
-       sta = sta_info_get_rx(sdata, cbss->bssid);
+       sta = sta_info_get(sdata, cbss->bssid);
        if (WARN_ON(!sta)) {
                mutex_unlock(&sdata->local->sta_mtx);
                return false;
        }
 
-       sta_info_move_state(sta, IEEE80211_STA_AUTH);
-       sta_info_move_state(sta, IEEE80211_STA_ASSOC);
-       if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
-               sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
-
        rates = 0;
        basic_rates = 0;
-       sband = local->hw.wiphy->bands[wk->chan->band];
+       sband = local->hw.wiphy->bands[local->oper_channel->band];
 
        ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len,
                            &rates, &basic_rates, &have_higher_than_11mbit,
@@ -1615,11 +2106,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
                basic_rates = BIT(min_rate_index);
        }
 
-       sta->sta.supp_rates[wk->chan->band] = rates;
+       sta->sta.supp_rates[local->oper_channel->band] = rates;
        sdata->vif.bss_conf.basic_rates = basic_rates;
 
        /* cf. IEEE 802.11 9.2.12 */
-       if (wk->chan->band == IEEE80211_BAND_2GHZ &&
+       if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
            have_higher_than_11mbit)
                sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
        else
@@ -1639,15 +2130,22 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
        if (elems.wmm_param)
                set_sta_flag(sta, WLAN_STA_WME);
 
-       /* sta_info_reinsert will also unlock the mutex lock */
-       err = sta_info_reinsert(sta);
-       sta = NULL;
+       err = sta_info_move_state(sta, IEEE80211_STA_AUTH);
+       if (!err)
+               err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
+       if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
+               err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
        if (err) {
-               printk(KERN_DEBUG "%s: failed to insert STA entry for"
-                      " the AP (error %d)\n", sdata->name, err);
+               printk(KERN_DEBUG
+                      "%s: failed to move station %pM to desired state\n",
+                      sdata->name, sta->sta.addr);
+               WARN_ON(__sta_info_destroy(sta));
+               mutex_unlock(&sdata->local->sta_mtx);
                return false;
        }
 
+       mutex_unlock(&sdata->local->sta_mtx);
+
        /*
         * Always handle WMM once after association regardless
         * of the first value the AP uses. Setting -1 here has
@@ -1660,9 +2158,8 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
                ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
                                         elems.wmm_param_len);
        else
-               ieee80211_set_wmm_default(sdata);
-
-       local->oper_channel = wk->chan;
+               ieee80211_set_wmm_default(sdata, false);
+       changed |= BSS_CHANGED_QOS;
 
        if (elems.ht_info_elem && elems.wmm_param &&
            (sdata->local->hw.queues >= 4) &&
@@ -1694,7 +2191,96 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
        return true;
 }
 
+static enum rx_mgmt_action __must_check
+ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+                            struct ieee80211_mgmt *mgmt, size_t len,
+                            struct cfg80211_bss **bss)
+{
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
+       u16 capab_info, status_code, aid;
+       struct ieee802_11_elems elems;
+       u8 *pos;
+       bool reassoc;
+
+       lockdep_assert_held(&ifmgd->mtx);
+
+       if (!assoc_data)
+               return RX_MGMT_NONE;
+       if (compare_ether_addr(assoc_data->bss->bssid, mgmt->bssid))
+               return RX_MGMT_NONE;
+
+       /*
+        * AssocResp and ReassocResp have identical structure, so process both
+        * of them in this function.
+        */
+
+       if (len < 24 + 6)
+               return RX_MGMT_NONE;
+
+       reassoc = ieee80211_is_reassoc_req(mgmt->frame_control);
+       capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
+       status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
+       aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
+
+       printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
+              "status=%d aid=%d)\n",
+              sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
+              capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
+
+       pos = mgmt->u.assoc_resp.variable;
+       ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
+
+       if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
+           elems.timeout_int && elems.timeout_int_len == 5 &&
+           elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
+               u32 tu, ms;
+               tu = get_unaligned_le32(elems.timeout_int + 1);
+               ms = tu * 1024 / 1000;
+               printk(KERN_DEBUG "%s: %pM rejected association temporarily; "
+                      "comeback duration %u TU (%u ms)\n",
+                      sdata->name, mgmt->sa, tu, ms);
+               assoc_data->timeout = jiffies + msecs_to_jiffies(ms);
+               if (ms > IEEE80211_ASSOC_TIMEOUT)
+                       run_again(ifmgd, assoc_data->timeout);
+               return RX_MGMT_NONE;
+       }
+
+       *bss = assoc_data->bss;
+
+       if (status_code != WLAN_STATUS_SUCCESS) {
+               printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n",
+                      sdata->name, mgmt->sa, status_code);
+               ieee80211_destroy_assoc_data(sdata, false);
+       } else {
+               printk(KERN_DEBUG "%s: associated\n", sdata->name);
+
+               /* tell driver about sync done first */
+               if (assoc_data->synced) {
+                       drv_finish_tx_sync(sdata->local, sdata,
+                                          assoc_data->bss->bssid,
+                                          IEEE80211_TX_SYNC_ASSOC);
+                       assoc_data->synced = false;
+               }
 
+               if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
+                       /* oops -- internal error -- send timeout for now */
+                       ieee80211_destroy_assoc_data(sdata, true);
+                       sta_info_destroy_addr(sdata, mgmt->bssid);
+                       cfg80211_put_bss(*bss);
+                       return RX_MGMT_CFG80211_ASSOC_TIMEOUT;
+               }
+
+               /*
+                * destroy assoc_data afterwards, as otherwise an idle
+                * recalc after assoc_data is NULL but before associated
+                * is set can cause the interface to go idle
+                */
+               ieee80211_destroy_assoc_data(sdata, true);
+       }
+
+       return RX_MGMT_CFG80211_RX_ASSOC;
+}
 static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                                  struct ieee80211_mgmt *mgmt,
                                  size_t len,
@@ -1708,7 +2294,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_channel *channel;
        bool need_ps = false;
 
-       if (sdata->u.mgd.associated) {
+       if (sdata->u.mgd.associated &&
+           compare_ether_addr(mgmt->bssid, sdata->u.mgd.associated->bssid)
+           == 0) {
                bss = (void *)sdata->u.mgd.associated->priv;
                /* not previously set so we may need to recalc */
                need_ps = !bss->dtim_period;
@@ -1763,7 +2351,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
 
        ASSERT_MGD_MTX(ifmgd);
 
-       if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
+       if (compare_ether_addr(mgmt->da, sdata->vif.addr))
                return; /* ignore ProbeResp to foreign address */
 
        baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
@@ -1776,8 +2364,18 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
        ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
 
        if (ifmgd->associated &&
-           memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0)
+           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid) == 0)
                ieee80211_reset_ap_probe(sdata);
+
+       if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies &&
+           compare_ether_addr(mgmt->bssid, ifmgd->auth_data->bss->bssid)
+           == 0) {
+               /* got probe response, continue with auth */
+               printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
+               ifmgd->auth_data->tries = 0;
+               ifmgd->auth_data->timeout = jiffies;
+               run_again(ifmgd, ifmgd->auth_data->timeout);
+       }
 }
 
 /*
@@ -1817,7 +2415,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
        u32 ncrc;
        u8 *bssid;
 
-       ASSERT_MGD_MTX(ifmgd);
+       lockdep_assert_held(&ifmgd->mtx);
 
        /* Process beacon from the current BSS */
        baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
@@ -1827,21 +2425,26 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
        if (rx_status->freq != local->hw.conf.channel->center_freq)
                return;
 
-       /*
-        * We might have received a number of frames, among them a
-        * disassoc frame and a beacon...
-        */
-       if (!ifmgd->associated)
-               return;
+       if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
+           compare_ether_addr(mgmt->bssid, ifmgd->assoc_data->bss->bssid)
+           == 0) {
+               ieee802_11_parse_elems(mgmt->u.beacon.variable,
+                                      len - baselen, &elems);
 
-       bssid = ifmgd->associated->bssid;
+               ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
+                                     false);
+               ifmgd->assoc_data->have_beacon = true;
+               ifmgd->assoc_data->sent_assoc = false;
+               /* continue assoc process */
+               ifmgd->assoc_data->timeout = jiffies;
+               run_again(ifmgd, ifmgd->assoc_data->timeout);
+               return;
+       }
 
-       /*
-        * And in theory even frames from a different AP we were just
-        * associated to a split-second ago!
-        */
-       if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
+       if (!ifmgd->associated ||
+           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
                return;
+       bssid = ifmgd->associated->bssid;
 
        /* Track average RSSI from the Beacon frames of the current AP */
        ifmgd->last_beacon_signal = rx_status->signal;
@@ -1882,7 +2485,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 
        if (bss_conf->cqm_rssi_thold &&
            ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
-           !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
+           !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) {
                int sig = ifmgd->ave_beacon_signal / 16;
                int last_event = ifmgd->last_cqm_event_signal;
                int thold = bss_conf->cqm_rssi_thold;
@@ -2025,6 +2628,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_rx_status *rx_status;
        struct ieee80211_mgmt *mgmt;
+       struct cfg80211_bss *bss = NULL;
        enum rx_mgmt_action rma = RX_MGMT_NONE;
        u16 fc;
 
@@ -2034,92 +2638,59 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 
        mutex_lock(&ifmgd->mtx);
 
-       if (ifmgd->associated &&
-           memcmp(ifmgd->associated->bssid, mgmt->bssid, ETH_ALEN) == 0) {
-               switch (fc & IEEE80211_FCTL_STYPE) {
-               case IEEE80211_STYPE_BEACON:
-                       ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
-                                                rx_status);
-                       break;
-               case IEEE80211_STYPE_PROBE_RESP:
-                       ieee80211_rx_mgmt_probe_resp(sdata, skb);
-                       break;
-               case IEEE80211_STYPE_DEAUTH:
-                       rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
-                       break;
-               case IEEE80211_STYPE_DISASSOC:
-                       rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
-                       break;
-               case IEEE80211_STYPE_ACTION:
-                       switch (mgmt->u.action.category) {
-                       case WLAN_CATEGORY_SPECTRUM_MGMT:
-                               ieee80211_sta_process_chanswitch(sdata,
-                                               &mgmt->u.action.u.chan_switch.sw_elem,
-                                               (void *)ifmgd->associated->priv,
-                                               rx_status->mactime);
-                               break;
-                       }
-               }
-               mutex_unlock(&ifmgd->mtx);
-
-               switch (rma) {
-               case RX_MGMT_NONE:
-                       /* no action */
-                       break;
-               case RX_MGMT_CFG80211_DEAUTH:
-                       cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
-                       break;
-               case RX_MGMT_CFG80211_DISASSOC:
-                       cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
+       switch (fc & IEEE80211_FCTL_STYPE) {
+       case IEEE80211_STYPE_BEACON:
+               ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
+               break;
+       case IEEE80211_STYPE_PROBE_RESP:
+               ieee80211_rx_mgmt_probe_resp(sdata, skb);
+               break;
+       case IEEE80211_STYPE_AUTH:
+               rma = ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len);
+               break;
+       case IEEE80211_STYPE_DEAUTH:
+               rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
+               break;
+       case IEEE80211_STYPE_DISASSOC:
+               rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
+               break;
+       case IEEE80211_STYPE_ASSOC_RESP:
+       case IEEE80211_STYPE_REASSOC_RESP:
+               rma = ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, &bss);
+               break;
+       case IEEE80211_STYPE_ACTION:
+               switch (mgmt->u.action.category) {
+               case WLAN_CATEGORY_SPECTRUM_MGMT:
+                       ieee80211_sta_process_chanswitch(sdata,
+                                       &mgmt->u.action.u.chan_switch.sw_elem,
+                                       (void *)ifmgd->associated->priv,
+                                       rx_status->mactime);
                        break;
-               default:
-                       WARN(1, "unexpected: %d", rma);
                }
-               return;
        }
-
        mutex_unlock(&ifmgd->mtx);
 
-       if (skb->len >= 24 + 2 /* mgmt + deauth reason */ &&
-           (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) {
-               struct ieee80211_local *local = sdata->local;
-               struct ieee80211_work *wk;
-
-               mutex_lock(&local->mtx);
-               list_for_each_entry(wk, &local->work_list, list) {
-                       if (wk->sdata != sdata)
-                               continue;
-
-                       if (wk->type != IEEE80211_WORK_ASSOC &&
-                           wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
-                               continue;
-
-                       if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN))
-                               continue;
-                       if (memcmp(mgmt->sa, wk->filter_ta, ETH_ALEN))
-                               continue;
-
-                       /*
-                        * Printing the message only here means we can't
-                        * spuriously print it, but it also means that it
-                        * won't be printed when the frame comes in before
-                        * we even tried to associate or in similar cases.
-                        *
-                        * Ultimately, I suspect cfg80211 should print the
-                        * messages instead.
-                        */
-                       printk(KERN_DEBUG
-                              "%s: deauthenticated from %pM (Reason: %u)\n",
-                              sdata->name, mgmt->bssid,
-                              le16_to_cpu(mgmt->u.deauth.reason_code));
-
-                       list_del_rcu(&wk->list);
-                       free_work(wk);
-                       break;
-               }
-               mutex_unlock(&local->mtx);
-
+       switch (rma) {
+       case RX_MGMT_NONE:
+               /* no action */
+               break;
+       case RX_MGMT_CFG80211_DEAUTH:
                cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
+               break;
+       case RX_MGMT_CFG80211_DISASSOC:
+               cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
+               break;
+       case RX_MGMT_CFG80211_RX_AUTH:
+               cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, skb->len);
+               break;
+       case RX_MGMT_CFG80211_RX_ASSOC:
+               cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, skb->len);
+               break;
+       case RX_MGMT_CFG80211_ASSOC_TIMEOUT:
+               cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
+               break;
+       default:
+               WARN(1, "unexpected: %d", rma);
        }
 }
 
@@ -2143,19 +2714,20 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       u8 frame_buf[DEAUTH_DISASSOC_LEN];
 
        ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
                          IEEE80211_STA_BEACON_POLL);
 
-       ieee80211_set_disassoc(sdata, true, true);
+       ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
+                              false, frame_buf);
        mutex_unlock(&ifmgd->mtx);
+
        /*
         * must be outside lock due to cfg80211,
         * but that's not a problem.
         */
-       ieee80211_send_deauth_disassoc(sdata, bssid,
-                       IEEE80211_STYPE_DEAUTH, reason,
-                       NULL, true);
+       cfg80211_send_deauth(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
 
        mutex_lock(&local->mtx);
        ieee80211_recalc_idle(local);
@@ -2164,14 +2736,160 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
        mutex_lock(&ifmgd->mtx);
 }
 
+static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data;
+
+       lockdep_assert_held(&ifmgd->mtx);
+
+       if (WARN_ON_ONCE(!auth_data))
+               return -EINVAL;
+
+       if (!auth_data->synced) {
+               int ret = drv_tx_sync(local, sdata, auth_data->bss->bssid,
+                                     IEEE80211_TX_SYNC_AUTH);
+               if (ret)
+                       return ret;
+       }
+       auth_data->synced = true;
+
+       auth_data->tries++;
+
+       if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
+               printk(KERN_DEBUG "%s: authentication with %pM timed out\n",
+                      sdata->name, auth_data->bss->bssid);
+
+               /*
+                * Most likely AP is not in the range so remove the
+                * bss struct for that AP.
+                */
+               cfg80211_unlink_bss(local->hw.wiphy, auth_data->bss);
+
+               return -ETIMEDOUT;
+       }
+
+       if (auth_data->bss->proberesp_ies) {
+               printk(KERN_DEBUG "%s: send auth to %pM (try %d/%d)\n",
+                      sdata->name, auth_data->bss->bssid, auth_data->tries,
+                      IEEE80211_AUTH_MAX_TRIES);
+
+               auth_data->expected_transaction = 2;
+               ieee80211_send_auth(sdata, 1, auth_data->algorithm,
+                                   auth_data->ie, auth_data->ie_len,
+                                   auth_data->bss->bssid,
+                                   auth_data->bss->bssid, NULL, 0, 0);
+       } else {
+               const u8 *ssidie;
+
+               printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
+                      sdata->name, auth_data->bss->bssid, auth_data->tries,
+                      IEEE80211_AUTH_MAX_TRIES);
+
+               ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID);
+               if (!ssidie)
+                       return -EINVAL;
+               /*
+                * Direct probe is sent to broadcast address as some APs
+                * will not answer to direct packet in unassociated state.
+                */
+               ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
+                                        NULL, 0, (u32) -1, true, false);
+       }
+
+       auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
+       run_again(ifmgd, auth_data->timeout);
+
+       return 0;
+}
+
+static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
+       struct ieee80211_local *local = sdata->local;
+
+       lockdep_assert_held(&sdata->u.mgd.mtx);
+
+       if (!assoc_data->synced) {
+               int ret = drv_tx_sync(local, sdata, assoc_data->bss->bssid,
+                                     IEEE80211_TX_SYNC_ASSOC);
+               if (ret)
+                       return ret;
+       }
+       assoc_data->synced = true;
+
+       assoc_data->tries++;
+       if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
+               printk(KERN_DEBUG "%s: association with %pM timed out\n",
+                      sdata->name, assoc_data->bss->bssid);
+
+               /*
+                * Most likely AP is not in the range so remove the
+                * bss struct for that AP.
+                */
+               cfg80211_unlink_bss(local->hw.wiphy, assoc_data->bss);
+
+               return -ETIMEDOUT;
+       }
+
+       printk(KERN_DEBUG "%s: associate with %pM (try %d/%d)\n",
+              sdata->name, assoc_data->bss->bssid, assoc_data->tries,
+              IEEE80211_ASSOC_MAX_TRIES);
+       ieee80211_send_assoc(sdata);
+
+       assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
+       run_again(&sdata->u.mgd, assoc_data->timeout);
+
+       return 0;
+}
+
 void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
-       /* then process the rest of the work */
        mutex_lock(&ifmgd->mtx);
 
+       if (ifmgd->auth_data &&
+           time_after(jiffies, ifmgd->auth_data->timeout)) {
+               if (ifmgd->auth_data->done) {
+                       /*
+                        * ok ... we waited for assoc but userspace didn't,
+                        * so let's just kill the auth data
+                        */
+                       ieee80211_destroy_auth_data(sdata, false);
+               } else if (ieee80211_probe_auth(sdata)) {
+                       u8 bssid[ETH_ALEN];
+
+                       memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
+
+                       ieee80211_destroy_auth_data(sdata, false);
+
+                       mutex_unlock(&ifmgd->mtx);
+                       cfg80211_send_auth_timeout(sdata->dev, bssid);
+                       mutex_lock(&ifmgd->mtx);
+               }
+       } else if (ifmgd->auth_data)
+               run_again(ifmgd, ifmgd->auth_data->timeout);
+
+       if (ifmgd->assoc_data &&
+           time_after(jiffies, ifmgd->assoc_data->timeout)) {
+               if (!ifmgd->assoc_data->have_beacon ||
+                   ieee80211_do_assoc(sdata)) {
+                       u8 bssid[ETH_ALEN];
+
+                       memcpy(bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN);
+
+                       ieee80211_destroy_assoc_data(sdata, false);
+
+                       mutex_unlock(&ifmgd->mtx);
+                       cfg80211_send_assoc_timeout(sdata->dev, bssid);
+                       mutex_lock(&ifmgd->mtx);
+               }
+       } else if (ifmgd->assoc_data)
+               run_again(ifmgd, ifmgd->assoc_data->timeout);
+
        if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
                            IEEE80211_STA_CONNECTION_POLL) &&
            ifmgd->associated) {
@@ -2247,6 +2965,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
        }
 
        mutex_unlock(&ifmgd->mtx);
+
+       mutex_lock(&local->mtx);
+       ieee80211_recalc_idle(local);
+       mutex_unlock(&local->mtx);
 }
 
 static void ieee80211_sta_bcn_mon_timer(unsigned long data)
@@ -2286,13 +3008,17 @@ static void ieee80211_sta_monitor_work(struct work_struct *work)
 
 static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
 {
+       u32 flags;
+
        if (sdata->vif.type == NL80211_IFTYPE_STATION) {
                sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL |
                                        IEEE80211_STA_CONNECTION_POLL);
 
                /* let's probe the connection once */
-               ieee80211_queue_work(&sdata->local->hw,
-                          &sdata->u.mgd.monitor_work);
+               flags = sdata->local->hw.flags;
+               if (!(flags & IEEE80211_HW_CONNECTION_MONITOR))
+                       ieee80211_queue_work(&sdata->local->hw,
+                                            &sdata->u.mgd.monitor_work);
                /* and do all the other regular work too */
                ieee80211_queue_work(&sdata->local->hw, &sdata->work);
        }
@@ -2356,7 +3082,6 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
                add_timer(&ifmgd->chswitch_timer);
        ieee80211_sta_reset_beacon_monitor(sdata);
        ieee80211_restart_sta_timer(sdata);
-       ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.monitor_work);
 }
 #endif
 
@@ -2419,53 +3144,24 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
 }
 
 /* config hooks */
-static enum work_done_result
-ieee80211_probe_auth_done(struct ieee80211_work *wk,
-                         struct sk_buff *skb)
-{
-       struct ieee80211_local *local = wk->sdata->local;
-
-       if (!skb) {
-               cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
-               goto destroy;
-       }
-
-       if (wk->type == IEEE80211_WORK_AUTH) {
-               cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len);
-               goto destroy;
-       }
-
-       mutex_lock(&wk->sdata->u.mgd.mtx);
-       ieee80211_rx_mgmt_probe_resp(wk->sdata, skb);
-       mutex_unlock(&wk->sdata->u.mgd.mtx);
-
-       wk->type = IEEE80211_WORK_AUTH;
-       wk->probe_auth.tries = 0;
-       return WORK_DONE_REQUEUE;
- destroy:
-       if (wk->probe_auth.synced)
-               drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
-                                  IEEE80211_TX_SYNC_AUTH);
-
-       return WORK_DONE_DESTROY;
-}
-
 int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
                       struct cfg80211_auth_request *req)
 {
-       const u8 *ssid;
-       struct ieee80211_work *wk;
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       struct ieee80211_mgd_auth_data *auth_data;
+       struct sta_info *sta;
        u16 auth_alg;
+       int err;
 
-       if (req->local_state_change)
-               return 0; /* no need to update mac80211 state */
+       /* prepare auth data structure */
 
        switch (req->auth_type) {
        case NL80211_AUTHTYPE_OPEN_SYSTEM:
                auth_alg = WLAN_AUTH_OPEN;
                break;
        case NL80211_AUTHTYPE_SHARED_KEY:
-               if (IS_ERR(sdata->local->wep_tx_tfm))
+               if (IS_ERR(local->wep_tx_tfm))
                        return -EOPNOTSUPP;
                auth_alg = WLAN_AUTH_SHARED_KEY;
                break;
@@ -2479,171 +3175,142 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
                return -EOPNOTSUPP;
        }
 
-       wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL);
-       if (!wk)
+       auth_data = kzalloc(sizeof(*auth_data) + req->ie_len, GFP_KERNEL);
+       if (!auth_data)
                return -ENOMEM;
 
-       memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);
+       auth_data->bss = req->bss;
 
        if (req->ie && req->ie_len) {
-               memcpy(wk->ie, req->ie, req->ie_len);
-               wk->ie_len = req->ie_len;
+               memcpy(auth_data->ie, req->ie, req->ie_len);
+               auth_data->ie_len = req->ie_len;
        }
 
        if (req->key && req->key_len) {
-               wk->probe_auth.key_len = req->key_len;
-               wk->probe_auth.key_idx = req->key_idx;
-               memcpy(wk->probe_auth.key, req->key, req->key_len);
+               auth_data->key_len = req->key_len;
+               auth_data->key_idx = req->key_idx;
+               memcpy(auth_data->key, req->key, req->key_len);
        }
 
-       ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
-       memcpy(wk->probe_auth.ssid, ssid + 2, ssid[1]);
-       wk->probe_auth.ssid_len = ssid[1];
-
-       wk->probe_auth.algorithm = auth_alg;
-       wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY;
-
-       /* if we already have a probe, don't probe again */
-       if (req->bss->proberesp_ies)
-               wk->type = IEEE80211_WORK_AUTH;
-       else
-               wk->type = IEEE80211_WORK_DIRECT_PROBE;
-       wk->chan = req->bss->channel;
-       wk->chan_type = NL80211_CHAN_NO_HT;
-       wk->sdata = sdata;
-       wk->done = ieee80211_probe_auth_done;
-
-       ieee80211_add_work(wk);
-       return 0;
-}
-
-/* create and insert a dummy station entry */
-static int ieee80211_pre_assoc(struct ieee80211_sub_if_data *sdata,
-                               u8 *bssid) {
-       struct sta_info *sta;
-       int err;
+       auth_data->algorithm = auth_alg;
 
-       sta = sta_info_alloc(sdata, bssid, GFP_KERNEL);
-       if (!sta)
-               return -ENOMEM;
+       /* try to authenticate/probe */
 
-       sta->dummy = true;
+       mutex_lock(&ifmgd->mtx);
 
-       err = sta_info_insert(sta);
-       sta = NULL;
-       if (err) {
-               printk(KERN_DEBUG "%s: failed to insert Dummy STA entry for"
-                      " the AP (error %d)\n", sdata->name, err);
-               return err;
+       if ((ifmgd->auth_data && !ifmgd->auth_data->done) ||
+           ifmgd->assoc_data) {
+               err = -EBUSY;
+               goto err_free;
        }
 
-       return 0;
-}
+       if (ifmgd->auth_data)
+               ieee80211_destroy_auth_data(sdata, false);
 
-static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
-                                                 struct sk_buff *skb)
-{
-       struct ieee80211_local *local = wk->sdata->local;
-       struct ieee80211_mgmt *mgmt;
-       struct ieee80211_rx_status *rx_status;
-       struct ieee802_11_elems elems;
-       struct cfg80211_bss *cbss = wk->assoc.bss;
-       u16 status;
+       /* prep auth_data so we don't go into idle on disassoc */
+       ifmgd->auth_data = auth_data;
 
-       if (!skb) {
-               sta_info_destroy_addr(wk->sdata, cbss->bssid);
-               cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
-               goto destroy;
-       }
+       if (ifmgd->associated)
+               ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
 
-       if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) {
-               mutex_lock(&wk->sdata->u.mgd.mtx);
-               rx_status = (void *) skb->cb;
-               ieee802_11_parse_elems(skb->data + 24 + 12, skb->len - 24 - 12, &elems);
-               ieee80211_rx_bss_info(wk->sdata, (void *)skb->data, skb->len, rx_status,
-                                     &elems, true);
-               mutex_unlock(&wk->sdata->u.mgd.mtx);
+       printk(KERN_DEBUG "%s: authenticate with %pM\n",
+              sdata->name, req->bss->bssid);
 
-               wk->type = IEEE80211_WORK_ASSOC;
-               /* not really done yet */
-               return WORK_DONE_REQUEUE;
-       }
+       mutex_lock(&local->mtx);
+       ieee80211_recalc_idle(sdata->local);
+       mutex_unlock(&local->mtx);
 
-       mgmt = (void *)skb->data;
-       status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
+       /* switch to the right channel */
+       local->oper_channel = req->bss->channel;
+       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
-       if (status == WLAN_STATUS_SUCCESS) {
-               if (wk->assoc.synced)
-                       drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
-                                          IEEE80211_TX_SYNC_ASSOC);
+       /* set BSSID */
+       memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
 
-               mutex_lock(&wk->sdata->u.mgd.mtx);
-               if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
-                       mutex_unlock(&wk->sdata->u.mgd.mtx);
-                       /* oops -- internal error -- send timeout for now */
-                       sta_info_destroy_addr(wk->sdata, cbss->bssid);
-                       cfg80211_send_assoc_timeout(wk->sdata->dev,
-                                                   wk->filter_ta);
-                       return WORK_DONE_DESTROY;
-               }
+       /* add station entry */
+       sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
+       if (!sta) {
+               err = -ENOMEM;
+               goto err_clear;
+       }
 
-               mutex_unlock(&wk->sdata->u.mgd.mtx);
-       } else {
-               /* assoc failed - destroy the dummy station entry */
-               sta_info_destroy_addr(wk->sdata, cbss->bssid);
+       err = sta_info_insert(sta);
+       if (err) {
+               printk(KERN_DEBUG
+                      "%s: failed to insert STA entry for the AP %pM (error %d)\n",
+                      sdata->name, req->bss->bssid, err);
+               goto err_clear;
        }
 
-       cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
- destroy:
-       if (wk->assoc.synced)
-               drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
-                                  IEEE80211_TX_SYNC_ASSOC);
+       err = ieee80211_probe_auth(sdata);
+       if (err) {
+               if (auth_data->synced)
+                       drv_finish_tx_sync(local, sdata, req->bss->bssid,
+                                          IEEE80211_TX_SYNC_AUTH);
+               sta_info_destroy_addr(sdata, req->bss->bssid);
+               goto err_clear;
+       }
+
+       /* hold our own reference */
+       cfg80211_ref_bss(auth_data->bss);
+       err = 0;
+       goto out_unlock;
+
+ err_clear:
+       ifmgd->auth_data = NULL;
+ err_free:
+       kfree(auth_data);
+ out_unlock:
+       mutex_unlock(&ifmgd->mtx);
 
-       return WORK_DONE_DESTROY;
+       return err;
 }
 
 int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
                        struct cfg80211_assoc_request *req)
 {
+       struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_bss *bss = (void *)req->bss->priv;
-       struct ieee80211_work *wk;
-       const u8 *ssid;
+       struct ieee80211_mgd_assoc_data *assoc_data;
+       struct sta_info *sta;
+       const u8 *ssidie;
        int i, err;
 
+       ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
+       if (!ssidie)
+               return -EINVAL;
+
+       assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL);
+       if (!assoc_data)
+               return -ENOMEM;
+
        mutex_lock(&ifmgd->mtx);
-       if (ifmgd->associated) {
-               if (!req->prev_bssid ||
-                   memcmp(req->prev_bssid, ifmgd->associated->bssid,
-                          ETH_ALEN)) {
-                       /*
-                        * We are already associated and the request was not a
-                        * reassociation request from the current BSS, so
-                        * reject it.
-                        */
-                       mutex_unlock(&ifmgd->mtx);
-                       return -EALREADY;
-               }
 
-               /* Trying to reassociate - clear previous association state */
-               ieee80211_set_disassoc(sdata, true, false);
+       if (ifmgd->associated)
+               ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
+
+       if (ifmgd->auth_data && !ifmgd->auth_data->done) {
+               err = -EBUSY;
+               goto err_free;
        }
-       mutex_unlock(&ifmgd->mtx);
 
-       wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL);
-       if (!wk)
-               return -ENOMEM;
+       if (ifmgd->assoc_data) {
+               err = -EBUSY;
+               goto err_free;
+       }
 
-       /*
-        * create a dummy station info entry in order
-        * to start accepting incoming EAPOL packets from the station
-        */
-       err = ieee80211_pre_assoc(sdata, req->bss->bssid);
-       if (err) {
-               kfree(wk);
-               return err;
+       if (ifmgd->auth_data) {
+               bool match;
+
+               /* keep sta info, bssid if matching */
+               match = compare_ether_addr(ifmgd->bssid, req->bss->bssid) == 0;
+               ieee80211_destroy_auth_data(sdata, match);
        }
 
+       /* prepare assoc data */
+
        ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
        ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
 
@@ -2655,7 +3322,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
                    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
                        ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
 
-
        if (req->flags & ASSOC_REQ_DISABLE_HT)
                ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
 
@@ -2664,16 +3330,12 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
               sizeof(ifmgd->ht_capa_mask));
 
        if (req->ie && req->ie_len) {
-               memcpy(wk->ie, req->ie, req->ie_len);
-               wk->ie_len = req->ie_len;
-       } else
-               wk->ie_len = 0;
-
-       wk->assoc.bss = req->bss;
+               memcpy(assoc_data->ie, req->ie, req->ie_len);
+               assoc_data->ie_len = req->ie_len;
+       }
 
-       memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);
+       assoc_data->bss = req->bss;
 
-       /* new association always uses requested smps mode */
        if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
                if (ifmgd->powersave)
                        ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
@@ -2682,7 +3344,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        } else
                ifmgd->ap_smps = ifmgd->req_smps;
 
-       wk->assoc.smps = ifmgd->ap_smps;
        /*
         * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
         * We still associate in non-HT mode (11a/b/g) if any one of these
@@ -2690,39 +3351,27 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
         * We can set this to true for non-11n hardware, that'll be checked
         * separately along with the peer capabilities.
         */
-       wk->assoc.use_11n = !(ifmgd->flags & IEEE80211_STA_DISABLE_11N);
-       wk->assoc.capability = req->bss->capability;
-       wk->assoc.wmm_used = bss->wmm_used;
-       wk->assoc.supp_rates = bss->supp_rates;
-       wk->assoc.supp_rates_len = bss->supp_rates_len;
-       wk->assoc.ht_information_ie =
+       assoc_data->capability = req->bss->capability;
+       assoc_data->wmm_used = bss->wmm_used;
+       assoc_data->supp_rates = bss->supp_rates;
+       assoc_data->supp_rates_len = bss->supp_rates_len;
+       assoc_data->ht_information_ie =
                ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION);
 
        if (bss->wmm_used && bss->uapsd_supported &&
            (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
-               wk->assoc.uapsd_used = true;
+               assoc_data->uapsd_used = true;
                ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
        } else {
-               wk->assoc.uapsd_used = false;
+               assoc_data->uapsd_used = false;
                ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
        }
 
-       ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
-       memcpy(wk->assoc.ssid, ssid + 2, ssid[1]);
-       wk->assoc.ssid_len = ssid[1];
+       memcpy(assoc_data->ssid, ssidie + 2, ssidie[1]);
+       assoc_data->ssid_len = ssidie[1];
 
        if (req->prev_bssid)
-               memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN);
-
-       wk->chan = req->bss->channel;
-       wk->chan_type = NL80211_CHAN_NO_HT;
-       wk->sdata = sdata;
-       wk->done = ieee80211_assoc_done;
-       if (!bss->dtim_period &&
-           sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
-               wk->type = IEEE80211_WORK_ASSOC_BEACON_WAIT;
-       else
-               wk->type = IEEE80211_WORK_ASSOC;
+               memcpy(assoc_data->prev_bssid, req->prev_bssid, ETH_ALEN);
 
        if (req->use_mfp) {
                ifmgd->mfp = IEEE80211_MFP_REQUIRED;
@@ -2740,91 +3389,119 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        sdata->control_port_protocol = req->crypto.control_port_ethertype;
        sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
 
-       ieee80211_add_work(wk);
-       return 0;
-}
+       /* kick off associate process */
 
-int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
-                        struct cfg80211_deauth_request *req,
-                        void *cookie)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-       u8 bssid[ETH_ALEN];
-       bool assoc_bss = false;
+       ifmgd->assoc_data = assoc_data;
 
-       mutex_lock(&ifmgd->mtx);
+       mutex_lock(&local->mtx);
+       ieee80211_recalc_idle(sdata->local);
+       mutex_unlock(&local->mtx);
 
-       memcpy(bssid, req->bss->bssid, ETH_ALEN);
-       if (ifmgd->associated == req->bss) {
-               ieee80211_set_disassoc(sdata, false, true);
-               mutex_unlock(&ifmgd->mtx);
-               assoc_bss = true;
-       } else {
-               bool not_auth_yet = false;
-               struct ieee80211_work *tmp, *wk = NULL;
+       /* switch to the right channel */
+       local->oper_channel = req->bss->channel;
+       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
-               mutex_unlock(&ifmgd->mtx);
+       rcu_read_lock();
+       sta = sta_info_get(sdata, req->bss->bssid);
+       rcu_read_unlock();
 
-               mutex_lock(&local->mtx);
-               list_for_each_entry(tmp, &local->work_list, list) {
-                       if (tmp->sdata != sdata)
-                               continue;
+       if (!sta) {
+               /* set BSSID */
+               memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
+               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
 
-                       if (tmp->type != IEEE80211_WORK_DIRECT_PROBE &&
-                           tmp->type != IEEE80211_WORK_AUTH &&
-                           tmp->type != IEEE80211_WORK_ASSOC &&
-                           tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
-                               continue;
+               sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
+               if (!sta) {
+                       err = -ENOMEM;
+                       goto err_clear;
+               }
 
-                       if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN))
-                               continue;
+               sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
 
-                       not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE;
-                       list_del_rcu(&tmp->list);
-                       synchronize_rcu();
-                       wk = tmp;
-                       break;
-               }
-               mutex_unlock(&local->mtx);
-
-               if (wk && wk->type == IEEE80211_WORK_ASSOC) {
-                       /* clean up dummy sta & TX sync */
-                       sta_info_destroy_addr(wk->sdata, wk->filter_ta);
-                       if (wk->assoc.synced)
-                               drv_finish_tx_sync(local, wk->sdata,
-                                                  wk->filter_ta,
-                                                  IEEE80211_TX_SYNC_ASSOC);
-               } else if (wk && wk->type == IEEE80211_WORK_AUTH) {
-                       if (wk->probe_auth.synced)
-                               drv_finish_tx_sync(local, wk->sdata,
-                                                  wk->filter_ta,
-                                                  IEEE80211_TX_SYNC_AUTH);
+               err = sta_info_insert(sta);
+               sta = NULL;
+               if (err) {
+                       printk(KERN_DEBUG
+                              "%s: failed to insert STA entry for the AP (error %d)\n",
+                              sdata->name, err);
+                       goto err_clear;
                }
-               kfree(wk);
+       } else
+               WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, req->bss->bssid));
 
+       if (!bss->dtim_period &&
+           sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {
                /*
-                * If somebody requests authentication and we haven't
-                * sent out an auth frame yet there's no need to send
-                * out a deauth frame either. If the state was PROBE,
-                * then this is the case. If it's AUTH we have sent a
-                * frame, and if it's IDLE we have completed the auth
-                * process already.
+                * Wait up to one beacon interval ...
+                * should this be more if we miss one?
                 */
-               if (not_auth_yet) {
-                       __cfg80211_auth_canceled(sdata->dev, bssid);
-                       return 0;
-               }
+               printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
+                      sdata->name, ifmgd->bssid);
+               assoc_data->timeout = jiffies +
+                               TU_TO_EXP_TIME(req->bss->beacon_interval);
+       } else {
+               assoc_data->have_beacon = true;
+               assoc_data->sent_assoc = false;
+               assoc_data->timeout = jiffies;
+       }
+       run_again(ifmgd, assoc_data->timeout);
+
+       if (bss->corrupt_data) {
+               char *corrupt_type = "data";
+               if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_BEACON) {
+                       if (bss->corrupt_data &
+                                       IEEE80211_BSS_CORRUPT_PROBE_RESP)
+                               corrupt_type = "beacon and probe response";
+                       else
+                               corrupt_type = "beacon";
+               } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP)
+                       corrupt_type = "probe response";
+               printk(KERN_DEBUG "%s: associating with AP with corrupt %s\n",
+                      sdata->name, corrupt_type);
+       }
+
+       err = 0;
+       goto out;
+ err_clear:
+       ifmgd->assoc_data = NULL;
+ err_free:
+       kfree(assoc_data);
+ out:
+       mutex_unlock(&ifmgd->mtx);
+
+       return err;
+}
+
+int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
+                        struct cfg80211_deauth_request *req)
+{
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       u8 frame_buf[DEAUTH_DISASSOC_LEN];
+
+       mutex_lock(&ifmgd->mtx);
+
+       if (ifmgd->auth_data) {
+               ieee80211_destroy_auth_data(sdata, false);
+               mutex_unlock(&ifmgd->mtx);
+               return 0;
        }
 
-       printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
-              sdata->name, bssid, req->reason_code);
+       printk(KERN_DEBUG
+              "%s: deauthenticating from %pM by local choice (reason=%d)\n",
+              sdata->name, req->bssid, req->reason_code);
+
+       if (ifmgd->associated &&
+           compare_ether_addr(ifmgd->associated->bssid, req->bssid) == 0)
+               ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
+                                      req->reason_code, true, frame_buf);
+       else
+               ieee80211_send_deauth_disassoc(sdata, req->bssid,
+                                              IEEE80211_STYPE_DEAUTH,
+                                              req->reason_code, true,
+                                              frame_buf);
+       mutex_unlock(&ifmgd->mtx);
 
-       ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH,
-                                      req->reason_code, cookie,
-                                      !req->local_state_change);
-       if (assoc_bss)
-               sta_info_flush(sdata->local, sdata);
+       __cfg80211_send_deauth(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
 
        mutex_lock(&sdata->local->mtx);
        ieee80211_recalc_idle(sdata->local);
@@ -2834,11 +3511,11 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
 }
 
 int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
-                          struct cfg80211_disassoc_request *req,
-                          void *cookie)
+                          struct cfg80211_disassoc_request *req)
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        u8 bssid[ETH_ALEN];
+       u8 frame_buf[DEAUTH_DISASSOC_LEN];
 
        mutex_lock(&ifmgd->mtx);
 
@@ -2857,14 +3534,12 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
               sdata->name, req->bss->bssid, req->reason_code);
 
        memcpy(bssid, req->bss->bssid, ETH_ALEN);
-       ieee80211_set_disassoc(sdata, false, true);
-
+       ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC,
+                              req->reason_code, !req->local_state_change,
+                              frame_buf);
        mutex_unlock(&ifmgd->mtx);
 
-       ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
-                       IEEE80211_STYPE_DISASSOC, req->reason_code,
-                       cookie, !req->local_state_change);
-       sta_info_flush(sdata->local, sdata);
+       __cfg80211_send_disassoc(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
 
        mutex_lock(&sdata->local->mtx);
        ieee80211_recalc_idle(sdata->local);
@@ -2873,6 +3548,19 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
        return 0;
 }
 
+void ieee80211_mgd_teardown(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+       mutex_lock(&ifmgd->mtx);
+       if (ifmgd->assoc_data)
+               ieee80211_destroy_assoc_data(sdata, false);
+       if (ifmgd->auth_data)
+               ieee80211_destroy_auth_data(sdata, false);
+       del_timer_sync(&ifmgd->timer);
+       mutex_unlock(&ifmgd->mtx);
+}
+
 void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
                               enum nl80211_cqm_rssi_threshold_event rssi_event,
                               gfp_t gfp)
index 596efaf50e096c354aaa3fb0c01abefe1afe87ab..ef8eba1d736d125cffa30c5a8a1431f2c6fdb1b1 100644 (file)
@@ -98,13 +98,12 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
        mutex_lock(&local->sta_mtx);
        list_for_each_entry(sta, &local->sta_list, list) {
                if (sta->uploaded) {
-                       sdata = sta->sdata;
-                       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-                               sdata = container_of(sdata->bss,
-                                            struct ieee80211_sub_if_data,
-                                            u.ap);
+                       enum ieee80211_sta_state state;
 
-                       drv_sta_remove(local, sdata, &sta->sta);
+                       state = sta->sta_state;
+                       for (; state > IEEE80211_STA_NOTEXIST; state--)
+                               WARN_ON(drv_sta_state(local, sta->sdata, sta,
+                                                     state, state - 1));
                }
 
                mesh_plink_quiesce(sta);
index 5a5a7767d541c2a952aecbeefca79125dfe17052..b4f7600a3e36c010f6d428ad0461db2324087dc3 100644 (file)
@@ -159,7 +159,6 @@ static struct rate_control_ref *rate_control_alloc(const char *name,
        ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
        if (!ref)
                goto fail_ref;
-       kref_init(&ref->kref);
        ref->local = local;
        ref->ops = ieee80211_rate_control_ops_get(name);
        if (!ref->ops)
@@ -184,11 +183,8 @@ fail_ref:
        return NULL;
 }
 
-static void rate_control_release(struct kref *kref)
+static void rate_control_free(struct rate_control_ref *ctrl_ref)
 {
-       struct rate_control_ref *ctrl_ref;
-
-       ctrl_ref = container_of(kref, struct rate_control_ref, kref);
        ctrl_ref->ops->free(ctrl_ref->priv);
 
 #ifdef CONFIG_MAC80211_DEBUGFS
@@ -293,8 +289,8 @@ bool rate_control_send_low(struct ieee80211_sta *sta,
 }
 EXPORT_SYMBOL(rate_control_send_low);
 
-static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
-                               int n_bitrates, u32 mask)
+static bool rate_idx_match_legacy_mask(struct ieee80211_tx_rate *rate,
+                                      int n_bitrates, u32 mask)
 {
        int j;
 
@@ -303,7 +299,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
                if (mask & (1 << j)) {
                        /* Okay, found a suitable rate. Use it. */
                        rate->idx = j;
-                       return;
+                       return true;
                }
        }
 
@@ -312,6 +308,112 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
                if (mask & (1 << j)) {
                        /* Okay, found a suitable rate. Use it. */
                        rate->idx = j;
+                       return true;
+               }
+       }
+       return false;
+}
+
+static bool rate_idx_match_mcs_mask(struct ieee80211_tx_rate *rate,
+                                   u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
+{
+       int i, j;
+       int ridx, rbit;
+
+       ridx = rate->idx / 8;
+       rbit = rate->idx % 8;
+
+       /* sanity check */
+       if (ridx < 0 || ridx >= IEEE80211_HT_MCS_MASK_LEN)
+               return false;
+
+       /* See whether the selected rate or anything below it is allowed. */
+       for (i = ridx; i >= 0; i--) {
+               for (j = rbit; j >= 0; j--)
+                       if (mcs_mask[i] & BIT(j)) {
+                               rate->idx = i * 8 + j;
+                               return true;
+                       }
+               rbit = 7;
+       }
+
+       /* Try to find a higher rate that would be allowed */
+       ridx = (rate->idx + 1) / 8;
+       rbit = (rate->idx + 1) % 8;
+
+       for (i = ridx; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
+               for (j = rbit; j < 8; j++)
+                       if (mcs_mask[i] & BIT(j)) {
+                               rate->idx = i * 8 + j;
+                               return true;
+                       }
+               rbit = 0;
+       }
+       return false;
+}
+
+
+
+static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
+                               struct ieee80211_tx_rate_control *txrc,
+                               u32 mask,
+                               u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
+{
+       struct ieee80211_tx_rate alt_rate;
+
+       /* handle HT rates */
+       if (rate->flags & IEEE80211_TX_RC_MCS) {
+               if (rate_idx_match_mcs_mask(rate, mcs_mask))
+                       return;
+
+               /* also try the legacy rates. */
+               alt_rate.idx = 0;
+               /* keep protection flags */
+               alt_rate.flags = rate->flags &
+                                (IEEE80211_TX_RC_USE_RTS_CTS |
+                                 IEEE80211_TX_RC_USE_CTS_PROTECT |
+                                 IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
+               alt_rate.count = rate->count;
+               if (rate_idx_match_legacy_mask(&alt_rate,
+                                              txrc->sband->n_bitrates,
+                                              mask)) {
+                       *rate = alt_rate;
+                       return;
+               }
+       } else {
+               struct sk_buff *skb = txrc->skb;
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+               __le16 fc;
+
+               /* handle legacy rates */
+               if (rate_idx_match_legacy_mask(rate, txrc->sband->n_bitrates,
+                                              mask))
+                       return;
+
+               /* if HT BSS, and we handle a data frame, also try HT rates */
+               if (txrc->bss_conf->channel_type == NL80211_CHAN_NO_HT)
+                       return;
+
+               fc = hdr->frame_control;
+               if (!ieee80211_is_data(fc))
+                       return;
+
+               alt_rate.idx = 0;
+               /* keep protection flags */
+               alt_rate.flags = rate->flags &
+                                (IEEE80211_TX_RC_USE_RTS_CTS |
+                                 IEEE80211_TX_RC_USE_CTS_PROTECT |
+                                 IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
+               alt_rate.count = rate->count;
+
+               alt_rate.flags |= IEEE80211_TX_RC_MCS;
+
+               if ((txrc->bss_conf->channel_type == NL80211_CHAN_HT40MINUS) ||
+                   (txrc->bss_conf->channel_type == NL80211_CHAN_HT40PLUS))
+                       alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+
+               if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) {
+                       *rate = alt_rate;
                        return;
                }
        }
@@ -335,8 +437,9 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
        int i;
        u32 mask;
+       u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
 
-       if (sta) {
+       if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
                ista = &sta->sta;
                priv_sta = sta->rate_ctrl_priv;
        }
@@ -344,7 +447,7 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
        for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
                info->control.rates[i].idx = -1;
                info->control.rates[i].flags = 0;
-               info->control.rates[i].count = 1;
+               info->control.rates[i].count = 0;
        }
 
        if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
@@ -358,10 +461,14 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
         * the common case.
         */
        mask = sdata->rc_rateidx_mask[info->band];
+       memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band],
+              sizeof(mcs_mask));
        if (mask != (1 << txrc->sband->n_bitrates) - 1) {
                if (sta) {
                        /* Filter out rates that the STA does not support */
                        mask &= sta->sta.supp_rates[info->band];
+                       for (i = 0; i < sizeof(mcs_mask); i++)
+                               mcs_mask[i] &= sta->sta.ht_cap.mcs.rx_mask[i];
                }
                /*
                 * Make sure the rate index selected for each TX rate is
@@ -372,32 +479,18 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
                        /* Skip invalid rates */
                        if (info->control.rates[i].idx < 0)
                                break;
-                       /* Rate masking supports only legacy rates for now */
-                       if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS)
-                               continue;
-                       rate_idx_match_mask(&info->control.rates[i],
-                                           txrc->sband->n_bitrates, mask);
+                       rate_idx_match_mask(&info->control.rates[i], txrc,
+                                           mask, mcs_mask);
                }
        }
 
        BUG_ON(info->control.rates[0].idx < 0);
 }
 
-struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
-{
-       kref_get(&ref->kref);
-       return ref;
-}
-
-void rate_control_put(struct rate_control_ref *ref)
-{
-       kref_put(&ref->kref, rate_control_release);
-}
-
 int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
                                 const char *name)
 {
-       struct rate_control_ref *ref, *old;
+       struct rate_control_ref *ref;
 
        ASSERT_RTNL();
 
@@ -417,12 +510,8 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
                return -ENOENT;
        }
 
-       old = local->rate_ctrl;
+       WARN_ON(local->rate_ctrl);
        local->rate_ctrl = ref;
-       if (old) {
-               rate_control_put(old);
-               sta_info_flush(local, NULL);
-       }
 
        wiphy_debug(local->hw.wiphy, "Selected rate control algorithm '%s'\n",
                    ref->ops->name);
@@ -440,6 +529,6 @@ void rate_control_deinitialize(struct ieee80211_local *local)
                return;
 
        local->rate_ctrl = NULL;
-       rate_control_put(ref);
+       rate_control_free(ref);
 }
 
index 168427b0ffdc97fca6147118518f4593b79770f6..fbb1efdc4d04152237648c0faf48a887a4eab65d 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/types.h>
-#include <linux/kref.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "sta_info.h"
@@ -23,14 +22,11 @@ struct rate_control_ref {
        struct ieee80211_local *local;
        struct rate_control_ops *ops;
        void *priv;
-       struct kref kref;
 };
 
 void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
                           struct sta_info *sta,
                           struct ieee80211_tx_rate_control *txrc);
-struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
-void rate_control_put(struct rate_control_ref *ref);
 
 static inline void rate_control_tx_status(struct ieee80211_local *local,
                                          struct ieee80211_supported_band *sband,
@@ -41,7 +37,7 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
        struct ieee80211_sta *ista = &sta->sta;
        void *priv_sta = sta->rate_ctrl_priv;
 
-       if (!ref)
+       if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
                return;
 
        ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
@@ -62,6 +58,7 @@ static inline void rate_control_rate_init(struct sta_info *sta)
        sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
        ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
+       set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
 }
 
 static inline void rate_control_rate_update(struct ieee80211_local *local,
index 5a5e504a8ffbc9cbf1d22bf8e35949311990406e..5f6e32ca08585ff640fb790f4353f9ace120aaf6 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/export.h>
 #include <net/mac80211.h>
 #include <net/ieee80211_radiotap.h>
+#include <asm/unaligned.h>
 
 #include "ieee80211_i.h"
 #include "driver-ops.h"
@@ -176,7 +177,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
        pos += 2;
 
        /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
-       if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+       if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM &&
+           !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
                *pos = status->signal;
                rthdr->it_present |=
                        cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
@@ -226,7 +228,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
 {
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
        struct ieee80211_sub_if_data *sdata;
-       int needed_headroom = 0;
+       int needed_headroom;
        struct sk_buff *skb, *skb2;
        struct net_device *prev_dev = NULL;
        int present_fcs_len = 0;
@@ -488,12 +490,12 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
                        if (ieee80211_has_tods(hdr->frame_control) ||
                                !ieee80211_has_fromds(hdr->frame_control))
                                return RX_DROP_MONITOR;
-                       if (memcmp(hdr->addr3, dev_addr, ETH_ALEN) == 0)
+                       if (compare_ether_addr(hdr->addr3, dev_addr) == 0)
                                return RX_DROP_MONITOR;
                } else {
                        if (!ieee80211_has_a4(hdr->frame_control))
                                return RX_DROP_MONITOR;
-                       if (memcmp(hdr->addr4, dev_addr, ETH_ALEN) == 0)
+                       if (compare_ether_addr(hdr->addr4, dev_addr) == 0)
                                return RX_DROP_MONITOR;
                }
        }
@@ -859,7 +861,12 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
                     rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
                     rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
                     (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) {
-               if (rx->sta && rx->sta->dummy &&
+               /*
+                * accept port control frames from the AP even when it's not
+                * yet marked ASSOC to prevent a race where we don't set the
+                * assoc bit quickly enough before it sends the first frame
+                */
+               if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
                    ieee80211_is_data_present(hdr->frame_control)) {
                        u16 ethertype;
                        u8 *payload;
@@ -1145,19 +1152,15 @@ static void ap_sta_ps_start(struct sta_info *sta)
 
 static void ap_sta_ps_end(struct sta_info *sta)
 {
-       struct ieee80211_sub_if_data *sdata = sta->sdata;
-
-       atomic_dec(&sdata->bss->num_sta_ps);
-
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
        printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
-              sdata->name, sta->sta.addr, sta->sta.aid);
+              sta->sdata->name, sta->sta.addr, sta->sta.aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
 
        if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
                printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n",
-                      sdata->name, sta->sta.addr, sta->sta.aid);
+                      sta->sdata->name, sta->sta.addr, sta->sta.aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
                return;
        }
@@ -1307,8 +1310,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 
        sta->rx_fragments++;
        sta->rx_bytes += rx->skb->len;
-       sta->last_signal = status->signal;
-       ewma_add(&sta->avg_signal, -status->signal);
+       if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
+               sta->last_signal = status->signal;
+               ewma_add(&sta->avg_signal, -status->signal);
+       }
 
        /*
         * Change STA power saving mode only at the end of a frame
@@ -1955,6 +1960,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
                return RX_DROP_MONITOR;
        }
 
+       if (!ifmsh->mshcfg.dot11MeshForwarding)
+               goto out;
+
        fwd_skb = skb_copy(skb, GFP_ATOMIC);
        if (!fwd_skb) {
                if (net_ratelimit())
@@ -2180,12 +2188,14 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
        if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
            ieee80211_is_beacon(mgmt->frame_control) &&
            !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
-               struct ieee80211_rx_status *status;
+               int sig = 0;
+
+               if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
+                       sig = status->signal;
 
-               status = IEEE80211_SKB_RXCB(rx->skb);
                cfg80211_report_obss_beacon(rx->local->hw.wiphy,
                                            rx->skb->data, rx->skb->len,
-                                           status->freq, GFP_ATOMIC);
+                                           status->freq, sig, GFP_ATOMIC);
                rx->flags |= IEEE80211_RX_BEACON_REPORTED;
        }
 
@@ -2337,7 +2347,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                        if (sdata->vif.type != NL80211_IFTYPE_STATION)
                                break;
 
-                       if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN))
+                       if (compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid))
                                break;
 
                        goto queue;
@@ -2409,6 +2419,7 @@ static ieee80211_rx_result debug_noinline
 ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
 {
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+       int sig = 0;
 
        /* skip known-bad action frames and return them in the next handler */
        if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM)
@@ -2421,7 +2432,10 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
         * it transmitted were processed or returned.
         */
 
-       if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq,
+       if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
+               sig = status->signal;
+
+       if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig,
                             rx->skb->data, rx->skb->len,
                             GFP_ATOMIC)) {
                if (rx->sta)
@@ -2486,14 +2500,9 @@ static ieee80211_rx_result debug_noinline
 ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
 {
        struct ieee80211_sub_if_data *sdata = rx->sdata;
-       ieee80211_rx_result rxs;
        struct ieee80211_mgmt *mgmt = (void *)rx->skb->data;
        __le16 stype;
 
-       rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb);
-       if (rxs != RX_CONTINUE)
-               return rxs;
-
        stype = mgmt->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE);
 
        if (!ieee80211_vif_is_mesh(&sdata->vif) &&
@@ -2502,10 +2511,13 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
                return RX_DROP_MONITOR;
 
        switch (stype) {
+       case cpu_to_le16(IEEE80211_STYPE_AUTH):
        case cpu_to_le16(IEEE80211_STYPE_BEACON):
        case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
                /* process for all: mesh, mlme, ibss */
                break;
+       case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
+       case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
        case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
        case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
                if (is_multicast_ether_addr(mgmt->da) &&
@@ -2517,7 +2529,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
                        return RX_DROP_MONITOR;
                break;
        case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
-       case cpu_to_le16(IEEE80211_STYPE_AUTH):
                /* process only for ibss */
                if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
                        return RX_DROP_MONITOR;
@@ -2542,16 +2553,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
 {
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_local *local = rx->local;
-       struct ieee80211_rtap_hdr {
-               struct ieee80211_radiotap_header hdr;
-               u8 flags;
-               u8 rate_or_pad;
-               __le16 chan_freq;
-               __le16 chan_flags;
-       } __packed *rthdr;
        struct sk_buff *skb = rx->skb, *skb2;
        struct net_device *prev_dev = NULL;
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+       int needed_headroom;
 
        /*
         * If cooked monitor has been processed already, then
@@ -2565,30 +2570,15 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
        if (!local->cooked_mntrs)
                goto out_free_skb;
 
-       if (skb_headroom(skb) < sizeof(*rthdr) &&
-           pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC))
-               goto out_free_skb;
-
-       rthdr = (void *)skb_push(skb, sizeof(*rthdr));
-       memset(rthdr, 0, sizeof(*rthdr));
-       rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
-       rthdr->hdr.it_present =
-               cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
-                           (1 << IEEE80211_RADIOTAP_CHANNEL));
+       /* room for the radiotap header based on driver features */
+       needed_headroom = ieee80211_rx_radiotap_len(local, status);
 
-       if (rate) {
-               rthdr->rate_or_pad = rate->bitrate / 5;
-               rthdr->hdr.it_present |=
-                       cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
-       }
-       rthdr->chan_freq = cpu_to_le16(status->freq);
+       if (skb_headroom(skb) < needed_headroom &&
+           pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC))
+               goto out_free_skb;
 
-       if (status->band == IEEE80211_BAND_5GHZ)
-               rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM |
-                                               IEEE80211_CHAN_5GHZ);
-       else
-               rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN |
-                                               IEEE80211_CHAN_2GHZ);
+       /* prepend radiotap information */
+       ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom);
 
        skb_set_mac_header(skb, 0);
        skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2956,7 +2946,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
        if (ieee80211_is_data(fc)) {
                prev_sta = NULL;
 
-               for_each_sta_info_rx(local, hdr->addr2, sta, tmp) {
+               for_each_sta_info(local, hdr->addr2, sta, tmp) {
                        if (!prev_sta) {
                                prev_sta = sta;
                                continue;
@@ -3000,7 +2990,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
                        continue;
                }
 
-               rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
+               rx.sta = sta_info_get_bss(prev, hdr->addr2);
                rx.sdata = prev;
                ieee80211_prepare_and_rx_handle(&rx, skb, false);
 
@@ -3008,7 +2998,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
        }
 
        if (prev) {
-               rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
+               rx.sta = sta_info_get_bss(prev, hdr->addr2);
                rx.sdata = prev;
 
                if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
index 9270771702fe9a5a12fef9fcde4554f30b18b58d..33cd169013781321a813e10ebfb474c9595bd857 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/if_arp.h>
+#include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/pm_qos.h>
 #include <net/sch_generic.h>
@@ -103,16 +104,35 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
        cbss->free_priv = ieee80211_rx_bss_free;
        bss = (void *)cbss->priv;
 
+       if (elems->parse_error) {
+               if (beacon)
+                       bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON;
+               else
+                       bss->corrupt_data |= IEEE80211_BSS_CORRUPT_PROBE_RESP;
+       } else {
+               if (beacon)
+                       bss->corrupt_data &= ~IEEE80211_BSS_CORRUPT_BEACON;
+               else
+                       bss->corrupt_data &= ~IEEE80211_BSS_CORRUPT_PROBE_RESP;
+       }
+
        /* save the ERP value so that it is available at association time */
-       if (elems->erp_info && elems->erp_info_len >= 1) {
+       if (elems->erp_info && elems->erp_info_len >= 1 &&
+                       (!elems->parse_error ||
+                        !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) {
                bss->erp_value = elems->erp_info[0];
                bss->has_erp_value = true;
+               if (!elems->parse_error)
+                       bss->valid_data |= IEEE80211_BSS_VALID_ERP;
        }
 
-       if (elems->tim) {
+       if (elems->tim && (!elems->parse_error ||
+                          !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) {
                struct ieee80211_tim_ie *tim_ie =
                        (struct ieee80211_tim_ie *)elems->tim;
                bss->dtim_period = tim_ie->dtim_period;
+               if (!elems->parse_error)
+                               bss->valid_data |= IEEE80211_BSS_VALID_DTIM;
        }
 
        /* If the beacon had no TIM IE, or it was invalid, use 1 */
@@ -120,26 +140,38 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
                bss->dtim_period = 1;
 
        /* replace old supported rates if we get new values */
-       srlen = 0;
-       if (elems->supp_rates) {
-               clen = IEEE80211_MAX_SUPP_RATES;
-               if (clen > elems->supp_rates_len)
-                       clen = elems->supp_rates_len;
-               memcpy(bss->supp_rates, elems->supp_rates, clen);
-               srlen += clen;
-       }
-       if (elems->ext_supp_rates) {
-               clen = IEEE80211_MAX_SUPP_RATES - srlen;
-               if (clen > elems->ext_supp_rates_len)
-                       clen = elems->ext_supp_rates_len;
-               memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen);
-               srlen += clen;
+       if (!elems->parse_error ||
+           !(bss->valid_data & IEEE80211_BSS_VALID_RATES)) {
+               srlen = 0;
+               if (elems->supp_rates) {
+                       clen = IEEE80211_MAX_SUPP_RATES;
+                       if (clen > elems->supp_rates_len)
+                               clen = elems->supp_rates_len;
+                       memcpy(bss->supp_rates, elems->supp_rates, clen);
+                       srlen += clen;
+               }
+               if (elems->ext_supp_rates) {
+                       clen = IEEE80211_MAX_SUPP_RATES - srlen;
+                       if (clen > elems->ext_supp_rates_len)
+                               clen = elems->ext_supp_rates_len;
+                       memcpy(bss->supp_rates + srlen, elems->ext_supp_rates,
+                              clen);
+                       srlen += clen;
+               }
+               if (srlen) {
+                       bss->supp_rates_len = srlen;
+                       if (!elems->parse_error)
+                               bss->valid_data |= IEEE80211_BSS_VALID_RATES;
+               }
        }
-       if (srlen)
-               bss->supp_rates_len = srlen;
 
-       bss->wmm_used = elems->wmm_param || elems->wmm_info;
-       bss->uapsd_supported = is_uapsd_supported(elems);
+       if (!elems->parse_error ||
+           !(bss->valid_data & IEEE80211_BSS_VALID_WMM)) {
+               bss->wmm_used = elems->wmm_param || elems->wmm_info;
+               bss->uapsd_supported = is_uapsd_supported(elems);
+               if (!elems->parse_error)
+                       bss->valid_data |= IEEE80211_BSS_VALID_WMM;
+       }
 
        if (!beacon)
                bss->last_probe_resp = jiffies;
@@ -176,7 +208,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
        presp = ieee80211_is_probe_resp(fc);
        if (presp) {
                /* ignore ProbeResp to foreign address */
-               if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
+               if (compare_ether_addr(mgmt->da, sdata->vif.addr))
                        return RX_DROP_MONITOR;
 
                presp = true;
index ff11f6bf8266dc1a01b1b16330b416a054d702de..38137cb5f6f05877a6aadca7fcb846d0062df648 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/etherdevice.h>
 #include <linux/netdevice.h>
 #include <linux/types.h>
 #include <linux/slab.h>
@@ -97,30 +98,11 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
-                                   lockdep_is_held(&local->sta_mtx));
-       while (sta) {
-               if (sta->sdata == sdata && !sta->dummy &&
-                   memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
-                       break;
-               sta = rcu_dereference_check(sta->hnext,
-                                           lockdep_is_held(&local->sta_mtx));
-       }
-       return sta;
-}
-
-/* get a station info entry even if it is a dummy station*/
-struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
-                             const u8 *addr)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct sta_info *sta;
-
        sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
                                    lockdep_is_held(&local->sta_mtx));
        while (sta) {
                if (sta->sdata == sdata &&
-                   memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
+                   compare_ether_addr(sta->sta.addr, addr) == 0)
                        break;
                sta = rcu_dereference_check(sta->hnext,
                                            lockdep_is_held(&local->sta_mtx));
@@ -143,31 +125,7 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
        while (sta) {
                if ((sta->sdata == sdata ||
                     (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
-                   !sta->dummy &&
-                   memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
-                       break;
-               sta = rcu_dereference_check(sta->hnext,
-                                           lockdep_is_held(&local->sta_mtx));
-       }
-       return sta;
-}
-
-/*
- * Get sta info either from the specified interface
- * or from one of its vlans (including dummy stations)
- */
-struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
-                                 const u8 *addr)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct sta_info *sta;
-
-       sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
-                                   lockdep_is_held(&local->sta_mtx));
-       while (sta) {
-               if ((sta->sdata == sdata ||
-                    (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
-                   memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
+                   compare_ether_addr(sta->sta.addr, addr) == 0)
                        break;
                sta = rcu_dereference_check(sta->hnext,
                                            lockdep_is_held(&local->sta_mtx));
@@ -208,10 +166,8 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
  */
 void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
 {
-       if (sta->rate_ctrl) {
+       if (sta->rate_ctrl)
                rate_control_free_sta(sta);
-               rate_control_put(sta->rate_ctrl);
-       }
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
        wiphy_debug(local->hw.wiphy, "Destroyed STA %pM\n", sta->sta.addr);
@@ -264,13 +220,11 @@ static int sta_prepare_rate_control(struct ieee80211_local *local,
        if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
                return 0;
 
-       sta->rate_ctrl = rate_control_get(local->rate_ctrl);
+       sta->rate_ctrl = local->rate_ctrl;
        sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl,
                                                     &sta->sta, gfp);
-       if (!sta->rate_ctrl_priv) {
-               rate_control_put(sta->rate_ctrl);
+       if (!sta->rate_ctrl_priv)
                return -ENOMEM;
-       }
 
        return 0;
 }
@@ -297,6 +251,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        sta->sdata = sdata;
        sta->last_rx = jiffies;
 
+       sta->sta_state = IEEE80211_STA_NONE;
+
        do_posix_clock_monotonic_gettime(&uptime);
        sta->last_connected = uptime.tv_sec;
        ewma_init(&sta->avg_signal, 1024, 8);
@@ -353,6 +309,43 @@ static int sta_info_insert_check(struct sta_info *sta)
        return 0;
 }
 
+static int sta_info_insert_drv_state(struct ieee80211_local *local,
+                                    struct ieee80211_sub_if_data *sdata,
+                                    struct sta_info *sta)
+{
+       enum ieee80211_sta_state state;
+       int err = 0;
+
+       for (state = IEEE80211_STA_NOTEXIST; state < sta->sta_state; state++) {
+               err = drv_sta_state(local, sdata, sta, state, state + 1);
+               if (err)
+                       break;
+       }
+
+       if (!err) {
+               /*
+                * Drivers using legacy sta_add/sta_remove callbacks only
+                * get uploaded set to true after sta_add is called.
+                */
+               if (!local->ops->sta_add)
+                       sta->uploaded = true;
+               return 0;
+       }
+
+       if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+               printk(KERN_DEBUG
+                      "%s: failed to move IBSS STA %pM to state %d (%d) - keeping it anyway.\n",
+                      sdata->name, sta->sta.addr, state + 1, err);
+               err = 0;
+       }
+
+       /* unwind on error */
+       for (; state > IEEE80211_STA_NOTEXIST; state--)
+               WARN_ON(drv_sta_state(local, sdata, sta, state, state - 1));
+
+       return err;
+}
+
 /*
  * should be called with sta_mtx locked
  * this function replaces the mutex lock
@@ -362,70 +355,43 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
 {
        struct ieee80211_local *local = sta->local;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
-       struct sta_info *exist_sta;
-       bool dummy_reinsert = false;
+       struct station_info sinfo;
        int err = 0;
 
        lockdep_assert_held(&local->sta_mtx);
 
-       /*
-        * check if STA exists already.
-        * only accept a scenario of a second call to sta_info_insert_finish
-        * with a dummy station entry that was inserted earlier
-        * in that case - assume that the dummy station flag should
-        * be removed.
-        */
-       exist_sta = sta_info_get_bss_rx(sdata, sta->sta.addr);
-       if (exist_sta) {
-               if (exist_sta == sta && sta->dummy) {
-                       dummy_reinsert = true;
-               } else {
-                       err = -EEXIST;
-                       goto out_err;
-               }
+       /* check if STA exists already */
+       if (sta_info_get_bss(sdata, sta->sta.addr)) {
+               err = -EEXIST;
+               goto out_err;
        }
 
-       if (!sta->dummy || dummy_reinsert) {
-               /* notify driver */
-               err = drv_sta_add(local, sdata, &sta->sta);
-               if (err) {
-                       if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
-                               goto out_err;
-                       printk(KERN_DEBUG "%s: failed to add IBSS STA %pM to "
-                                         "driver (%d) - keeping it anyway.\n",
-                              sdata->name, sta->sta.addr, err);
-               } else
-                       sta->uploaded = true;
-       }
+       /* notify driver */
+       err = sta_info_insert_drv_state(local, sdata, sta);
+       if (err)
+               goto out_err;
 
-       if (!dummy_reinsert) {
-               local->num_sta++;
-               local->sta_generation++;
-               smp_mb();
+       local->num_sta++;
+       local->sta_generation++;
+       smp_mb();
 
-               /* make the station visible */
-               sta_info_hash_add(local, sta);
+       /* make the station visible */
+       sta_info_hash_add(local, sta);
 
-               list_add(&sta->list, &local->sta_list);
-       } else {
-               sta->dummy = false;
-       }
+       list_add(&sta->list, &local->sta_list);
 
-       if (!sta->dummy) {
-               struct station_info sinfo;
+       set_sta_flag(sta, WLAN_STA_INSERTED);
 
-               ieee80211_sta_debugfs_add(sta);
-               rate_control_add_sta_debugfs(sta);
+       ieee80211_sta_debugfs_add(sta);
+       rate_control_add_sta_debugfs(sta);
 
-               memset(&sinfo, 0, sizeof(sinfo));
-               sinfo.filled = 0;
-               sinfo.generation = local->sta_generation;
-               cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
-       }
+       memset(&sinfo, 0, sizeof(sinfo));
+       sinfo.filled = 0;
+       sinfo.generation = local->sta_generation;
+       cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       wiphy_debug(local->hw.wiphy, "Inserted %sSTA %pM\n",
-                       sta->dummy ? "dummy " : "", sta->sta.addr);
+       wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr);
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 
        /* move reference to rcu-protected */
@@ -477,25 +443,6 @@ int sta_info_insert(struct sta_info *sta)
        return err;
 }
 
-/* Caller must hold sta->local->sta_mtx */
-int sta_info_reinsert(struct sta_info *sta)
-{
-       struct ieee80211_local *local = sta->local;
-       int err = 0;
-
-       err = sta_info_insert_check(sta);
-       if (err) {
-               mutex_unlock(&local->sta_mtx);
-               return err;
-       }
-
-       might_sleep();
-
-       err = sta_info_insert_finish(sta);
-       rcu_read_unlock();
-       return err;
-}
-
 static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid)
 {
        /*
@@ -711,7 +658,7 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
        return have_buffered;
 }
 
-static int __must_check __sta_info_destroy(struct sta_info *sta)
+int __must_check __sta_info_destroy(struct sta_info *sta)
 {
        struct ieee80211_local *local;
        struct ieee80211_sub_if_data *sdata;
@@ -726,6 +673,8 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
        local = sta->local;
        sdata = sta->sdata;
 
+       lockdep_assert_held(&local->sta_mtx);
+
        /*
         * Before removing the station from the driver and
         * rate control, it might still start new aggregation
@@ -750,33 +699,24 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
 
        sta->dead = true;
 
-       if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
-           test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
-               BUG_ON(!sdata->bss);
-
-               clear_sta_flag(sta, WLAN_STA_PS_STA);
-               clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-
-               atomic_dec(&sdata->bss->num_sta_ps);
-               sta_info_recalc_tim(sta);
-       }
-
        local->num_sta--;
        local->sta_generation++;
 
        if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
                RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
 
-       while (sta->sta_state > IEEE80211_STA_NONE)
-               sta_info_move_state(sta, sta->sta_state - 1);
+       while (sta->sta_state > IEEE80211_STA_NONE) {
+               ret = sta_info_move_state(sta, sta->sta_state - 1);
+               if (ret) {
+                       WARN_ON_ONCE(1);
+                       break;
+               }
+       }
 
        if (sta->uploaded) {
-               if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-                       sdata = container_of(sdata->bss,
-                                            struct ieee80211_sub_if_data,
-                                            u.ap);
-               drv_sta_remove(local, sdata, &sta->sta);
-               sdata = sta->sdata;
+               ret = drv_sta_state(local, sdata, sta, IEEE80211_STA_NONE,
+                                   IEEE80211_STA_NOTEXIST);
+               WARN_ON_ONCE(ret != 0);
        }
 
        /*
@@ -787,6 +727,15 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
         */
        synchronize_rcu();
 
+       if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+               BUG_ON(!sdata->bss);
+
+               clear_sta_flag(sta, WLAN_STA_PS_STA);
+
+               atomic_dec(&sdata->bss->num_sta_ps);
+               sta_info_recalc_tim(sta);
+       }
+
        for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
                local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
                __skb_queue_purge(&sta->ps_tx_buf[ac]);
@@ -815,35 +764,20 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
        }
 #endif
 
-       /* There could be some memory leaks because of ampdu tx pending queue
-        * not being freed before destroying the station info.
-        *
-        * Make sure that such queues are purged before freeing the station
-        * info.
-        * TODO: We have to somehow postpone the full destruction
-        * until the aggregation stop completes. Refer
-        * http://thread.gmane.org/gmane.linux.kernel.wireless.general/81936
+       /*
+        * Destroy aggregation state here. It would be nice to wait for the
+        * driver to finish aggregation stop and then clean up, but for now
+        * drivers have to handle aggregation stop being requested, followed
+        * directly by station destruction.
         */
-
-       mutex_lock(&sta->ampdu_mlme.mtx);
-
        for (i = 0; i < STA_TID_NUM; i++) {
-               tid_tx = rcu_dereference_protected_tid_tx(sta, i);
+               tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
                if (!tid_tx)
                        continue;
-               if (skb_queue_len(&tid_tx->pending)) {
-#ifdef CONFIG_MAC80211_HT_DEBUG
-                       wiphy_debug(local->hw.wiphy, "TX A-MPDU  purging %d "
-                               "packets for tid=%d\n",
-                               skb_queue_len(&tid_tx->pending), i);
-#endif /* CONFIG_MAC80211_HT_DEBUG */
-                       __skb_queue_purge(&tid_tx->pending);
-               }
-               kfree_rcu(tid_tx, rcu_head);
+               __skb_queue_purge(&tid_tx->pending);
+               kfree(tid_tx);
        }
 
-       mutex_unlock(&sta->ampdu_mlme.mtx);
-
        sta_info_free(local, sta);
 
        return 0;
@@ -855,7 +789,7 @@ int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, const u8 *addr)
        int ret;
 
        mutex_lock(&sdata->local->sta_mtx);
-       sta = sta_info_get_rx(sdata, addr);
+       sta = sta_info_get(sdata, addr);
        ret = __sta_info_destroy(sta);
        mutex_unlock(&sdata->local->sta_mtx);
 
@@ -869,7 +803,7 @@ int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,
        int ret;
 
        mutex_lock(&sdata->local->sta_mtx);
-       sta = sta_info_get_bss_rx(sdata, addr);
+       sta = sta_info_get_bss(sdata, addr);
        ret = __sta_info_destroy(sta);
        mutex_unlock(&sdata->local->sta_mtx);
 
@@ -932,8 +866,10 @@ int sta_info_flush(struct ieee80211_local *local,
 
        mutex_lock(&local->sta_mtx);
        list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
-               if (!sdata || sdata == sta->sdata)
+               if (!sdata || sdata == sta->sdata) {
                        WARN_ON(__sta_info_destroy(sta));
+                       ret++;
+               }
        }
        mutex_unlock(&local->sta_mtx);
 
@@ -1009,9 +945,11 @@ EXPORT_SYMBOL(ieee80211_find_sta);
 static void clear_sta_ps_flags(void *_sta)
 {
        struct sta_info *sta = _sta;
+       struct ieee80211_sub_if_data *sdata = sta->sdata;
 
        clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-       clear_sta_flag(sta, WLAN_STA_PS_STA);
+       if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA))
+               atomic_dec(&sdata->bss->num_sta_ps);
 }
 
 /* powersave support code */
@@ -1113,7 +1051,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
         * exchange. Also set EOSP to indicate this packet
         * ends the poll/service period.
         */
-       info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE |
+       info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER |
                       IEEE80211_TX_STATUS_EOSP |
                       IEEE80211_TX_CTL_REQ_TX_STATUS;
 
@@ -1240,7 +1178,7 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
                         * STA may still remain is PS mode after this frame
                         * exchange.
                         */
-                       info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE;
+                       info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
 
                        /*
                         * Use MoreData flag to indicate whether there are
@@ -1410,28 +1348,68 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
 }
 EXPORT_SYMBOL(ieee80211_sta_set_buffered);
 
-int sta_info_move_state_checked(struct sta_info *sta,
-                               enum ieee80211_sta_state new_state)
+int sta_info_move_state(struct sta_info *sta,
+                       enum ieee80211_sta_state new_state)
 {
        might_sleep();
 
        if (sta->sta_state == new_state)
                return 0;
 
+       /* check allowed transitions first */
+
+       switch (new_state) {
+       case IEEE80211_STA_NONE:
+               if (sta->sta_state != IEEE80211_STA_AUTH)
+                       return -EINVAL;
+               break;
+       case IEEE80211_STA_AUTH:
+               if (sta->sta_state != IEEE80211_STA_NONE &&
+                   sta->sta_state != IEEE80211_STA_ASSOC)
+                       return -EINVAL;
+               break;
+       case IEEE80211_STA_ASSOC:
+               if (sta->sta_state != IEEE80211_STA_AUTH &&
+                   sta->sta_state != IEEE80211_STA_AUTHORIZED)
+                       return -EINVAL;
+               break;
+       case IEEE80211_STA_AUTHORIZED:
+               if (sta->sta_state != IEEE80211_STA_ASSOC)
+                       return -EINVAL;
+               break;
+       default:
+               WARN(1, "invalid state %d", new_state);
+               return -EINVAL;
+       }
+
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+       printk(KERN_DEBUG "%s: moving STA %pM to state %d\n",
+               sta->sdata->name, sta->sta.addr, new_state);
+#endif
+
+       /*
+        * notify the driver before the actual changes so it can
+        * fail the transition
+        */
+       if (test_sta_flag(sta, WLAN_STA_INSERTED)) {
+               int err = drv_sta_state(sta->local, sta->sdata, sta,
+                                       sta->sta_state, new_state);
+               if (err)
+                       return err;
+       }
+
+       /* reflect the change in all state variables */
+
        switch (new_state) {
        case IEEE80211_STA_NONE:
                if (sta->sta_state == IEEE80211_STA_AUTH)
                        clear_bit(WLAN_STA_AUTH, &sta->_flags);
-               else
-                       return -EINVAL;
                break;
        case IEEE80211_STA_AUTH:
                if (sta->sta_state == IEEE80211_STA_NONE)
                        set_bit(WLAN_STA_AUTH, &sta->_flags);
                else if (sta->sta_state == IEEE80211_STA_ASSOC)
                        clear_bit(WLAN_STA_ASSOC, &sta->_flags);
-               else
-                       return -EINVAL;
                break;
        case IEEE80211_STA_ASSOC:
                if (sta->sta_state == IEEE80211_STA_AUTH) {
@@ -1440,24 +1418,19 @@ int sta_info_move_state_checked(struct sta_info *sta,
                        if (sta->sdata->vif.type == NL80211_IFTYPE_AP)
                                atomic_dec(&sta->sdata->u.ap.num_sta_authorized);
                        clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
-               } else
-                       return -EINVAL;
+               }
                break;
        case IEEE80211_STA_AUTHORIZED:
                if (sta->sta_state == IEEE80211_STA_ASSOC) {
                        if (sta->sdata->vif.type == NL80211_IFTYPE_AP)
                                atomic_inc(&sta->sdata->u.ap.num_sta_authorized);
                        set_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
-               } else
-                       return -EINVAL;
+               }
                break;
        default:
-               WARN(1, "invalid state %d", new_state);
-               return -EINVAL;
+               break;
        }
 
-       printk(KERN_DEBUG "%s: moving STA %pM to state %d\n",
-               sta->sdata->name, sta->sta.addr, new_state);
        sta->sta_state = new_state;
 
        return 0;
index 6f77f12dc3fc313410964a91f318e48f1319d86c..ab0576827baf84c9b22a0b0aef2177699c856adf 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/if_ether.h>
 #include <linux/workqueue.h>
 #include <linux/average.h>
+#include <linux/etherdevice.h>
 #include "key.h"
 
 /**
@@ -52,6 +53,8 @@
  * @WLAN_STA_SP: Station is in a service period, so don't try to
  *     reply to other uAPSD trigger frames or PS-Poll.
  * @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame.
+ * @WLAN_STA_INSERTED: This station is inserted into the hash table.
+ * @WLAN_STA_RATE_CONTROL: rate control was initialized for this station.
  */
 enum ieee80211_sta_info_flags {
        WLAN_STA_AUTH,
@@ -71,14 +74,8 @@ enum ieee80211_sta_info_flags {
        WLAN_STA_UAPSD,
        WLAN_STA_SP,
        WLAN_STA_4ADDR_EVENT,
-};
-
-enum ieee80211_sta_state {
-       /* NOTE: These need to be ordered correctly! */
-       IEEE80211_STA_NONE,
-       IEEE80211_STA_AUTH,
-       IEEE80211_STA_ASSOC,
-       IEEE80211_STA_AUTHORIZED,
+       WLAN_STA_INSERTED,
+       WLAN_STA_RATE_CONTROL,
 };
 
 #define STA_TID_NUM 16
@@ -271,8 +268,6 @@ struct sta_ampdu_mlme {
  * @dead: set to true when sta is unlinked
  * @uploaded: set to true when sta is uploaded to the driver
  * @lost_packets: number of consecutive lost packets
- * @dummy: indicate a dummy station created for receiving
- *     EAP frames before association
  * @sta: station information we share with the driver
  * @sta_state: duplicates information about station state (for debug)
  * @beacon_loss_count: number of times beacon loss has triggered
@@ -370,9 +365,6 @@ struct sta_info {
        unsigned int lost_packets;
        unsigned int beacon_loss_count;
 
-       /* should be right in front of sta to be in the same cache line */
-       bool dummy;
-
        /* keep last! */
        struct ieee80211_sta sta;
 };
@@ -427,13 +419,17 @@ static inline int test_and_set_sta_flag(struct sta_info *sta,
        return test_and_set_bit(flag, &sta->_flags);
 }
 
-int sta_info_move_state_checked(struct sta_info *sta,
-                               enum ieee80211_sta_state new_state);
+int sta_info_move_state(struct sta_info *sta,
+                       enum ieee80211_sta_state new_state);
 
-static inline void sta_info_move_state(struct sta_info *sta,
-                                      enum ieee80211_sta_state new_state)
+static inline void sta_info_pre_move_state(struct sta_info *sta,
+                                          enum ieee80211_sta_state new_state)
 {
-       int ret = sta_info_move_state_checked(sta, new_state);
+       int ret;
+
+       WARN_ON_ONCE(test_sta_flag(sta, WLAN_STA_INSERTED));
+
+       ret = sta_info_move_state(sta, new_state);
        WARN_ON_ONCE(ret);
 }
 
@@ -470,15 +466,9 @@ rcu_dereference_protected_tid_tx(struct sta_info *sta, int tid)
 struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
                              const u8 *addr);
 
-struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
-                             const u8 *addr);
-
 struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
                                  const u8 *addr);
 
-struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
-                                 const u8 *addr);
-
 static inline
 void for_each_sta_info_type_check(struct ieee80211_local *local,
                                  const u8 *addr,
@@ -487,23 +477,7 @@ void for_each_sta_info_type_check(struct ieee80211_local *local,
 {
 }
 
-#define for_each_sta_info(local, _addr, _sta, nxt)                     \
-       for (   /* initialise loop */                                   \
-               _sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
-               nxt = _sta ? rcu_dereference(_sta->hnext) : NULL;       \
-               /* typecheck */                                         \
-               for_each_sta_info_type_check(local, (_addr), _sta, nxt),\
-               /* continue condition */                                \
-               _sta;                                                   \
-               /* advance loop */                                      \
-               _sta = nxt,                                             \
-               nxt = _sta ? rcu_dereference(_sta->hnext) : NULL        \
-            )                                                          \
-       /* run code only if address matches and it's not a dummy sta */ \
-       if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0 &&           \
-               !_sta->dummy)
-
-#define for_each_sta_info_rx(local, _addr, _sta, nxt)                  \
+#define for_each_sta_info(local, _addr, _sta, nxt)                     \
        for (   /* initialise loop */                                   \
                _sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
                nxt = _sta ? rcu_dereference(_sta->hnext) : NULL;       \
@@ -516,7 +490,7 @@ void for_each_sta_info_type_check(struct ieee80211_local *local,
                nxt = _sta ? rcu_dereference(_sta->hnext) : NULL        \
             )                                                          \
        /* compare address and run code only if it matches */           \
-       if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0)
+       if (compare_ether_addr(_sta->sta.addr, (_addr)) == 0)
 
 /*
  * Get STA info by index, BROKEN!
@@ -542,8 +516,8 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta);
  */
 int sta_info_insert(struct sta_info *sta);
 int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU);
-int sta_info_reinsert(struct sta_info *sta);
 
+int __must_check __sta_info_destroy(struct sta_info *sta);
 int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata,
                          const u8 *addr);
 int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,
@@ -555,6 +529,9 @@ void sta_info_init(struct ieee80211_local *local);
 void sta_info_stop(struct ieee80211_local *local);
 int sta_info_flush(struct ieee80211_local *local,
                   struct ieee80211_sub_if_data *sdata);
+void sta_set_rate_info_tx(struct sta_info *sta,
+                         const struct ieee80211_tx_rate *rate,
+                         struct rate_info *rinfo);
 void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
                          unsigned long exp_time);
 
index 30c265c98f73ccb190a0d642977f33d53298650f..5f8f89e89d6b446e989d9d3ae546174a711e016f 100644 (file)
@@ -10,7 +10,9 @@
  */
 
 #include <linux/export.h>
+#include <linux/etherdevice.h>
 #include <net/mac80211.h>
+#include <asm/unaligned.h>
 #include "ieee80211_i.h"
 #include "rate.h"
 #include "mesh.h"
@@ -350,7 +352,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
        bool send_to_cooked;
        bool acked;
        struct ieee80211_bar *bar;
-       u16 tid;
        int rtap_len;
 
        for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
@@ -377,7 +378,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 
        for_each_sta_info(local, hdr->addr1, sta, tmp) {
                /* skip wrong virtual interface */
-               if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
+               if (compare_ether_addr(hdr->addr2, sta->sdata->vif.addr))
                        continue;
 
                if (info->flags & IEEE80211_TX_STATUS_EOSP)
@@ -412,7 +413,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
                }
 
                if (!acked && ieee80211_is_back_req(fc)) {
-                       u16 control;
+                       u16 tid, control;
 
                        /*
                         * BAR failed, store the last SSN and retry sending
@@ -516,7 +517,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 
                if (ieee80211_is_nullfunc(hdr->frame_control) ||
                    ieee80211_is_qos_nullfunc(hdr->frame_control)) {
-                       bool acked = info->flags & IEEE80211_TX_STAT_ACK;
+                       acked = info->flags & IEEE80211_TX_STAT_ACK;
+
                        cfg80211_probe_status(skb->dev, hdr->addr1,
                                              cookie, acked, GFP_ATOMIC);
                } else {
index e05667cd5e766057c22770670834e6f2b19e3301..570737df2d2244e729c9c9928a902592ccc3d120 100644 (file)
@@ -448,18 +448,23 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
        struct ieee80211_local *local = tx->local;
 
-       if (unlikely(!sta ||
-                    ieee80211_is_probe_resp(hdr->frame_control) ||
-                    ieee80211_is_auth(hdr->frame_control) ||
-                    ieee80211_is_assoc_resp(hdr->frame_control) ||
-                    ieee80211_is_reassoc_resp(hdr->frame_control)))
+       if (unlikely(!sta))
                return TX_CONTINUE;
 
        if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
                      test_sta_flag(sta, WLAN_STA_PS_DRIVER)) &&
-                    !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) {
+                    !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
                int ac = skb_get_queue_mapping(tx->skb);
 
+               /* only deauth, disassoc and action are bufferable MMPDUs */
+               if (ieee80211_is_mgmt(hdr->frame_control) &&
+                   !ieee80211_is_deauth(hdr->frame_control) &&
+                   !ieee80211_is_disassoc(hdr->frame_control) &&
+                   !ieee80211_is_action(hdr->frame_control)) {
+                       info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
+                       return TX_CONTINUE;
+               }
+
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
                printk(KERN_DEBUG "STA %pM aid %d: PS buffer for AC %d\n",
                       sta->sta.addr, sta->sta.aid, ac);
@@ -625,7 +630,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
                         tx->local->hw.wiphy->frag_threshold);
 
        /* set up the tx rate control struct we give the RC algo */
-       txrc.hw = local_to_hw(tx->local);
+       txrc.hw = &tx->local->hw;
        txrc.sband = sband;
        txrc.bss_conf = &tx->sdata->vif.bss_conf;
        txrc.skb = tx->skb;
@@ -635,6 +640,9 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
                txrc.max_rate_idx = -1;
        else
                txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
+       memcpy(txrc.rate_idx_mcs_mask,
+              tx->sdata->rc_rateidx_mcs_mask[tx->channel->band],
+              sizeof(txrc.rate_idx_mcs_mask));
        txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
                    tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
                    tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
@@ -2203,7 +2211,8 @@ void ieee80211_tx_pending(unsigned long data)
 
 /* functions for drivers to get certain frames */
 
-static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss,
+static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
+                                    struct ieee80211_if_ap *bss,
                                     struct sk_buff *skb,
                                     struct beacon_data *beacon)
 {
@@ -2220,7 +2229,7 @@ static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss,
                                          IEEE80211_MAX_AID+1);
 
        if (bss->dtim_count == 0)
-               bss->dtim_count = beacon->dtim_period - 1;
+               bss->dtim_count = sdata->vif.bss_conf.dtim_period - 1;
        else
                bss->dtim_count--;
 
@@ -2228,7 +2237,7 @@ static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss,
        *pos++ = WLAN_EID_TIM;
        *pos++ = 4;
        *pos++ = bss->dtim_count;
-       *pos++ = beacon->dtim_period;
+       *pos++ = sdata->vif.bss_conf.dtim_period;
 
        if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf))
                aid0 = 1;
@@ -2321,12 +2330,14 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
                         * of the tim bitmap in mac80211 and the driver.
                         */
                        if (local->tim_in_locked_section) {
-                               ieee80211_beacon_add_tim(ap, skb, beacon);
+                               ieee80211_beacon_add_tim(sdata, ap, skb,
+                                                        beacon);
                        } else {
                                unsigned long flags;
 
                                spin_lock_irqsave(&local->tim_lock, flags);
-                               ieee80211_beacon_add_tim(ap, skb, beacon);
+                               ieee80211_beacon_add_tim(sdata, ap, skb,
+                                                        beacon);
                                spin_unlock_irqrestore(&local->tim_lock, flags);
                        }
 
@@ -2431,6 +2442,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
                txrc.max_rate_idx = -1;
        else
                txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
+       memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
+              sizeof(txrc.rate_idx_mcs_mask));
        txrc.bss = true;
        rate_control_get_rate(sdata, NULL, &txrc);
 
index 9919892575f45a94f55e34c474f3f93736755237..32f7a3b3d43ce0f4232ef890f004af5186dceb51 100644 (file)
@@ -572,24 +572,40 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
        size_t left = len;
        u8 *pos = start;
        bool calc_crc = filter != 0;
+       DECLARE_BITMAP(seen_elems, 256);
 
+       bitmap_zero(seen_elems, 256);
        memset(elems, 0, sizeof(*elems));
        elems->ie_start = start;
        elems->total_len = len;
 
        while (left >= 2) {
                u8 id, elen;
+               bool elem_parse_failed;
 
                id = *pos++;
                elen = *pos++;
                left -= 2;
 
-               if (elen > left)
+               if (elen > left) {
+                       elems->parse_error = true;
                        break;
+               }
+
+               if (id != WLAN_EID_VENDOR_SPECIFIC &&
+                   id != WLAN_EID_QUIET &&
+                   test_bit(id, seen_elems)) {
+                       elems->parse_error = true;
+                       left -= elen;
+                       pos += elen;
+                       continue;
+               }
 
                if (calc_crc && id < 64 && (filter & (1ULL << id)))
                        crc = crc32_be(crc, pos - 2, elen + 2);
 
+               elem_parse_failed = false;
+
                switch (id) {
                case WLAN_EID_SSID:
                        elems->ssid = pos;
@@ -615,7 +631,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                        if (elen >= sizeof(struct ieee80211_tim_ie)) {
                                elems->tim = (void *)pos;
                                elems->tim_len = elen;
-                       }
+                       } else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_IBSS_PARAMS:
                        elems->ibss_params = pos;
@@ -664,10 +681,14 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                case WLAN_EID_HT_CAPABILITY:
                        if (elen >= sizeof(struct ieee80211_ht_cap))
                                elems->ht_cap_elem = (void *)pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_HT_INFORMATION:
                        if (elen >= sizeof(struct ieee80211_ht_info))
                                elems->ht_info_elem = (void *)pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_MESH_ID:
                        elems->mesh_id = pos;
@@ -676,6 +697,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                case WLAN_EID_MESH_CONFIG:
                        if (elen >= sizeof(struct ieee80211_meshconf_ie))
                                elems->mesh_config = (void *)pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_PEER_MGMT:
                        elems->peering = pos;
@@ -696,6 +719,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                case WLAN_EID_RANN:
                        if (elen >= sizeof(struct ieee80211_rann_ie))
                                elems->rann = (void *)pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_CHANNEL_SWITCH:
                        elems->ch_switch_elem = pos;
@@ -724,10 +749,18 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                        break;
                }
 
+               if (elem_parse_failed)
+                       elems->parse_error = true;
+               else
+                       set_bit(id, seen_elems);
+
                left -= elen;
                pos += elen;
        }
 
+       if (left != 0)
+               elems->parse_error = true;
+
        return crc;
 }
 
@@ -737,7 +770,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
        ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
 }
 
-void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
+void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
+                              bool bss_notify)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_tx_queue_params qparam;
@@ -753,7 +787,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
        use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) &&
                 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
 
-       for (queue = 0; queue < local_to_hw(local)->queues; queue++) {
+       for (queue = 0; queue < local->hw.queues; queue++) {
                /* Set defaults according to 802.11-2007 Table 7-37 */
                aCWmax = 1023;
                if (use_11b)
@@ -807,7 +841,9 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
        if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
                sdata->vif.bss_conf.qos =
                        sdata->vif.type != NL80211_IFTYPE_STATION;
-               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
+               if (bss_notify)
+                       ieee80211_bss_info_change_notify(sdata,
+                                                        BSS_CHANGED_QOS);
        }
 }
 
@@ -829,7 +865,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
        else
                sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
 
-       ieee80211_set_wmm_default(sdata);
+       ieee80211_set_wmm_default(sdata, true);
 }
 
 u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
@@ -862,8 +898,8 @@ u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
 
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
                         u16 transaction, u16 auth_alg,
-                        u8 *extra, size_t extra_len, const u8 *bssid,
-                        const u8 *key, u8 key_len, u8 key_idx)
+                        u8 *extra, size_t extra_len, const u8 *da,
+                        const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx)
 {
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
@@ -881,7 +917,7 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
        memset(mgmt, 0, 24 + 6);
        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                          IEEE80211_STYPE_AUTH);
-       memcpy(mgmt->da, bssid, ETH_ALEN);
+       memcpy(mgmt->da, da, ETH_ALEN);
        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
        memcpy(mgmt->bssid, bssid, ETH_ALEN);
        mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg);
@@ -1185,13 +1221,12 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        mutex_lock(&local->sta_mtx);
        list_for_each_entry(sta, &local->sta_list, list) {
                if (sta->uploaded) {
-                       sdata = sta->sdata;
-                       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-                               sdata = container_of(sdata->bss,
-                                            struct ieee80211_sub_if_data,
-                                            u.ap);
+                       enum ieee80211_sta_state state;
 
-                       WARN_ON(drv_sta_add(local, sdata, &sta->sta));
+                       for (state = IEEE80211_STA_NOTEXIST;
+                            state < sta->sta_state - 1; state++)
+                               WARN_ON(drv_sta_state(local, sta->sdata, sta,
+                                                     state, state + 1));
                }
        }
        mutex_unlock(&local->sta_mtx);
@@ -1271,6 +1306,21 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 
        ieee80211_recalc_ps(local, -1);
 
+       /*
+        * The sta might be in psm against the ap (e.g. because
+        * this was the state before a hw restart), so we
+        * explicitly send a null packet in order to make sure
+        * it'll sync against the ap (and get out of psm).
+        */
+       if (!(local->hw.conf.flags & IEEE80211_CONF_PS)) {
+               list_for_each_entry(sdata, &local->interfaces, list) {
+                       if (sdata->vif.type != NL80211_IFTYPE_STATION)
+                               continue;
+
+                       ieee80211_send_nullfunc(local, sdata, 0);
+               }
+       }
+
        /*
         * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
         * sessions can be established after a resume.
index c6dd01a05291e25865bac897a67353785131a4fa..c6e230efa04952314cf3f995f4c58d08ba142038 100644 (file)
 #include "rate.h"
 #include "driver-ops.h"
 
-#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
-#define IEEE80211_AUTH_MAX_TRIES 3
-#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
-#define IEEE80211_ASSOC_MAX_TRIES 3
-
 enum work_action {
-       WORK_ACT_MISMATCH,
        WORK_ACT_NONE,
        WORK_ACT_TIMEOUT,
-       WORK_ACT_DONE,
 };
 
 
@@ -71,464 +64,6 @@ void free_work(struct ieee80211_work *wk)
        kfree_rcu(wk, rcu_head);
 }
 
-static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
-                                     struct ieee80211_supported_band *sband,
-                                     u32 *rates)
-{
-       int i, j, count;
-       *rates = 0;
-       count = 0;
-       for (i = 0; i < supp_rates_len; i++) {
-               int rate = (supp_rates[i] & 0x7F) * 5;
-
-               for (j = 0; j < sband->n_bitrates; j++)
-                       if (sband->bitrates[j].bitrate == rate) {
-                               *rates |= BIT(j);
-                               count++;
-                               break;
-                       }
-       }
-
-       return count;
-}
-
-/* frame sending functions */
-
-static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
-                               struct sk_buff *skb, const u8 *ht_info_ie,
-                               struct ieee80211_supported_band *sband,
-                               struct ieee80211_channel *channel,
-                               enum ieee80211_smps_mode smps)
-{
-       struct ieee80211_ht_info *ht_info;
-       u8 *pos;
-       u32 flags = channel->flags;
-       u16 cap;
-       struct ieee80211_sta_ht_cap ht_cap;
-
-       BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
-
-       if (!sband->ht_cap.ht_supported)
-               return;
-
-       if (!ht_info_ie)
-               return;
-
-       if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
-               return;
-
-       memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
-       ieee80211_apply_htcap_overrides(sdata, &ht_cap);
-
-       ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
-
-       /* determine capability flags */
-       cap = ht_cap.cap;
-
-       switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
-       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
-               if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
-                       cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
-                       cap &= ~IEEE80211_HT_CAP_SGI_40;
-               }
-               break;
-       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-               if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
-                       cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
-                       cap &= ~IEEE80211_HT_CAP_SGI_40;
-               }
-               break;
-       }
-
-       /* set SM PS mode properly */
-       cap &= ~IEEE80211_HT_CAP_SM_PS;
-       switch (smps) {
-       case IEEE80211_SMPS_AUTOMATIC:
-       case IEEE80211_SMPS_NUM_MODES:
-               WARN_ON(1);
-       case IEEE80211_SMPS_OFF:
-               cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
-                       IEEE80211_HT_CAP_SM_PS_SHIFT;
-               break;
-       case IEEE80211_SMPS_STATIC:
-               cap |= WLAN_HT_CAP_SM_PS_STATIC <<
-                       IEEE80211_HT_CAP_SM_PS_SHIFT;
-               break;
-       case IEEE80211_SMPS_DYNAMIC:
-               cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
-                       IEEE80211_HT_CAP_SM_PS_SHIFT;
-               break;
-       }
-
-       /* reserve and fill IE */
-       pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
-       ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
-}
-
-static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
-                                struct ieee80211_work *wk)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct sk_buff *skb;
-       struct ieee80211_mgmt *mgmt;
-       u8 *pos, qos_info;
-       size_t offset = 0, noffset;
-       int i, count, rates_len, supp_rates_len;
-       u16 capab;
-       struct ieee80211_supported_band *sband;
-       u32 rates = 0;
-
-       sband = local->hw.wiphy->bands[wk->chan->band];
-
-       if (wk->assoc.supp_rates_len) {
-               /*
-                * Get all rates supported by the device and the AP as
-                * some APs don't like getting a superset of their rates
-                * in the association request (e.g. D-Link DAP 1353 in
-                * b-only mode)...
-                */
-               rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates,
-                                                      wk->assoc.supp_rates_len,
-                                                      sband, &rates);
-       } else {
-               /*
-                * In case AP not provide any supported rates information
-                * before association, we send information element(s) with
-                * all rates that we support.
-                */
-               rates = ~0;
-               rates_len = sband->n_bitrates;
-       }
-
-       skb = alloc_skb(local->hw.extra_tx_headroom +
-                       sizeof(*mgmt) + /* bit too much but doesn't matter */
-                       2 + wk->assoc.ssid_len + /* SSID */
-                       4 + rates_len + /* (extended) rates */
-                       4 + /* power capability */
-                       2 + 2 * sband->n_channels + /* supported channels */
-                       2 + sizeof(struct ieee80211_ht_cap) + /* HT */
-                       wk->ie_len + /* extra IEs */
-                       9, /* WMM */
-                       GFP_KERNEL);
-       if (!skb)
-               return;
-
-       skb_reserve(skb, local->hw.extra_tx_headroom);
-
-       capab = WLAN_CAPABILITY_ESS;
-
-       if (sband->band == IEEE80211_BAND_2GHZ) {
-               if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
-                       capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
-               if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
-                       capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
-       }
-
-       if (wk->assoc.capability & WLAN_CAPABILITY_PRIVACY)
-               capab |= WLAN_CAPABILITY_PRIVACY;
-
-       if ((wk->assoc.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
-           (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
-               capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
-
-       mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
-       memset(mgmt, 0, 24);
-       memcpy(mgmt->da, wk->filter_ta, ETH_ALEN);
-       memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
-       memcpy(mgmt->bssid, wk->filter_ta, ETH_ALEN);
-
-       if (!is_zero_ether_addr(wk->assoc.prev_bssid)) {
-               skb_put(skb, 10);
-               mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-                                                 IEEE80211_STYPE_REASSOC_REQ);
-               mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
-               mgmt->u.reassoc_req.listen_interval =
-                               cpu_to_le16(local->hw.conf.listen_interval);
-               memcpy(mgmt->u.reassoc_req.current_ap, wk->assoc.prev_bssid,
-                      ETH_ALEN);
-       } else {
-               skb_put(skb, 4);
-               mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-                                                 IEEE80211_STYPE_ASSOC_REQ);
-               mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
-               mgmt->u.assoc_req.listen_interval =
-                               cpu_to_le16(local->hw.conf.listen_interval);
-       }
-
-       /* SSID */
-       pos = skb_put(skb, 2 + wk->assoc.ssid_len);
-       *pos++ = WLAN_EID_SSID;
-       *pos++ = wk->assoc.ssid_len;
-       memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len);
-
-       /* add all rates which were marked to be used above */
-       supp_rates_len = rates_len;
-       if (supp_rates_len > 8)
-               supp_rates_len = 8;
-
-       pos = skb_put(skb, supp_rates_len + 2);
-       *pos++ = WLAN_EID_SUPP_RATES;
-       *pos++ = supp_rates_len;
-
-       count = 0;
-       for (i = 0; i < sband->n_bitrates; i++) {
-               if (BIT(i) & rates) {
-                       int rate = sband->bitrates[i].bitrate;
-                       *pos++ = (u8) (rate / 5);
-                       if (++count == 8)
-                               break;
-               }
-       }
-
-       if (rates_len > count) {
-               pos = skb_put(skb, rates_len - count + 2);
-               *pos++ = WLAN_EID_EXT_SUPP_RATES;
-               *pos++ = rates_len - count;
-
-               for (i++; i < sband->n_bitrates; i++) {
-                       if (BIT(i) & rates) {
-                               int rate = sband->bitrates[i].bitrate;
-                               *pos++ = (u8) (rate / 5);
-                       }
-               }
-       }
-
-       if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
-               /* 1. power capabilities */
-               pos = skb_put(skb, 4);
-               *pos++ = WLAN_EID_PWR_CAPABILITY;
-               *pos++ = 2;
-               *pos++ = 0; /* min tx power */
-               *pos++ = wk->chan->max_power; /* max tx power */
-
-               /* 2. supported channels */
-               /* TODO: get this in reg domain format */
-               pos = skb_put(skb, 2 * sband->n_channels + 2);
-               *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
-               *pos++ = 2 * sband->n_channels;
-               for (i = 0; i < sband->n_channels; i++) {
-                       *pos++ = ieee80211_frequency_to_channel(
-                                       sband->channels[i].center_freq);
-                       *pos++ = 1; /* one channel in the subband*/
-               }
-       }
-
-       /* if present, add any custom IEs that go before HT */
-       if (wk->ie_len && wk->ie) {
-               static const u8 before_ht[] = {
-                       WLAN_EID_SSID,
-                       WLAN_EID_SUPP_RATES,
-                       WLAN_EID_EXT_SUPP_RATES,
-                       WLAN_EID_PWR_CAPABILITY,
-                       WLAN_EID_SUPPORTED_CHANNELS,
-                       WLAN_EID_RSN,
-                       WLAN_EID_QOS_CAPA,
-                       WLAN_EID_RRM_ENABLED_CAPABILITIES,
-                       WLAN_EID_MOBILITY_DOMAIN,
-                       WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
-               };
-               noffset = ieee80211_ie_split(wk->ie, wk->ie_len,
-                                            before_ht, ARRAY_SIZE(before_ht),
-                                            offset);
-               pos = skb_put(skb, noffset - offset);
-               memcpy(pos, wk->ie + offset, noffset - offset);
-               offset = noffset;
-       }
-
-       if (wk->assoc.use_11n && wk->assoc.wmm_used &&
-           local->hw.queues >= 4)
-               ieee80211_add_ht_ie(sdata, skb, wk->assoc.ht_information_ie,
-                                   sband, wk->chan, wk->assoc.smps);
-
-       /* if present, add any custom non-vendor IEs that go after HT */
-       if (wk->ie_len && wk->ie) {
-               noffset = ieee80211_ie_split_vendor(wk->ie, wk->ie_len,
-                                                   offset);
-               pos = skb_put(skb, noffset - offset);
-               memcpy(pos, wk->ie + offset, noffset - offset);
-               offset = noffset;
-       }
-
-       if (wk->assoc.wmm_used && local->hw.queues >= 4) {
-               if (wk->assoc.uapsd_used) {
-                       qos_info = local->uapsd_queues;
-                       qos_info |= (local->uapsd_max_sp_len <<
-                                    IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
-               } else {
-                       qos_info = 0;
-               }
-
-               pos = skb_put(skb, 9);
-               *pos++ = WLAN_EID_VENDOR_SPECIFIC;
-               *pos++ = 7; /* len */
-               *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
-               *pos++ = 0x50;
-               *pos++ = 0xf2;
-               *pos++ = 2; /* WME */
-               *pos++ = 0; /* WME info */
-               *pos++ = 1; /* WME ver */
-               *pos++ = qos_info;
-       }
-
-       /* add any remaining custom (i.e. vendor specific here) IEs */
-       if (wk->ie_len && wk->ie) {
-               noffset = wk->ie_len;
-               pos = skb_put(skb, noffset - offset);
-               memcpy(pos, wk->ie + offset, noffset - offset);
-       }
-
-       IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
-       ieee80211_tx_skb(sdata, skb);
-}
-
-static void ieee80211_remove_auth_bss(struct ieee80211_local *local,
-                                     struct ieee80211_work *wk)
-{
-       struct cfg80211_bss *cbss;
-       u16 capa_val = WLAN_CAPABILITY_ESS;
-
-       if (wk->probe_auth.privacy)
-               capa_val |= WLAN_CAPABILITY_PRIVACY;
-
-       cbss = cfg80211_get_bss(local->hw.wiphy, wk->chan, wk->filter_ta,
-                               wk->probe_auth.ssid, wk->probe_auth.ssid_len,
-                               WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
-                               capa_val);
-       if (!cbss)
-               return;
-
-       cfg80211_unlink_bss(local->hw.wiphy, cbss);
-       cfg80211_put_bss(cbss);
-}
-
-static enum work_action __must_check
-ieee80211_direct_probe(struct ieee80211_work *wk)
-{
-       struct ieee80211_sub_if_data *sdata = wk->sdata;
-       struct ieee80211_local *local = sdata->local;
-
-       if (!wk->probe_auth.synced) {
-               int ret = drv_tx_sync(local, sdata, wk->filter_ta,
-                                     IEEE80211_TX_SYNC_AUTH);
-               if (ret)
-                       return WORK_ACT_TIMEOUT;
-       }
-       wk->probe_auth.synced = true;
-
-       wk->probe_auth.tries++;
-       if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
-               printk(KERN_DEBUG "%s: direct probe to %pM timed out\n",
-                      sdata->name, wk->filter_ta);
-
-               /*
-                * Most likely AP is not in the range so remove the
-                * bss struct for that AP.
-                */
-               ieee80211_remove_auth_bss(local, wk);
-
-               return WORK_ACT_TIMEOUT;
-       }
-
-       printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
-              sdata->name, wk->filter_ta, wk->probe_auth.tries,
-              IEEE80211_AUTH_MAX_TRIES);
-
-       /*
-        * Direct probe is sent to broadcast address as some APs
-        * will not answer to direct packet in unassociated state.
-        */
-       ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
-                                wk->probe_auth.ssid_len, NULL, 0,
-                                (u32) -1, true, false);
-
-       wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
-       run_again(local, wk->timeout);
-
-       return WORK_ACT_NONE;
-}
-
-
-static enum work_action __must_check
-ieee80211_authenticate(struct ieee80211_work *wk)
-{
-       struct ieee80211_sub_if_data *sdata = wk->sdata;
-       struct ieee80211_local *local = sdata->local;
-
-       if (!wk->probe_auth.synced) {
-               int ret = drv_tx_sync(local, sdata, wk->filter_ta,
-                                     IEEE80211_TX_SYNC_AUTH);
-               if (ret)
-                       return WORK_ACT_TIMEOUT;
-       }
-       wk->probe_auth.synced = true;
-
-       wk->probe_auth.tries++;
-       if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
-               printk(KERN_DEBUG "%s: authentication with %pM"
-                      " timed out\n", sdata->name, wk->filter_ta);
-
-               /*
-                * Most likely AP is not in the range so remove the
-                * bss struct for that AP.
-                */
-               ieee80211_remove_auth_bss(local, wk);
-
-               return WORK_ACT_TIMEOUT;
-       }
-
-       printk(KERN_DEBUG "%s: authenticate with %pM (try %d)\n",
-              sdata->name, wk->filter_ta, wk->probe_auth.tries);
-
-       ieee80211_send_auth(sdata, 1, wk->probe_auth.algorithm, wk->ie,
-                           wk->ie_len, wk->filter_ta, NULL, 0, 0);
-       wk->probe_auth.transaction = 2;
-
-       wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
-       run_again(local, wk->timeout);
-
-       return WORK_ACT_NONE;
-}
-
-static enum work_action __must_check
-ieee80211_associate(struct ieee80211_work *wk)
-{
-       struct ieee80211_sub_if_data *sdata = wk->sdata;
-       struct ieee80211_local *local = sdata->local;
-
-       if (!wk->assoc.synced) {
-               int ret = drv_tx_sync(local, sdata, wk->filter_ta,
-                                     IEEE80211_TX_SYNC_ASSOC);
-               if (ret)
-                       return WORK_ACT_TIMEOUT;
-       }
-       wk->assoc.synced = true;
-
-       wk->assoc.tries++;
-       if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) {
-               printk(KERN_DEBUG "%s: association with %pM"
-                      " timed out\n",
-                      sdata->name, wk->filter_ta);
-
-               /*
-                * Most likely AP is not in the range so remove the
-                * bss struct for that AP.
-                */
-               if (wk->assoc.bss)
-                       cfg80211_unlink_bss(local->hw.wiphy, wk->assoc.bss);
-
-               return WORK_ACT_TIMEOUT;
-       }
-
-       printk(KERN_DEBUG "%s: associate with %pM (try %d)\n",
-              sdata->name, wk->filter_ta, wk->assoc.tries);
-       ieee80211_send_assoc(sdata, wk);
-
-       wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
-       run_again(local, wk->timeout);
-
-       return WORK_ACT_NONE;
-}
-
 static enum work_action __must_check
 ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
 {
@@ -568,300 +103,6 @@ ieee80211_offchannel_tx(struct ieee80211_work *wk)
        return WORK_ACT_TIMEOUT;
 }
 
-static enum work_action __must_check
-ieee80211_assoc_beacon_wait(struct ieee80211_work *wk)
-{
-       if (wk->started)
-               return WORK_ACT_TIMEOUT;
-
-       /*
-        * Wait up to one beacon interval ...
-        * should this be more if we miss one?
-        */
-       printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
-              wk->sdata->name, wk->filter_ta);
-       wk->timeout = TU_TO_EXP_TIME(wk->assoc.bss->beacon_interval);
-       return WORK_ACT_NONE;
-}
-
-static void ieee80211_auth_challenge(struct ieee80211_work *wk,
-                                    struct ieee80211_mgmt *mgmt,
-                                    size_t len)
-{
-       struct ieee80211_sub_if_data *sdata = wk->sdata;
-       u8 *pos;
-       struct ieee802_11_elems elems;
-
-       pos = mgmt->u.auth.variable;
-       ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
-       if (!elems.challenge)
-               return;
-       ieee80211_send_auth(sdata, 3, wk->probe_auth.algorithm,
-                           elems.challenge - 2, elems.challenge_len + 2,
-                           wk->filter_ta, wk->probe_auth.key,
-                           wk->probe_auth.key_len, wk->probe_auth.key_idx);
-       wk->probe_auth.transaction = 4;
-}
-
-static enum work_action __must_check
-ieee80211_rx_mgmt_auth(struct ieee80211_work *wk,
-                      struct ieee80211_mgmt *mgmt, size_t len)
-{
-       u16 auth_alg, auth_transaction, status_code;
-
-       if (wk->type != IEEE80211_WORK_AUTH)
-               return WORK_ACT_MISMATCH;
-
-       if (len < 24 + 6)
-               return WORK_ACT_NONE;
-
-       auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
-       auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
-       status_code = le16_to_cpu(mgmt->u.auth.status_code);
-
-       if (auth_alg != wk->probe_auth.algorithm ||
-           auth_transaction != wk->probe_auth.transaction)
-               return WORK_ACT_NONE;
-
-       if (status_code != WLAN_STATUS_SUCCESS) {
-               printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
-                      wk->sdata->name, mgmt->sa, status_code);
-               return WORK_ACT_DONE;
-       }
-
-       switch (wk->probe_auth.algorithm) {
-       case WLAN_AUTH_OPEN:
-       case WLAN_AUTH_LEAP:
-       case WLAN_AUTH_FT:
-               break;
-       case WLAN_AUTH_SHARED_KEY:
-               if (wk->probe_auth.transaction != 4) {
-                       ieee80211_auth_challenge(wk, mgmt, len);
-                       /* need another frame */
-                       return WORK_ACT_NONE;
-               }
-               break;
-       default:
-               WARN_ON(1);
-               return WORK_ACT_NONE;
-       }
-
-       printk(KERN_DEBUG "%s: authenticated\n", wk->sdata->name);
-       return WORK_ACT_DONE;
-}
-
-static enum work_action __must_check
-ieee80211_rx_mgmt_assoc_resp(struct ieee80211_work *wk,
-                            struct ieee80211_mgmt *mgmt, size_t len,
-                            bool reassoc)
-{
-       struct ieee80211_sub_if_data *sdata = wk->sdata;
-       struct ieee80211_local *local = sdata->local;
-       u16 capab_info, status_code, aid;
-       struct ieee802_11_elems elems;
-       u8 *pos;
-
-       if (wk->type != IEEE80211_WORK_ASSOC)
-               return WORK_ACT_MISMATCH;
-
-       /*
-        * AssocResp and ReassocResp have identical structure, so process both
-        * of them in this function.
-        */
-
-       if (len < 24 + 6)
-               return WORK_ACT_NONE;
-
-       capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
-       status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
-       aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
-
-       printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
-              "status=%d aid=%d)\n",
-              sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
-              capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
-
-       pos = mgmt->u.assoc_resp.variable;
-       ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
-
-       if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
-           elems.timeout_int && elems.timeout_int_len == 5 &&
-           elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
-               u32 tu, ms;
-               tu = get_unaligned_le32(elems.timeout_int + 1);
-               ms = tu * 1024 / 1000;
-               printk(KERN_DEBUG "%s: %pM rejected association temporarily; "
-                      "comeback duration %u TU (%u ms)\n",
-                      sdata->name, mgmt->sa, tu, ms);
-               wk->timeout = jiffies + msecs_to_jiffies(ms);
-               if (ms > IEEE80211_ASSOC_TIMEOUT)
-                       run_again(local, wk->timeout);
-               return WORK_ACT_NONE;
-       }
-
-       if (status_code != WLAN_STATUS_SUCCESS)
-               printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n",
-                      sdata->name, mgmt->sa, status_code);
-       else
-               printk(KERN_DEBUG "%s: associated\n", sdata->name);
-
-       return WORK_ACT_DONE;
-}
-
-static enum work_action __must_check
-ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk,
-                            struct ieee80211_mgmt *mgmt, size_t len,
-                            struct ieee80211_rx_status *rx_status)
-{
-       struct ieee80211_sub_if_data *sdata = wk->sdata;
-       struct ieee80211_local *local = sdata->local;
-       size_t baselen;
-
-       ASSERT_WORK_MTX(local);
-
-       if (wk->type != IEEE80211_WORK_DIRECT_PROBE)
-               return WORK_ACT_MISMATCH;
-
-       if (len < 24 + 12)
-               return WORK_ACT_NONE;
-
-       baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
-       if (baselen > len)
-               return WORK_ACT_NONE;
-
-       printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
-       return WORK_ACT_DONE;
-}
-
-static enum work_action __must_check
-ieee80211_rx_mgmt_beacon(struct ieee80211_work *wk,
-                        struct ieee80211_mgmt *mgmt, size_t len)
-{
-       struct ieee80211_sub_if_data *sdata = wk->sdata;
-       struct ieee80211_local *local = sdata->local;
-
-       ASSERT_WORK_MTX(local);
-
-       if (wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
-               return WORK_ACT_MISMATCH;
-
-       if (len < 24 + 12)
-               return WORK_ACT_NONE;
-
-       printk(KERN_DEBUG "%s: beacon received\n", sdata->name);
-       return WORK_ACT_DONE;
-}
-
-static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
-                                         struct sk_buff *skb)
-{
-       struct ieee80211_rx_status *rx_status;
-       struct ieee80211_mgmt *mgmt;
-       struct ieee80211_work *wk;
-       enum work_action rma = WORK_ACT_NONE;
-       u16 fc;
-
-       rx_status = (struct ieee80211_rx_status *) skb->cb;
-       mgmt = (struct ieee80211_mgmt *) skb->data;
-       fc = le16_to_cpu(mgmt->frame_control);
-
-       mutex_lock(&local->mtx);
-
-       list_for_each_entry(wk, &local->work_list, list) {
-               const u8 *bssid = NULL;
-
-               switch (wk->type) {
-               case IEEE80211_WORK_DIRECT_PROBE:
-               case IEEE80211_WORK_AUTH:
-               case IEEE80211_WORK_ASSOC:
-               case IEEE80211_WORK_ASSOC_BEACON_WAIT:
-                       bssid = wk->filter_ta;
-                       break;
-               default:
-                       continue;
-               }
-
-               /*
-                * Before queuing, we already verified mgmt->sa,
-                * so this is needed just for matching.
-                */
-               if (compare_ether_addr(bssid, mgmt->bssid))
-                       continue;
-
-               switch (fc & IEEE80211_FCTL_STYPE) {
-               case IEEE80211_STYPE_BEACON:
-                       rma = ieee80211_rx_mgmt_beacon(wk, mgmt, skb->len);
-                       break;
-               case IEEE80211_STYPE_PROBE_RESP:
-                       rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len,
-                                                          rx_status);
-                       break;
-               case IEEE80211_STYPE_AUTH:
-                       rma = ieee80211_rx_mgmt_auth(wk, mgmt, skb->len);
-                       break;
-               case IEEE80211_STYPE_ASSOC_RESP:
-                       rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
-                                                          skb->len, false);
-                       break;
-               case IEEE80211_STYPE_REASSOC_RESP:
-                       rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
-                                                          skb->len, true);
-                       break;
-               default:
-                       WARN_ON(1);
-                       rma = WORK_ACT_NONE;
-               }
-
-               /*
-                * We've either received an unexpected frame, or we have
-                * multiple work items and need to match the frame to the
-                * right one.
-                */
-               if (rma == WORK_ACT_MISMATCH)
-                       continue;
-
-               /*
-                * We've processed this frame for that work, so it can't
-                * belong to another work struct.
-                * NB: this is also required for correctness for 'rma'!
-                */
-               break;
-       }
-
-       switch (rma) {
-       case WORK_ACT_MISMATCH:
-               /* ignore this unmatched frame */
-               break;
-       case WORK_ACT_NONE:
-               break;
-       case WORK_ACT_DONE:
-               list_del_rcu(&wk->list);
-               break;
-       default:
-               WARN(1, "unexpected: %d", rma);
-       }
-
-       mutex_unlock(&local->mtx);
-
-       if (rma != WORK_ACT_DONE)
-               goto out;
-
-       switch (wk->done(wk, skb)) {
-       case WORK_DONE_DESTROY:
-               free_work(wk);
-               break;
-       case WORK_DONE_REQUEUE:
-               synchronize_rcu();
-               wk->started = false; /* restart */
-               mutex_lock(&local->mtx);
-               list_add_tail(&wk->list, &local->work_list);
-               mutex_unlock(&local->mtx);
-       }
-
- out:
-       kfree_skb(skb);
-}
-
 static void ieee80211_work_timer(unsigned long data)
 {
        struct ieee80211_local *local = (void *) data;
@@ -876,7 +117,6 @@ static void ieee80211_work_work(struct work_struct *work)
 {
        struct ieee80211_local *local =
                container_of(work, struct ieee80211_local, work_work);
-       struct sk_buff *skb;
        struct ieee80211_work *wk, *tmp;
        LIST_HEAD(free_work);
        enum work_action rma;
@@ -892,10 +132,6 @@ static void ieee80211_work_work(struct work_struct *work)
        if (WARN(local->suspended, "work scheduled while going to suspend\n"))
                return;
 
-       /* first process frames to avoid timing out while a frame is pending */
-       while ((skb = skb_dequeue(&local->work_skb_queue)))
-               ieee80211_work_rx_queued_mgmt(local, skb);
-
        mutex_lock(&local->mtx);
 
        ieee80211_recalc_idle(local);
@@ -946,24 +182,12 @@ static void ieee80211_work_work(struct work_struct *work)
                case IEEE80211_WORK_ABORT:
                        rma = WORK_ACT_TIMEOUT;
                        break;
-               case IEEE80211_WORK_DIRECT_PROBE:
-                       rma = ieee80211_direct_probe(wk);
-                       break;
-               case IEEE80211_WORK_AUTH:
-                       rma = ieee80211_authenticate(wk);
-                       break;
-               case IEEE80211_WORK_ASSOC:
-                       rma = ieee80211_associate(wk);
-                       break;
                case IEEE80211_WORK_REMAIN_ON_CHANNEL:
                        rma = ieee80211_remain_on_channel_timeout(wk);
                        break;
                case IEEE80211_WORK_OFFCHANNEL_TX:
                        rma = ieee80211_offchannel_tx(wk);
                        break;
-               case IEEE80211_WORK_ASSOC_BEACON_WAIT:
-                       rma = ieee80211_assoc_beacon_wait(wk);
-                       break;
                }
 
                wk->started = started;
@@ -1051,7 +275,6 @@ void ieee80211_work_init(struct ieee80211_local *local)
        setup_timer(&local->work_timer, ieee80211_work_timer,
                    (unsigned long)local);
        INIT_WORK(&local->work_work, ieee80211_work_work);
-       skb_queue_head_init(&local->work_skb_queue);
 }
 
 void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
@@ -1085,43 +308,6 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
        mutex_unlock(&local->mtx);
 }
 
-ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
-                                          struct sk_buff *skb)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct ieee80211_mgmt *mgmt;
-       struct ieee80211_work *wk;
-       u16 fc;
-
-       if (skb->len < 24)
-               return RX_DROP_MONITOR;
-
-       mgmt = (struct ieee80211_mgmt *) skb->data;
-       fc = le16_to_cpu(mgmt->frame_control);
-
-       list_for_each_entry_rcu(wk, &local->work_list, list) {
-               if (sdata != wk->sdata)
-                       continue;
-               if (compare_ether_addr(wk->filter_ta, mgmt->sa))
-                       continue;
-               if (compare_ether_addr(wk->filter_ta, mgmt->bssid))
-                       continue;
-
-               switch (fc & IEEE80211_FCTL_STYPE) {
-               case IEEE80211_STYPE_AUTH:
-               case IEEE80211_STYPE_PROBE_RESP:
-               case IEEE80211_STYPE_ASSOC_RESP:
-               case IEEE80211_STYPE_REASSOC_RESP:
-               case IEEE80211_STYPE_BEACON:
-                       skb_queue_tail(&local->work_skb_queue, skb);
-                       ieee80211_queue_work(&local->hw, &local->work_work);
-                       return RX_QUEUED;
-               }
-       }
-
-       return RX_CONTINUE;
-}
-
 static enum work_done_result ieee80211_remain_done(struct ieee80211_work *wk,
                                                   struct sk_buff *skb)
 {
index da67756425ce927f233bd9f490e58befbefd4390..9d68441e2a5ab571ab5e5d20891251bedd3b2d7b 100644 (file)
@@ -30,7 +30,7 @@ static DEFINE_RWLOCK(proto_tab_lock);
 static const struct nfc_protocol *proto_tab[NFC_SOCKPROTO_MAX];
 
 static int nfc_sock_create(struct net *net, struct socket *sock, int proto,
-                                                               int kern)
+                          int kern)
 {
        int rc = -EPROTONOSUPPORT;
 
index 3ddf6e698df0569c2f8aafbb19cecd4fa15b9aa4..295d129864d246cb6c1a3b993dfbc54ebc826bad 100644 (file)
@@ -181,13 +181,13 @@ error:
        return rc;
 }
 
-int nfc_dep_link_up(struct nfc_dev *dev, int target_index,
-                                       u8 comm_mode, u8 rf_mode)
+int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode)
 {
        int rc = 0;
+       u8 *gb;
+       size_t gb_len;
 
-       pr_debug("dev_name=%s comm:%d rf:%d\n",
-                       dev_name(&dev->dev), comm_mode, rf_mode);
+       pr_debug("dev_name=%s comm %d\n", dev_name(&dev->dev), comm_mode);
 
        if (!dev->ops->dep_link_up)
                return -EOPNOTSUPP;
@@ -204,7 +204,13 @@ int nfc_dep_link_up(struct nfc_dev *dev, int target_index,
                goto error;
        }
 
-       rc = dev->ops->dep_link_up(dev, target_index, comm_mode, rf_mode);
+       gb = nfc_llcp_general_bytes(dev, &gb_len);
+       if (gb_len > NFC_MAX_GT_LEN) {
+               rc = -EINVAL;
+               goto error;
+       }
+
+       rc = dev->ops->dep_link_up(dev, target_index, comm_mode, gb, gb_len);
 
 error:
        device_unlock(&dev->dev);
@@ -250,7 +256,7 @@ error:
 }
 
 int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx,
-                                       u8 comm_mode, u8 rf_mode)
+                      u8 comm_mode, u8 rf_mode)
 {
        dev->dep_link_up = true;
        dev->dep_rf_mode = rf_mode;
@@ -330,10 +336,8 @@ error:
  *
  * The user must wait for the callback before calling this function again.
  */
-int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx,
-                                       struct sk_buff *skb,
-                                       data_exchange_cb_t cb,
-                                       void *cb_context)
+int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
+                     data_exchange_cb_t cb, void *cb_context)
 {
        int rc;
 
@@ -357,8 +361,7 @@ error:
 
 int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len)
 {
-       pr_debug("dev_name=%s gb_len=%d\n",
-                       dev_name(&dev->dev), gb_len);
+       pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len);
 
        if (gb_len > NFC_MAX_GT_LEN)
                return -EINVAL;
@@ -367,12 +370,6 @@ int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len)
 }
 EXPORT_SYMBOL(nfc_set_remote_general_bytes);
 
-u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *gt_len)
-{
-       return nfc_llcp_general_bytes(dev, gt_len);
-}
-EXPORT_SYMBOL(nfc_get_local_general_bytes);
-
 /**
  * nfc_alloc_send_skb - allocate a skb for data exchange responses
  *
@@ -380,8 +377,8 @@ EXPORT_SYMBOL(nfc_get_local_general_bytes);
  * @gfp: gfp flags
  */
 struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk,
-                                       unsigned int flags, unsigned int size,
-                                       unsigned int *err)
+                                  unsigned int flags, unsigned int size,
+                                  unsigned int *err)
 {
        struct sk_buff *skb;
        unsigned int total_size;
@@ -428,25 +425,20 @@ EXPORT_SYMBOL(nfc_alloc_recv_skb);
  * are found. After calling this function, the device driver must stop
  * polling for targets.
  */
-int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets,
-                                                       int n_targets)
+int nfc_targets_found(struct nfc_dev *dev,
+                     struct nfc_target *targets, int n_targets)
 {
-       int i;
-
        pr_debug("dev_name=%s n_targets=%d\n", dev_name(&dev->dev), n_targets);
 
        dev->polling = false;
 
-       for (i = 0; i < n_targets; i++)
-               targets[i].idx = dev->target_idx++;
-
        spin_lock_bh(&dev->targets_lock);
 
        dev->targets_generation++;
 
        kfree(dev->targets);
        dev->targets = kmemdup(targets, n_targets * sizeof(struct nfc_target),
-                                                               GFP_ATOMIC);
+                              GFP_ATOMIC);
 
        if (!dev->targets) {
                dev->n_targets = 0;
@@ -506,15 +498,14 @@ struct nfc_dev *nfc_get_device(unsigned idx)
  * @supported_protocols: NFC protocols supported by the device
  */
 struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
-                                       u32 supported_protocols,
-                                       int tx_headroom,
-                                       int tx_tailroom)
+                                   u32 supported_protocols,
+                                   int tx_headroom, int tx_tailroom)
 {
        static atomic_t dev_no = ATOMIC_INIT(0);
        struct nfc_dev *dev;
 
        if (!ops->start_poll || !ops->stop_poll || !ops->activate_target ||
-               !ops->deactivate_target || !ops->data_exchange)
+           !ops->deactivate_target || !ops->data_exchange)
                return NULL;
 
        if (!supported_protocols)
index 151f2ef429c4cf93708bdb6d1524ccf6f2b1cb55..7b76eb7192f37fc50167d39ff6d2a1d7ffc400e4 100644 (file)
@@ -118,7 +118,7 @@ u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length)
 }
 
 int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
-                       u8 *tlv_array, u16 tlv_array_len)
+                      u8 *tlv_array, u16 tlv_array_len)
 {
        u8 *tlv = tlv_array, type, length, offset = 0;
 
@@ -152,6 +152,8 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
                case LLCP_TLV_RW:
                        local->remote_rw = llcp_tlv_rw(tlv);
                        break;
+               case LLCP_TLV_SN:
+                       break;
                default:
                        pr_err("Invalid gt tlv value 0x%x\n", type);
                        break;
@@ -162,15 +164,15 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
        }
 
        pr_debug("version 0x%x miu %d lto %d opt 0x%x wks 0x%x rw %d\n",
-               local->remote_version, local->remote_miu,
-               local->remote_lto, local->remote_opt,
-               local->remote_wks, local->remote_rw);
+                local->remote_version, local->remote_miu,
+                local->remote_lto, local->remote_opt,
+                local->remote_wks, local->remote_rw);
 
        return 0;
 }
 
 static struct sk_buff *llcp_add_header(struct sk_buff *pdu,
-                                       u8 dsap, u8 ssap, u8 ptype)
+                                      u8 dsap, u8 ssap, u8 ptype)
 {
        u8 header[2];
 
@@ -186,7 +188,8 @@ static struct sk_buff *llcp_add_header(struct sk_buff *pdu,
        return pdu;
 }
 
-static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, u8 tlv_length)
+static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv,
+                                   u8 tlv_length)
 {
        /* XXX Add an skb length check */
 
@@ -199,7 +202,7 @@ static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, u8 tlv_length)
 }
 
 static struct sk_buff *llcp_allocate_pdu(struct nfc_llcp_sock *sock,
-                                                       u8 cmd, u16 size)
+                                        u8 cmd, u16 size)
 {
        struct sk_buff *skb;
        int err;
@@ -208,7 +211,7 @@ static struct sk_buff *llcp_allocate_pdu(struct nfc_llcp_sock *sock,
                return NULL;
 
        skb = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT,
-                                       size + LLCP_HEADER_SIZE, &err);
+                                size + LLCP_HEADER_SIZE, &err);
        if (skb == NULL) {
                pr_err("Could not allocate PDU\n");
                return NULL;
@@ -276,7 +279,7 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
        skb = llcp_add_header(skb, 0, 0, LLCP_PDU_SYMM);
 
        return nfc_data_exchange(dev, local->target_idx, skb,
-                                       nfc_llcp_recv, local);
+                                nfc_llcp_recv, local);
 }
 
 int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
@@ -284,6 +287,9 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
        struct nfc_llcp_local *local;
        struct sk_buff *skb;
        u8 *service_name_tlv = NULL, service_name_tlv_length;
+       u8 *miux_tlv = NULL, miux_tlv_length;
+       u8 *rw_tlv = NULL, rw_tlv_length, rw;
+       __be16 miux;
        int err;
        u16 size = 0;
 
@@ -295,12 +301,21 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
 
        if (sock->service_name != NULL) {
                service_name_tlv = nfc_llcp_build_tlv(LLCP_TLV_SN,
-                                       sock->service_name,
-                                       sock->service_name_len,
-                                       &service_name_tlv_length);
+                                                     sock->service_name,
+                                                     sock->service_name_len,
+                                                     &service_name_tlv_length);
                size += service_name_tlv_length;
        }
 
+       miux = cpu_to_be16(LLCP_MAX_MIUX);
+       miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
+                                     &miux_tlv_length);
+       size += miux_tlv_length;
+
+       rw = LLCP_MAX_RW;
+       rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length);
+       size += rw_tlv_length;
+
        pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len);
 
        skb = llcp_allocate_pdu(sock, LLCP_PDU_CONNECT, size);
@@ -311,7 +326,10 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
 
        if (service_name_tlv != NULL)
                skb = llcp_add_tlv(skb, service_name_tlv,
-                                       service_name_tlv_length);
+                                  service_name_tlv_length);
+
+       skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length);
+       skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length);
 
        skb_queue_tail(&local->tx_queue, skb);
 
@@ -321,6 +339,8 @@ error_tlv:
        pr_err("error %d\n", err);
 
        kfree(service_name_tlv);
+       kfree(miux_tlv);
+       kfree(rw_tlv);
 
        return err;
 }
@@ -329,6 +349,11 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
 {
        struct nfc_llcp_local *local;
        struct sk_buff *skb;
+       u8 *miux_tlv = NULL, miux_tlv_length;
+       u8 *rw_tlv = NULL, rw_tlv_length, rw;
+       __be16 miux;
+       int err;
+       u16 size = 0;
 
        pr_debug("Sending CC\n");
 
@@ -336,13 +361,35 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
        if (local == NULL)
                return -ENODEV;
 
-       skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, 0);
-       if (skb == NULL)
-               return -ENOMEM;
+       miux = cpu_to_be16(LLCP_MAX_MIUX);
+       miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
+                                     &miux_tlv_length);
+       size += miux_tlv_length;
+
+       rw = LLCP_MAX_RW;
+       rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length);
+       size += rw_tlv_length;
+
+       skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size);
+       if (skb == NULL) {
+               err = -ENOMEM;
+               goto error_tlv;
+       }
+
+       skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length);
+       skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length);
 
        skb_queue_tail(&local->tx_queue, skb);
 
        return 0;
+
+error_tlv:
+       pr_err("error %d\n", err);
+
+       kfree(miux_tlv);
+       kfree(rw_tlv);
+
+       return err;
 }
 
 int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason)
@@ -397,3 +444,87 @@ int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock)
 
        return 0;
 }
+
+int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
+                         struct msghdr *msg, size_t len)
+{
+       struct sk_buff *pdu;
+       struct sock *sk = &sock->sk;
+       struct nfc_llcp_local *local;
+       size_t frag_len = 0, remaining_len;
+       u8 *msg_data, *msg_ptr;
+
+       pr_debug("Send I frame len %zd\n", len);
+
+       local = sock->local;
+       if (local == NULL)
+               return -ENODEV;
+
+       msg_data = kzalloc(len, GFP_KERNEL);
+       if (msg_data == NULL)
+               return -ENOMEM;
+
+       if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) {
+               kfree(msg_data);
+               return -EFAULT;
+       }
+
+       remaining_len = len;
+       msg_ptr = msg_data;
+
+       while (remaining_len > 0) {
+
+               frag_len = min_t(u16, local->remote_miu, remaining_len);
+
+               pr_debug("Fragment %zd bytes remaining %zd",
+                        frag_len, remaining_len);
+
+               pdu = llcp_allocate_pdu(sock, LLCP_PDU_I,
+                                       frag_len + LLCP_SEQUENCE_SIZE);
+               if (pdu == NULL)
+                       return -ENOMEM;
+
+               skb_put(pdu, LLCP_SEQUENCE_SIZE);
+
+               memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len);
+
+               skb_queue_head(&sock->tx_queue, pdu);
+
+               lock_sock(sk);
+
+               nfc_llcp_queue_i_frames(sock);
+
+               release_sock(sk);
+
+               remaining_len -= frag_len;
+               msg_ptr += len;
+       }
+
+       kfree(msg_data);
+
+       return 0;
+}
+
+int nfc_llcp_send_rr(struct nfc_llcp_sock *sock)
+{
+       struct sk_buff *skb;
+       struct nfc_llcp_local *local;
+
+       pr_debug("Send rr nr %d\n", sock->recv_n);
+
+       local = sock->local;
+       if (local == NULL)
+               return -ENODEV;
+
+       skb = llcp_allocate_pdu(sock, LLCP_PDU_RR, LLCP_SEQUENCE_SIZE);
+       if (skb == NULL)
+               return -ENOMEM;
+
+       skb_put(skb, LLCP_SEQUENCE_SIZE);
+
+       skb->data[2] = sock->recv_n % 16;
+
+       skb_queue_head(&local->tx_queue, skb);
+
+       return 0;
+}
index 1d32680807d67f3729bb19724d9c09ba2f4cc599..17a578f641f12f8bf5b98a58996af292e5ef50a0 100644 (file)
@@ -37,7 +37,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local)
        struct sock *sk, *parent_sk;
        int i;
 
-
        mutex_lock(&local->socket_lock);
 
        for (i = 0; i < LLCP_MAX_SAP; i++) {
@@ -47,7 +46,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local)
 
                /* Release all child sockets */
                list_for_each_entry_safe(s, n, &parent->list, list) {
-                       list_del(&s->list);
+                       list_del_init(&s->list);
                        sk = &s->sk;
 
                        lock_sock(sk);
@@ -56,9 +55,12 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local)
                                nfc_put_device(s->dev);
 
                        sk->sk_state = LLCP_CLOSED;
-                       sock_set_flag(sk, SOCK_DEAD);
 
                        release_sock(sk);
+
+                       sock_orphan(sk);
+
+                       s->local = NULL;
                }
 
                parent_sk = &parent->sk;
@@ -70,18 +72,19 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local)
                        struct sock *accept_sk;
 
                        list_for_each_entry_safe(lsk, n, &parent->accept_queue,
-                                                               accept_queue) {
+                                                accept_queue) {
                                accept_sk = &lsk->sk;
                                lock_sock(accept_sk);
 
                                nfc_llcp_accept_unlink(accept_sk);
 
                                accept_sk->sk_state = LLCP_CLOSED;
-                               sock_set_flag(accept_sk, SOCK_DEAD);
 
                                release_sock(accept_sk);
 
                                sock_orphan(accept_sk);
+
+                               lsk->local = NULL;
                        }
                }
 
@@ -89,18 +92,32 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local)
                        nfc_put_device(parent->dev);
 
                parent_sk->sk_state = LLCP_CLOSED;
-               sock_set_flag(parent_sk, SOCK_DEAD);
 
                release_sock(parent_sk);
+
+               sock_orphan(parent_sk);
+
+               parent->local = NULL;
        }
 
        mutex_unlock(&local->socket_lock);
 }
 
+static void nfc_llcp_clear_sdp(struct nfc_llcp_local *local)
+{
+       mutex_lock(&local->sdp_lock);
+
+       local->local_wks = 0;
+       local->local_sdp = 0;
+       local->local_sap = 0;
+
+       mutex_unlock(&local->sdp_lock);
+}
+
 static void nfc_llcp_timeout_work(struct work_struct *work)
 {
        struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
-                                                       timeout_work);
+                                                   timeout_work);
 
        nfc_dep_link_down(local->dev);
 }
@@ -146,7 +163,7 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len)
 
        num_wks = ARRAY_SIZE(wks);
 
-       for (sap = 0 ; sap < num_wks; sap++) {
+       for (sap = 0; sap < num_wks; sap++) {
                if (wks[sap] == NULL)
                        continue;
 
@@ -158,13 +175,13 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len)
 }
 
 u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
-                               struct nfc_llcp_sock *sock)
+                        struct nfc_llcp_sock *sock)
 {
        mutex_lock(&local->sdp_lock);
 
        if (sock->service_name != NULL && sock->service_name_len > 0) {
                int ssap = nfc_llcp_wks_sap(sock->service_name,
-                                               sock->service_name_len);
+                                           sock->service_name_len);
 
                if (ssap > 0) {
                        pr_debug("WKS %d\n", ssap);
@@ -176,7 +193,7 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
                                return LLCP_SAP_MAX;
                        }
 
-                       set_bit(BIT(ssap), &local->local_wks);
+                       set_bit(ssap, &local->local_wks);
                        mutex_unlock(&local->sdp_lock);
 
                        return ssap;
@@ -195,25 +212,25 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
 
                pr_debug("SDP ssap %d\n", LLCP_WKS_NUM_SAP + ssap);
 
-               set_bit(BIT(ssap), &local->local_sdp);
+               set_bit(ssap, &local->local_sdp);
                mutex_unlock(&local->sdp_lock);
 
                return LLCP_WKS_NUM_SAP + ssap;
 
        } else if (sock->ssap != 0) {
                if (sock->ssap < LLCP_WKS_NUM_SAP) {
-                       if (!(local->local_wks & BIT(sock->ssap))) {
-                               set_bit(BIT(sock->ssap), &local->local_wks);
+                       if (!test_bit(sock->ssap, &local->local_wks)) {
+                               set_bit(sock->ssap, &local->local_wks);
                                mutex_unlock(&local->sdp_lock);
 
                                return sock->ssap;
                        }
 
                } else if (sock->ssap < LLCP_SDP_NUM_SAP) {
-                       if (!(local->local_sdp &
-                               BIT(sock->ssap - LLCP_WKS_NUM_SAP))) {
-                               set_bit(BIT(sock->ssap - LLCP_WKS_NUM_SAP),
-                                                       &local->local_sdp);
+                       if (!test_bit(sock->ssap - LLCP_WKS_NUM_SAP,
+                                     &local->local_sdp)) {
+                               set_bit(sock->ssap - LLCP_WKS_NUM_SAP,
+                                       &local->local_sdp);
                                mutex_unlock(&local->sdp_lock);
 
                                return sock->ssap;
@@ -238,7 +255,7 @@ u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local)
                return LLCP_SAP_MAX;
        }
 
-       set_bit(BIT(local_ssap), &local->local_sap);
+       set_bit(local_ssap, &local->local_sap);
 
        mutex_unlock(&local->sdp_lock);
 
@@ -265,12 +282,12 @@ void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap)
 
        mutex_lock(&local->sdp_lock);
 
-       clear_bit(1 << local_ssap, sdp);
+       clear_bit(local_ssap, sdp);
 
        mutex_unlock(&local->sdp_lock);
 }
 
-u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *general_bytes_len)
+u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len)
 {
        struct nfc_llcp_local *local;
 
@@ -294,7 +311,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
 
        version = LLCP_VERSION_11;
        version_tlv = nfc_llcp_build_tlv(LLCP_TLV_VERSION, &version,
-                                                       1, &version_length);
+                                        1, &version_length);
        gb_len += version_length;
 
        /* 1500 ms */
@@ -304,7 +321,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
 
        pr_debug("Local wks 0x%lx\n", local->local_wks);
        wks_tlv = nfc_llcp_build_tlv(LLCP_TLV_WKS, (u8 *)&local->local_wks, 2,
-                                                               &wks_length);
+                                    &wks_length);
        gb_len += wks_length;
 
        gb_len += ARRAY_SIZE(llcp_magic);
@@ -349,8 +366,7 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
        memcpy(local->remote_gb, gb, gb_len);
        local->remote_gb_len = gb_len;
 
-       if (local->remote_gb == NULL ||
-                       local->remote_gb_len == 0)
+       if (local->remote_gb == NULL || local->remote_gb_len == 0)
                return -ENODEV;
 
        if (memcmp(local->remote_gb, llcp_magic, 3)) {
@@ -359,26 +375,27 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
        }
 
        return nfc_llcp_parse_tlv(local,
-                       &local->remote_gb[3], local->remote_gb_len - 3);
+                                 &local->remote_gb[3],
+                                 local->remote_gb_len - 3);
 }
 
 static void nfc_llcp_tx_work(struct work_struct *work)
 {
        struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
-                                                       tx_work);
+                                                   tx_work);
        struct sk_buff *skb;
 
        skb = skb_dequeue(&local->tx_queue);
        if (skb != NULL) {
                pr_debug("Sending pending skb\n");
                nfc_data_exchange(local->dev, local->target_idx,
-                                       skb, nfc_llcp_recv, local);
+                                 skb, nfc_llcp_recv, local);
        } else {
                nfc_llcp_send_symm(local->dev);
        }
 
        mod_timer(&local->link_timer,
-                       jiffies + msecs_to_jiffies(local->remote_lto));
+                 jiffies + msecs_to_jiffies(local->remote_lto));
 }
 
 static u8 nfc_llcp_dsap(struct sk_buff *pdu)
@@ -408,13 +425,13 @@ static u8 nfc_llcp_nr(struct sk_buff *pdu)
 
 static void nfc_llcp_set_nrns(struct nfc_llcp_sock *sock, struct sk_buff *pdu)
 {
-       pdu->data[2] = (sock->send_n << 4) | ((sock->recv_n - 1) % 16);
+       pdu->data[2] = (sock->send_n << 4) | (sock->recv_n % 16);
        sock->send_n = (sock->send_n + 1) % 16;
        sock->recv_ack_n = (sock->recv_n - 1) % 16;
 }
 
 static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local,
-                                               u8 ssap, u8 dsap)
+                                              u8 ssap, u8 dsap)
 {
        struct nfc_llcp_sock *sock, *llcp_sock, *n;
 
@@ -438,7 +455,7 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local,
 
        list_for_each_entry_safe(llcp_sock, n, &sock->list, list) {
                pr_debug("llcp_sock %p sk %p dsap %d\n", llcp_sock,
-                               &llcp_sock->sk, llcp_sock->dsap);
+                        &llcp_sock->sk, llcp_sock->dsap);
                if (llcp_sock->dsap == dsap) {
                        sock_hold(&llcp_sock->sk);
                        mutex_unlock(&local->socket_lock);
@@ -482,7 +499,7 @@ static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len)
 }
 
 static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
-                               struct sk_buff *skb)
+                                 struct sk_buff *skb)
 {
        struct sock *new_sk, *parent;
        struct nfc_llcp_sock *sock, *new_sock;
@@ -494,7 +511,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
        pr_debug("%d %d\n", dsap, ssap);
 
        nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE],
-                               skb->len - LLCP_HEADER_SIZE);
+                          skb->len - LLCP_HEADER_SIZE);
 
        if (dsap != LLCP_SAP_SDP) {
                bound_sap = dsap;
@@ -513,7 +530,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
                lock_sock(&sock->sk);
 
                if (sock->dsap == LLCP_SAP_SDP &&
-                               sock->sk.sk_state == LLCP_LISTEN)
+                   sock->sk.sk_state == LLCP_LISTEN)
                        goto enqueue;
        } else {
                u8 *sn;
@@ -529,23 +546,23 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
 
                mutex_lock(&local->socket_lock);
                for (bound_sap = 0; bound_sap < LLCP_LOCAL_SAP_OFFSET;
-                                                               bound_sap++) {
+                    bound_sap++) {
                        sock = local->sockets[bound_sap];
                        if (sock == NULL)
                                continue;
 
                        if (sock->service_name == NULL ||
-                               sock->service_name_len == 0)
+                           sock->service_name_len == 0)
                                        continue;
 
                        if (sock->service_name_len != sn_len)
                                continue;
 
                        if (sock->dsap == LLCP_SAP_SDP &&
-                                       sock->sk.sk_state == LLCP_LISTEN &&
-                                       !memcmp(sn, sock->service_name, sn_len)) {
+                           sock->sk.sk_state == LLCP_LISTEN &&
+                           !memcmp(sn, sock->service_name, sn_len)) {
                                pr_debug("Found service name at SAP %d\n",
-                                                               bound_sap);
+                                        bound_sap);
                                sock_hold(&sock->sk);
                                mutex_unlock(&local->socket_lock);
 
@@ -570,8 +587,7 @@ enqueue:
                goto fail;
        }
 
-       new_sk = nfc_llcp_sock_alloc(NULL, parent->sk_type,
-                                    GFP_ATOMIC);
+       new_sk = nfc_llcp_sock_alloc(NULL, parent->sk_type, GFP_ATOMIC);
        if (new_sk == NULL) {
                reason = LLCP_DM_REJ;
                release_sock(&sock->sk);
@@ -616,8 +632,39 @@ fail:
 
 }
 
+int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock)
+{
+       int nr_frames = 0;
+       struct nfc_llcp_local *local = sock->local;
+
+       pr_debug("Remote ready %d tx queue len %d remote rw %d",
+                sock->remote_ready, skb_queue_len(&sock->tx_pending_queue),
+                local->remote_rw);
+
+       /* Try to queue some I frames for transmission */
+       while (sock->remote_ready &&
+              skb_queue_len(&sock->tx_pending_queue) < local->remote_rw) {
+               struct sk_buff *pdu, *pending_pdu;
+
+               pdu = skb_dequeue(&sock->tx_queue);
+               if (pdu == NULL)
+                       break;
+
+               /* Update N(S)/N(R) */
+               nfc_llcp_set_nrns(sock, pdu);
+
+               pending_pdu = skb_clone(pdu, GFP_KERNEL);
+
+               skb_queue_tail(&local->tx_queue, pdu);
+               skb_queue_tail(&sock->tx_pending_queue, pending_pdu);
+               nr_frames++;
+       }
+
+       return nr_frames;
+}
+
 static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
-                               struct sk_buff *skb)
+                              struct sk_buff *skb)
 {
        struct nfc_llcp_sock *llcp_sock;
        struct sock *sk;
@@ -644,15 +691,15 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
                nfc_llcp_sock_put(llcp_sock);
        }
 
-       if (ns == llcp_sock->recv_n)
-               llcp_sock->recv_n = (llcp_sock->recv_n + 1) % 16;
-       else
-               pr_err("Received out of sequence I PDU\n");
-
        /* Pass the payload upstream */
        if (ptype == LLCP_PDU_I) {
                pr_debug("I frame, queueing on %p\n", &llcp_sock->sk);
 
+               if (ns == llcp_sock->recv_n)
+                       llcp_sock->recv_n = (llcp_sock->recv_n + 1) % 16;
+               else
+                       pr_err("Received out of sequence I PDU\n");
+
                skb_pull(skb, LLCP_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
                if (sock_queue_rcv_skb(&llcp_sock->sk, skb)) {
                        pr_err("receive queue is full\n");
@@ -673,30 +720,20 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
                        }
        }
 
-       /* Queue some I frames for transmission */
-       while (llcp_sock->remote_ready &&
-               skb_queue_len(&llcp_sock->tx_pending_queue) <= local->remote_rw) {
-               struct sk_buff *pdu, *pending_pdu;
-
-               pdu = skb_dequeue(&llcp_sock->tx_queue);
-               if (pdu == NULL)
-                       break;
-
-               /* Update N(S)/N(R) */
-               nfc_llcp_set_nrns(llcp_sock, pdu);
+       if (ptype == LLCP_PDU_RR)
+               llcp_sock->remote_ready = true;
+       else if (ptype == LLCP_PDU_RNR)
+               llcp_sock->remote_ready = false;
 
-               pending_pdu = skb_clone(pdu, GFP_KERNEL);
-
-               skb_queue_tail(&local->tx_queue, pdu);
-               skb_queue_tail(&llcp_sock->tx_pending_queue, pending_pdu);
-       }
+       if (nfc_llcp_queue_i_frames(llcp_sock) == 0)
+               nfc_llcp_send_rr(llcp_sock);
 
        release_sock(sk);
        nfc_llcp_sock_put(llcp_sock);
 }
 
 static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
-                               struct sk_buff *skb)
+                              struct sk_buff *skb)
 {
        struct nfc_llcp_sock *llcp_sock;
        struct sock *sk;
@@ -718,7 +755,6 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
                nfc_llcp_sock_put(llcp_sock);
        }
 
-
        if (sk->sk_state == LLCP_CONNECTED) {
                nfc_put_device(local->dev);
                sk->sk_state = LLCP_CLOSED;
@@ -731,13 +767,11 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
        nfc_llcp_sock_put(llcp_sock);
 }
 
-static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
-                               struct sk_buff *skb)
+static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb)
 {
        struct nfc_llcp_sock *llcp_sock;
        u8 dsap, ssap;
 
-
        dsap = nfc_llcp_dsap(skb);
        ssap = nfc_llcp_ssap(skb);
 
@@ -756,7 +790,7 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
        llcp_sock->dsap = ssap;
 
        nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE],
-                               skb->len - LLCP_HEADER_SIZE);
+                          skb->len - LLCP_HEADER_SIZE);
 
        nfc_llcp_sock_put(llcp_sock);
 }
@@ -764,7 +798,7 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
 static void nfc_llcp_rx_work(struct work_struct *work)
 {
        struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
-                                                               rx_work);
+                                                   rx_work);
        u8 dsap, ssap, ptype;
        struct sk_buff *skb;
 
@@ -802,6 +836,7 @@ static void nfc_llcp_rx_work(struct work_struct *work)
 
        case LLCP_PDU_I:
        case LLCP_PDU_RR:
+       case LLCP_PDU_RNR:
                pr_debug("I frame\n");
                nfc_llcp_recv_hdlc(local, skb);
                break;
@@ -821,7 +856,7 @@ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err)
 
        pr_debug("Received an LLCP PDU\n");
        if (err < 0) {
-               pr_err("err %d", err);
+               pr_err("err %d\n", err);
                return;
        }
 
@@ -840,6 +875,8 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
        if (local == NULL)
                return;
 
+       nfc_llcp_clear_sdp(local);
+
        /* Close and purge all existing sockets */
        nfc_llcp_socket_release(local);
 }
@@ -865,7 +902,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
                queue_work(local->tx_wq, &local->tx_work);
        } else {
                mod_timer(&local->link_timer,
-                       jiffies + msecs_to_jiffies(local->remote_lto));
+                         jiffies + msecs_to_jiffies(local->remote_lto));
        }
 }
 
@@ -891,8 +928,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
        skb_queue_head_init(&local->tx_queue);
        INIT_WORK(&local->tx_work, nfc_llcp_tx_work);
        snprintf(name, sizeof(name), "%s_llcp_tx_wq", dev_name(dev));
-       local->tx_wq = alloc_workqueue(name,
-                       WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+       local->tx_wq =
+               alloc_workqueue(name,
+                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
+                               1);
        if (local->tx_wq == NULL) {
                err = -ENOMEM;
                goto err_local;
@@ -901,8 +940,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
        local->rx_pending = NULL;
        INIT_WORK(&local->rx_work, nfc_llcp_rx_work);
        snprintf(name, sizeof(name), "%s_llcp_rx_wq", dev_name(dev));
-       local->rx_wq = alloc_workqueue(name,
-                       WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+       local->rx_wq =
+               alloc_workqueue(name,
+                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
+                               1);
        if (local->rx_wq == NULL) {
                err = -ENOMEM;
                goto err_tx_wq;
@@ -910,8 +951,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
 
        INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work);
        snprintf(name, sizeof(name), "%s_llcp_timeout_wq", dev_name(dev));
-       local->timeout_wq = alloc_workqueue(name,
-                       WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+       local->timeout_wq =
+               alloc_workqueue(name,
+                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
+                               1);
        if (local->timeout_wq == NULL) {
                err = -ENOMEM;
                goto err_rx_wq;
index 0ad2e3361584a074ab2c0a09b489d1056889f247..50680ce5ae4396435552936f22cf3a8d17e26a25 100644 (file)
@@ -28,6 +28,10 @@ enum llcp_state {
 #define LLCP_DEFAULT_RW  1
 #define LLCP_DEFAULT_MIU 128
 
+#define LLCP_MAX_LTO  0xff
+#define LLCP_MAX_RW   15
+#define LLCP_MAX_MIUX 0x7ff
+
 #define LLCP_WKS_NUM_SAP   16
 #define LLCP_SDP_NUM_SAP   16
 #define LLCP_LOCAL_NUM_SAP 32
@@ -162,9 +166,10 @@ struct nfc_llcp_sock {
 
 struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
 u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
-                               struct nfc_llcp_sock *sock);
+                        struct nfc_llcp_sock *sock);
 u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local);
 void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap);
+int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock);
 
 /* Sock API */
 struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp);
@@ -175,7 +180,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *sk, struct socket *newsock);
 
 /* TLV API */
 int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
-                       u8 *tlv_array, u16 tlv_array_len);
+                      u8 *tlv_array, u16 tlv_array_len);
 
 /* Commands API */
 void nfc_llcp_recv(void *data, struct sk_buff *skb, int err);
@@ -187,6 +192,9 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock);
 int nfc_llcp_send_cc(struct nfc_llcp_sock *sock);
 int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason);
 int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock);
+int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
+                         struct msghdr *msg, size_t len);
+int nfc_llcp_send_rr(struct nfc_llcp_sock *sock);
 
 /* Socket API */
 int __init nfc_llcp_sock_init(void);
index f738ccd535f1c984f3a741ac32c43acc6bc3c7c5..c13e02ebdef9b08e5c995f5cbb5a671db42d8e3c 100644 (file)
@@ -78,9 +78,11 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
        llcp_sock->local = local;
        llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
        llcp_sock->service_name_len = min_t(unsigned int,
-                       llcp_addr.service_name_len, NFC_LLCP_MAX_SERVICE_NAME);
+                                           llcp_addr.service_name_len,
+                                           NFC_LLCP_MAX_SERVICE_NAME);
        llcp_sock->service_name = kmemdup(llcp_addr.service_name,
-                               llcp_sock->service_name_len, GFP_KERNEL);
+                                         llcp_sock->service_name_len,
+                                         GFP_KERNEL);
 
        llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock);
        if (llcp_sock->ssap == LLCP_MAX_SAP)
@@ -110,7 +112,7 @@ static int llcp_sock_listen(struct socket *sock, int backlog)
        lock_sock(sk);
 
        if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
-                       || sk->sk_state != LLCP_BOUND) {
+           || sk->sk_state != LLCP_BOUND) {
                ret = -EBADFD;
                goto error;
        }
@@ -149,13 +151,13 @@ void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk)
        sock_hold(sk);
 
        list_add_tail(&llcp_sock->accept_queue,
-                       &llcp_sock_parent->accept_queue);
+                     &llcp_sock_parent->accept_queue);
        llcp_sock->parent = parent;
        sk_acceptq_added(parent);
 }
 
 struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
-                                       struct socket *newsock)
+                                    struct socket *newsock)
 {
        struct nfc_llcp_sock *lsk, *n, *llcp_parent;
        struct sock *sk;
@@ -163,7 +165,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
        llcp_parent = nfc_llcp_sock(parent);
 
        list_for_each_entry_safe(lsk, n, &llcp_parent->accept_queue,
-                                                       accept_queue) {
+                                accept_queue) {
                sk = &lsk->sk;
                lock_sock(sk);
 
@@ -192,7 +194,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
 }
 
 static int llcp_sock_accept(struct socket *sock, struct socket *newsock,
-                                                               int flags)
+                           int flags)
 {
        DECLARE_WAITQUEUE(wait, current);
        struct sock *sk = sock->sk, *new_sk;
@@ -248,7 +250,7 @@ error:
 static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr,
                             int *len, int peer)
 {
-       struct sockaddr_nfc_llcp *llcp_addr = (struct sockaddr_nfc_llcp *) addr;
+       struct sockaddr_nfc_llcp *llcp_addr = (struct sockaddr_nfc_llcp *)addr;
        struct sock *sk = sock->sk;
        struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
 
@@ -262,7 +264,7 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr,
        llcp_addr->ssap = llcp_sock->ssap;
        llcp_addr->service_name_len = llcp_sock->service_name_len;
        memcpy(llcp_addr->service_name, llcp_sock->service_name,
-                                       llcp_addr->service_name_len);
+              llcp_addr->service_name_len);
 
        return 0;
 }
@@ -275,7 +277,7 @@ static inline unsigned int llcp_accept_poll(struct sock *parent)
        parent_sock = nfc_llcp_sock(parent);
 
        list_for_each_entry_safe(llcp_sock, n, &parent_sock->accept_queue,
-                                                               accept_queue) {
+                                accept_queue) {
                sk = &llcp_sock->sk;
 
                if (sk->sk_state == LLCP_CONNECTED)
@@ -286,7 +288,7 @@ static inline unsigned int llcp_accept_poll(struct sock *parent)
 }
 
 static unsigned int llcp_sock_poll(struct file *file, struct socket *sock,
-                                                       poll_table *wait)
+                                  poll_table *wait)
 {
        struct sock *sk = sock->sk;
        unsigned int mask = 0;
@@ -315,6 +317,7 @@ static int llcp_sock_release(struct socket *sock)
        struct sock *sk = sock->sk;
        struct nfc_llcp_local *local;
        struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
+       int err = 0;
 
        if (!sk)
                return 0;
@@ -322,25 +325,17 @@ static int llcp_sock_release(struct socket *sock)
        pr_debug("%p\n", sk);
 
        local = llcp_sock->local;
-       if (local == NULL)
-               return -ENODEV;
+       if (local == NULL) {
+               err = -ENODEV;
+               goto out;
+       }
 
        mutex_lock(&local->socket_lock);
 
-       if (llcp_sock == local->sockets[llcp_sock->ssap]) {
+       if (llcp_sock == local->sockets[llcp_sock->ssap])
                local->sockets[llcp_sock->ssap] = NULL;
-       } else {
-               struct nfc_llcp_sock *parent, *s, *n;
-
-               parent = local->sockets[llcp_sock->ssap];
-
-               list_for_each_entry_safe(s, n, &parent->list, list)
-                       if (llcp_sock == s) {
-                               list_del(&s->list);
-                               break;
-                       }
-
-       }
+       else
+               list_del_init(&llcp_sock->list);
 
        mutex_unlock(&local->socket_lock);
 
@@ -355,7 +350,7 @@ static int llcp_sock_release(struct socket *sock)
                struct sock *accept_sk;
 
                list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue,
-                                                               accept_queue) {
+                                        accept_queue) {
                        accept_sk = &lsk->sk;
                        lock_sock(accept_sk);
 
@@ -364,31 +359,27 @@ static int llcp_sock_release(struct socket *sock)
 
                        release_sock(accept_sk);
 
-                       sock_set_flag(sk, SOCK_DEAD);
                        sock_orphan(accept_sk);
-                       sock_put(accept_sk);
                }
        }
 
        /* Freeing the SAP */
        if ((sk->sk_state == LLCP_CONNECTED
-                       && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) ||
-           sk->sk_state == LLCP_BOUND ||
-           sk->sk_state == LLCP_LISTEN)
+            && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) ||
+           sk->sk_state == LLCP_BOUND || sk->sk_state == LLCP_LISTEN)
                nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap);
 
-       sock_set_flag(sk, SOCK_DEAD);
-
        release_sock(sk);
 
+out:
        sock_orphan(sk);
        sock_put(sk);
 
-       return 0;
+       return err;
 }
 
 static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
-                                                       int len, int flags)
+                            int len, int flags)
 {
        struct sock *sk = sock->sk;
        struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
@@ -400,7 +391,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
        pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags);
 
        if (!addr || len < sizeof(struct sockaddr_nfc) ||
-                       addr->sa_family != AF_NFC) {
+           addr->sa_family != AF_NFC) {
                pr_err("Invalid socket\n");
                return -EINVAL;
        }
@@ -411,7 +402,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
        }
 
        pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", addr->dev_idx,
-                                       addr->target_idx, addr->nfc_protocol);
+                addr->target_idx, addr->nfc_protocol);
 
        lock_sock(sk);
 
@@ -441,7 +432,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
        device_unlock(&dev->dev);
 
        if (local->rf_mode == NFC_RF_INITIATOR &&
-                       addr->target_idx != local->target_idx) {
+           addr->target_idx != local->target_idx) {
                ret = -ENOLINK;
                goto put_dev;
        }
@@ -459,9 +450,11 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
                llcp_sock->dsap = LLCP_SAP_SDP;
        llcp_sock->nfc_protocol = addr->nfc_protocol;
        llcp_sock->service_name_len = min_t(unsigned int,
-                       addr->service_name_len, NFC_LLCP_MAX_SERVICE_NAME);
+                                           addr->service_name_len,
+                                           NFC_LLCP_MAX_SERVICE_NAME);
        llcp_sock->service_name = kmemdup(addr->service_name,
-                                llcp_sock->service_name_len, GFP_KERNEL);
+                                         llcp_sock->service_name_len,
+                                         GFP_KERNEL);
 
        local->sockets[llcp_sock->ssap] = llcp_sock;
 
@@ -482,6 +475,34 @@ error:
        return ret;
 }
 
+static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
+                            struct msghdr *msg, size_t len)
+{
+       struct sock *sk = sock->sk;
+       struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
+       int ret;
+
+       pr_debug("sock %p sk %p", sock, sk);
+
+       ret = sock_error(sk);
+       if (ret)
+               return ret;
+
+       if (msg->msg_flags & MSG_OOB)
+               return -EOPNOTSUPP;
+
+       lock_sock(sk);
+
+       if (sk->sk_state != LLCP_CONNECTED) {
+               release_sock(sk);
+               return -ENOTCONN;
+       }
+
+       release_sock(sk);
+
+       return nfc_llcp_send_i_frame(llcp_sock, msg, len);
+}
+
 static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                             struct msghdr *msg, size_t len, int flags)
 {
@@ -496,7 +517,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        lock_sock(sk);
 
        if (sk->sk_state == LLCP_CLOSED &&
-                       skb_queue_empty(&sk->sk_receive_queue)) {
+           skb_queue_empty(&sk->sk_receive_queue)) {
                release_sock(sk);
                return 0;
        }
@@ -509,7 +530,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        skb = skb_recv_datagram(sk, flags, noblock, &err);
        if (!skb) {
                pr_err("Recv datagram failed state %d %d %d",
-                               sk->sk_state, err, sock_error(sk));
+                      sk->sk_state, err, sock_error(sk));
 
                if (sk->sk_shutdown & RCV_SHUTDOWN)
                        return 0;
@@ -517,7 +538,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                return err;
        }
 
-       rlen   = skb->len;              /* real length of skb */
+       rlen = skb->len;                /* real length of skb */
        copied = min_t(unsigned int, rlen, len);
 
        cskb = skb;
@@ -567,7 +588,7 @@ static const struct proto_ops llcp_sock_ops = {
        .shutdown       = sock_no_shutdown,
        .setsockopt     = sock_no_setsockopt,
        .getsockopt     = sock_no_getsockopt,
-       .sendmsg        = sock_no_sendmsg,
+       .sendmsg        = llcp_sock_sendmsg,
        .recvmsg        = llcp_sock_recvmsg,
        .mmap           = sock_no_mmap,
 };
@@ -627,6 +648,8 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp)
 
 void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
 {
+       struct nfc_llcp_local *local = sock->local;
+
        kfree(sock->service_name);
 
        skb_queue_purge(&sock->tx_queue);
@@ -635,11 +658,16 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
 
        list_del_init(&sock->accept_queue);
 
+       if (local != NULL && sock == local->sockets[sock->ssap])
+               local->sockets[sock->ssap] = NULL;
+       else
+               list_del_init(&sock->list);
+
        sock->parent = NULL;
 }
 
 static int llcp_sock_create(struct net *net, struct socket *sock,
-                               const struct nfc_protocol *nfc_proto)
+                           const struct nfc_protocol *nfc_proto)
 {
        struct sock *sk;
 
index 7650139a1a0538da0a6857b21e4460e8f2f47a01..9ec065bb9ee1e78b96321a8f2f1e5c6827dd15bc 100644 (file)
@@ -66,9 +66,8 @@ static void nci_req_cancel(struct nci_dev *ndev, int err)
 
 /* Execute request and wait for completion. */
 static int __nci_request(struct nci_dev *ndev,
-       void (*req)(struct nci_dev *ndev, unsigned long opt),
-       unsigned long opt,
-       __u32 timeout)
+                        void (*req)(struct nci_dev *ndev, unsigned long opt),
+                        unsigned long opt, __u32 timeout)
 {
        int rc = 0;
        long completion_rc;
@@ -77,9 +76,9 @@ static int __nci_request(struct nci_dev *ndev,
 
        init_completion(&ndev->req_completion);
        req(ndev, opt);
-       completion_rc = wait_for_completion_interruptible_timeout(
-                                                       &ndev->req_completion,
-                                                       timeout);
+       completion_rc =
+               wait_for_completion_interruptible_timeout(&ndev->req_completion,
+                                                         timeout);
 
        pr_debug("wait_for_completion return %ld\n", completion_rc);
 
@@ -110,8 +109,9 @@ static int __nci_request(struct nci_dev *ndev,
 }
 
 static inline int nci_request(struct nci_dev *ndev,
-               void (*req)(struct nci_dev *ndev, unsigned long opt),
-               unsigned long opt, __u32 timeout)
+                             void (*req)(struct nci_dev *ndev,
+                                         unsigned long opt),
+                             unsigned long opt, __u32 timeout)
 {
        int rc;
 
@@ -152,14 +152,14 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
        /* by default mapping is set to NCI_RF_INTERFACE_FRAME */
        for (i = 0; i < ndev->num_supported_rf_interfaces; i++) {
                if (ndev->supported_rf_interfaces[i] ==
-                       NCI_RF_INTERFACE_ISO_DEP) {
+                   NCI_RF_INTERFACE_ISO_DEP) {
                        cfg[*num].rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
                        cfg[*num].mode = NCI_DISC_MAP_MODE_POLL |
                                NCI_DISC_MAP_MODE_LISTEN;
                        cfg[*num].rf_interface = NCI_RF_INTERFACE_ISO_DEP;
                        (*num)++;
                } else if (ndev->supported_rf_interfaces[i] ==
-                       NCI_RF_INTERFACE_NFC_DEP) {
+                          NCI_RF_INTERFACE_NFC_DEP) {
                        cfg[*num].rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
                        cfg[*num].mode = NCI_DISC_MAP_MODE_POLL |
                                NCI_DISC_MAP_MODE_LISTEN;
@@ -172,8 +172,7 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
        }
 
        nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_MAP_CMD,
-               (1 + ((*num)*sizeof(struct disc_map_config))),
-               &cmd);
+                    (1 + ((*num) * sizeof(struct disc_map_config))), &cmd);
 }
 
 static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
@@ -184,36 +183,68 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
        cmd.num_disc_configs = 0;
 
        if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
-               (protocols & NFC_PROTO_JEWEL_MASK
-               || protocols & NFC_PROTO_MIFARE_MASK
-               || protocols & NFC_PROTO_ISO14443_MASK
-               || protocols & NFC_PROTO_NFC_DEP_MASK)) {
+           (protocols & NFC_PROTO_JEWEL_MASK
+            || protocols & NFC_PROTO_MIFARE_MASK
+            || protocols & NFC_PROTO_ISO14443_MASK
+            || protocols & NFC_PROTO_NFC_DEP_MASK)) {
                cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
-               NCI_NFC_A_PASSIVE_POLL_MODE;
+                       NCI_NFC_A_PASSIVE_POLL_MODE;
                cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
                cmd.num_disc_configs++;
        }
 
        if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
-               (protocols & NFC_PROTO_ISO14443_MASK)) {
+           (protocols & NFC_PROTO_ISO14443_MASK)) {
                cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
-               NCI_NFC_B_PASSIVE_POLL_MODE;
+                       NCI_NFC_B_PASSIVE_POLL_MODE;
                cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
                cmd.num_disc_configs++;
        }
 
        if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
-               (protocols & NFC_PROTO_FELICA_MASK
-               || protocols & NFC_PROTO_NFC_DEP_MASK)) {
+           (protocols & NFC_PROTO_FELICA_MASK
+            || protocols & NFC_PROTO_NFC_DEP_MASK)) {
                cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
-               NCI_NFC_F_PASSIVE_POLL_MODE;
+                       NCI_NFC_F_PASSIVE_POLL_MODE;
                cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
                cmd.num_disc_configs++;
        }
 
        nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_CMD,
-               (1 + (cmd.num_disc_configs*sizeof(struct disc_config))),
-               &cmd);
+                    (1 + (cmd.num_disc_configs * sizeof(struct disc_config))),
+                    &cmd);
+}
+
+struct nci_rf_discover_select_param {
+       __u8    rf_discovery_id;
+       __u8    rf_protocol;
+};
+
+static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt)
+{
+       struct nci_rf_discover_select_param *param =
+               (struct nci_rf_discover_select_param *)opt;
+       struct nci_rf_discover_select_cmd cmd;
+
+       cmd.rf_discovery_id = param->rf_discovery_id;
+       cmd.rf_protocol = param->rf_protocol;
+
+       switch (cmd.rf_protocol) {
+       case NCI_RF_PROTOCOL_ISO_DEP:
+               cmd.rf_interface = NCI_RF_INTERFACE_ISO_DEP;
+               break;
+
+       case NCI_RF_PROTOCOL_NFC_DEP:
+               cmd.rf_interface = NCI_RF_INTERFACE_NFC_DEP;
+               break;
+
+       default:
+               cmd.rf_interface = NCI_RF_INTERFACE_FRAME;
+               break;
+       }
+
+       nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_SELECT_CMD,
+                    sizeof(struct nci_rf_discover_select_cmd), &cmd);
 }
 
 static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt)
@@ -223,8 +254,7 @@ static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt)
        cmd.type = NCI_DEACTIVATE_TYPE_IDLE_MODE;
 
        nci_send_cmd(ndev, NCI_OP_RF_DEACTIVATE_CMD,
-                       sizeof(struct nci_rf_deactivate_cmd),
-                       &cmd);
+                    sizeof(struct nci_rf_deactivate_cmd), &cmd);
 }
 
 static int nci_open_device(struct nci_dev *ndev)
@@ -248,22 +278,24 @@ static int nci_open_device(struct nci_dev *ndev)
        set_bit(NCI_INIT, &ndev->flags);
 
        rc = __nci_request(ndev, nci_reset_req, 0,
-                               msecs_to_jiffies(NCI_RESET_TIMEOUT));
+                          msecs_to_jiffies(NCI_RESET_TIMEOUT));
 
        if (!rc) {
                rc = __nci_request(ndev, nci_init_req, 0,
-                               msecs_to_jiffies(NCI_INIT_TIMEOUT));
+                                  msecs_to_jiffies(NCI_INIT_TIMEOUT));
        }
 
        if (!rc) {
                rc = __nci_request(ndev, nci_init_complete_req, 0,
-                               msecs_to_jiffies(NCI_INIT_TIMEOUT));
+                                  msecs_to_jiffies(NCI_INIT_TIMEOUT));
        }
 
        clear_bit(NCI_INIT, &ndev->flags);
 
        if (!rc) {
                set_bit(NCI_UP, &ndev->flags);
+               nci_clear_target_list(ndev);
+               atomic_set(&ndev->state, NCI_IDLE);
        } else {
                /* Init failed, cleanup */
                skb_queue_purge(&ndev->cmd_q);
@@ -286,6 +318,7 @@ static int nci_close_device(struct nci_dev *ndev)
 
        if (!test_and_clear_bit(NCI_UP, &ndev->flags)) {
                del_timer_sync(&ndev->cmd_timer);
+               del_timer_sync(&ndev->data_timer);
                mutex_unlock(&ndev->req_lock);
                return 0;
        }
@@ -304,7 +337,7 @@ static int nci_close_device(struct nci_dev *ndev)
 
        set_bit(NCI_INIT, &ndev->flags);
        __nci_request(ndev, nci_reset_req, 0,
-                               msecs_to_jiffies(NCI_RESET_TIMEOUT));
+                     msecs_to_jiffies(NCI_RESET_TIMEOUT));
        clear_bit(NCI_INIT, &ndev->flags);
 
        /* Flush cmd wq */
@@ -331,6 +364,15 @@ static void nci_cmd_timer(unsigned long arg)
        queue_work(ndev->cmd_wq, &ndev->cmd_work);
 }
 
+/* NCI data exchange timer function */
+static void nci_data_timer(unsigned long arg)
+{
+       struct nci_dev *ndev = (void *) arg;
+
+       set_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
+       queue_work(ndev->rx_wq, &ndev->rx_work);
+}
+
 static int nci_dev_up(struct nfc_dev *nfc_dev)
 {
        struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
@@ -350,7 +392,8 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols)
        struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
        int rc;
 
-       if (test_bit(NCI_DISCOVERY, &ndev->flags)) {
+       if ((atomic_read(&ndev->state) == NCI_DISCOVERY) ||
+           (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) {
                pr_err("unable to start poll, since poll is already active\n");
                return -EBUSY;
        }
@@ -360,17 +403,18 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols)
                return -EBUSY;
        }
 
-       if (test_bit(NCI_POLL_ACTIVE, &ndev->flags)) {
-               pr_debug("target is active, implicitly deactivate...\n");
+       if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) ||
+           (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) {
+               pr_debug("target active or w4 select, implicitly deactivate\n");
 
                rc = nci_request(ndev, nci_rf_deactivate_req, 0,
-                       msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
+                                msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
                if (rc)
                        return -EBUSY;
        }
 
        rc = nci_request(ndev, nci_rf_discover_req, protocols,
-               msecs_to_jiffies(NCI_RF_DISC_TIMEOUT));
+                        msecs_to_jiffies(NCI_RF_DISC_TIMEOUT));
 
        if (!rc)
                ndev->poll_prots = protocols;
@@ -382,23 +426,29 @@ static void nci_stop_poll(struct nfc_dev *nfc_dev)
 {
        struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
 
-       if (!test_bit(NCI_DISCOVERY, &ndev->flags)) {
+       if ((atomic_read(&ndev->state) != NCI_DISCOVERY) &&
+           (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) {
                pr_err("unable to stop poll, since poll is not active\n");
                return;
        }
 
        nci_request(ndev, nci_rf_deactivate_req, 0,
-               msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
+                   msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
 }
 
 static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx,
-                               __u32 protocol)
+                              __u32 protocol)
 {
        struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
+       struct nci_rf_discover_select_param param;
+       struct nfc_target *target = NULL;
+       int i;
+       int rc = 0;
 
        pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol);
 
-       if (!test_bit(NCI_POLL_ACTIVE, &ndev->flags)) {
+       if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) &&
+           (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
                pr_err("there is no available target to activate\n");
                return -EINVAL;
        }
@@ -408,16 +458,47 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx,
                return -EBUSY;
        }
 
-       if (!(ndev->target_available_prots & (1 << protocol))) {
+       for (i = 0; i < ndev->n_targets; i++) {
+               if (ndev->targets[i].idx == target_idx) {
+                       target = &ndev->targets[i];
+                       break;
+               }
+       }
+
+       if (!target) {
+               pr_err("unable to find the selected target\n");
+               return -EINVAL;
+       }
+
+       if (!(target->supported_protocols & (1 << protocol))) {
                pr_err("target does not support the requested protocol 0x%x\n",
                       protocol);
                return -EINVAL;
        }
 
-       ndev->target_active_prot = protocol;
-       ndev->target_available_prots = 0;
+       if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) {
+               param.rf_discovery_id = target->idx;
 
-       return 0;
+               if (protocol == NFC_PROTO_JEWEL)
+                       param.rf_protocol = NCI_RF_PROTOCOL_T1T;
+               else if (protocol == NFC_PROTO_MIFARE)
+                       param.rf_protocol = NCI_RF_PROTOCOL_T2T;
+               else if (protocol == NFC_PROTO_FELICA)
+                       param.rf_protocol = NCI_RF_PROTOCOL_T3T;
+               else if (protocol == NFC_PROTO_ISO14443)
+                       param.rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
+               else
+                       param.rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
+
+               rc = nci_request(ndev, nci_rf_discover_select_req,
+                                (unsigned long)&param,
+                                msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT));
+       }
+
+       if (!rc)
+               ndev->target_active_prot = protocol;
+
+       return rc;
 }
 
 static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx)
@@ -433,16 +514,15 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx)
 
        ndev->target_active_prot = 0;
 
-       if (test_bit(NCI_POLL_ACTIVE, &ndev->flags)) {
+       if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) {
                nci_request(ndev, nci_rf_deactivate_req, 0,
-                       msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
+                           msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
        }
 }
 
 static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx,
-                                               struct sk_buff *skb,
-                                               data_exchange_cb_t cb,
-                                               void *cb_context)
+                            struct sk_buff *skb,
+                            data_exchange_cb_t cb, void *cb_context)
 {
        struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
        int rc;
@@ -487,9 +567,8 @@ static struct nfc_ops nci_nfc_ops = {
  * @supported_protocols: NFC protocols supported by the device
  */
 struct nci_dev *nci_allocate_device(struct nci_ops *ops,
-                                       __u32 supported_protocols,
-                                       int tx_headroom,
-                                       int tx_tailroom)
+                                   __u32 supported_protocols,
+                                   int tx_headroom, int tx_tailroom)
 {
        struct nci_dev *ndev;
 
@@ -510,9 +589,9 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops,
        ndev->tx_tailroom = tx_tailroom;
 
        ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops,
-                                               supported_protocols,
-                                               tx_headroom + NCI_DATA_HDR_SIZE,
-                                               tx_tailroom);
+                                           supported_protocols,
+                                           tx_headroom + NCI_DATA_HDR_SIZE,
+                                           tx_tailroom);
        if (!ndev->nfc_dev)
                goto free_exit;
 
@@ -584,7 +663,9 @@ int nci_register_device(struct nci_dev *ndev)
        skb_queue_head_init(&ndev->tx_q);
 
        setup_timer(&ndev->cmd_timer, nci_cmd_timer,
-                       (unsigned long) ndev);
+                   (unsigned long) ndev);
+       setup_timer(&ndev->data_timer, nci_data_timer,
+                   (unsigned long) ndev);
 
        mutex_init(&ndev->req_lock);
 
@@ -633,7 +714,7 @@ int nci_recv_frame(struct sk_buff *skb)
        pr_debug("len %d\n", skb->len);
 
        if (!ndev || (!test_bit(NCI_UP, &ndev->flags)
-               && !test_bit(NCI_INIT, &ndev->flags))) {
+                     && !test_bit(NCI_INIT, &ndev->flags))) {
                kfree_skb(skb);
                return -ENXIO;
        }
@@ -713,7 +794,7 @@ static void nci_tx_work(struct work_struct *work)
 
                /* Check if data flow control is used */
                if (atomic_read(&ndev->credits_cnt) !=
-                               NCI_DATA_FLOW_CONTROL_NOT_USED)
+                   NCI_DATA_FLOW_CONTROL_NOT_USED)
                        atomic_dec(&ndev->credits_cnt);
 
                pr_debug("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n",
@@ -722,6 +803,9 @@ static void nci_tx_work(struct work_struct *work)
                         nci_plen(skb->data));
 
                nci_send_frame(skb);
+
+               mod_timer(&ndev->data_timer,
+                         jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT));
        }
 }
 
@@ -753,6 +837,15 @@ static void nci_rx_work(struct work_struct *work)
                        break;
                }
        }
+
+       /* check if a data exchange timout has occurred */
+       if (test_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags)) {
+               /* complete the data exchange transaction, if exists */
+               if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
+                       nci_data_exchange_complete(ndev, NULL, -ETIMEDOUT);
+
+               clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
+       }
 }
 
 /* ----- NCI TX CMD worker thread ----- */
@@ -781,6 +874,6 @@ static void nci_cmd_work(struct work_struct *work)
                nci_send_frame(skb);
 
                mod_timer(&ndev->cmd_timer,
-                       jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT));
+                         jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT));
        }
 }
index e5756b30e6025ff6e90a6419824c6e9c378131bd..a0bc326308a56911c4f3b26358971df21ad65399 100644 (file)
@@ -35,8 +35,7 @@
 #include <linux/nfc.h>
 
 /* Complete data exchange transaction and forward skb to nfc core */
-void nci_data_exchange_complete(struct nci_dev *ndev,
-                               struct sk_buff *skb,
+void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,
                                int err)
 {
        data_exchange_cb_t cb = ndev->data_exchange_cb;
@@ -44,6 +43,10 @@ void nci_data_exchange_complete(struct nci_dev *ndev,
 
        pr_debug("len %d, err %d\n", skb ? skb->len : 0, err);
 
+       /* data exchange is complete, stop the data timer */
+       del_timer_sync(&ndev->data_timer);
+       clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
+
        if (cb) {
                ndev->data_exchange_cb = NULL;
                ndev->data_exchange_cb_context = 0;
@@ -63,9 +66,9 @@ void nci_data_exchange_complete(struct nci_dev *ndev,
 /* ----------------- NCI TX Data ----------------- */
 
 static inline void nci_push_data_hdr(struct nci_dev *ndev,
-                                       __u8 conn_id,
-                                       struct sk_buff *skb,
-                                       __u8 pbf)
+                                    __u8 conn_id,
+                                    struct sk_buff *skb,
+                                    __u8 pbf)
 {
        struct nci_data_hdr *hdr;
        int plen = skb->len;
@@ -82,8 +85,8 @@ static inline void nci_push_data_hdr(struct nci_dev *ndev,
 }
 
 static int nci_queue_tx_data_frags(struct nci_dev *ndev,
-                                       __u8 conn_id,
-                                       struct sk_buff *skb) {
+                                  __u8 conn_id,
+                                  struct sk_buff *skb) {
        int total_len = skb->len;
        unsigned char *data = skb->data;
        unsigned long flags;
@@ -101,8 +104,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev,
                        min_t(int, total_len, ndev->max_data_pkt_payload_size);
 
                skb_frag = nci_skb_alloc(ndev,
-                                       (NCI_DATA_HDR_SIZE + frag_len),
-                                       GFP_KERNEL);
+                                        (NCI_DATA_HDR_SIZE + frag_len),
+                                        GFP_KERNEL);
                if (skb_frag == NULL) {
                        rc = -ENOMEM;
                        goto free_exit;
@@ -114,7 +117,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev,
 
                /* second, set the header */
                nci_push_data_hdr(ndev, conn_id, skb_frag,
-               ((total_len == frag_len) ? (NCI_PBF_LAST) : (NCI_PBF_CONT)));
+                                 ((total_len == frag_len) ?
+                                  (NCI_PBF_LAST) : (NCI_PBF_CONT)));
 
                __skb_queue_tail(&frags_q, skb_frag);
 
@@ -182,8 +186,8 @@ exit:
 /* ----------------- NCI RX Data ----------------- */
 
 static void nci_add_rx_data_frag(struct nci_dev *ndev,
-                               struct sk_buff *skb,
-                               __u8 pbf)
+                                struct sk_buff *skb,
+                                __u8 pbf)
 {
        int reassembly_len;
        int err = 0;
@@ -207,8 +211,8 @@ static void nci_add_rx_data_frag(struct nci_dev *ndev,
 
                /* second, combine the two fragments */
                memcpy(skb_push(skb, reassembly_len),
-                               ndev->rx_data_reassembly->data,
-                               reassembly_len);
+                      ndev->rx_data_reassembly->data,
+                      reassembly_len);
 
                /* third, free old reassembly */
                kfree_skb(ndev->rx_data_reassembly);
index b16a8dc2afbe7fcd457787791f887092985021e5..2e3dee42196d064d0fdcf5ad7c6e4fe50945d57b 100644 (file)
@@ -40,7 +40,7 @@
 /* Handle NCI Notification packets */
 
 static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
-                                               struct sk_buff *skb)
+                                            struct sk_buff *skb)
 {
        struct nci_core_conn_credit_ntf *ntf = (void *) skb->data;
        int i;
@@ -62,7 +62,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
                if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) {
                        /* found static rf connection */
                        atomic_add(ntf->conn_entries[i].credits,
-                               &ndev->credits_cnt);
+                                  &ndev->credits_cnt);
                }
        }
 
@@ -71,6 +71,20 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
                queue_work(ndev->tx_wq, &ndev->tx_work);
 }
 
+static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev,
+                                             struct sk_buff *skb)
+{
+       __u8 status = skb->data[0];
+
+       pr_debug("status 0x%x\n", status);
+
+       if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) {
+               /* Activation failed, so complete the request
+                  (the state remains the same) */
+               nci_req_complete(ndev, status);
+       }
+}
+
 static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
                                                struct sk_buff *skb)
 {
@@ -86,12 +100,9 @@ static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
 }
 
 static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
-                       struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
+                       struct rf_tech_specific_params_nfca_poll *nfca_poll,
+                                                    __u8 *data)
 {
-       struct rf_tech_specific_params_nfca_poll *nfca_poll;
-
-       nfca_poll = &ntf->rf_tech_specific_params.nfca_poll;
-
        nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data));
        data += 2;
 
@@ -115,79 +126,266 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
        return data;
 }
 
+static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev,
+                       struct rf_tech_specific_params_nfcb_poll *nfcb_poll,
+                                                    __u8 *data)
+{
+       nfcb_poll->sensb_res_len = *data++;
+
+       pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len);
+
+       memcpy(nfcb_poll->sensb_res, data, nfcb_poll->sensb_res_len);
+       data += nfcb_poll->sensb_res_len;
+
+       return data;
+}
+
+static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev,
+                       struct rf_tech_specific_params_nfcf_poll *nfcf_poll,
+                                                    __u8 *data)
+{
+       nfcf_poll->bit_rate = *data++;
+       nfcf_poll->sensf_res_len = *data++;
+
+       pr_debug("bit_rate %d, sensf_res_len %d\n",
+                nfcf_poll->bit_rate, nfcf_poll->sensf_res_len);
+
+       memcpy(nfcf_poll->sensf_res, data, nfcf_poll->sensf_res_len);
+       data += nfcf_poll->sensf_res_len;
+
+       return data;
+}
+
+static int nci_add_new_protocol(struct nci_dev *ndev,
+                               struct nfc_target *target,
+                               __u8 rf_protocol,
+                               __u8 rf_tech_and_mode,
+                               void *params)
+{
+       struct rf_tech_specific_params_nfca_poll *nfca_poll;
+       struct rf_tech_specific_params_nfcb_poll *nfcb_poll;
+       struct rf_tech_specific_params_nfcf_poll *nfcf_poll;
+       __u32 protocol;
+
+       if (rf_protocol == NCI_RF_PROTOCOL_T2T)
+               protocol = NFC_PROTO_MIFARE_MASK;
+       else if (rf_protocol == NCI_RF_PROTOCOL_ISO_DEP)
+               protocol = NFC_PROTO_ISO14443_MASK;
+       else if (rf_protocol == NCI_RF_PROTOCOL_T3T)
+               protocol = NFC_PROTO_FELICA_MASK;
+       else
+               protocol = 0;
+
+       if (!(protocol & ndev->poll_prots)) {
+               pr_err("the target found does not have the desired protocol\n");
+               return -EPROTO;
+       }
+
+       if (rf_tech_and_mode == NCI_NFC_A_PASSIVE_POLL_MODE) {
+               nfca_poll = (struct rf_tech_specific_params_nfca_poll *)params;
+
+               target->sens_res = nfca_poll->sens_res;
+               target->sel_res = nfca_poll->sel_res;
+               target->nfcid1_len = nfca_poll->nfcid1_len;
+               if (target->nfcid1_len > 0) {
+                       memcpy(target->nfcid1, nfca_poll->nfcid1,
+                              target->nfcid1_len);
+               }
+       } else if (rf_tech_and_mode == NCI_NFC_B_PASSIVE_POLL_MODE) {
+               nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params;
+
+               target->sensb_res_len = nfcb_poll->sensb_res_len;
+               if (target->sensb_res_len > 0) {
+                       memcpy(target->sensb_res, nfcb_poll->sensb_res,
+                              target->sensb_res_len);
+               }
+       } else if (rf_tech_and_mode == NCI_NFC_F_PASSIVE_POLL_MODE) {
+               nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params;
+
+               target->sensf_res_len = nfcf_poll->sensf_res_len;
+               if (target->sensf_res_len > 0) {
+                       memcpy(target->sensf_res, nfcf_poll->sensf_res,
+                              target->sensf_res_len);
+               }
+       } else {
+               pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode);
+               return -EPROTO;
+       }
+
+       target->supported_protocols |= protocol;
+
+       pr_debug("protocol 0x%x\n", protocol);
+
+       return 0;
+}
+
+static void nci_add_new_target(struct nci_dev *ndev,
+                              struct nci_rf_discover_ntf *ntf)
+{
+       struct nfc_target *target;
+       int i, rc;
+
+       for (i = 0; i < ndev->n_targets; i++) {
+               target = &ndev->targets[i];
+               if (target->idx == ntf->rf_discovery_id) {
+                       /* This target already exists, add the new protocol */
+                       nci_add_new_protocol(ndev, target, ntf->rf_protocol,
+                                            ntf->rf_tech_and_mode,
+                                            &ntf->rf_tech_specific_params);
+                       return;
+               }
+       }
+
+       /* This is a new target, check if we've enough room */
+       if (ndev->n_targets == NCI_MAX_DISCOVERED_TARGETS) {
+               pr_debug("not enough room, ignoring new target...\n");
+               return;
+       }
+
+       target = &ndev->targets[ndev->n_targets];
+
+       rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
+                                 ntf->rf_tech_and_mode,
+                                 &ntf->rf_tech_specific_params);
+       if (!rc) {
+               target->idx = ntf->rf_discovery_id;
+               ndev->n_targets++;
+
+               pr_debug("target_idx %d, n_targets %d\n", target->idx,
+                        ndev->n_targets);
+       }
+}
+
+void nci_clear_target_list(struct nci_dev *ndev)
+{
+       memset(ndev->targets, 0,
+              (sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS));
+
+       ndev->n_targets = 0;
+}
+
+static void nci_rf_discover_ntf_packet(struct nci_dev *ndev,
+                                      struct sk_buff *skb)
+{
+       struct nci_rf_discover_ntf ntf;
+       __u8 *data = skb->data;
+       bool add_target = true;
+
+       ntf.rf_discovery_id = *data++;
+       ntf.rf_protocol = *data++;
+       ntf.rf_tech_and_mode = *data++;
+       ntf.rf_tech_specific_params_len = *data++;
+
+       pr_debug("rf_discovery_id %d\n", ntf.rf_discovery_id);
+       pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol);
+       pr_debug("rf_tech_and_mode 0x%x\n", ntf.rf_tech_and_mode);
+       pr_debug("rf_tech_specific_params_len %d\n",
+                ntf.rf_tech_specific_params_len);
+
+       if (ntf.rf_tech_specific_params_len > 0) {
+               switch (ntf.rf_tech_and_mode) {
+               case NCI_NFC_A_PASSIVE_POLL_MODE:
+                       data = nci_extract_rf_params_nfca_passive_poll(ndev,
+                               &(ntf.rf_tech_specific_params.nfca_poll), data);
+                       break;
+
+               case NCI_NFC_B_PASSIVE_POLL_MODE:
+                       data = nci_extract_rf_params_nfcb_passive_poll(ndev,
+                               &(ntf.rf_tech_specific_params.nfcb_poll), data);
+                       break;
+
+               case NCI_NFC_F_PASSIVE_POLL_MODE:
+                       data = nci_extract_rf_params_nfcf_passive_poll(ndev,
+                               &(ntf.rf_tech_specific_params.nfcf_poll), data);
+                       break;
+
+               default:
+                       pr_err("unsupported rf_tech_and_mode 0x%x\n",
+                              ntf.rf_tech_and_mode);
+                       data += ntf.rf_tech_specific_params_len;
+                       add_target = false;
+               }
+       }
+
+       ntf.ntf_type = *data++;
+       pr_debug("ntf_type %d\n", ntf.ntf_type);
+
+       if (add_target == true)
+               nci_add_new_target(ndev, &ntf);
+
+       if (ntf.ntf_type == NCI_DISCOVER_NTF_TYPE_MORE) {
+               atomic_set(&ndev->state, NCI_W4_ALL_DISCOVERIES);
+       } else {
+               atomic_set(&ndev->state, NCI_W4_HOST_SELECT);
+               nfc_targets_found(ndev->nfc_dev, ndev->targets,
+                                 ndev->n_targets);
+       }
+}
+
 static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
                        struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
 {
        struct activation_params_nfca_poll_iso_dep *nfca_poll;
+       struct activation_params_nfcb_poll_iso_dep *nfcb_poll;
 
        switch (ntf->activation_rf_tech_and_mode) {
        case NCI_NFC_A_PASSIVE_POLL_MODE:
                nfca_poll = &ntf->activation_params.nfca_poll_iso_dep;
                nfca_poll->rats_res_len = *data++;
+               pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len);
                if (nfca_poll->rats_res_len > 0) {
                        memcpy(nfca_poll->rats_res,
-                               data,
-                               nfca_poll->rats_res_len);
+                              data, nfca_poll->rats_res_len);
+               }
+               break;
+
+       case NCI_NFC_B_PASSIVE_POLL_MODE:
+               nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep;
+               nfcb_poll->attrib_res_len = *data++;
+               pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len);
+               if (nfcb_poll->attrib_res_len > 0) {
+                       memcpy(nfcb_poll->attrib_res,
+                              data, nfcb_poll->attrib_res_len);
                }
                break;
 
        default:
                pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
                       ntf->activation_rf_tech_and_mode);
-               return -EPROTO;
+               return NCI_STATUS_RF_PROTOCOL_ERROR;
        }
 
-       return 0;
+       return NCI_STATUS_OK;
 }
 
-static void nci_target_found(struct nci_dev *ndev,
-                               struct nci_rf_intf_activated_ntf *ntf)
+static void nci_target_auto_activated(struct nci_dev *ndev,
+                                     struct nci_rf_intf_activated_ntf *ntf)
 {
-       struct nfc_target nfc_tgt;
+       struct nfc_target *target;
+       int rc;
 
-       if (ntf->rf_protocol == NCI_RF_PROTOCOL_T2T)    /* T2T MifareUL */
-               nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK;
-       else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP)   /* 4A */
-               nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK;
-       else
-               nfc_tgt.supported_protocols = 0;
-
-       nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res;
-       nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res;
-       nfc_tgt.nfcid1_len = ntf->rf_tech_specific_params.nfca_poll.nfcid1_len;
-       if (nfc_tgt.nfcid1_len > 0) {
-               memcpy(nfc_tgt.nfcid1,
-                       ntf->rf_tech_specific_params.nfca_poll.nfcid1,
-                       nfc_tgt.nfcid1_len);
-       }
+       target = &ndev->targets[ndev->n_targets];
 
-       if (!(nfc_tgt.supported_protocols & ndev->poll_prots)) {
-               pr_debug("the target found does not have the desired protocol\n");
+       rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
+                                 ntf->activation_rf_tech_and_mode,
+                                 &ntf->rf_tech_specific_params);
+       if (rc)
                return;
-       }
 
-       pr_debug("new target found,  supported_protocols 0x%x\n",
-                nfc_tgt.supported_protocols);
+       target->idx = ntf->rf_discovery_id;
+       ndev->n_targets++;
 
-       ndev->target_available_prots = nfc_tgt.supported_protocols;
-       ndev->max_data_pkt_payload_size = ntf->max_data_pkt_payload_size;
-       ndev->initial_num_credits = ntf->initial_num_credits;
+       pr_debug("target_idx %d, n_targets %d\n", target->idx, ndev->n_targets);
 
-       /* set the available credits to initial value */
-       atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
-
-       nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1);
+       nfc_targets_found(ndev->nfc_dev, ndev->targets, ndev->n_targets);
 }
 
 static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
-                                               struct sk_buff *skb)
+                                            struct sk_buff *skb)
 {
        struct nci_rf_intf_activated_ntf ntf;
        __u8 *data = skb->data;
-       int err = 0;
-
-       clear_bit(NCI_DISCOVERY, &ndev->flags);
-       set_bit(NCI_POLL_ACTIVE, &ndev->flags);
+       int err = NCI_STATUS_OK;
 
        ntf.rf_discovery_id = *data++;
        ntf.rf_interface = *data++;
@@ -204,7 +402,8 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
                 ntf.activation_rf_tech_and_mode);
        pr_debug("max_data_pkt_payload_size 0x%x\n",
                 ntf.max_data_pkt_payload_size);
-       pr_debug("initial_num_credits 0x%x\n", ntf.initial_num_credits);
+       pr_debug("initial_num_credits 0x%x\n",
+                ntf.initial_num_credits);
        pr_debug("rf_tech_specific_params_len %d\n",
                 ntf.rf_tech_specific_params_len);
 
@@ -212,13 +411,24 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
                switch (ntf.activation_rf_tech_and_mode) {
                case NCI_NFC_A_PASSIVE_POLL_MODE:
                        data = nci_extract_rf_params_nfca_passive_poll(ndev,
-                               &ntf, data);
+                               &(ntf.rf_tech_specific_params.nfca_poll), data);
+                       break;
+
+               case NCI_NFC_B_PASSIVE_POLL_MODE:
+                       data = nci_extract_rf_params_nfcb_passive_poll(ndev,
+                               &(ntf.rf_tech_specific_params.nfcb_poll), data);
+                       break;
+
+               case NCI_NFC_F_PASSIVE_POLL_MODE:
+                       data = nci_extract_rf_params_nfcf_passive_poll(ndev,
+                               &(ntf.rf_tech_specific_params.nfcf_poll), data);
                        break;
 
                default:
                        pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
                               ntf.activation_rf_tech_and_mode);
-                       return;
+                       err = NCI_STATUS_RF_PROTOCOL_ERROR;
+                       goto exit;
                }
        }
 
@@ -229,18 +439,15 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
 
        pr_debug("data_exch_rf_tech_and_mode 0x%x\n",
                 ntf.data_exch_rf_tech_and_mode);
-       pr_debug("data_exch_tx_bit_rate 0x%x\n",
-                ntf.data_exch_tx_bit_rate);
-       pr_debug("data_exch_rx_bit_rate 0x%x\n",
-                ntf.data_exch_rx_bit_rate);
-       pr_debug("activation_params_len %d\n",
-                ntf.activation_params_len);
+       pr_debug("data_exch_tx_bit_rate 0x%x\n", ntf.data_exch_tx_bit_rate);
+       pr_debug("data_exch_rx_bit_rate 0x%x\n", ntf.data_exch_rx_bit_rate);
+       pr_debug("activation_params_len %d\n", ntf.activation_params_len);
 
        if (ntf.activation_params_len > 0) {
                switch (ntf.rf_interface) {
                case NCI_RF_INTERFACE_ISO_DEP:
                        err = nci_extract_activation_params_iso_dep(ndev,
-                               &ntf, data);
+                                                                   &ntf, data);
                        break;
 
                case NCI_RF_INTERFACE_FRAME:
@@ -250,24 +457,39 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
                default:
                        pr_err("unsupported rf_interface 0x%x\n",
                               ntf.rf_interface);
-                       return;
+                       err = NCI_STATUS_RF_PROTOCOL_ERROR;
+                       break;
                }
        }
 
-       if (!err)
-               nci_target_found(ndev, &ntf);
+exit:
+       if (err == NCI_STATUS_OK) {
+               ndev->max_data_pkt_payload_size = ntf.max_data_pkt_payload_size;
+               ndev->initial_num_credits = ntf.initial_num_credits;
+
+               /* set the available credits to initial value */
+               atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
+       }
+
+       if (atomic_read(&ndev->state) == NCI_DISCOVERY) {
+               /* A single target was found and activated automatically */
+               atomic_set(&ndev->state, NCI_POLL_ACTIVE);
+               if (err == NCI_STATUS_OK)
+                       nci_target_auto_activated(ndev, &ntf);
+       } else {        /* ndev->state == NCI_W4_HOST_SELECT */
+               /* A selected target was activated, so complete the request */
+               atomic_set(&ndev->state, NCI_POLL_ACTIVE);
+               nci_req_complete(ndev, err);
+       }
 }
 
 static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
-                                       struct sk_buff *skb)
+                                        struct sk_buff *skb)
 {
        struct nci_rf_deactivate_ntf *ntf = (void *) skb->data;
 
        pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason);
 
-       clear_bit(NCI_POLL_ACTIVE, &ndev->flags);
-       ndev->target_active_prot = 0;
-
        /* drop tx data queue */
        skb_queue_purge(&ndev->tx_q);
 
@@ -280,6 +502,10 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
        /* complete the data exchange transaction, if exists */
        if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
                nci_data_exchange_complete(ndev, NULL, -EIO);
+
+       nci_clear_target_list(ndev);
+       atomic_set(&ndev->state, NCI_IDLE);
+       nci_req_complete(ndev, NCI_STATUS_OK);
 }
 
 void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
@@ -300,10 +526,18 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
                nci_core_conn_credits_ntf_packet(ndev, skb);
                break;
 
+       case NCI_OP_CORE_GENERIC_ERROR_NTF:
+               nci_core_generic_error_ntf_packet(ndev, skb);
+               break;
+
        case NCI_OP_CORE_INTF_ERROR_NTF:
                nci_core_conn_intf_error_ntf_packet(ndev, skb);
                break;
 
+       case NCI_OP_RF_DISCOVER_NTF:
+               nci_rf_discover_ntf_packet(ndev, skb);
+               break;
+
        case NCI_OP_RF_INTF_ACTIVATED_NTF:
                nci_rf_intf_activated_ntf_packet(ndev, skb);
                break;
index 2840ae2f361527e278ae871a84f18f968d612057..3003c3390e492c18907cc7f5076949439dd7273d 100644 (file)
@@ -67,19 +67,18 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
        ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces;
 
        if (ndev->num_supported_rf_interfaces >
-                       NCI_MAX_SUPPORTED_RF_INTERFACES) {
+           NCI_MAX_SUPPORTED_RF_INTERFACES) {
                ndev->num_supported_rf_interfaces =
                        NCI_MAX_SUPPORTED_RF_INTERFACES;
        }
 
        memcpy(ndev->supported_rf_interfaces,
-               rsp_1->supported_rf_interfaces,
-               ndev->num_supported_rf_interfaces);
+              rsp_1->supported_rf_interfaces,
+              ndev->num_supported_rf_interfaces);
 
        rsp_2 = (void *) (skb->data + 6 + rsp_1->num_supported_rf_interfaces);
 
-       ndev->max_logical_connections =
-               rsp_2->max_logical_connections;
+       ndev->max_logical_connections = rsp_2->max_logical_connections;
        ndev->max_routing_table_size =
                __le16_to_cpu(rsp_2->max_routing_table_size);
        ndev->max_ctrl_pkt_payload_len =
@@ -121,7 +120,7 @@ exit:
 }
 
 static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev,
-                                       struct sk_buff *skb)
+                                      struct sk_buff *skb)
 {
        __u8 status = skb->data[0];
 
@@ -137,21 +136,37 @@ static void nci_rf_disc_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
        pr_debug("status 0x%x\n", status);
 
        if (status == NCI_STATUS_OK)
-               set_bit(NCI_DISCOVERY, &ndev->flags);
+               atomic_set(&ndev->state, NCI_DISCOVERY);
 
        nci_req_complete(ndev, status);
 }
 
-static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
-                                       struct sk_buff *skb)
+static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev,
+                                         struct sk_buff *skb)
 {
        __u8 status = skb->data[0];
 
        pr_debug("status 0x%x\n", status);
 
-       clear_bit(NCI_DISCOVERY, &ndev->flags);
+       /* Complete the request on intf_activated_ntf or generic_error_ntf */
+       if (status != NCI_STATUS_OK)
+               nci_req_complete(ndev, status);
+}
 
-       nci_req_complete(ndev, status);
+static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
+                                        struct sk_buff *skb)
+{
+       __u8 status = skb->data[0];
+
+       pr_debug("status 0x%x\n", status);
+
+       /* If target was active, complete the request only in deactivate_ntf */
+       if ((status != NCI_STATUS_OK) ||
+           (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
+               nci_clear_target_list(ndev);
+               atomic_set(&ndev->state, NCI_IDLE);
+               nci_req_complete(ndev, status);
+       }
 }
 
 void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
@@ -187,6 +202,10 @@ void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
                nci_rf_disc_rsp_packet(ndev, skb);
                break;
 
+       case NCI_OP_RF_DISCOVER_SELECT_RSP:
+               nci_rf_disc_select_rsp_packet(ndev, skb);
+               break;
+
        case NCI_OP_RF_DEACTIVATE_RSP:
                nci_rf_deactivate_rsp_packet(ndev, skb);
                break;
index 6989dfa28ee21d585d0f91fe8274e493a5f73c36..6404052d6c070ccf8f54c4827408d5f9291d6b67 100644 (file)
@@ -48,28 +48,34 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
        [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 },
        [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 },
        [NFC_ATTR_RF_MODE] = { .type = NLA_U8 },
+       [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 },
 };
 
 static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
-                                       struct netlink_callback *cb, int flags)
+                               struct netlink_callback *cb, int flags)
 {
        void *hdr;
 
        hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
-                               &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
+                         &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
        if (!hdr)
                return -EMSGSIZE;
 
        genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
 
        NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx);
-       NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS,
-                               target->supported_protocols);
+       NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols);
        NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res);
        NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res);
        if (target->nfcid1_len > 0)
                NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
-                               target->nfcid1);
+                       target->nfcid1);
+       if (target->sensb_res_len > 0)
+               NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
+                       target->sensb_res);
+       if (target->sensf_res_len > 0)
+               NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
+                       target->sensf_res);
 
        return genlmsg_end(msg, hdr);
 
@@ -85,9 +91,9 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
        u32 idx;
 
        rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize,
-                                               nfc_genl_family.attrbuf,
-                                               nfc_genl_family.maxattr,
-                                               nfc_genl_policy);
+                        nfc_genl_family.attrbuf,
+                        nfc_genl_family.maxattr,
+                        nfc_genl_policy);
        if (rc < 0)
                return ERR_PTR(rc);
 
@@ -104,7 +110,7 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
 }
 
 static int nfc_genl_dump_targets(struct sk_buff *skb,
-                               struct netlink_callback *cb)
+                                struct netlink_callback *cb)
 {
        int i = cb->args[0];
        struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
@@ -124,7 +130,7 @@ static int nfc_genl_dump_targets(struct sk_buff *skb,
 
        while (i < dev->n_targets) {
                rc = nfc_genl_send_target(skb, &dev->targets[i], cb,
-                                                               NLM_F_MULTI);
+                                         NLM_F_MULTI);
                if (rc < 0)
                        break;
 
@@ -160,7 +166,7 @@ int nfc_genl_targets_found(struct nfc_dev *dev)
                return -ENOMEM;
 
        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                               NFC_EVENT_TARGETS_FOUND);
+                         NFC_EVENT_TARGETS_FOUND);
        if (!hdr)
                goto free_msg;
 
@@ -187,13 +193,14 @@ int nfc_genl_device_added(struct nfc_dev *dev)
                return -ENOMEM;
 
        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                               NFC_EVENT_DEVICE_ADDED);
+                         NFC_EVENT_DEVICE_ADDED);
        if (!hdr)
                goto free_msg;
 
        NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
        NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
        NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
+       NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up);
 
        genlmsg_end(msg, hdr);
 
@@ -218,7 +225,7 @@ int nfc_genl_device_removed(struct nfc_dev *dev)
                return -ENOMEM;
 
        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                               NFC_EVENT_DEVICE_REMOVED);
+                         NFC_EVENT_DEVICE_REMOVED);
        if (!hdr)
                goto free_msg;
 
@@ -238,14 +245,14 @@ free_msg:
 }
 
 static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
-                                               u32 pid, u32 seq,
-                                               struct netlink_callback *cb,
-                                               int flags)
+                               u32 pid, u32 seq,
+                               struct netlink_callback *cb,
+                               int flags)
 {
        void *hdr;
 
        hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags,
-                                                       NFC_CMD_GET_DEVICE);
+                         NFC_CMD_GET_DEVICE);
        if (!hdr)
                return -EMSGSIZE;
 
@@ -255,6 +262,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
        NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
        NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
        NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
+       NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up);
 
        return genlmsg_end(msg, hdr);
 
@@ -264,7 +272,7 @@ nla_put_failure:
 }
 
 static int nfc_genl_dump_devices(struct sk_buff *skb,
-                               struct netlink_callback *cb)
+                                struct netlink_callback *cb)
 {
        struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
        struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
@@ -291,8 +299,7 @@ static int nfc_genl_dump_devices(struct sk_buff *skb,
                int rc;
 
                rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid,
-                                                       cb->nlh->nlmsg_seq,
-                                                       cb, NLM_F_MULTI);
+                                         cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
                if (rc < 0)
                        break;
 
@@ -317,7 +324,7 @@ static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
 }
 
 int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
-                                               u8 comm_mode, u8 rf_mode)
+                              u8 comm_mode, u8 rf_mode)
 {
        struct sk_buff *msg;
        void *hdr;
@@ -328,8 +335,7 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
        if (!msg)
                return -ENOMEM;
 
-       hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                               NFC_CMD_DEP_LINK_UP);
+       hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP);
        if (!hdr)
                goto free_msg;
 
@@ -366,7 +372,7 @@ int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
                return -ENOMEM;
 
        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                               NFC_CMD_DEP_LINK_DOWN);
+                         NFC_CMD_DEP_LINK_DOWN);
        if (!hdr)
                goto free_msg;
 
@@ -408,7 +414,7 @@ static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
        }
 
        rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq,
-                                                               NULL, 0);
+                                 NULL, 0);
        if (rc < 0)
                goto out_free;
 
@@ -475,7 +481,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
        pr_debug("Poll start\n");
 
        if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
-               !info->attrs[NFC_ATTR_PROTOCOLS])
+           !info->attrs[NFC_ATTR_PROTOCOLS])
                return -EINVAL;
 
        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
@@ -533,13 +539,12 @@ static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
        struct nfc_dev *dev;
        int rc, tgt_idx;
        u32 idx;
-       u8 comm, rf;
+       u8 comm;
 
        pr_debug("DEP link up\n");
 
        if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
-                       !info->attrs[NFC_ATTR_COMM_MODE] ||
-                       !info->attrs[NFC_ATTR_RF_MODE])
+           !info->attrs[NFC_ATTR_COMM_MODE])
                return -EINVAL;
 
        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
@@ -549,19 +554,15 @@ static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
                tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
 
        comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]);
-       rf = nla_get_u8(info->attrs[NFC_ATTR_RF_MODE]);
 
        if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE)
                return -EINVAL;
 
-       if (rf != NFC_RF_INITIATOR && comm != NFC_RF_TARGET)
-               return -EINVAL;
-
        dev = nfc_get_device(idx);
        if (!dev)
                return -ENODEV;
 
-       rc = nfc_dep_link_up(dev, tgt_idx, comm, rf);
+       rc = nfc_dep_link_up(dev, tgt_idx, comm);
 
        nfc_put_device(dev);
 
@@ -636,7 +637,7 @@ static struct genl_ops nfc_genl_ops[] = {
 };
 
 static int nfc_genl_rcv_nl_event(struct notifier_block *this,
-                                               unsigned long event, void *ptr)
+                                unsigned long event, void *ptr)
 {
        struct netlink_notify *n = ptr;
        struct class_dev_iter iter;
@@ -689,7 +690,7 @@ int __init nfc_genl_init(void)
        int rc;
 
        rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops,
-                                       ARRAY_SIZE(nfc_genl_ops));
+                                          ARRAY_SIZE(nfc_genl_ops));
        if (rc)
                return rc;
 
index 6d28d75995b036e2da23410836313716efd9318f..ec8794c1099c9c2961446f101d9f0846caa96aca 100644 (file)
@@ -32,7 +32,7 @@ struct nfc_protocol {
        struct proto *proto;
        struct module *owner;
        int (*create)(struct net *net, struct socket *sock,
-                       const struct nfc_protocol *nfc_proto);
+                     const struct nfc_protocol *nfc_proto);
 };
 
 struct nfc_rawsock {
@@ -54,7 +54,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
 int nfc_llcp_register_device(struct nfc_dev *dev);
 void nfc_llcp_unregister_device(struct nfc_dev *dev);
 int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len);
-u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *general_bytes_len);
+u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len);
 int __init nfc_llcp_init(void);
 void nfc_llcp_exit(void);
 
@@ -65,7 +65,7 @@ static inline void nfc_llcp_mac_is_down(struct nfc_dev *dev)
 }
 
 static inline void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
-                       u8 comm_mode, u8 rf_mode)
+                                     u8 comm_mode, u8 rf_mode)
 {
 }
 
@@ -78,7 +78,8 @@ static inline void nfc_llcp_unregister_device(struct nfc_dev *dev)
 {
 }
 
-static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
+static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev,
+                                        u8 *gb, u8 gb_len)
 {
        return 0;
 }
@@ -160,8 +161,7 @@ int nfc_start_poll(struct nfc_dev *dev, u32 protocols);
 
 int nfc_stop_poll(struct nfc_dev *dev);
 
-int nfc_dep_link_up(struct nfc_dev *dev, int target_idx,
-                               u8 comm_mode, u8 rf_mode);
+int nfc_dep_link_up(struct nfc_dev *dev, int target_idx, u8 comm_mode);
 
 int nfc_dep_link_down(struct nfc_dev *dev);
 
@@ -169,9 +169,7 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol);
 
 int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx);
 
-int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx,
-                                       struct sk_buff *skb,
-                                       data_exchange_cb_t cb,
-                                       void *cb_context);
+int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
+                     data_exchange_cb_t cb, void *cb_context);
 
 #endif /* __LOCAL_NFC_H */
index 2e2f8c6a61fe90579486c553032d14af2a7f0588..5a839ceb2e82f1f23e45595ae836526b9589fefd 100644 (file)
@@ -63,7 +63,7 @@ static int rawsock_release(struct socket *sock)
 }
 
 static int rawsock_connect(struct socket *sock, struct sockaddr *_addr,
-                                                       int len, int flags)
+                          int len, int flags)
 {
        struct sock *sk = sock->sk;
        struct sockaddr_nfc *addr = (struct sockaddr_nfc *)_addr;
@@ -73,7 +73,7 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr,
        pr_debug("sock=%p sk=%p flags=%d\n", sock, sk, flags);
 
        if (!addr || len < sizeof(struct sockaddr_nfc) ||
-               addr->sa_family != AF_NFC)
+           addr->sa_family != AF_NFC)
                return -EINVAL;
 
        pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n",
@@ -92,18 +92,6 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr,
                goto error;
        }
 
-       if (addr->target_idx > dev->target_idx - 1 ||
-               addr->target_idx < dev->target_idx - dev->n_targets) {
-               rc = -EINVAL;
-               goto error;
-       }
-
-       if (addr->target_idx > dev->target_idx - 1 ||
-               addr->target_idx < dev->target_idx - dev->n_targets) {
-               rc = -EINVAL;
-               goto error;
-       }
-
        rc = nfc_activate_target(dev, addr->target_idx, addr->nfc_protocol);
        if (rc)
                goto put_dev;
@@ -132,7 +120,7 @@ static int rawsock_add_header(struct sk_buff *skb)
 }
 
 static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb,
-                                                               int err)
+                                          int err)
 {
        struct sock *sk = (struct sock *) context;
 
@@ -185,7 +173,7 @@ static void rawsock_tx_work(struct work_struct *work)
 
        sock_hold(sk);
        rc = nfc_data_exchange(dev, target_idx, skb,
-                               rawsock_data_exchange_complete, sk);
+                              rawsock_data_exchange_complete, sk);
        if (rc) {
                rawsock_report_error(sk, rc);
                sock_put(sk);
@@ -193,7 +181,7 @@ static void rawsock_tx_work(struct work_struct *work)
 }
 
 static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
-                                       struct msghdr *msg, size_t len)
+                          struct msghdr *msg, size_t len)
 {
        struct sock *sk = sock->sk;
        struct nfc_dev *dev = nfc_rawsock(sk)->dev;
@@ -230,7 +218,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
 }
 
 static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,
-                               struct msghdr *msg, size_t len, int flags)
+                          struct msghdr *msg, size_t len, int flags)
 {
        int noblock = flags & MSG_DONTWAIT;
        struct sock *sk = sock->sk;
@@ -286,7 +274,7 @@ static void rawsock_destruct(struct sock *sk)
 
        if (sk->sk_state == TCP_ESTABLISHED) {
                nfc_deactivate_target(nfc_rawsock(sk)->dev,
-                                       nfc_rawsock(sk)->target_idx);
+                                     nfc_rawsock(sk)->target_idx);
                nfc_put_device(nfc_rawsock(sk)->dev);
        }
 
@@ -299,7 +287,7 @@ static void rawsock_destruct(struct sock *sk)
 }
 
 static int rawsock_create(struct net *net, struct socket *sock,
-                               const struct nfc_protocol *nfc_proto)
+                         const struct nfc_protocol *nfc_proto)
 {
        struct sock *sk;
 
index 43ad9c81efcff1164b08c532e29f7a73e84d5cbf..3ac2dd00d7149b123db51463b449a112a2d1b908 100644 (file)
@@ -144,11 +144,6 @@ static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pu
        return container_of(pub, struct cfg80211_internal_bss, pub);
 }
 
-static inline void cfg80211_ref_bss(struct cfg80211_internal_bss *bss)
-{
-       kref_get(&bss->ref);
-}
-
 static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
 {
        atomic_inc(&bss->hold);
@@ -325,15 +320,13 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
                         const u8 *bssid,
                         const u8 *ssid, int ssid_len,
                         const u8 *ie, int ie_len,
-                        const u8 *key, int key_len, int key_idx,
-                        bool local_state_change);
+                        const u8 *key, int key_len, int key_idx);
 int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
                       struct net_device *dev, struct ieee80211_channel *chan,
                       enum nl80211_auth_type auth_type, const u8 *bssid,
                       const u8 *ssid, int ssid_len,
                       const u8 *ie, int ie_len,
-                      const u8 *key, int key_len, int key_idx,
-                      bool local_state_change);
+                      const u8 *key, int key_len, int key_idx);
 int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
                          struct net_device *dev,
                          struct ieee80211_channel *chan,
@@ -421,7 +414,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
                             size_t ie_len, u16 reason, bool from_ap);
 void cfg80211_sme_scan_done(struct net_device *dev);
 void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
-void cfg80211_sme_disassoc(struct net_device *dev, int idx);
+void cfg80211_sme_disassoc(struct net_device *dev,
+                          struct cfg80211_internal_bss *bss);
 void __cfg80211_scan_done(struct work_struct *wk);
 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
 void __cfg80211_sched_scan_results(struct work_struct *wk);
index 8c550df13037c7e0108c692cd080762fafd0ab38..ba21ab22187bef366394743d9d94d6ee33d72b6a 100644 (file)
@@ -23,6 +23,8 @@
 #define MESH_PERR_MIN_INT      100
 #define MESH_DIAM_TRAVERSAL_TIME 50
 
+#define MESH_RSSI_THRESHOLD    0
+
 /*
  * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds
  * before timing out.  This way it will remain ACTIVE and no data frames
@@ -55,6 +57,8 @@ const struct mesh_config default_mesh_config = {
        .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
        .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL,
        .dot11MeshGateAnnouncementProtocol = false,
+       .dot11MeshForwarding = true,
+       .rssi_threshold = MESH_RSSI_THRESHOLD,
 };
 
 const struct mesh_setup default_mesh_setup = {
index 438dfc105b4a0b316fa801e2bef001d89b0d39dc..f5a7ac3a0939ab0e782bf31bc538c0fa2a22cb3d 100644 (file)
@@ -20,40 +20,18 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct wiphy *wiphy = wdev->wiphy;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
-       u8 *bssid = mgmt->bssid;
-       int i;
-       u16 status = le16_to_cpu(mgmt->u.auth.status_code);
-       bool done = false;
 
        wdev_lock(wdev);
 
-       for (i = 0; i < MAX_AUTH_BSSES; i++) {
-               if (wdev->authtry_bsses[i] &&
-                   memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
-                                                       ETH_ALEN) == 0) {
-                       if (status == WLAN_STATUS_SUCCESS) {
-                               wdev->auth_bsses[i] = wdev->authtry_bsses[i];
-                       } else {
-                               cfg80211_unhold_bss(wdev->authtry_bsses[i]);
-                               cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
-                       }
-                       wdev->authtry_bsses[i] = NULL;
-                       done = true;
-                       break;
-               }
-       }
-
-       if (done) {
-               nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
-               cfg80211_sme_rx_auth(dev, buf, len);
-       }
+       nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
+       cfg80211_sme_rx_auth(dev, buf, len);
 
        wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_rx_auth);
 
-void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
+void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
+                           const u8 *buf, size_t len)
 {
        u16 status_code;
        struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -61,8 +39,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
        u8 *ie = mgmt->u.assoc_resp.variable;
-       int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
-       struct cfg80211_internal_bss *bss = NULL;
+       int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
 
        wdev_lock(wdev);
 
@@ -75,43 +52,20 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
         * frame instead of reassoc.
         */
        if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
-           cfg80211_sme_failed_reassoc(wdev))
+           cfg80211_sme_failed_reassoc(wdev)) {
+               cfg80211_put_bss(bss);
                goto out;
+       }
 
        nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
 
-       if (status_code == WLAN_STATUS_SUCCESS) {
-               for (i = 0; i < MAX_AUTH_BSSES; i++) {
-                       if (!wdev->auth_bsses[i])
-                               continue;
-                       if (memcmp(wdev->auth_bsses[i]->pub.bssid, mgmt->bssid,
-                                  ETH_ALEN) == 0) {
-                               bss = wdev->auth_bsses[i];
-                               wdev->auth_bsses[i] = NULL;
-                               /* additional reference to drop hold */
-                               cfg80211_ref_bss(bss);
-                               break;
-                       }
-               }
-
-               /*
-                * We might be coming here because the driver reported
-                * a successful association at the same time as the
-                * user requested a deauth. In that case, we will have
-                * removed the BSS from the auth_bsses list due to the
-                * deauth request when the assoc response makes it. If
-                * the two code paths acquire the lock the other way
-                * around, that's just the standard situation of a
-                * deauth being requested while connected.
-                */
-               if (!bss)
-                       goto out;
-       } else if (wdev->conn) {
+       if (status_code != WLAN_STATUS_SUCCESS && wdev->conn) {
                cfg80211_sme_failed_assoc(wdev);
                /*
                 * do not call connect_result() now because the
                 * sme will schedule work that does it later.
                 */
+               cfg80211_put_bss(bss);
                goto out;
        }
 
@@ -124,17 +78,10 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
                wdev->sme_state = CFG80211_SME_CONNECTING;
        }
 
-       /* this consumes one bss reference (unless bss is NULL) */
+       /* this consumes the bss reference */
        __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
                                  status_code,
-                                 status_code == WLAN_STATUS_SUCCESS,
-                                 bss ? &bss->pub : NULL);
-       /* drop hold now, and also reference acquired above */
-       if (bss) {
-               cfg80211_unhold_bss(bss);
-               cfg80211_put_bss(&bss->pub);
-       }
-
+                                 status_code == WLAN_STATUS_SUCCESS, bss);
  out:
        wdev_unlock(wdev);
 }
@@ -148,8 +95,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
        const u8 *bssid = mgmt->bssid;
-       int i;
-       bool found = false, was_current = false;
+       bool was_current = false;
 
        ASSERT_WDEV_LOCK(wdev);
 
@@ -158,32 +104,9 @@ void __cfg80211_send_deauth(struct net_device *dev,
                cfg80211_unhold_bss(wdev->current_bss);
                cfg80211_put_bss(&wdev->current_bss->pub);
                wdev->current_bss = NULL;
-               found = true;
                was_current = true;
-       } else for (i = 0; i < MAX_AUTH_BSSES; i++) {
-               if (wdev->auth_bsses[i] &&
-                   memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
-                       cfg80211_unhold_bss(wdev->auth_bsses[i]);
-                       cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
-                       wdev->auth_bsses[i] = NULL;
-                       found = true;
-                       break;
-               }
-               if (wdev->authtry_bsses[i] &&
-                   memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
-                          ETH_ALEN) == 0 &&
-                   memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) == 0) {
-                       cfg80211_unhold_bss(wdev->authtry_bsses[i]);
-                       cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
-                       wdev->authtry_bsses[i] = NULL;
-                       found = true;
-                       break;
-               }
        }
 
-       if (!found)
-               return;
-
        nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
 
        if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) {
@@ -220,10 +143,8 @@ void __cfg80211_send_disassoc(struct net_device *dev,
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
        const u8 *bssid = mgmt->bssid;
-       int i;
        u16 reason_code;
        bool from_ap;
-       bool done = false;
 
        ASSERT_WDEV_LOCK(wdev);
 
@@ -234,16 +155,10 @@ void __cfg80211_send_disassoc(struct net_device *dev,
 
        if (wdev->current_bss &&
            memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
-               for (i = 0; i < MAX_AUTH_BSSES; i++) {
-                       if (wdev->authtry_bsses[i] || wdev->auth_bsses[i])
-                               continue;
-                       wdev->auth_bsses[i] = wdev->current_bss;
-                       wdev->current_bss = NULL;
-                       done = true;
-                       cfg80211_sme_disassoc(dev, i);
-                       break;
-               }
-               WARN_ON(!done);
+               cfg80211_sme_disassoc(dev, wdev->current_bss);
+               cfg80211_unhold_bss(wdev->current_bss);
+               cfg80211_put_bss(&wdev->current_bss->pub);
+               wdev->current_bss = NULL;
        } else
                WARN_ON(1);
 
@@ -287,34 +202,6 @@ void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
 }
 EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
 
-static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
-{
-       int i;
-       bool done = false;
-
-       ASSERT_WDEV_LOCK(wdev);
-
-       for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
-               if (wdev->authtry_bsses[i] &&
-                   memcmp(wdev->authtry_bsses[i]->pub.bssid,
-                          addr, ETH_ALEN) == 0) {
-                       cfg80211_unhold_bss(wdev->authtry_bsses[i]);
-                       cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
-                       wdev->authtry_bsses[i] = NULL;
-                       done = true;
-                       break;
-               }
-       }
-
-       WARN_ON(!done);
-}
-
-void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr)
-{
-       __cfg80211_auth_remove(dev->ieee80211_ptr, addr);
-}
-EXPORT_SYMBOL(__cfg80211_auth_canceled);
-
 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -329,8 +216,6 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
                                          WLAN_STATUS_UNSPECIFIED_FAILURE,
                                          false, NULL);
 
-       __cfg80211_auth_remove(wdev, addr);
-
        wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
@@ -340,8 +225,6 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct wiphy *wiphy = wdev->wiphy;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-       int i;
-       bool done = false;
 
        wdev_lock(wdev);
 
@@ -351,20 +234,6 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
                                          WLAN_STATUS_UNSPECIFIED_FAILURE,
                                          false, NULL);
 
-       for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
-               if (wdev->auth_bsses[i] &&
-                   memcmp(wdev->auth_bsses[i]->pub.bssid,
-                          addr, ETH_ALEN) == 0) {
-                       cfg80211_unhold_bss(wdev->auth_bsses[i]);
-                       cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
-                       wdev->auth_bsses[i] = NULL;
-                       done = true;
-                       break;
-               }
-       }
-
-       WARN_ON(!done);
-
        wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
@@ -403,13 +272,11 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
                         const u8 *bssid,
                         const u8 *ssid, int ssid_len,
                         const u8 *ie, int ie_len,
-                        const u8 *key, int key_len, int key_idx,
-                        bool local_state_change)
+                        const u8 *key, int key_len, int key_idx)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_auth_request req;
-       struct cfg80211_internal_bss *bss;
-       int i, err, slot = -1, nfree = 0;
+       int err;
 
        ASSERT_WDEV_LOCK(wdev);
 
@@ -421,20 +288,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
            memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
                return -EALREADY;
 
-       for (i = 0; i < MAX_AUTH_BSSES; i++) {
-               if (wdev->authtry_bsses[i] &&
-                   memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid,
-                                               ETH_ALEN) == 0)
-                       return -EALREADY;
-               if (wdev->auth_bsses[i] &&
-                   memcmp(bssid, wdev->auth_bsses[i]->pub.bssid,
-                                               ETH_ALEN) == 0)
-                       return -EALREADY;
-       }
-
        memset(&req, 0, sizeof(req));
 
-       req.local_state_change = local_state_change;
        req.ie = ie;
        req.ie_len = ie_len;
        req.auth_type = auth_type;
@@ -446,39 +301,9 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
        if (!req.bss)
                return -ENOENT;
 
-       bss = bss_from_pub(req.bss);
-
-       for (i = 0; i < MAX_AUTH_BSSES; i++) {
-               if (!wdev->auth_bsses[i] && !wdev->authtry_bsses[i]) {
-                       slot = i;
-                       nfree++;
-               }
-       }
-
-       /* we need one free slot for disassoc and one for this auth */
-       if (nfree < 2) {
-               err = -ENOSPC;
-               goto out;
-       }
-
-       if (local_state_change)
-               wdev->auth_bsses[slot] = bss;
-       else
-               wdev->authtry_bsses[slot] = bss;
-       cfg80211_hold_bss(bss);
-
        err = rdev->ops->auth(&rdev->wiphy, dev, &req);
-       if (err) {
-               if (local_state_change)
-                       wdev->auth_bsses[slot] = NULL;
-               else
-                       wdev->authtry_bsses[slot] = NULL;
-               cfg80211_unhold_bss(bss);
-       }
 
- out:
-       if (err)
-               cfg80211_put_bss(req.bss);
+       cfg80211_put_bss(req.bss);
        return err;
 }
 
@@ -487,15 +312,14 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
                       enum nl80211_auth_type auth_type, const u8 *bssid,
                       const u8 *ssid, int ssid_len,
                       const u8 *ie, int ie_len,
-                      const u8 *key, int key_len, int key_idx,
-                      bool local_state_change)
+                      const u8 *key, int key_len, int key_idx)
 {
        int err;
 
        wdev_lock(dev->ieee80211_ptr);
        err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
                                   ssid, ssid_len, ie, ie_len,
-                                  key, key_len, key_idx, local_state_change);
+                                  key, key_len, key_idx);
        wdev_unlock(dev->ieee80211_ptr);
 
        return err;
@@ -530,8 +354,7 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_assoc_request req;
-       struct cfg80211_internal_bss *bss;
-       int i, err, slot = -1;
+       int err;
        bool was_connected = false;
 
        ASSERT_WDEV_LOCK(wdev);
@@ -573,26 +396,14 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
                return -ENOENT;
        }
 
-       bss = bss_from_pub(req.bss);
-
-       for (i = 0; i < MAX_AUTH_BSSES; i++) {
-               if (bss == wdev->auth_bsses[i]) {
-                       slot = i;
-                       break;
-               }
-       }
+       err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
 
-       if (slot < 0) {
-               err = -ENOTCONN;
-               goto out;
+       if (err) {
+               if (was_connected)
+                       wdev->sme_state = CFG80211_SME_CONNECTED;
+               cfg80211_put_bss(req.bss);
        }
 
-       err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
- out:
-       if (err && was_connected)
-               wdev->sme_state = CFG80211_SME_CONNECTED;
-       /* still a reference in wdev->auth_bsses[slot] */
-       cfg80211_put_bss(req.bss);
        return err;
 }
 
@@ -624,36 +435,27 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
                           bool local_state_change)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
-       struct cfg80211_deauth_request req;
-       int i;
+       struct cfg80211_deauth_request req = {
+               .bssid = bssid,
+               .reason_code = reason,
+               .ie = ie,
+               .ie_len = ie_len,
+       };
 
        ASSERT_WDEV_LOCK(wdev);
 
-       memset(&req, 0, sizeof(req));
-       req.reason_code = reason;
-       req.local_state_change = local_state_change;
-       req.ie = ie;
-       req.ie_len = ie_len;
-       if (wdev->current_bss &&
-           memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
-               req.bss = &wdev->current_bss->pub;
-       } else for (i = 0; i < MAX_AUTH_BSSES; i++) {
-               if (wdev->auth_bsses[i] &&
-                   memcmp(bssid, wdev->auth_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
-                       req.bss = &wdev->auth_bsses[i]->pub;
-                       break;
-               }
-               if (wdev->authtry_bsses[i] &&
-                   memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
-                       req.bss = &wdev->authtry_bsses[i]->pub;
-                       break;
+       if (local_state_change) {
+               if (wdev->current_bss &&
+                   memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
+                       cfg80211_unhold_bss(wdev->current_bss);
+                       cfg80211_put_bss(&wdev->current_bss->pub);
+                       wdev->current_bss = NULL;
                }
-       }
 
-       if (!req.bss)
-               return -ENOTCONN;
+               return 0;
+       }
 
-       return rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
+       return rdev->ops->deauth(&rdev->wiphy, dev, &req);
 }
 
 int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
@@ -698,7 +500,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
        else
                return -ENOTCONN;
 
-       return rdev->ops->disassoc(&rdev->wiphy, dev, &req, wdev);
+       return rdev->ops->disassoc(&rdev->wiphy, dev, &req);
 }
 
 int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
@@ -722,7 +524,7 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_deauth_request req;
-       int i;
+       u8 bssid[ETH_ALEN];
 
        ASSERT_WDEV_LOCK(wdev);
 
@@ -734,35 +536,17 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
        req.ie = NULL;
        req.ie_len = 0;
 
-       if (wdev->current_bss) {
-               req.bss = &wdev->current_bss->pub;
-               rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
-               if (wdev->current_bss) {
-                       cfg80211_unhold_bss(wdev->current_bss);
-                       cfg80211_put_bss(&wdev->current_bss->pub);
-                       wdev->current_bss = NULL;
-               }
-       }
+       if (!wdev->current_bss)
+               return;
 
-       for (i = 0; i < MAX_AUTH_BSSES; i++) {
-               if (wdev->auth_bsses[i]) {
-                       req.bss = &wdev->auth_bsses[i]->pub;
-                       rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
-                       if (wdev->auth_bsses[i]) {
-                               cfg80211_unhold_bss(wdev->auth_bsses[i]);
-                               cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
-                               wdev->auth_bsses[i] = NULL;
-                       }
-               }
-               if (wdev->authtry_bsses[i]) {
-                       req.bss = &wdev->authtry_bsses[i]->pub;
-                       rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
-                       if (wdev->authtry_bsses[i]) {
-                               cfg80211_unhold_bss(wdev->authtry_bsses[i]);
-                               cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
-                               wdev->authtry_bsses[i] = NULL;
-                       }
-               }
+       memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
+       req.bssid = bssid;
+       rdev->ops->deauth(&rdev->wiphy, dev, &req);
+
+       if (wdev->current_bss) {
+               cfg80211_unhold_bss(wdev->current_bss);
+               cfg80211_put_bss(&wdev->current_bss->pub);
+               wdev->current_bss = NULL;
        }
 }
 
@@ -1030,8 +814,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
                                  cookie);
 }
 
-bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
-                     size_t len, gfp_t gfp)
+bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_mbm,
+                     const u8 *buf, size_t len, gfp_t gfp)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct wiphy *wiphy = wdev->wiphy;
@@ -1070,7 +854,8 @@ bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
                /* found match! */
 
                /* Indicate the received Action frame to user space */
-               if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq,
+               if (nl80211_send_mgmt(rdev, dev, reg->nlpid,
+                                     freq, sig_mbm,
                                      buf, len, gfp))
                        continue;
 
index afeea32e04ad9ea1a0caa1adeabe83b940bc0c42..39dbdf2adb12969b100e91a5e87dc3507bd3f110 100644 (file)
@@ -204,6 +204,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
                .len = NL80211_HT_CAPABILITY_LEN
        },
        [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
+       [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
 };
 
 /* policy for the key attributes */
@@ -427,10 +428,9 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
 
        if (tb[NL80211_KEY_DEFAULT_TYPES]) {
                struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
-               int err = nla_parse_nested(kdt,
-                                          NUM_NL80211_KEY_DEFAULT_TYPES - 1,
-                                          tb[NL80211_KEY_DEFAULT_TYPES],
-                                          nl80211_key_default_policy);
+               err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
+                                      tb[NL80211_KEY_DEFAULT_TYPES],
+                                      nl80211_key_default_policy);
                if (err)
                        return err;
 
@@ -872,7 +872,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
        CMD(add_virtual_intf, NEW_INTERFACE);
        CMD(change_virtual_intf, SET_INTERFACE);
        CMD(add_key, NEW_KEY);
-       CMD(add_beacon, NEW_BEACON);
+       CMD(start_ap, START_AP);
        CMD(add_station, NEW_STATION);
        CMD(add_mpath, NEW_MPATH);
        CMD(update_mesh_config, SET_MESH_CONFIG);
@@ -2076,15 +2076,10 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
        return err;
 }
 
-static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
+static int nl80211_parse_beacon(struct genl_info *info,
+                               struct cfg80211_beacon_data *bcn)
 {
-        int (*call)(struct wiphy *wiphy, struct net_device *dev,
-                   struct beacon_parameters *info);
-       struct cfg80211_registered_device *rdev = info->user_ptr[0];
-       struct net_device *dev = info->user_ptr[1];
-       struct wireless_dev *wdev = dev->ieee80211_ptr;
-       struct beacon_parameters params;
-       int haveinfo = 0, err;
+       bool haveinfo = false;
 
        if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) ||
            !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) ||
@@ -2092,149 +2087,190 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
            !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]))
                return -EINVAL;
 
-       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
-           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
-               return -EOPNOTSUPP;
-
-       memset(&params, 0, sizeof(params));
-
-       switch (info->genlhdr->cmd) {
-       case NL80211_CMD_NEW_BEACON:
-               /* these are required for NEW_BEACON */
-               if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
-                   !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
-                   !info->attrs[NL80211_ATTR_BEACON_HEAD])
-                       return -EINVAL;
-
-               params.interval =
-                       nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
-               params.dtim_period =
-                       nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
-
-               err = cfg80211_validate_beacon_int(rdev, params.interval);
-               if (err)
-                       return err;
-
-               /*
-                * In theory, some of these attributes could be required for
-                * NEW_BEACON, but since they were not used when the command was
-                * originally added, keep them optional for old user space
-                * programs to work with drivers that do not need the additional
-                * information.
-                */
-               if (info->attrs[NL80211_ATTR_SSID]) {
-                       params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
-                       params.ssid_len =
-                               nla_len(info->attrs[NL80211_ATTR_SSID]);
-                       if (params.ssid_len == 0 ||
-                           params.ssid_len > IEEE80211_MAX_SSID_LEN)
-                               return -EINVAL;
-               }
-
-               if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
-                       params.hidden_ssid = nla_get_u32(
-                               info->attrs[NL80211_ATTR_HIDDEN_SSID]);
-                       if (params.hidden_ssid !=
-                           NL80211_HIDDEN_SSID_NOT_IN_USE &&
-                           params.hidden_ssid !=
-                           NL80211_HIDDEN_SSID_ZERO_LEN &&
-                           params.hidden_ssid !=
-                           NL80211_HIDDEN_SSID_ZERO_CONTENTS)
-                               return -EINVAL;
-               }
-
-               params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
-
-               if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
-                       params.auth_type = nla_get_u32(
-                               info->attrs[NL80211_ATTR_AUTH_TYPE]);
-                       if (!nl80211_valid_auth_type(params.auth_type))
-                               return -EINVAL;
-               } else
-                       params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
-
-               err = nl80211_crypto_settings(rdev, info, &params.crypto,
-                                             NL80211_MAX_NR_CIPHER_SUITES);
-               if (err)
-                       return err;
-
-               call = rdev->ops->add_beacon;
-               break;
-       case NL80211_CMD_SET_BEACON:
-               call = rdev->ops->set_beacon;
-               break;
-       default:
-               WARN_ON(1);
-               return -EOPNOTSUPP;
-       }
-
-       if (!call)
-               return -EOPNOTSUPP;
+       memset(bcn, 0, sizeof(*bcn));
 
        if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
-               params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
-               params.head_len =
-                   nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
-               haveinfo = 1;
+               bcn->head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
+               bcn->head_len = nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
+               if (!bcn->head_len)
+                       return -EINVAL;
+               haveinfo = true;
        }
 
        if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
-               params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
-               params.tail_len =
+               bcn->tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
+               bcn->tail_len =
                    nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
-               haveinfo = 1;
+               haveinfo = true;
        }
 
        if (!haveinfo)
                return -EINVAL;
 
        if (info->attrs[NL80211_ATTR_IE]) {
-               params.beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]);
-               params.beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+               bcn->beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]);
+               bcn->beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
        }
 
        if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) {
-               params.proberesp_ies =
+               bcn->proberesp_ies =
                        nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
-               params.proberesp_ies_len =
+               bcn->proberesp_ies_len =
                        nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
        }
 
        if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
-               params.assocresp_ies =
+               bcn->assocresp_ies =
                        nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
-               params.assocresp_ies_len =
+               bcn->assocresp_ies_len =
                        nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
        }
 
        if (info->attrs[NL80211_ATTR_PROBE_RESP]) {
-               params.probe_resp =
+               bcn->probe_resp =
                        nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]);
-               params.probe_resp_len =
+               bcn->probe_resp_len =
                        nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]);
        }
 
-       err = call(&rdev->wiphy, dev, &params);
-       if (!err && params.interval)
-               wdev->beacon_interval = params.interval;
+       return 0;
+}
+
+static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_ap_settings params;
+       int err;
+
+       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+               return -EOPNOTSUPP;
+
+       if (!rdev->ops->start_ap)
+               return -EOPNOTSUPP;
+
+       if (wdev->beacon_interval)
+               return -EALREADY;
+
+       memset(&params, 0, sizeof(params));
+
+       /* these are required for START_AP */
+       if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
+           !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
+           !info->attrs[NL80211_ATTR_BEACON_HEAD])
+               return -EINVAL;
+
+       err = nl80211_parse_beacon(info, &params.beacon);
+       if (err)
+               return err;
+
+       params.beacon_interval =
+               nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
+       params.dtim_period =
+               nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
+
+       err = cfg80211_validate_beacon_int(rdev, params.beacon_interval);
+       if (err)
+               return err;
+
+       /*
+        * In theory, some of these attributes should be required here
+        * but since they were not used when the command was originally
+        * added, keep them optional for old user space programs to let
+        * them continue to work with drivers that do not need the
+        * additional information -- drivers must check!
+        */
+       if (info->attrs[NL80211_ATTR_SSID]) {
+               params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+               params.ssid_len =
+                       nla_len(info->attrs[NL80211_ATTR_SSID]);
+               if (params.ssid_len == 0 ||
+                   params.ssid_len > IEEE80211_MAX_SSID_LEN)
+                       return -EINVAL;
+       }
+
+       if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
+               params.hidden_ssid = nla_get_u32(
+                       info->attrs[NL80211_ATTR_HIDDEN_SSID]);
+               if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE &&
+                   params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN &&
+                   params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS)
+                       return -EINVAL;
+       }
+
+       params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
+
+       if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
+               params.auth_type = nla_get_u32(
+                       info->attrs[NL80211_ATTR_AUTH_TYPE]);
+               if (!nl80211_valid_auth_type(params.auth_type))
+                       return -EINVAL;
+       } else
+               params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
+
+       err = nl80211_crypto_settings(rdev, info, &params.crypto,
+                                     NL80211_MAX_NR_CIPHER_SUITES);
+       if (err)
+               return err;
+
+       if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
+               if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
+                       return -EOPNOTSUPP;
+               params.inactivity_timeout = nla_get_u16(
+                       info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
+       }
+
+       err = rdev->ops->start_ap(&rdev->wiphy, dev, &params);
+       if (!err)
+               wdev->beacon_interval = params.beacon_interval;
        return err;
 }
 
-static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
+static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_beacon_data params;
+       int err;
+
+       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+               return -EOPNOTSUPP;
+
+       if (!rdev->ops->change_beacon)
+               return -EOPNOTSUPP;
+
+       if (!wdev->beacon_interval)
+               return -EINVAL;
+
+       err = nl80211_parse_beacon(info, &params);
+       if (err)
+               return err;
+
+       return rdev->ops->change_beacon(&rdev->wiphy, dev, &params);
+}
+
+static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
        struct net_device *dev = info->user_ptr[1];
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        int err;
 
-       if (!rdev->ops->del_beacon)
+       if (!rdev->ops->stop_ap)
                return -EOPNOTSUPP;
 
        if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
            dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
                return -EOPNOTSUPP;
 
-       err = rdev->ops->del_beacon(&rdev->wiphy, dev);
+       if (!wdev->beacon_interval)
+               return -ENOENT;
+
+       err = rdev->ops->stop_ap(&rdev->wiphy, dev);
        if (!err)
                wdev->beacon_interval = 0;
        return err;
@@ -2655,13 +2691,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                break;
        case NL80211_IFTYPE_P2P_CLIENT:
        case NL80211_IFTYPE_STATION:
-               /* disallow things sta doesn't support */
-               if (params.plink_action)
-                       return -EINVAL;
-               if (params.ht_capa)
-                       return -EINVAL;
-               if (params.listen_interval >= 0)
-                       return -EINVAL;
                /*
                 * Don't allow userspace to change the TDLS_PEER flag,
                 * but silently ignore attempts to change it since we
@@ -2669,7 +2698,15 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                 * to change the flag.
                 */
                params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
-
+               /* fall through */
+       case NL80211_IFTYPE_ADHOC:
+               /* disallow things sta doesn't support */
+               if (params.plink_action)
+                       return -EINVAL;
+               if (params.ht_capa)
+                       return -EINVAL;
+               if (params.listen_interval >= 0)
+                       return -EINVAL;
                /* reject any changes other than AUTHORIZED */
                if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
                        return -EINVAL;
@@ -3259,6 +3296,10 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
                        cur_params.dot11MeshHWMPRannInterval);
        NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
                        cur_params.dot11MeshGateAnnouncementProtocol);
+       NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING,
+                       cur_params.dot11MeshForwarding);
+       NLA_PUT_U32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
+                       cur_params.rssi_threshold);
        nla_nest_end(msg, pinfoattr);
        genlmsg_end(msg, hdr);
        return genlmsg_reply(msg, info);
@@ -3290,6 +3331,8 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
        [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
        [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
        [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
+       [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
+       [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32},
 };
 
 static const struct nla_policy
@@ -3379,6 +3422,10 @@ do {\
                        dot11MeshGateAnnouncementProtocol, mask,
                        NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
                        nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
+                       mask, NL80211_MESHCONF_FORWARDING, nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold,
+                       mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32);
        if (mask_out)
                *mask_out = mask;
 
@@ -4079,7 +4126,6 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
        struct cfg80211_bss *res = &intbss->pub;
        void *hdr;
        struct nlattr *bss;
-       int i;
 
        ASSERT_WDEV_LOCK(wdev);
 
@@ -4132,13 +4178,6 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
                if (intbss == wdev->current_bss)
                        NLA_PUT_U32(msg, NL80211_BSS_STATUS,
                                    NL80211_BSS_STATUS_ASSOCIATED);
-               else for (i = 0; i < MAX_AUTH_BSSES; i++) {
-                       if (intbss != wdev->auth_bsses[i])
-                               continue;
-                       NLA_PUT_U32(msg, NL80211_BSS_STATUS,
-                                   NL80211_BSS_STATUS_AUTHENTICATED);
-                       break;
-               }
                break;
        case NL80211_IFTYPE_ADHOC:
                if (intbss == wdev->current_bss)
@@ -4406,10 +4445,16 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
 
        local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
 
+       /*
+        * Since we no longer track auth state, ignore
+        * requests to only change local state.
+        */
+       if (local_state_change)
+               return 0;
+
        return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
                                  ssid, ssid_len, ie, ie_len,
-                                 key.p.key, key.p.key_len, key.idx,
-                                 local_state_change);
+                                 key.p.key, key.p.key_len, key.idx);
 }
 
 static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
@@ -4781,7 +4826,6 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
                        nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
                struct ieee80211_supported_band *sband =
                        wiphy->bands[ibss.channel->band];
-               int err;
 
                err = ieee80211_get_ratemask(sband, rates, n_rates,
                                             &ibss.basic_rates);
@@ -4801,6 +4845,9 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
                        return PTR_ERR(connkeys);
        }
 
+       ibss.control_port =
+               nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
+
        err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
        if (err)
                kfree(connkeys);
@@ -5390,9 +5437,39 @@ static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
        return mask;
 }
 
+static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
+                              u8 *rates, u8 rates_len,
+                              u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
+{
+       u8 i;
+
+       memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
+
+       for (i = 0; i < rates_len; i++) {
+               int ridx, rbit;
+
+               ridx = rates[i] / 8;
+               rbit = BIT(rates[i] % 8);
+
+               /* check validity */
+               if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
+                       return false;
+
+               /* check availability */
+               if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
+                       mcs[ridx] |= rbit;
+               else
+                       return false;
+       }
+
+       return true;
+}
+
 static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
        [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
                                    .len = NL80211_MAX_SUPP_RATES },
+       [NL80211_TXRATE_MCS] = { .type = NLA_BINARY,
+                                .len = NL80211_MAX_SUPP_HT_RATES },
 };
 
 static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
@@ -5418,12 +5495,20 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
                sband = rdev->wiphy.bands[i];
                mask.control[i].legacy =
                        sband ? (1 << sband->n_bitrates) - 1 : 0;
+               if (sband)
+                       memcpy(mask.control[i].mcs,
+                              sband->ht_cap.mcs.rx_mask,
+                              sizeof(mask.control[i].mcs));
+               else
+                       memset(mask.control[i].mcs, 0,
+                              sizeof(mask.control[i].mcs));
        }
 
        /*
         * The nested attribute uses enum nl80211_band as the index. This maps
         * directly to the enum ieee80211_band values used in cfg80211.
         */
+       BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
        nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
        {
                enum ieee80211_band band = nla_type(tx_rates);
@@ -5439,7 +5524,28 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
                                sband,
                                nla_data(tb[NL80211_TXRATE_LEGACY]),
                                nla_len(tb[NL80211_TXRATE_LEGACY]));
-                       if (mask.control[band].legacy == 0)
+               }
+               if (tb[NL80211_TXRATE_MCS]) {
+                       if (!ht_rateset_to_mask(
+                                       sband,
+                                       nla_data(tb[NL80211_TXRATE_MCS]),
+                                       nla_len(tb[NL80211_TXRATE_MCS]),
+                                       mask.control[band].mcs))
+                               return -EINVAL;
+               }
+
+               if (mask.control[band].legacy == 0) {
+                       /* don't allow empty legacy rates if HT
+                        * is not even supported. */
+                       if (!rdev->wiphy.bands[band]->ht_cap.ht_supported)
+                               return -EINVAL;
+
+                       for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
+                               if (mask.control[band].mcs[i])
+                                       break;
+
+                       /* legacy and mcs rates may not be both empty */
+                       if (i == IEEE80211_HT_MCS_MASK_LEN)
                                return -EINVAL;
                }
        }
@@ -6293,23 +6399,23 @@ static struct genl_ops nl80211_ops[] = {
                .cmd = NL80211_CMD_SET_BEACON,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .doit = nl80211_addset_beacon,
+               .doit = nl80211_set_beacon,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
-               .cmd = NL80211_CMD_NEW_BEACON,
+               .cmd = NL80211_CMD_START_AP,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .doit = nl80211_addset_beacon,
+               .doit = nl80211_start_ap,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
-               .cmd = NL80211_CMD_DEL_BEACON,
+               .cmd = NL80211_CMD_STOP_AP,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .doit = nl80211_del_beacon,
+               .doit = nl80211_stop_ap,
                .internal_flags = NL80211_FLAG_NEED_NETDEV |
                                  NL80211_FLAG_NEED_RTNL,
        },
@@ -7580,7 +7686,8 @@ bool nl80211_unexpected_4addr_frame(struct net_device *dev,
 
 int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
                      struct net_device *netdev, u32 nlpid,
-                     int freq, const u8 *buf, size_t len, gfp_t gfp)
+                     int freq, int sig_dbm,
+                     const u8 *buf, size_t len, gfp_t gfp)
 {
        struct sk_buff *msg;
        void *hdr;
@@ -7598,6 +7705,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
+       if (sig_dbm)
+               NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm);
        NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
 
        genlmsg_end(msg, hdr);
@@ -7859,7 +7968,7 @@ EXPORT_SYMBOL(cfg80211_probe_status);
 
 void cfg80211_report_obss_beacon(struct wiphy *wiphy,
                                 const u8 *frame, size_t len,
-                                int freq, gfp_t gfp)
+                                int freq, int sig_dbm, gfp_t gfp)
 {
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
        struct sk_buff *msg;
@@ -7882,6 +7991,8 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
        if (freq)
                NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
+       if (sig_dbm)
+               NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm);
        NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame);
 
        genlmsg_end(msg, hdr);
index 12bf4d185abe7dd1f0e89494261c3441faab3680..4ffe50df9f31461e84c426aeb54e46fb1cd8c897 100644 (file)
@@ -92,7 +92,8 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
                                gfp_t gfp);
 
 int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
-                     struct net_device *netdev, u32 nlpid, int freq,
+                     struct net_device *netdev, u32 nlpid,
+                     int freq, int sig_dbm,
                      const u8 *buf, size_t len, gfp_t gfp);
 void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
                                 struct net_device *netdev, u64 cookie,
index f65feaad155f42a328460d03ee0c47c770b81981..e9a0ac83b84c2798961e59b1045a2e09d52b0a5d 100644 (file)
@@ -882,23 +882,8 @@ static void handle_channel(struct wiphy *wiphy,
        chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
        chan->max_antenna_gain = min(chan->orig_mag,
                (int) MBI_TO_DBI(power_rule->max_antenna_gain));
-       if (chan->orig_mpwr) {
-               /*
-                * Devices that have their own custom regulatory domain
-                * but also use WIPHY_FLAG_STRICT_REGULATORY will follow the
-                * passed country IE power settings.
-                */
-               if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
-                   wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY &&
-                   wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) {
-                       chan->max_power =
-                               MBM_TO_DBM(power_rule->max_eirp);
-               } else {
-                       chan->max_power = min(chan->orig_mpwr,
-                               (int) MBM_TO_DBM(power_rule->max_eirp));
-               }
-       } else
-               chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
+       chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
+       chan->max_power = min(chan->max_power, chan->max_reg_power);
 }
 
 static void handle_band(struct wiphy *wiphy,
index 31119e32e092b6e2615a8653c768a5cd7531465b..afde7e5f001057d84f8528dbd85ebc16c08bf92b 100644 (file)
@@ -861,6 +861,18 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
 }
 EXPORT_SYMBOL(cfg80211_inform_bss_frame);
 
+void cfg80211_ref_bss(struct cfg80211_bss *pub)
+{
+       struct cfg80211_internal_bss *bss;
+
+       if (!pub)
+               return;
+
+       bss = container_of(pub, struct cfg80211_internal_bss, pub);
+       kref_get(&bss->ref);
+}
+EXPORT_SYMBOL(cfg80211_ref_bss);
+
 void cfg80211_put_bss(struct cfg80211_bss *pub)
 {
        struct cfg80211_internal_bss *bss;
index 7b9ecaed96bef13aab274b5cd3686dd2487096ac..f7e937ff897893a2dff84efcf9d8a9422aebe3b0 100644 (file)
@@ -179,7 +179,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
                                            params->ssid, params->ssid_len,
                                            NULL, 0,
                                            params->key, params->key_len,
-                                           params->key_idx, false);
+                                           params->key_idx);
        case CFG80211_CONN_ASSOCIATE_NEXT:
                BUG_ON(!rdev->ops->assoc);
                wdev->conn->state = CFG80211_CONN_ASSOCIATING;
@@ -477,6 +477,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
                kfree(wdev->connect_keys);
                wdev->connect_keys = NULL;
                wdev->ssid_len = 0;
+               cfg80211_put_bss(bss);
                return;
        }
 
@@ -701,31 +702,10 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
        wdev->ssid_len = 0;
 
        if (wdev->conn) {
-               const u8 *bssid;
-               int ret;
-
                kfree(wdev->conn->ie);
                wdev->conn->ie = NULL;
                kfree(wdev->conn);
                wdev->conn = NULL;
-
-               /*
-                * If this disconnect was due to a disassoc, we
-                * we might still have an auth BSS around. For
-                * the userspace SME that's currently expected,
-                * but for the kernel SME (nl80211 CONNECT or
-                * wireless extensions) we want to clear up all
-                * state.
-                */
-               for (i = 0; i < MAX_AUTH_BSSES; i++) {
-                       if (!wdev->auth_bsses[i])
-                               continue;
-                       bssid = wdev->auth_bsses[i]->pub.bssid;
-                       ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
-                                               WLAN_REASON_DEAUTH_LEAVING,
-                                               false);
-                       WARN(ret, "deauth failed: %d\n", ret);
-               }
        }
 
        nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
@@ -1012,7 +992,8 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
        return err;
 }
 
-void cfg80211_sme_disassoc(struct net_device *dev, int idx)
+void cfg80211_sme_disassoc(struct net_device *dev,
+                          struct cfg80211_internal_bss *bss)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1031,16 +1012,8 @@ void cfg80211_sme_disassoc(struct net_device *dev, int idx)
         * want it any more so deauthenticate too.
         */
 
-       if (!wdev->auth_bsses[idx])
-               return;
+       memcpy(bssid, bss->pub.bssid, ETH_ALEN);
 
-       memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN);
-       if (__cfg80211_mlme_deauth(rdev, dev, bssid,
-                                  NULL, 0, WLAN_REASON_DEAUTH_LEAVING,
-                                  false)) {
-               /* whatever -- assume gone anyway */
-               cfg80211_unhold_bss(wdev->auth_bsses[idx]);
-               cfg80211_put_bss(&wdev->auth_bsses[idx]->pub);
-               wdev->auth_bsses[idx] = NULL;
-       }
+       __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
+                              WLAN_REASON_DEAUTH_LEAVING, false);
 }
index 9aa9db6c81411ddfcd77c34de8128fcd57e2e5d2..1b7a08df933c79bf4ffe62455747464468c84bdb 100644 (file)
@@ -904,6 +904,7 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate)
        /* do NOT round down here */
        return (bitrate + 50000) / 100000;
 }
+EXPORT_SYMBOL(cfg80211_calculate_bitrate);
 
 int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
                                 u32 beacon_int)